diff options
Diffstat (limited to 'lib')
1111 files changed, 131211 insertions, 46849 deletions
diff --git a/lib/.gitignore b/lib/.gitignore index fc8a1c5568..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 @@ -141,6 +142,11 @@ # orber & cos* applications +/orber/test/idl_output +/cosEvent/test/idl_output +/cosNotification/test/idl_output +/cosTransactions/test/idl_output + /cosEvent/include/CosEventChannelAdmin.hrl /cosEvent/include/CosEventChannelAdmin_ConsumerAdmin.hrl /cosEvent/include/CosEventChannelAdmin_EventChannel.hrl diff --git a/lib/appmon/doc/src/appmon_chapter.xml b/lib/appmon/doc/src/appmon_chapter.xml index 9673a13078..0dab23b549 100644 --- a/lib/appmon/doc/src/appmon_chapter.xml +++ b/lib/appmon/doc/src/appmon_chapter.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2000</year><year>2009</year> + <year>2000</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>Appmon</title> @@ -226,8 +226,8 @@ <p>In the left frame it is possible to:</p> <list type="bulleted"> <item>Select which node to supervise.</item> - <item>Select an application to view it's process tree.</item> - <item>Select an application to view it's specification.</item> + <item>Select an application to view its process tree.</item> + <item>Select an application to view its specification.</item> </list> <p>The right frame shows the selected information, either the application specification or the process tree and process information.</p> diff --git a/lib/appmon/doc/src/notes.xml b/lib/appmon/doc/src/notes.xml index 219b5671a4..ace163bcad 100644 --- a/lib/appmon/doc/src/notes.xml +++ b/lib/appmon/doc/src/notes.xml @@ -30,6 +30,37 @@ </header> <p>This document describes the changes made to the Appmon application.</p> +<section><title>Appmon 2.1.13</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + An obsolete compiler directive for native code generation + was removed from a source file.</p> + <p> + Own Id: OTP-8839</p> + </item> + </list> + </section> + +</section> + +<section><title>Appmon 2.1.12</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Warnings due to new autoimported BIFs removed</p> + <p> + Own Id: OTP-8674 Aux Id: OTP-8579 </p> + </item> + </list> + </section> + +</section> + <section><title>Appmon 2.1.11</title> <section><title>Improvements and New Features</title> diff --git a/lib/appmon/src/appmon.erl b/lib/appmon/src/appmon.erl index 6f5d2824d2..2b982cddf0 100644 --- a/lib/appmon/src/appmon.erl +++ b/lib/appmon/src/appmon.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(appmon). -behaviour(gen_server). @@ -838,7 +838,7 @@ draw_apps(GUI, [App | Apps], X, Lx0, N, GSObjs) -> %% Some necessary data {_Pid, AppName, _Descr} = App, Text = atom_to_list(AppName), - Width = max(8*length(Text)+10, ?wBTN), + Width = erlang:max(8*length(Text)+10, ?wBTN), %% Connect the application to the node label with a line %% Lx0 = leftmost X coordinate (above previous application button) @@ -1009,9 +1009,6 @@ bcast(MNodes, Msg) -> end, MNodes). -max(X, Y) when X>Y -> X; -max(_, Y) -> Y. - %% parse_nodes(MNodes) -> NodeApps %% MNodes -> [#mnode{}] %% NodeApps -> [{Node, Status, Apps}] diff --git a/lib/appmon/src/appmon_info.erl b/lib/appmon/src/appmon_info.erl index 4e36d3a13f..332140f69d 100644 --- a/lib/appmon/src/appmon_info.erl +++ b/lib/appmon/src/appmon_info.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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% %% %%---------------------------------------------------------------------- @@ -807,24 +807,21 @@ load(Opts) -> case get_opt(load_scale, Opts) of linear -> - min(trunc(load_range()*(Td/Tot+Q/6)), + erlang:min(trunc(load_range()*(Td/Tot+Q/6)), load_range()); prog -> - min(trunc(load_range()*prog(Td/Tot+Q/6)), + erlang:min(trunc(load_range()*prog(Td/Tot+Q/6)), load_range()) end; queue -> case get_opt(load_scale, Opts) of linear -> - min(trunc(load_range()*Q/6), load_range()); + erlang:min(trunc(load_range()*Q/6), load_range()); prog -> - min(trunc(load_range()*prog(Q/6)), load_range()) + erlang:min(trunc(load_range()*prog(Q/6)), load_range()) end end. -min(X,Y) when X<Y -> X; -min(_,Y)->Y. - %% %% T shall be within 0 and 0.9 for this to work correctly diff --git a/lib/appmon/src/appmon_place.erl b/lib/appmon/src/appmon_place.erl index 5a6ae6aa48..fe1e909d7c 100644 --- a/lib/appmon/src/appmon_place.erl +++ b/lib/appmon/src/appmon_place.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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% %%------------------------------------------------------------ %% @@ -155,10 +155,8 @@ move2(DG, V, LastX, DeltaX) -> ChLX = foldl(fun(C, LX) -> move2(DG, C, LX, DeltaX) end, tll(LastX), appmon_dg:get(out, DG, V)), - [max(NewX+appmon_dg:get(w, DG, V), hdd(LastX)) | ChLX]. + [erlang:max(NewX+appmon_dg:get(w, DG, V), hdd(LastX)) | ChLX]. -max(A, B) when A>B -> A; -max(_, B) -> B. %%------------------------------------------------------------ %% 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 e6c2b13877..fa17345daf 100644 --- a/lib/appmon/vsn.mk +++ b/lib/appmon/vsn.mk @@ -1 +1 @@ -APPMON_VSN = 2.1.11 +APPMON_VSN = 2.1.13 diff --git a/lib/asn1/c_src/Makefile b/lib/asn1/c_src/Makefile index 906c513fad..9e9cb18524 100644 --- a/lib/asn1/c_src/Makefile +++ b/lib/asn1/c_src/Makefile @@ -124,7 +124,7 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt $(INSTALL_DIR) $(RELSYSDIR)/priv/lib - $(INSTALL_DATA) $(SHARED_OBJ_FILES) $(RELSYSDIR)/priv/lib + $(INSTALL_PROGRAM) $(SHARED_OBJ_FILES) $(RELSYSDIR)/priv/lib $(INSTALL_DIR) $(RELSYSDIR)/c_src $(INSTALL_DATA) $(C_FILES) $(RELSYSDIR)/c_src diff --git a/lib/asn1/c_src/asn1_erl_driver.c b/lib/asn1/c_src/asn1_erl_driver.c index fd284e5800..9dd3a0fd7d 100644 --- a/lib/asn1/c_src/asn1_erl_driver.c +++ b/lib/asn1/c_src/asn1_erl_driver.c @@ -1407,7 +1407,6 @@ int decode_partial(ErlDrvBinary **drv_binary,unsigned char *in_buf, int in_buf_l int msg_index_val; int *msg_index, *tag_index, tmp_index; int tag_seq_length; - char tag_code; /* one of ASN1_SKIPPED, ASN1_OPTIONAL, ASN1_CHOOSEN */ int wanted_tag, next_tag; int buf_end_index = in_buf_len; int ret = 0, length, old_index; @@ -1600,7 +1599,7 @@ int get_value(char *out_buf, { int len, lenoflen, indef=0, skip_len; int ret=0; - int start_index, out_index = 0; + int start_index; /* printf("get_value 1\n\r"); */ if (in_buf[*msg_index] < 0x80){ /* short definite length */ diff --git a/lib/asn1/doc/src/asn1_ug.xml b/lib/asn1/doc/src/asn1_ug.xml index f2cd073ec8..12d986308f 100644 --- a/lib/asn1/doc/src/asn1_ug.xml +++ b/lib/asn1/doc/src/asn1_ug.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>1997</year><year>2009</year> + <year>1997</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -22,7 +22,7 @@ </legalnotice> <title>Asn1</title> - <prepared>ETX/DN/SP Kenneth. Lundin</prepared> + <prepared>Kenneth Lundin</prepared> <docno></docno> <date>1999-03-25</date> <rev>D</rev> @@ -41,17 +41,28 @@ decode functions to be used by Erlang programs sending and receiving ASN.1 specified data.</item> <item>Run-time functions used by the generated code.</item> - <item>Encoding rules supported are <em>BER</em>, the - specialized BER version <em>DER</em> and the basic form of - aligned and unaligned variants of <em>PER</em>.</item> + <item>The supported encoding rules are: + <list> + <item> + Basic Encoding Rules (<em>BER</em>) + </item> + <item> + Distinguished Encoding Rules (<em>DER</em>), a specialized form of BER that is used in security-conscious applications. + </item> + <item> + Packed Encoding Rules (<em>PER</em>) both the aligned and unaligned variant. + </item> + </list> + </item> </list> </section> <section> <title>Overview</title> - <p>ASN.1 (Abstract Syntax Notation 1) defines the abstract - syntax of information. The purpose of ASN.1 is to have - a platform independent language to express types using a + <p>ASN.1 (Abstract Syntax Notation 1) is a formal language for describing data structures to be exchanged between distributed computer systems. + The purpose of ASN.1 is to have + a platform and programming language independent notation to express + types using a standardized set of rules for the transformation of values of a defined type, into a stream of bytes. This stream of bytes can then be sent on a communication channel set up by the @@ -102,20 +113,16 @@ [<cite id="DUBUISSON"></cite>], free to download at <url href="http://www.oss.com/asn1/dubuisson.html">http://www.oss.com/asn1/dubuisson.html </url>. </p> - <p>Knowledge of Erlang programming is also essential and reading the book - <em>Concurrent Programming in ERLANG</em>, - [<cite id="erlbook2"></cite>], is recommended. Part 1 of this is available on the web in - <url href="http://www.erlang.org/download/erlang-book-part1.pdf">PDF</url> format. - </p> </section> <section> <title>Capability</title> <p>This application covers all features of ASN.1 up to the 1997 - edition of the specification. In the 2002 edition some new - extensions came up of which there are support only for some of - them. ECN (Cncoding Control Notation) and XML notation are still - unsupported. Though, the other features of 2002 edition are + edition of the specification. In the 2002 edition of ASN.1 a number of + new features where introduced of which some are supported while + others are not. For example the + ECN (Encoding Control Notation) and XML notation are still + unsupported. Though, the other features of the 2002 edition are fully or partly supported as shown below:</p> <list type="bulleted"> <item> @@ -308,7 +315,7 @@ erlc -o ../asnfiles -I ../asnfiles -I /usr/local/standards/asn1 Person.asn <p>Choice of encoding rules, if omitted <c>ber</c> is the default. The <c>ber_bin</c> and <c>per_bin</c> options allows for optimizations and are therefore recommended - instaed of the <c>ber</c> and <c>per</c> options.</p> + instead of the <c>ber</c> and <c>per</c> options.</p> </item> <tag><c>-o OutDirectory</c></tag> <item> @@ -629,7 +636,7 @@ asn1ct:decode('H323-MESSAGES','SomeChoiceType',Bytes). </pre> <c>driver</c> options does not affect the encode or decode result, just the time spent in run-time. When <c>ber_bin</c> and <c>driver</c> or <c>per_bin, optimize</c> and <c>driver</c> is - combined the C-code driver is used in choosen parts of encode / + combined the C-code driver is used in chosen parts of encode / decode procedure. </p> <table> @@ -749,11 +756,11 @@ asn1rt:decode('H323-MESSAGES','SomeChoiceType',Bytes). </pre> you may want to continue running the old asn1 run-time functionality.</item> <item>Performance issues: If you have an asn1 system with a lot - of cross references you may gain in performance. Meassurements + of cross references you may gain in performance. Measurements must be done for each case.</item> </list> <p>You may choose either the plain multi file compilation that just - merges the choosen asn1 specs or the <c>{inline,OutputModule}</c> + merges the chosen asn1 specs or the <c>{inline,OutputModule}</c> that also includes the used asn1 run-time functionality.</p> <p>For both cases you need to specify which asn1 specs you will compile in a module that must have the extension @@ -919,7 +926,7 @@ T5 ::= INTEGER (MIN<..-99) T6 ::= INTEGER {red(0),blue(1),white(2)} </pre> <p>The Erlang representation of an ASN.1 INTEGER is an integer or - an atom if a so called \011<c>Named NumberList</c> (see T6 above) + an atom if a so called <c>Named Number List</c> (see T6 above) is specified.</p> <p>Below is an example of Erlang code which assigns values for the above types: </p> @@ -934,7 +941,7 @@ T6value3 = white ASN.1 defined types. This style of value can be passed directly to the encoder for transformation into a series of bytes.</p> <p>The decoder will return an atom if the value corresponds to a - symbol in the Named NumberList.</p> + symbol in the Named Number List.</p> </section> <section> @@ -978,8 +985,9 @@ N1 = 'NULL', <p>The enumerated type can be used, when the value we wish to describe, may only take one of a set of predefined values.</p> <pre> -DaysOfTheWeek ::= ENUMERATED { sunday(1),monday(2),tuesday(3), -\011wednesday(4),thursday(5),friday(6),saturday(7) } +DaysOfTheWeek ::= ENUMERATED { + sunday(1),monday(2),tuesday(3), + wednesday(4),thursday(5),friday(6),saturday(7) } </pre> <p>For example to assign a weekday value in Erlang use the same atom as in the <c>Enumerations</c> of the type definition:</p> @@ -1273,11 +1281,14 @@ Pdu ::= SEQUENCE { <p>Values can be assigned in Erlang as shown below:</p> <pre> MyPdu = #'Pdu'{a=22,b=77.99,c={0,1,2,3,4},d='NULL'}. </pre> - <p>It is also possible to specify the value for each component in - a SEQUENCE or a SET as <c>{ComponentName,Value}</c>. It is not - recommended and is not supported if the flags <c>per_bin</c> or - <c>ber_bin</c> and <c>optimize</c> were used when the module was - compiled.</p> +<note> + <p> + In very early versions of the asn1 compiler it was also possible to + specify the values of the components in + a SEQUENCE or a SET as a list of tuples <c>{ComponentName,Value}</c>. + This is no longer supported. + </p> +</note> <p>The decode functions will return a record as result when decoding a <c>SEQUENCE</c> or a <c>SET</c>. <marker id="DEFAULT"></marker> @@ -1293,13 +1304,13 @@ MyPdu = #'Pdu'{a=22,b=77.99,c={0,1,2,3,4},d='NULL'}. </pre> <p>For instance, if the following types exists in a file "File.asn":</p> <pre> Seq1 ::= SEQUENCE { -\011a INTEGER DEFAULT 1, -\011b Seq2 DEFAULT {aa TRUE, bb 15} + a INTEGER DEFAULT 1, + b Seq2 DEFAULT {aa TRUE, bb 15} } Seq2 ::= SEQUENCE { -\011aa BOOLEAN, -\011bb INTEGER + aa BOOLEAN, + bb INTEGER } </pre> <p>Some values and the corresponding encoding in an Erlang terminal @@ -1331,7 +1342,7 @@ ok <marker id="DEFAULT DER"></marker> </p> <p>But, the DER encoding format has stronger requirements regarding - default\011values both for SET and SEQUENCE. A more elaborate and time + default values both for SET and SEQUENCE. A more elaborate and time expensive check of default values will take place. The following is an example with the same types and values as above but with der encoding format.</p> @@ -1409,7 +1420,7 @@ Bad ::= SET {i INTEGER, values is the same for SET as for SEQUENCE, and is supported by the compiler, <seealso marker="#DEFAULT DER">see above</seealso>.</p> <p>Moreover, in DER the elements of a SET will be sorted. If a - component is an untagged choice the sorting have to take place + component is an un-tagged choice the sorting have to take place in run-time. This fact emphasizes the following recommendation if DER encoding format is used.</p> <p>The concept of SET is an unusual @@ -1425,7 +1436,7 @@ Bad ::= SET {i INTEGER, </section> <section> - <title>Notes about Extendability for SEQUENCE and SET</title> + <title>Notes about Extend-ability for SEQUENCE and SET</title> <p>When a SEQUENCE or SET contains an extension marker and extension components like this:</p> <pre> @@ -1498,9 +1509,9 @@ C2 ::= CHOICE { <section> <title>Extendable CHOICE</title> <p>When a CHOICE contains an extension marker and the decoder detects - an unknown alternative of the CHIOCE the value is represented as:</p> + an unknown alternative of the CHOICE the value is represented as:</p> <pre> -\011 {asn1_ExtAlt, BytesForOpenType} +{asn1_ExtAlt, BytesForOpenType} </pre> <p>Where <c>BytesForOpenType</c> is a list of bytes constituting the encoding of the "unknown" CHOICE alternative. </p> @@ -1630,15 +1641,15 @@ V = #'Emb'{a=["qqqq",[1,2,255]], the record name is extended with an underscore and the component name. If the embedded structure is deeper with SEQUENCE, SET or CHOICE types in the line, each component-/alternative-name will - be added to the recordname.</p> + be added to the record-name.</p> <p>For example:</p> <pre> Seq ::= SEQUENCE{ - a\011CHOICE{ -\011b SEQUENCE { -\011 c INTEGER -\011 } -\011} + a CHOICE{ + b SEQUENCE { + c INTEGER + } + } } </pre> <p>will result in the following record:</p> <pre> @@ -1650,10 +1661,10 @@ Seq ::= SEQUENCE{ <pre> Seq ::= SEQUENCE { a SEQUENCE OF SEQUENCE { -\011 b + b } c SET OF SEQUENCE { -\011 d + d } } </pre> <p>This results in the records:</p> @@ -1802,16 +1813,16 @@ GENERAL-PROCEDURES GENERAL-PROCEDURE ::= { <pre> StartMessage ::= SEQUENCE { msgId GENERAL-PROCEDURE.&id ({GENERAL-PROCEDURES}), - content GENERAL-PROCEDURE.&Message\011({GENERAL-PROCEDURES}{@msgId}), + content GENERAL-PROCEDURE.&Message ({GENERAL-PROCEDURES}{@msgId}), } </pre> <p>In the type <c>StartMessage</c> the constraint following the <c>content</c> field tells that in a value of type <c>StartMessage</c> the value in the <c>content</c> field must - come from the same object that is choosen by the <c>msgId</c> + come from the same object that is chosen by the <c>msgId</c> field.</p> <p>So, the value <c>#'StartMessage'{msgId="home",content="Any Printable String"}</c> is legal to encode as a StartMessage value, while the value <c>#'StartMessage'{msgId="remote", content="Some String"}</c> is illegal since the constraint - in StartMessage tells that when you have choosen a value from a + in StartMessage tells that when you have chosen a value from a specific object in the object set GENERAL-PROCEDURES in the msgId field you have to choose a value from that same object in the content field too. In this second case it should have been @@ -1831,7 +1842,7 @@ StartMessage ::= SEQUENCE { information object sets. A part of a definition can be supplied as a parameter. For instance, if a Type is used in a definition with certain - purpose, one want the typename to express the intention. This + purpose, one want the type-name to express the intention. This can be done with parameterization.</p> <p>When many types (or an other ASN.1 entity) only differs in some minor cases, but the structure of the types are similar, only diff --git a/lib/asn1/doc/src/asn1ct.xml b/lib/asn1/doc/src/asn1ct.xml index 8a0ae52c39..265f8735c2 100644 --- a/lib/asn1/doc/src/asn1ct.xml +++ b/lib/asn1/doc/src/asn1ct.xml @@ -53,7 +53,7 @@ <v>Option = ber_bin | per_bin | uper_bin | der | compact_bit_string | noobj | {n2n,EnumTypeName} |{outdir,Dir} | {i,IncludeDir} | optimize | driver | asn1config | undec_rest | {inline,OutputName} | inline | - {macro_name_prefix, Prefix} | {record_name_prefix, Prefix}</v> + {macro_name_prefix, Prefix} | {record_name_prefix, Prefix} | verbose</v> <v>OldOption = ber | per</v> <v>Reason = term()</v> <v>Prefix = string()</v> @@ -284,6 +284,11 @@ Binary = binary() <c>Prefix</c>. This is useful when multiple protocols that contains records with identical names are included in a single module.</p> </item> + <tag><c>verbose</c></tag> + <item> + <p>Causes more verbose information from the compiler + describing what it is doing.</p> + </item> </taglist> <p>Any additional option that is applied will be passed to the final step when the generated .erl file is compiled. diff --git a/lib/asn1/doc/src/notes.xml b/lib/asn1/doc/src/notes.xml index 714902e63f..375e859d20 100644 --- a/lib/asn1/doc/src/notes.xml +++ b/lib/asn1/doc/src/notes.xml @@ -30,32 +30,64 @@ </header> <p>This document describes the changes made to the asn1 application.</p> -<section><title>Asn1 1.6.13.2</title> + +<section><title>Asn1 1.6.14.1</title> <section><title>Fixed Bugs and Malfunctions</title> <list> <item> <p> - The encoding of ExtensionAdditionGroup (for PER and UPER) - is corrected.</p> + Extension Addition Groups are now supported by the parser + and in all backends.</p> + <p> + Own Id: OTP-8598 Aux Id: seq-11557 </p> + </item> + <item> + <p> + Extension Addition Groups are now supported in nested + types within a SEQUENCE and CHOICE as well (missed that + in previous fix)</p> <p> - Own Id: OTP-8866 Aux Id: OTP-8797, SEQ-11557 </p> + Own Id: OTP-8797 Aux Id: seq-11557 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Bug in UNALIGNED PER regarding encoding and decoding of + constrained numbers with a valuerange > 1024. (Thanks to + Vincent de Phily)</p> + <p> + Own Id: OTP-8779</p> + </item> + <item> + <p> + Minor corrections in the User Guide.</p> + <p> + Own Id: OTP-8829</p> </item> </list> </section> </section> -<section><title>Asn1 1.6.13.1</title> +<section><title>Asn1 1.6.14</title> - <section><title>Fixed Bugs and Malfunctions</title> + <section><title>Improvements and New Features</title> <list> <item> <p> - Extension Addition Groups are now supported by the parser - and in all backends.</p> + By default, the ASN.1 compiler is now silent in the + absence of warnings or errors. The new '<c>verbose</c>' + option or the '<c>-v</c>' option for <c>erlc</c> can be + given to show extra information (for instance, about the + files that are generated). (Thanks to Tuncer Ayaz.)</p> <p> - Own Id: OTP-8598</p> + Own Id: OTP-8565</p> </item> </list> </section> diff --git a/lib/asn1/src/asn1ct.erl b/lib/asn1/src/asn1ct.erl index e6fd3663dd..968468cb7f 100644 --- a/lib/asn1/src/asn1ct.erl +++ b/lib/asn1/src/asn1ct.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% %% %% @@ -39,7 +39,7 @@ add_tobe_refed_func/1,add_generated_refed_func/1, maybe_rename_function/3,latest_sindex/0,current_sindex/0, set_current_sindex/1,next_sindex/0,maybe_saved_sindex/2, - parse_and_save/2]). + parse_and_save/2,report_verbose/3]). -include("asn1_records.hrl"). -include_lib("stdlib/include/erl_compile.hrl"). @@ -103,8 +103,8 @@ compile(File,Options) when is_list(Options) -> compile1(File,Options) when is_list(Options) -> - io:format("Erlang ASN.1 version ~p compiling ~p ~n",[?vsn,File]), - io:format("Compiler Options: ~p~n",[Options]), + report_verbose("Erlang ASN.1 version ~p compiling ~p ~n",[?vsn,File],Options), + report_verbose("Compiler Options: ~p~n",[Options],Options), Ext = filename:extension(File), Base = filename:basename(File,Ext), OutFile = outfile(Base,"",Options), @@ -152,7 +152,7 @@ inline(true,Name,Module,Options) -> IgorName = filename:rootname(filename:basename(Name)), % io:format("*****~nName: ~p~nModules: ~p~nIgorOptions: ~p~n*****~n", % [IgorName,Modules++RTmodule,IgorOptions]), - io:format("Inlining modules: ~p in ~p~n",[[Module]++RTmodule,IgorName]), + report_verbose("Inlining modules: ~p in ~p~n",[[Module]++RTmodule,IgorName],Options), case catch igor:merge(IgorName,[Module]++RTmodule,[{preprocess,true},{stubs,false},{backups,false}]++IgorOptions) of {'EXIT',{undef,Reason}} -> %% module igor first in R10B io:format("Module igor in syntax_tools must be available:~n~p~n", @@ -173,8 +173,8 @@ inline(_,_,_,_) -> compile_set(SetBase,Files,Options) when is_list(hd(Files)),is_list(Options) -> %% case when there are several input files in a list - io:format("Erlang ASN.1 version ~p compiling ~p ~n",[?vsn,Files]), - io:format("Compiler Options: ~p~n",[Options]), + report_verbose("Erlang ASN.1 version ~p compiling ~p ~n",[?vsn,Files],Options), + report_verbose("Compiler Options: ~p~n",[Options],Options), OutFile = outfile(SetBase,"",Options), DbFile = outfile(SetBase,"asn1db",Options), Includes = [I || {i,I} <- Options], @@ -802,7 +802,7 @@ check({true,M},File,OutFile,Includes,EncodingRule,DbFile,Options,InputMods) -> NewM = Module#module{typeorval=NewTypeOrVal}, asn1_db:dbput(NewM#module.name,'MODULE',NewM), asn1_db:dbsave(DbFile,M#module.name), - io:format("--~p--~n",[{generated,DbFile}]), + report_verbose("--~p--~n",[{generated,DbFile}],Options), {true,{M,NewM,GenTypeOrVal}} end end; @@ -833,7 +833,7 @@ generate({true,{M,_Module,GenTOrV}},OutFile,EncodingRule,Options) -> Result = case (catch asn1ct_gen:pgen(OutFile,EncodingRule, - M#module.name,GenTOrV)) of + M#module.name,GenTOrV,Options)) of {'EXIT',Reason2} -> io:format("ERROR: ~p~n",[Reason2]), {error,Reason2}; @@ -1215,7 +1215,6 @@ compile(File, _OutFile, Options) -> %% io:format("~p~n~s~n",[_Reason,"error"]), error; ok -> - io:format("ok~n"), ok; ParseRes when is_tuple(ParseRes) -> io:format("~p~n",[ParseRes]), @@ -1675,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] -> @@ -2518,3 +2517,14 @@ type_check(#'Externaltypereference'{}) -> lists:concat(["_",I]); make_suffix(_) -> "". + +report_verbose(Format, Args, S) -> + case is_verbose(S) of + true -> + io:format(Format, Args); + false -> + ok + end. + +is_verbose(S) -> + lists:member(verbose, S). diff --git a/lib/asn1/src/asn1ct_check.erl b/lib/asn1/src/asn1ct_check.erl index 7cd29623c1..c6f3b60786 100644 --- a/lib/asn1/src/asn1ct_check.erl +++ b/lib/asn1/src/asn1ct_check.erl @@ -22,6 +22,8 @@ %% Main Module for ASN.1 compile time functions %-compile(export_all). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([check/2,storeindb/2]). %-define(debug,1). -include("asn1_records.hrl"). diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl index 7a28a16877..0bb0b65e5d 100644 --- a/lib/asn1/src/asn1ct_gen.erl +++ b/lib/asn1/src/asn1ct_gen.erl @@ -22,7 +22,7 @@ -include("asn1_records.hrl"). -export([pgen_exports/3, - pgen_hrl/4, + pgen_hrl/5, gen_head/3, demit/1, emit/1, @@ -41,28 +41,29 @@ rt2ct_suffix/0, index2suffix/1, get_record_name_prefix/0]). --export([pgen/4, - pgen_module/5, +-export([pgen/5, + pgen_module/6, mk_var/1, un_hyphen_var/1]). -export([gen_encode_constructed/4, gen_decode_constructed/4]). -%% pgen(Erules, Module, TypeOrVal) +%% pgen(Outfile, Erules, Module, TypeOrVal, Options) %% Generate Erlang module (.erl) and (.hrl) file corresponding to an ASN.1 module %% .hrl file is only generated if necessary %% Erules = per | ber | ber_bin | per_bin %% Module = atom() %% TypeOrVal = {TypeList,ValueList} %% TypeList = ValueList = [atom()] +%% Options = [Options] from asn1ct:compile() -pgen(OutFile,Erules,Module,TypeOrVal) -> - pgen_module(OutFile,Erules,Module,TypeOrVal,true). +pgen(OutFile,Erules,Module,TypeOrVal,Options) -> + pgen_module(OutFile,Erules,Module,TypeOrVal,Options,true). pgen_module(OutFile,Erules,Module, TypeOrVal = {Types,_Values,_Ptypes,_Classes,_Objects,_ObjectSets}, - Indent) -> + Options,Indent) -> N2nConvEnums = [CName|| {n2n,CName} <- get(encoding_options)], case N2nConvEnums -- Types of [] -> @@ -72,7 +73,7 @@ pgen_module(OutFile,Erules,Module, UnmatchedTypes}) end, put(outfile,OutFile), - HrlGenerated = pgen_hrl(Erules,Module,TypeOrVal,Indent), + HrlGenerated = pgen_hrl(Erules,Module,TypeOrVal,Options,Indent), asn1ct_name:start(), ErlFile = lists:concat([OutFile,".erl"]), Fid = fopen(ErlFile,[write]), @@ -86,7 +87,7 @@ pgen_module(OutFile,Erules,Module, % gen_vars(asn1_db:mod_to_vars(Module)), % gen_tag_table(AllTypes), file:close(Fid), - io:format("--~p--~n",[{generated,ErlFile}]). + asn1ct:report_verbose("--~p--~n",[{generated,ErlFile}],Options). pgen_typeorval(Erules,Module,N2nConvEnums,{Types,Values,_Ptypes,_Classes,Objects,ObjectSets}) -> @@ -1315,7 +1316,7 @@ fopen(F, ModeList) -> exit({error,Reason}) end. -pgen_hrl(Erules,Module,TypeOrVal,_Indent) -> +pgen_hrl(Erules,Module,TypeOrVal,Options,_Indent) -> put(currmod,Module), {Types,Values,Ptypes,_,_,_} = TypeOrVal, Ret = @@ -1339,8 +1340,9 @@ pgen_hrl(Erules,Module,TypeOrVal,_Indent) -> Y -> Fid = get(gen_file_out), file:close(Fid), - io:format("--~p--~n", - [{generated,lists:concat([get(outfile),".hrl"])}]), + asn1ct:report_verbose("--~p--~n", + [{generated,lists:concat([get(outfile),".hrl"])}], + Options), Y end. diff --git a/lib/asn1/src/asn1ct_gen_ber.erl b/lib/asn1/src/asn1ct_gen_ber.erl index 8943541303..491ebcb8fd 100644 --- a/lib/asn1/src/asn1ct_gen_ber.erl +++ b/lib/asn1/src/asn1ct_gen_ber.erl @@ -68,7 +68,7 @@ %% TypeList = ValueList = [atom()] pgen(OutFile,Erules,Module,TypeOrVal) -> - asn1ct_gen:pgen_module(OutFile,Erules,Module,TypeOrVal,true). + asn1ct_gen:pgen_module(OutFile,Erules,Module,TypeOrVal,[],true). %%=============================================================================== diff --git a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl index ac232ea710..9ec458e351 100644 --- a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl +++ b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl @@ -68,7 +68,7 @@ %% TypeList = ValueList = [atom()] pgen(OutFile,Erules,Module,TypeOrVal) -> - asn1ct_gen:pgen_module(OutFile,Erules,Module,TypeOrVal,true). + asn1ct_gen:pgen_module(OutFile,Erules,Module,TypeOrVal,[],true). %%=============================================================================== diff --git a/lib/asn1/src/asn1ct_gen_per.erl b/lib/asn1/src/asn1ct_gen_per.erl index a8908db7e4..8313cf1b60 100644 --- a/lib/asn1/src/asn1ct_gen_per.erl +++ b/lib/asn1/src/asn1ct_gen_per.erl @@ -44,7 +44,7 @@ %% TypeList = ValueList = [atom()] pgen(OutFile,Erules,Module,TypeOrVal) -> - asn1ct_gen:pgen_module(OutFile,Erules,Module,TypeOrVal,true). + asn1ct_gen:pgen_module(OutFile,Erules,Module,TypeOrVal,[],true). %% Generate ENCODING ****************************** diff --git a/lib/asn1/src/asn1ct_gen_per_rt2ct.erl b/lib/asn1/src/asn1ct_gen_per_rt2ct.erl index cd05701965..4f4fcfafc3 100644 --- a/lib/asn1/src/asn1ct_gen_per_rt2ct.erl +++ b/lib/asn1/src/asn1ct_gen_per_rt2ct.erl @@ -44,7 +44,7 @@ %% TypeList = ValueList = [atom()] pgen(OutFile,Erules,Module,TypeOrVal) -> - asn1ct_gen:pgen_module(OutFile,Erules,Module,TypeOrVal,true). + asn1ct_gen:pgen_module(OutFile,Erules,Module,TypeOrVal,[],true). %% Generate ENCODING ****************************** diff --git a/lib/asn1/src/asn1rt_uper_bin.erl b/lib/asn1/src/asn1rt_uper_bin.erl index a964b835ae..abe178a69e 100644 --- a/lib/asn1/src/asn1rt_uper_bin.erl +++ b/lib/asn1/src/asn1rt_uper_bin.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 @@ -1611,25 +1611,8 @@ complete_NFP(InList) when is_bitstring(InList) -> %% 10.5.6 NOTE: If "range" satisfies the inequality 2^m < "range" =< %% 2^(m+1) then the number of bits = m + 1 -num_bits(1) -> 0; -num_bits(2) -> 1; -num_bits(R) when R =< 4 -> - 2; -num_bits(R) when R =< 8 -> - 3; -num_bits(R) when R =< 16 -> - 4; -num_bits(R) when R =< 32 -> - 5; -num_bits(R) when R =< 64 -> - 6; -num_bits(R) when R =< 128 -> - 7; -num_bits(R) when R =< 256 -> - 8; -num_bits(R) when R =< 512 -> - 9; -num_bits(R) when R =< 1024 -> - 10; -num_bits(R) -> - 1+num_bits(R bsr 1). + +num_bits(N) -> + num_bits(N,1,0). +num_bits(N,T,B) when N=<T->B; +num_bits(N,T,B) ->num_bits(N,T bsl 1, B+1). diff --git a/lib/asn1/test/Makefile b/lib/asn1/test/Makefile index b065db7de8..e8f65ec70b 100644 --- a/lib/asn1/test/Makefile +++ b/lib/asn1/test/Makefile @@ -1,19 +1,19 @@ # # %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% # # @@ -133,9 +133,7 @@ ERL_FILES= $(MODULES:%=%.erl) HRL_FILES= External.hrl -TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) - -INSTALL_PROGS= $(TARGET_FILES) +EMAKEFILE=Emakefile # ---------------------------------------------------- # Release directory specification @@ -145,19 +143,20 @@ RELSYSDIR = $(RELEASE_PATH)/asn1_test # ---------------------------------------------------- # FLAGS # ---------------------------------------------------- -ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include \ - -I$(ERL_TOP)/lib/kernel/include - +ERL_COMPILE_FLAGS += +warnings_as_errors EBIN = . # ---------------------------------------------------- # Targets # ---------------------------------------------------- -tests debug opt: $(TARGET_FILES) $(SUITE) $(SUITE_BIN) $(SUITE_BIN_V2) +$(EMAKEFILE): $(ERL_FILES) $(HRL_FILES) + $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) $(ERL_FILES) >$(EMAKEFILE) + +tests debug opt: $(SUITE) $(SUITE_BIN) $(SUITE_BIN_V2) $(EMAKEFILE) clean: - rm -f $(TARGET_FILES) $(SUITE) $(SUITE_BIN) $(SUITE_BIN_V2) + rm -f $(SUITE) $(SUITE_BIN) $(SUITE_BIN_V2) rm -f core docs: diff --git a/lib/asn1/test/asn1_SUITE.erl.src b/lib/asn1/test/asn1_SUITE.erl.src index 2cb059fa4e..e1a09adc82 100644 --- a/lib/asn1/test/asn1_SUITE.erl.src +++ b/lib/asn1/test/asn1_SUITE.erl.src @@ -48,7 +48,7 @@ -compile(export_all). %%-export([Function/Arity, ...]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). %% records used by test-case default -record('Def1',{ @@ -2237,10 +2237,11 @@ test_compile_options(Config) -> cover_compiled -> {skip,"Not runnable when cover compiled"}; _ -> - ?line ok = test_compile_options:wrong_path(Config), - ?line ok = test_compile_options:path(Config), - ?line ok = test_compile_options:noobj(Config), - ?line ok = test_compile_options:record_name_prefix(Config) + ?line ok = test_compile_options:wrong_path(Config), + ?line ok = test_compile_options:path(Config), + ?line ok = test_compile_options:noobj(Config), + ?line ok = test_compile_options:record_name_prefix(Config), + ?line ok = test_compile_options:verbose(Config) end. testDoubleEllipses(suite) -> []; testDoubleEllipses(Config) -> diff --git a/lib/asn1/test/asn1_SUITE_data/P-Record.py b/lib/asn1/test/asn1_SUITE_data/P-Record.py index f1db09ac6c..ac3dc9abe0 100644 --- a/lib/asn1/test/asn1_SUITE_data/P-Record.py +++ b/lib/asn1/test/asn1_SUITE_data/P-Record.py @@ -1,44 +1,44 @@ -P-Record DEFINITIONS ::=
-BEGIN
-
-
-PersonnelRecord ::= [APPLICATION 0] SET
-{ name Name,
- title VisibleString,
- number EmployeeNumber,
- dateOfHire Date,
- nameOfSpouse [1] Name,
- children SEQUENCE OF ChildInformation DEFAULT {}
-}
-
-ChildInformation ::= SET
-{ name Name,
- dateOfBirth Date
-}
-
-Name ::= [APPLICATION 1] SEQUENCE
-{ givenName VisibleString,
- initial VisibleString,
- familyName VisibleString
-}
-
-EmployeeNumber ::= [APPLICATION 2] INTEGER
-Date ::= [APPLICATION 3] VisibleString -- YYYY MMDD
+P-Record DEFINITIONS ::= +BEGIN + + +PersonnelRecord ::= [APPLICATION 0] SET +{ name Name, + title VisibleString, + number EmployeeNumber, + dateOfHire Date, + nameOfSpouse [1] Name, + children SEQUENCE OF ChildInformation DEFAULT {} +} + +ChildInformation ::= SET +{ name Name, + dateOfBirth Date +} + +Name ::= [APPLICATION 1] SEQUENCE +{ givenName VisibleString, + initial VisibleString, + familyName VisibleString +} + +EmployeeNumber ::= [APPLICATION 2] INTEGER +Date ::= [APPLICATION 3] VisibleString -- YYYY MMDD v PersonnelRecord ::= { name { - givenName "John",
- initial "P",
- familyName "Smith"
+ givenName "John", + initial "P", + familyName "Smith" }, title "Director", number 51, - dateOfHire "19710917",
+ dateOfHire "19710917", nameOfSpouse { - givenName "Mary",
- initial "T",
- familyName "Smith"
+ givenName "Mary", + initial "T", + familyName "Smith" }, children { {name { diff --git a/lib/asn1/test/asn1_SUITE_data/XSeq.py b/lib/asn1/test/asn1_SUITE_data/XSeq.py index b068ab4393..35b4469440 100644 --- a/lib/asn1/test/asn1_SUITE_data/XSeq.py +++ b/lib/asn1/test/asn1_SUITE_data/XSeq.py @@ -1,42 +1,42 @@ -XSeq DEFINITIONS ::=
-BEGIN
-
--- F.2.10.2
--- Use a sequence type to model a collection of variables whose
--- types are the same,
--- whose number is known and modest, and whose order is significant,
--- provided that the
--- makeup of the collection is unlikely to change from one version
--- of the protocol to the next.
--- EXAMPLE
-
-NamesOfOfficers ::= SEQUENCE {
- president VisibleString,
- vicePresident VisibleString,
- secretary VisibleString}
-
-acmeCorp NamesOfOfficers ::= {
- president "Jane Doe",
- vicePresident "John Doe",
- secretary "Joe Doe"}
-
--- F.2.10.3
--- Use a sequence type to model a collection of variables whose types differ,
--- whose number is known and modest, and whose order is significant,
--- provided that
--- the makeup of the collection is unlikely to change from one version
--- of the protocol to the next.
--- EXAMPLE
-
-Credentials ::= SEQUENCE {
- userName VisibleString,
- password VisibleString,
- accountNumber INTEGER}
-
+XSeq DEFINITIONS ::= +BEGIN + +-- F.2.10.2 +-- Use a sequence type to model a collection of variables whose +-- types are the same, +-- whose number is known and modest, and whose order is significant, +-- provided that the +-- makeup of the collection is unlikely to change from one version +-- of the protocol to the next. +-- EXAMPLE + +NamesOfOfficers ::= SEQUENCE { + president VisibleString, + vicePresident VisibleString, + secretary VisibleString} + +acmeCorp NamesOfOfficers ::= { + president "Jane Doe", + vicePresident "John Doe", + secretary "Joe Doe"} + +-- F.2.10.3 +-- Use a sequence type to model a collection of variables whose types differ, +-- whose number is known and modest, and whose order is significant, +-- provided that +-- the makeup of the collection is unlikely to change from one version +-- of the protocol to the next. +-- EXAMPLE + +Credentials ::= SEQUENCE { + userName VisibleString, + password VisibleString, + accountNumber INTEGER} + -- Empty SEQUENCE stupid but just for test BasicCallCategories ::= SEQUENCE { ... -- So far, no specific categories identified } -END
+END diff --git a/lib/asn1/test/asn1_SUITE_data/XSeqOf.py b/lib/asn1/test/asn1_SUITE_data/XSeqOf.py index f9fee92e56..116bd4a82d 100644 --- a/lib/asn1/test/asn1_SUITE_data/XSeqOf.py +++ b/lib/asn1/test/asn1_SUITE_data/XSeqOf.py @@ -1,19 +1,19 @@ -XSeqOf DEFINITIONS ::=
-BEGIN
-
--- F.2.10.1
--- Use a sequence-of type to model a collection of variables whose
--- types are the same,
--- whose number is large or unpredictable, and whose order is significant.
--- EXAMPLE
-
-NamesOfMemberNations ::= SEQUENCE OF VisibleString
--- in alphabetical order
-
-firstTwo NamesOfMemberNations ::= {"Australia", "Austria"}
+XSeqOf DEFINITIONS ::= +BEGIN + +-- F.2.10.1 +-- Use a sequence-of type to model a collection of variables whose +-- types are the same, +-- whose number is large or unpredictable, and whose order is significant. +-- EXAMPLE + +NamesOfMemberNations ::= SEQUENCE OF VisibleString +-- in alphabetical order + +firstTwo NamesOfMemberNations ::= {"Australia", "Austria"} DayNames1 ::= SEQUENCE SIZE(7) OF VisibleString DayNames2 ::= SEQUENCE SIZE(1..7) OF VisibleString DayNames3 ::= SEQUENCE (SIZE(7)) OF VisibleString DayNames4 ::= SEQUENCE (SIZE(1..7)) OF VisibleString -END
+END diff --git a/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl b/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl index 1cf2eb4088..5fcec23756 100644 --- a/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl +++ b/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl @@ -129,3 +129,4 @@ run3(Erule) -> Val -> ok; _ -> exit({expected,Val, got, Val2}) end. + diff --git a/lib/asn1/test/asn1_app_test.erl b/lib/asn1/test/asn1_app_test.erl index 1ea76426f1..23a7e691e7 100644 --- a/lib/asn1/test/asn1_app_test.erl +++ b/lib/asn1/test/asn1_app_test.erl @@ -18,26 +18,12 @@ %% %% %%---------------------------------------------------------------------- -%% Purpose: Verify the application specifics of the Megaco application +%% Purpose: Verify the application specifics of the asn1 application %%---------------------------------------------------------------------- -module(asn1_app_test). -compile(export_all). -%-include("megaco_test_lib.hrl"). - - -% t() -> megaco_test_lib:t(?MODULE). -% t(Case) -> megaco_test_lib:t({?MODULE, Case}). - - -% %% Test server callbacks -% init_per_testcase(Case, Config) -> -% megaco_test_lib:init_per_testcase(Case, Config). - -% fin_per_testcase(Case, Config) -> -% megaco_test_lib:fin_per_testcase(Case, Config). - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% all(suite) -> diff --git a/lib/asn1/test/asn1_appup_test.erl b/lib/asn1/test/asn1_appup_test.erl index 96197ed963..4a60c814e8 100644 --- a/lib/asn1/test/asn1_appup_test.erl +++ b/lib/asn1/test/asn1_appup_test.erl @@ -18,26 +18,12 @@ %% %% %%---------------------------------------------------------------------- -%% Purpose: Verify the application specifics of the Megaco application +%% Purpose: Verify the application specifics of the asn1 application %%---------------------------------------------------------------------- -module(asn1_appup_test). - +-compile({no_auto_import,[error/1]}). -compile(export_all). -%-include("megaco_test_lib.hrl"). - - -%t() -> megaco_test_lib:t(?MODULE). -%t(Case) -> megaco_test_lib:t({?MODULE, Case}). - - -%% Test server callbacks -% init_per_testcase(Case, Config) -> -% megaco_test_lib:init_per_testcase(Case, Config). - -% fin_per_testcase(Case, Config) -> -% megaco_test_lib:fin_per_testcase(Case, Config). - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% all(suite) -> diff --git a/lib/asn1/test/asn1_test_lib.erl b/lib/asn1/test/asn1_test_lib.erl index 2884c79216..26cbdeb940 100644 --- a/lib/asn1/test/asn1_test_lib.erl +++ b/lib/asn1/test/asn1_test_lib.erl @@ -22,7 +22,7 @@ -export([ticket_7407_compile/2,ticket_7407_code/1, ticket_7678/2, ticket_7708/2, ticket_7763/1, ticket_7876/3]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). ticket_7407_compile(Config,Option) -> diff --git a/lib/asn1/test/bench/README b/lib/asn1/test/bench/README deleted file mode 100644 index 2aa9e4cd70..0000000000 --- a/lib/asn1/test/bench/README +++ /dev/null @@ -1,109 +0,0 @@ -Benchmark framework -------------------- - -This benchmark framework consists of the files: -bench.erl - see bench module below -bench.hrl - Defines some useful macros -all.erl - see all module below - -bench module ------------ - -The module bench is a generic module that measures execution time -of functions in callback modules and writes an html-report on the outcome. - -When you execute the function bench:run/0 it will compile and run all -benchmark modules in the current directory. - -all module ------------ - -In the all module there is a function called releases/0 that you can -edit to contain all your erlang installations and then you can -run your benchmarks on several erlang versions using only one command i.e. -all:run(). - -Requirements on callback modules ---------------------------------- - -* A callback module must be named <callbackModuleName>_bm.erl - -* The module must export the function benchmarks/0 that must return: - {Iterations, [Name1,Name2...]} where Iterations is the number of - times each benchmark should be run. Name1, Name2 and so one are the - name of exported functions in the module. - -* The exported functions Name1 etc. must take one argument i.e. the number - of iterations and should return the atom ok. - -* The functions in a benchmark module should represent different - ways/different sequential algorithms for doing something. And the - result will be how fast they are compared to each other. - -Files created --------------- - -Files that are created in the current directory are *.bmres and -index.html. The file(s) with the extension "bmres" are an intermediate -representation of the benchmark results and is only meant to be read -by the reporting mechanism defined in bench.erl. The index.html file -is the report telling you how good the benchmarks are in comparison to -each other. If you run your test on several erlang releases the -html-file will include the result for all versions. - - -Pitfalls ---------- -To get meaningful measurements, you should make sure that: - -* The total execution time is at least several seconds. - -* That any time spent in setup before entering the measurement loop is very - small compared to the total time. - -* That time spent by the loop itself is small compared to the total execution - time - -Consider the following example of a benchmark function that does -a local function call. - -local_call(0) -> ok; -local_call(Iter) -> - foo(), % Local function call - local_call(Iter-1). - -The problem is that both "foo()" and "local_call(Iter-1)" takes about -the same amount of time. To get meaningful figures you'll need to make -sure that the loop overhead will not be visible. In this case we can -take help of a macro in bench.hrl to repeat the local function call -many times, making sure that time spent calling the local function is -relatively much longer than the time spent iterating. Of course, all -benchmarks in the same module must be repeated the same number of -times; thus external_call will look like - -external_call(0) -> ok; -external_call(Iter) -> - ?rep20(?MODULE:foo()), - external_call(Iter-1). - -This technique is only necessary if the operation we are testing executes -really fast. - -If you for instance want to test a sort routine we can keep it simple: - -sorted(Iter) -> - do_sort(Iter, lists:seq(0, 63)). - -do_sort(0, List) -> ok; -do_sort(Iter, List) -> - lists:sort(List), - do_sort(Iter-1, List). - -The call to lists:seq/2 is only done once. The loop overhead in the -do_sort/2 function is small compared to the execution time of lists:sort/1. - -Error handling ---------------- - -Any error enforced by a callback module will result in exit of the benchmark -program and an errormessage that should give a good idea of what is wrong. diff --git a/lib/asn1/test/bench/RanapASN1.asn b/lib/asn1/test/bench/RanapASN1.asn deleted file mode 100644 index b848aadc84..0000000000 --- a/lib/asn1/test/bench/RanapASN1.asn +++ /dev/null @@ -1,3146 +0,0 @@ -RanapASN1 { -itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) -umts-Access (20) modules (3) ranap (0) version1 (1) ranap-PDU-Descriptions (0)} - -DEFINITIONS AUTOMATIC TAGS ::= - -BEGIN - --- ************************************************************** --- --- Interface Elementary Procedure Class --- --- ************************************************************** - -RANAP-ELEMENTARY-PROCEDURE ::= CLASS { - &InitiatingMessage , - &SuccessfulOutcome OPTIONAL, - &UnsuccessfulOutcome OPTIONAL, - &Outcome OPTIONAL, - &procedureCode ProcedureCode UNIQUE, - &criticality Criticality DEFAULT ignore -} -WITH SYNTAX { - INITIATING MESSAGE &InitiatingMessage - [SUCCESSFUL OUTCOME &SuccessfulOutcome] - [UNSUCCESSFUL OUTCOME &UnsuccessfulOutcome] - [OUTCOME &Outcome] - PROCEDURE CODE &procedureCode - [CRITICALITY &criticality] -} - --- ************************************************************** --- --- Interface PDU Definition --- --- ************************************************************** - -RANAP-PDU ::= CHOICE { - initiatingMessage InitiatingMessage, - successfulOutcome SuccessfulOutcome, - unsuccessfulOutcome UnsuccessfulOutcome, - outcome Outcome, - ... -} - -InitiatingMessage ::= SEQUENCE { - procedureCode RANAP-ELEMENTARY-PROCEDURE.&procedureCode ({RANAP-ELEMENTARY-PROCEDURES}), - criticality RANAP-ELEMENTARY-PROCEDURE.&criticality ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode}), - value RANAP-ELEMENTARY-PROCEDURE.&InitiatingMessage ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode}) -} - -SuccessfulOutcome ::= SEQUENCE { - procedureCode RANAP-ELEMENTARY-PROCEDURE.&procedureCode ({RANAP-ELEMENTARY-PROCEDURES}), - criticality RANAP-ELEMENTARY-PROCEDURE.&criticality ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode}), - value RANAP-ELEMENTARY-PROCEDURE.&SuccessfulOutcome ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode}) -} - -UnsuccessfulOutcome ::= SEQUENCE { - procedureCode RANAP-ELEMENTARY-PROCEDURE.&procedureCode ({RANAP-ELEMENTARY-PROCEDURES}), - criticality RANAP-ELEMENTARY-PROCEDURE.&criticality ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode}), - value RANAP-ELEMENTARY-PROCEDURE.&UnsuccessfulOutcome ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode}) -} - -Outcome ::= SEQUENCE { - procedureCode RANAP-ELEMENTARY-PROCEDURE.&procedureCode ({RANAP-ELEMENTARY-PROCEDURES}), - criticality RANAP-ELEMENTARY-PROCEDURE.&criticality ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode}), - value RANAP-ELEMENTARY-PROCEDURE.&Outcome ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode}) -} - --- ************************************************************** --- --- Interface Elementary Procedure List --- --- ************************************************************** - -RANAP-ELEMENTARY-PROCEDURES RANAP-ELEMENTARY-PROCEDURE ::= { - RANAP-ELEMENTARY-PROCEDURES-CLASS-1 | - RANAP-ELEMENTARY-PROCEDURES-CLASS-2 | - RANAP-ELEMENTARY-PROCEDURES-CLASS-3 , - ... -} - - -RANAP-ELEMENTARY-PROCEDURES-CLASS-1 RANAP-ELEMENTARY-PROCEDURE ::= { - iu-Release | - relocationPreparation | - relocationResourceAllocation | - relocationCancel | - sRNS-ContextTransfer | - securityModeControl | - dataVolumeReport | - reset | - resetResource , - ... -} - -RANAP-ELEMENTARY-PROCEDURES-CLASS-2 RANAP-ELEMENTARY-PROCEDURE ::= { - rAB-ReleaseRequest | - iu-ReleaseRequest | - relocationDetect | - relocationComplete | - paging | - commonID | - cN-InvokeTrace | - cN-DeactivateTrace | - locationReportingControl | - locationReport | - initialUE-Message | - directTransfer | - overloadControl | - errorIndication | - sRNS-DataForward | - forwardSRNS-Context | - privateMessage | - rANAP-Relocation , - ... -} - -RANAP-ELEMENTARY-PROCEDURES-CLASS-3 RANAP-ELEMENTARY-PROCEDURE ::= { - rAB-Assignment , - ... -} - --- ************************************************************** --- --- Interface Elementary Procedures --- --- ************************************************************** - -iu-Release RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE Iu-ReleaseCommand - SUCCESSFUL OUTCOME Iu-ReleaseComplete - PROCEDURE CODE id-Iu-Release - CRITICALITY reject -} - -relocationPreparation RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE RelocationRequired - SUCCESSFUL OUTCOME RelocationCommand - UNSUCCESSFUL OUTCOME RelocationPreparationFailure - PROCEDURE CODE id-RelocationPreparation - CRITICALITY reject -} - -relocationResourceAllocation RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE RelocationRequest - SUCCESSFUL OUTCOME RelocationRequestAcknowledge - UNSUCCESSFUL OUTCOME RelocationFailure - PROCEDURE CODE id-RelocationResourceAllocation - CRITICALITY reject -} - -relocationCancel RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE RelocationCancel - SUCCESSFUL OUTCOME RelocationCancelAcknowledge - PROCEDURE CODE id-RelocationCancel - CRITICALITY reject -} - -sRNS-ContextTransfer RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE SRNS-ContextRequest - SUCCESSFUL OUTCOME SRNS-ContextResponse - PROCEDURE CODE id-SRNS-ContextTransfer - CRITICALITY reject -} - -securityModeControl RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE SecurityModeCommand - SUCCESSFUL OUTCOME SecurityModeComplete - UNSUCCESSFUL OUTCOME SecurityModeReject - PROCEDURE CODE id-SecurityModeControl - CRITICALITY reject -} - -dataVolumeReport RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE DataVolumeReportRequest - SUCCESSFUL OUTCOME DataVolumeReport - PROCEDURE CODE id-DataVolumeReport - CRITICALITY reject -} - - -reset RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE Reset - SUCCESSFUL OUTCOME ResetAcknowledge - PROCEDURE CODE id-Reset - CRITICALITY reject -} - -rAB-ReleaseRequest RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE RAB-ReleaseRequest - PROCEDURE CODE id-RAB-ReleaseRequest - CRITICALITY ignore -} - -iu-ReleaseRequest RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE Iu-ReleaseRequest - PROCEDURE CODE id-Iu-ReleaseRequest - CRITICALITY ignore -} - -relocationDetect RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE RelocationDetect - PROCEDURE CODE id-RelocationDetect - CRITICALITY ignore -} - -relocationComplete RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE RelocationComplete - PROCEDURE CODE id-RelocationComplete - CRITICALITY ignore -} - -paging RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE Paging - PROCEDURE CODE id-Paging - CRITICALITY ignore -} - -commonID RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE CommonID - PROCEDURE CODE id-CommonID - CRITICALITY ignore -} - -cN-InvokeTrace RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE CN-InvokeTrace - PROCEDURE CODE id-CN-InvokeTrace - CRITICALITY ignore -} - -cN-DeactivateTrace RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE CN-DeactivateTrace - PROCEDURE CODE id-CN-DeactivateTrace - CRITICALITY ignore -} - -locationReportingControl RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE LocationReportingControl - PROCEDURE CODE id-LocationReportingControl - CRITICALITY ignore -} - -locationReport RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE LocationReport - PROCEDURE CODE id-LocationReport - CRITICALITY ignore -} - -initialUE-Message RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE InitialUE-Message - PROCEDURE CODE id-InitialUE-Message - CRITICALITY ignore -} - -directTransfer RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE DirectTransfer - PROCEDURE CODE id-DirectTransfer - CRITICALITY ignore -} - -overloadControl RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE Overload - PROCEDURE CODE id-OverloadControl - CRITICALITY ignore -} - -errorIndication RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE ErrorIndication - PROCEDURE CODE id-ErrorIndication - CRITICALITY ignore -} - -sRNS-DataForward RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE SRNS-DataForwardCommand - PROCEDURE CODE id-SRNS-DataForward - CRITICALITY ignore -} - -forwardSRNS-Context RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE ForwardSRNS-Context - PROCEDURE CODE id-ForwardSRNS-Context - CRITICALITY ignore -} - -rAB-Assignment RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE RAB-AssignmentRequest - OUTCOME RAB-AssignmentResponse - PROCEDURE CODE id-RAB-Assignment - CRITICALITY reject -} - -privateMessage RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE PrivateMessage - - PROCEDURE CODE id-privateMessage - CRITICALITY ignore -} - -resetResource RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE ResetResource - SUCCESSFUL OUTCOME ResetResourceAcknowledge - PROCEDURE CODE id-ResetResource - CRITICALITY reject -} - -rANAP-Relocation RANAP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE RANAP-RelocationInformation - PROCEDURE CODE id-RANAP-Relocation - CRITICALITY ignore -} - - - --- ************************************************************** --- --- PDU definitions for RANAP. --- --- ************************************************************** - - ---BEGIN_2 - --- ************************************************************** --- --- Common Container Lists --- --- ************************************************************** - -RAB-IE-ContainerList { RANAP-PROTOCOL-IES : IEsSetParam } ::= ProtocolIE-ContainerList { 1, maxNrOfRABs, {IEsSetParam} } -RAB-IE-ContainerPairList { RANAP-PROTOCOL-IES-PAIR : IEsSetParam } ::= ProtocolIE-ContainerPairList { 1, maxNrOfRABs, {IEsSetParam} } -ProtocolError-IE-ContainerList { RANAP-PROTOCOL-IES : IEsSetParam } ::= ProtocolIE-ContainerList { 1, maxNrOfRABs, {IEsSetParam} } -IuSigConId-IE-ContainerList { RANAP-PROTOCOL-IES : IEsSetParam } ::= ProtocolIE-ContainerList { 1, maxNrOfIuSigConIds, {IEsSetParam} } -DirectTransfer-IE-ContainerList { RANAP-PROTOCOL-IES : IEsSetParam } ::= ProtocolIE-ContainerList { 1, maxNrOfDTs, {IEsSetParam} } - --- ************************************************************** --- --- Iu RELEASE ELEMENTARY PROCEDURE --- --- ************************************************************** - --- ************************************************************** --- --- Iu Release Command --- --- ************************************************************** - -Iu-ReleaseCommand ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {Iu-ReleaseCommandIEs} }, - protocolExtensions ProtocolExtensionContainer { {Iu-ReleaseCommandExtensions} } OPTIONAL, - ... -} - -Iu-ReleaseCommandIEs RANAP-PROTOCOL-IES ::= { - { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }, - ... -} - -Iu-ReleaseCommandExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- Iu Release Complete --- --- ************************************************************** - -Iu-ReleaseComplete ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {Iu-ReleaseCompleteIEs} }, - protocolExtensions ProtocolExtensionContainer { {Iu-ReleaseCompleteExtensions} } OPTIONAL, - ... -} - -Iu-ReleaseCompleteIEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-DataVolumeReportList CRITICALITY ignore TYPE RAB-DataVolumeReportList PRESENCE conditional - -- This group is only present if data volume reporting for PS domain is required -- } | - { ID id-RAB-ReleasedList-IuRelComp CRITICALITY ignore TYPE RAB-ReleasedList-IuRelComp PRESENCE conditional - -- This group is only present for RABs towards the PS domain when sequence numbers are available and when the release was initiated by UTRAN -- } | - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, - ... -} - -RAB-DataVolumeReportList ::= RAB-IE-ContainerList { {RAB-DataVolumeReportItemIEs} } - -RAB-DataVolumeReportItemIEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-DataVolumeReportItem CRITICALITY ignore TYPE RAB-DataVolumeReportItem PRESENCE mandatory }, - ... -} - -RAB-DataVolumeReportItem ::= SEQUENCE { - rAB-ID RAB-ID, - dl-UnsuccessfullyTransmittedDataVolume DataVolumeList OPTIONAL - -- This IE is only present if data volume reporting for PS domain is required --, - iE-Extensions ProtocolExtensionContainer { {RAB-DataVolumeReportItem-ExtIEs} } OPTIONAL, - ... -} - -RAB-DataVolumeReportItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -RAB-ReleasedList-IuRelComp ::= RAB-IE-ContainerList { {RAB-ReleasedItem-IuRelComp-IEs} } - -RAB-ReleasedItem-IuRelComp-IEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-ReleasedItem-IuRelComp CRITICALITY ignore TYPE RAB-ReleasedItem-IuRelComp PRESENCE mandatory }, - ... -} - -RAB-ReleasedItem-IuRelComp ::= SEQUENCE { - rAB-ID RAB-ID, - dL-GTP-PDU-SequenceNumber DL-GTP-PDU-SequenceNumber OPTIONAL - --This IE is only present when available--, - uL-GTP-PDU-SequenceNumber UL-GTP-PDU-SequenceNumber OPTIONAL - --This IE is only present when available--, - iE-Extensions ProtocolExtensionContainer { {RAB-ReleasedItem-IuRelComp-ExtIEs} } OPTIONAL, - ... -} - -RAB-ReleasedItem-IuRelComp-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - - -Iu-ReleaseCompleteExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- RELOCATION PREPARATION ELEMENTARY PROCEDURE --- --- ************************************************************** - --- ************************************************************** --- --- Relocation Required --- --- ************************************************************** - -RelocationRequired ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {RelocationRequiredIEs} }, - protocolExtensions ProtocolExtensionContainer { {RelocationRequiredExtensions} } OPTIONAL, - ... -} - -RelocationRequiredIEs RANAP-PROTOCOL-IES ::= { - { ID id-RelocationType CRITICALITY reject TYPE RelocationType PRESENCE mandatory } | - { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } | - { ID id-SourceID CRITICALITY ignore TYPE SourceID PRESENCE mandatory } | - { ID id-TargetID CRITICALITY reject TYPE TargetID PRESENCE mandatory } | - { ID id-ClassmarkInformation2 CRITICALITY reject TYPE ClassmarkInformation2 PRESENCE conditional - -- This is only present when initiating an inter system handover towards GSM BSC -- } | - { ID id-ClassmarkInformation3 CRITICALITY ignore TYPE ClassmarkInformation3 PRESENCE conditional - -- This is only present when initiating an inter system handover towards GSM BSC -- } | - { ID id-SourceRNC-ToTargetRNC-TransparentContainer - CRITICALITY reject TYPE SourceRNC-ToTargetRNC-TransparentContainer PRESENCE conditional - -- This IE shall be present when initiating relocation of SRNS -- } | - { ID id-OldBSS-ToNewBSS-Information CRITICALITY ignore TYPE OldBSS-ToNewBSS-Information PRESENCE conditional - -- This is only present when initiating an inter system handover towards GSM BSC -- } , - ... -} - -RelocationRequiredExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- Relocation Command --- --- ************************************************************** - -RelocationCommand ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {RelocationCommandIEs} }, - protocolExtensions ProtocolExtensionContainer { {RelocationCommandExtensions} } OPTIONAL, - ... -} - -RelocationCommandIEs RANAP-PROTOCOL-IES ::= { - { ID id-TargetRNC-ToSourceRNC-TransparentContainer - CRITICALITY reject TYPE TargetRNC-ToSourceRNC-TransparentContainer PRESENCE conditional - -- This IE shall be included if it is received by the CN from the relocation target. -- } | - { ID id-L3-Information CRITICALITY ignore TYPE L3-Information PRESENCE conditional - -- This IE shall be included if it is received by the CN from the relocation target. -- } | - { ID id-RAB-RelocationReleaseList CRITICALITY ignore TYPE RAB-RelocationReleaseList PRESENCE optional } | - { ID id-RAB-DataForwardingList CRITICALITY ignore TYPE RAB-DataForwardingList PRESENCE conditional - -- This group if applicable is only present for RABs towards the PS domain -- } | - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, - ... -} - -RAB-RelocationReleaseList ::= RAB-IE-ContainerList { {RAB-RelocationReleaseItemIEs} } - -RAB-RelocationReleaseItemIEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-RelocationReleaseItem CRITICALITY ignore TYPE RAB-RelocationReleaseItem PRESENCE mandatory }, - ... -} - -RAB-RelocationReleaseItem ::= SEQUENCE { - rAB-ID RAB-ID, - iE-Extensions ProtocolExtensionContainer { {RAB-RelocationReleaseItem-ExtIEs} } OPTIONAL, - ... -} - -RAB-RelocationReleaseItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -RAB-DataForwardingList ::= RAB-IE-ContainerList { {RAB-DataForwardingItemIEs} } - -RAB-DataForwardingItemIEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-DataForwardingItem CRITICALITY ignore TYPE RAB-DataForwardingItem PRESENCE mandatory }, - ... -} - -RAB-DataForwardingItem ::= SEQUENCE { - rAB-ID RAB-ID, - transportLayerAddress TransportLayerAddress, - iuTransportAssociation IuTransportAssociation, - iE-Extensions ProtocolExtensionContainer { {RAB-DataForwardingItem-ExtIEs} } OPTIONAL, - ... -} - -RAB-DataForwardingItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -RelocationCommandExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- Relocation Preparation Failure --- --- ************************************************************** - -RelocationPreparationFailure ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {RelocationPreparationFailureIEs} }, - protocolExtensions ProtocolExtensionContainer { {RelocationPreparationFailureExtensions} } OPTIONAL, - ... -} - -RelocationPreparationFailureIEs RANAP-PROTOCOL-IES ::= { - { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } | - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, - ... -} - -RelocationPreparationFailureExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- RELOCATION RESOURCE ALLOCATION ELEMENTARY PROCEDURE --- --- ************************************************************** - --- ************************************************************** --- --- Relocation Request --- --- ************************************************************** - -RelocationRequest ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {RelocationRequestIEs} }, - protocolExtensions ProtocolExtensionContainer { {RelocationRequestExtensions} } OPTIONAL, - ... -} - -RelocationRequestIEs RANAP-PROTOCOL-IES ::= { - { ID id-PermanentNAS-UE-ID CRITICALITY ignore TYPE PermanentNAS-UE-ID PRESENCE conditional - -- This IE is only present if available at the sending side -- } | - { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } | - { ID id-CN-DomainIndicator CRITICALITY reject TYPE CN-DomainIndicator PRESENCE mandatory } | - { ID id-SourceRNC-ToTargetRNC-TransparentContainer - CRITICALITY reject TYPE SourceRNC-ToTargetRNC-TransparentContainer PRESENCE mandatory } | - { ID id-RAB-SetupList-RelocReq CRITICALITY reject TYPE RAB-SetupList-RelocReq PRESENCE optional } | - { ID id-IntegrityProtectionInformation CRITICALITY ignore TYPE IntegrityProtectionInformation PRESENCE conditional - -- This IE is only present if available at the sending side -- } | - { ID id-EncryptionInformation CRITICALITY ignore TYPE EncryptionInformation PRESENCE optional } | - { ID id-IuSigConId CRITICALITY ignore TYPE IuSignallingConnectionIdentifier PRESENCE mandatory }, - ... -} - -RAB-SetupList-RelocReq ::= RAB-IE-ContainerList { {RAB-SetupItem-RelocReq-IEs} } - -RAB-SetupItem-RelocReq-IEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-SetupItem-RelocReq CRITICALITY reject TYPE RAB-SetupItem-RelocReq PRESENCE mandatory }, - ... -} - -RAB-SetupItem-RelocReq ::= SEQUENCE { - rAB-ID RAB-ID, - nAS-SynchronisationIndicator NAS-SynchronisationIndicator OPTIONAL - -- This IE is present if the relevant NAS information is provided by the CN --, - rAB-Parameters RAB-Parameters, - dataVolumeReportingIndication DataVolumeReportingIndication OPTIONAL - -- This IE, if applicable, is only present for RABs towards the PS domain --, - pDP-TypeInformation PDP-TypeInformation OPTIONAL - -- This IE is only present for RABs towards the PS domain --, - userPlaneInformation UserPlaneInformation, - transportLayerAddress TransportLayerAddress, - iuTransportAssociation IuTransportAssociation, - service-Handover Service-Handover OPTIONAL, - iE-Extensions ProtocolExtensionContainer { {RAB-SetupItem-RelocReq-ExtIEs} } OPTIONAL, - ... -} - -RAB-SetupItem-RelocReq-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -UserPlaneInformation ::= SEQUENCE { - userPlaneMode UserPlaneMode, - uP-ModeVersions UP-ModeVersions, - iE-Extensions ProtocolExtensionContainer { {UserPlaneInformation-ExtIEs} } OPTIONAL, - ... -} - -UserPlaneInformation-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -RelocationRequestExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- Relocation Request Acknowledge --- --- ************************************************************** - -RelocationRequestAcknowledge ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {RelocationRequestAcknowledgeIEs} }, - protocolExtensions ProtocolExtensionContainer { {RelocationRequestAcknowledgeExtensions} } OPTIONAL, - ... -} - -RelocationRequestAcknowledgeIEs RANAP-PROTOCOL-IES ::= { - { ID id-TargetRNC-ToSourceRNC-TransparentContainer - CRITICALITY ignore TYPE TargetRNC-ToSourceRNC-TransparentContainer PRESENCE conditional - -- Must be included if applicapble and if not sent via the other CN -- } | - { ID id-RAB-SetupList-RelocReqAck CRITICALITY ignore TYPE RAB-SetupList-RelocReqAck PRESENCE optional} | - { ID id-RAB-FailedList CRITICALITY ignore TYPE RAB-FailedList PRESENCE optional }| - { ID id-ChosenIntegrityProtectionAlgorithm CRITICALITY ignore TYPE ChosenIntegrityProtectionAlgorithm PRESENCE conditional - -- This IE is only present if available at the sending side -- } | - { ID id-ChosenEncryptionAlgorithm CRITICALITY ignore TYPE ChosenEncryptionAlgorithm PRESENCE optional } | - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, - ... -} - -RAB-SetupList-RelocReqAck ::= RAB-IE-ContainerList { {RAB-SetupItem-RelocReqAck-IEs} } - -RAB-SetupItem-RelocReqAck-IEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-SetupItem-RelocReqAck CRITICALITY reject TYPE RAB-SetupItem-RelocReqAck PRESENCE mandatory }, - ... -} - -RAB-SetupItem-RelocReqAck ::= SEQUENCE { - rAB-ID RAB-ID, - transportLayerAddress TransportLayerAddress OPTIONAL, - --This IE is only present for RABS towards the PS Domain - iuTransportAssociation IuTransportAssociation OPTIONAL, - --This IE is only present for RABS towards the PS Domain - iE-Extensions ProtocolExtensionContainer { {RAB-SetupItem-RelocReqAck-ExtIEs} } OPTIONAL, - ... -} - -RAB-SetupItem-RelocReqAck-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -RAB-FailedList ::= RAB-IE-ContainerList { {RAB-FailedItemIEs} } - -RAB-FailedItemIEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-FailedItem CRITICALITY ignore TYPE RAB-FailedItem PRESENCE mandatory }, - ... -} - -RAB-FailedItem ::= SEQUENCE { - rAB-ID RAB-ID, - cause Cause, - iE-Extensions ProtocolExtensionContainer { {RAB-FailedItem-ExtIEs} } OPTIONAL, - ... -} - -RAB-FailedItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -RelocationRequestAcknowledgeExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- Relocation Failure --- --- ************************************************************** - -RelocationFailure ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {RelocationFailureIEs} }, - protocolExtensions ProtocolExtensionContainer { {RelocationFailureExtensions} } OPTIONAL, - ... -} - -RelocationFailureIEs RANAP-PROTOCOL-IES ::= { - { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } | - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, - ... -} - -RelocationFailureExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- RELOCATION CANCEL ELEMENTARY PROCEDURE --- --- ************************************************************** - --- ************************************************************** --- --- Relocation Cancel --- --- ************************************************************** - -RelocationCancel ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {RelocationCancelIEs} }, - protocolExtensions ProtocolExtensionContainer { {RelocationCancelExtensions} } OPTIONAL, - ... -} - -RelocationCancelIEs RANAP-PROTOCOL-IES ::= { - { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }, - ... -} - -RelocationCancelExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- Relocation Cancel Acknowledge --- --- ************************************************************** - -RelocationCancelAcknowledge ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {RelocationCancelAcknowledgeIEs} }, - protocolExtensions ProtocolExtensionContainer { {RelocationCancelAcknowledgeExtensions} } OPTIONAL, - ... -} - -RelocationCancelAcknowledgeIEs RANAP-PROTOCOL-IES ::= { - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, - ... -} - -RelocationCancelAcknowledgeExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- SRNS CONTEXT TRANSFER OPEARATION --- --- ************************************************************** - --- ************************************************************** --- --- SRNS Context Request --- --- ************************************************************** - -SRNS-ContextRequest ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {SRNS-ContextRequestIEs} }, - protocolExtensions ProtocolExtensionContainer { {SRNS-ContextRequestExtensions} } OPTIONAL, - ... -} - -SRNS-ContextRequestIEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-DataForwardingList-SRNS-CtxReq CRITICALITY ignore TYPE RAB-DataForwardingList-SRNS-CtxReq PRESENCE mandatory }, - ... -} - -RAB-DataForwardingList-SRNS-CtxReq ::= RAB-IE-ContainerList { {RAB-DataForwardingItem-SRNS-CtxReq-IEs} } - -RAB-DataForwardingItem-SRNS-CtxReq-IEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-DataForwardingItem-SRNS-CtxReq CRITICALITY reject TYPE RAB-DataForwardingItem-SRNS-CtxReq PRESENCE mandatory }, - ... -} - -RAB-DataForwardingItem-SRNS-CtxReq ::= SEQUENCE { - rAB-ID RAB-ID, - iE-Extensions ProtocolExtensionContainer { {RAB-DataForwardingItem-SRNS-CtxReq-ExtIEs} } OPTIONAL, - ... -} - -RAB-DataForwardingItem-SRNS-CtxReq-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -SRNS-ContextRequestExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- SRNS Context Response --- --- ************************************************************** - -SRNS-ContextResponse ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {SRNS-ContextResponseIEs} }, - protocolExtensions ProtocolExtensionContainer { {SRNS-ContextResponseExtensions} } OPTIONAL, - ... -} - -SRNS-ContextResponseIEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-ContextList CRITICALITY ignore TYPE RAB-ContextList PRESENCE conditional - -- This group must be present at least when no other group is present, ie. at least one group must be present -- } | - { ID id-RAB-ContextFailedtoTransferList CRITICALITY ignore TYPE RAB-ContextFailedtoTransferList PRESENCE conditional - -- This group must be present at least when no other group is present, ie. at least one group must be present -- }| - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, - ... -} - -RAB-ContextList ::= RAB-IE-ContainerList { {RAB-ContextItemIEs} } - -RAB-ContextItemIEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-ContextItem CRITICALITY ignore TYPE RAB-ContextItem PRESENCE mandatory }, - ... -} - -RAB-ContextItem ::= SEQUENCE { - rAB-ID RAB-ID, - dl-GTP-PDU-SequenceNumber DL-GTP-PDU-SequenceNumber OPTIONAL - --This IE is only present when available--, - ul-GTP-PDU-SequenceNumber UL-GTP-PDU-SequenceNumber OPTIONAL - --This IE is only present when available--, - dl-N-PDU-SequenceNumber DL-N-PDU-SequenceNumber OPTIONAL - --This IE is only present when available--, - ul-N-PDU-SequenceNumber UL-N-PDU-SequenceNumber OPTIONAL - --This IE is only present when available--, - iE-Extensions ProtocolExtensionContainer { {RAB-ContextItem-ExtIEs} } OPTIONAL, - ... -} - -RAB-ContextItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -RAB-ContextFailedtoTransferList ::= RAB-IE-ContainerList { {RABs-ContextFailedtoTransferItemIEs} } - -RABs-ContextFailedtoTransferItemIEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-ContextFailedtoTransferItem CRITICALITY ignore TYPE RABs-ContextFailedtoTransferItem PRESENCE mandatory }, - ... -} - -RABs-ContextFailedtoTransferItem::= SEQUENCE { - rAB-ID RAB-ID, - cause Cause, - iE-Extensions ProtocolExtensionContainer { { RABs-ContextFailedtoTransferItem-ExtIEs} } OPTIONAL, - ... -} - - -RABs-ContextFailedtoTransferItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -SRNS-ContextResponseExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- SECURITY MODE CONTROL ELEMENTARY PROCEDURE --- --- ************************************************************** - --- ************************************************************** --- --- Security Mode Command --- --- ************************************************************** - -SecurityModeCommand ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {SecurityModeCommandIEs} }, - protocolExtensions ProtocolExtensionContainer { {SecurityModeCommandExtensions} } OPTIONAL, - ... -} - -SecurityModeCommandIEs RANAP-PROTOCOL-IES ::= { - { ID id-IntegrityProtectionInformation CRITICALITY reject TYPE IntegrityProtectionInformation PRESENCE mandatory } | - { ID id-EncryptionInformation CRITICALITY ignore TYPE EncryptionInformation PRESENCE optional } | - { ID id-KeyStatus CRITICALITY reject TYPE KeyStatus PRESENCE mandatory}, - ... -} - -SecurityModeCommandExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- Security Mode Complete --- --- ************************************************************** - -SecurityModeComplete ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {SecurityModeCompleteIEs} }, - protocolExtensions ProtocolExtensionContainer { {SecurityModeCompleteExtensions} } OPTIONAL, - ... -} - -SecurityModeCompleteIEs RANAP-PROTOCOL-IES ::= { - { ID id-ChosenIntegrityProtectionAlgorithm CRITICALITY reject TYPE ChosenIntegrityProtectionAlgorithm PRESENCE mandatory } | - { ID id-ChosenEncryptionAlgorithm CRITICALITY ignore TYPE ChosenEncryptionAlgorithm PRESENCE optional } | - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, - ... -} - -SecurityModeCompleteExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- Security Mode Reject --- --- ************************************************************** - -SecurityModeReject ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {SecurityModeRejectIEs} }, - protocolExtensions ProtocolExtensionContainer { {SecurityModeRejectExtensions} } OPTIONAL, - ... -} - -SecurityModeRejectIEs RANAP-PROTOCOL-IES ::= { - { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } | - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, - ... -} - -SecurityModeRejectExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- DATA VOLUME REPORT ELEMENTARY PROCEDURE --- --- ************************************************************** - --- ************************************************************** --- --- Data Volume Report Request --- --- ************************************************************** - -DataVolumeReportRequest ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {DataVolumeReportRequestIEs} }, - protocolExtensions ProtocolExtensionContainer { {DataVolumeReportRequestExtensions} } OPTIONAL, - ... -} - -DataVolumeReportRequestIEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-DataVolumeReportRequestList CRITICALITY ignore TYPE RAB-DataVolumeReportRequestList PRESENCE mandatory }, - ... -} - -RAB-DataVolumeReportRequestList ::= RAB-IE-ContainerList { {RAB-DataVolumeReportRequestItemIEs} } - -RAB-DataVolumeReportRequestItemIEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-DataVolumeReportRequestItem CRITICALITY reject TYPE RAB-DataVolumeReportRequestItem PRESENCE mandatory }, - ... -} - -RAB-DataVolumeReportRequestItem ::= SEQUENCE { - rAB-ID RAB-ID, - iE-Extensions ProtocolExtensionContainer { {RAB-DataVolumeReportRequestItem-ExtIEs} } OPTIONAL, - ... -} - -RAB-DataVolumeReportRequestItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -DataVolumeReportRequestExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- Data Volume Report --- --- ************************************************************** - -DataVolumeReport ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {DataVolumeReportIEs} }, - protocolExtensions ProtocolExtensionContainer { {DataVolumeReportExtensions} } OPTIONAL, - ... -} - -DataVolumeReportIEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-DataVolumeReportList CRITICALITY ignore TYPE RAB-DataVolumeReportList PRESENCE conditional - -- This group must be present at least when no other group is present, ie. at least one group must be present -- } | - { ID id-RAB-FailedtoReportList CRITICALITY ignore TYPE RAB-FailedtoReportList PRESENCE conditional - -- This group must be present at least when no other group is present, ie. at least one group must be present -- } | - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, - ... -} - -DataVolumeReportExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -RAB-FailedtoReportList ::= RAB-IE-ContainerList { {RABs-failed-to-reportItemIEs} } - -RABs-failed-to-reportItemIEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-FailedtoReportItem CRITICALITY ignore TYPE RABs-failed-to-reportItem PRESENCE mandatory }, - ... -} - -RABs-failed-to-reportItem::= SEQUENCE { - rAB-ID RAB-ID, - cause Cause, - iE-Extensions ProtocolExtensionContainer { { RABs-failed-to-reportItem-ExtIEs} } OPTIONAL, - ... -} - - -RABs-failed-to-reportItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - - --- ************************************************************** --- --- RESET ELEMENTARY PROCEDURE --- --- ************************************************************** - --- ************************************************************** --- --- Reset --- --- ************************************************************** - -Reset ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {ResetIEs} }, - protocolExtensions ProtocolExtensionContainer { {ResetExtensions} } OPTIONAL, - ... -} - -ResetIEs RANAP-PROTOCOL-IES ::= { - { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } | - { ID id-CN-DomainIndicator CRITICALITY reject TYPE CN-DomainIndicator PRESENCE mandatory } | - { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE conditional - -- This IE is always used in the uplink direction -- }, - ... -} - -ResetExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- Reset Acknowledge --- --- ************************************************************** - -ResetAcknowledge ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {ResetAcknowledgeIEs} }, - protocolExtensions ProtocolExtensionContainer { {ResetAcknowledgeExtensions} } OPTIONAL, - ... -} - -ResetAcknowledgeIEs RANAP-PROTOCOL-IES ::= { - { ID id-CN-DomainIndicator CRITICALITY reject TYPE CN-DomainIndicator PRESENCE mandatory } | - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } | - { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE conditional - -- This IE is always used in the uplink direction -- }, - ... -} - -ResetAcknowledgeExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} --- ************************************************************** --- --- RESET RESOURCE ELEMENTARY PROCEDURE --- --- ************************************************************** - - --- ************************************************************** --- --- Reset Resource --- --- ************************************************************** - -ResetResource ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {ResetResourceIEs} }, - protocolExtensions ProtocolExtensionContainer { {ResetResourceExtensions} } OPTIONAL, - ... -} - -ResetResourceIEs RANAP-PROTOCOL-IES ::= { - { ID id-CN-DomainIndicator CRITICALITY reject TYPE CN-DomainIndicator PRESENCE mandatory } | - { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } | - { ID id-IuSigConIdList CRITICALITY ignore TYPE ResetResourceList PRESENCE mandatory } | - { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE conditional - -- This IE is always used in the uplink direction -- }, - ... -} - -ResetResourceList ::= IuSigConId-IE-ContainerList{ {ResetResourceItemIEs} } - -ResetResourceItemIEs RANAP-PROTOCOL-IES ::= { - { ID id-IuSigConIdItem CRITICALITY reject TYPE ResetResourceItem PRESENCE mandatory }, - ... -} - -ResetResourceItem ::= SEQUENCE { - iuSigConId IuSignallingConnectionIdentifier, - iE-Extensions ProtocolExtensionContainer { { ResetResourceItem-ExtIEs} } OPTIONAL, - ... -} - -ResetResourceItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -ResetResourceExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- Reset Resource Acknowledge --- --- ************************************************************** - -ResetResourceAcknowledge ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {ResetResourceAcknowledgeIEs} }, - protocolExtensions ProtocolExtensionContainer { {ResetResourceAcknowledgeExtensions} } OPTIONAL, - ... -} - -ResetResourceAcknowledgeIEs RANAP-PROTOCOL-IES ::= { - { ID id-CN-DomainIndicator CRITICALITY reject TYPE CN-DomainIndicator PRESENCE mandatory } | - { ID id-IuSigConIdList CRITICALITY ignore TYPE ResetResourceAckList PRESENCE mandatory } | - { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE conditional - -- This IE is always used in the uplink direction -- } | - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, - ... -} -ResetResourceAckList ::= IuSigConId-IE-ContainerList{ {ResetResourceAckItemIEs} } - -ResetResourceAckItemIEs RANAP-PROTOCOL-IES ::= { - { ID id-IuSigConIdItem CRITICALITY reject TYPE ResetResourceAckItem PRESENCE mandatory }, - ... -} - -ResetResourceAckItem ::= SEQUENCE { - iuSigConId IuSignallingConnectionIdentifier, - iE-Extensions ProtocolExtensionContainer { { ResetResourceAckItem-ExtIEs} } OPTIONAL, - ... -} - -ResetResourceAckItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -ResetResourceAcknowledgeExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- RAB RELEASE REQUEST ELEMENTARY PROCEDURE --- --- ************************************************************** - --- ************************************************************** --- --- RAB Release Request --- --- ************************************************************** - -RAB-ReleaseRequest ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {RAB-ReleaseRequestIEs} }, - protocolExtensions ProtocolExtensionContainer { {RAB-ReleaseRequestExtensions} } OPTIONAL, - ... -} - -RAB-ReleaseRequestIEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-ReleaseList CRITICALITY ignore TYPE RAB-ReleaseList PRESENCE mandatory }, - ... -} - -RAB-ReleaseList ::= RAB-IE-ContainerList { {RAB-ReleaseItemIEs} } - -RAB-ReleaseItemIEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-ReleaseItem CRITICALITY ignore TYPE RAB-ReleaseItem PRESENCE mandatory }, - ... -} - -RAB-ReleaseItem ::= SEQUENCE { - rAB-ID RAB-ID, - cause Cause, - iE-Extensions ProtocolExtensionContainer { {RAB-ReleaseItem-ExtIEs} } OPTIONAL, - ... -} - -RAB-ReleaseItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -RAB-ReleaseRequestExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- Iu RELEASE REQUEST ELEMENTARY PROCEDURE --- --- ************************************************************** - --- ************************************************************** --- --- Iu Release Request --- --- ************************************************************** - -Iu-ReleaseRequest ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {Iu-ReleaseRequestIEs} }, - protocolExtensions ProtocolExtensionContainer { {Iu-ReleaseRequestExtensions} } OPTIONAL, - ... -} - -Iu-ReleaseRequestIEs RANAP-PROTOCOL-IES ::= { - { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }, - ... -} - -Iu-ReleaseRequestExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- RELOCATION DETECT ELEMENTARY PROCEDURE --- --- ************************************************************** - --- ************************************************************** --- --- Relocation Detect --- --- ************************************************************** - -RelocationDetect ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {RelocationDetectIEs} }, - protocolExtensions ProtocolExtensionContainer { {RelocationDetectExtensions} } OPTIONAL, - ... -} - -RelocationDetectIEs RANAP-PROTOCOL-IES ::= { - ... -} - -RelocationDetectExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- RELOCATION COMPLETE ELEMENTARY PROCEDURE --- --- ************************************************************** - --- ************************************************************** --- --- Relocation Complete --- --- ************************************************************** - -RelocationComplete ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {RelocationCompleteIEs} }, - protocolExtensions ProtocolExtensionContainer { {RelocationCompleteExtensions} } OPTIONAL, - ... -} - -RelocationCompleteIEs RANAP-PROTOCOL-IES ::= { - ... -} - -RelocationCompleteExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- PAGING ELEMENTARY PROCEDURE --- --- ************************************************************** - --- ************************************************************** --- --- Paging --- --- ************************************************************** - -Paging ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {PagingIEs} }, - protocolExtensions ProtocolExtensionContainer { {PagingExtensions} } OPTIONAL, - ... -} - -PagingIEs RANAP-PROTOCOL-IES ::= { - { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE mandatory } | - { ID id-PermanentNAS-UE-ID CRITICALITY ignore TYPE PermanentNAS-UE-ID PRESENCE mandatory } | - { ID id-TemporaryUE-ID CRITICALITY ignore TYPE TemporaryUE-ID PRESENCE optional } | - { ID id-PagingAreaID CRITICALITY ignore TYPE PagingAreaID PRESENCE optional } | - { ID id-PagingCause CRITICALITY ignore TYPE PagingCause PRESENCE optional } | - { ID id-NonSearchingIndication CRITICALITY ignore TYPE NonSearchingIndication PRESENCE optional } | - { ID id-DRX-CycleLengthCoefficient CRITICALITY ignore TYPE DRX-CycleLengthCoefficient PRESENCE conditional - -- This IE shall be included whenever available for that UE -- } , - ... -} - -PagingExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- COMMON ID ELEMENTARY PROCEDURE --- --- ************************************************************** - --- ************************************************************** --- --- Common ID --- --- ************************************************************** - -CommonID ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {CommonID-IEs} }, - protocolExtensions ProtocolExtensionContainer { {CommonIDExtensions} } OPTIONAL, - ... -} - -CommonID-IEs RANAP-PROTOCOL-IES ::= { - { ID id-PermanentNAS-UE-ID CRITICALITY ignore TYPE PermanentNAS-UE-ID PRESENCE mandatory }, - ... -} - -CommonIDExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- CN INVOKE TRACE ELEMENTARY PROCEDURE --- --- ************************************************************** - --- ************************************************************** --- --- CN Invoke Trace --- --- ************************************************************** - -CN-InvokeTrace ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {CN-InvokeTraceIEs} }, - protocolExtensions ProtocolExtensionContainer { {CN-InvokeTraceExtensions} } OPTIONAL, - ... -} - -CN-InvokeTraceIEs RANAP-PROTOCOL-IES ::= { - { ID id-TraceType CRITICALITY ignore TYPE TraceType PRESENCE mandatory } | - { ID id-TraceReference CRITICALITY ignore TYPE TraceReference PRESENCE mandatory } | - { ID id-TriggerID CRITICALITY ignore TYPE TriggerID PRESENCE optional } | - { ID id-UE-ID CRITICALITY ignore TYPE UE-ID PRESENCE optional } | - { ID id-OMC-ID CRITICALITY ignore TYPE OMC-ID PRESENCE optional }, - ... -} - -CN-InvokeTraceExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- CN DEACTIVATE TRACE ELEMENTARY PROCEDURE --- --- ************************************************************** - --- ************************************************************** --- --- CN Deactivate Trace --- --- ************************************************************** - -CN-DeactivateTrace ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {CN-DeactivateTraceIEs} }, - protocolExtensions ProtocolExtensionContainer { {CN-DeactivateTraceExtensions} } OPTIONAL, - ... -} - -CN-DeactivateTraceIEs RANAP-PROTOCOL-IES ::= { - { ID id-TraceReference CRITICALITY ignore TYPE TraceReference PRESENCE mandatory } | - { ID id-TriggerID CRITICALITY ignore TYPE TriggerID PRESENCE optional }, - ... -} - -CN-DeactivateTraceExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- LOCATION REPORTING CONTROL ELEMENTARY PROCEDURE --- --- ************************************************************** - --- ************************************************************** --- --- Location Reporting Control --- --- ************************************************************** - -LocationReportingControl ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {LocationReportingControlIEs} }, - protocolExtensions ProtocolExtensionContainer { {LocationReportingControlExtensions} } OPTIONAL, - ... -} - -LocationReportingControlIEs RANAP-PROTOCOL-IES ::= { - { ID id-RequestType CRITICALITY ignore TYPE RequestType PRESENCE mandatory }, - ... -} - -LocationReportingControlExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- LOCATION REPORT ELEMENTARY PROCEDURE --- --- ************************************************************** - --- ************************************************************** --- --- Location Report --- --- ************************************************************** - -LocationReport ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {LocationReportIEs} }, - protocolExtensions ProtocolExtensionContainer { {LocationReportExtensions} } OPTIONAL, - ... -} - -LocationReportIEs RANAP-PROTOCOL-IES ::= { - { ID id-AreaIdentity CRITICALITY ignore TYPE AreaIdentity PRESENCE optional } | - { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE optional } | - { ID id-RequestType CRITICALITY ignore TYPE RequestType PRESENCE conditional - -- This IE shall be present when Cause IE is present and has value "Requested Report Type not supported" --} , - ... -} - -LocationReportExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- INITIAL UE MESSAGE ELEMENTARY PROCEDURE --- --- ************************************************************** - --- ************************************************************** --- --- Initial UE Message --- --- ************************************************************** - -InitialUE-Message ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {InitialUE-MessageIEs} }, - protocolExtensions ProtocolExtensionContainer { {InitialUE-MessageExtensions} } OPTIONAL, - ... -} - -InitialUE-MessageIEs RANAP-PROTOCOL-IES ::= { - { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE mandatory } | - { ID id-LAI CRITICALITY ignore TYPE LAI PRESENCE mandatory } | - { ID id-RAC CRITICALITY ignore TYPE RAC PRESENCE conditional - -- This IE is only present for RABs towards the PS domain -- } | - { ID id-SAI CRITICALITY ignore TYPE SAI PRESENCE mandatory } | - { ID id-NAS-PDU CRITICALITY ignore TYPE NAS-PDU PRESENCE mandatory } | - { ID id-IuSigConId CRITICALITY ignore TYPE IuSignallingConnectionIdentifier PRESENCE mandatory } | - { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE mandatory }, - - ... -} - -InitialUE-MessageExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- DIRECT TRANSFER ELEMENTARY PROCEDURE --- --- ************************************************************** - --- ************************************************************** --- --- Direct Transfer --- --- ************************************************************** - -DirectTransfer ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {DirectTransferIEs} }, - protocolExtensions ProtocolExtensionContainer { {DirectTransferExtensions} } OPTIONAL, - ... -} - -DirectTransferIEs RANAP-PROTOCOL-IES ::= { - { ID id-NAS-PDU CRITICALITY ignore TYPE NAS-PDU PRESENCE mandatory } | - { ID id-LAI CRITICALITY ignore TYPE LAI PRESENCE conditional - -- This IE is only present if the message is directed to the PS domain -- } | - { ID id-RAC CRITICALITY ignore TYPE RAC PRESENCE conditional - -- This IE is only present if the message is directed to the PS domain -- } | - { ID id-SAI CRITICALITY ignore TYPE SAI PRESENCE conditional - -- This IE is only present if the message is directed to the PS domain -- } | - { ID id-SAPI CRITICALITY ignore TYPE SAPI PRESENCE conditional - -- This IE is always used in downlink direction-- }, - ... -} - -DirectTransferExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- OVERLOAD CONTROL ELEMENTARY PROCEDURE --- --- ************************************************************** - --- ************************************************************** --- --- Overload --- --- ************************************************************** - -Overload ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {OverloadIEs} }, - protocolExtensions ProtocolExtensionContainer { {OverloadExtensions} } OPTIONAL, - ... -} - -OverloadIEs RANAP-PROTOCOL-IES ::= { - { ID id-NumberOfSteps CRITICALITY ignore TYPE NumberOfSteps PRESENCE optional } | - { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE conditional - -- This IE is always used in the uplink direction -- }, - ... -} - -OverloadExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- ERROR INDICATION ELEMENTARY PROCEDURE --- --- ************************************************************** - --- ************************************************************** --- --- Error Indication --- --- ************************************************************** - -ErrorIndication ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {ErrorIndicationIEs} }, - protocolExtensions ProtocolExtensionContainer { {ErrorIndicationExtensions} } OPTIONAL, - ... -} - -ErrorIndicationIEs RANAP-PROTOCOL-IES ::= { - { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE conditional - -- At least either of Cause IE or Criticality IE shall be present -- } | - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE conditional - -- At least either of Cause IE or Criticality IE shall be present -- } | - { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE optional } | - { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE conditional - -- This IE is always used in the uplink direction when message is sent connectionless -- }, - ... -} - -ErrorIndicationExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- SRNS DATA FORWARD ELEMENTARY PROCEDURE --- --- ************************************************************** - --- ************************************************************** --- --- SRNS Data Forward Command --- --- ************************************************************** - -SRNS-DataForwardCommand ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {SRNS-DataForwardCommandIEs} }, - protocolExtensions ProtocolExtensionContainer { {SRNS-DataForwardCommandExtensions} } OPTIONAL, - ... -} - -SRNS-DataForwardCommandIEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-DataForwardingList CRITICALITY ignore TYPE RAB-DataForwardingList PRESENCE conditional - -- This group is only present for RABs towards the PS domain -- }, - ... -} - -SRNS-DataForwardCommandExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- FORWARD SRNS CONTEXT ELEMENTARY PROCEDURE --- --- ************************************************************** - --- ************************************************************** --- --- Forward SRNS Context --- --- ************************************************************** - -ForwardSRNS-Context ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {ForwardSRNS-ContextIEs} }, - protocolExtensions ProtocolExtensionContainer { {ForwardSRNS-ContextExtensions} } OPTIONAL, - ... -} - -ForwardSRNS-ContextIEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-ContextList CRITICALITY ignore TYPE RAB-ContextList PRESENCE mandatory }, - ... -} - -ForwardSRNS-ContextExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- RAB ASSIGNMENT ELEMENTARY PROCEDURE --- --- ************************************************************** - --- ************************************************************** --- --- RAB Assignment Request --- --- ************************************************************** - -RAB-AssignmentRequest ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {RAB-AssignmentRequestIEs} }, - protocolExtensions ProtocolExtensionContainer { {RAB-AssignmentRequestExtensions} } OPTIONAL, - ... -} - -RAB-AssignmentRequestIEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-SetupOrModifyList CRITICALITY ignore TYPE RAB-SetupOrModifyList PRESENCE conditional - -- This group must be present at least when no other group is present, ie. at least one group must be present -- } | - { ID id-RAB-ReleaseList CRITICALITY ignore TYPE RAB-ReleaseList PRESENCE conditional - -- This group must be present at least when no other group is present, ie. at least one group must be present -- }, - ... -} - -RAB-SetupOrModifyList ::= RAB-IE-ContainerPairList { {RAB-SetupOrModifyItem-IEs} } - -RAB-SetupOrModifyItem-IEs RANAP-PROTOCOL-IES-PAIR ::= { - { ID id-RAB-SetupOrModifyItem FIRST CRITICALITY reject FIRST TYPE RAB-SetupOrModifyItemFirst - SECOND CRITICALITY ignore SECOND TYPE RAB-SetupOrModifyItemSecond - PRESENCE mandatory }, - ... -} - -RAB-SetupOrModifyItemFirst ::= SEQUENCE { - rAB-ID RAB-ID, - nAS-SynchronisationIndicator NAS-SynchronisationIndicator OPTIONAL - -- This IE is present at a RAB modification if the relevant NAS information is provided by the CN --, - rAB-Parameters RAB-Parameters OPTIONAL - -- This IE is present at a RAB establishment or when any previously set value shall be modified at a RAB modification --, - userPlaneInformation UserPlaneInformation OPTIONAL - -- This IE is present at a RAB establishment or when any previously set value shall be modified at a RAB modification --, - transportLayerInformation TransportLayerInformation OPTIONAL - -- This IE is present at a RAB establishment, and may be present at a RAB modification if at least one more IE than the RAB ID IE and the NAS Syncronisation Indicator IE is also included --, - service-Handover Service-Handover OPTIONAL, - iE-Extensions ProtocolExtensionContainer { {RAB-SetupOrModifyItemFirst-ExtIEs} } OPTIONAL, - ... -} - -TransportLayerInformation ::= SEQUENCE { - transportLayerAddress TransportLayerAddress, - iuTransportAssociation IuTransportAssociation, - iE-Extensions ProtocolExtensionContainer { {TransportLayerInformation-ExtIEs} } OPTIONAL, - ... -} - -TransportLayerInformation-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -RAB-SetupOrModifyItemFirst-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -RAB-SetupOrModifyItemSecond ::= SEQUENCE { - pDP-TypeInformation PDP-TypeInformation OPTIONAL - -- This IE is only present for RABs towards the PS domain at RAB establishment --, - dataVolumeReportingIndication DataVolumeReportingIndication OPTIONAL - -- This IE, if applicable, is only present for RABs towards the PS domain at RAB establishment --, - dl-GTP-PDU-SequenceNumber DL-GTP-PDU-SequenceNumber OPTIONAL - -- This IE, if available, is only present for RABs towards the PS domain at RAB establishment --, - ul-GTP-PDU-SequenceNumber UL-GTP-PDU-SequenceNumber OPTIONAL - -- This IE, if available, is only present for RABs towards the PS domain at RAB establishment --, - dl-N-PDU-SequenceNumber DL-N-PDU-SequenceNumber OPTIONAL - -- This IE, if available, is only present for RABs towards the PS domain at RAB establishment --, - ul-N-PDU-SequenceNumber UL-N-PDU-SequenceNumber OPTIONAL - -- This IE, if available, is only present for RABs towards the PS domain at RAB establishment --, - iE-Extensions ProtocolExtensionContainer { {RAB-SetupOrModifyItemSecond-ExtIEs} } OPTIONAL, - ... -} - -RAB-SetupOrModifyItemSecond-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -RAB-AssignmentRequestExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- RAB Assignment Response --- --- ************************************************************** - -RAB-AssignmentResponse ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {RAB-AssignmentResponseIEs} }, - protocolExtensions ProtocolExtensionContainer { {RAB-AssignmentResponseExtensions} } OPTIONAL, - ... -} - -RAB-AssignmentResponseIEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-SetupOrModifiedList CRITICALITY ignore TYPE RAB-SetupOrModifiedList PRESENCE conditional - -- This group must be present at least when no other group is present, ie. at least one group must be present -- } | - { ID id-RAB-ReleasedList CRITICALITY ignore TYPE RAB-ReleasedList PRESENCE conditional - -- This group must be present at least when no other group is present, ie. at least one group must be present -- } | - - { ID id-RAB-QueuedList CRITICALITY ignore TYPE RAB-QueuedList PRESENCE conditional - -- This group must be present at least when no other group is present, ie. at least one group must be present -- } | - { ID id-RAB-FailedList CRITICALITY ignore TYPE RAB-FailedList PRESENCE conditional - -- This group must be present at least when no other group is present, ie. at least one group must be present -- } | - { ID id-RAB-ReleaseFailedList CRITICALITY ignore TYPE RAB-ReleaseFailedList PRESENCE conditional - -- This group must be present at least when no other group is present, ie. at least one group must be present -- } | - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, - ... -} - -RAB-SetupOrModifiedList ::= RAB-IE-ContainerList { {RAB-SetupOrModifiedItemIEs} } - -RAB-SetupOrModifiedItemIEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-SetupOrModifiedItem CRITICALITY ignore TYPE RAB-SetupOrModifiedItem PRESENCE mandatory }, - ... -} - -RAB-SetupOrModifiedItem ::= SEQUENCE { - rAB-ID RAB-ID, - transportLayerAddress TransportLayerAddress OPTIONAL - -- This IE is only present for RABs towards the PS domain --, - iuTransportAssociation IuTransportAssociation OPTIONAL - -- This IE is only present for RABs towards the PS domain --, - dl-dataVolumes DataVolumeList OPTIONAL - -- This IE is only present if the RAB has been modified and -- - -- RAB data volume reporting for PS domain is required --, - iE-Extensions ProtocolExtensionContainer { {RAB-SetupOrModifiedItem-ExtIEs} } OPTIONAL, - ... -} - -RAB-SetupOrModifiedItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -RAB-ReleasedList ::= RAB-IE-ContainerList { {RAB-ReleasedItemIEs} } - -RAB-ReleasedItemIEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-ReleasedItem CRITICALITY ignore TYPE RAB-ReleasedItem PRESENCE mandatory }, - ... -} - -RAB-ReleasedItem ::= SEQUENCE { - rAB-ID RAB-ID, - dl-dataVolumes DataVolumeList OPTIONAL - -- This IE is only present if data volume reporting for PS domain is required --, - dL-GTP-PDU-SequenceNumber DL-GTP-PDU-SequenceNumber OPTIONAL - -- This IE is only present for RABs towards the PS domain when available and when the release is UTRAN initiated -- , - uL-GTP-PDU-SequenceNumber UL-GTP-PDU-SequenceNumber OPTIONAL - -- This IE is only present for RABs towards the PS domain when available and when the release is UTRAN initiated -- , - iE-Extensions ProtocolExtensionContainer { {RAB-ReleasedItem-ExtIEs} } OPTIONAL, - ... -} - -RAB-ReleasedItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -DataVolumeList ::= SEQUENCE (SIZE (1..maxNrOfVol)) OF - SEQUENCE { - dl-UnsuccessfullyTransmittedDataVolume UnsuccessfullyTransmittedDataVolume, - dataVolumeReference DataVolumeReference OPTIONAL, - iE-Extensions ProtocolExtensionContainer { {DataVolumeList-ExtIEs} } OPTIONAL, - ... - } - -DataVolumeList-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -RAB-QueuedList ::= RAB-IE-ContainerList { {RAB-QueuedItemIEs} } - -RAB-QueuedItemIEs RANAP-PROTOCOL-IES ::= { - { ID id-RAB-QueuedItem CRITICALITY ignore TYPE RAB-QueuedItem PRESENCE mandatory }, - ... -} - -RAB-QueuedItem ::= SEQUENCE { - rAB-ID RAB-ID, - iE-Extensions ProtocolExtensionContainer { {RAB-QueuedItem-ExtIEs} } OPTIONAL, - ... -} - -RAB-QueuedItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -RAB-ReleaseFailedList ::= RAB-FailedList - -RAB-AssignmentResponseExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - --- ************************************************************** --- --- PRIVATE MESSAGE --- --- ************************************************************** - -PrivateMessage ::= SEQUENCE { - privateIEs PrivateIE-Container { {PrivateMessage-IEs } }, - ... -} - -PrivateMessage-IEs RANAP-PRIVATE-IES ::= { - ... -} - --- ************************************************************** --- --- RANAP RELOCATION INFORMATION ELEMENTARY PROCEDURE --- --- ************************************************************** - -RANAP-RelocationInformation ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {RANAP-RelocationInformationIEs} }, - protocolExtensions ProtocolExtensionContainer { {RANAP-RelocationInformationExtensions} } OPTIONAL, - ... -} - -RANAP-RelocationInformationIEs RANAP-PROTOCOL-IES ::= { - { ID id-DirectTransferInformationList-RANAP-RelocInf - CRITICALITY ignore TYPE DirectTransferInformationList-RANAP-RelocInf - PRESENCE optional } | - { ID id-RAB-ContextList-RANAP-RelocInf CRITICALITY ignore TYPE RAB-ContextList-RANAP-RelocInf PRESENCE optional }, - ... -} - -DirectTransferInformationList-RANAP-RelocInf ::= DirectTransfer-IE-ContainerList { {DirectTransferInformationItemIEs-RANAP-RelocInf} } - -DirectTransferInformationItemIEs-RANAP-RelocInf RANAP-PROTOCOL-IES ::= { - { ID id-DirectTransferInformationItem-RANAP-RelocInf - CRITICALITY ignore TYPE DirectTransferInformationItem-RANAP-RelocInf - PRESENCE mandatory }, - ... -} - -DirectTransferInformationItem-RANAP-RelocInf ::= SEQUENCE { - nAS-PDU NAS-PDU, - sAPI SAPI, - cN-DomainIndicator CN-DomainIndicator, - iE-Extensions ProtocolExtensionContainer { {RANAP-DirectTransferInformationItem-ExtIEs-RANAP-RelocInf} } OPTIONAL, - ... -} - -RANAP-DirectTransferInformationItem-ExtIEs-RANAP-RelocInf RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -RAB-ContextList-RANAP-RelocInf ::= RAB-IE-ContainerList { {RAB-ContextItemIEs-RANAP-RelocInf} } - -RAB-ContextItemIEs-RANAP-RelocInf RANAP-PROTOCOL-IES ::= { - { ID id-RAB-ContextItem-RANAP-RelocInf CRITICALITY ignore TYPE RAB-ContextItem-RANAP-RelocInf PRESENCE mandatory }, - ... -} - -RAB-ContextItem-RANAP-RelocInf ::= SEQUENCE { - rAB-ID RAB-ID, - dl-GTP-PDU-SequenceNumber DL-GTP-PDU-SequenceNumber OPTIONAL - --This IE is only present when available--, - ul-GTP-PDU-SequenceNumber UL-GTP-PDU-SequenceNumber OPTIONAL - --This IE is only present when available--, - dl-N-PDU-SequenceNumber DL-N-PDU-SequenceNumber OPTIONAL - --This IE is only present when available--, - ul-N-PDU-SequenceNumber UL-N-PDU-SequenceNumber OPTIONAL - --This IE is only present when available--, - iE-Extensions ProtocolExtensionContainer { {RAB-ContextItem-ExtIEs-RANAP-RelocInf} } OPTIONAL, - ... -} - -RAB-ContextItem-ExtIEs-RANAP-RelocInf RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -RANAP-RelocationInformationExtensions RANAP-PROTOCOL-EXTENSION ::= { - ... -} - - --- ************************************************************** --- --- Information Element Definitions --- --- ************************************************************** - ---BEGIN_3 - - --- A - -AllocationOrRetentionPriority ::= SEQUENCE { - priorityLevel PriorityLevel, - pre-emptionCapability Pre-emptionCapability, - pre-emptionVulnerability Pre-emptionVulnerability, - queuingAllowed QueuingAllowed, - iE-Extensions ProtocolExtensionContainer { {AllocationOrRetentionPriority-ExtIEs} } OPTIONAL, - ... -} - -AllocationOrRetentionPriority-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -AreaIdentity ::= CHOICE { - sAI SAI, - geographicalArea GeographicalArea, - ... -} - --- B - -BindingID ::= OCTET STRING (SIZE (4)) - --- C - - -Cause ::= CHOICE { - radioNetwork CauseRadioNetwork, - transmissionNetwork CauseTransmissionNetwork, - nAS CauseNAS, - protocol CauseProtocol, - misc CauseMisc, - non-Standard CauseNon-Standard, - ... -} - -CauseMisc ::= INTEGER { - om-intervention (113), - no-resource-available (114), - unspecified-failure (115), - network-optimisation (116) -} (113..128) - -CauseNAS ::= INTEGER { - user-restriction-start-indication (81), - user-restriction-end-indication (82), - normal-release (83) -} (81..96) - -CauseProtocol ::= INTEGER { - transfer-syntax-error (97), - semantic-error (98), - message-not-compatible-with-receiver-state (99), - abstract-syntax-error-reject (100), - abstract-syntax-error-ignore-and-notify (101), - abstract-syntax-error-falsely-constructed-message (102) - -} (97..112) - -CauseRadioNetwork ::= INTEGER { - rab-pre-empted (1), - trelocoverall-expiry (2), - trelocprep-expiry (3), - treloccomplete-expiry (4), - tqueing-expiry (5), - relocation-triggered (6), - trellocalloc-expiry(7), - unable-to-establish-during-relocation (8), - unknown-target-rnc (9), - relocation-cancelled (10), - successful-relocation (11), - requested-ciphering-and-or-integrity-protection-algorithms-not-supported (12), - change-of-ciphering-and-or-integrity-protection-is-not-supported (13), - failure-in-the-radio-interface-procedure (14), - release-due-to-utran-generated-reason (15), - user-inactivity (16), - time-critical-relocation (17), - requested-traffic-class-not-available (18), - invalid-rab-parameters-value (19), - requested-maximum-bit-rate-not-available (20), - requested-guaranteed-bit-rate-not-available (21), - requested-transfer-delay-not-achievable (22), - invalid-rab-parameters-combination (23), - condition-violation-for-sdu-parameters (24), - condition-violation-for-traffic-handling-priority (25), - condition-violation-for-guaranteed-bit-rate (26), - user-plane-versions-not-supported (27), - iu-up-failure (28), - relocation-failure-in-target-CN-RNC-or-target-system(29), - invalid-RAB-ID (30), - no-remaining-rab (31), - interaction-with-other-procedure (32), - requested-maximum-bit-rate-for-dl-not-available (33), - requested-maximum-bit-rate-for-ul-not-available (34), - requested-guaranteed-bit-rate-for-dl-not-available (35), - requested-guaranteed-bit-rate-for-ul-not-available (36), - repeated-integrity-checking-failure (37), - requested-report-type-not-supported (38), - request-superseded (39), - release-due-to-UE-generated-signalling-connection-release (40), - resource-optimisation-relocation (41), - requested-information-not-available (42), - relocation-desirable-for-radio-reasons (43), - relocation-not-supported-in-target-RNC-or-target-system (44), - directed-retry (45), - radio-connection-with-UE-Lost (46) -} (1..64) - -CauseNon-Standard ::= INTEGER (129..256) - -CauseTransmissionNetwork ::= INTEGER { - signalling-transport-resource-failure (65), - iu-transport-connection-failed-to-establish (66) -} (65..80) - - -CriticalityDiagnostics ::= SEQUENCE { - procedureCode ProcedureCode OPTIONAL, - triggeringMessage TriggeringMessage OPTIONAL, - procedureCriticality Criticality OPTIONAL, - iEsCriticalityDiagnostics CriticalityDiagnostics-IE-List OPTIONAL, - iE-Extensions ProtocolExtensionContainer { {CriticalityDiagnostics-ExtIEs} } OPTIONAL, - ... -} - -CriticalityDiagnostics-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -CriticalityDiagnostics-IE-List ::= SEQUENCE (SIZE (1..maxNrOfErrors)) OF - SEQUENCE { - iECriticality Criticality, - iE-ID ProtocolIE-ID, - repetitionNumber RepetitionNumber OPTIONAL, - iE-Extensions ProtocolExtensionContainer { {CriticalityDiagnostics-IE-List-ExtIEs} } OPTIONAL, - ... - } - -CriticalityDiagnostics-IE-List-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - { ID id-MessageStructure CRITICALITY ignore EXTENSION MessageStructure PRESENCE optional }, - ... -} - -MessageStructure ::= SEQUENCE (SIZE (1..maxNrOfLevels)) OF - SEQUENCE { - iE-ID ProtocolIE-ID, - repetitionNumber RepetitionNumber OPTIONAL, - iE-Extensions ProtocolExtensionContainer { {MessageStructure-ExtIEs} } OPTIONAL, - ... - } - - -MessageStructure-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -CGI ::= SEQUENCE { - pLMN-ID PLMN-ID, - lAC LAC, - cI CI, - iE-Extensions ProtocolExtensionContainer { {CGI-ExtIEs} } OPTIONAL -} - -CGI-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -ChosenEncryptionAlgorithm ::= EncryptionAlgorithm - -ChosenIntegrityProtectionAlgorithm ::= IntegrityProtectionAlgorithm - -CI ::= OCTET STRING (SIZE (2)) - -ClassmarkInformation2 ::= OCTET STRING - -ClassmarkInformation3 ::= OCTET STRING - -CN-DomainIndicator ::= ENUMERATED { - cs-domain, - ps-domain -} - - - --- D - -DataVolumeReference ::= INTEGER (0..255) - -DataVolumeReportingIndication ::= ENUMERATED { - do-report, - do-not-report -} - -DCH-ID ::= INTEGER (0..255) - -DeliveryOfErroneousSDU ::= ENUMERATED { - yes, - no, - no-error-detection-consideration -} - -DeliveryOrder::= ENUMERATED { - delivery-order-requested, - delivery-order-not-requested -} - -DL-GTP-PDU-SequenceNumber ::= INTEGER (0..65535) --- Reference: xx.xxx - -DL-N-PDU-SequenceNumber ::= INTEGER (0..65535) --- Reference: xx.xxx - -D-RNTI ::= INTEGER (0..1048575) - -DRX-CycleLengthCoefficient ::= INTEGER (6..9) - -DSCH-ID ::= INTEGER (0..255) - --- E - -EncryptionAlgorithm ::= INTEGER { no-encryption (0), standard-UMTS-encryption-algorith-UEA1 (1) } (0..15) - -EncryptionInformation ::= SEQUENCE { - permittedAlgorithms PermittedEncryptionAlgorithms, - key EncryptionKey, - iE-Extensions ProtocolExtensionContainer { {EncryptionInformation-ExtIEs} } OPTIONAL -} - -EncryptionInformation-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -EncryptionKey ::= BIT STRING (SIZE (128)) --- Reference: 33.102 - -Event ::= ENUMERATED { - stop, - direct, - change-of-servicearea, - ... -} - --- F --- G - -GeographicalArea ::= CHOICE { - point GA-Point, - pointWithUnCertainty GA-PointWithUnCertainty, - polygon GA-Polygon, - ... -} - -GeographicalCoordinates ::= SEQUENCE { - latitudeSign ENUMERATED { north, south }, - latitude INTEGER (0..8388607), - longitude INTEGER (-8388608..8388607), - iE-Extensions ProtocolExtensionContainer { {GeographicalCoordinates-ExtIEs} } OPTIONAL, - ... -} - -GeographicalCoordinates-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -GA-Point ::= SEQUENCE { - geographicalCoordinates GeographicalCoordinates, - iE-Extensions ProtocolExtensionContainer { {GA-Point-ExtIEs} } OPTIONAL, - ... -} - -GA-Point-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -GA-PointWithUnCertainty ::=SEQUENCE { - geographicalCoordinates GeographicalCoordinates, - iE-Extensions ProtocolExtensionContainer { {GA-PointWithUnCertainty-ExtIEs} } OPTIONAL, - uncertaintyCode INTEGER (0..127) -} - -GA-PointWithUnCertainty-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -GA-Polygon ::= SEQUENCE (SIZE (1..maxNrOfPoints)) OF - SEQUENCE { - geographicalCoordinates GeographicalCoordinates, - iE-Extensions ProtocolExtensionContainer { {GA-Polygon-ExtIEs} } OPTIONAL, - ... - } - -GA-Polygon-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -GlobalRNC-ID ::= SEQUENCE { - pLMN-ID PLMN-ID, - rNC-ID RNC-ID -} - -GTP-TEI ::= OCTET STRING (SIZE (4)) --- Reference: xx.xxx - -GuaranteedBitrate ::= INTEGER (0..16000000) --- Unit is bits per sec - --- H - --- I - - -IMEI ::= OCTET STRING (SIZE (8)) --- Reference: 23.003 - -IMSI ::= TBCD-STRING (SIZE (3..8)) --- Reference: 23.003 - -IntegrityProtectionAlgorithm ::= INTEGER { standard-UMTS-integrity-algorithm-UIA1 (0) } (0..15) - -IntegrityProtectionInformation ::= SEQUENCE { - permittedAlgorithms PermittedIntegrityProtectionAlgorithms, - key IntegrityProtectionKey, - iE-Extensions ProtocolExtensionContainer { {IntegrityProtectionInformation-ExtIEs} } OPTIONAL -} - -IntegrityProtectionInformation-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -IntegrityProtectionKey ::= BIT STRING (SIZE (128)) - -IuSignallingConnectionIdentifier ::= BIT STRING (SIZE (24)) - -IuTransportAssociation ::= CHOICE { - gTP-TEI GTP-TEI, - bindingID BindingID, - ... -} - --- J --- K - -KeyStatus ::= ENUMERATED { - old, - new, - ... -} --- L - -LAC ::= OCTET STRING (SIZE (2)) - -LAI ::= SEQUENCE { - pLMN-ID PLMN-ID, - lAC LAC, - iE-Extensions ProtocolExtensionContainer { {LAI-ExtIEs} } OPTIONAL -} - -LAI-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -L3-Information ::= OCTET STRING - --- M - -MaxBitrate ::= INTEGER (1..16000000) --- Unit is bits per sec - -MaxSDU-Size ::= INTEGER (0..32768) --- MaxSDU-Size --- Unit is bit - -MCC ::= TBCD-STRING (SIZE (2)) --- Reference: 24.008 - -MNC ::= TBCD-STRING (SIZE (2)) --- Reference: 24.008 - --- N - - -NAS-PDU ::= OCTET STRING - -NAS-SynchronisationIndicator ::= BIT STRING (SIZE (4)) - -NonSearchingIndication ::= ENUMERATED { - non-searching, - searching -} - -NumberOfIuInstances ::= INTEGER (1..2) - -NumberOfSteps ::= INTEGER (1..16) - --- O - -OldBSS-ToNewBSS-Information ::= OCTET STRING - -OMC-ID ::= OCTET STRING (SIZE (3..22)) --- Reference: GSM TS 12.20 - --- P - -PagingAreaID ::= CHOICE { - lAI LAI, - rAI RAI, - ... -} - -PagingCause ::= ENUMERATED { - terminating-conversational-call, - terminating-streaming-call, - terminating-interactive-call, - terminating-background-call, - terminating-low-priority-signalling, - ..., - terminating-high-priority-signalling -} - -PDP-TypeInformation ::= SEQUENCE (SIZE (1..maxNrOfPDPDirections)) OF - PDP-Type - -PDP-Type ::= ENUMERATED { - empty, - ppp, - osp-ihoss -- this value shall not be used -- , - ipv4, - ipv6, - ... -} - -PermanentNAS-UE-ID ::= CHOICE { - iMSI IMSI, - ... -} - -PermittedEncryptionAlgorithms ::= SEQUENCE (SIZE (1..16)) OF - EncryptionAlgorithm - -PermittedIntegrityProtectionAlgorithms ::= SEQUENCE (SIZE (1..16)) OF - IntegrityProtectionAlgorithm - -PLMN-ID ::= TBCD-STRING (SIZE (3)) - -Pre-emptionCapability ::= ENUMERATED { - shall-not-trigger-pre-emption, - may-trigger-pre-emption -} - -Pre-emptionVulnerability ::= ENUMERATED { - not-pre-emptable, - pre-emptable -} - -PriorityLevel ::= INTEGER { spare (0), highest (1), lowest (14), no-priority (15) } (0..15) - -P-TMSI ::= OCTET STRING (SIZE (4)) - --- Q - -QueuingAllowed ::= ENUMERATED { - queueing-not-allowed, - queueing-allowed -} - --- R -RAB-AsymmetryIndicator::= ENUMERATED { - symmetric-bidirectional, - asymmetric-unidirectional-downlink, - asymmetric-unidirectional-uplink, - asymmetric-bidirectional, - ... -} - -RAB-ID ::= BIT STRING (SIZE (8)) - -RAB-Parameter-GuaranteedBitrateList ::= SEQUENCE (SIZE (1..maxNrOfSeparateTrafficDirections)) OF GuaranteedBitrate - -RAB-Parameter-MaxBitrateList ::= SEQUENCE (SIZE (1..maxNrOfSeparateTrafficDirections)) OF MaxBitrate - -RAB-Parameters ::= SEQUENCE { - trafficClass TrafficClass, - rAB-AsymmetryIndicator RAB-AsymmetryIndicator, - maxBitrate RAB-Parameter-MaxBitrateList, - guaranteedBitRate RAB-Parameter-GuaranteedBitrateList OPTIONAL - -- This IE is only present when traffic class indicates Conversational or Streaming --, - deliveryOrder DeliveryOrder, - maxSDU-Size MaxSDU-Size, - sDU-Parameters SDU-Parameters, - transferDelay TransferDelay OPTIONAL - -- This IE is only present when traffic class indicates Conversational or Streaming --, - trafficHandlingPriority TrafficHandlingPriority OPTIONAL - -- This IE is only present when traffic class indicates Interactiv --, - allocationOrRetentionPriority AllocationOrRetentionPriority OPTIONAL, - sourceStatisticsDescriptor SourceStatisticsDescriptor OPTIONAL - -- This IE is only present when traffic class indicates Conversational or Streaming --, - relocationRequirement RelocationRequirement OPTIONAL - -- This IE is only present for RABs towards the PS domain --, - iE-Extensions ProtocolExtensionContainer { {RAB-Parameters-ExtIEs} } OPTIONAL, - ... -} - -RAB-Parameters-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -RAB-SubflowCombinationBitRate ::= INTEGER (0..16000000) - -RAB-TrCH-Mapping ::= SEQUENCE ( SIZE (1..maxNrOfRABs)) OF - RAB-TrCH-MappingItem - -RAB-TrCH-MappingItem ::= SEQUENCE { - rAB-ID RAB-ID, - trCH-ID-List TrCH-ID-List, - ... -} - -RAC ::= OCTET STRING (SIZE (1)) - -RAI ::= SEQUENCE { - lAI LAI, - rAC RAC, - iE-Extensions ProtocolExtensionContainer { {RAI-ExtIEs} } OPTIONAL, - ... -} - -RAI-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -RateControlAllowed ::= ENUMERATED { - not-allowed, - allowed -} - -RelocationRequirement ::= ENUMERATED { - lossless, - none, - ... -} - -RelocationType ::= ENUMERATED { - ue-not-involved, - ue-involved, - ... -} - -RepetitionNumber ::= INTEGER (1..256) - -ReportArea ::= ENUMERATED { - service-area, - geographical-coordinates, - ... -} - -RequestType ::= SEQUENCE { - event Event, - reportArea ReportArea, - accuracyCode INTEGER (0..127) OPTIONAL, - -- To be used if Geographical Coordinates shall be reported with a requested accuracy. -- - ... -} - -ResidualBitErrorRatio ::= SEQUENCE { - mantissa INTEGER (1..9), - exponent INTEGER (1..8), - iE-Extensions ProtocolExtensionContainer { {ResidualBitErrorRatio-ExtIEs} } OPTIONAL -} --- ResidualBitErrorRatio = mantissa * 10^-exponent - -ResidualBitErrorRatio-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -RNC-ID ::= INTEGER (0..4095) --- RNC-ID ::= BIT STRING (SIZE (12)) --- Harmonized with RNSAP and NBAP definitions - -RRC-Container ::= OCTET STRING - --- S - -SAC ::= OCTET STRING (SIZE (2)) - -SAI ::= SEQUENCE { - pLMN-ID PLMN-ID, - lAC LAC, - sAC SAC, - iE-Extensions ProtocolExtensionContainer { {SAI-ExtIEs} } OPTIONAL -} - -SAI-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -SAPI ::= ENUMERATED { - sapi-0, - sapi-3, - ... -} - -SDU-ErrorRatio ::= SEQUENCE { - mantissa INTEGER (1..9), - exponent INTEGER (1..6), - iE-Extensions ProtocolExtensionContainer { {SDU-ErrorRatio-ExtIEs} } OPTIONAL -} --- SDU-ErrorRatio = mantissa * 10^-exponent - -SDU-ErrorRatio-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} -SDU-FormatInformationParameters ::= SEQUENCE (SIZE (1..maxRAB-SubflowCombination)) OF - SEQUENCE { - subflowSDU-Size SubflowSDU-Size OPTIONAL - -- This IE is only present for RABs that have predefined SDU size(s) --, - rAB-SubflowCombinationBitRate RAB-SubflowCombinationBitRate OPTIONAL - -- At least either of subflowSDU-Size or rABsubflowCombinationBitRate -- - -- shall be present when SDUformatInformationParameter is present --, - iE-Extensions ProtocolExtensionContainer { {SDU-FormatInformationParameters-ExtIEs} } OPTIONAL, - ... - } - -SDU-FormatInformationParameters-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -SDU-Parameters ::= SEQUENCE (SIZE (1..maxRAB-Subflows)) OF - SEQUENCE { - sDU-ErrorRatio SDU-ErrorRatio OPTIONAL - -- This IE is not present when DeliveryOfErroneousSDU is set to no-error-detection-consideration --, - residualBitErrorRatio ResidualBitErrorRatio, - deliveryOfErroneousSDU DeliveryOfErroneousSDU, - sDU-FormatInformationParameters SDU-FormatInformationParameters OPTIONAL - -- This IE shall be present for RABs with predefined SDU sizes --, - iE-Extensions ProtocolExtensionContainer { {SDU-Parameters-ExtIEs} } OPTIONAL, - ... - } - -SDU-Parameters-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -Service-Handover ::= ENUMERATED { - handover-to-GSM-should-be-performed, - handover-to-GSM-should-not-be-performed, - handover-to-GSM-shall-not-be-performed, - ... -} - -SourceID ::= CHOICE { - sourceRNC-ID SourceRNC-ID, -- If UMTS target - sAI SAI, -- if GSM target - ... -} - - -SourceRNC-ID ::= SEQUENCE { - pLMN-ID PLMN-ID, - rNC-ID RNC-ID, - iE-Extensions ProtocolExtensionContainer { {SourceRNC-ID-ExtIEs} } OPTIONAL -} - -SourceRNC-ID-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -SourceRNC-ToTargetRNC-TransparentContainer ::= SEQUENCE { - rRC-Container RRC-Container, - numberOfIuInstances NumberOfIuInstances, - relocationType RelocationType, - chosenIntegrityProtectionAlgorithm ChosenIntegrityProtectionAlgorithm OPTIONAL - -- Must be present for intra UMTS Handovers if available --, - integrityProtectionKey IntegrityProtectionKey OPTIONAL - -- Must be present for intra UMTS Handovers if available --, - chosenEncryptionAlgorithForSignalling ChosenEncryptionAlgorithm OPTIONAL - -- Must be present for intra UMTS Handovers if ciphering is active --, - cipheringKey EncryptionKey OPTIONAL - -- Must be present for intra UMTS Handovers if ciphering is active --, - chosenEncryptionAlgorithForCS ChosenEncryptionAlgorithm OPTIONAL - -- Must be present for intra UMTS Handovers if ciphering is active --, - chosenEncryptionAlgorithForPS ChosenEncryptionAlgorithm OPTIONAL - -- Must be present for intra UMTS Handovers if ciphering is active --, - d-RNTI D-RNTI OPTIONAL - -- Included for SRNS Relocation without UE involvement --, - targetCellId TargetCellId OPTIONAL - -- Included for SRNS Relocation with UE involvement --, - rAB-TrCH-Mapping RAB-TrCH-Mapping OPTIONAL - -- Included for SRNS Relocation without UE involvement and -- - -- if RABs are carried on DCH, USCH or DSCH transport channels --, - iE-Extensions ProtocolExtensionContainer { {SourceRNC-ToTargetRNC-TransparentContainer-ExtIEs} } OPTIONAL, - ... -} - -SourceRNC-ToTargetRNC-TransparentContainer-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -SourceStatisticsDescriptor ::= ENUMERATED { - speech, - unknown, - ... -} - -SubflowSDU-Size ::= INTEGER (0..4095) --- Unit is bit - - --- T - -TargetCellId ::= INTEGER (0..268435455) - -TargetID ::= CHOICE { - targetRNC-ID TargetRNC-ID, -- If UMTS target - cGI CGI, -- If GSM target - ... -} - - - - -TargetRNC-ID ::= SEQUENCE { - lAI LAI, - rAC RAC OPTIONAL - -- Must always be present towards the PS domain and never towards the CS domain --, - rNC-ID RNC-ID, - iE-Extensions ProtocolExtensionContainer { {TargetRNC-ID-ExtIEs} } OPTIONAL -} - -TargetRNC-ID-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -TargetRNC-ToSourceRNC-TransparentContainer ::= SEQUENCE { - rRC-Container RRC-Container, - d-RNTI D-RNTI OPTIONAL - -- May be included to allow the triggering of the Relocation Detect procedure from the Iur Interface --, - iE-Extensions ProtocolExtensionContainer { {TargetRNC-ToSourceRNC-TransparentContainer-ExtIEs} } OPTIONAL, - ... -} - -TargetRNC-ToSourceRNC-TransparentContainer-ExtIEs RANAP-PROTOCOL-EXTENSION ::= { - ... -} - -TBCD-STRING ::= OCTET STRING - -TemporaryUE-ID ::= CHOICE { - tMSI TMSI, - p-TMSI P-TMSI, - ... -} - -TMSI ::= OCTET STRING (SIZE (4)) - -TraceReference ::= OCTET STRING (SIZE (2..3)) - -TraceType ::= OCTET STRING (SIZE (1)) --- Reference: GSM TS 12.08 - -TrafficClass ::= ENUMERATED { - conversational, - streaming, - interactive, - background, - ... -} - -TrafficHandlingPriority ::= INTEGER { spare (0), highest (1), lowest (14), no-priority-used (15) } (0..15) - -TransferDelay ::= INTEGER (0..65535) --- Unit is millisecond - -UnsuccessfullyTransmittedDataVolume ::= INTEGER (0..4294967295) - -TransportLayerAddress ::= BIT STRING (SIZE (1..160, ...)) - -TrCH-ID ::= SEQUENCE { - dCH-ID DCH-ID OPTIONAL - -- At least one of these IEs shall be included --, - dSCH-ID DSCH-ID OPTIONAL - -- At least one of these IEs shall be included --, - uSCH-ID USCH-ID OPTIONAL - -- At least one of these IEs shall be included --, - ... -} - -TrCH-ID-List ::= SEQUENCE (SIZE (1..maxRAB-Subflows)) OF - TrCH-ID - -TriggerID ::= OCTET STRING (SIZE (3..22)) - --- U - -UE-ID ::= CHOICE { - imsi IMSI, - imei IMEI, - ... -} - -UL-GTP-PDU-SequenceNumber ::= INTEGER (0..65535) - -UL-N-PDU-SequenceNumber ::= INTEGER (0..65535) - -UP-ModeVersions ::= BIT STRING (SIZE (16)) - -USCH-ID ::= INTEGER (0..255) - -UserPlaneMode ::= ENUMERATED { - transparent-mode, - support-mode-for-predefined-SDU-sizes, - ... -} - - --- ************************************************************** --- --- Common definitions --- --- ************************************************************** - ---BEGIN_4 - -Criticality ::= ENUMERATED { reject, ignore, notify } - -Presence ::= ENUMERATED { optional, conditional, mandatory } - -PrivateIE-ID ::= CHOICE { - local INTEGER (0..65535), - global OBJECT IDENTIFIER -} - -ProcedureCode ::= INTEGER (0..255) - -ProtocolExtensionID ::= INTEGER (0..65535) - -ProtocolIE-ID ::= INTEGER (0..65535) - -TriggeringMessage ::= ENUMERATED { initiating-message, successful-outcome, unsuccessfull-outcome, outcome } - - --- ************************************************************** --- --- Constant definitions --- --- ************************************************************** - ---BEGIN_5 - --- ************************************************************** --- --- Elementary Procedures --- --- ************************************************************** - -id-RAB-Assignment INTEGER ::= 0 -id-Iu-Release INTEGER ::= 1 -id-RelocationPreparation INTEGER ::= 2 -id-RelocationResourceAllocation INTEGER ::= 3 -id-RelocationCancel INTEGER ::= 4 -id-SRNS-ContextTransfer INTEGER ::= 5 -id-SecurityModeControl INTEGER ::= 6 -id-DataVolumeReport INTEGER ::= 7 -id-Reset INTEGER ::= 9 -id-RAB-ReleaseRequest INTEGER ::= 10 -id-Iu-ReleaseRequest INTEGER ::= 11 -id-RelocationDetect INTEGER ::= 12 -id-RelocationComplete INTEGER ::= 13 -id-Paging INTEGER ::= 14 -id-CommonID INTEGER ::= 15 -id-CN-InvokeTrace INTEGER ::= 16 -id-LocationReportingControl INTEGER ::= 17 -id-LocationReport INTEGER ::= 18 -id-InitialUE-Message INTEGER ::= 19 -id-DirectTransfer INTEGER ::= 20 -id-OverloadControl INTEGER ::= 21 -id-ErrorIndication INTEGER ::= 22 -id-SRNS-DataForward INTEGER ::= 23 -id-ForwardSRNS-Context INTEGER ::= 24 -id-privateMessage INTEGER ::= 25 -id-CN-DeactivateTrace INTEGER ::= 26 -id-ResetResource INTEGER ::= 27 -id-RANAP-Relocation INTEGER ::= 28 - --- ************************************************************** --- --- Extension constants --- --- ************************************************************** - -maxPrivateIEs INTEGER ::= 65535 -maxProtocolExtensions INTEGER ::= 65535 -maxProtocolIEs INTEGER ::= 65535 - --- ************************************************************** --- --- Lists --- --- ************************************************************** - -maxNrOfDTs INTEGER ::= 15 -maxNrOfErrors INTEGER ::= 256 -maxNrOfIuSigConIds INTEGER ::= 250 -maxNrOfPDPDirections INTEGER ::= 2 -maxNrOfPoints INTEGER ::= 15 -maxNrOfRABs INTEGER ::= 256 -maxNrOfSeparateTrafficDirections INTEGER ::= 2 -maxNrOfVol INTEGER ::= 2 -maxNrOfLevels INTEGER ::= 256 - -maxRAB-Subflows INTEGER ::= 7 -maxRAB-SubflowCombination INTEGER ::= 64 - --- ************************************************************** --- --- IEs --- --- ************************************************************** - -id-AreaIdentity INTEGER ::= 0 -id-CN-DomainIndicator INTEGER ::= 3 -id-Cause INTEGER ::= 4 -id-ChosenEncryptionAlgorithm INTEGER ::= 5 -id-ChosenIntegrityProtectionAlgorithm INTEGER ::= 6 -id-ClassmarkInformation2 INTEGER ::= 7 -id-ClassmarkInformation3 INTEGER ::= 8 -id-CriticalityDiagnostics INTEGER ::= 9 -id-DL-GTP-PDU-SequenceNumber INTEGER ::= 10 -id-EncryptionInformation INTEGER ::= 11 -id-IntegrityProtectionInformation INTEGER ::= 12 -id-IuTransportAssociation INTEGER ::= 13 -id-L3-Information INTEGER ::= 14 -id-LAI INTEGER ::= 15 -id-NAS-PDU INTEGER ::= 16 -id-NonSearchingIndication INTEGER ::= 17 -id-NumberOfSteps INTEGER ::= 18 -id-OMC-ID INTEGER ::= 19 -id-OldBSS-ToNewBSS-Information INTEGER ::= 20 -id-PagingAreaID INTEGER ::= 21 -id-PagingCause INTEGER ::= 22 -id-PermanentNAS-UE-ID INTEGER ::= 23 -id-RAB-ContextItem INTEGER ::= 24 -id-RAB-ContextList INTEGER ::= 25 -id-RAB-DataForwardingItem INTEGER ::= 26 -id-RAB-DataForwardingItem-SRNS-CtxReq INTEGER ::= 27 -id-RAB-DataForwardingList INTEGER ::= 28 -id-RAB-DataForwardingList-SRNS-CtxReq INTEGER ::= 29 -id-RAB-DataVolumeReportItem INTEGER ::= 30 -id-RAB-DataVolumeReportList INTEGER ::= 31 -id-RAB-DataVolumeReportRequestItem INTEGER ::= 32 -id-RAB-DataVolumeReportRequestList INTEGER ::= 33 -id-RAB-FailedItem INTEGER ::= 34 -id-RAB-FailedList INTEGER ::= 35 -id-RAB-ID INTEGER ::= 36 -id-RAB-QueuedItem INTEGER ::= 37 -id-RAB-QueuedList INTEGER ::= 38 -id-RAB-ReleaseFailedList INTEGER ::= 39 -id-RAB-ReleaseItem INTEGER ::= 40 -id-RAB-ReleaseList INTEGER ::= 41 -id-RAB-ReleasedItem INTEGER ::= 42 -id-RAB-ReleasedList INTEGER ::= 43 -id-RAB-ReleasedList-IuRelComp INTEGER ::= 44 -id-RAB-RelocationReleaseItem INTEGER ::= 45 -id-RAB-RelocationReleaseList INTEGER ::= 46 -id-RAB-SetupItem-RelocReq INTEGER ::= 47 -id-RAB-SetupItem-RelocReqAck INTEGER ::= 48 -id-RAB-SetupList-RelocReq INTEGER ::= 49 -id-RAB-SetupList-RelocReqAck INTEGER ::= 50 -id-RAB-SetupOrModifiedItem INTEGER ::= 51 -id-RAB-SetupOrModifiedList INTEGER ::= 52 -id-RAB-SetupOrModifyItem INTEGER ::= 53 -id-RAB-SetupOrModifyList INTEGER ::= 54 -id-RAC INTEGER ::= 55 -id-RelocationType INTEGER ::= 56 -id-RequestType INTEGER ::= 57 -id-SAI INTEGER ::= 58 -id-SAPI INTEGER ::= 59 -id-SourceID INTEGER ::= 60 -id-SourceRNC-ToTargetRNC-TransparentContainer INTEGER ::= 61 -id-TargetID INTEGER ::= 62 -id-TargetRNC-ToSourceRNC-TransparentContainer INTEGER ::= 63 -id-TemporaryUE-ID INTEGER ::= 64 -id-TraceReference INTEGER ::= 65 -id-TraceType INTEGER ::= 66 -id-TransportLayerAddress INTEGER ::= 67 -id-TriggerID INTEGER ::= 68 -id-UE-ID INTEGER ::= 69 -id-UL-GTP-PDU-SequenceNumber INTEGER ::= 70 -id-RAB-FailedtoReportItem INTEGER ::= 71 -id-RAB-FailedtoReportList INTEGER ::= 72 -id-KeyStatus INTEGER ::= 75 -id-DRX-CycleLengthCoefficient INTEGER ::= 76 -id-IuSigConIdList INTEGER ::= 77 -id-IuSigConIdItem INTEGER ::= 78 -id-IuSigConId INTEGER ::= 79 -id-DirectTransferInformationItem-RANAP-RelocInf INTEGER ::= 80 -id-DirectTransferInformationList-RANAP-RelocInf INTEGER ::= 81 -id-RAB-ContextItem-RANAP-RelocInf INTEGER ::= 82 -id-RAB-ContextList-RANAP-RelocInf INTEGER ::= 83 -id-RAB-ContextFailedtoTransferItem INTEGER ::= 84 -id-RAB-ContextFailedtoTransferList INTEGER ::= 85 -id-GlobalRNC-ID INTEGER ::= 86 -id-RAB-ReleasedItem-IuRelComp INTEGER ::= 87 -id-MessageStructure INTEGER ::= 88 - - --- ************************************************************** --- --- Container definitions --- --- ************************************************************** - ---BEGIN_6 - --- ************************************************************** --- --- Class Definition for Protocol IEs --- --- ************************************************************** - -RANAP-PROTOCOL-IES ::= CLASS { - &id ProtocolIE-ID UNIQUE, - &criticality Criticality, - &Value, - &presence Presence -} -WITH SYNTAX { - ID &id - CRITICALITY &criticality - TYPE &Value - PRESENCE &presence -} - --- ************************************************************** --- --- Class Definition for Protocol IEs --- --- ************************************************************** - -RANAP-PROTOCOL-IES-PAIR ::= CLASS { - &id ProtocolIE-ID UNIQUE, - &firstCriticality Criticality, - &FirstValue, - &secondCriticality Criticality, - &SecondValue, - &presence Presence -} -WITH SYNTAX { - ID &id - FIRST CRITICALITY &firstCriticality - FIRST TYPE &FirstValue - SECOND CRITICALITY &secondCriticality - SECOND TYPE &SecondValue - PRESENCE &presence -} - --- ************************************************************** --- --- Class Definition for Protocol Extensions --- --- ************************************************************** - -RANAP-PROTOCOL-EXTENSION ::= CLASS { - &id ProtocolExtensionID UNIQUE, - &criticality Criticality, - &Extension, - &presence Presence -} -WITH SYNTAX { - ID &id - CRITICALITY &criticality - EXTENSION &Extension - PRESENCE &presence -} - --- ************************************************************** --- --- Class Definition for Private IEs --- --- ************************************************************** - -RANAP-PRIVATE-IES ::= CLASS { - &id PrivateIE-ID, - &criticality Criticality, - &Value, - &presence Presence -} -WITH SYNTAX { - ID &id - CRITICALITY &criticality - TYPE &Value - PRESENCE &presence -} - --- ************************************************************** --- --- Container for Protocol IEs --- --- ************************************************************** - -ProtocolIE-Container {RANAP-PROTOCOL-IES : IEsSetParam} ::= - SEQUENCE (SIZE (0..maxProtocolIEs)) OF - ProtocolIE-Field {{IEsSetParam}} - -ProtocolIE-Field {RANAP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE { - id RANAP-PROTOCOL-IES.&id ({IEsSetParam}), - criticality RANAP-PROTOCOL-IES.&criticality ({IEsSetParam}{@id}), - value RANAP-PROTOCOL-IES.&Value ({IEsSetParam}{@id}) -} - --- ************************************************************** --- --- Container for Protocol IE Pairs --- --- ************************************************************** - -ProtocolIE-ContainerPair {RANAP-PROTOCOL-IES-PAIR : IEsSetParam} ::= - SEQUENCE (SIZE (0..maxProtocolIEs)) OF - ProtocolIE-FieldPair {{IEsSetParam}} - -ProtocolIE-FieldPair {RANAP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE { - id RANAP-PROTOCOL-IES-PAIR.&id ({IEsSetParam}), - firstCriticality RANAP-PROTOCOL-IES-PAIR.&firstCriticality ({IEsSetParam}{@id}), - firstValue RANAP-PROTOCOL-IES-PAIR.&FirstValue ({IEsSetParam}{@id}), - secondCriticality RANAP-PROTOCOL-IES-PAIR.&secondCriticality ({IEsSetParam}{@id}), - secondValue RANAP-PROTOCOL-IES-PAIR.&SecondValue ({IEsSetParam}{@id}) -} - --- ************************************************************** --- --- Container Lists for Protocol IE Containers --- --- ************************************************************** - -ProtocolIE-ContainerList {INTEGER : lowerBound, INTEGER : upperBound, RANAP-PROTOCOL-IES : IEsSetParam} ::= - SEQUENCE (SIZE (lowerBound..upperBound)) OF - ProtocolIE-Container {{IEsSetParam}} - -ProtocolIE-ContainerPairList {INTEGER : lowerBound, INTEGER : upperBound, RANAP-PROTOCOL-IES-PAIR : IEsSetParam} ::= - SEQUENCE (SIZE (lowerBound..upperBound)) OF - ProtocolIE-ContainerPair {{IEsSetParam}} - --- ************************************************************** --- --- Container for Protocol Extensions --- --- ************************************************************** - -ProtocolExtensionContainer {RANAP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= - SEQUENCE (SIZE (1..maxProtocolExtensions)) OF - ProtocolExtensionField {{ExtensionSetParam}} - -ProtocolExtensionField {RANAP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE { - id RANAP-PROTOCOL-EXTENSION.&id ({ExtensionSetParam}), - criticality RANAP-PROTOCOL-EXTENSION.&criticality ({ExtensionSetParam}{@id}), - extensionValue RANAP-PROTOCOL-EXTENSION.&Extension ({ExtensionSetParam}{@id}) -} - --- ************************************************************** --- --- Container for Private IEs --- --- ************************************************************** - -PrivateIE-Container {RANAP-PRIVATE-IES : IEsSetParam } ::= - SEQUENCE (SIZE (1.. maxPrivateIEs)) OF - PrivateIE-Field {{IEsSetParam}} - -PrivateIE-Field {RANAP-PRIVATE-IES : IEsSetParam} ::= SEQUENCE { - id RANAP-PRIVATE-IES.&id ({IEsSetParam}), - criticality RANAP-PRIVATE-IES.&criticality ({IEsSetParam}{@id}), - value RANAP-PRIVATE-IES.&Value ({IEsSetParam}{@id}) -} - -END diff --git a/lib/asn1/test/bench/all.erl b/lib/asn1/test/bench/all.erl deleted file mode 100644 index 0841201e85..0000000000 --- a/lib/asn1/test/bench/all.erl +++ /dev/null @@ -1,98 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2002-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% -%% -%% --module(all). - -%% User interface --export([run/0]). - -%% Interna constants --define(NORMAL, 0). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%% Interface -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% run() -> _ -%% -%% Runs all benchmark modules in the current directory on all erlang -%% installations specified by releases/0 -run() -> - %% Delete previous intermediate test result files. - lists:foreach(fun(F) -> file:delete(F) end, filelib:wildcard("*.bmres")), - lists:foreach(fun run/1, releases()). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%% Internal functions -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%% run(Release) -> _ -%% Release = string() - Erlang release -%% Help functions to run/0 -run({Release,Comment}) -> - command(Release ++ " -noshell -compile bench -s erlang halt"), - command(Release ++ " -noshell -s bench run " ++ Comment ++" -s erlang halt"). - -%% command(Command) -> _ -%% Command = string() - is the name and arguments of the external -%% program which will be run -command(Command) -> - io:format("~s\n", [Command]), % Progress info to user - Port = open_port({spawn,Command}, [exit_status, in]), - print_output(Port). - -%% print_output(Port) -> _ -%% Port = port() -%% Print data from the port i.e. output from external program, -%% on standard out. -print_output(Port) -> - receive - {Port, {data,Bytes}} -> - io:put_chars(Bytes), - print_output(Port); - {Port, {exit_status, ?NORMAL}} -> - ok - end. - -%% run() -> Releases -%% Releases = [Release |_] -%% Release = string() - Erlang release -%% Defines which erlang releases to run on -%% --- Change this function to reflect your own erlang installations --- -releases() -> - [ - {"/usr/local/otp/releases/otp_beam_sunos5_r8b_patched/bin/erl","standardr8"}, - {"/usr/local/otp/releases/otp_beam_sunos5_r8b_patched/bin/erl -pa /clearcase/otp/erts/lib/asn1/ebin", "asn1r9"} -]. - - - - - - - - - - - - - - - - - diff --git a/lib/asn1/test/bench/bench.erl b/lib/asn1/test/bench/bench.erl deleted file mode 100644 index bae7d792a4..0000000000 --- a/lib/asn1/test/bench/bench.erl +++ /dev/null @@ -1,454 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2002-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% -%% -%% - --module(bench). - -%% User interface --export([run/1]). - -%% Exported to be used in spawn --export([measure/4]). - -%% Internal constants --define(MAX, 999999999999999). --define(RANGE_MAX, 16#7ffffff). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%% Interface -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%% run() -> _ -%% -%% Compiles and runs all benchmarks in the current directory, -%% and creates a report -run([Comment]) -> - run(atom_to_list(Comment),compiler_options()). - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%% Generic Benchmark functions -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%% compiler_options() -> OptionsList -%% OptionsList = list() - See Erlang/OTP module compile -compiler_options() -> - [report_errors, report_warnings]. - -%% run(OptionsList) -> -%% OptionsList = list() - See Erlang/OTP module compile -%% -%% Help function to run/0. -run(Comment,OptionsList) -> - Bms = compile_benchmarks(OptionsList), - run_benchmarks(Comment,Bms), - report(). - -%% compile_benchmarks(OptionsList) -> [BmInfo| _] -%% OptionsList = list() - See Erlang/OTP module compile -%% BmInfo = {Module, Iterations, [BmFunctionName| _]} -%% Module = atom() -%% Iterations = integer() -%% BmFunctionName = atom() -%% -%% Compiles all benchmark modules in the current directory and -%% returns info about the benchmarks. -compile_benchmarks(OptionsList) -> - {ok, FilesInCurrentDir} = file:list_dir("."), - BmFiles = [BmFile || BmFile <- lists:sort(FilesInCurrentDir), - lists:suffix("_bm.erl", BmFile)], - - lists:foldr(fun(Module, BmInfoAcc) -> - BmInfo = bm_compile(Module, OptionsList), - [BmInfo | BmInfoAcc] - end, [], BmFiles). - - -%% bm_compile(FileName, OptionsList) -> BmInfo -%% FileName = string() -%% OptionsList = list() - See Erlang/OTP module compile -%% BmInfo = {Module, Iterations, [BmFunctionName| _]} -%% Iterations = integer() -%% Module = atom() -%% BmFunctionName = atom() -%% -%% Compiles the benchmark module implemented in <FileName> and returns -%% information about the benchmark tests. -bm_compile(FileName, OptionsList) -> - io:format("Compiling ~s...\n", [FileName]), % Progress info to user - case c:c(FileName, OptionsList) of - {ok, Mod} -> - bm_init(Mod), - bm_cases(Mod); - %% If compilation fails there is no point in trying to continue - error -> - Reason = - lists:flatten( - io_lib:format("Could not compile file ~s", [FileName])), - exit(self(), Reason) - end. - -%% bm_init(Module) -> ok -%% -%% calls the Module:init/0 function to let each benchmark make initialisation if -%% there is need for that. -%% -bm_init(Module) -> - case catch Module:init() of - ok -> - ok; - Other -> - ok % the init function is not mandatory yet - end. - - -%% bm_cases(Module) -> {Module, Iter, [BmFunctionName |_]} -%% Module = atom() -%% Iter = integer() -%% BmFunctionName = atom() -%% -%% Fetches the number of iterations and the names of the benchmark -%% functions for the module <Module>. -bm_cases(Module) -> - case catch Module:benchmarks() of - {Iter, BmList} when integer(Iter), list(BmList) -> - {Module, Iter, BmList}; - %% The benchmark is incorrect implemented there is no point in - %% trying to continue - Other -> - Reason = - lists:flatten( - io_lib:format("Incorrect return value: ~p " - "from ~p:benchmarks()", - [Other, Module])), - exit(self(), Reason) - end. - -%% run_benchmarks(Bms) -> -%% Bms = [{Module, Iter, [BmFunctionName |_]} | _] -%% Module = atom() -%% Iter = integer() -%% BmFunctionName = atom() -%% -%% Runs all the benchmark tests described in <Bms>. -run_benchmarks(Comment,Bms) -> - Ver = erlang:system_info(version), - Machine = erlang:system_info(machine), - SysInfo = {Ver,Machine,Comment}, - - Res = [bms_run(Mod, Tests, Iter, SysInfo) || {Mod,Iter,Tests} <- Bms], - - %% Create an intermediate file that is later used to generate a bench - %% mark report. - Name = Ver ++ [$.|Machine] ++ Comment ++ ".bmres", - {ok, IntermediatFile} = file:open(Name, [write]), - - %% Create mark that identifies version of the benchmark modules - io:format(IntermediatFile, "~p.\n", [erlang:phash(Bms, ?RANGE_MAX)]), - - io:format(IntermediatFile, "~p.\n", [Res]), - file:close(IntermediatFile). - - -%% bms_run(Module, BmTests, Iter, Info) -> -%% Module = atom(), -%% BmTests = [BmFunctionName|_], -%% BmFunctionName = atom() -%% Iter = integer(), -%% SysInfo = {Ver, Machine} -%% Ver = string() -%% Machine = string() -%% -%% Runs all benchmark tests in module <Module>. -bms_run(Module, BmTests, Iter, SysInfo) -> - io:format("Running ~s:", [Module]), % Progress info to user - Res = - {Module,{SysInfo,[{Bm, bm_run(Module, Bm, Iter)} || Bm <- BmTests]}}, - io:nl(), - Res. - -%% bm_run(Module, BmTest, Iter) -> Elapsed -%% Module = atom(), -%% BmTest = atom(), -%% Iter = integer() -%% Elapsed = integer() - elapsed time in milliseconds. -%% -%% Runs the benchmark Module:BmTest(Iter) -bm_run(Module, BmTest, Iter) -> - io:format(" ~s", [BmTest]), % Progress info to user - spawn_link(?MODULE, measure, [self(), Module, BmTest, Iter]), - receive - {Elapsed, ok} -> - Elapsed; - {_Elapsed, Fault} -> - io:nl(), - Reason = - lists:flatten( - io_lib:format("~w", [Fault])), - exit(self(), Reason) - end. - -%% measure(Parent, Module, BmTest, Iter) -> _ -%% Parent = pid(), -%% Module = atom(), -%% BmTest = atom(), -%% Iter = integer() -%% -%% Measures the time it take to execute Module:Bm(Iter) -%% and send the result to <Parent>. -measure(Parent, Module, BmTest, Iter) -> - statistics(runtime), - Res = (catch apply(Module, BmTest, [Iter])), - {_TotalRunTime, TimeSinceLastCall} = statistics(runtime), - Parent ! {TimeSinceLastCall, Res}. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%% Report functions -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%% report() -> _ -%% -%% Creates a report of the bench marking test that appeals to a human. -%% Currently this means creating a html-file. (Other formats could be added) -report() -> - {ok, AllFiles} = file:list_dir("."), - BmResultFiles = [File || File <- AllFiles, lists:suffix(".bmres", File)], - - Results = fetch_bmres_data(BmResultFiles), - create_report(Results). - -%% fetch_bmres_data(BmResultFiles) -> Results -%% BmResultFiles = [FileName | _] -%% FileName = string() -%% Results = [[{Bm, Res} | _]] -%% Bm = atom() - Name of benchmark module -%% Res = [{VersionInfo, [{Test, Time} | _]}] -%% VersionInfo = {Ver, Machine} -%% Ver = string() -%% Machine = string() -%% Test = atom() -%% Time = integer() -%% -%% Reads result data from intermediate files -fetch_bmres_data(BmResultFiles) -> - fetch_bmres_data(BmResultFiles, [], undefined). - -%% fetch_bmres_data(BmResultFiles, AccResData, Check) -> Results -%% BmResultFiles = [FileName | _] -%% FileName = string() -%% AccResData = see Results fetch_bmres_data/1 -%% Check = integer() | undefined (first time) -%% -%% Help function to fetch_bmres_data/1 -fetch_bmres_data([], AccResData, _Check) -> - AccResData; - -fetch_bmres_data([Name | BmResultFiles], AccResData, Check) -> - {DataList, NewCheck} = read_bmres_file(Name, Check), - fetch_bmres_data(BmResultFiles, [DataList| AccResData], NewCheck). - - -%% read_bmres_file(Name, Check) -> -%% Name = string() -%% Check = integer() | undefined -%% -%% Reads the data from the result files. Checks that all result -%% files where created with the same set of tests. -read_bmres_file(Name, Check) -> - case file:consult(Name) of - {ok, [Check1, List]} when Check =:= undefined, integer(Check1) -> - {List, Check1}; - {ok, [Check, List]} when integer(Check) -> - {List, Check}; - {ok, [Check1, List]} when integer(Check1) -> - Reason = - lists:flatten( - io_lib:format("Different test setup, remove old setup " - "result by removing *.bmres files and " - "try again", [])), - exit(self(), Reason); - {error, Reason} when atom(Reason) -> - exit(self(), Reason); - {error, Reason} -> - exit(self(), file:format(Reason)) - end. - -%% create_report(Results) -> -%% Results = see Results fetch_bmres_data/1 -%% -%% Organizes <Result> so it will be right for create_html_report/1 -%% i.e. group results for the same benchmark test, run on different versions -%% of erlang. -create_report(Results) -> - Dictionary = - lists:foldl(fun(BmResultList, Dict0) -> - lists:foldl(fun({Bm, VerResult}, Dict1) -> - dict:append(Bm, VerResult, - Dict1) - end,Dict0, BmResultList) - end, - dict:new(), Results), - - create_html_report(dict:dict_to_list(Dictionary)). - -%% create_html_report(ResultList) -> _ -%% ResultList = [{Bm, Res} | _] -%% Bm = atom() - Name of benchmark module -%% Res = [{VersionInfo, [{Test, Time} | _]} | _] -%% VersionInfo = {Ver, Machine} -%% Ver = string() -%% Machine = string() -%% Test = atom() -%% Time = integer() -%% -%% Writes the result to an html-file -create_html_report(ResultList) -> - - {ok, OutputFile} = file:open("index.html", [write]), - - %% Create the begining of the result html-file. - Head = Title = "Benchmark Results", - io:put_chars(OutputFile, "<html>\n"), - io:put_chars(OutputFile, "<head>\n"), - io:format(OutputFile, "<title>~s</title>\n", [Title]), - io:put_chars(OutputFile, "</head>\n"), - io:put_chars(OutputFile, "<body bgcolor=\"#FFFFFF\" text=\"#000000\"" ++ - " link=\"#0000FF\" vlink=\"#800080\" alink=\"#FF0000\">\n"), - io:format(OutputFile, "<h1>~s</h1>\n", [Head]), - - %% Add the result tables - lists:foreach(fun(Element) -> - create_html_table(OutputFile, Element) end, - ResultList), - - %% Put in the end-html tags - io:put_chars(OutputFile, "</body>\n"), - io:put_chars(OutputFile, "</html>\n"), - - file:close(OutputFile). - -%% create_html_table(File, {Bm, Res}) -> _ -%% File = file() - html file to write data to. -%% Bm = atom() - Name of benchmark module -%% Res = [{VersionInfo, [{Test, Time} | _]}] -%% VersionInfo = {Ver, Machine} -%% Ver = string() -%% Machine = string() -%% Test = atom() -%% Time = integer() -%% -%% Creates a html table that displays the result of the benchmark <Bm>. -create_html_table(File, {Bm, Res}) -> - - {MinTime, Order} = min_time_and_sort(Res), - - io:format(File, "<h2>~s</h2>\n" , [Bm]), - - %% Fun that calculates relative measure values and puts them in - %% a dictionary - RelativeMesureFun = fun({TestName, Time}, Dict1) -> - dict:append(TestName, Time/MinTime, Dict1) - end, - - %% For all erlang versions that the benchmark tests has been run, - %% calculate the relative measure values and put them in a dictionary. - ResultDict = - lists:foldl(fun({_VerInfo, Bms}, Dict0) -> - lists:foldl(RelativeMesureFun, Dict0, Bms) end, - dict:new(), Res), - - %% Create the table and its headings - io:put_chars(File, "<table border=0 cellpadding=1><tr>" - "<td bgcolor=\"#000000\">\n"), - io:put_chars(File, "<table cellpadding=3 border=0 cellspacing=1>\n"), - io:put_chars(File, "<tr bgcolor=white>"), - io:put_chars(File, "<td>Test</td>"), - Heads = table_headers(Res), - lists:foreach(fun({Ver,Machine,Comment}) -> - io:format(File, "<td>~s<br>~s<br>~s</td>", - [Ver,Machine,Comment]) end, Heads), - io:put_chars(File, "</tr>\n"), - - %% Create table rows - lists:foreach(fun(Name) -> - create_html_row(File, Name, ResultDict) - end, Order), - - %% Tabel end-tags - io:put_chars(File, "</table></td></tr></table>\n"), - - %% Create link to benchmark source code - io:format(File, "<p><a href=\"~s.erl\">Source for ~s.erl</a>\n", - [Bm,Bm]). - -%% create_html_row(File, Name, Dict) -> _ -%% File = file() - html file to write data to. -%% Name = atom() - Name of benchmark test -%% Dict = dict() - Dictonary where the relative time measures for -%% the test can be found. -%% -%% Creates an actual html table-row. -create_html_row(File, Name, Dict) -> - ReletiveTimes = dict:fetch(Name, Dict), - io:put_chars(File, "<tr bgcolor=white>\n"), - io:format(File, "<td>~s</td>", [Name]), - lists:foreach(fun(Time) -> - io:format(File, "<td>~-8.2f</td>", [Time]) end, - ReletiveTimes), - io:put_chars(File, "</tr>\n"). - -%% min_time_and_sort(ResultList) -> {MinTime, Order} -%% ResultList = [{VersionInfo, [{Test, Time} | _]}] -%% MinTime = integer() - The execution time of the fastes test -%% Order = [BmFunctionName|_] - the order of the testcases in -%% increasing execution time. -%% BmFunctionName = atom() -min_time_and_sort(ResultList) -> - - %% Use the results from the run on the highest version - %% of Erlang as norm. - {_, TestRes} = - lists:foldl(fun ({Ver, ResList}, - CurrentVer) when Ver > CurrentVer -> - {Ver, ResList}; - (_, VerAndRes) -> - VerAndRes - end, {"0", []}, ResultList), - - {lists:foldl(fun ({_, Time0}, Min1) when Time0 < Min1 -> - Time0; - (_, Min1) -> - Min1 - end, ?MAX, TestRes), - [Name || {Name, _} <- lists:keysort(2, TestRes)]}. - - -%% table_headers(VerResultList) -> SysInfo -%% VerResultList = [{{Ver, Machine},[{BmFunctionName, Time}]} | _] -%% Ver = string() -%% Machine = string() -%% BmFunctionName = atom() -%% Time = integer() -%% SysInfo = {Ver, Machine} -table_headers(VerResultList) -> - [SysInfo || {SysInfo, _} <- VerResultList]. - - - diff --git a/lib/asn1/test/bench/per_bm.erl b/lib/asn1/test/bench/per_bm.erl deleted file mode 100644 index 23f8a8f010..0000000000 --- a/lib/asn1/test/bench/per_bm.erl +++ /dev/null @@ -1,650 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2002-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% -%% -%% --module(per_bm). - --define(DATADIR,"/clearcase/otp/erts/lib/asn1/test/asn1_SUITE_data/"). --include("bench.hrl"). - --export([init/0,benchmarks/0]). --export([encode/1,decode/1,ranap_enc/1,ranap_dec/1]). - - -init() -> - ok = asn1ct:compile(?DATADIR++"H235-SECURITY-MESSAGES",[per_bin]), - ok = asn1ct:compile(?DATADIR++"H323-MESSAGES",[per_bin]), - ok = asn1ct:compile("RanapASN1",[per_bin]), - ok. - - -benchmarks() -> - {5000,[encode,decode,ranap_enc,ranap_dec]}. - -ranap_dec(N) -> - V = ranap_v2(), - {ok,Bl} = asn1rt:encode('RanapASN1','RANAP-PDU',V), - B = list_to_binary(Bl), - ranap_n_dec(N,B), - ok. - -ranap_n_dec(0,_) -> - ok; -ranap_n_dec(N,B) -> - {ok,V}=asn1rt:decode('RanapASN1','RANAP-PDU',B), - ranap_n_dec(N-1,B). - -ranap_enc(N) -> - V = ranap_v2(), - ranap_n_enc(N,V), - ok. - -ranap_n_enc(0,V) -> - ok; -ranap_n_enc(N,V) -> - {ok,B} = asn1rt:encode('RanapASN1','RANAP-PDU',V), - ranap_n_enc(N-1,V). - - -decode(N) -> - V = v1(), - {ok,Bl} = asn1rt:encode('H323-MESSAGES','H323-UserInformation',V), - B = list_to_binary(Bl), - n_decode(N,B), - ok. - -n_decode(0,_) -> - ok; -n_decode(N,B) -> - {ok,V}=asn1rt:decode('H323-MESSAGES','H323-UserInformation',B), - n_decode(N-1,B). - - -v1() -> - V = - {'H323-UserInformation', - {'H323-UU-PDU', - {callProceeding, - {'CallProceeding-UUIE', - {0, - 7, - 180}, - {'EndpointType', - {'NonStandardParameter', - {object, - {0, - 8, - 202}}, - "O"}, - {'VendorIdentifier', - {'H221NonStandard', - 55, - 55, - 14277}, - "OC", - "OC"}, - {'GatekeeperInfo', - {'NonStandardParameter', - {object, - {0, - 9, - 232}}, - "O"}}, - {'GatewayInfo', - [{h320, - {'H320Caps', - {'NonStandardParameter', - {object, - {0, - 10, - 268}}, - "O"}, - [{'DataRate', - {'NonStandardParameter', - {object, - {0, - 11, - 284}}, - "O"}, - 1244176737, - 75}], - [{'SupportedPrefix', - {'NonStandardParameter', - {object, - {0, - 12, - 304}}, - "O"}, - {'h323-ID', - "BM"}}]}}], - {'NonStandardParameter', - {object, - {0, - 13, - 324}}, - "O"}}, - {'McuInfo', - {'NonStandardParameter', - {object, - {1, - 13, - 346, - 347}}, - "OC"}}, - {'TerminalInfo', - {'NonStandardParameter', - {object, - {1, - 14, - 363, - 363}}, - "OC"}}, - true, - true}, - {ipxAddress, - {'TransportAddress_ipxAddress', - "OCTET ", - "OCTE", - "OC"}}, - {'CallIdentifier', - "OCTET STRINGOCTE"}, - {noSecurity, - 'NULL'}, - [ -% {'ClearToken', -% 1703375497, -% "BM", -% {'DHset', -% [1], -% [1], -% [1]}, -% "OCTET STRI", -% -21825559, -% {'TypedCertificate', -% {1, -% 17, -% 424, -% 424}, -% "OC"}, -% "BMP", -% {'NonStandardParameter', -% {1, -% 17, -% 435, -% 436}, -% "OC"}}, - {'ClearToken', - 1929575502, - "BMP", - {'DHset', - [1], - [1], - [1]}, - "OCTET STRI", - -9591354, - {'TypedCertificate', - {1, - 18, - 471, - 471}, - "OC"}, - "BMP", - {'NonStandardParameter', - {1, - 19, - 482, - 483}, - "OC"}}], - [ -% {cryptoEPCert, -% {'CryptoH323Token_cryptoEPCert', -% {'ClearToken', -% 2227304001, -% "BMP", -% {'DHset', -% [1], -% [1], -% [1]}, -% "OCTET STRI", -% 9574387, -% {'TypedCertificate', -% {1, -% 21, -% 541, -% 542}, -% "OCT"}, -% "BMP", -% {'NonStandardParameter', -% {1, -% 22, -% 552, -% 553}, -% "OCT"}}, -% {1, -% 22, -% 559, -% 560}, -% {'Params', -% 18993485, -% "OCTET ST"}, -% [1, -% 0, -% 1]}}, - {cryptoEPCert, - {'CryptoH323Token_cryptoEPCert', - {'ClearToken', - 2581405450, - "BMPS", - {'DHset', - [1, - 0, - 1], - [1, - 0, - 1], - [1, - 0, - 1]}, - "OCTET STRIN", - 32050976, - {'TypedCertificate', - {1, - 25, - 625, - 625}, - "OCT"}, - "BMPS", - {'NonStandardParameter', - {1, - 25, - 636, - 637}, - "OCT"}}, - {1, - 25, - 644, - 645}, - {'Params', - 40708757, - "OCTET ST"}, - [1, - 0, - 1]}}], - ["OCT", - "OCT", - "OCT"]}}, - {'NonStandardParameter', - {h221NonStandard, - {'H221NonStandard', - 173, - 173, - 44666}}, - "OCTE"}, - ["OCTE", - "OCTE", - "OCTE", - "OCTE"], - true, - ["OCTE", - "OCTE", - "OCTE", - "OCTE"], - [ -% {'NonStandardParameter', -% {h221NonStandard, -% {'H221NonStandard', -% 182, -% 183, -% 46981}}, -% "OCTE"}, -% {'NonStandardParameter', -% {h221NonStandard, -% {'H221NonStandard', -% 186, -% 187, -% 48016}}, -% "OCTE"}, -% {'NonStandardParameter', -% {h221NonStandard, -% {'H221NonStandard', -% 190, -% 191, -% 49026}}, -% "OCTE"}, - {'NonStandardParameter', - {h221NonStandard, - {'H221NonStandard', - 195, - 196, - 50303}}, - "OCTE"}]}, - {'H323-UserInformation_user-data', - 197, - "OCTE"}}. - -encode(N) -> - V = v1(), - n_encode(N,V), - ok. - -n_encode(0,V) -> - ok; -n_encode(N,V) -> - {ok,B} = asn1rt:encode('H323-MESSAGES','H323-UserInformation',V), - n_encode(N-1,V). - - -ranap_v1() -> - {successfulOutcome, - {'SuccessfulOutcome', - 9, - ignore, - {'ResetAcknowledge', - [{'ProtocolIE-Field',3,ignore,'ps-domain'}, - {'ProtocolIE-Field', - 86, - ignore, - {'GlobalRNC-ID',"!Ce",2}}], - asn1_NOVALUE}}}. - -ranap_v2() -> - {initiatingMessage,{'InitiatingMessage', - 6, - {'Criticality',reject}, - {'SecurityModeCommand', - [{'ProtocolIE-Field', - 12, - {'Criticality',reject}, - {'IntegrityProtectionInformation', - ['standard-UMTS-integrity-algorithm-UIA1'], - [0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0], - asn1_NOVALUE}}, - {'ProtocolIE-Field', - 11, - {'Criticality',ignore}, - {'EncryptionInformation', - ['no-encryption', - 'standard-UMTS-encryption-algorith-UEA1'], - [0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1], - asn1_NOVALUE}}, - {'ProtocolIE-Field', - 75, - {'Criticality',reject}, - new}], - asn1_NOVALUE}}}. - - - - - - - diff --git a/lib/asn1/test/ber_decode_error.erl b/lib/asn1/test/ber_decode_error.erl index aa3b0122fd..96d6545636 100644 --- a/lib/asn1/test/ber_decode_error.erl +++ b/lib/asn1/test/ber_decode_error.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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% %% %% @@ -21,7 +21,7 @@ -export([run/1, compile/3]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config,Rules,Options) -> diff --git a/lib/asn1/test/choice_extension.erl b/lib/asn1/test/choice_extension.erl index 843704ee9e..85e0936ebf 100644 --- a/lib/asn1/test/choice_extension.erl +++ b/lib/asn1/test/choice_extension.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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% %% %% @@ -21,7 +21,7 @@ -export([run/0, compile/3]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config,Rules,Options) -> diff --git a/lib/asn1/test/h323test.erl b/lib/asn1/test/h323test.erl index 60d2c39be0..5545dd45b9 100644 --- a/lib/asn1/test/h323test.erl +++ b/lib/asn1/test/h323test.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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% %% %% @@ -21,7 +21,7 @@ -compile(export_all). -export([compile/3,run/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config,Rules,Options) -> ?line DataDir = ?config(data_dir,Config), diff --git a/lib/asn1/test/testChoExtension.erl b/lib/asn1/test/testChoExtension.erl index 125dfaa3bd..5e149ed247 100644 --- a/lib/asn1/test/testChoExtension.erl +++ b/lib/asn1/test/testChoExtension.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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([extension/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config,Rules,Options) -> diff --git a/lib/asn1/test/testChoExternal.erl b/lib/asn1/test/testChoExternal.erl index 5f804d9d7f..b6586b616b 100644 --- a/lib/asn1/test/testChoExternal.erl +++ b/lib/asn1/test/testChoExternal.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% %% %% @@ -23,7 +23,7 @@ -export([compile/3]). -export([external/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -include("External.hrl"). diff --git a/lib/asn1/test/testChoOptional.erl b/lib/asn1/test/testChoOptional.erl index 2d969391d0..61a1955d28 100644 --- a/lib/asn1/test/testChoOptional.erl +++ b/lib/asn1/test/testChoOptional.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% %% %% @@ -24,7 +24,7 @@ -export([optional/1]). %-include("ChoOptional.hrl"). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -include("External.hrl"). diff --git a/lib/asn1/test/testChoOptionalImplicitTag.erl b/lib/asn1/test/testChoOptionalImplicitTag.erl index 30addf2e20..e28353cb5a 100644 --- a/lib/asn1/test/testChoOptionalImplicitTag.erl +++ b/lib/asn1/test/testChoOptionalImplicitTag.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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% %% %% @@ -24,7 +24,7 @@ -export([optional/1]). %-include("ChoOptional.hrl"). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -include("External.hrl"). diff --git a/lib/asn1/test/testChoPrim.erl b/lib/asn1/test/testChoPrim.erl index 7fa6164b5a..f037db1c5d 100644 --- a/lib/asn1/test/testChoPrim.erl +++ b/lib/asn1/test/testChoPrim.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% %% %% @@ -23,7 +23,7 @@ -export([bool/1]). -export([int/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config,Rules,Options) -> diff --git a/lib/asn1/test/testChoRecursive.erl b/lib/asn1/test/testChoRecursive.erl index f8c5e60f55..36e23e2e03 100644 --- a/lib/asn1/test/testChoRecursive.erl +++ b/lib/asn1/test/testChoRecursive.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% %% %% @@ -23,7 +23,7 @@ -export([compile/3]). -export([recursive/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('ChoRec_something',{a, b, c}). -record('ChoRec2_something',{a, b, c}). diff --git a/lib/asn1/test/testChoTypeRefCho.erl b/lib/asn1/test/testChoTypeRefCho.erl index 341a77c21b..f381d9078d 100644 --- a/lib/asn1/test/testChoTypeRefCho.erl +++ b/lib/asn1/test/testChoTypeRefCho.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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([choice/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). diff --git a/lib/asn1/test/testChoTypeRefPrim.erl b/lib/asn1/test/testChoTypeRefPrim.erl index 1ef221819c..8fb9ed9f02 100644 --- a/lib/asn1/test/testChoTypeRefPrim.erl +++ b/lib/asn1/test/testChoTypeRefPrim.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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([prim/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). diff --git a/lib/asn1/test/testChoTypeRefSeq.erl b/lib/asn1/test/testChoTypeRefSeq.erl index 2e9aa7c411..45d6209e79 100644 --- a/lib/asn1/test/testChoTypeRefSeq.erl +++ b/lib/asn1/test/testChoTypeRefSeq.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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([seq/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('ChoSeq',{seqInt, seqOs}). -record('ChoSeqImp',{seqInt, seqOs}). diff --git a/lib/asn1/test/testChoTypeRefSet.erl b/lib/asn1/test/testChoTypeRefSet.erl index e4db73c1e3..9869549d7a 100644 --- a/lib/asn1/test/testChoTypeRefSet.erl +++ b/lib/asn1/test/testChoTypeRefSet.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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([set/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('ChoSet',{setInt, setOs}). -record('ChoSetImp',{setInt, setOs}). diff --git a/lib/asn1/test/testChoiceIndefinite.erl b/lib/asn1/test/testChoiceIndefinite.erl index 5eff4ce5d4..e5f3ee51c8 100644 --- a/lib/asn1/test/testChoiceIndefinite.erl +++ b/lib/asn1/test/testChoiceIndefinite.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config,Rules,Options) -> diff --git a/lib/asn1/test/testCompactBitString.erl b/lib/asn1/test/testCompactBitString.erl index 12aae260ea..cd5586602b 100644 --- a/lib/asn1/test/testCompactBitString.erl +++ b/lib/asn1/test/testCompactBitString.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% @@ -23,7 +23,7 @@ -export([compact_bit_string/1, bit_string_unnamed/1,otp_4869/1, ticket_7734/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config,Rules,Option) -> diff --git a/lib/asn1/test/testConstraints.erl b/lib/asn1/test/testConstraints.erl index f70089fe82..dcbc04f8d8 100644 --- a/lib/asn1/test/testConstraints.erl +++ b/lib/asn1/test/testConstraints.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% @@ -23,7 +23,7 @@ -export([int_constraints/1,refed_NNL_name/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). diff --git a/lib/asn1/test/testContextSwitchingTypes.erl b/lib/asn1/test/testContextSwitchingTypes.erl index 399c9ecaf7..260a016c6c 100644 --- a/lib/asn1/test/testContextSwitchingTypes.erl +++ b/lib/asn1/test/testContextSwitchingTypes.erl @@ -22,7 +22,7 @@ -export([compile/3]). -export([test/0]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config,Rules,Options) -> diff --git a/lib/asn1/test/testDER.erl b/lib/asn1/test/testDER.erl index 970e8dadd4..630f7ecc14 100644 --- a/lib/asn1/test/testDER.erl +++ b/lib/asn1/test/testDER.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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,7 +22,7 @@ -export([compile/3]). -export([test/0]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config,Rule,Options) -> diff --git a/lib/asn1/test/testDeepTConstr.erl b/lib/asn1/test/testDeepTConstr.erl index a185a127e5..53d2b3040e 100644 --- a/lib/asn1/test/testDeepTConstr.erl +++ b/lib/asn1/test/testDeepTConstr.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% @@ -23,7 +23,7 @@ -export([compile/3,main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config,Rules,Options) -> diff --git a/lib/asn1/test/testDef.erl b/lib/asn1/test/testDef.erl index aa41f7b678..7942a358be 100644 --- a/lib/asn1/test/testDef.erl +++ b/lib/asn1/test/testDef.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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('Def1',{bool0, bool1 = asn1_DEFAULT, diff --git a/lib/asn1/test/testDoubleEllipses.erl b/lib/asn1/test/testDoubleEllipses.erl index 444b06995f..20be4ea215 100644 --- a/lib/asn1/test/testDoubleEllipses.erl +++ b/lib/asn1/test/testDoubleEllipses.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('Seq',{a, c}). -record('SeqV2',{a, b ,c}). diff --git a/lib/asn1/test/testEnumExt.erl b/lib/asn1/test/testEnumExt.erl index 7e25aa9b4e..4ea0f3b8a1 100644 --- a/lib/asn1/test/testEnumExt.erl +++ b/lib/asn1/test/testEnumExt.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1998-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,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config,Rules,Options) -> diff --git a/lib/asn1/test/testExternal.erl b/lib/asn1/test/testExternal.erl index 3c3dc2ea29..6e1fa0ee7d 100644 --- a/lib/asn1/test/testExternal.erl +++ b/lib/asn1/test/testExternal.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% %% %% @@ -21,7 +21,7 @@ -export([compile/3]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config,Rules,Options) -> diff --git a/lib/asn1/test/testINSTANCE_OF.erl b/lib/asn1/test/testINSTANCE_OF.erl index 7f5b634e06..6ae656da44 100644 --- a/lib/asn1/test/testINSTANCE_OF.erl +++ b/lib/asn1/test/testINSTANCE_OF.erl @@ -21,7 +21,7 @@ -export([compile/3,main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config,Rules,Opt) -> diff --git a/lib/asn1/test/testInfObj.erl b/lib/asn1/test/testInfObj.erl index 317cd75e4b..9d73be9f23 100644 --- a/lib/asn1/test/testInfObj.erl +++ b/lib/asn1/test/testInfObj.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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,7 +22,7 @@ -export([compile/3,main/1,compile_RANAPfiles/3]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('InitiatingMessage',{procedureCode,criticality,value}). -record('InitiatingMessage2',{procedureCode,criticality,value}). diff --git a/lib/asn1/test/testInfObjectClass.erl b/lib/asn1/test/testInfObjectClass.erl index 63b332ad0a..07ebb7dbd0 100644 --- a/lib/asn1/test/testInfObjectClass.erl +++ b/lib/asn1/test/testInfObjectClass.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% @@ -23,7 +23,7 @@ -export([compile/3,main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). diff --git a/lib/asn1/test/testMegaco.erl b/lib/asn1/test/testMegaco.erl index 50bc6e7dee..ca2b1062d1 100644 --- a/lib/asn1/test/testMegaco.erl +++ b/lib/asn1/test/testMegaco.erl @@ -22,7 +22,7 @@ -export([compile/3,main/2,msg11/0]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -define(MID, {ip4Address, #'IP4Address'{address = [124, 124, 124, 222], portNumber = 55555}}). -define(A4444, ["11111111"]). diff --git a/lib/asn1/test/testMergeCompile.erl b/lib/asn1/test/testMergeCompile.erl index e70ca16b77..733cbc0eef 100644 --- a/lib/asn1/test/testMergeCompile.erl +++ b/lib/asn1/test/testMergeCompile.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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,7 +22,7 @@ -export([compile/3,main/1,mvrasn/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('InitiatingMessage',{procedureCode,criticality,value}). -record('Iu-ReleaseCommand',{protocolIEs,protocolExtensions}). diff --git a/lib/asn1/test/testMvrasn6.erl b/lib/asn1/test/testMvrasn6.erl index 65668f3ed4..eaa667e6d7 100644 --- a/lib/asn1/test/testMvrasn6.erl +++ b/lib/asn1/test/testMvrasn6.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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,7 +22,7 @@ -export([compile/2]). -export([main/0]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config,Rules) -> diff --git a/lib/asn1/test/testNBAPsystem.erl b/lib/asn1/test/testNBAPsystem.erl index 79e553a596..1269f94060 100644 --- a/lib/asn1/test/testNBAPsystem.erl +++ b/lib/asn1/test/testNBAPsystem.erl @@ -21,7 +21,7 @@ -export([compile/3,test/2,cell_setup_req_msg/0]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('InitiatingMessage',{ procedureID, criticality, messageDiscriminator, transactionID, value}). diff --git a/lib/asn1/test/testOpenTypeImplicitTag.erl b/lib/asn1/test/testOpenTypeImplicitTag.erl index 4300509e07..8662744ed3 100644 --- a/lib/asn1/test/testOpenTypeImplicitTag.erl +++ b/lib/asn1/test/testOpenTypeImplicitTag.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config,Rules,Options) -> diff --git a/lib/asn1/test/testOpt.erl b/lib/asn1/test/testOpt.erl index 2967595fd2..a1ad8099b5 100644 --- a/lib/asn1/test/testOpt.erl +++ b/lib/asn1/test/testOpt.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% %% %% @@ -22,7 +22,7 @@ -export([compile/2]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('Opt1',{bool0, bool1 = asn1_NOVALUE, diff --git a/lib/asn1/test/testParamBasic.erl b/lib/asn1/test/testParamBasic.erl index 172a2881cd..4ba0029b54 100644 --- a/lib/asn1/test/testParamBasic.erl +++ b/lib/asn1/test/testParamBasic.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% @@ -23,7 +23,7 @@ -export([compile_der/2]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('T11',{number, string=asn1_DEFAULT}). -record('T12',{number, string=asn1_DEFAULT}). diff --git a/lib/asn1/test/testParameterizedInfObj.erl b/lib/asn1/test/testParameterizedInfObj.erl index 91d160f335..b95d627d58 100644 --- a/lib/asn1/test/testParameterizedInfObj.erl +++ b/lib/asn1/test/testParameterizedInfObj.erl @@ -22,7 +22,7 @@ -export([compile/3,main/1,ranap/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('AllocationOrRetentionPriority',{priorityLevel,iE_Extensions}). -record('ProtocolExtensionField',{id,criticality,extensionValue}). diff --git a/lib/asn1/test/testPrim.erl b/lib/asn1/test/testPrim.erl index 4ccdd82c13..97f99e7b1c 100644 --- a/lib/asn1/test/testPrim.erl +++ b/lib/asn1/test/testPrim.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% %% %% @@ -28,7 +28,7 @@ -export([null/1]). -export([real/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). diff --git a/lib/asn1/test/testPrimExternal.erl b/lib/asn1/test/testPrimExternal.erl index 2a6384009a..23633177eb 100644 --- a/lib/asn1/test/testPrimExternal.erl +++ b/lib/asn1/test/testPrimExternal.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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([external/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config,Rules,Options) -> diff --git a/lib/asn1/test/testPrimStrings.erl b/lib/asn1/test/testPrimStrings.erl index a2252ba99b..33652d6554 100644 --- a/lib/asn1/test/testPrimStrings.erl +++ b/lib/asn1/test/testPrimStrings.erl @@ -31,7 +31,7 @@ -export([times/1]). -export([utf8_string/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config,Rules,Option) -> diff --git a/lib/asn1/test/testRANAP.erl b/lib/asn1/test/testRANAP.erl index 7c35674d3a..52a58d850b 100644 --- a/lib/asn1/test/testRANAP.erl +++ b/lib/asn1/test/testRANAP.erl @@ -22,7 +22,7 @@ -export([compile/3,testobj/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config,Erule,Options) -> diff --git a/lib/asn1/test/testROSE.erl b/lib/asn1/test/testROSE.erl index 65851e21fc..a692ec7682 100644 --- a/lib/asn1/test/testROSE.erl +++ b/lib/asn1/test/testROSE.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% @@ -21,7 +21,7 @@ -export([compile/3]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). diff --git a/lib/asn1/test/testSSLspecs.erl b/lib/asn1/test/testSSLspecs.erl index 87e5e5fd02..10623af51e 100644 --- a/lib/asn1/test/testSSLspecs.erl +++ b/lib/asn1/test/testSSLspecs.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% 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% %% %% @@ -22,7 +22,7 @@ -export([compile/3,run/1,compile_inline/2,run_inline/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config,Rules,Options) -> diff --git a/lib/asn1/test/testSelectionTypes.erl b/lib/asn1/test/testSelectionTypes.erl index a3876c259e..893c31622f 100644 --- a/lib/asn1/test/testSelectionTypes.erl +++ b/lib/asn1/test/testSelectionTypes.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% 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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([test/0]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config,Rule,Options) -> diff --git a/lib/asn1/test/testSeq2738.erl b/lib/asn1/test/testSeq2738.erl index 0f3c4b7bf7..9cf9c8fcb4 100644 --- a/lib/asn1/test/testSeq2738.erl +++ b/lib/asn1/test/testSeq2738.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). %-record('SeqOpt',{int, opt = asn1_NOVALUE}). -record('SeqOptFake',{int, opt = asn1_NOVALUE}). diff --git a/lib/asn1/test/testSeqDefault.erl b/lib/asn1/test/testSeqDefault.erl index a626bfd645..edf07cf1c1 100644 --- a/lib/asn1/test/testSeqDefault.erl +++ b/lib/asn1/test/testSeqDefault.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% %% %% @@ -23,7 +23,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('SeqDef1',{bool1 = asn1_DEFAULT, int1, seq1 = asn1_DEFAULT}). -record('SeqDef1Imp',{bool1 = asn1_DEFAULT, int1, seq1 = asn1_DEFAULT}). diff --git a/lib/asn1/test/testSeqExtension.erl b/lib/asn1/test/testSeqExtension.erl index 4ddaddb8f1..538e2c250b 100644 --- a/lib/asn1/test/testSeqExtension.erl +++ b/lib/asn1/test/testSeqExtension.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% %% %% @@ -23,7 +23,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('SeqExt1',{}). -record('SeqExt2',{bool, int}). diff --git a/lib/asn1/test/testSeqExternal.erl b/lib/asn1/test/testSeqExternal.erl index f148d32b21..b89b98d3fa 100644 --- a/lib/asn1/test/testSeqExternal.erl +++ b/lib/asn1/test/testSeqExternal.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% %% %% @@ -23,7 +23,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('SeqXSet1',{set, bool, int}). diff --git a/lib/asn1/test/testSeqIndefinite.erl b/lib/asn1/test/testSeqIndefinite.erl index b1b622bdfa..9285d7b368 100644 --- a/lib/asn1/test/testSeqIndefinite.erl +++ b/lib/asn1/test/testSeqIndefinite.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config,Rules,Options) -> diff --git a/lib/asn1/test/testSeqOf.erl b/lib/asn1/test/testSeqOf.erl index 71556ed746..961e2d89d9 100644 --- a/lib/asn1/test/testSeqOf.erl +++ b/lib/asn1/test/testSeqOf.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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('Seq1',{bool1, int1, seq1 = asn1_DEFAULT}). -record('Seq2',{seq2 = asn1_DEFAULT, bool2, int2}). diff --git a/lib/asn1/test/testSeqOfCho.erl b/lib/asn1/test/testSeqOfCho.erl index eefb258346..05bd45580f 100644 --- a/lib/asn1/test/testSeqOfCho.erl +++ b/lib/asn1/test/testSeqOfCho.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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('SeqChoDef',{bool1, int1, seq1 = asn1_DEFAULT}). -record('SeqChoOpt',{bool1, int1, seq1 = asn1_NOVALUE}). diff --git a/lib/asn1/test/testSeqOfExternal.erl b/lib/asn1/test/testSeqOfExternal.erl index dde36e6949..4c4c9e2b0f 100644 --- a/lib/asn1/test/testSeqOfExternal.erl +++ b/lib/asn1/test/testSeqOfExternal.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% %% %% @@ -23,7 +23,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -include("External.hrl"). -record('NT',{os, bool}). diff --git a/lib/asn1/test/testSeqOfIndefinite.erl b/lib/asn1/test/testSeqOfIndefinite.erl index 8e8967572a..0221581cf1 100644 --- a/lib/asn1/test/testSeqOfIndefinite.erl +++ b/lib/asn1/test/testSeqOfIndefinite.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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,7 +22,7 @@ -export([compile/3]). -export([main/0]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). %-record('Seq1',{bool1, int1, seq1 = asn1_DEFAULT}). %-record('Seq2',{seq2 = asn1_DEFAULT, bool2, int2}). diff --git a/lib/asn1/test/testSeqOfTag.erl b/lib/asn1/test/testSeqOfTag.erl index 0a4e1397a6..4f56ab717b 100644 --- a/lib/asn1/test/testSeqOfTag.erl +++ b/lib/asn1/test/testSeqOfTag.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% %% %% @@ -23,7 +23,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -include("External.hrl"). diff --git a/lib/asn1/test/testSeqOptional.erl b/lib/asn1/test/testSeqOptional.erl index 7177011427..0125c9fb3e 100644 --- a/lib/asn1/test/testSeqOptional.erl +++ b/lib/asn1/test/testSeqOptional.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% %% %% @@ -23,7 +23,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('SeqOpt1',{bool1 = asn1_NOVALUE, int1, seq1 = asn1_NOVALUE}). -record('SeqOpt1Imp',{bool1 = asn1_NOVALUE, int1, seq1 = asn1_NOVALUE}). diff --git a/lib/asn1/test/testSeqPrim.erl b/lib/asn1/test/testSeqPrim.erl index 7ad1de58a1..ec48d1b779 100644 --- a/lib/asn1/test/testSeqPrim.erl +++ b/lib/asn1/test/testSeqPrim.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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('Seq',{bool, boolCon, boolPri, boolApp, boolExpCon, boolExpPri, boolExpApp}). -record('Empty',{}). diff --git a/lib/asn1/test/testSeqSetDefaultVal.erl b/lib/asn1/test/testSeqSetDefaultVal.erl index 1c238fd1b7..5a1a443ebc 100644 --- a/lib/asn1/test/testSeqSetDefaultVal.erl +++ b/lib/asn1/test/testSeqSetDefaultVal.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% @@ -23,7 +23,7 @@ -export([compile/2]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('SeqInts',{a = asn1_DEFAULT, b = asn1_DEFAULT, diff --git a/lib/asn1/test/testSeqTag.erl b/lib/asn1/test/testSeqTag.erl index ff6d1bbe91..60d3629840 100644 --- a/lib/asn1/test/testSeqTag.erl +++ b/lib/asn1/test/testSeqTag.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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -include("External.hrl"). -record('SeqTag',{nt, imp, exp}). diff --git a/lib/asn1/test/testSeqTypeRefCho.erl b/lib/asn1/test/testSeqTypeRefCho.erl index 03933d68ae..9262fd1bfd 100644 --- a/lib/asn1/test/testSeqTypeRefCho.erl +++ b/lib/asn1/test/testSeqTypeRefCho.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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -include("External.hrl"). -record('SeqTRcho',{seqCho, seqChoE, 'seqCho-E', 'seqChoE-E'}). diff --git a/lib/asn1/test/testSeqTypeRefPrim.erl b/lib/asn1/test/testSeqTypeRefPrim.erl index 264fc24f85..7d4c2acc0e 100644 --- a/lib/asn1/test/testSeqTypeRefPrim.erl +++ b/lib/asn1/test/testSeqTypeRefPrim.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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('SeqTR',{octStr, octStrI, octStrE, 'octStr-I', 'octStrI-I', 'octStrE-I', 'octStr-E', 'octStrI-E', 'octStrE-E'}). diff --git a/lib/asn1/test/testSeqTypeRefSeq.erl b/lib/asn1/test/testSeqTypeRefSeq.erl index b01c14ee32..51b0f13c57 100644 --- a/lib/asn1/test/testSeqTypeRefSeq.erl +++ b/lib/asn1/test/testSeqTypeRefSeq.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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('Seq1',{bool1, int1, seq1}). -record('Seq2',{seq2, bool2, int2}). diff --git a/lib/asn1/test/testSeqTypeRefSet.erl b/lib/asn1/test/testSeqTypeRefSet.erl index 92d2cadf28..a704ce3403 100644 --- a/lib/asn1/test/testSeqTypeRefSet.erl +++ b/lib/asn1/test/testSeqTypeRefSet.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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('SeqTRset',{seqSet, seqSetI, seqSetE, 'seqSet-I', 'seqSetI-I', 'seqSetE-I', 'seqSet-E', 'seqSetI-E', 'seqSetE-E'}). -record('SeqSet',{setInt, setOs}). diff --git a/lib/asn1/test/testSetDefault.erl b/lib/asn1/test/testSetDefault.erl index e4b6a0ab82..e36894327c 100644 --- a/lib/asn1/test/testSetDefault.erl +++ b/lib/asn1/test/testSetDefault.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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('SetDef1',{bool1 = asn1_DEFAULT, int1, set1 = asn1_DEFAULT}). -record('SetDef2',{set2 = asn1_DEFAULT, bool2, int2}). diff --git a/lib/asn1/test/testSetExtension.erl b/lib/asn1/test/testSetExtension.erl index 85a84e020a..c7fb3b42c4 100644 --- a/lib/asn1/test/testSetExtension.erl +++ b/lib/asn1/test/testSetExtension.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% %% %% @@ -24,7 +24,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('SetExt1',{}). -record('SetExt2',{bool, int}). diff --git a/lib/asn1/test/testSetExternal.erl b/lib/asn1/test/testSetExternal.erl index 83974a5499..41f32dcd90 100644 --- a/lib/asn1/test/testSetExternal.erl +++ b/lib/asn1/test/testSetExternal.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% %% %% @@ -23,7 +23,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('SetXSeq1',{seq, bool, int}). diff --git a/lib/asn1/test/testSetIndefinite.erl b/lib/asn1/test/testSetIndefinite.erl index 0e6a86bac4..bf8b242860 100644 --- a/lib/asn1/test/testSetIndefinite.erl +++ b/lib/asn1/test/testSetIndefinite.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config,Rules,Options) -> diff --git a/lib/asn1/test/testSetOf.erl b/lib/asn1/test/testSetOf.erl index fe68a0705a..0769b9a344 100644 --- a/lib/asn1/test/testSetOf.erl +++ b/lib/asn1/test/testSetOf.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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('Set1',{bool1, int1, set1 = asn1_DEFAULT}). -record('Set2',{set2 = asn1_DEFAULT, bool2, int2}). diff --git a/lib/asn1/test/testSetOfCho.erl b/lib/asn1/test/testSetOfCho.erl index f3164273f6..474742fbdb 100644 --- a/lib/asn1/test/testSetOfCho.erl +++ b/lib/asn1/test/testSetOfCho.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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('SetChoDef',{bool1, int1, set1 = asn1_DEFAULT}). -record('SetChoOpt',{bool1, int1, set1 = asn1_NOVALUE}). diff --git a/lib/asn1/test/testSetOfExternal.erl b/lib/asn1/test/testSetOfExternal.erl index 1c59ad0a74..9e2b01c698 100644 --- a/lib/asn1/test/testSetOfExternal.erl +++ b/lib/asn1/test/testSetOfExternal.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% %% %% @@ -23,7 +23,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -include("External.hrl"). -record('NT',{os, bool}). diff --git a/lib/asn1/test/testSetOfTag.erl b/lib/asn1/test/testSetOfTag.erl index ff59a329e3..c101306d7a 100644 --- a/lib/asn1/test/testSetOfTag.erl +++ b/lib/asn1/test/testSetOfTag.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% %% %% @@ -23,7 +23,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -include("External.hrl"). diff --git a/lib/asn1/test/testSetOptional.erl b/lib/asn1/test/testSetOptional.erl index 3df1ed58bb..035fa70424 100644 --- a/lib/asn1/test/testSetOptional.erl +++ b/lib/asn1/test/testSetOptional.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% %% %% @@ -23,7 +23,7 @@ -export([compile/3]). -export([main/1]). -export([ticket_7533/1,decoder/4]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('SetOpt1',{bool1 = asn1_NOVALUE, int1, set1 = asn1_NOVALUE}). -record('SetOpt1Imp',{bool1 = asn1_NOVALUE, int1, set1 = asn1_NOVALUE}). diff --git a/lib/asn1/test/testSetPrim.erl b/lib/asn1/test/testSetPrim.erl index cb64011dcc..e093c918e3 100644 --- a/lib/asn1/test/testSetPrim.erl +++ b/lib/asn1/test/testSetPrim.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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('Set',{bool, boolCon, boolPri, boolApp, boolExpCon, boolExpPri, boolExpApp}). -record('Empty',{}). diff --git a/lib/asn1/test/testSetTag.erl b/lib/asn1/test/testSetTag.erl index fcf15dc0f0..8df3e36815 100644 --- a/lib/asn1/test/testSetTag.erl +++ b/lib/asn1/test/testSetTag.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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -include("External.hrl"). -record('SetTag',{nt, imp, exp}). diff --git a/lib/asn1/test/testSetTypeRefCho.erl b/lib/asn1/test/testSetTypeRefCho.erl index c2dbf076bd..1f68a8fbc4 100644 --- a/lib/asn1/test/testSetTypeRefCho.erl +++ b/lib/asn1/test/testSetTypeRefCho.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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -include("External.hrl"). -record('SetTRcho',{setCho, setChoE, 'setCho-E', 'setChoE-E'}). diff --git a/lib/asn1/test/testSetTypeRefPrim.erl b/lib/asn1/test/testSetTypeRefPrim.erl index 1f95947168..e6cec260e5 100644 --- a/lib/asn1/test/testSetTypeRefPrim.erl +++ b/lib/asn1/test/testSetTypeRefPrim.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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('SetTR',{octStr, octStrI, octStrE, 'octStr-I', 'octStrI-I', 'octStrE-I', 'octStr-E', 'octStrI-E', 'octStrE-E'}). diff --git a/lib/asn1/test/testSetTypeRefSeq.erl b/lib/asn1/test/testSetTypeRefSeq.erl index 2f6dfec9c6..0c1c9400bf 100644 --- a/lib/asn1/test/testSetTypeRefSeq.erl +++ b/lib/asn1/test/testSetTypeRefSeq.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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('SetTRseq',{setSeq, setSeqI, setSeqE, 'setSeq-I', 'setSeqI-I', 'setSeqE-I', 'setSeq-E', 'setSeqI-E', 'setSeqE-E'}). -record('SetSeq',{seqInt, seqOs}). diff --git a/lib/asn1/test/testSetTypeRefSet.erl b/lib/asn1/test/testSetTypeRefSet.erl index 132e5fb3f5..6544e77458 100644 --- a/lib/asn1/test/testSetTypeRefSet.erl +++ b/lib/asn1/test/testSetTypeRefSet.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% %% %% @@ -22,7 +22,7 @@ -export([compile/3]). -export([main/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('Set1',{bool1, int1, set1}). -record('Set2',{set2, bool2, int2}). diff --git a/lib/asn1/test/testTCAP.erl b/lib/asn1/test/testTCAP.erl index 3e2c2de371..5e29938a16 100644 --- a/lib/asn1/test/testTCAP.erl +++ b/lib/asn1/test/testTCAP.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% @@ -21,7 +21,7 @@ -export([compile/3,test/2,compile_asn1config/3,test_asn1config/0]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). diff --git a/lib/asn1/test/testTcapsystem.erl b/lib/asn1/test/testTcapsystem.erl index c48b1b835d..2f13c11cd4 100644 --- a/lib/asn1/test/testTcapsystem.erl +++ b/lib/asn1/test/testTcapsystem.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% 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% %% %% @@ -21,7 +21,7 @@ -export([compile/3]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). diff --git a/lib/asn1/test/testTimer.erl b/lib/asn1/test/testTimer.erl index 34b9cf1740..74002e16e9 100644 --- a/lib/asn1/test/testTimer.erl +++ b/lib/asn1/test/testTimer.erl @@ -22,7 +22,7 @@ -compile(export_all). %%-export([Function/Arity, ...]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -define(times, 5000). diff --git a/lib/asn1/test/testTypeValueNotation.erl b/lib/asn1/test/testTypeValueNotation.erl index 0fc3dc3197..f0699370e0 100644 --- a/lib/asn1/test/testTypeValueNotation.erl +++ b/lib/asn1/test/testTypeValueNotation.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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,7 +22,7 @@ -export([compile/3]). -export([main/2]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -record('Seq',{octstr, int, bool, enum, bitstr, null, oid, vstr}). diff --git a/lib/asn1/test/testX420.erl b/lib/asn1/test/testX420.erl index 314c5c837a..1d18e76c48 100644 --- a/lib/asn1/test/testX420.erl +++ b/lib/asn1/test/testX420.erl @@ -23,7 +23,7 @@ -export([compile/3, ticket7759/2]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Erule,Options,Config) -> diff --git a/lib/asn1/test/test_bad_values.erl b/lib/asn1/test/test_bad_values.erl index 0190b6ee9a..d379a509ab 100644 --- a/lib/asn1/test/test_bad_values.erl +++ b/lib/asn1/test/test_bad_values.erl @@ -1,26 +1,26 @@ %% %% %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 %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% -module(test_bad_values). -export([tests/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). tests(Config) -> ?line DataDir = ?config(data_dir,Config), diff --git a/lib/asn1/test/test_compile_options.erl b/lib/asn1/test/test_compile_options.erl index a6e0caa0f1..5e027cdedb 100644 --- a/lib/asn1/test/test_compile_options.erl +++ b/lib/asn1/test/test_compile_options.erl @@ -1,30 +1,30 @@ %% %% %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 %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% -module(test_compile_options). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -export([wrong_path/1,comp/2,path/1,ticket_6143/1,noobj/1, - record_name_prefix/1]). + record_name_prefix/1,verbose/1]). %% OTP-5689 wrong_path(Config) -> @@ -122,6 +122,25 @@ noobj(Config) -> file:delete(filename:join([OutDir,'p_record.erl'])), file:delete(filename:join([OutDir,'p_record.beam'])). +verbose(Config) when is_list(Config) -> + DataDir = ?config(data_dir,Config), + OutDir = ?config(priv_dir,Config), + Asn1File = filename:join([DataDir,"Comment.asn"]), + + %% Test verbose compile + ?line test_server:capture_start(), + ?line ok = asn1ct:compile(Asn1File, [{i,DataDir},{outdir,OutDir},noobj,verbose]), + ?line test_server:capture_stop(), + ?line [Line0|_] = test_server:capture_get(), + ?line true = lists:prefix("Erlang ASN.1 version", Line0), + + %% Test non-verbose compile + ?line test_server:capture_start(), + ?line ok = asn1ct:compile(Asn1File, [{i,DataDir},{outdir,OutDir},noobj]), + ?line test_server:capture_stop(), + ?line [] = test_server:capture_get(), + ok. + outfiles_check(OutDir) -> outfiles_check(OutDir,outfiles1()). diff --git a/lib/asn1/test/test_driver_load.erl b/lib/asn1/test/test_driver_load.erl index 37a7e36a45..965f2473e9 100644 --- a/lib/asn1/test/test_driver_load.erl +++ b/lib/asn1/test/test_driver_load.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% @@ -21,7 +21,7 @@ -export([compile/2,test/2,encode/0]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). test(per_bin,0) -> diff --git a/lib/asn1/test/test_inline.erl b/lib/asn1/test/test_inline.erl index aac003baf6..dfa3c134ae 100644 --- a/lib/asn1/test/test_inline.erl +++ b/lib/asn1/test/test_inline.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% 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% %% %% @@ -23,7 +23,7 @@ -export([mvrasn_inlined_encdec/2,mvrasn_encdec/2, mi_encdec/2,m_encdec/2]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -define(times, 5000). -define(times2, 50000). diff --git a/lib/asn1/test/test_modified_x420.erl b/lib/asn1/test/test_modified_x420.erl index 93fcd73eaf..4e96db070b 100644 --- a/lib/asn1/test/test_modified_x420.erl +++ b/lib/asn1/test/test_modified_x420.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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,7 +22,7 @@ %-compile(export_all). -export([compile/1, test_io/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config) -> ?line DataDir = ?config(data_dir,Config), diff --git a/lib/asn1/test/test_partial_incomplete_decode.erl b/lib/asn1/test/test_partial_incomplete_decode.erl index 9fd078e952..a2e0a96bd8 100644 --- a/lib/asn1/test/test_partial_incomplete_decode.erl +++ b/lib/asn1/test/test_partial_incomplete_decode.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% @@ -21,7 +21,7 @@ -export([compile/3,test/2]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). diff --git a/lib/asn1/test/test_selective_decode.erl b/lib/asn1/test/test_selective_decode.erl index 94d3d5f34a..e1e101b622 100644 --- a/lib/asn1/test/test_selective_decode.erl +++ b/lib/asn1/test/test_selective_decode.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% @@ -21,7 +21,7 @@ -export([test/2]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). test(ber_bin_v2,_Config) -> diff --git a/lib/asn1/test/test_special_decode_performance.erl b/lib/asn1/test/test_special_decode_performance.erl index c451d65172..60a95a3675 100644 --- a/lib/asn1/test/test_special_decode_performance.erl +++ b/lib/asn1/test/test_special_decode_performance.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% @@ -21,7 +21,7 @@ -export([compile/2,go/1,loop2/4,loop1/5]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config,Rule) when Rule==ber_bin_v2 -> diff --git a/lib/asn1/test/test_undecoded_rest.erl b/lib/asn1/test/test_undecoded_rest.erl index d2c98e130d..647fe2bb1c 100644 --- a/lib/asn1/test/test_undecoded_rest.erl +++ b/lib/asn1/test/test_undecoded_rest.erl @@ -21,7 +21,7 @@ -export([compile/3,test/1]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). %% testing OTP-5104 @@ -42,7 +42,7 @@ test(Opt) -> fun(B) when is_list(B) -> B ++ [55,55,55]; (B) when is_binary(B) -> - erlang:list_to_binary([B,<<55,55,55>>]) + iolist_to_binary([B,<<55,55,55>>]) end (Bytes), case Opt of diff --git a/lib/asn1/test/test_x691.erl b/lib/asn1/test/test_x691.erl index 5bf3a4a077..bc8a3495d8 100644 --- a/lib/asn1/test/test_x691.erl +++ b/lib/asn1/test/test_x691.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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,7 +22,7 @@ -export([compile/3]). -export([cases/2]). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). compile(Config,Rules,Option) -> diff --git a/lib/asn1/vsn.mk b/lib/asn1/vsn.mk index 20ee8ac6ff..0399ff2732 100644 --- a/lib/asn1/vsn.mk +++ b/lib/asn1/vsn.mk @@ -1,318 +1,2 @@ -#next version number to use is 1.6.14 | 1.7 | 2.0 -ASN1_VSN = 1.6.13.2 - -TICKETS = OTP-8463 - -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 - +#next version number to use is 1.6.15 | 1.7 | 2.0 +ASN1_VSN = 1.6.14.1 diff --git a/lib/common_test/AUTHORS b/lib/common_test/AUTHORS index 152ec1868f..ff443e89e8 100644 --- a/lib/common_test/AUTHORS +++ b/lib/common_test/AUTHORS @@ -5,3 +5,4 @@ Siri Hansen Kenneth Lundin Ingela Anderton Niclas Eklund +Andrey Pampukha diff --git a/lib/common_test/Makefile b/lib/common_test/Makefile index ebca4523ab..aecec1a50d 100644 --- a/lib/common_test/Makefile +++ b/lib/common_test/Makefile @@ -1,19 +1,19 @@ # # %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 # 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% # diff --git a/lib/common_test/doc/src/Makefile b/lib/common_test/doc/src/Makefile index a2c014418d..6322860088 100644 --- a/lib/common_test/doc/src/Makefile +++ b/lib/common_test/doc/src/Makefile @@ -45,7 +45,8 @@ CT_MODULES = \ ct_ssh \ ct_rpc \ ct_snmp \ - unix_telnet + unix_telnet \ + ct_slave CT_XML_FILES = $(CT_MODULES:=.xml) diff --git a/lib/common_test/doc/src/common_test_app.xml b/lib/common_test/doc/src/common_test_app.xml index 7b52883f8a..e30eef2488 100644 --- a/lib/common_test/doc/src/common_test_app.xml +++ b/lib/common_test/doc/src/common_test_app.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>2003</year><year>2009</year> + <year>2003</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>Common Test</title> @@ -337,7 +337,7 @@ </func> <func> - <name>Module:testcase() -> [Info] </name> + <name>Module:Testcase() -> [Info] </name> <fsummary>Test case info function. </fsummary> <type> <v> Info = {timetrap,Time} | {require,Required} | @@ -396,7 +396,7 @@ <func> - <name>Module:testcase(Config) -> void() | {skip,Reason} | {comment,Comment} | {save_config,SaveConfig} | {skip_and_save,Reason,SaveConfig} | exit() </name> + <name>Module:Testcase(Config) -> void() | {skip,Reason} | {comment,Comment} | {save_config,SaveConfig} | {skip_and_save,Reason,SaveConfig} | exit() </name> <fsummary>A test case</fsummary> <type> <v> Config = SaveConfig = [{Key,Value}]</v> diff --git a/lib/common_test/doc/src/config_file_chapter.xml b/lib/common_test/doc/src/config_file_chapter.xml index a22a5270c1..77b0c0c0b7 100644 --- a/lib/common_test/doc/src/config_file_chapter.xml +++ b/lib/common_test/doc/src/config_file_chapter.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> @@ -13,15 +13,15 @@ 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>Config Files</title> + <title>External Configuration Data</title> <prepared>Siri Hansen, Peter Andersson</prepared> <docno></docno> <date></date> @@ -32,16 +32,19 @@ <section> <title>General</title> - <p>The Common Test framework uses configuration files to - describe data related to a test and/or an SUT (System Under Test). - The configuration data makes it possible to change properties without - changing the test program itself. Configuration data can for example be:</p> + <p>To avoid hard coding data values related to the test and/or SUT (System + Under Test) in the test suites, the data may instead be specified by means + of configuration files or strings that Common Test reads before + the start of a test run. External configuration data makes it possible to + change test properties without having to modify the actual test suites + using the data. Examples of configuration data:</p> <list> <item>Addresses to the test plant or other instruments</item> - <item>Filenames for files needed by the test</item> - <item>Program names for programs that shall be run by the test</item> - <item>Any other variable that is needed by the test</item> + <item>User login information</item> + <item>Names of files needed by the test</item> + <item>Names of programs that should be executed during the test</item> + <item>Any other variable needed by the test</item> </list> </section> @@ -51,12 +54,12 @@ <p>A configuration file can contain any number of elements of the type:</p> <pre> - {Key,Value}.</pre> + {CfgVarName,Value}.</pre> <p>where</p> <pre> - Key = atom() - Value = term() | [{Key,Value}]</pre> + CfgVarName = atom() + Value = term() | [{CfgVarName,Value}]</pre> </section> @@ -65,8 +68,8 @@ <marker id="require_config_data"></marker> <p>In a test suite, one must <em>require</em> that a configuration - variable exists before attempting to read the associated - value in a test case.</p> + variable (<c>CfgVarName</c> in the definition above) exists before + attempting to read the associated value in a test case or config function.</p> <p><c>require</c> is an assert statement that can be part of the <seealso marker="write_test_chapter#suite">test suite info function</seealso> or @@ -83,13 +86,13 @@ <p>A <c>require</c> statement in the test suite info- or test case info-list should look like this: - <c>{require,Required}</c> or <c>{require,Name,Required}</c>. The - arguments <c>Name</c> and <c>Required</c> are the same as the + <c>{require,CfgVarName}</c> or <c>{require,AliasName,CfgVarName}</c>. + The arguments <c>AliasName</c> and <c>CfgVarName</c> are the same as the arguments to <c>ct:require/[1,2]</c> which are described in the reference manual for <seealso marker="ct">ct</seealso>. - <c>Name</c> becomes an alias for the configuration variable - <c>Required</c>, and can be used as reference to the configuration - data value. The configuration variable may be associated with an + <c>AliasName</c> becomes an alias for the configuration variable, + and can be used as reference to the configuration data value. + The configuration variable may be associated with an arbitrary number of alias names, but each name must be unique within the same test suite. There are two main uses for alias names:</p> <list> @@ -180,7 +183,126 @@ </section> <section> - <title>Examples</title> + <title>User specific configuration data formats</title> + + <p>It is possible for the user to specify configuration data on a + different format than key-value tuples in a text file, as described + so far. The data can e.g. be read from arbitrary files, fetched from + the web over http, or requested from a user specific process. + To support this, Common Test provides a callback module plugin + mechanism to handle configuration data.</p> + + <section> + <title>Default callback modules for handling configuration data</title> + <p>The Common Test application includes default callback modules + for handling configuration data specified in standard config files + (see above) and in xml files:</p> + <list> + <item> + <c>ct_config_plain</c> - for reading configuration files with + key-value tuples (standard format). This handler will be used to + parse configuration files if no user callback is specified. + </item> + <item> + <c>ct_config_xml</c> - for reading configuration data from XML + files. + </item> + </list> + </section> + + <section> + <title>Using XML configuration files</title> + <p>This is an example of an XML configuration file:</p> + <pre><![CDATA[ +<config> + <ftp_host> + <ftp>"targethost"</ftp> + <username>"tester"</username> + <password>"letmein"</password> + </ftp_host> + <lm_directory>"/test/loadmodules"</lm_directory> +</config>]]></pre> + + <p>This configuration file, once read, will produce the same configuration + variables as the following text file:</p> + <pre> +{ftp_host, [{ftp,"targethost"}, + {username,"tester"}, + {password,"letmein"}]}. + +{lm_directory, "/test/loadmodules"}.</pre> + </section> + + <section> + <title>How to implement a user specific handler</title> + + <p>The user specific handler can be written to handle special + configuration file formats. The parameter can be either file + name(s) or configuration string(s) (the empty list is valid).</p> + + <p>The callback module implementing the handler is responsible for + checking correctness of configuration strings.</p> + + <p>To perform validation of the configuration strings, the callback module + should have the following function exported:</p> + + <p><c>Callback:check_parameter/1</c></p> + <p>The input argument will be passed from Common Test, as defined in the test + specification or given as an option to <c>run_test</c>.</p> + + <p>The return value should be any of the following values indicating if given + configuration parameter is valid:</p> + <list> + <item> + <c>{ok, {file, FileName}}</c> - parameter is a file name and + the file exists, + </item> + <item> + <c>{ok, {config, ConfigString}}</c> - parameter is a config string + and it is correct, + </item> + <item> + <c>{error, {nofile, FileName}}</c> - there is no file with the given + name in the current directory, + </item> + <item> + <c>{error, {wrong_config, ConfigString}}</c> - the configuration string + is wrong. + </item> + </list> + + <p>To perform reading of configuration data - initially before the tests + start, or as a result of data being reloaded during test execution - + the following function should be exported from the callback module:</p> + + <p><c>Callback:read_config/1</c></p> + + <p>The input argument is the same as for the <c>check_parameter/1</c> function.</p> + <p>The return value should be either:</p> + + <list> + <item> + <c>{ok, Config}</c> - if the configuration variables are read successfully, + </item> + <item> + <c>{error, Error, ErrorDetails}</c> - if the callback module fails to + proceed with the given configuration parameters. + </item> + </list> + <p><c>Config</c> is the proper Erlang key-value list, with possible + key-value sublists as values, like for the configuration file + example above:</p> + + <pre> + [{ftp_host, [{ftp, "targethost"}, {username, "tester"}, {password, "letmein"}]}, + {lm_directory, "/test/loadmodules"}]</pre> + + </section> + + </section> + + <section> + <title>Examples of configuration data handling</title> <p>A config file for using the FTP client to access files on a remote host could look like this:</p> @@ -188,28 +310,33 @@ <pre> {ftp_host, [{ftp,"targethost"}, {username,"tester"}, - {password,"letmein"}]}. + {password,"letmein"}]}. {lm_directory, "/test/loadmodules"}.</pre> - <p>Example of how to assert that the configuration data is available and + + <p>The XML version shown in the chapter above can also be used, but it should be + explicitly specified that the <c>ct_config_xml</c> callback module is to be + used by Common Test.</p> + + <p>Example of how to assert that the configuration data is available and use it for an FTP session:</p> <pre> init_per_testcase(ftptest, Config) -> {ok,_} = ct_ftp:open(ftp), - Config. + Config. end_per_testcase(ftptest, _Config) -> ct_ftp:close(ftp). ftptest() -> [{require,ftp,ftp_host}, - {require,lm_directory}]. + {require,lm_directory}]. ftptest(Config) -> - Remote = filename:join(ct:get_config(lm_directory), "loadmodX"), + Remote = filename:join(ct:get_config(lm_directory), "loadmodX"), Local = filename:join(?config(priv_dir,Config), "loadmodule"), ok = ct_ftp:recv(ftp, Remote, Local), - ...</pre> + ...</pre> <p>An example of how the above functions could be rewritten if necessary to open multiple connections to the FTP server:</p> @@ -217,7 +344,7 @@ init_per_testcase(ftptest, Config) -> {ok,Handle1} = ct_ftp:open(ftp_host), {ok,Handle2} = ct_ftp:open(ftp_host), - [{ftp_handles,[Handle1,Handle2]} | Config]. + [{ftp_handles,[Handle1,Handle2]} | Config]. end_per_testcase(ftptest, Config) -> lists:foreach(fun(Handle) -> ct_ftp:close(Handle) end, @@ -225,17 +352,117 @@ ftptest() -> [{require,ftp_host}, - {require,lm_directory}]. + {require,lm_directory}]. ftptest(Config) -> - Remote = filename:join(ct:get_config(lm_directory), "loadmodX"), + Remote = filename:join(ct:get_config(lm_directory), "loadmodX"), Local = filename:join(?config(priv_dir,Config), "loadmodule"), [Handle | MoreHandles] = ?config(ftp_handles,Config), ok = ct_ftp:recv(Handle, Remote, Local), - ...</pre> + ...</pre> </section> + <section> + <title>Example of user specific configuration handler</title> + <p>A simple configuration handling driver which will ask an external server for + configuration data can be implemented this way:</p> + <pre> +-module(config_driver). +-export([read_config/1, check_parameter/1]). + +read_config(ServerName)-> + ServerModule = list_to_atom(ServerName), + ServerModule:start(), + ServerModule:get_config(). + +check_parameter(ServerName)-> + ServerModule = list_to_atom(ServerName), + case code:is_loaded(ServerModule) of + {file, _}-> + {ok, {config, ServerName}}; + false-> + case code:load_file(ServerModule) of + {module, ServerModule}-> + {ok, {config, ServerName}}; + {error, nofile}-> + {error, {wrong_config, "File not found: " ++ ServerName ++ ".beam"}} + end + end.</pre> + + <p>The configuration string for this driver may be "config_server", if the + config_server.erl module below is compiled and exists in the code path + during test execution:</p> + <pre> +-module(config_server). +-export([start/0, stop/0, init/1, get_config/0, loop/0]). + +-define(REGISTERED_NAME, ct_test_config_server). + +start()-> + case whereis(?REGISTERED_NAME) of + undefined-> + spawn(?MODULE, init, [?REGISTERED_NAME]), + wait(); + _Pid-> + ok + end, + ?REGISTERED_NAME. + +init(Name)-> + register(Name, self()), + loop(). + +get_config()-> + call(self(), get_config). + +stop()-> + call(self(), stop). + +call(Client, Request)-> + case whereis(?REGISTERED_NAME) of + undefined-> + {error, not_started, Request}; + Pid-> + Pid ! {Client, Request}, + receive + Reply-> + {ok, Reply} + after 4000-> + {error, timeout, Request} + end + end. + +loop()-> + receive + {Pid, stop}-> + Pid ! ok; + {Pid, get_config}-> + {D,T} = erlang:localtime(), + Pid ! + [{localtime, [{date, D}, {time, T}]}, + {node, erlang:node()}, + {now, erlang:now()}, + {config_server_pid, self()}, + {config_server_vsn, ?vsn}], + ?MODULE:loop() + end. + +wait()-> + case whereis(?REGISTERED_NAME) of + undefined-> + wait(); + _Pid-> + ok + end.</pre> + + <p>In this example, the handler also provides the ability to dynamically reload + configuration variables. If <c>ct:reload_config(localtime)</c> is called from + the test case function, all variables loaded with <c>config_driver:read_config/1</c> + will be updated with their latest values, and the new value for variable + <c>localtime</c> will be returned.</p> + </section> + </chapter> diff --git a/lib/common_test/doc/src/ct_master_chapter.xml b/lib/common_test/doc/src/ct_master_chapter.xml index 79288cfe4c..01f8e61d36 100644 --- a/lib/common_test/doc/src/ct_master_chapter.xml +++ b/lib/common_test/doc/src/ct_master_chapter.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2006</year><year>2009</year> + <year>2006</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>Using Common Test for Large Scale Testing</title> @@ -30,6 +30,7 @@ </header> <section> + <marker id="general"></marker> <title>General</title> <p>Large scale automated testing requires running multiple independent test sessions in parallel. This is accomplished by running @@ -102,9 +103,10 @@ <p><c>ct_master:abort()</c> (stop all) or <c>ct_master:abort(Nodes)</c></p> <p>For detailed information about the <c>ct_master</c> API, please see the - manual page for this module.</p> + <seealso marker="ct_master">manual page</seealso> for this module.</p> </section> <section> + <marker id="test_specifications"></marker> <title>Test Specifications</title> <p>The test specifications used as input to CT Master are fully compatible with the specifications used as input to the regular CT server. The syntax is described in the @@ -186,7 +188,7 @@ <seealso marker="run_test_chapter#test_specifications">Running Test Suites</seealso> chapter). The result is that any test specified to run on a node with the same name as the Common Test node in question (typically <c>ct@somehost</c> if started - with the <c>run_test</c> script), will be performed. Tests without explicit + with the <c>run_test</c> program), will be performed. Tests without explicit node association will always be performed too of course!</p> <note><p>It is recommended that absolute paths are used for log directories, @@ -194,6 +196,56 @@ current working directory settings are not important.</p></note> </section> + <section> + <title>Automatic startup of test target nodes</title> + <marker id="ct_slave"></marker> + <p>Is is possible to automatically start, and perform initial actions, on + test target nodes by using the test specification term <c>init</c>.</p> + <p>Currently, two sub-terms are supported, <c>node_start</c> and <c>eval</c>.</p> + <p>Example:</p> + <pre> + {node, node1, node1@host1}. + {node, node2, node1@host2}. + {node, node3, node2@host2}. + {node, node4, node1@host3}. + {init, node1, [{node_start, [{callback_module, my_slave_callback}]}]}. + {init, [node2, node3], {node_start, [{username, "ct_user"}, {password, "ct_password"}]}}. + {init, node4, {eval, {module, function, []}}}.</pre> + + <p>This test specification declares that <c>node1@host1</c> is to be started using + the user callback function <c>callback_module:my_slave_callback/0</c>, and nodes + <c>node1@host2</c> and <c>node2@host2</c> will be started with the default callback + module <c>ct_slave</c>. The given user name and password is used to log into remote + host <c>host2</c>. Also, the function <c>module:function/0</c> will be evaluated on + <c>node1@host3</c>, and the result of this call will be printed to the log.</p> + + <p>The default <seealso marker="ct_slave">ct_slave</seealso> callback module, + which is part of the Common Test application, has the following features: + <list> + <item>Starting Erlang target nodes on local or remote hosts + (ssh is used for communication). + </item> + <item>Ability to start an Erlang emulator with additional flags + (any flags supported by <c>erl</c> are supported). + </item> + <item>Supervision of a node being started by means of internal callback + functions. Used to prevent hanging nodes. (Configurable). + </item> + <item>Monitoring of the master node by the slaves. A slave node may be + stopped in case the master node terminates. (Configurable). + </item> + <item>Execution of user functions after a slave node is started. + Functions can be given as a list of {Module, Function, Arguments} tuples. + </item> + </list> + </p> + <p>Note that it is possible to specify an <c>eval</c> term for the node as well + as <c>startup_functions</c> in the <c>node_start</c> options list. In this + case first the node will be started, then the <c>startup_functions</c> are + executed, and finally functions specified with <c>eval</c> are called. + </p> + </section> + </chapter> diff --git a/lib/common_test/doc/src/ct_slave.xml b/lib/common_test/doc/src/ct_slave.xml new file mode 100644 index 0000000000..ceebf51f1a --- /dev/null +++ b/lib/common_test/doc/src/ct_slave.xml @@ -0,0 +1,139 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> +<erlref> +<header> +<title>ct_slave</title> +<prepared></prepared> +<responsible></responsible> +<docno>1</docno> +<approved></approved> +<checked></checked> +<date></date> +<rev>A</rev> +<file>ct_slave.xml</file></header> +<module>ct_slave</module> +<modulesummary>Common Test Framework functions for starting and stopping nodes for +Large Scale Testing.</modulesummary> +<description> +<p>Common Test Framework functions for starting and stopping nodes for +Large Scale Testing.</p> + + <p>This module exports functions which are used by the Common Test Master + to start and stop "slave" nodes. It is the default callback module for the + <c>{init, node_start}</c> term of the Test Specification.</p></description> +<funcs> +<func> +<name>start(Node) -> Result</name> +<fsummary>Starts an Erlang node with name Node on the local host.</fsummary> +<type> +<v>Node = atom()</v><v>Result = {ok, NodeName} | {error, already_started, NodeName} | {error, started_not_connected, NodeName} | {error, boot_timeout, NodeName} | {error, init_timeout, NodeName} | {error, startup_timeout, NodeName} | {error, not_alive, NodeName}</v><v>NodeName = atom()</v></type> +<desc><marker id="start-1"/> + +<p>Starts an Erlang node with name <c>Node</c> on the local host.</p> +<p><em>See also:</em> <seealso marker="#start-3">start/3</seealso>.</p> +</desc></func> +<func> +<name>start(Host, Node) -> Result</name> +<fsummary>Starts an Erlang node with name Node on host + Host with the default options.</fsummary> +<type> +<v>Node = atom()</v><v>Host = atom()</v><v>Result = {ok, NodeName} | {error, already_started, NodeName} | {error, started_not_connected, NodeName} | {error, boot_timeout, NodeName} | {error, init_timeout, NodeName} | {error, startup_timeout, NodeName} | {error, not_alive, NodeName}</v><v>NodeName = atom()</v></type> +<desc><marker id="start-2"/> + +<p>Starts an Erlang node with name <c>Node</c> on host + <c>Host</c> with the default options.</p> +<p><em>See also:</em> <seealso marker="#start-3">start/3</seealso>.</p> +</desc></func> +<func> +<name>start(Host, Node, Options::Opts) -> Result</name> +<fsummary>Starts an Erlang node with name Node on host + Host as specified by the combination of options in + Opts.</fsummary> +<type> +<v>Node = atom()</v><v>Host = atom()</v><v>Opts = [OptTuples]</v><v>OptTuples = {username, Username} | {password, Password} | {boot_timeout, BootTimeout} | {init_timeout, InitTimeout} | {startup_timeout, StartupTimeout} | {startup_functions, StartupFunctions} | {monitor_master, Monitor} | {kill_if_fail, KillIfFail} | {erl_flags, ErlangFlags}</v><v>Username = string()</v><v>Password = string()</v><v>BootTimeout = integer()</v><v>InitTimeout = integer()</v><v>StartupTimeout = integer()</v><v>StartupFunctions = [StartupFunctionSpec]</v><v>StartupFunctionSpec = {Module, Function, Arguments}</v><v>Module = atom()</v><v>Function = atom()</v><v>Arguments = [term]</v><v>Monitor = bool()</v><v>KillIfFail = bool()</v><v>ErlangFlags = string()</v><v>Result = {ok, NodeName} | {error, already_started, NodeName} | {error, started_not_connected, NodeName} | {error, boot_timeout, NodeName} | {error, init_timeout, NodeName} | {error, startup_timeout, NodeName} | {error, not_alive, NodeName}</v><v>NodeName = atom()</v></type> +<desc><marker id="start-3"/> + +<p>Starts an Erlang node with name <c>Node</c> on host + <c>Host</c> as specified by the combination of options in + <c>Opts</c>.</p> + + <p>Options <c>Username</c> and <c>Password</c> will be used + to log in onto the remote host <c>Host</c>. + Username, if omitted, defaults to the current user name, + and password is empty by default.</p> + + <p>A list of functions specified in the <c>Startup</c> option will be + executed after startup of the node. Note that all used modules should be + present in the code path on the <c>Host</c>.</p> + + <p>The timeouts are applied as follows: + <list> + <item> + <c>BootTimeout</c> - time to start the Erlang node, in seconds. + Defaults to 3 seconds. If node does not become pingable within this time, + the result <c>{error, boot_timeout, NodeName}</c> is returned; + </item> + <item> + <c>InitTimeout</c> - time to wait for the node until it calls the + internal callback function informing master about successfull startup. + Defaults to one second. + In case of timed out message the result + <c>{error, init_timeout, NodeName}</c> is returned; + </item> + <item> + <c>StartupTimeout</c> - time to wait intil the node finishes to run + the <c>StartupFunctions</c>. Defaults to one second. + If this timeout occurs, the result + <c>{error, startup_timeout, NodeName}</c> is returned. + </item> + </list></p> + + <p>Option <c>monitor_master</c> specifies, if the slave node should be + stopped in case of master node stop. Defaults to false.</p> + + <p>Option <c>kill_if_fail</c> specifies, if the slave node should be + killed in case of a timeout during initialization or startup. + Defaults to true. Note that node also may be still alive it the boot + timeout occurred, but it will not be killed in this case.</p> + + <p>Option <c>erlang_flags</c> specifies, which flags will be added + to the parameters of the <c>erl</c> executable.</p> + + <p>Special return values are: + <list> + <item><c>{error, already_started, NodeName}</c> - if the node with + the given name is already started on a given host;</item> + <item><c>{error, started_not_connected, NodeName}</c> - if node is + started, but not connected to the master node.</item> + <item><c>{error, not_alive, NodeName}</c> - if node on which the + <c>ct_slave:start/3</c> is called, is not alive. Note that + <c>NodeName</c> is the name of current node in this case.</item> + </list></p> + +</desc></func> +<func> +<name>stop(Node) -> Result</name> +<fsummary>Stops the running Erlang node with name Node on + the localhost.</fsummary> +<type> +<v>Node = atom()</v><v>Result = {ok, NodeName} | {error, not_started, NodeName} | {error, not_connected, NodeName} | {error, stop_timeout, NodeName}</v><v>NodeName = atom()</v></type> +<desc><marker id="stop-1"/> + +<p>Stops the running Erlang node with name <c>Node</c> on + the localhost.</p> +</desc></func> +<func> +<name>stop(Host, Node) -> Result</name> +<fsummary>Stops the running Erlang node with name Node on + host Host.</fsummary> +<type> +<v>Host = atom()</v><v>Node = atom()</v><v>Result = {ok, NodeName} | {error, not_started, NodeName} | {error, not_connected, NodeName} | {error, stop_timeout, NodeName}</v><v>NodeName = atom()</v></type> +<desc><marker id="stop-2"/> + +<p>Stops the running Erlang node with name <c>Node</c> on + host <c>Host</c>.</p> +</desc></func></funcs> + +<authors> +<aname> </aname> +<email> </email></authors></erlref>
\ No newline at end of file diff --git a/lib/common_test/doc/src/event_handler_chapter.xml b/lib/common_test/doc/src/event_handler_chapter.xml index a550810850..7f5144b760 100644 --- a/lib/common_test/doc/src/event_handler_chapter.xml +++ b/lib/common_test/doc/src/event_handler_chapter.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2006</year><year>2009</year> + <year>2006</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>Event Handling</title> @@ -68,29 +68,27 @@ Example:</p> <p><c>$ run_test -suite test/my_SUITE -event_handler handlers/my_evh1 handlers/my_evh2 -pa $PWD/handlers</c></p> + <p>Use the <c><![CDATA[run_test -event_handler_init]]></c> option instead of + <c><![CDATA[-event_handler]]></c> to pass start arguments to the event handler + init function.</p> <p>All event handler modules must have gen_event behaviour. Note also that these modules must be precompiled, and that their locations must be added explicitly to the Erlang code server search path (like in the example).</p> - <p>It is not possible to specify start arguments to the event handlers when - using the <c>run_test</c> script. You may however pass along start arguments - if you use the <c>ct:run_test/1</c> function. An event_handler tuple in the argument - <c>Opts</c> has the following definition (see also <c>ct:run_test/1</c> in the - reference manual):</p> + <p>An event_handler tuple in the argument <c>Opts</c> has the following + definition (see also <c>ct:run_test/1</c> in the reference manual):</p> <pre> {event_handler,EventHandlers} EventHandlers = EH | [EH] EH = atom() | {atom(),InitArgs} | {[atom()],InitArgs} - InitArgs = [term()] - </pre> + InitArgs = [term()]</pre> <p>Example:</p> <pre> - 1> ct:run_test([{suite,"test/my_SUITE"},{event_handler,[my_evh1,{my_evh2,[node()]}]}]). - </pre> + 1> ct:run_test([{suite,"test/my_SUITE"},{event_handler,[my_evh1,{my_evh2,[node()]}]}]).</pre> <p>This will install two event handlers for the <c>my_SUITE</c> test. Event handler <c>my_evh1</c> is started with <c>[]</c> as argument to the init function. Event handler <c>my_evh2</c> is started with the name of the current node in the init argument list.</p> diff --git a/lib/common_test/doc/src/install_chapter.xml b/lib/common_test/doc/src/install_chapter.xml index e1ff5abf6a..828588a673 100644 --- a/lib/common_test/doc/src/install_chapter.xml +++ b/lib/common_test/doc/src/install_chapter.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2007</year><year>2009</year> + <year>2007</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>Installation</title> @@ -33,82 +33,77 @@ <marker id="general"></marker> <title>General information</title> - <p>The two main interfaces for running tests with Common Test - are an executable Bourne shell script named <c>run_test</c> and an - erlang module named <c>ct</c>. The shell script will work on Unix/Linux - (and Linux-like environments such as Cygwin on Windows) and the - <c>ct</c> interface functions can be called from the Erlang shell - (or from any Erlang function) on any supported platform.</p> - - <p>The Common Test application is installed with the Erlang/OTP - system and no explicit installation is required to start using - Common Test by means of the interface functions in the <c>ct</c> - module. If you wish to use <c>run_test</c>, however, this script - needs to be generated first, according to the instructions below.</p> - </section> + <p>The two main interfaces for running tests with Common Test + are an executable program named run_test and an + erlang module named <c>ct</c>. The run_test program + is compiled for the underlying operating system (e.g. Unix/Linux + or Windows) during the build of the Erlang/OTP system, and is + installed automatically with other executable programs in + the top level <c>bin</c> directory of Erlang/OTP. + The <c>ct</c> interface functions can be called from the Erlang shell, + or from any Erlang function, on any supported platform.</p> + + <p>A legacy Bourne shell script - also named run_test - exists, + which may be manually generated and installed. This script may be used + instead of the run_test program mentioned above, e.g. if the user + wishes to modify or customize the Common Test start flags in a simpler + way than making changes to the run_test C program.</p> - <section> - <title>Unix/Linux</title> - - <p>Go to the <c><![CDATA[common_test-<vsn>]]></c> directory, located - among the other OTP applications (under the OTP lib directory). Here you - execute the <c>install.sh</c> script with argument <c>local</c>:</p> - - <p><c> - $ ./install.sh local - </c></p> + <p>The Common Test application is installed with the Erlang/OTP + system and no additional installation step is required to start using + Common Test by means of the run_test executable program, and/or the interface + functions in the <c>ct</c> module. If you wish to use the legacy Bourne + shell script version of run_test, however, this script needs to be + generated first, according to the instructions below.</p> + + <p><note>Before reading on, please note that since Common Test version + 1.5, the run_test shell script is no longer required for starting + tests with Common Test from the OS command line. The run_test + program (descibed above) is the new recommended command line interface + for Common Test. The shell script exists mainly for legacy reasons and + may not be updated in future releases of Common Test. It may even be removed. + </note></p> + + <p>Optional step to generate a shell script for starting Common Test:</p> + <p>To generate the run_test shell script, navigate to the + <c><![CDATA[common_test-<vsn>]]></c> directory, located among the other + OTP applications (under the OTP lib directory). Here execute the + <c>install.sh</c> script with argument <c>local</c>:</p> + + <p><c> + $ ./install.sh local + </c></p> - <p>This generates the executable <c>run_test</c> script in the - <c><![CDATA[common_test-<vsn>/priv/bin]]></c> directory. The script - will include absolute paths to the Common Test and Test Server - application directories, so it's possible to copy or move the script to - a different location on the file system, if desired, without having to - update it. It's of course possible to leave the script under the - <c>priv/bin</c> directory and update the PATH variable accordingly (or - create a link or alias to it).</p> - - <p>If you, for any reason, have copied Common Test and Test Server - to a different location than the default OTP lib directory, you can - generate a <c>run_test</c> script with a different top level directory, - simply by specifying the directory, instead of <c>local</c>, when running - <c>install.sh</c>. Example:</p> - - <p><c> - $ install.sh /usr/local/test_tools + <p>This generates the executable run_test script in the + <c><![CDATA[common_test-<vsn>/priv/bin]]></c> directory. The script + will include absolute paths to the Common Test and Test Server + application directories, so it's possible to copy or move the script to + a different location on the file system, if desired, without having to + update it. It's of course possible to leave the script under the + <c>priv/bin</c> directory and update the PATH variable accordingly (or + create a link or alias to it).</p> + + <p>If you, for any reason, have copied Common Test and Test Server + to a different location than the default OTP lib directory, you can + generate a run_test script with a different top level directory, + simply by specifying the directory, instead of <c>local</c>, when running + <c>install.sh</c>. Example:</p> + + <p><c> + $ install.sh /usr/local/test_tools </c></p> <p>Note that the <c><![CDATA[common_test-<vsn>]]></c> and - <c><![CDATA[test_server-<vsn>]]></c> directories must be located under the - same top directory. Note also that the install script does not copy files - or update environment variables. It only generates the <c>run_test</c> - script.</p> + <c><![CDATA[test_server-<vsn>]]></c> directories must be located under the + same top directory. Note also that the install script does not copy files + or update environment variables. It only generates the run_test + script.</p> - <p>Whenever you install a new version of Erlang/OTP, the <c>run_test</c> - script needs to be regenerated, or updated manually with new directory names - (new version numbers), for it to "see" the latest Common Test and Test Server - versions.</p> + <p>Whenever you install a new version of Erlang/OTP, the run_test + script needs to be regenerated, or updated manually with new directory names + (new version numbers), for it to "see" the latest Common Test and Test Server + versions.</p> - <p>For more information on the <c>run_test</c> script and the <c>ct</c> - module, please see the reference manual.</p> - </section> - - <section> - <title>Windows</title> - - <p>On Windows it is very convenient to use Cygwin (<c>www.cygwin.com</c>) - for running Common Test and Erlang, since it enables you to use the - <c>run_test</c> script for starting Common Test. If you are a Cygwin - user, simply follow the instructions above for generating the <c>run_test</c> - script.</p> - - <p>If you do not use Cygwin, you have to rely on the API functions - in the <c>ct</c> module (instead of <c>run_test</c>) for running - Common Test as described initially in this chapter.</p> - - <p>If you, for any reason, have chosen to store Common Test and Test Server - in a different location than the default OTP lib directory, make - sure the <c>ebin</c> directories of these applications are included - in the Erlang code server path (so the application modules can be loaded).</p> </section> </chapter> diff --git a/lib/common_test/doc/src/notes.xml b/lib/common_test/doc/src/notes.xml index 4f5f6caa8c..af9dbfa9ec 100644 --- a/lib/common_test/doc/src/notes.xml +++ b/lib/common_test/doc/src/notes.xml @@ -32,6 +32,215 @@ <file>notes.xml</file> </header> +<section><title>Common_Test 1.5.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Returning {return_group_result,failed} from end_per_group + in a group that is part of a sequence, did not cause the + proceeding cases (or groups) to get skipped. This has + been fixed.</p> + <p> + Own Id: OTP-8753 Aux Id: seq11644 </p> + </item> + <item> + <p> + ct:install now works as the documentation describes.</p> + <p> + Own Id: OTP-8818 Aux Id: seq-11666 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Common Test has been updated to handle start options and + test specification terms for test case groups (and test + cases in groups). Also, an option named 'label', has been + added that associates the test run with a name that + Common Test prints in the overview HTML logs.</p> + <p> + Own Id: OTP-8725 Aux Id: OTP-8727 </p> + </item> + <item> + <p> + Andrey Pampukha has been added to the AUTHORS file. Thank + you Andrey for your work on configuration data handling, + Large Scale Testing improvements, and other useful + updates and fixes.</p> + <p> + Own Id: OTP-8803</p> + </item> + <item> + <p> + The Configuration Data chapter in the User's Guide has + been updated.</p> + <p> + Own Id: OTP-8804</p> + </item> + <item> + <p> + Milliseconds are now included in timestamps in Common + Test log entries. (Thanks to Tomas Johansson.)</p> + <p> + Own Id: OTP-8808</p> + </item> + </list> + </section> + +</section> + +<section><title>Common_Test 1.5</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Process calls using monitors in Common Test would not + clear the inbox of remaining DOWN messages. This has been + fixed.</p> + <p> + Own Id: OTP-8621 Aux Id: seq11560 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + It is now possible for the user to provide specific + callback modules that handle test configuration data, so + that data on arbitray form can be accessed (e.g. by + reading files or by communicating with a configuration + server process). Two default callback modules have been + introduced in Common Test: ct_config_plain and + ct_config_xml. The former is used to handle the + traditional Common Test configuration files (with terms + on key-value tuple form) and the latter to handle + configuration data on XML representation.</p> + <p> + Own Id: OTP-8485</p> + </item> + <item> + <p> + It is now possible to execute test suites that are not + necessarily available on the local file system, but have + been loaded on the test node in advance (e.g. sent as + binaries from a remote node and loaded by RPC). A + requirement is that the no_auto_compile (or + {auto_compile,false}) parameter has been set.</p> + <p> + Own Id: OTP-8490 Aux Id: seq11500 </p> + </item> + <item> + <p> + Test Server will now call the end_per_testcase/2 function + even if the test case has been terminated explicitly + (with abort_current_testcase/1), or after a timetrap + timeout. Under these circumstances the return value of + end_per_testcase is completely ignored. Therefore the + function will not be able to change the reason for test + case termination by returning {fail,Reason}, nor will it + be able to save data with {save_config,Data}.</p> + <p> + Own Id: OTP-8500 Aux Id: seq11521 </p> + </item> + <item> + <p> + It is now possible to use the test specification term + 'init' to start Common Test nodes automatically, as well + as have initial function calls evaluated on the nodes. A + default callback module for the 'init' term, ct_slave, + has been introduced to enable Common Test Master to + perform host login and node startup operations over ssh.</p> + <p> + Own Id: OTP-8570</p> + </item> + <item> + <p> + The run_test script has been replaced by a program (with + the same name) which can be executed without explicit + installation. The start flags are the same as for the + legacy start script.</p> + <p> + Own Id: OTP-8650</p> + </item> + <item> + <p> + Previously, a repeat property of a test case group + specified the number of times the group should be + repeated after the main test run. I.e. {repeat,N} would + case the group to execute 1+N times. To be consistent + with the behaviour of the run_test repeat option, this + has been changed. N now specifies the absolute number of + executions instead.</p> + <p> + Own Id: OTP-8689 Aux Id: seq11502 </p> + </item> + <item> + <p> + With the run_test -erl_args option, it's possible to + divide the options on the run_test command line into ones + that Common Test should process (those preceding + -erl_args, and ones it should ignore (those succeeding + -erl_args). Options preceding -erl_args that Common Test + doesn't recognize are also ignored (i.e. the same + behaviour as earlier versions of Common Test).</p> + <p> + Own Id: OTP-8690 Aux Id: OTP-8650 </p> + </item> + <item> + <p> + Directories added with -pa or -pz in the pre-erl_args + part of the run_test command line will be converted from + relative to absolute, this to avoid problems loading user + modules when Common Test switches working directory + during the test run.</p> + <p> + Own Id: OTP-8691 Aux Id: OTP-8650 </p> + </item> + <item> + <p> + The timetrap handling has been made more user + controllable by means of new start options and new ct + interface functions. With the 'multiply_timetraps' start + option, it's possible to specify a value which all + timetrap timeout values get multiplied by. This is useful + e.g. to extend the timetraps temporarily while running + cover or trace. The 'scale_timetraps' start option + switches on or off the Test Server timetrap scaling + feature (which tries to detect if the tests may benefit + from extended timetraps, e.g. due to running certain test + tools, and performs the scaling automatically). + Furthermore, the ct:timetrap/1 function has been + introduced, which makes it possible to set/reset + timetraps during test execution. Also, a ct:sleep/1 + function is now available, which takes the timetrap + parameters into account when calculating the time to + suspend the process.</p> + <p> + Own Id: OTP-8693</p> + </item> + <item> + <p> + A new run_test start option, event_handler_init, has been + added that takes a start argument which gets passed to + the init function of the event handler.</p> + <p> + Own Id: OTP-8694</p> + </item> + </list> + </section> + +</section> + <section><title>Common_Test 1.4.7</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/common_test/doc/src/ref_man.xml b/lib/common_test/doc/src/ref_man.xml index beb3ed3247..8be234d979 100644 --- a/lib/common_test/doc/src/ref_man.xml +++ b/lib/common_test/doc/src/ref_man.xml @@ -4,7 +4,7 @@ <application xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>2003</year><year>2009</year> + <year>2003</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>Common Test Reference Manual</title> @@ -75,6 +75,7 @@ <xi:include href="ct_snmp.xml"/> <xi:include href="ct_telnet.xml"/> <xi:include href="unix_telnet.xml"/> + <xi:include href="ct_slave.xml"/> </application> diff --git a/lib/common_test/doc/src/run_test.xml b/lib/common_test/doc/src/run_test.xml index d9dd22d411..2f0a94afba 100644 --- a/lib/common_test/doc/src/run_test.xml +++ b/lib/common_test/doc/src/run_test.xml @@ -4,7 +4,7 @@ <comref> <header> <copyright> - <year>2007</year><year>2009</year> + <year>2007</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -13,62 +13,95 @@ 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>The run_test shell script</title> + <title>The run_test program</title> <prepared>Peter Andersson</prepared> <responsible>Peter Andersson</responsible> <docno></docno> <approved></approved> <checked></checked> - <date>2007-07-04</date> - <rev>PA1</rev> + <date>2010-04-01</date> + <rev>PA2</rev> <file>run_test.xml</file> </header> - <com>run_test</com> - <comsummary>Shell script used for starting - Common Test from the Unix command line. + <com>run_test</com> + <comsummary>Program used for starting Common Test from the + OS command line. </comsummary> <description> - <p>The <c>run_test</c> script is automatically generated as Common - Test is installed (please see the Installation chapter in the Common - Test User's Guide for more information). The script accepts a number - of different start flags. Some flags trigger <c>run_test</c> - to start the Common Test application and pass on data to it. Some - flags start an Erlang node prepared for running Common Test in a - particular mode.</p> - <p><c>run_test</c> also accepts Erlang emulator - flags. These are used when <c>run_test</c> calls <c>erl</c> to - start the Erlang node (making it possible to e.g. add directories to - the code server path, change the cookie on the node, start - additional applications, etc).</p> - <p>If <c>run_test</c> is called without parameters, it prints all valid - start flags to stdout.</p> + <p>The <c>run_test</c> program is automatically installed with Erlang/OTP + and Common Test (please see the Installation chapter in the Common + Test User's Guide for more information). The program accepts a number + of different start flags. Some flags trigger <c>run_test</c> + to start the Common Test application and pass on data to it. Some + flags start an Erlang node prepared for running Common Test in a + particular mode.</p> + + <p>There is an interface function that corresponds to this program, + called <c>ct:run_test/1</c>, for starting Common Test from the Erlang + shell (or an Erlang program). Please see the <c>ct</c> man page for + details.</p> + + <p><c>run_test</c> also accepts Erlang emulator flags. These are used + when <c>run_test</c> calls <c>erl</c> to start the Erlang node + (making it possible to e.g. add directories to the code server path, + change the cookie on the node, start additional applications, etc).</p> + + <p>With the optional flag:</p> + <pre>-erl_args</pre> + <p>it's possible to divide the options on the <c>run_test</c> command line into + two groups, one that Common Test should process (those preceding <c>-erl_args</c>), + and one it should completely ignore and pass on directly to the emulator + (those following <c>-erl_args</c>). Options preceding <c>-erl_args</c> that Common Test + doesn't recognize, also get passed on to the emulator untouched. + By means of <c>-erl_args</c> the user may specify flags with the same name, but + with different destinations, on the <c>run_test</c> command line.</p> + <p>If <c>-pa</c> or <c>-pz</c> flags are specified in the Common Test group of options + (preceding <c>-erl_args</c>), relative directories will be converted to + absolute and re-inserted into the code path by Common Test (to avoid + problems loading user modules when Common Test changes working directory + during test runs). Common Test will however ignore <c>-pa</c> and <c>-pz</c> flags + following <c>-erl_args</c> on the command line. These directories are added + to the code path normally (i.e. on specified form)</p> + + <p>If <c>run_test</c> is called with option:</p> + <pre>-help</pre> + <p>it prints all valid start flags to stdout.</p> </description> + <marker id="run_test"></marker> + <section> <title>Run tests from command line</title> <pre> - run_test [-dir TestDir1 TestDir2 .. TestDirN] | - [-suite Suite1 Suite2 .. SuiteN + run_test [-dir TestDir1 TestDir2 .. TestDirN] | + [-suite Suite1 Suite2 .. SuiteN [[-group Group1 Group2 .. GroupN] [-case Case1 Case2 .. CaseN]]] [-step [config | keep_inactive]] [-config ConfigFile1 ConfigFile2 .. ConfigFileN] + [-userconfig CallbackModule1 ConfigString1 and CallbackModule2 + ConfigString2 and .. and CallbackModuleN ConfigStringN] [-decrypt_key Key] | [-decrypt_file KeyFile] + [-label Label] [-logdir LogDir] [-silent_connections [ConnType1 ConnType2 .. ConnTypeN]] [-stylesheet CSSFile] [-cover CoverCfgFile] - [-event_handler EvHandler1 EvHandler2 .. EvHandlerN] + [-event_handler EvHandler1 EvHandler2 .. EvHandlerN] | + [-event_handler_init EvHandler1 InitArg1 and + EvHandler2 InitArg2 and .. EvHandlerN InitArgN] [-include InclDir1 InclDir2 .. InclDirN] [-no_auto_compile] + [-muliply_timetraps Multiplier] + [-scale_timetraps] [-repeat N [-force_stop]] | [-duration HHMMSS [-force_stop]] | [-until [YYMoMoDD]HHMMSS [-force_stop]] @@ -79,15 +112,22 @@ <pre> run_test -spec TestSpec1 TestSpec2 .. TestSpecN [-config ConfigFile1 ConfigFile2 .. ConfigFileN] + [-userconfig CallbackModule1 ConfigString1 and CallbackModule2 + ConfigString2 and .. and CallbackModuleN ConfigStringN] [-decrypt_key Key] | [-decrypt_file KeyFile] + [-label Label] [-logdir LogDir] [-allow_user_terms] [-silent_connections [ConnType1 ConnType2 .. ConnTypeN]] [-stylesheet CSSFile] [-cover CoverCfgFile] - [-event_handler EvHandler1 EvHandler2 .. EvHandlerN] + [-event_handler EvHandler1 EvHandler2 .. EvHandlerN] | + [-event_handler_init EvHandler1 InitArg1 and + EvHandler2 InitArg2 and .. EvHandlerN InitArgN] [-include InclDir1 InclDir2 .. InclDirN] [-no_auto_compile] + [-muliply_timetraps Multiplier] + [-scale_timetraps] [-repeat N [-force_stop]] | [-duration HHMMSS [-force_stop]] | [-until [YYMoMoDD]HHMMSS [-force_stop]] @@ -97,12 +137,16 @@ <title>Run tests in web based GUI</title> <pre> run_test -vts [-browser Browser] - [-config ConfigFile1 ConfigFile2 .. ConfigFileN] - [-decrypt_key Key] | [-decrypt_file KeyFile] [-dir TestDir1 TestDir2 .. TestDirN] | [-suite Suite [[-group Group] [-case Case]]] + [-config ConfigFile1 ConfigFile2 .. ConfigFileN] + [-userconfig CallbackModule1 ConfigString1 and CallbackModule2 + ConfigString2 and .. and CallbackModuleN ConfigStringN] + [-decrypt_key Key] | [-decrypt_file KeyFile] [-include InclDir1 InclDir2 .. InclDirN] [-no_auto_compile] + [-muliply_timetraps Multiplier] + [-scale_timetraps] [-basic_html]</pre> </section> <section> @@ -113,28 +157,23 @@ <section> <title>Run CT in interactive mode</title> <pre> - run_test -shell + run_test -shell [-config ConfigFile1 ConfigFile2 ... ConfigFileN] + [-userconfig CallbackModule1 ConfigString1 and CallbackModule2 + ConfigString2 and .. and CallbackModuleN ConfigStringN] [-decrypt_key Key] | [-decrypt_file KeyFile]</pre> </section> <section> - <title>Start an Erlang node with a given name</title> - <pre> - run_test -ctname NodeName</pre> - </section> - <section> <title>Start a Common Test Master node</title> <pre> run_test -ctmaster</pre> </section> <section> - <title>See also</title> - <p>Please read the <seealso marker="run_test_chapter">Running Test Suites</seealso> - chapter in the Common Test User's Guide for information about the meaning of the - different start flags.</p> + <title>See also</title> + <p>Please read the <seealso marker="run_test_chapter">Running Test Suites</seealso> + chapter in the Common Test User's Guide for information about the meaning of the + different start flags.</p> </section> </comref> - - diff --git a/lib/common_test/doc/src/run_test_chapter.xml b/lib/common_test/doc/src/run_test_chapter.xml index d731d18783..1efff25f5b 100644 --- a/lib/common_test/doc/src/run_test_chapter.xml +++ b/lib/common_test/doc/src/run_test_chapter.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2003</year><year>2009</year> + <year>2003</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -13,15 +13,15 @@ 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>Running Test Suites</title> + <title>Running Tests</title> <prepared>Peter Andersson, Kenneth Lundin</prepared> <docno></docno> <date></date> @@ -97,25 +97,32 @@ the <c><![CDATA[{auto_compile,false}]]></c> option with <c><![CDATA[ct:run_test/1]]></c>. With automatic compilation disabled, the user is responsible for compiling the test suite modules - (and any help modules) before the test run. Common Test will only verify - that the specified test suites exist before starting the tests.</p> + (and any help modules) before the test run. If the modules can not be loaded + from the local file system during startup of Common Test, the user needs to + pre-load the modules before starting the test. Common Test will only verify + that the specified test suites exist (i.e. that they are, or can be, loaded). + This is useful e.g. if the test suites are transferred and loaded as binaries via + RPC from a remote node.</p> </section> <section> - <title>Running tests from the UNIX command line</title> + <title>Running tests from the OS command line</title> - <p>The script <c>run_test</c> can be used for running tests from - the Unix/Linux command line, e.g. + <p>The <c>run_test</c> program can be used for running tests from + the OS command line, e.g. </p> <list> <item><c><![CDATA[run_test -config <configfilenames> -dir <dirs>]]></c></item> <item><c><![CDATA[run_test -config <configfilenames> -suite <suiteswithfullpath>]]></c> </item> + <item><c><![CDATA[run_test -userconfig <callbackmodulename> <configfilenames> -suite <suiteswithfullpath>]]></c> + </item> <item><c><![CDATA[run_test -config <configfilenames> -suite <suitewithfullpath> -group <groupnames> -case <casenames>]]></c></item> </list> <p>Examples:</p> <p><c>$ run_test -config $CFGS/sys1.cfg $CFGS/sys2.cfg -dir $SYS1_TEST $SYS2_TEST</c></p> + <p><c>$ run_test -userconfig ct_config_xml $CFGS/sys1.xml $CFGS/sys2.xml -dir $SYS1_TEST $SYS2_TEST</c></p> <p><c>$ run_test -suite $SYS1_TEST/setup_SUITE $SYS2_TEST/config_SUITE</c></p> <p><c>$ run_test -suite $SYS1_TEST/setup_SUITE -case start stop</c></p> <p><c>$ run_test -suite $SYS1_TEST/setup_SUITE -group installation -case start stop</c></p> @@ -123,6 +130,8 @@ <p>Other flags that may be used with <c>run_test</c>:</p> <list> <item><c><![CDATA[-logdir <dir>]]></c>, specifies where the HTML log files are to be written.</item> + <item><c><![CDATA[-label <name_of_test_run>]]></c>, associates the test run with a name that gets printed + in the overview HTML log files.</item> <item><c>-refresh_logs</c>, refreshes the top level HTML index files.</item> <item><c>-vts</c>, start web based GUI (see below).</item> <item><c>-shell</c>, start interactive shell mode (see below).</item> @@ -136,8 +145,14 @@ <seealso marker="cover_chapter#cover">Code Coverage Analysis</seealso>).</item> <item><c><![CDATA[-event_handler <event_handlers>]]></c>, to install <seealso marker="event_handler_chapter#event_handling">event handlers</seealso>.</item> + <item><c><![CDATA[-event_handler_init <event_handlers>]]></c>, to install + <seealso marker="event_handler_chapter#event_handling">event handlers</seealso> including start arguments.</item> <item><c><![CDATA[-include]]></c>, specifies include directories (see above).</item> <item><c><![CDATA[-no_auto_compile]]></c>, disables the automatic test suite compilation feature (see above).</item> + <item><c><![CDATA[-multiply_timetraps <n>]]></c>, extends <seealso marker="write_test_chapter#timetraps">timetrap + timeout</seealso> values.</item> + <item><c><![CDATA[-scale_timetraps <bool>]]></c>, enables automatic <seealso marker="write_test_chapter#timetraps">timetrap + timeout</seealso> scaling.</item> <item><c><![CDATA[-repeat <n>]]></c>, tells Common Test to repeat the tests n times (see below).</item> <item><c><![CDATA[-duration <time>]]></c>, tells Common Test to repeat the tests for duration of time (see below).</item> <item><c><![CDATA[-until <stop_time>]]></c>, tells Common Test to repeat the tests until stop_time (see below).</item> @@ -165,7 +180,7 @@ the current working directory of the Erlang Runtime System during the test run!</p> </note> - <p>For details on how to generate the <c>run_test</c> script, see the + <p>For more information about the <c>run_test</c> program, see the <seealso marker="install_chapter#general">Installation</seealso> chapter. </p> </section> @@ -174,7 +189,7 @@ <title>Running tests from the Web based GUI</title> <p>The web based GUI, VTS, is started with the <c>run_test</c> - script. From the GUI you can load config files, and select + program. From the GUI you can load config files, and select directories, suites and cases to run. You can also state the config files, directories, suites and cases on the command line when starting the web based GUI. @@ -198,10 +213,11 @@ <p>Example:</p> <p><c><![CDATA[$ run_test -vts -browser 'firefox&']]></c></p> <p>Note that the browser must run as a separate OS process or VTS will hang!</p> - <p>If no specific browser start command is specified, netscape will + <p>If no specific browser start command is specified, Firefox will be the default browser on Unix platforms and Internet Explorer on Windows. - If Common Test fails to start a browser automatically, start your - favourite browser manually instead and type in the URL that Common Test + If Common Test fails to start a browser automatically, or <c>'none'</c> is + specified as the value for -browser (i.e. <c>-browser none</c>), start your + favourite browser manually and type in the URL that Common Test displays in the shell.</p> </section> @@ -211,7 +227,7 @@ <p>Common Test provides an Erlang API for running tests. The main (and most flexible) function for specifying and executing tests is called <c>ct:run_test/1</c>. This function takes the same start parameters as - the <c>run_test</c> script described above, only the flags are instead + the <c>run_test</c> program described above, only the flags are instead given as options in a list of key-value tuples. E.g. a test specified with <c>run_test</c> like:</p> <p><c>$ run_test -suite ./my_SUITE -logdir ./results</c></p> @@ -237,13 +253,14 @@ manually and call <c>ct:install/1</c> to install any configuration data you might need (use <c>[]</c> as argument otherwise), then call <c>ct:start_interactive/0</c> to start Common Test. If you use - the <c>run_test</c> script, you may start the Erlang shell and Common Test + the <c>run_test</c> program, you may start the Erlang shell and Common Test in the same go by using the <c>-shell</c> and, optionally, the <c>-config</c> - flag: + and/or <c>-userconfig</c> flag. Examples: </p> <list> <item><c>run_test -shell</c></item> - <item><c><![CDATA[run_test -shell -config <configfilename>]]></c></item> + <item><c><![CDATA[run_test -shell -config cfg/db.cfg]]></c></item> + <item><c><![CDATA[run_test -shell -userconfig db_login testuser x523qZ]]></c></item> </list> <p>If no config file is given with the <c>run_test</c> command, @@ -268,7 +285,8 @@ 2> ct_telnet:open(unix_telnet). {ok,<0.105.0>} 4> ct_telnet:cmd(unix_telnet, "ls ."). - {ok,["ls .","file1 ...",...]}</pre> + {ok,["ls .","file1 ...",...]} + </pre> <p>Everything that Common Test normally prints in the test case logs, will in the interactive mode be written to a log named @@ -319,54 +337,99 @@ <marker id="test_specifications"></marker> <title>Using test specifications</title> - <p>The most expressive way to specify what to test is to use a so - called test specification. A test specification is a sequence of - Erlang terms. The terms may be declared in a text file or passed - to the test server at runtime as a list (see <c>run_testspec/1</c> - in the manual page for <c>ct</c>). There are two general types - of terms: configuration terms and test specification terms.</p> - <p>With configuration terms it is possible to import configuration - data (similar to <c>run_test -config</c>), specify HTML log - directories (similar to <c>run_test -logdir</c>), give aliases - to test nodes and test directories (to make a specification - easier to read and maintain), enable code coverage analysis - (see the <seealso marker="cover_chapter#cover">Code Coverage - Analysis</seealso> chapter) and specify event_handler plugins + <p>The most flexible way to specify what to test, is to use a so + called test specification. A test specification is a sequence of + Erlang terms. The terms may be declared in a text file or passed + to the test server at runtime as a list + (see <c>run_testspec/1</c> in the manual page + for <c>ct</c>). There are two general types of terms: + configuration terms and test specification terms.</p> + <p>With configuration terms it is possible to e.g. label the test + run (similar to <c>run_test -label</c>), evaluate arbitrary expressions + before starting a test, import configuration + data (similar to + <c>run_test -config/-userconfig</c>), specify HTML log directories (similar + to + <c>run_test -logdir</c>), give aliases to test nodes and test + directories (to make a specification easier to read and + maintain), enable code coverage analysis (see + the <seealso marker="cover_chapter#cover">Code Coverage + Analysis</seealso> chapter) and specify event_handler plugins (see the <seealso marker="event_handler_chapter#event_handling"> - Event Handling</seealso> chapter). There is also a term - for specifying include directories that should be passed on - to the compiler when automatic compilation is performed - (similar to <c>run_test -include</c>, see above).</p> - <p>With test specification terms it is possible to state exactly which - tests should run and in which order. A test term specifies either - one or more suites or one or more test cases. An arbitrary number of test - terms may be declared in sequence. A test term can also specify one or - more test suites or test cases to be skipped. Skipped suites and cases - are not executed and show up in the HTML test log as SKIPPED.</p> - - <note><p>It is not yet possible to specify test case groups in - test specifications. This will be supported in a soon upcoming - release.</p></note> + Event Handling</seealso> chapter). There is also a term for + specifying include directories that should be passed on to the + compiler when automatic compilation is performed (similar + to <c>run_test -include</c>, see above).</p> + <p>With test specification terms it is possible to state exactly + which tests should run and in which order. A test term specifies + either one or more suites, one or more test case groups, or one + or more test cases in a group or suite.</p> + <p>An arbitrary number of test terms may be declared in sequence. + Common Test will compile the terms into one or more tests to be + performed in one resulting test run. Note that a term that + specifies a set of test cases will "swallow" one that only + specifies a subset of these cases. E.g. the result of merging + one term that specifies that all cases in suite S should be + executed, with another term specifying only test case X and Y in + S, is a test of all cases in S. However, if a term specifying + test case X and Y in S is merged with a term specifying case Z + in S, the result is a test of X, Y and Z in S.</p> + <p>A test term can also specify one or more test suites, groups, + or test cases to be skipped. Skipped suites, groups and cases + are not executed and show up in the HTML test log files as + SKIPPED.</p> + <p>When a test case group is specified, the resulting test + executes the + <c>init_per_group</c> function, followed by all test cases and + sub groups (including their configuration functions), and + finally the <c>end_per_group</c> function. Also if particular + test cases in a group are specified, <c>init_per_group</c> + and <c>end_per_group</c> for the group in question are + called. If a group which is defined (in <c>Suite:group/0</c>) to + be a sub group of another group, is specified (or particular test + cases of a sub group are), Common Test will call the configuration + functions for the top level groups as well as for the sub group + in question (making it possible to pass configuration data all + the way from <c>init_per_suite</c> down to the test cases in the + sub group).</p> <p>Below is the test specification syntax. Test specifications can - be used to run tests both in a single test host environment and in - a distributed Common Test environment. Node parameters are only relevant in the - latter (see the chapter about running Common Test in distributed mode for information). - For details on the event_handler term, see the - <seealso marker="event_handler_chapter#event_handling">Event Handling</seealso> - chapter.</p> + be used to run tests both in a single test host environment and + in a distributed Common Test environment (Large Scale + Testing). The node parameters in the init term are only + relevant in the latter (see the + <seealso marker="ct_master_chapter#test_specifications">Large + Scale Testing</seealso> chapter for information). For details on + the event_handler term, see the + <seealso marker="event_handler_chapter#event_handling">Event + Handling</seealso> chapter.</p> <p>Config terms:</p> <pre> {node, NodeAlias, Node}. + + {init, InitOptions}. + {init, [NodeAlias], InitOptions}. + + {label, Label}. + {label, NodeRefs, Label}. + + {multiply_timetraps, N}. + {multiply_timetraps, NodeRefs, N}. + + {scale_timetraps, Bool}. + {scale_timetraps, NodeRefs, Bool}. {cover, CoverSpecFile}. - {cover, NodeRef, CoverSpecFile}. + {cover, NodeRefs, CoverSpecFile}. {include, IncludeDirs}. {include, NodeRefs, IncludeDirs}. {config, ConfigFiles}. {config, NodeRefs, ConfigFiles}. + + {userconfig, {CallbackModule, ConfigStrings}}. + {userconfig, NodeRefs, {CallbackModule, ConfigStrings}}. {alias, DirAlias, Dir}. @@ -383,6 +446,12 @@ {suites, DirRef, Suites}. {suites, NodeRefs, DirRef, Suites}. + {groups, DirRef, Suite, Groups}. + {groups, NodeRefsDirRef, Suite, Groups}. + + {groups, DirRef, Suite, Group, {cases,Cases}}. + {groups, NodeRefsDirRef, Suite, Group, {cases,Cases}}. + {cases, DirRef, Suite, Cases}. {cases, NodeRefs, DirRef, Suite, Cases}. @@ -395,9 +464,12 @@ <p>Types:</p> <pre> NodeAlias = atom() + InitOptions = term() Node = node() NodeRef = NodeAlias | Node | master NodeRefs = all_nodes | [NodeRef] | NodeRef + N = integer() + Bool = true | false CoverSpecFile = string() IncludeDirs = string() | [string()] ConfigFiles = string() | [string()] @@ -408,6 +480,9 @@ InitArgs = [term()] DirRef = DirAlias | Dir Suites = atom() | [atom()] | all + Suite = atom() + Groups = atom() | [atom()] | all + Group = atom() Cases = atom() | [atom()] | all Comment = string() | "" </pre> @@ -449,9 +524,14 @@ <item>Secondly, the test for system t2 should run. The included suites are t2B and t2C. Included are also test cases test4, test1 and test7 in suite t2A. Note that the test cases will be executed in the specified order.</item> - <item>Lastly, all suites for systems t3 are to be completely skipped and this + <item>Lastly, all suites for systems t3 are to be completely skipped and this should be explicitly noted in the log files.</item> </list> + <p>It is possible to specify initialization options for nodes defined in the + test specification. Currently, there are options to start the node and/or to + evaluate any function on the node. + See the <seealso marker="ct_master_chapter#ct_slave">Automatic startup of + the test target nodes</seealso> chapter for details.</p> <p>It is possible for the user to provide a test specification that includes (for Common Test) unrecognizable terms. If this is desired, the <c>-allow_user_terms</c> flag should be used when starting tests with diff --git a/lib/common_test/doc/src/test_structure_chapter.xml b/lib/common_test/doc/src/test_structure_chapter.xml index c8628b3a7a..cd38ae0c7c 100644 --- a/lib/common_test/doc/src/test_structure_chapter.xml +++ b/lib/common_test/doc/src/test_structure_chapter.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2006</year><year>2009</year> + <year>2006</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>Test Structure</title> @@ -146,8 +146,8 @@ <tag><em>run_test</em></tag> <item> - The name of an executable Bourne shell script that may be - used on Linux/Unix as an interface for specifying and running + The name of an executable program that may be + used as an interface for specifying and running tests with Common Test. </item> diff --git a/lib/common_test/doc/src/write_test_chapter.xml b/lib/common_test/doc/src/write_test_chapter.xml index 212e3d85be..5afec6de6a 100644 --- a/lib/common_test/doc/src/write_test_chapter.xml +++ b/lib/common_test/doc/src/write_test_chapter.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2003</year><year>2009</year> + <year>2003</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>Writing Test Suites</title> @@ -157,6 +157,15 @@ <c>{skipped,Reason}</c> (where Reason is a user specific term). </p> + <p>The <c>end_per_testcase/2</c> function is called even after a + test case terminates due to a call to <c>ct:abort_current_testcase/1</c>, + or after a timetrap timeout. However, <c>end_per_testcase</c> + will then execute on a different process than the test case + function, and in this situation, <c>end_per_testcase</c> will + not be able to change the reason for test case termination by + returning <c>{fail,Reason}</c>, nor will it be able to save data with + <c>{save_config,Data}</c>.</p> + <p>If <c>init_per_testcase</c> crashes, the test case itself is skipped automatically (so called <em>auto skipped</em>). If <c>init_per_testcase</c> returns a <c>skip</c> tuple, also then will the test case be skipped (so @@ -682,12 +691,33 @@ <c>end_per_suite</c> execute, like test cases, on dedicated Erlang processes. </p> + </section> + <section> + <title>Timetrap timeouts</title> + <marker id="timetraps"></marker> <p>The default time limit for a test case is 30 minutes, unless a - <c>timetrap</c> is specified either by the test case info function - or the <c>suite/0</c> function. - </p> - + <c>timetrap</c> is specified either by the suite info function + or a test case info function. The timetrap timeout value defined + in <c>suite/0</c> is the value that will be used for each test case + in the suite (as well as for the configuration functions + <c>init_per_suite/1</c> and <c>end_per_suite</c>). A timetrap timeout + value set with the test case info function will override the value set + by <c>suite/0</c>, but only for that particular test case.</p> + <p>It is also possible to set/reset a timetrap during test case (or + configuration function) execution. This is done by calling + <c>ct:timetrap/1</c>. This function will cancel the current timetrap + and start a new one.</p> + <p>Timetrap values can be extended with a multiplier value specified at + startup with the <c>multiply_timetraps</c> option. It is also possible + to let Test Server decide to scale up timetrap timeout values + automatically, e.g. if tools such as cover or trace are running during + the test. This feature is disabled by default and can be enabled with + the <c>scale_timetraps</c> start option.</p> + <p>If a test case needs to suspend itself for a time that also gets + multipled by <c>multiply_timetraps</c>, and possibly scaled up if + <c>scale_timetraps</c> is enabled, the function <c>ct:sleep/1</c> + may be called.</p> </section> <section> diff --git a/lib/common_test/priv/Makefile.in b/lib/common_test/priv/Makefile.in index f144847a29..6372bbc8d5 100644 --- a/lib/common_test/priv/Makefile.in +++ b/lib/common_test/priv/Makefile.in @@ -56,8 +56,9 @@ ifneq ($(findstring win32,$(TARGET)),win32) # # Files # -FILES = vts.tool run_test.in -SCRIPTS = install.sh +FILES = +SCRIPTS = +IMAGES = tile1.jpg # # Rules @@ -83,14 +84,12 @@ include $(ERL_TOP)/make/otp_release_targets.mk ifeq ($(XNIX),true) release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv/bin - $(INSTALL_SCRIPT) $(SCRIPTS) $(RELSYSDIR) - $(INSTALL_DATA) $(FILES) $(RELSYSDIR)/priv + $(INSTALL_DIR) $(RELSYSDIR)/priv + $(INSTALL_DATA) $(FILES) $(IMAGES) $(RELSYSDIR)/priv else release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv/bin - $(INSTALL_SCRIPT) $(SCRIPTS) $(RELSYSDIR) - $(INSTALL_DATA) $(FILES) $(RELSYSDIR)/priv + $(INSTALL_DIR) $(RELSYSDIR)/priv + $(INSTALL_DATA) $(FILES) $(IMAGES) $(RELSYSDIR)/priv endif release_docs_spec: @@ -105,6 +104,7 @@ else # Files # FILES = vts.tool +IMAGES = tile1.jpg # # Rules @@ -123,8 +123,8 @@ clean: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv/bin - $(INSTALL_DATA) $(FILES) $(RELSYSDIR)/priv + $(INSTALL_DIR) $(RELSYSDIR)/priv + $(INSTALL_DATA) $(FILES) $(IMAGES) $(RELSYSDIR)/priv release_docs_spec: diff --git a/lib/common_test/priv/tile1.jpg b/lib/common_test/priv/tile1.jpg Binary files differnew file mode 100644 index 0000000000..8749383716 --- /dev/null +++ b/lib/common_test/priv/tile1.jpg diff --git a/lib/common_test/src/Makefile b/lib/common_test/src/Makefile index e7e2d1275d..027667e6b0 100644 --- a/lib/common_test/src/Makefile +++ b/lib/common_test/src/Makefile @@ -1,19 +1,19 @@ # # %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 # 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% # @@ -63,7 +63,11 @@ MODULES= \ ct_telnet_client \ ct_make \ vts \ - unix_telnet + unix_telnet \ + ct_config \ + ct_config_plain \ + ct_config_xml \ + ct_slave TARGET_MODULES= $(MODULES:%=$(EBIN)/%) diff --git a/lib/common_test/src/common_test.app.src b/lib/common_test/src/common_test.app.src index 7b72932ad4..b42173f412 100644 --- a/lib/common_test/src/common_test.app.src +++ b/lib/common_test/src/common_test.app.src @@ -1,19 +1,19 @@ % This is an -*- erlang -*- file. %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009. All Rights Reserved. -%% +%% +%% 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% {application, common_test, @@ -42,10 +42,15 @@ ct_testspec, ct_util, unix_telnet, - vts + vts, + ct_config, + ct_config_plain, + ct_config_xml, + ct_slave ]}, {registered, [ct_logs, ct_util_server, + ct_config_server, ct_make_ref, vts, ct_master, diff --git a/lib/common_test/src/ct.erl b/lib/common_test/src/ct.erl index 8ae041e5b4..8ae175f10d 100644 --- a/lib/common_test/src/ct.erl +++ b/lib/common_test/src/ct.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -59,18 +59,22 @@ %% Test suite API -export([require/1, require/2, get_config/1, get_config/2, get_config/3, + reload_config/1, log/1, log/2, log/3, print/1, print/2, print/3, pal/1, pal/2, pal/3, fail/1, comment/1, - testcases/2, userdata/2, userdata/3]). + testcases/2, userdata/2, userdata/3, + timetrap/1, sleep/1]). + +%% New API for manipulating with config handlers +-export([add_config/2, remove_config/2]). %% Other interface functions -export([get_status/0, abort_current_testcase/1, encrypt_config_file/2, encrypt_config_file/3, decrypt_config_file/2, decrypt_config_file/3]). - -export([get_target_name/1]). -export([parse_table/1, listenv/1]). @@ -93,7 +97,7 @@ %%% <code>install([{config,["config_node.ctc","config_user.ctc"]}])</code>.</p> %%% %%% <p>Note that this function is automatically run by the -%%% <code>run_test</code> script.</p> +%%% <code>run_test</code> program.</p> install(Opts) -> ct_run:install(Opts). @@ -134,22 +138,30 @@ run(TestDirs) -> %%%----------------------------------------------------------------- %%% @spec run_test(Opts) -> Result %%% Opts = [OptTuples] -%%% OptTuples = {config,CfgFiles} | {dir,TestDirs} | {suite,Suites} | -%%% {testcase,Cases} | {group,Groups} | {spec,TestSpecs} | -%%% {allow_user_terms,Bool} | {logdir,LogDir} | -%%% {silent_connections,Conns} | {cover,CoverSpecFile} | -%%% {step,StepOpts} | {event_handler,EventHandlers} | {include,InclDirs} | -%%% {auto_compile,Bool} | {repeat,N} | {duration,DurTime} | -%%% {until,StopTime} | {force_stop,Bool} | {decrypt,DecryptKeyOrFile} | +%%% OptTuples = {dir,TestDirs} | {suite,Suites} | {group,Groups} | +%%% {testcase,Cases} | {spec,TestSpecs} | {label,Label} | +%%% {config,CfgFiles} | {userconfig, UserConfig} | +%%% {allow_user_terms,Bool} | {logdir,LogDir} | +%%% {silent_connections,Conns} | {stylesheet,CSSFile} | +%%% {cover,CoverSpecFile} | {step,StepOpts} | +%%% {event_handler,EventHandlers} | {include,InclDirs} | +%%% {auto_compile,Bool} | {multiply_timetraps,M} | {scale_timetraps,Bool} | +%%% {repeat,N} | {duration,DurTime} | {until,StopTime} | +%%% {force_stop,Bool} | {decrypt,DecryptKeyOrFile} | %%% {refresh_logs,LogDir} | {basic_html,Bool} -%%% CfgFiles = [string()] | string() %%% TestDirs = [string()] | string() %%% Suites = [string()] | string() %%% Cases = [atom()] | atom() %%% Groups = [atom()] | atom() %%% TestSpecs = [string()] | string() +%%% Label = string() | atom() +%%% CfgFiles = [string()] | string() +%%% UserConfig = [{CallbackMod,CfgStrings}] | {CallbackMod,CfgStrings} +%%% CallbackMod = atom() +%%% CfgStrings = [string()] | string() %%% LogDir = string() %%% Conns = all | [atom()] +%%% CSSFile = string() %%% CoverSpecFile = string() %%% StepOpts = [StepOpt] | [] %%% StepOpt = config | keep_inactive @@ -157,6 +169,7 @@ run(TestDirs) -> %%% EH = atom() | {atom(),InitArgs} | {[atom()],InitArgs} %%% InitArgs = [term()] %%% InclDirs = [string()] | string() +%%% M = integer() %%% N = integer() %%% DurTime = string(HHMMSS) %%% StopTime = string(YYMoMoDDHHMMSS) | string(HHMMSS) @@ -165,11 +178,12 @@ run(TestDirs) -> %%% DecryptFile = string() %%% Result = [TestResult] | {error,Reason} %%% @doc Run tests as specified by the combination of options in <code>Opts</code>. -%%% The options are the same as those used with the <code>run_test</code> script. +%%% The options are the same as those used with the +%%% <seealso marker="run_test#run_test"><code>run_test</code></seealso> program. %%% Note that here a <code>TestDir</code> can be used to point out the path to %%% a <code>Suite</code>. Note also that the option <code>testcase</code> %%% corresponds to the <code>-case</code> option in the <code>run_test</code> -%%% script. Configuration files specified in <code>Opts</code> will be +%%% program. Configuration files specified in <code>Opts</code> will be %%% installed automatically at startup. run_test(Opts) -> ct_run:run_test(Opts). @@ -211,7 +225,7 @@ step(TestDir,Suite,Case,Opts) -> %%% %%% <p>From this mode all test case support functions can be executed %%% directly from the erlang shell. The interactive mode can also be -%%% started from the unix command line with <code>run_test -shell +%%% started from the OS command line with <code>run_test -shell %%% [-config File...]</code>.</p> %%% %%% <p>If any functions using "required config data" (e.g. telnet or @@ -269,7 +283,7 @@ stop_interactive() -> %%% @see get_config/2 %%% @see get_config/3 require(Required) -> - ct_util:require(Required). + ct_config:require(Required). %%%----------------------------------------------------------------- %%% @spec require(Name,Required) -> ok | {error,Reason} @@ -304,19 +318,19 @@ require(Required) -> %%% @see get_config/2 %%% @see get_config/3 require(Name,Required) -> - ct_util:require(Name,Required). + ct_config:require(Name,Required). %%%----------------------------------------------------------------- %%% @spec get_config(Required) -> Value %%% @equiv get_config(Required,undefined,[]) get_config(Required) -> - ct_util:get_config(Required,undefined,[]). + ct_config:get_config(Required,undefined,[]). %%%----------------------------------------------------------------- %%% @spec get_config(Required,Default) -> Value %%% @equiv get_config(Required,Default,[]) get_config(Required,Default) -> - ct_util:get_config(Required,Default,[]). + ct_config:get_config(Required,Default,[]). %%%----------------------------------------------------------------- %%% @spec get_config(Required,Default,Opts) -> ValueOrElement @@ -375,7 +389,26 @@ get_config(Required,Default) -> %%% @see require/1 %%% @see require/2 get_config(Required,Default,Opts) -> - ct_util:get_config(Required,Default,Opts). + ct_config:get_config(Required,Default,Opts). + +%%%----------------------------------------------------------------- +%%% @spec reload_config(Required) -> ValueOrElement +%%% Required = KeyOrName | {KeyOrName,SubKey} +%%% KeyOrName = atom() +%%% SubKey = atom() +%%% ValueOrElement = term() +%%% +%%% @doc Reload config file which contains specified configuration key. +%%% +%%% <p>This function performs updating of the configuration data from which the +%%% given configuration variable was read, and returns the (possibly) new +%%% value of this variable.</p> +%%% <p>Note that if some variables were present in the configuration but are not loaded +%%% using this function, they will be removed from the configuration table together +%%% with their aliases.</p> +%%% +reload_config(Required)-> + ct_config:reload_config(Required). %%%----------------------------------------------------------------- %%% @spec log(Format) -> ok @@ -734,7 +767,7 @@ abort_current_testcase(Reason) -> %%% <p>See the <code>crypto</code> application for details on DES3 %%% encryption/decryption.</p> encrypt_config_file(SrcFileName, EncryptFileName) -> - ct_util:encrypt_config_file(SrcFileName, EncryptFileName). + ct_config:encrypt_config_file(SrcFileName, EncryptFileName). %%%----------------------------------------------------------------- %%% @spec encrypt_config_file(SrcFileName, EncryptFileName, KeyOrFile) -> @@ -754,7 +787,7 @@ encrypt_config_file(SrcFileName, EncryptFileName) -> %%% <p>See the <code>crypto</code> application for details on DES3 %%% encryption/decryption.</p> encrypt_config_file(SrcFileName, EncryptFileName, KeyOrFile) -> - ct_util:encrypt_config_file(SrcFileName, EncryptFileName, KeyOrFile). + ct_config:encrypt_config_file(SrcFileName, EncryptFileName, KeyOrFile). %%%----------------------------------------------------------------- %%% @spec decrypt_config_file(EncryptFileName, TargetFileName) -> @@ -770,7 +803,7 @@ encrypt_config_file(SrcFileName, EncryptFileName, KeyOrFile) -> %%% <code>.ct_config.crypt</code> in the current directory, or the %%% home directory of the user (it is searched for in that order).</p> decrypt_config_file(EncryptFileName, TargetFileName) -> - ct_util:decrypt_config_file(EncryptFileName, TargetFileName). + ct_config:decrypt_config_file(EncryptFileName, TargetFileName). %%%----------------------------------------------------------------- %%% @spec decrypt_config_file(EncryptFileName, TargetFileName, KeyOrFile) -> @@ -785,5 +818,65 @@ decrypt_config_file(EncryptFileName, TargetFileName) -> %%% file contents is saved in the target file. The key must have the %%% the same value as that used for encryption.</p> decrypt_config_file(EncryptFileName, TargetFileName, KeyOrFile) -> - ct_util:decrypt_config_file(EncryptFileName, TargetFileName, KeyOrFile). + ct_config:decrypt_config_file(EncryptFileName, TargetFileName, KeyOrFile). + + +%%%----------------------------------------------------------------- +%%% @spec add_config(Callback, Config) -> ok | {error, Reason} +%%% Callback = atom() +%%% Config = string() +%%% Reason = term() +%%% +%%% @doc <p>This function loads configuration variables using the +%%% given callback module and configuration string. Callback module +%%% should be either loaded or present in the code part. Loaded +%%% configuration variables can later be removed using +%%% <code>remove_config/2</code> function.</p> +add_config(Callback, Config)-> + ct_config:add_config(Callback, Config). +%%%----------------------------------------------------------------- +%%% @spec remove_config(Callback, Config) -> ok +%%% Callback = atom() +%%% Config = string() +%%% Reason = term() +%%% +%%% @doc <p>This function removes configuration variables (together with +%%% their aliases) which were loaded with specified callback module and +%%% configuration string.</p> +remove_config(Callback, Config) -> + ct_config:remove_config(Callback, Config). + +%%%----------------------------------------------------------------- +%%% @spec timetrap(Time) -> ok +%%% Time = {hours,Hours} | {minutes,Mins} | {seconds,Secs} | Millisecs | infinity +%%% Hours = integer() +%%% Mins = integer() +%%% Secs = integer() +%%% Millisecs = integer() | float() +%%% +%%% @doc <p>Use this function to set a new timetrap for the running test case.</p> +timetrap(Time) -> + test_server:timetrap(Time). + +%%%----------------------------------------------------------------- +%%% @spec sleep(Time) -> ok +%%% Time = {hours,Hours} | {minutes,Mins} | {seconds,Secs} | Millisecs | infinity +%%% Hours = integer() +%%% Mins = integer() +%%% Secs = integer() +%%% Millisecs = integer() | float() +%%% +%%% @doc <p>This function, similar to <c>timer:sleep/1</c>, suspends the test +%%% case for specified time. However, this function also multiplies +%%% <c>Time</c> with the 'multiply_timetraps' value (if set) and under +%%% certain circumstances also scales up the time automatically +%%% if 'scale_timetraps' is set to true (default is false).</p> +sleep({hours,Hs}) -> + sleep(trunc(Hs * 1000 * 60 * 60)); +sleep({minutes,Ms}) -> + sleep(trunc(Ms * 1000 * 60)); +sleep({seconds,Ss}) -> + sleep(trunc(Ss * 1000)); +sleep(Time) -> + test_server:adjusted_sleep(Time). diff --git a/lib/common_test/src/ct_config.erl b/lib/common_test/src/ct_config.erl new file mode 100644 index 0000000000..6b75937668 --- /dev/null +++ b/lib/common_test/src/ct_config.erl @@ -0,0 +1,804 @@ +%%-------------------------------------------------------------------- +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% +%%---------------------------------------------------------------------- +%% File : ct_config.erl +%% Description : CT module for reading and manipulating of configuration +%% data +%% +%% Created : 15 February 2010 +%%---------------------------------------------------------------------- +-module(ct_config). + +-export([start/1, stop/0]). + +-export([read_config_files/1, + get_config_file_list/1]). + +-export([require/1, require/2]). + +-export([get_config/1, get_config/2, get_config/3, + get_all_config/0]). + +-export([set_default_config/2, set_default_config/3]). + +-export([delete_default_config/1]). + +-export([reload_config/1, update_config/2]). + +-export([release_allocated/0]). + +-export([encrypt_config_file/2, encrypt_config_file/3, + decrypt_config_file/2, decrypt_config_file/3, + get_crypt_key_from_file/0, get_crypt_key_from_file/1]). + +-export([get_ref_from_name/1, get_name_from_ref/1, get_key_from_name/1]). + +-export([check_config_files/1, add_default_callback/1, prepare_config_list/1]). + +-export([add_config/2, remove_config/2]). + +-include("ct_util.hrl"). + +-define(cryptfile, ".ct_config.crypt"). + +-record(ct_conf,{key,value,handler,config,ref,name='_UNDEF',default=false}). + +start(Mode) -> + case whereis(ct_config_server) of + undefined -> + Me = self(), + Pid = spawn_link(fun() -> do_start(Me) end), + receive + {Pid,started} -> Pid; + {Pid,Error} -> exit(Error) + end; + Pid -> + case ct_util:get_mode() of + interactive when Mode==interactive -> + Pid; + interactive -> + {error,interactive_mode}; + _OtherMode -> + Pid + end + end. + +do_start(Parent) -> + process_flag(trap_exit,true), + register(ct_config_server,self()), + ct_util:create_table(?attr_table,bag,#ct_conf.key), + {ok,StartDir} = file:get_cwd(), + Opts = case ct_util:read_opts() of + {ok,Opts1} -> + Opts1; + Error -> + Parent ! {self(),Error}, + exit(Error) + end, + case read_config_files(Opts) of + ok -> + Parent ! {self(),started}, + loop(StartDir); + ReadError -> + Parent ! {self(),ReadError}, + exit(ReadError) + end. + +stop() -> + case whereis(ct_config_server) of + undefined -> ok; + _ -> call({stop}) + end. + +call(Msg) -> + MRef = erlang:monitor(process, whereis(ct_config_server)), + Ref = make_ref(), + ct_config_server ! {Msg,{self(),Ref}}, + receive + {Ref, Result} -> + erlang:demonitor(MRef, [flush]), + Result; + {'DOWN',MRef,process,_,Reason} -> + {error,{ct_util_server_down,Reason}} + end. + +return({To,Ref},Result) -> + To ! {Ref, Result}. + +loop(StartDir) -> + receive + {{require,Name,Tag,SubTags},From} -> + Result = do_require(Name,Tag,SubTags), + return(From,Result), + loop(StartDir); + {{set_default_config,{Config,Scope}},From} -> + set_config(Config,{true,Scope}), + return(From,ok), + loop(StartDir); + {{set_default_config,{Name,Config,Scope}},From} -> + set_config(Name,Config,{true,Scope}), + return(From,ok), + loop(StartDir); + {{delete_default_config,Scope},From} -> + delete_config({true,Scope}), + return(From,ok), + loop(StartDir); + {{update_config,{Name,NewConfig}},From} -> + update_conf(Name,NewConfig), + return(From,ok), + loop(StartDir); + {{reload_config, KeyOrName},From}-> + NewValue = reload_conf(KeyOrName), + return(From, NewValue), + loop(StartDir); + {{stop},From} -> + ets:delete(?attr_table), + file:set_cwd(StartDir), + return(From,ok) + end. + +set_default_config(NewConfig, Scope) -> + call({set_default_config, {NewConfig, Scope}}). + +set_default_config(Name, NewConfig, Scope) -> + call({set_default_config, {Name, NewConfig, Scope}}). + +delete_default_config(Scope) -> + call({delete_default_config, Scope}). + +update_config(Name, Config) -> + call({update_config, {Name, Config}}). + +reload_config(KeyOrName) -> + call({reload_config, KeyOrName}). + +process_default_configs(Opts) -> + case lists:keysearch(config, 1, Opts) of + {value,{_,Files=[File|_]}} when is_list(File) -> + Files; + {value,{_,File=[C|_]}} when is_integer(C) -> + [File]; + {value,{_,[]}} -> + []; + false -> + [] + end. + +process_user_configs(Opts, Acc) -> + case lists:keytake(userconfig, 1, Opts) of + false -> + lists:reverse(Acc); + {value, {userconfig, Config=[{_,_}|_]}, NewOpts} -> + Acc1 = lists:map(fun({_Callback, []}=Cfg) -> + Cfg; + ({Callback, Files=[File|_]}) when is_list(File) -> + {Callback, Files}; + ({Callback, File=[C|_]}) when is_integer(C) -> + {Callback, [File]} + end, Config), + process_user_configs(NewOpts, lists:reverse(Acc1)++Acc); + {value, {userconfig, {Callback, []}}, NewOpts} -> + process_user_configs(NewOpts, [{Callback, []} | Acc]); + {value, {userconfig, {Callback, Files=[File|_]}}, NewOpts} when is_list(File) -> + process_user_configs(NewOpts, [{Callback, Files} | Acc]); + {value, {userconfig, {Callback, File=[C|_]}}, NewOpts} when is_integer(C) -> + process_user_configs(NewOpts, [{Callback, [File]} | Acc]) + end. + +get_config_file_list(Opts) -> + DefaultConfigs = process_default_configs(Opts), + CfgFiles = + if + DefaultConfigs == []-> + []; + true-> + [{?ct_config_txt, DefaultConfigs}] + end ++ + process_user_configs(Opts, []), + CfgFiles. + +add_default_callback(Opts) -> + case lists:keytake(config, 1, Opts) of + {value, {config, [File | _] = Files}, NoConfigOpts} + when is_integer(File) =/= true -> + [{config, lists:flatmap(fun add_def_cb/1, Files)} | NoConfigOpts]; + {value, {config, File}, NoConfigOpts} -> + [{config, add_def_cb(File)} | NoConfigOpts]; + false -> + Opts + end. + +add_def_cb([]) -> + []; +add_def_cb(Config) when is_tuple(Config) -> + [Config]; +add_def_cb([H|_T] = Config ) when is_integer(H) -> + [{?ct_config_txt, [Config]}]. + +read_config_files(Opts) -> + AddCallback = fun(CallBack, []) -> + [{CallBack, []}]; + (CallBack, [F|_]=Files) when is_integer(F) -> + [{CallBack, Files}]; + (CallBack, [F|_]=Files) when is_list(F) -> + lists:map(fun(X) -> {CallBack, X} end, Files) + end, + + ConfigFiles = case lists:keyfind(config, 1, Opts) of + {config,ConfigLists}-> + lists:foldr(fun({Callback,Files}, Acc) -> + AddCallback(Callback,Files) + ++ Acc + end,[],ConfigLists); + false-> + [] + end, + read_config_files_int(ConfigFiles, fun store_config/3). + +read_config_files_int([{Callback, File}|Files], FunToSave) -> + case Callback:read_config(File) of + {ok, Config} -> + FunToSave(Config, Callback, File), + read_config_files_int(Files, FunToSave); + {error, ErrorName, ErrorDetail}-> + {user_error, {ErrorName, File, ErrorDetail}} + end; +read_config_files_int([], _FunToSave) -> + ok. + +store_config(Config, Callback, File) -> + [ets:insert(?attr_table, + #ct_conf{key=Key, + value=Val, + handler=Callback, + config=File, + ref=ct_util:ct_make_ref(), + default=false}) || + {Key,Val} <- Config]. + +keyfindall(Key, Pos, List) -> + [E || E <- List, element(Pos, E) =:= Key]. + +rewrite_config(Config, Callback, File) -> + OldRows = ets:match_object(?attr_table, + #ct_conf{handler=Callback, + config=File,_='_'}), + ets:match_delete(?attr_table, + #ct_conf{handler=Callback, + config=File,_='_'}), + Updater = fun({Key, Value}) -> + case keyfindall(Key, #ct_conf.key, OldRows) of + []-> + ets:insert(?attr_table, + #ct_conf{key=Key, + value=Value, + handler=Callback, + config=File, + ref=ct_util:ct_make_ref()}); + RowsToUpdate -> + Inserter = fun(Row) -> + ets:insert(?attr_table, + Row#ct_conf{value=Value, + ref=ct_util:ct_make_ref()}) + end, + lists:foreach(Inserter, RowsToUpdate) + end + end, + [Updater({Key, Value})||{Key, Value}<-Config]. + +set_config(Config,Default) -> + set_config('_UNDEF',Config,Default). + +set_config(Name,Config,Default) -> + [ets:insert(?attr_table, + #ct_conf{key=Key,value=Val,ref=ct_util:ct_make_ref(), + name=Name,default=Default}) || + {Key,Val} <- Config]. + +get_config(KeyOrName) -> + get_config(KeyOrName,undefined,[]). + +get_config(KeyOrName,Default) -> + get_config(KeyOrName,Default,[]). + +get_config(KeyOrName,Default,Opts) when is_atom(KeyOrName) -> + case lookup_config(KeyOrName) of + [] -> + Default; + [{_Ref,Val}|_] = Vals -> + case {lists:member(all,Opts),lists:member(element,Opts)} of + {true,true} -> + [{KeyOrName,V} || {_R,V} <- lists:sort(Vals)]; + {true,false} -> + [V || {_R,V} <- lists:sort(Vals)]; + {false,true} -> + {KeyOrName,Val}; + {false,false} -> + Val + end + end; + +get_config({KeyOrName,SubKey},Default,Opts) -> + case lookup_config(KeyOrName) of + [] -> + Default; + Vals -> + Vals1 = case [Val || {_Ref,Val} <- lists:sort(Vals)] of + Result=[L|_] when is_list(L) -> + case L of + [{_,_}|_] -> + Result; + _ -> + [] + end; + _ -> + [] + end, + case get_subconfig([SubKey],Vals1,[],Opts) of + {ok,[{_,SubVal}|_]=SubVals} -> + case {lists:member(all,Opts),lists:member(element,Opts)} of + {true,true} -> + [{{KeyOrName,SubKey},Val} || {_,Val} <- SubVals]; + {true,false} -> + [Val || {_SubKey,Val} <- SubVals]; + {false,true} -> + {{KeyOrName,SubKey},SubVal}; + {false,false} -> + SubVal + end; + _ -> + Default + end + end. + +get_subconfig(SubKeys,Values) -> + get_subconfig(SubKeys,Values,[],[]). + +get_subconfig(SubKeys,[Value|Rest],Mapped,Opts) -> + case do_get_config(SubKeys,Value,[]) of + {ok,SubMapped} -> + case lists:member(all,Opts) of + true -> + get_subconfig(SubKeys,Rest,Mapped++SubMapped,Opts); + false -> + {ok,SubMapped} + end; + _Error -> + get_subconfig(SubKeys,Rest,Mapped,Opts) + end; +get_subconfig(SubKeys,[],[],_) -> + {error,{not_available,SubKeys}}; +get_subconfig(_SubKeys,[],Mapped,_) -> + {ok,Mapped}. + +do_get_config([Key|Required],Available,Mapped) -> + case lists:keysearch(Key,1,Available) of + {value,{Key,Value}} -> + NewAvailable = lists:keydelete(Key,1,Available), + NewMapped = [{Key,Value}|Mapped], + do_get_config(Required,NewAvailable,NewMapped); + false -> + {error,{not_available,Key}} + end; +do_get_config([],_Available,Mapped) -> + {ok,lists:reverse(Mapped)}. + +get_all_config() -> + ets:select(?attr_table,[{#ct_conf{name='$1',key='$2',value='$3', + default='$4',_='_'}, + [], + [{{'$1','$2','$3','$4'}}]}]). + +lookup_config(KeyOrName) -> + case lookup_name(KeyOrName) of + [] -> + lookup_key(KeyOrName); + Values -> + Values + end. + +lookup_name(Name) -> + ets:select(?attr_table,[{#ct_conf{ref='$1',value='$2',name=Name,_='_'}, + [], + [{{'$1','$2'}}]}]). +lookup_key(Key) -> + ets:select(?attr_table,[{#ct_conf{key=Key,ref='$1',value='$2',name='_UNDEF',_='_'}, + [], + [{{'$1','$2'}}]}]). + +lookup_handler_for_config({Key, _Subkey}) -> + lookup_handler_for_config(Key); +lookup_handler_for_config(KeyOrName) -> + case lookup_handler_for_name(KeyOrName) of + [] -> + lookup_handler_for_key(KeyOrName); + Values -> + Values + end. + +lookup_handler_for_name(Name) -> + ets:select(?attr_table,[{#ct_conf{handler='$1',config='$2',name=Name,_='_'}, + [], + [{{'$1','$2'}}]}]). + +lookup_handler_for_key(Key) -> + ets:select(?attr_table,[{#ct_conf{handler='$1',config='$2',key=Key,_='_'}, + [], + [{{'$1','$2'}}]}]). + + +update_conf(Name, NewConfig) -> + Old = ets:select(?attr_table,[{#ct_conf{name=Name,_='_'},[],['$_']}]), + lists:foreach(fun(OldElem) -> + NewElem = OldElem#ct_conf{value=NewConfig}, + ets:delete_object(?attr_table, OldElem), + ets:insert(?attr_table, NewElem) + end, Old), + ok. + +reload_conf(KeyOrName) -> + case lookup_handler_for_config(KeyOrName) of + []-> + undefined; + HandlerList-> + HandlerList2 = lists:usort(HandlerList), + read_config_files_int(HandlerList2, fun rewrite_config/3), + get_config(KeyOrName) + end. + +release_allocated() -> + Allocated = ets:select(?attr_table,[{#ct_conf{name='$1',_='_'}, + [{'=/=','$1','_UNDEF'}], + ['$_']}]), + release_allocated(Allocated). +release_allocated([H|T]) -> + ets:delete_object(?attr_table,H), + ets:insert(?attr_table,H#ct_conf{name='_UNDEF'}), + release_allocated(T); +release_allocated([]) -> + ok. + +allocate(Name,Key,SubKeys) -> + case ets:match_object(?attr_table,#ct_conf{key=Key,name='_UNDEF',_='_'}) of + [] -> + {error,{not_available,Key}}; + Available -> + case allocate_subconfig(Name,SubKeys,Available,false) of + ok -> + ok; + Error -> + Error + end + end. + +allocate_subconfig(Name,SubKeys,[C=#ct_conf{value=Value}|Rest],Found) -> + case do_get_config(SubKeys,Value,[]) of + {ok,_SubMapped} -> + ets:insert(?attr_table,C#ct_conf{name=Name}), + allocate_subconfig(Name,SubKeys,Rest,true); + _Error -> + allocate_subconfig(Name,SubKeys,Rest,Found) + end; +allocate_subconfig(_Name,_SubKeys,[],true) -> + ok; +allocate_subconfig(_Name,SubKeys,[],false) -> + {error,{not_available,SubKeys}}. + +delete_config(Default) -> + ets:match_delete(?attr_table,#ct_conf{default=Default,_='_'}), + ok. + +require(Key) when is_atom(Key) -> + require({Key,[]}); +require({Key,SubKeys}) when is_atom(Key) -> + allocate('_UNDEF',Key,to_list(SubKeys)); +require(Key) -> + {error,{invalid,Key}}. + +require(Name,Key) when is_atom(Key) -> + require(Name,{Key,[]}); +require(Name,{Key,SubKeys}) when is_atom(Name), is_atom(Key) -> + call({require,Name,Key,to_list(SubKeys)}); +require(Name,Keys) -> + {error,{invalid,{Name,Keys}}}. + +to_list(X) when is_list(X) -> X; +to_list(X) -> [X]. + +do_require(Name,Key,SubKeys) when is_list(SubKeys) -> + case get_key_from_name(Name) of + {error,_} -> + allocate(Name,Key,SubKeys); + {ok,Key} -> + %% already allocated - check that it has all required subkeys + Vals = [Val || {_Ref,Val} <- lookup_name(Name)], + case get_subconfig(SubKeys,Vals) of + {ok,_SubMapped} -> + ok; + Error -> + Error + end; + {ok,OtherKey} -> + {error,{name_in_use,Name,OtherKey}} + end. + +encrypt_config_file(SrcFileName, EncryptFileName) -> + case get_crypt_key_from_file() of + {error,_} = E -> + E; + Key -> + encrypt_config_file(SrcFileName, EncryptFileName, {key,Key}) + end. + +get_ref_from_name(Name) -> + case ets:select(?attr_table,[{#ct_conf{name=Name,ref='$1',_='_'}, + [], + ['$1']}]) of + [Ref] -> + {ok,Ref}; + _ -> + {error,{no_such_name,Name}} + end. + +get_name_from_ref(Ref) -> + case ets:select(?attr_table,[{#ct_conf{name='$1',ref=Ref,_='_'}, + [], + ['$1']}]) of + [Name] -> + {ok,Name}; + _ -> + {error,{no_such_ref,Ref}} + end. + +get_key_from_name(Name) -> + case ets:select(?attr_table,[{#ct_conf{name=Name,key='$1',_='_'}, + [], + ['$1']}]) of + [Key|_] -> + {ok,Key}; + _ -> + {error,{no_such_name,Name}} + end. + +encrypt_config_file(SrcFileName, EncryptFileName, {file,KeyFile}) -> + case get_crypt_key_from_file(KeyFile) of + {error,_} = E -> + E; + Key -> + encrypt_config_file(SrcFileName, EncryptFileName, {key,Key}) + end; + +encrypt_config_file(SrcFileName, EncryptFileName, {key,Key}) -> + crypto:start(), + {K1,K2,K3,IVec} = make_crypto_key(Key), + case file:read_file(SrcFileName) of + {ok,Bin0} -> + Bin1 = term_to_binary({SrcFileName,Bin0}), + Bin2 = case byte_size(Bin1) rem 8 of + 0 -> Bin1; + N -> list_to_binary([Bin1,random_bytes(8-N)]) + end, + EncBin = crypto:des3_cbc_encrypt(K1, K2, K3, IVec, Bin2), + case file:write_file(EncryptFileName, EncBin) of + ok -> + io:format("~s --(encrypt)--> ~s~n", + [SrcFileName,EncryptFileName]), + ok; + {error,Reason} -> + {error,{Reason,EncryptFileName}} + end; + {error,Reason} -> + {error,{Reason,SrcFileName}} + end. + +decrypt_config_file(EncryptFileName, TargetFileName) -> + case get_crypt_key_from_file() of + {error,_} = E -> + E; + Key -> + decrypt_config_file(EncryptFileName, TargetFileName, {key,Key}) + end. + +decrypt_config_file(EncryptFileName, TargetFileName, {file,KeyFile}) -> + case get_crypt_key_from_file(KeyFile) of + {error,_} = E -> + E; + Key -> + decrypt_config_file(EncryptFileName, TargetFileName, {key,Key}) + end; + +decrypt_config_file(EncryptFileName, TargetFileName, {key,Key}) -> + crypto:start(), + {K1,K2,K3,IVec} = make_crypto_key(Key), + case file:read_file(EncryptFileName) of + {ok,Bin} -> + DecBin = crypto:des3_cbc_decrypt(K1, K2, K3, IVec, Bin), + case catch binary_to_term(DecBin) of + {'EXIT',_} -> + {error,bad_file}; + {_SrcFile,SrcBin} -> + case TargetFileName of + undefined -> + {ok,SrcBin}; + _ -> + case file:write_file(TargetFileName, SrcBin) of + ok -> + io:format("~s --(decrypt)--> ~s~n", + [EncryptFileName,TargetFileName]), + ok; + {error,Reason} -> + {error,{Reason,TargetFileName}} + end + end + end; + {error,Reason} -> + {error,{Reason,EncryptFileName}} + end. + +get_crypt_key_from_file(File) -> + case file:read_file(File) of + {ok,Bin} -> + case catch string:tokens(binary_to_list(Bin), [$\n,$\r]) of + [Key] -> + Key; + _ -> + {error,{bad_crypt_file,File}} + end; + {error,Reason} -> + {error,{Reason,File}} + end. + +get_crypt_key_from_file() -> + CwdFile = filename:join(".",?cryptfile), + {Result,FullName} = + case file:read_file(CwdFile) of + {ok,Bin} -> + {Bin,CwdFile}; + _ -> + case init:get_argument(home) of + {ok,[[Home]]} -> + HomeFile = filename:join(Home,?cryptfile), + case file:read_file(HomeFile) of + {ok,Bin} -> + {Bin,HomeFile}; + _ -> + {{error,no_crypt_file},noent} + end; + _ -> + {{error,no_crypt_file},noent} + end + end, + case FullName of + noent -> + Result; + _ -> + case catch string:tokens(binary_to_list(Result), [$\n,$\r]) of + [Key] -> + io:format("~nCrypt key file: ~s~n", [FullName]), + Key; + _ -> + {error,{bad_crypt_file,FullName}} + end + end. + +make_crypto_key(String) -> + <<K1:8/binary,K2:8/binary>> = First = erlang:md5(String), + <<K3:8/binary,IVec:8/binary>> = erlang:md5([First|lists:reverse(String)]), + {K1,K2,K3,IVec}. + +random_bytes(N) -> + {A,B,C} = now(), + random:seed(A, B, C), + random_bytes_1(N, []). + +random_bytes_1(0, Acc) -> Acc; +random_bytes_1(N, Acc) -> random_bytes_1(N-1, [random:uniform(255)|Acc]). + +check_callback_load(Callback) -> + case code:is_loaded(Callback) of + {file, _Filename}-> + check_exports(Callback); + false-> + case code:load_file(Callback) of + {module, Callback}-> + check_exports(Callback); + {error, Error}-> + {error, Error} + end + end. + +check_exports(Callback) -> + Fs = Callback:module_info(exports), + case {lists:member({check_parameter,1},Fs), + lists:member({read_config,1},Fs)} of + {true, true} -> + {ok, Callback}; + _ -> + {error, missing_callback_functions} + end. + +check_config_files(Configs) -> + ConfigChecker = fun + ({Callback, [F|_R]=Files}) -> + case check_callback_load(Callback) of + {ok, Callback} -> + if is_integer(F) -> + Callback:check_parameter(Files); + is_list(F) -> + lists:map(fun(File) -> + Callback:check_parameter(File) + end, + Files) + end; + {error, Why}-> + {error, {callback, {Callback,Why}}} + end; + ({Callback, []}) -> + case check_callback_load(Callback) of + {ok, Callback}-> + Callback:check_parameter([]); + {error, Why}-> + {error, {callback, {Callback,Why}}} + end + end, + lists:keysearch(error, 1, lists:flatten(lists:map(ConfigChecker, Configs))). + +prepare_user_configs([ConfigString|UserConfigs], Acc, new) -> + prepare_user_configs(UserConfigs, + [{list_to_atom(ConfigString), []}|Acc], + cur); +prepare_user_configs(["and"|UserConfigs], Acc, _) -> + prepare_user_configs(UserConfigs, Acc, new); +prepare_user_configs([ConfigString|UserConfigs], [{LastMod, LastList}|Acc], cur) -> + prepare_user_configs(UserConfigs, + [{LastMod, [ConfigString|LastList]}|Acc], + cur); +prepare_user_configs([], Acc, _) -> + Acc. + +prepare_config_list(Args) -> + ConfigFiles = case lists:keysearch(ct_config, 1, Args) of + {value,{ct_config,Files}}-> + [{?ct_config_txt,[filename:absname(F) || F <- Files]}]; + false-> + [] + end, + UserConfigs = case lists:keysearch(userconfig, 1, Args) of + {value,{userconfig,UserConfigFiles}}-> + prepare_user_configs(UserConfigFiles, [], new); + false-> + [] + end, + ConfigFiles ++ UserConfigs. + +% TODO: add logging of the loaded configuration file to the CT FW log!!! +add_config(Callback, []) -> + read_config_files_int([{Callback, []}], fun store_config/3); +add_config(Callback, [File|_Files]=Config) when is_list(File) -> + lists:foreach(fun(CfgStr) -> + read_config_files_int([{Callback, CfgStr}], fun store_config/3) end, + Config); +add_config(Callback, [C|_]=Config) when is_integer(C) -> + read_config_files_int([{Callback, Config}], fun store_config/3), + ok. + +remove_config(Callback, Config) -> + ets:match_delete(?attr_table, + #ct_conf{handler=Callback, + config=Config,_='_'}), + ok. diff --git a/lib/common_test/src/ct_config_plain.erl b/lib/common_test/src/ct_config_plain.erl new file mode 100644 index 0000000000..3fbc8af9fb --- /dev/null +++ b/lib/common_test/src/ct_config_plain.erl @@ -0,0 +1,109 @@ +%%-------------------------------------------------------------------- +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% +%%---------------------------------------------------------------------- +%% File : ct_config_plain.erl +%% Description : CT callback module for reading configs from text files +%% +%% Created : 15 February 2010 +%%---------------------------------------------------------------------- +-module(ct_config_plain). +-export([read_config/1, check_parameter/1]). + +read_config(ConfigFile) -> + case file:consult(ConfigFile) of + {ok,Config} -> + {ok, Config}; + {error,enoent} -> + {error, config_file_error, enoent}; + {error,Reason} -> + Key = + case application:get_env(common_test, decrypt) of + {ok,KeyOrFile} -> + case KeyOrFile of + {key,K} -> + K; + {file,F} -> + ct_config:get_crypt_key_from_file(F) + end; + _ -> + ct_config:get_crypt_key_from_file() + end, + case Key of + {error,no_crypt_file} -> + {error, config_file_error, Reason}; + {error,CryptError} -> + {error, decrypt_file_error, CryptError}; + _ when is_list(Key) -> + case ct_config:decrypt_config_file(ConfigFile, undefined, {key,Key}) of + {ok,CfgBin} -> + case read_config_terms(CfgBin) of + {error,ReadFail} -> + {error, config_file_error, ReadFail}; + Config -> + {ok, Config} + end; + {error,DecryptFail} -> + {error, decrypt_config_error, DecryptFail} + end; + _ -> + {error, bad_decrypt_key, Key} + end + end. + +% check if config file exists +check_parameter(File)-> + case filelib:is_file(File) of + true-> + {ok, {file, File}}; + false-> + {error, {nofile, File}} + end. + +read_config_terms(Bin) when is_binary(Bin) -> + case catch binary_to_list(Bin) of + {'EXIT',_} -> + {error,invalid_textfile}; + Lines -> + read_config_terms(Lines) + end; +read_config_terms(Lines) when is_list(Lines) -> + read_config_terms1(erl_scan:tokens([], Lines, 0), 1, [], []). + +read_config_terms1({done,{ok,Ts,EL},Rest}, L, Terms, _) -> + case erl_parse:parse_term(Ts) of + {ok,Term} when Rest == [] -> + lists:reverse([Term|Terms]); + {ok,Term} -> + read_config_terms1(erl_scan:tokens([], Rest, 0), + EL+1, [Term|Terms], Rest); + _ -> + {error,{bad_term,{L,EL}}} + end; +read_config_terms1({done,{eof,_},_}, _, Terms, Rest) when Rest == [] -> + lists:reverse(Terms); +read_config_terms1({done,{eof,EL},_}, L, _, _) -> + {error,{bad_term,{L,EL}}}; +read_config_terms1({done,{error,Info,EL},_}, L, _, _) -> + {error,{Info,{L,EL}}}; +read_config_terms1({more,_}, L, Terms, Rest) -> + case string:tokens(Rest, [$\n,$\r,$\t]) of + [] -> + lists:reverse(Terms); + _ -> + {error,{bad_term,L}} + end. diff --git a/lib/common_test/src/ct_config_xml.erl b/lib/common_test/src/ct_config_xml.erl new file mode 100644 index 0000000000..8a6e75e635 --- /dev/null +++ b/lib/common_test/src/ct_config_xml.erl @@ -0,0 +1,118 @@ +%%-------------------------------------------------------------------- +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% +%%---------------------------------------------------------------------- +%% File : ct_config_xml.erl +%% Description : CT callback module for reading configs from XML files +%% +%% Created : 16 February 2010 +%%---------------------------------------------------------------------- +-module(ct_config_xml). +-export([read_config/1, check_parameter/1]). + +% read config file +read_config(ConfigFile) -> + case catch do_read_xml_config(ConfigFile) of + {ok, Config}-> + {ok, Config}; + {error, Error, ErroneousString}-> + {error, Error, ErroneousString} + end. + +% check file exists +check_parameter(File)-> + case filelib:is_file(File) of + true-> + {ok, {file, File}}; + false-> + {error, {nofile, File}} + end. + +% actual reading of the config +do_read_xml_config(ConfigFile)-> + case catch xmerl_sax_parser:file(ConfigFile, + [{event_fun, fun event/3}, + {event_state, []}]) of + {ok, EntityList, _}-> + {ok, lists:reverse(transform_entity_list(EntityList))}; + Oops-> + {error, parsing_failed, Oops} + end. + +% event callback for xmerl_sax_parser +event(Event, _LineNo, State) -> + tag(Event, State). + +% document start +tag(startDocument, State) -> + State; + +% start of the config +tag({startElement, _Uri, "config", _QName, _Attributes}, []) -> + [{"config", []}]; + +% start tag +tag({startElement, _Uri, Name, _QName, _Attributes}, Tags) -> + [{Name, []}|Tags]; + +% value +tag({characters, String}, [{Tag, _Value}|Tags]) -> + [{Tag, String}|Tags]; + +% end tag +tag({endElement, _Uri, _Name, _QName}, + [Entity, {PrevEntityTag, PrevEntityValue}|Tags]) -> + NewHead = {PrevEntityTag, [Entity|PrevEntityValue]}, + [NewHead|Tags]; + +% end of the config +tag({endElement, _Uri, "config", _QName}, [{"config", Config}]) -> + Config; + +% end of document, return result +tag(endDocument, {_Tags, Result}) -> + Result; + +% default +tag(_El, State) -> + State. + +% transform of the ugly deeply nested entity list to the key-value "tree" +transform_entity_list(EntityList)-> + lists:map(fun transform_entity/1, EntityList). + +% transform entity from {list(), list()} to {atom(), term()} +transform_entity({Tag, [Value|Rest]}) when + is_tuple(Value)-> + {list_to_atom(Tag), transform_entity_list(lists:reverse([Value|Rest]))}; +transform_entity({Tag, String})-> + case list_to_term(String) of + {ok, Value}-> + {list_to_atom(Tag), Value}; + Error-> + throw(Error) + end. + +% transform a string with Erlang terms +list_to_term(String) -> + {ok, T, _} = erl_scan:string(String++"."), + case catch erl_parse:parse_term(T) of + {ok, Term} -> + {ok, Term}; + Error -> + {error, Error, String} + end. diff --git a/lib/common_test/src/ct_framework.erl b/lib/common_test/src/ct_framework.erl index ed8b564921..f2ca023cff 100644 --- a/lib/common_test/src/ct_framework.erl +++ b/lib/common_test/src/ct_framework.erl @@ -27,8 +27,12 @@ -export([init_tc/3, end_tc/3, get_suite/2, report/2, warn/1]). -export([error_notification/4]). +-export([overview_html_header/1]). + -export([error_in_suite/1, ct_init_per_group/2, ct_end_per_group/2]). +-export([make_all_conf/3, make_conf/5]). + -include("ct_event.hrl"). -include("ct_util.hrl"). @@ -101,7 +105,8 @@ init_tc1(Mod,Func,[Config0],DoInit) when is_list(Config0) -> [{saved_config,{LastFunc,SavedConfig}} | lists:keydelete(saved_config,1,Config0)]; {{LastSuite,InitOrEnd},SavedConfig} when InitOrEnd == init_per_suite ; - InitOrEnd == end_per_suite -> % last suite + InitOrEnd == end_per_suite -> + %% last suite [{saved_config,{LastSuite,SavedConfig}} | lists:keydelete(saved_config,1,Config0)]; undefined -> @@ -113,9 +118,9 @@ init_tc1(Mod,Func,[Config0],DoInit) when is_list(Config0) -> ok; true -> %% delete all default values used in previous suite - ct_util:delete_default_config(suite), + ct_config:delete_default_config(suite), %% release all name -> key bindings (once per suite) - ct_util:release_allocated() + ct_config:release_allocated() end, TestCaseInfo = case catch apply(Mod,Func,[]) of @@ -125,7 +130,7 @@ init_tc1(Mod,Func,[Config0],DoInit) when is_list(Config0) -> %% clear all config data default values set by previous %% testcase info function (these should only survive the %% testcase, not the whole suite) - ct_util:delete_default_config(testcase), + ct_config:delete_default_config(testcase), case add_defaults(Mod,Func,TestCaseInfo,DoInit) of Error = {suite0_failed,_} -> ct_logs:init_tc(), @@ -161,6 +166,7 @@ init_tc2(Mod,Func,SuiteInfo,MergeResult,Config,DoInit) -> _ -> MergeResult end, + %% timetrap must be handled before require MergedInfo1 = timetrap_first(MergedInfo, [], []), %% tell logger to use specified style sheet @@ -244,8 +250,8 @@ add_defaults(Mod,Func,FuncInfo,DoInit) -> _ -> {suite0_failed,bad_return_value} end. - -add_defaults1(_Mod,init_per_suite,[],SuiteInfo,_) -> + +add_defaults1(_Mod,init_per_suite,[],SuiteInfo,_DoInit) -> SuiteInfo; add_defaults1(Mod,Func,FuncInfo,SuiteInfo,DoInit) -> @@ -253,15 +259,27 @@ add_defaults1(Mod,Func,FuncInfo,SuiteInfo,DoInit) -> %% can result in weird behaviour (suite values get overwritten) SuiteReqs = [SDDef || SDDef <- SuiteInfo, - require == element(1,SDDef)], - case [element(2,Clash) || Clash <- SuiteReqs, - true == lists:keymember(element(2,Clash),2,FuncInfo)] of + ((require == element(1,SDDef)) or + (default_config == element(1,SDDef)))], + FuncReqs = + [FIDef || FIDef <- FuncInfo, + require == element(1,FIDef)], + case [element(2,Clash) || Clash <- SuiteReqs, + require == element(1, Clash), + true == lists:keymember(element(2,Clash),2, + FuncReqs)] of [] -> add_defaults2(Mod,Func,FuncInfo,SuiteInfo,SuiteReqs,DoInit); Clashes -> {error,{config_name_already_in_use,Clashes}} end. +add_defaults2(Mod,init_per_suite,IPSInfo,SuiteInfo,SuiteReqs,false) -> + %% not common practise to use a test case info function for + %% init_per_suite (usually handled by suite/0), but let's support + %% it just in case... + add_defaults2(Mod,init_per_suite,IPSInfo,SuiteInfo,SuiteReqs,true); + add_defaults2(_Mod,_Func,FuncInfo,SuiteInfo,_,false) -> %% include require elements from test case info, but not from suite/0 %% (since we've already required those vars) @@ -381,10 +399,10 @@ try_set_default(Name,Key,Info,Where) -> {_,[]} -> no_default; {'_UNDEF',_} -> - [ct_util:set_default_config([CfgVal],Where) || CfgVal <- CfgElems], + [ct_config:set_default_config([CfgVal],Where) || CfgVal <- CfgElems], ok; _ -> - [ct_util:set_default_config(Name,[CfgVal],Where) || CfgVal <- CfgElems], + [ct_config:set_default_config(Name,[CfgVal],Where) || CfgVal <- CfgElems], ok end. @@ -631,12 +649,12 @@ group_or_func(Func, _Config) -> %%% and every test case. If the former, all test cases in the suite %%% should be returned. -get_suite(Mod, all) -> +get_suite(Mod, all) -> case catch apply(Mod, groups, []) of {'EXIT',_} -> get_all(Mod, []); GroupDefs when is_list(GroupDefs) -> - case catch check_groups(Mod, GroupDefs) of + case catch find_groups(Mod, all, all, GroupDefs) of {error,_} = Error -> %% this makes test_server call error_in_suite as first %% (and only) test case so we can report Error properly @@ -651,96 +669,193 @@ get_suite(Mod, all) -> %%!============================================================ %%! Note: The handling of sequences in get_suite/2 and get_all/2 -%%! is deprecated and should be removed after OTP R13! +%%! is deprecated and should be removed at some point... %%!============================================================ -get_suite(Mod, Name) -> - %% Name may be name of a group or a test case. If it's a group, - %% it should be expanded to list of cases (in a conf term) +%% group +get_suite(Mod, Group={conf,Props,_Init,TCs,_End}) -> + Name = proplists:get_value(name, Props), case catch apply(Mod, groups, []) of {'EXIT',_} -> - get_seq(Mod, Name); + [Group]; GroupDefs when is_list(GroupDefs) -> - case catch check_groups(Mod, GroupDefs) of + case catch find_groups(Mod, Name, TCs, GroupDefs) of {error,_} = Error -> %% this makes test_server call error_in_suite as first %% (and only) test case so we can report Error properly [{?MODULE,error_in_suite,[[Error]]}]; + [] -> + {error,{invalid_group_spec,Name}}; ConfTests -> - FindConf = fun({conf,Props,_,_,_}) -> - case proplists:get_value(name, Props) of - Name -> true; - _ -> false - end - end, - case lists:filter(FindConf, ConfTests) of - [] -> % must be a test case - get_seq(Mod, Name); - [ConfTest|_] -> - ConfTest + case lists:member(skipped, Props) of + true -> + %% a *subgroup* specified *only* as skipped (and not + %% as an explicit test) should not be returned, or + %% init/end functions for top groups will be executed + case catch proplists:get_value(name, element(2, hd(ConfTests))) of + Name -> % top group + ConfTests; + _ -> + [] + end; + false -> + ConfTests end end; _ -> E = "Bad return value from "++atom_to_list(Mod)++":groups/0", [{?MODULE,error_in_suite,[[{error,list_to_atom(E)}]]}] - end. + end; -check_groups(_Mod, []) -> - []; -check_groups(Mod, Defs) -> - check_groups(Mod, Defs, Defs, []). +%% testcase +get_suite(Mod, Name) -> + get_seq(Mod, Name). -check_groups(Mod, [TC | Gs], Defs, Levels) when is_atom(TC), length(Levels)>0 -> - [TC | check_groups(Mod, Gs, Defs, Levels)]; +%%%----------------------------------------------------------------- -check_groups(Mod, [{group,SubName} | Gs], Defs, Levels) when is_atom(SubName) -> - case lists:member(SubName, Levels) of - true -> - E = "Cyclic reference to group "++atom_to_list(SubName)++ - " in "++atom_to_list(Mod)++":groups/0", - throw({error,list_to_atom(E)}); - false -> - case find_group(Mod, SubName, Defs) of - {error,_} = Error -> - throw(Error); - G -> - [check_groups(Mod, [G], Defs, Levels) | - check_groups(Mod, Gs, Defs, Levels)] - end +find_groups(Mod, Name, TCs, GroupDefs) -> + Found = find(Mod, Name, TCs, GroupDefs, [], GroupDefs, false), + Trimmed = trim(Found), + delete_subs(Trimmed, Trimmed). + +find(Mod, all, _TCs, [{Name,Props,Tests} | Gs], Known, Defs, _) -> + cyclic_test(Mod, Name, Known), + [make_conf(Mod, Name, Props, + find(Mod, all, all, Tests, [Name | Known], Defs, true)) | + find(Mod, all, all, Gs, [], Defs, true)]; + +find(Mod, Name, TCs, [{Name,Props,Tests} | _Gs], Known, Defs, false) + when is_atom(Name), is_list(Props), is_list(Tests) -> + cyclic_test(Mod, Name, Known), + case TCs of + all -> + [make_conf(Mod, Name, Props, + find(Mod, Name, TCs, Tests, [Name | Known], Defs, true))]; + _ -> + Tests1 = [TC || TC <- TCs, + lists:member(TC, Tests) == true], + [make_conf(Mod, Name, Props, Tests1)] end; -check_groups(Mod, [{Name,Tests} | Gs], Defs, Levels) when is_atom(Name), - is_list(Tests) -> - check_groups(Mod, [{Name,[],Tests} | Gs], Defs, Levels); - -check_groups(Mod, [{Name,Props,Tests} | Gs], Defs, Levels) when is_atom(Name), - is_list(Props), - is_list(Tests) -> - {TestSpec,Levels1} = - case Levels of - [] -> - {check_groups(Mod, Tests, Defs, [Name]),[]}; - _ -> - {check_groups(Mod, Tests, Defs, [Name|Levels]),Levels} - end, - [make_conf(Mod, Name, Props, TestSpec) | - check_groups(Mod, Gs, Defs, Levels1)]; +find(Mod, Name, TCs, [{Name1,Props,Tests} | Gs], Known, Defs, false) + when is_atom(Name1), is_list(Props), is_list(Tests) -> + cyclic_test(Mod, Name1, Known), + [make_conf(Mod, Name1, Props, + find(Mod, Name, TCs, Tests, [Name1 | Known], Defs, false)) | + find(Mod, Name, TCs, Gs, [], Defs, false)]; + +find(Mod, Name, _TCs, [{Name,_Props,_Tests} | _Gs], _Known, _Defs, true) + when is_atom(Name) -> + E = "Duplicate groups named "++atom_to_list(Name)++" in "++ + atom_to_list(Mod)++":groups/0", + throw({error,list_to_atom(E)}); + +find(Mod, Name, all, [{Name1,Props,Tests} | Gs], Known, Defs, true) + when is_atom(Name1), is_list(Props), is_list(Tests) -> + cyclic_test(Mod, Name1, Known), + [make_conf(Mod, Name1, Props, + find(Mod, Name, all, Tests, [Name1 | Known], Defs, true)) | + find(Mod, Name, all, Gs, [], Defs, true)]; + +find(Mod, Name, TCs, [{group,Name1} | Gs], Known, Defs, Found) when is_atom(Name1) -> + find(Mod, Name, TCs, [expand(Mod, Name1, Defs) | Gs], Known, Defs, Found); -check_groups(Mod, [BadTerm | _Gs], _Defs, Levels) -> - Where = if length(Levels) == 0 -> +find(Mod, Name, TCs, [{Name1,Tests} | Gs], Known, Defs, Found) + when is_atom(Name1), is_list(Tests) -> + find(Mod, Name, TCs, [{Name1,[],Tests} | Gs], Known, Defs, Found); + +find(Mod, Name, TCs, [TC | Gs], Known, Defs, false) when is_atom(TC) -> + find(Mod, Name, TCs, Gs, Known, Defs, false); + +find(Mod, Name, TCs, [TC | Gs], Known, Defs, true) when is_atom(TC) -> + [TC | find(Mod, Name, TCs, Gs, Known, Defs, true)]; + +find(Mod, _Name, _TCs, [BadTerm | _Gs], Known, _Defs, _Found) -> + Where = if length(Known) == 0 -> atom_to_list(Mod)++":groups/0"; true -> - "group "++atom_to_list(lists:last(Levels))++ + "group "++atom_to_list(lists:last(Known))++ " in "++atom_to_list(Mod)++":groups/0" end, Term = io_lib:format("~p", [BadTerm]), E = "Bad term "++lists:flatten(Term)++" in "++Where, throw({error,list_to_atom(E)}); -check_groups(_Mod, [], _Defs, _) -> +find(_Mod, _Name, _TCs, [], _Known, _Defs, false) -> + ['$NOMATCH']; + +find(_Mod, _Name, _TCs, [], _Known, _Defs, _Found) -> []. -find_group(Mod, Name, Defs) -> +delete_subs([Conf | Confs], All) -> + All1 = delete_conf(Conf, All), + case is_sub(Conf, All1) of + true -> + delete_subs(Confs, All1); + false -> + delete_subs(Confs, All) + end; + +delete_subs([], All) -> + All. + +delete_conf({conf,Props,_,_,_}, Confs) -> + Name = proplists:get_value(name, Props), + [Conf || Conf = {conf,Props0,_,_,_} <- Confs, + Name =/= proplists:get_value(name, Props0)]. + +is_sub({conf,Props,_,_,_}=Conf, [{conf,_,_,Tests,_} | Confs]) -> + Name = proplists:get_value(name, Props), + case lists:any(fun({conf,Props0,_,_,_}) -> + case proplists:get_value(name, Props0) of + N when N == Name -> + true; + _ -> + false + end; + (_) -> + false + end, Tests) of + true -> + true; + false -> + is_sub(Conf, Tests) or is_sub(Conf, Confs) + end; + +is_sub(Conf, [_TC | Tests]) -> + is_sub(Conf, Tests); + +is_sub(_Conf, []) -> + false. + +trim(['$NOMATCH' | Tests]) -> + trim(Tests); + +trim([{conf,Props,Init,Tests,End} | Confs]) -> + case trim(Tests) of + [] -> + trim(Confs); + Trimmed -> + [{conf,Props,Init,Trimmed,End} | trim(Confs)] + end; + +trim([TC | Tests]) -> + [TC | trim(Tests)]; + +trim([]) -> + []. + +cyclic_test(Mod, Name, Names) -> + case lists:member(Name, Names) of + true -> + E = "Cyclic reference to group "++atom_to_list(Name)++ + " in "++atom_to_list(Mod)++":groups/0", + throw({error,list_to_atom(E)}); + false -> + ok + end. + +expand(Mod, Name, Defs) -> case lists:keysearch(Name, 1, Defs) of {value,Def} -> Def; @@ -750,7 +865,48 @@ find_group(Mod, Name, Defs) -> throw({error,list_to_atom(E)}) end. +make_all_conf(Dir, Mod, _Props) -> + case code:is_loaded(Mod) of + false -> + code:load_abs(filename:join(Dir,atom_to_list(Mod))); + _ -> + ok + end, + make_all_conf(Mod). + +make_all_conf(Mod) -> + case catch apply(Mod, groups, []) of + {'EXIT',_} -> + {error,{invalid_group_definition,Mod}}; + GroupDefs when is_list(GroupDefs) -> + case catch find_groups(Mod, all, all, GroupDefs) of + {error,_} = Error -> + %% this makes test_server call error_in_suite as first + %% (and only) test case so we can report Error properly + [{?MODULE,error_in_suite,[[Error]]}]; + [] -> + {error,{invalid_group_spec,Mod}}; + ConfTests -> + [{conf,Props,Init,all,End} || {conf,Props,Init,_,End} <- ConfTests] + end + end. + +make_conf(Dir, Mod, Name, Props, TestSpec) -> + case code:is_loaded(Mod) of + false -> + code:load_abs(filename:join(Dir,atom_to_list(Mod))); + _ -> + ok + end, + make_conf(Mod, Name, Props, TestSpec). + make_conf(Mod, Name, Props, TestSpec) -> + case code:is_loaded(Mod) of + false -> + code:load_file(Mod); + _ -> + ok + end, {InitConf,EndConf} = case erlang:function_exported(Mod,init_per_group,2) of true -> @@ -761,6 +917,7 @@ make_conf(Mod, Name, Props, TestSpec) -> end, {conf,[{name,Name}|Props],InitConf,TestSpec,EndConf}. +%%%----------------------------------------------------------------- get_all(Mod, ConfTests) -> case catch apply(Mod, all, []) of @@ -1076,4 +1233,31 @@ add_data_dir(File,Config) when is_list(File) -> File end. +%%%----------------------------------------------------------------- +%%% @spec overview_html_header(TestName) -> Header +overview_html_header(TestName) -> + TestName1 = lists:flatten(io_lib:format("~p", [TestName])), + Label = case application:get_env(common_test, test_label) of + {ok,Lbl} when Lbl =/= undefined -> + "<H1><FONT color=\"green\">" ++ Lbl ++ "</FONT></H1>\n"; + _ -> + "" + end, + Bgr = case ct_logs:basic_html() of + true -> + ""; + false -> + CTPath = code:lib_dir(common_test), + TileFile = filename:join(filename:join(CTPath,"priv"),"tile1.jpg"), + " background=\"" ++ TileFile ++ "\"" + end, + + ["<html>\n", + "<head><title>Test ", TestName1, " results</title>\n", + "<meta http-equiv=\"cache-control\" content=\"no-cache\">\n", + "</head>\n", + "<body", Bgr, " bgcolor=\"white\" text=\"black\" ", + "link=\"blue\" vlink=\"purple\" alink=\"red\">\n", + Label, + "<H2>Results from test ", TestName1, "</H2>\n"]. diff --git a/lib/common_test/src/ct_gen_conn.erl b/lib/common_test/src/ct_gen_conn.erl index a31e57c7ea..5aab4dd2dd 100644 --- a/lib/common_test/src/ct_gen_conn.erl +++ b/lib/common_test/src/ct_gen_conn.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -76,7 +76,7 @@ start(Name,Address,InitData,CallbackMod) -> MRef = erlang:monitor(process,Pid), receive {connected,Pid} -> - erlang:demonitor(MRef), + erlang:demonitor(MRef, [flush]), ct_util:register_connection(Name,Address,CallbackMod,Pid), {ok,Pid}; {Error,Pid} -> @@ -182,7 +182,7 @@ call(Pid,Msg) -> Pid ! {Msg,{self(),Ref}}, receive {Ref, Result} -> - erlang:demonitor(MRef), + erlang:demonitor(MRef, [flush]), case Result of {retry,_Data} -> call(Pid,Result); diff --git a/lib/common_test/src/ct_logs.erl b/lib/common_test/src/ct_logs.erl index bd1a89ae1f..f8ace73cbf 100644 --- a/lib/common_test/src/ct_logs.erl +++ b/lib/common_test/src/ct_logs.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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 @@ -export([make_all_suites_index/1,make_all_runs_index/1]). %% Logging stuff directly from testcase --export([tc_log/3,tc_print/3,tc_pal/3]). +-export([tc_log/3,tc_print/3,tc_pal/3, + basic_html/0]). %% Simulate logger process for use without ct environment running -export([simulate/0]). @@ -57,7 +58,7 @@ -define(table_color2,"#E4F0FE"). -define(table_color3,"#F0F8FF"). --define(testname_width, 70). +-define(testname_width, 60). -define(abs(Name), filename:absname(Name)). @@ -80,7 +81,7 @@ init(Mode) -> MRef = erlang:monitor(process,Pid), receive {started,Pid,Result} -> - erlang:demonitor(MRef), + erlang:demonitor(MRef, [flush]), Result; {'DOWN',MRef,process,_,Reason} -> exit({could_not_start_process,?MODULE,Reason}) @@ -163,7 +164,7 @@ call(Msg) -> ?MODULE ! {Msg,{self(),Ref}}, receive {Ref, Result} -> - erlang:demonitor(MRef), + erlang:demonitor(MRef, [flush]), Result; {'DOWN',MRef,process,_,Reason} -> {error,{process_down,?MODULE,Reason}} @@ -383,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 @@ -460,9 +464,11 @@ logger_loop(State) -> {'EXIT',_Reason} -> Fd = State#logger_state.ct_log_fd, io:format(Fd, - "Logging fails! Str: ~p, Args: ~p~n", + "Logging fails! " + "Str: ~p, Args: ~p~n", [Str,Args]), - %% stop the testcase, we need to see the fault + %% stop the testcase, we need + %% to see the fault exit(Pid,logging_failed), ok; IoStr when IoList == [] -> @@ -505,7 +511,7 @@ logger_loop(State) -> logger_loop(State); {set_stylesheet,TC,SSFile} -> Fd = State#logger_state.ct_log_fd, - io:format(Fd, "~p uses external style sheet: ~s~n", [TC,SSFile]), + io:format(Fd, "~p loading external style sheet: ~s~n", [TC,SSFile]), logger_loop(State#logger_state{stylesheet=SSFile}); {clear_stylesheet,_} when State#logger_state.stylesheet == undefined -> logger_loop(State); @@ -716,7 +722,7 @@ make_last_run_index1(StartTime,IndexName) -> [Log]; Logs -> case read_totals_file(?totals_name) of - {_Node,Logs0,_Totals} -> + {_Node,_Lbl,Logs0,_Totals} -> insert_dirs(Logs,Logs0); _ -> %% someone deleted the totals file!? @@ -728,10 +734,15 @@ make_last_run_index1(StartTime,IndexName) -> {ok,Bin} -> binary_to_term(Bin); _ -> [] end, - {ok,Index0,Totals} = make_last_run_index(Logs1, index_header(StartTime), + Label = case application:get_env(common_test, test_label) of + {ok,Lbl} -> Lbl; + _ -> undefined + end, + {ok,Index0,Totals} = make_last_run_index(Logs1, + index_header(Label,StartTime), 0, 0, 0, 0, 0, Missing), %% write current Totals to file, later to be used in all_runs log - write_totals_file(?totals_name,Logs1,Totals), + write_totals_file(?totals_name,Label,Logs1,Totals), Index = [Index0|index_footer()], case force_write_file(IndexName, Index) of ok -> @@ -761,7 +772,7 @@ make_last_run_index([Name|Rest], Result, TotSucc, TotFail, UserSkip, AutoSkip, TotNotBuilt, Missing); LastLogDir -> SuiteName = filename:rootname(filename:basename(Name)), - case make_one_index_entry(SuiteName, LastLogDir, false, Missing) of + case make_one_index_entry(SuiteName, LastLogDir, "-", false, Missing) of {Result1,Succ,Fail,USkip,ASkip,NotBuilt} -> %% for backwards compatibility AutoSkip1 = case catch AutoSkip+ASkip of @@ -780,18 +791,18 @@ make_last_run_index([], Result, TotSucc, TotFail, UserSkip, AutoSkip, TotNotBuil {ok, [Result|total_row(TotSucc, TotFail, UserSkip, AutoSkip, TotNotBuilt, false)], {TotSucc,TotFail,UserSkip,AutoSkip,TotNotBuilt}}. -make_one_index_entry(SuiteName, LogDir, All, Missing) -> +make_one_index_entry(SuiteName, LogDir, Label, All, Missing) -> case count_cases(LogDir) of {Succ,Fail,UserSkip,AutoSkip} -> NotBuilt = not_built(SuiteName, LogDir, All, Missing), - NewResult = make_one_index_entry1(SuiteName, LogDir, Succ, Fail, + NewResult = make_one_index_entry1(SuiteName, LogDir, Label, Succ, Fail, UserSkip, AutoSkip, NotBuilt, All), {NewResult,Succ,Fail,UserSkip,AutoSkip,NotBuilt}; error -> error end. -make_one_index_entry1(SuiteName, Link, Success, Fail, UserSkip, AutoSkip, +make_one_index_entry1(SuiteName, Link, Label, Success, Fail, UserSkip, AutoSkip, NotBuilt, All) -> LogFile = filename:join(Link, ?suitelog_name ++ ".html"), CrashDumpName = SuiteName ++ "_erl_crash.dump", @@ -803,7 +814,7 @@ make_one_index_entry1(SuiteName, Link, Success, Fail, UserSkip, AutoSkip, false -> "" end, - {Timestamp,Node,AllInfo} = + {Lbl,Timestamp,Node,AllInfo} = case All of {true,OldRuns} -> [_Prefix,NodeOrDate|_] = string:tokens(Link,"."), @@ -811,20 +822,21 @@ make_one_index_entry1(SuiteName, Link, Success, Fail, UserSkip, AutoSkip, 0 -> "-"; _ -> NodeOrDate end, - N = ["<TD ALIGN=right>",Node1,"</TD>\n"], + N = ["<TD ALIGN=right><FONT SIZE=-1>",Node1,"</FONT></TD>\n"], CtRunDir = filename:dirname(filename:dirname(Link)), - T = ["<TD>",timestamp(CtRunDir),"</TD>\n"], + L = ["<TD ALIGN=center><FONT SIZE=-1><B>",Label,"</FONT></B></TD>\n"], + T = ["<TD><FONT SIZE=-1>",timestamp(CtRunDir),"</FONT></TD>\n"], CtLogFile = filename:join(CtRunDir,?ct_log_name), OldRunsLink = case OldRuns of [] -> "none"; _ -> "<A HREF=\""++?all_runs_name++"\">Old Runs</A>" end, - A=["<TD><A HREF=\"",CtLogFile,"\">CT Log</A></TD>\n", - "<TD>",OldRunsLink,"</TD>\n"], - {T,N,A}; + A=["<TD><FONT SIZE=-1><A HREF=\"",CtLogFile,"\">CT Log</A></FONT></TD>\n", + "<TD><FONT SIZE=-1>",OldRunsLink,"</FONT></TD>\n"], + {L,T,N,A}; false -> - {"","",""} + {"","","",""} end, NotBuiltStr = if NotBuilt == 0 -> @@ -851,7 +863,8 @@ make_one_index_entry1(SuiteName, Link, Success, Fail, UserSkip, AutoSkip, {UserSkip+AutoSkip,integer_to_list(UserSkip),ASStr} end, ["<TR valign=top>\n", - "<TD><A HREF=\"",LogFile,"\">",SuiteName,"</A>",CrashDumpLink,"</TD>\n", + "<TD><FONT SIZE=-1><A HREF=\"",LogFile,"\">",SuiteName,"</A>",CrashDumpLink,"</FONT></TD>\n", + Lbl, Timestamp, "<TD ALIGN=right>",integer_to_list(Success),"</TD>\n", "<TD ALIGN=right>",FailStr,"</TD>\n", @@ -862,12 +875,14 @@ make_one_index_entry1(SuiteName, Link, Success, Fail, UserSkip, AutoSkip, AllInfo, "</TR>\n"]. total_row(Success, Fail, UserSkip, AutoSkip, NotBuilt, All) -> - {TimestampCell,AllInfo} = + {Label,TimestampCell,AllInfo} = case All of - true -> - {"<TD> </TD>\n","<TD> </TD>\n<TD> </TD>\n"}; + true -> + {"<TD> </TD>\n", + "<TD> </TD>\n", + "<TD> </TD>\n<TD> </TD>\n"}; false -> - {"",""} + {"","",""} end, {AllSkip,UserSkipStr,AutoSkipStr} = @@ -877,6 +892,7 @@ total_row(Success, Fail, UserSkip, AutoSkip, NotBuilt, All) -> end, ["<TR valign=top>\n", "<TD><B>Total</B></TD>", + Label, TimestampCell, "<TD ALIGN=right><B>",integer_to_list(Success),"<B></TD>\n", "<TD ALIGN=right><B>",integer_to_list(Fail),"<B></TD>\n", @@ -937,13 +953,21 @@ term_to_text(Term) -> %%% Headers and footers. -index_header(StartTime) -> - [header("Test Results " ++ format_time(StartTime)) | +index_header(Label, StartTime) -> + Head = + case Label of + undefined -> + header("Test Results", format_time(StartTime)); + _ -> + header("Test Results for \"" ++ Label ++ "\"", + format_time(StartTime)) + end, + [Head | ["<CENTER>\n", "<P><A HREF=\"",?ct_log_name,"\">Common Test Framework Log</A></P>", "<TABLE border=\"3\" cellpadding=\"5\" " "BGCOLOR=\"",?table_color3,"\">\n" - "<th><B>Name</B></th>\n", + "<th><B>Test Name</B></th>\n", "<th><font color=\"",?table_color3,"\">_</font>Ok" "<font color=\"",?table_color3,"\">_</font></th>\n" "<th>Failed</th>\n", @@ -952,13 +976,17 @@ index_header(StartTime) -> "\n"]]. all_suites_index_header() -> + {ok,Cwd} = file:get_cwd(), + LogDir = filename:basename(Cwd), + AllRuns = "All test runs in \"" ++ LogDir ++ "\"", [header("Test Results") | ["<CENTER>\n", - "<A HREF=\"",?all_runs_name,"\">All Test Runs in this directory</A>\n", + "<A HREF=\"",?all_runs_name,"\">",AllRuns,"</A>\n", "<br><br>\n", "<TABLE border=\"3\" cellpadding=\"5\" " "BGCOLOR=\"",?table_color2,"\">\n" - "<th>Name</th>\n", + "<th>Test Name</th>\n", + "<th>Label</th>\n", "<th>Test Run Started</th>\n", "<th><font color=\"",?table_color2,"\">_</font>Ok" "<font color=\"",?table_color2,"\">_</font></th>\n" @@ -971,13 +999,17 @@ all_suites_index_header() -> "\n"]]. all_runs_header() -> - [header("All test runs in current directory") | + {ok,Cwd} = file:get_cwd(), + LogDir = filename:basename(Cwd), + Title = "All test runs in \"" ++ LogDir ++ "\"", + [header(Title) | ["<CENTER><TABLE border=\"3\" cellpadding=\"5\" " "BGCOLOR=\"",?table_color1,"\">\n" "<th><B>History</B></th>\n" "<th><B>Node</B></th>\n" + "<th><B>Label</B></th>\n" "<th>Tests</th>\n" - "<th><B>Names</B></th>\n" + "<th><B>Test Names</B></th>\n" "<th>Total</th>\n" "<th><font color=\"",?table_color1,"\">_</font>Ok" "<font color=\"",?table_color1,"\">_</font></th>\n" @@ -987,12 +1019,23 @@ all_runs_header() -> "\n"]]. header(Title) -> + header1(Title, ""). +header(Title, SubTitle) -> + header1(Title, SubTitle). + +header1(Title, SubTitle) -> + SubTitleHTML = if SubTitle =/= "" -> + ["<CENTER>\n", + "<H2>" ++ SubTitle ++ "</H2>\n", + "</CENTER>\n<BR>\n"]; + true -> "<BR>\n" + end, ["<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n" "<!-- autogenerated by '"++atom_to_list(?MODULE)++"'. -->\n" "<HTML>\n", "<HEAD>\n", - "<TITLE>" ++ Title ++ "</TITLE>\n", + "<TITLE>" ++ Title ++ " " ++ SubTitle ++ "</TITLE>\n", "<META HTTP-EQUIV=\"CACHE-CONTROL\" CONTENT=\"NO-CACHE\">\n", "</HEAD>\n", @@ -1004,6 +1047,7 @@ header(Title) -> "<CENTER>\n", "<H1>" ++ Title ++ "</H1>\n", "</CENTER>\n", + SubTitleHTML, "<!-- ---- CONTENT ---- -->\n"]. @@ -1013,19 +1057,28 @@ index_footer() -> footer() -> ["<P><CENTER>\n" - "<HR>\n" - "<P><FONT SIZE=-1>\n" - "Copyright © ", year(), - " <A HREF=\"http://erlang.ericsson.se\">Open Telecom Platform</A><BR>\n" - "Updated: <!date>", current_time(), "<!/date><BR>\n" - "</FONT>\n" - "</CENTER>\n" - "</body>\n"]. + "<BR><BR>\n" + "<HR>\n" + "<P><FONT SIZE=-1>\n" + "Copyright © ", year(), + " <A HREF=\"http://erlang.ericsson.se\">Open Telecom Platform</A><BR>\n" + "Updated: <!date>", current_time(), "<!/date><BR>\n" + "</FONT>\n" + "</CENTER>\n" + "</body>\n"]. body_tag() -> - "<body bgcolor=\"#FFFFFF\" text=\"#000000\" link=\"#0000FF\"" - "vlink=\"#800080\" alink=\"#FF0000\">\n". + case basic_html() of + true -> + "<body bgcolor=\"#FFFFFF\" text=\"#000000\" link=\"#0000FF\" " + "vlink=\"#800080\" alink=\"#FF0000\">\n"; + false -> + CTPath = code:lib_dir(common_test), + TileFile = filename:join(filename:join(CTPath,"priv"),"tile1.jpg"), + "<body background=\"" ++ TileFile ++ "\" bgcolor=\"#FFFFFF\" text=\"#000000\" link=\"#0000FF\" " + "vlink=\"#800080\" alink=\"#FF0000\">\n" + end. current_time() -> format_time(calendar:local_time()). @@ -1217,7 +1270,7 @@ runentry(Dir, BasicHtml) -> TotalsFile = filename:join(Dir,?totals_name), TotalsStr = case read_totals_file(TotalsFile) of - {Node,Logs,{TotSucc,TotFail,UserSkip,AutoSkip,NotBuilt}} -> + {Node,Label,Logs,{TotSucc,TotFail,UserSkip,AutoSkip,NotBuilt}} -> TotFailStr = if TotFail > 0 -> ["<FONT color=\"red\">", @@ -1263,6 +1316,7 @@ runentry(Dir, BasicHtml) -> end, Total = TotSucc+TotFail+AllSkip, A = ["<TD ALIGN=center><FONT SIZE=-1>",Node,"</FONT></TD>\n", + "<TD ALIGN=center><FONT SIZE=-1><B>",Label,"</B></FONT></TD>\n", "<TD ALIGN=right>",NoOfTests,"</TD>\n"], B = if BasicHtml -> ["<TD ALIGN=center><FONT SIZE=-1>",TestNamesTrunc,"</FONT></TD>\n"]; @@ -1283,17 +1337,19 @@ runentry(Dir, BasicHtml) -> end, Index = filename:join(Dir,?index_name), ["<TR>\n" - "<TD><A HREF=\"",Index,"\">",timestamp(Dir),"</A>",TotalsStr,"</TD>\n" + "<TD><FONT SIZE=-1><A HREF=\"",Index,"\">",timestamp(Dir),"</A>",TotalsStr,"</FONT></TD>\n" "</TR>\n"]. -write_totals_file(Name,Logs,Totals) -> +write_totals_file(Name,Label,Logs,Totals) -> AbsName = ?abs(Name), notify_and_lock_file(AbsName), force_write_file(AbsName, term_to_binary({atom_to_list(node()), - Logs,Totals})), + Label,Logs,Totals})), notify_and_unlock_file(AbsName). +%% this function needs to convert from old formats to new so that old +%% test results (prev ct versions) can be listed together with new read_totals_file(Name) -> AbsName = ?abs(Name), notify_and_lock_file(AbsName), @@ -1303,12 +1359,23 @@ read_totals_file(Name) -> case catch binary_to_term(Bin) of {'EXIT',_Reason} -> % corrupt file {"-",[],undefined}; - R = {Node,Ls,Tot} -> + {Node,Label,Ls,Tot} -> % all info available + Label1 = case Label of + undefined -> "-"; + _ -> Label + end, case Tot of - {_,_,_,_,_} -> % latest format - R; + {_Ok,_Fail,_USkip,_ASkip,_NoBuild} -> % latest format + {Node,Label1,Ls,Tot}; {TotSucc,TotFail,AllSkip,NotBuilt} -> - {Node,Ls,{TotSucc,TotFail,AllSkip,undefined,NotBuilt}} + {Node,Label1,Ls,{TotSucc,TotFail,AllSkip,undefined,NotBuilt}} + end; + {Node,Ls,Tot} -> % no label found + case Tot of + {_Ok,_Fail,_USkip,_ASkip,_NoBuild} -> % latest format + {Node,"-",Ls,Tot}; + {TotSucc,TotFail,AllSkip,NotBuilt} -> + {Node,"-",Ls,{TotSucc,TotFail,AllSkip,undefined,NotBuilt}} end; %% for backwards compatibility {Ls,Tot} -> {"-",Ls,Tot}; @@ -1411,7 +1478,7 @@ make_all_suites_index1(When,AllSuitesLogDirs) -> make_all_suites_index2(IndexName,AllSuitesLogDirs) -> {ok,Index0,_Totals} = make_all_suites_index3(AllSuitesLogDirs, all_suites_index_header(), - 0, 0, 0, 0, 0), + 0, 0, 0, 0, 0, []), Index = [Index0|index_footer()], case force_write_file(IndexName, Index) of ok -> @@ -1421,14 +1488,25 @@ make_all_suites_index2(IndexName,AllSuitesLogDirs) -> end. make_all_suites_index3([{SuiteName,[LastLogDir|OldDirs]}|Rest], - Result, TotSucc, TotFail, UserSkip, AutoSkip, TotNotBuilt) -> + Result, TotSucc, TotFail, UserSkip, AutoSkip, TotNotBuilt, + Labels) -> [EntryDir|_] = filename:split(LastLogDir), Missing = case file:read_file(filename:join(EntryDir,?missing_suites_info)) of {ok,Bin} -> binary_to_term(Bin); _ -> [] end, - case make_one_index_entry(SuiteName, LastLogDir, {true,OldDirs}, Missing) of + {Label,Labels1} = + case proplists:get_value(EntryDir, Labels) of + undefined -> + case read_totals_file(filename:join(EntryDir,?totals_name)) of + {_,Lbl,_,_} -> {Lbl,[{EntryDir,Lbl}|Labels]}; + _ -> {"-",[{EntryDir,"-"}|Labels]} + end; + Lbl -> + {Lbl,Labels} + end, + case make_one_index_entry(SuiteName, LastLogDir, Label, {true,OldDirs}, Missing) of {Result1,Succ,Fail,USkip,ASkip,NotBuilt} -> %% for backwards compatibility AutoSkip1 = case catch AutoSkip+ASkip of @@ -1437,13 +1515,13 @@ make_all_suites_index3([{SuiteName,[LastLogDir|OldDirs]}|Rest], end, make_all_suites_index3(Rest, [Result|Result1], TotSucc+Succ, TotFail+Fail, UserSkip+USkip, AutoSkip1, - TotNotBuilt+NotBuilt); + TotNotBuilt+NotBuilt,Labels1); error -> make_all_suites_index3(Rest, Result, TotSucc, TotFail, - UserSkip, AutoSkip, TotNotBuilt) + UserSkip, AutoSkip, TotNotBuilt,Labels1) end; make_all_suites_index3([], Result, TotSucc, TotFail, UserSkip, AutoSkip, - TotNotBuilt) -> + TotNotBuilt,_) -> {ok, [Result|total_row(TotSucc, TotFail, UserSkip, AutoSkip, TotNotBuilt,true)], {TotSucc,TotFail,UserSkip,AutoSkip,TotNotBuilt}}. diff --git a/lib/common_test/src/ct_master.erl b/lib/common_test/src/ct_master.erl index 7eb2c3cfef..42e4cf08f4 100644 --- a/lib/common_test/src/ct_master.erl +++ b/lib/common_test/src/ct_master.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -28,7 +28,7 @@ -export([abort/0,abort/1,progress/0]). --export([init_master/6, init_node_ctrl/3]). +-export([init_master/7, init_node_ctrl/3]). -export([status/2]). @@ -49,7 +49,8 @@ %%% OptTuples = {config,CfgFiles} | {dir,TestDirs} | {suite,Suites} | %%% {testcase,Cases} | {spec,TestSpecs} | {allow_user_terms,Bool} | %%% {logdir,LogDir} | {event_handler,EventHandlers} | -%%% {silent_connections,Conns} | {cover,CoverSpecFile} +%%% {silent_connections,Conns} | {cover,CoverSpecFile} | +%%% {userconfig, UserCfgFiles} %%% CfgFiles = string() | [string()] %%% TestDirs = string() | [string()] %%% Suites = atom() | [atom()] @@ -98,11 +99,14 @@ run([TS|TestSpecs],AllowUserTerms,InclNodes,ExclNodes) when is_list(TS), {error,Reason} -> {error,Reason}; TSRec=#testspec{logdir=AllLogDirs, - config=AllCfgFiles, + config=StdCfgFiles, + userconfig=UserCfgFiles, + init=AllInitOpts, event_handler=AllEvHs} -> + AllCfgFiles = {StdCfgFiles, UserCfgFiles}, RunSkipPerNode = ct_testspec:prepare_tests(TSRec), RunSkipPerNode2 = exclude_nodes(ExclNodes,RunSkipPerNode), - run_all(RunSkipPerNode2,AllLogDirs,AllCfgFiles,AllEvHs,[],[],TS1) + run_all(RunSkipPerNode2,AllLogDirs,AllCfgFiles,AllEvHs,[],[],AllInitOpts,TS1) end, [{TS,Result} | run(TestSpecs,AllowUserTerms,InclNodes,ExclNodes)]; run([],_,_,_) -> @@ -157,10 +161,13 @@ run_on_node([TS|TestSpecs],AllowUserTerms,Node) when is_list(TS),is_atom(Node) - {error,Reason} -> {error,Reason}; TSRec=#testspec{logdir=AllLogDirs, - config=AllCfgFiles, + config=StdCfgFiles, + init=AllInitOpts, + userconfig=UserCfgFiles, event_handler=AllEvHs} -> + AllCfgFiles = {StdCfgFiles, UserCfgFiles}, {Run,Skip} = ct_testspec:prepare_tests(TSRec,Node), - run_all([{Node,Run,Skip}],AllLogDirs,AllCfgFiles,AllEvHs,[],[],TS1) + run_all([{Node,Run,Skip}],AllLogDirs,AllCfgFiles,AllEvHs,[],[],AllInitOpts,TS1) end, [{TS,Result} | run_on_node(TestSpecs,AllowUserTerms,Node)]; run_on_node([],_,_) -> @@ -180,7 +187,9 @@ run_on_node(TestSpecs,Node) -> -run_all([{Node,Run,Skip}|Rest],AllLogDirs,AllCfgFiles,AllEvHs,NodeOpts,LogDirs,Specs) -> +run_all([{Node,Run,Skip}|Rest],AllLogDirs, + {AllStdCfgFiles, AllUserCfgFiles}=AllCfgFiles, + AllEvHs,NodeOpts,LogDirs,InitOptions,Specs) -> LogDir = lists:foldl(fun({N,Dir},_Found) when N == Node -> Dir; @@ -191,29 +200,36 @@ run_all([{Node,Run,Skip}|Rest],AllLogDirs,AllCfgFiles,AllEvHs,NodeOpts,LogDirs,S (_Dir,Found) -> Found end,".",AllLogDirs), - CfgFiles = + + StdCfgFiles = lists:foldr(fun({N,F},Fs) when N == Node -> [F|Fs]; ({_N,_F},Fs) -> Fs; (F,Fs) -> [F|Fs] - end,[],AllCfgFiles), + end,[],AllStdCfgFiles), + UserCfgFiles = + lists:foldr(fun({N,F},Fs) when N == Node -> [{userconfig, F}|Fs]; + ({_N,_F},Fs) -> Fs; + (F,Fs) -> [{userconfig, F}|Fs] + end,[],AllUserCfgFiles), EvHs = lists:foldr(fun({N,H,A},Hs) when N == Node -> [{H,A}|Hs]; ({_N,_H,_A},Hs) -> Hs; ({H,A},Hs) -> [{H,A}|Hs] end,[],AllEvHs), + NO = {Node,[{prepared_tests,{Run,Skip},Specs}, {logdir,LogDir}, - {config,CfgFiles}, - {event_handler,EvHs}]}, - run_all(Rest,AllLogDirs,AllCfgFiles,AllEvHs,[NO|NodeOpts],[LogDir|LogDirs],Specs); -run_all([],AllLogDirs,_,AllEvHs,NodeOpts,LogDirs,Specs) -> + {config,StdCfgFiles}, + {event_handler,EvHs}] ++ UserCfgFiles}, + run_all(Rest,AllLogDirs,AllCfgFiles,AllEvHs,[NO|NodeOpts],[LogDir|LogDirs],InitOptions,Specs); +run_all([],AllLogDirs,_,AllEvHs,NodeOpts,LogDirs,InitOptions,Specs) -> Handlers = [{H,A} || {Master,H,A} <- AllEvHs, Master == master], MasterLogDir = case lists:keysearch(master,1,AllLogDirs) of {value,{_,Dir}} -> Dir; false -> "." end, log(tty,"Master Logdir","~s",[MasterLogDir]), - start_master(lists:reverse(NodeOpts),Handlers,MasterLogDir,LogDirs,Specs), + start_master(lists:reverse(NodeOpts),Handlers,MasterLogDir,LogDirs,InitOptions,Specs), ok. @@ -251,17 +267,17 @@ progress() -> %%% MASTER, runs on central controlling node. %%%----------------------------------------------------------------- start_master(NodeOptsList) -> - start_master(NodeOptsList,[],".",[],[]). + start_master(NodeOptsList,[],".",[],[],[]). -start_master(NodeOptsList,EvHandlers,MasterLogDir,LogDirs,Specs) -> +start_master(NodeOptsList,EvHandlers,MasterLogDir,LogDirs,InitOptions,Specs) -> Master = spawn_link(?MODULE,init_master,[self(),NodeOptsList,EvHandlers, - MasterLogDir,LogDirs,Specs]), + MasterLogDir,LogDirs,InitOptions,Specs]), receive {Master,Result} -> Result end. %%% @hidden -init_master(Parent,NodeOptsList,EvHandlers,MasterLogDir,LogDirs,Specs) -> +init_master(Parent,NodeOptsList,EvHandlers,MasterLogDir,LogDirs,InitOptions,Specs) -> case whereis(ct_master) of undefined -> register(ct_master,self()), @@ -314,10 +330,10 @@ init_master(Parent,NodeOptsList,EvHandlers,MasterLogDir,LogDirs,Specs) -> Pid when is_pid(Pid) -> ok end, - init_master1(Parent,NodeOptsList,LogDirs). + init_master1(Parent,NodeOptsList,InitOptions,LogDirs). -init_master1(Parent,NodeOptsList,LogDirs) -> - {Inaccessible,NodeOptsList1} = ping_nodes(NodeOptsList,[],[]), +init_master1(Parent,NodeOptsList,InitOptions,LogDirs) -> + {Inaccessible,NodeOptsList1,InitOptions1} = init_nodes(NodeOptsList,InitOptions), case Inaccessible of [] -> init_master2(Parent,NodeOptsList,LogDirs); @@ -331,7 +347,7 @@ init_master1(Parent,NodeOptsList,LogDirs) -> "Proceeding without: ~p",[Inaccessible]), init_master2(Parent,NodeOptsList1,LogDirs); "r\n" -> - init_master1(Parent,NodeOptsList,LogDirs); + init_master1(Parent,NodeOptsList,InitOptions1,LogDirs); _ -> log(html,"Aborting Tests","",[]), ct_master_event:stop(), @@ -542,6 +558,9 @@ get_pid(Node,NodeCtrlPids) -> undefined end. +ping_nodes(NodeOptions)-> + ping_nodes(NodeOptions, [], []). + ping_nodes([NO={Node,_Opts}|NOs],Inaccessible,NodeOpts) -> case net_adm:ping(Node) of pong -> @@ -678,13 +697,80 @@ call(Pid,Msg) -> {'DOWN', Ref, _, _, _} -> {error,master_died} end, - erlang:demonitor(Ref), + erlang:demonitor(Ref, [flush]), Return. reply(Result,To) -> To ! {self(),Result}, ok. +init_nodes(NodeOptions, InitOptions)-> + ping_nodes(NodeOptions), + start_nodes(InitOptions), + eval_on_nodes(InitOptions), + {Inaccessible, NodeOptions1}=ping_nodes(NodeOptions), + InitOptions1 = filter_accessible(InitOptions, Inaccessible), + {Inaccessible, NodeOptions1, InitOptions1}. + +% only nodes which are inaccessible now, should be initiated later +filter_accessible(InitOptions, Inaccessible)-> + [{Node,Option}||{Node,Option}<-InitOptions, lists:member(Node, Inaccessible)]. + +start_nodes(InitOptions)-> + lists:foreach(fun({NodeName, Options})-> + [NodeS,HostS]=string:tokens(atom_to_list(NodeName), "@"), + Node=list_to_atom(NodeS), + Host=list_to_atom(HostS), + HasNodeStart = lists:keymember(node_start, 1, Options), + IsAlive = lists:member(NodeName, nodes()), + case {HasNodeStart, IsAlive} of + {false, false}-> + io:format("WARNING: Node ~p is not alive but has no node_start option~n", [NodeName]); + {false, true}-> + io:format("Node ~p is alive~n", [NodeName]); + {true, false}-> + {node_start, NodeStart} = lists:keyfind(node_start, 1, Options), + {value, {callback_module, Callback}, NodeStart2}= + lists:keytake(callback_module, 1, NodeStart), + case Callback:start(Host, Node, NodeStart2) of + {ok, NodeName} -> + io:format("Node ~p started successfully with callback ~p~n", [NodeName,Callback]); + {error, Reason, _NodeName} -> + io:format("Failed to start node ~p with callback ~p! Reason: ~p~n", [NodeName, Callback, Reason]) + end; + {true, true}-> + io:format("WARNING: Node ~p is alive but has node_start option~n", [NodeName]) + end + end, + InitOptions). + +eval_on_nodes(InitOptions)-> + lists:foreach(fun({NodeName, Options})-> + HasEval = lists:keymember(eval, 1, Options), + IsAlive = lists:member(NodeName, nodes()), + case {HasEval, IsAlive} of + {false,_}-> + ok; + {true,false}-> + io:format("WARNING: Node ~p is not alive but has eval option ~n", [NodeName]); + {true,true}-> + {eval, MFAs} = lists:keyfind(eval, 1, Options), + evaluate(NodeName, MFAs) + end + end, + InitOptions). + +evaluate(Node, [{M,F,A}|MFAs])-> + case rpc:call(Node, M, F, A) of + {badrpc,Reason}-> + io:format("WARNING: Failed to call ~p:~p/~p on node ~p due to ~p~n", [M,F,length(A),Node,Reason]); + Result-> + io:format("Called ~p:~p/~p on node ~p, result: ~p~n", [M,F,length(A),Node,Result]) + end, + evaluate(Node, MFAs); +evaluate(_Node, [])-> + ok. + %cast(Msg) -> % cast(whereis(ct_master),Msg). diff --git a/lib/common_test/src/ct_master_logs.erl b/lib/common_test/src/ct_master_logs.erl index 63f60b1182..244faace06 100644 --- a/lib/common_test/src/ct_master_logs.erl +++ b/lib/common_test/src/ct_master_logs.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -44,7 +44,7 @@ start(LogDir,Nodes) -> MRef = erlang:monitor(process,Pid), receive {started,Pid,Result} -> - erlang:demonitor(MRef), + erlang:demonitor(MRef, [flush]), {Pid,Result}; {'DOWN',MRef,process,_,Reason} -> exit({could_not_start_process,?MODULE,Reason}) @@ -435,7 +435,7 @@ call(Msg) -> ?MODULE ! {Msg,{self(),Ref}}, receive {Ref, Result} -> - erlang:demonitor(MRef), + erlang:demonitor(MRef, [flush]), Result; {'DOWN',MRef,process,_,Reason} -> {error,{process_down,?MODULE,Reason}} diff --git a/lib/common_test/src/ct_repeat.erl b/lib/common_test/src/ct_repeat.erl index 7ac6e045d7..be3c485b75 100644 --- a/lib/common_test/src/ct_repeat.erl +++ b/lib/common_test/src/ct_repeat.erl @@ -1,26 +1,26 @@ %% %% %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 %% 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% %% %%% @doc Common Test Framework module that handles repeated test runs %%% %%% <p>This module exports functions for repeating tests. The following -%%% script flags (or equivalent ct:run_test/1 options) are supported: +%%% start flags (or equivalent ct:run_test/1 options) are supported: %%% -until <StopTime>, StopTime = YYMoMoDDHHMMSS | HHMMSS %%% -duration <DurTime>, DurTime = HHMMSS %%% -force_stop diff --git a/lib/common_test/src/ct_run.erl b/lib/common_test/src/ct_run.erl index 6b1063f74c..586b3893f1 100644 --- a/lib/common_test/src/ct_run.erl +++ b/lib/common_test/src/ct_run.erl @@ -24,7 +24,6 @@ -module(ct_run). - %% Script interface -export([script_start/0,script_usage/0]). @@ -46,11 +45,28 @@ -define(abs(Name), filename:absname(Name)). -define(testdir(Name, Suite), ct_util:get_testdir(Name, Suite)). +-record(opts, {label, + vts, + shell, + cover, + coverspec, + step, + logdir, + config = [], + event_handlers = [], + include = [], + silent_connections, + stylesheet, + multiply_timetraps = 1, + scale_timetraps = false, + testspecs = [], + tests}). + %%%----------------------------------------------------------------- %%% @spec script_start() -> void() %%% -%%% @doc Start tests via the run_test script. -%%% +%%% @doc Start tests via the run_test program or script. +%%% %%% <p>Example:<br/><code>./run_test -config config.ctc -dir %%% $TEST_DIR</code></p> %%% @@ -59,13 +75,53 @@ %%% script_start() -> process_flag(trap_exit, true), - Args = merge_arguments(init:get_arguments()), + Init = init:get_arguments(), + CtArgs = lists:takewhile(fun({ct_erl_args,_}) -> false; + (_) -> true end, Init), + + %% convert relative dirs added with pa or pz (pre erl_args on + %% the run_test command line) to absolute so that app modules + %% can be found even after CT changes CWD to logdir + rel_to_abs(CtArgs), + + Args = + case application:get_env(common_test, run_test_start_opts) of + {ok,EnvStartOpts} -> + FlagFilter = fun(Flags) -> + lists:filter(fun({root,_}) -> false; + ({progname,_}) -> false; + ({home,_}) -> false; + ({noshell,_}) -> false; + ({noinput,_}) -> false; + (_) -> true + end, Flags) + end, + %% used for purpose of testing the run_test interface + io:format(user, "~n-------------------- START ARGS --------------------~n", []), + io:format(user, "--- Init args:~n~p~n", [FlagFilter(Init)]), + io:format(user, "--- CT args:~n~p~n", [FlagFilter(CtArgs)]), + EnvArgs = opts2args(EnvStartOpts), + io:format(user, "--- Env opts -> args:~n~p~n =>~n~p~n", + [EnvStartOpts,EnvArgs]), + Merged = merge_arguments(CtArgs ++ EnvArgs), + io:format(user, "--- Merged args:~n~p~n", [FlagFilter(Merged)]), + io:format(user, "----------------------------------------------------~n~n", []), + Merged; + _ -> + merge_arguments(CtArgs) + end, + case proplists:get_value(help, Args) of + undefined -> script_start(Args); + _ -> script_usage() + end. + +script_start(Args) -> Tracing = start_trace(Args), - Res = + Res = case ct_repeat:loop_test(script, Args) of - false -> + false -> {ok,Cwd} = file:get_cwd(), - CTVsn = + CTVsn = case filename:basename(code:lib_dir(common_test)) of CTBase when is_list(CTBase) -> case string:tokens(CTBase, "-") of @@ -76,7 +132,7 @@ script_start() -> io:format("~nCommon Test~s starting (cwd is ~s)~n~n", [CTVsn,Cwd]), Self = self(), Pid = spawn_link(fun() -> script_start1(Self, Args) end), - receive + receive {'EXIT',Pid,Reason} -> case Reason of {user_error,What} -> @@ -98,296 +154,335 @@ script_start() -> Result end, stop_trace(Tracing), + timer:sleep(1000), Res. script_start1(Parent, Args) -> - case lists:keymember(preload, 1, Args) of - true -> preload(); - false -> ok - end, - - VtsOrShell = - case lists:keymember(vts, 1, Args) of - true -> - vts; - false -> - case lists:keymember(shell, 1, Args) of - true -> shell; - false -> false - end - end, - LogDir = - case lists:keysearch(logdir, 1, Args) of - {value,{logdir,[LogD]}} -> LogD; - false -> "." - end, - EvHandlers = - case lists:keysearch(event_handler, 1, Args) of - {value,{event_handler,Handlers}} -> - lists:map(fun(H) -> {list_to_atom(H),[]} end, Handlers); - false -> - [] - end, - Cover = - case lists:keysearch(cover, 1, Args) of - {value,{cover,CoverFile}} -> - {cover,?abs(CoverFile)}; - false -> - false - end, - - case lists:keysearch(ct_decrypt_key, 1, Args) of - {value,{_,[DecryptKey]}} -> + %% read general start flags + Label = get_start_opt(label, fun([Lbl]) -> Lbl end, Args), + Vts = get_start_opt(vts, true, Args), + Shell = get_start_opt(shell, true, Args), + Cover = get_start_opt(cover, fun([CoverFile]) -> ?abs(CoverFile) end, Args), + LogDir = get_start_opt(logdir, fun([LogD]) -> LogD end, Args), + MultTT = get_start_opt(multiply_timetraps, + fun([MT]) -> list_to_integer(MT) end, 1, Args), + ScaleTT = get_start_opt(scale_timetraps, + fun([CT]) -> list_to_atom(CT); + ([]) -> true + end, false, Args), + EvHandlers = event_handler_args2opts(Args), + + %% check flags and set corresponding application env variables + + %% ct_decrypt_key | ct_decrypt_file + case proplists:get_value(ct_decrypt_key, Args) of + [DecryptKey] -> application:set_env(common_test, decrypt, {key,DecryptKey}); - false -> - case lists:keysearch(ct_decrypt_file, 1, Args) of - {value,{_,[DecryptFile]}} -> - application:set_env(common_test, decrypt, - {file,filename:absname(DecryptFile)}); - false -> + undefined -> + case proplists:get_value(ct_decrypt_file, Args) of + [DecryptFile] -> + application:set_env(common_test, decrypt, + {file,?abs(DecryptFile)}); + undefined -> application:unset_env(common_test, decrypt) end end, - - case lists:keysearch(no_auto_compile, 1, Args) of - {value,_} -> - application:set_env(common_test, auto_compile, false); - false -> - application:set_env(common_test, auto_compile, true), - - InclDirs = - case lists:keysearch(include,1,Args) of - {value,{include,Incl}} when is_list(hd(Incl)) -> - Incl; - {value,{include,Incl}} when is_list(Incl) -> - [Incl]; + %% no_auto_compile + include + IncludeDirs = + case proplists:get_value(no_auto_compile, Args) of + undefined -> + application:set_env(common_test, auto_compile, true), + InclDirs = + case proplists:get_value(include, Args) of + Incl when is_list(hd(Incl)) -> + Incl; + Incl when is_list(Incl) -> + [Incl]; + undefined -> + [] + end, + case os:getenv("CT_INCLUDE_PATH") of false -> - [] - end, - case os:getenv("CT_INCLUDE_PATH") of - false -> - application:set_env(common_test, include, InclDirs); - CtInclPath -> - InclDirs1 = string:tokens(CtInclPath,[$:,$ ,$,]), - application:set_env(common_test, include, InclDirs1++InclDirs) - end - end, - - case lists:keysearch(basic_html, 1, Args) of - {value,_} -> - application:set_env(common_test, basic_html, true); - false -> - application:set_env(common_test, basic_html, false) - end, - - Result = - case lists:keysearch(refresh_logs, 1, Args) of - {value,{refresh_logs,Refresh}} -> - LogDir1 = case Refresh of - [] -> LogDir; - [RefreshDir] -> ?abs(RefreshDir) - end, - {ok,Cwd} = file:get_cwd(), - file:set_cwd(LogDir1), - timer:sleep(500), % give the shell time to print version etc - io:nl(), - case catch ct_logs:make_all_suites_index(refresh) of - {'EXIT',ASReason} -> - file:set_cwd(Cwd), - {error,{all_suites_index,ASReason}}; - _ -> - case catch ct_logs:make_all_runs_index(refresh) of - {'EXIT',ARReason} -> - file:set_cwd(Cwd), - {error,{all_runs_index,ARReason}}; - _ -> - file:set_cwd(Cwd), - io:format("Logs in ~s refreshed!~n~n", [LogDir1]), - timer:sleep(500), % time to flush io before quitting - ok - end + application:set_env(common_test, include, InclDirs), + InclDirs; + CtInclPath -> + AllInclDirs = + string:tokens(CtInclPath,[$:,$ ,$,]) ++ InclDirs, + application:set_env(common_test, include, AllInclDirs), + AllInclDirs end; - false -> - case lists:keysearch(ct_config, 1, Args) of - {value,{ct_config,ConfigFiles}} -> - case lists:keysearch(spec, 1, Args) of - false -> - case get_configfiles(ConfigFiles, [], LogDir, - EvHandlers) of - ok -> - script_start2(VtsOrShell, ConfigFiles, - EvHandlers, Args, LogDir, - Cover); - Error -> - Error - end; - _ -> - script_start2(VtsOrShell, ConfigFiles, - EvHandlers, Args, LogDir, Cover) - end; - false -> - case install([{config,[]}, - {event_handler,EvHandlers}], - LogDir) of - ok -> - script_start2(VtsOrShell, [], EvHandlers, - Args, LogDir, Cover); - Error -> - Error - end - end + _ -> + application:set_env(common_test, auto_compile, false), + [] end, + %% silent connections + SilentConns = + get_start_opt(silent_connections, + fun(["all"]) -> []; + (Conns) -> [list_to_atom(Conn) || Conn <- Conns] + end, Args), + %% stylesheet + Stylesheet = get_start_opt(stylesheet, + fun([SS]) -> ?abs(SS) end, Args), + %% basic_html - used by ct_logs + case proplists:get_value(basic_html, Args) of + undefined -> + application:set_env(common_test, basic_html, false); + _ -> + application:set_env(common_test, basic_html, true) + end, + + StartOpts = #opts{label = Label, vts = Vts, shell = Shell, cover = Cover, + logdir = LogDir, event_handlers = EvHandlers, + include = IncludeDirs, + silent_connections = SilentConns, + stylesheet = Stylesheet, + multiply_timetraps = MultTT, + scale_timetraps = ScaleTT}, + + %% check if log files should be refreshed or go on to run tests... + Result = run_or_refresh(StartOpts, Args), + %% send final results to starting process waiting in script_start/0 Parent ! {self(), Result}. -get_configfiles([File|Files], Acc, LogDir, EvHandlers) -> - case filelib:is_file(File) of - true -> - get_configfiles(Files, [?abs(File)|Acc], - LogDir, EvHandlers); - false -> - {error,{cant_read_config_file,File}} - end; -get_configfiles([], Acc, LogDir, EvHandlers) -> - install([{config,lists:reverse(Acc)}, {event_handler,EvHandlers}], LogDir). +run_or_refresh(StartOpts = #opts{logdir = LogDir}, Args) -> + case proplists:get_value(refresh_logs, Args) of + undefined -> + script_start2(StartOpts, Args); + Refresh -> + LogDir1 = case Refresh of + [] -> which(logdir,LogDir); + [RefreshDir] -> ?abs(RefreshDir) + end, + {ok,Cwd} = file:get_cwd(), + file:set_cwd(LogDir1), + %% give the shell time to print version etc + timer:sleep(500), + io:nl(), + case catch ct_logs:make_all_suites_index(refresh) of + {'EXIT',ASReason} -> + file:set_cwd(Cwd), + {error,{all_suites_index,ASReason}}; + _ -> + case catch ct_logs:make_all_runs_index(refresh) of + {'EXIT',ARReason} -> + file:set_cwd(Cwd), + {error,{all_runs_index,ARReason}}; + _ -> + file:set_cwd(Cwd), + io:format("Logs in ~s refreshed!~n~n", [LogDir1]), + timer:sleep(500), % time to flush io before quitting + ok + end + end + end. -script_start2(false, ConfigFiles, EvHandlers, Args, LogDir, Cover) -> - case lists:keysearch(spec, 1, Args) of - {value,{spec,[]}} -> +script_start2(StartOpts = #opts{vts = undefined, + shell = undefined}, Args) -> + TestSpec = proplists:get_value(spec, Args), + {Terms,Opts} = + case TestSpec of + Specs when Specs =/= [], Specs =/= undefined -> + %% using testspec as input for test + Relaxed = get_start_opt(allow_user_terms, true, false, Args), + case catch ct_testspec:collect_tests_from_file(Specs, Relaxed) of + {E,Reason} when E == error ; E == 'EXIT' -> + {{error,Reason},StartOpts}; + TS -> + SpecStartOpts = get_data_for_node(TS, node()), + + Label = choose_val(StartOpts#opts.label, + SpecStartOpts#opts.label), + + LogDir = choose_val(StartOpts#opts.logdir, + SpecStartOpts#opts.logdir), + + Cover = choose_val(StartOpts#opts.cover, + SpecStartOpts#opts.cover), + MultTT = choose_val(StartOpts#opts.multiply_timetraps, + SpecStartOpts#opts.multiply_timetraps), + ScaleTT = choose_val(StartOpts#opts.scale_timetraps, + SpecStartOpts#opts.scale_timetraps), + AllEvHs = merge_vals([StartOpts#opts.event_handlers, + SpecStartOpts#opts.event_handlers]), + AllInclude = merge_vals([StartOpts#opts.include, + SpecStartOpts#opts.include]), + application:set_env(common_test, include, AllInclude), + + {TS,StartOpts#opts{label = Label, + testspecs = Specs, + cover = Cover, + logdir = LogDir, + config = SpecStartOpts#opts.config, + event_handlers = AllEvHs, + include = AllInclude, + multiply_timetraps = MultTT, + scale_timetraps = ScaleTT}} + end; + _ -> + {undefined,StartOpts} + end, + %% read config/userconfig from start flags + InitConfig = ct_config:prepare_config_list(Args), + TheLogDir = which(logdir, Opts#opts.logdir), + case {TestSpec,Terms} of + {_,{error,_}=Error} -> + Error; + {[],_} -> {error,no_testspec_specified}; - {value,{spec,Specs}} -> - Relaxed = lists:keymember(allow_user_terms, 1, Args), - %% using testspec as input for test - case catch ct_testspec:collect_tests_from_file(Specs, Relaxed) of - {error,Reason} -> - {error,Reason}; - TS -> - {LogDir1,TSCoverFile,ConfigFiles1,EvHandlers1,Include1} = - get_data_for_node(TS,node()), - UserInclude = - case application:get_env(common_test, include) of - {ok,Include} -> Include++Include1; - _ -> Include1 - end, - application:set_env(common_test, include, UserInclude), - LogDir2 = which_logdir(LogDir,LogDir1), - CoverOpt = case {Cover,TSCoverFile} of - {false,undef} -> []; - {_,undef} -> [Cover]; - {false,_} -> [{cover,TSCoverFile}] - end, - case get_configfiles(ConfigFiles++ConfigFiles1, - [], LogDir2, - EvHandlers++EvHandlers1) of - ok -> - {Run,Skip} = ct_testspec:prepare_tests(TS, node()), - do_run(Run, Skip, CoverOpt, Args, LogDir2); - Error -> - Error - end + {undefined,_} -> % no testspec used + case check_and_install_configfiles(InitConfig, TheLogDir, + Opts#opts.event_handlers) of + ok -> % go on read tests from start flags + script_start3(Opts#opts{config=InitConfig, + logdir=TheLogDir}, Args); + Error -> + Error end; - false -> - script_start3(false, ConfigFiles, EvHandlers, Args, LogDir, Cover) + {_,_} -> % testspec used + %% merge config from start flags with config from testspec + AllConfig = merge_vals([InitConfig, Opts#opts.config]), + case check_and_install_configfiles(AllConfig, TheLogDir, + Opts#opts.event_handlers) of + ok -> % read tests from spec + {Run,Skip} = ct_testspec:prepare_tests(Terms, node()), + do_run(Run, Skip, Opts#opts{config=AllConfig, + logdir=TheLogDir}, Args); + Error -> + Error + end end; -script_start2(VtsOrShell, ConfigFiles, EvHandlers, Args, LogDir, Cover) -> - script_start3(VtsOrShell, ConfigFiles, EvHandlers, Args, LogDir, Cover). -script_start3(VtsOrShell, ConfigFiles, EvHandlers, Args, LogDir, Cover) -> - case lists:keysearch(dir, 1, Args) of - {value,{dir,[]}} -> - {error,no_dir_specified}; - {value,{dir,Dirs}} -> - script_start4(VtsOrShell, ConfigFiles, EvHandlers, tests(Dirs), - Cover, Args, LogDir); +script_start2(StartOpts, Args) -> + %% read config/userconfig from start flags + InitConfig = ct_config:prepare_config_list(Args), + LogDir = which(logdir, StartOpts#opts.logdir), + case check_and_install_configfiles(InitConfig, LogDir, + StartOpts#opts.event_handlers) of + ok -> % go on read tests from start flags + script_start3(StartOpts#opts{config=InitConfig, + logdir=LogDir}, Args); + Error -> + Error + end. + +check_and_install_configfiles(Configs, LogDir, EvHandlers) -> + case ct_config:check_config_files(Configs) of false -> - case lists:keysearch(suite, 1, Args) of - {value,{suite,[]}} -> + install([{config,Configs}, + {event_handler,EvHandlers}], LogDir); + {value,{error,{nofile,File}}} -> + {error,{cant_read_config_file,File}}; + {value,{error,{wrong_config,Message}}}-> + {error,{wrong_config,Message}}; + {value,{error,{callback,Info}}} -> + {error,{cant_load_callback_module,Info}} + end. + +script_start3(StartOpts, Args) -> + case proplists:get_value(dir, Args) of + [] -> + {error,no_dir_specified}; + Dirs when is_list(Dirs) -> + script_start4(StartOpts#opts{tests = tests(Dirs)}, Args); + undefined -> + case proplists:get_value(suite, Args) of + [] -> {error,no_suite_specified}; - {value,{suite,Suites}} -> - StepOrCover = - case lists:keysearch(step, 1, Args) of - {value,Step} -> Step; - false -> Cover - end, - S2M = fun(S) -> - {filename:dirname(S), - list_to_atom( - filename:rootname(filename:basename(S)))} - end, - DirMods = lists:map(S2M, Suites), - {Specified,GroupsAndCases} = - case {lists:keysearch(group, 1, Args), - lists:keysearch('case', 1, Args)} of - {{value,{_,Gs}},{value,{_,Cs}}} -> {true,Gs++Cs}; - {{value,{_,Gs}},_} -> {true,Gs}; - {_,{value,{_,Cs}}} -> {true,Cs}; - _ -> {false,[]} - end, - if Specified, length(GroupsAndCases) == 0 -> - {error,no_case_or_group_specified}; - Specified, length(DirMods) > 1 -> + Suites when is_list(Suites) -> + StartOpts1 = + get_start_opt(step, + fun(Step) -> + StartOpts#opts{step = Step, + cover = undefined} + end, StartOpts, Args), + DirMods = [suite_to_test(S) || S <- Suites], + case groups_and_cases(proplists:get_value(group, Args), + proplists:get_value(testcase, Args)) of + Error = {error,_} -> + Error; + [] when DirMods =/= [] -> + Ts = tests(DirMods), + script_start4(StartOpts1#opts{tests = Ts}, Args); + GroupsAndCases when length(DirMods) == 1 -> + Ts = tests(DirMods, GroupsAndCases), + script_start4(StartOpts1#opts{tests = Ts}, Args); + [_,_|_] when length(DirMods) > 1 -> {error,multiple_suites_and_cases}; - length(GroupsAndCases) > 0, length(DirMods) == 1 -> - GsAndCs = lists:map(fun(C) -> list_to_atom(C) end, - GroupsAndCases), - script_start4(VtsOrShell, ConfigFiles, EvHandlers, - tests(DirMods, GsAndCs), - StepOrCover, Args, LogDir); - not Specified, length(DirMods) > 0 -> - script_start4(VtsOrShell, ConfigFiles, EvHandlers, - tests(DirMods), - StepOrCover, Args, LogDir); - true -> - {error,incorrect_suite_and_case_options} + _ -> + {error,incorrect_suite_option} end; - false when VtsOrShell=/=false -> - script_start4(VtsOrShell, ConfigFiles, EvHandlers, - [], Cover, Args, LogDir); - false -> - script_usage(), - {error,incorrect_usage} + undefined -> + if StartOpts#opts.vts ; StartOpts#opts.shell -> + script_start4(StartOpts#opts{tests = []}, Args); + true -> + script_usage(), + {error,incorrect_usage} + end end end. -script_start4(vts, ConfigFiles, EvHandlers, Tests, false, _Args, LogDir) -> +script_start4(#opts{vts = true, config = Config, event_handlers = EvHandlers, + tests = Tests, logdir = LogDir}, _Args) -> + ConfigFiles = + lists:foldl(fun({ct_config_plain,CfgFiles}, AllFiles) when + is_list(hd(CfgFiles)) -> + AllFiles ++ CfgFiles; + ({ct_config_plain,CfgFile}, AllFiles) when + is_integer(hd(CfgFile)) -> + AllFiles ++ [CfgFile]; + (_, AllFiles) -> + AllFiles + end, [], Config), vts:init_data(ConfigFiles, EvHandlers, ?abs(LogDir), Tests); -script_start4(shell, ConfigFiles, EvHandlers, _Tests, false, Args, LogDir) -> - Opts = [{config,ConfigFiles},{event_handler,EvHandlers}], - if ConfigFiles == [] -> + +script_start4(#opts{label = Label, shell = true, config = Config, + event_handlers = EvHandlers, + logdir = LogDir, testspecs = Specs}, _Args) -> + %% label - used by ct_logs + application:set_env(common_test, test_label, Label), + + InstallOpts = [{config,Config},{event_handler,EvHandlers}], + if Config == [] -> ok; true -> - io:format("\nInstalling: ~p\n\n", [ConfigFiles]) + io:format("\nInstalling: ~p\n\n", [Config]) end, - case install(Opts) of + case install(InstallOpts) of ok -> ct_util:start(interactive, LogDir), - log_ts_names(Args), + log_ts_names(Specs), io:nl(), ok; Error -> Error end; -script_start4(vts, _CfgFs, _EvHs, _Tests, _Cover={cover,_}, _Args, _LogDir) -> - %% Add support later (maybe). - script_usage(), - erlang:halt(); -script_start4(shell, _CfgFs, _EvHs, _Tests, _Cover={cover,_}, _Args, _LogDir) -> - %% Add support later (maybe). - script_usage(); -script_start4(false, _CfgFs, _EvHs, Tests, Cover={cover,_}, Args, LogDir) -> - do_run(Tests, [], [Cover], Args, LogDir); -script_start4(false, _ConfigFiles, _EvHandlers, Tests, false, Args, LogDir) -> - do_run(Tests, [], [], Args, LogDir); -script_start4(false, _ConfigFiles, _EvHandlers, Test, Step, Args, LogDir) -> - do_run(Test, [], [Step], Args, LogDir); -script_start4(vts, _ConfigFiles, _EvHandlers, _Test, _Step, _Args, _LogDir) -> - script_usage(), + +script_start4(#opts{vts = true, cover = Cover}, _) -> + case Cover of + undefined -> + script_usage(); + _ -> + %% Add support later (maybe). + io:format("\nCan't run cover in vts mode.\n\n", []) + end, erlang:halt(); -script_start4(shell, _ConfigFiles, _EvHandlers, _Test, _Step, _Args, _LogDir) -> - script_usage(). + +script_start4(#opts{shell = true, cover = Cover}, _) -> + case Cover of + undefined -> + script_usage(); + _ -> + %% Add support later (maybe). + io:format("\nCan't run cover in interactive mode.\n\n", []) + end; + +script_start4(Opts = #opts{tests = Tests}, Args) -> + do_run(Tests, [], Opts, Args). %%%----------------------------------------------------------------- %%% @spec script_usage() -> ok -%%% @doc Print script usage information for <code>run_test</code>. +%%% @doc Print usage information for <code>run_test</code>. script_usage() -> io:format("\n\nUsage:\n\n"), io:format("Run tests in web based GUI:\n\n" @@ -396,24 +491,29 @@ script_usage() -> "\n\t[-decrypt_key Key] | [-decrypt_file KeyFile]" "\n\t[-dir TestDir1 TestDir2 .. TestDirN] |" "\n\t[-suite Suite [-case Case]]" - "\n\t[-include InclDir1 InclDir2 .. InclDirN]" + "\n\t[-include InclDir1 InclDir2 .. InclDirN]" "\n\t[-no_auto_compile]" + "\n\t[-multiply_timetraps N]" + "\n\t[-scale_timetraps]" "\n\t[-basic_html]\n\n"), io:format("Run tests from command line:\n\n" "\trun_test [-dir TestDir1 TestDir2 .. TestDirN] |" "\n\t[-suite Suite1 Suite2 .. SuiteN [-case Case1 Case2 .. CaseN]]" "\n\t[-step [config | keep_inactive]]" "\n\t[-config ConfigFile1 ConfigFile2 .. ConfigFileN]" + "\n\t[-userconfig CallbackModule ConfigFile1 .. ConfigFileN]" "\n\t[-decrypt_key Key] | [-decrypt_file KeyFile]" "\n\t[-logdir LogDir]" "\n\t[-silent_connections [ConnType1 ConnType2 .. ConnTypeN]]" "\n\t[-stylesheet CSSFile]" "\n\t[-cover CoverCfgFile]" "\n\t[-event_handler EvHandler1 EvHandler2 .. EvHandlerN]" - "\n\t[-include InclDir1 InclDir2 .. InclDirN]" + "\n\t[-include InclDir1 InclDir2 .. InclDirN]" "\n\t[-no_auto_compile]" - "\n\t[-basic_html]" - "\n\t[-repeat N [-force_stop]] |" + "\n\t[-multiply_timetraps N]" + "\n\t[-scale_timetraps]" + "\n\t[-basic_html]" + "\n\t[-repeat N [-force_stop]] |" "\n\t[-duration HHMMSS [-force_stop]] |" "\n\t[-until [YYMoMoDD]HHMMSS [-force_stop]]\n\n"), io:format("Run tests using test specification:\n\n" @@ -426,10 +526,12 @@ script_usage() -> "\n\t[-stylesheet CSSFile]" "\n\t[-cover CoverCfgFile]" "\n\t[-event_handler EvHandler1 EvHandler2 .. EvHandlerN]" - "\n\t[-include InclDir1 InclDir2 .. InclDirN]" + "\n\t[-include InclDir1 InclDir2 .. InclDirN]" "\n\t[-no_auto_compile]" - "\n\t[-basic_html]" - "\n\t[-repeat N [-force_stop]] |" + "\n\t[-multiply_timetraps N]" + "\n\t[-scale_timetraps]" + "\n\t[-basic_html]" + "\n\t[-repeat N [-force_stop]] |" "\n\t[-duration HHMMSS [-force_stop]] |" "\n\t[-until [YYMoMoDD]HHMMSS [-force_stop]]\n\n"), io:format("Refresh the HTML index files:\n\n" @@ -440,7 +542,6 @@ script_usage() -> "\trun_test -shell" "\n\t[-config ConfigFile1 ConfigFile2 .. ConfigFileN]" "\n\t[-decrypt_key Key] | [-decrypt_file KeyFile]\n\n"). - %%%----------------------------------------------------------------- %%% @hidden @@ -449,6 +550,9 @@ install(Opts) -> install(Opts, "."). install(Opts, LogDir) -> + + ConfOpts = ct_config:add_default_callback(Opts), + case application:get_env(common_test, decrypt) of {ok,_} -> ok; @@ -465,10 +569,10 @@ install(Opts, LogDir) -> VarFile = variables_file_name(LogDir), case file:open(VarFile, [write]) of {ok,Fd} -> - [io:format(Fd, "~p.\n", [Opt]) || Opt <- Opts], + [io:format(Fd, "~p.\n", [Opt]) || Opt <- ConfOpts ], file:close(Fd), ok; - {error,Reason} -> + {error,Reason} -> io:format("CT failed to install configuration data. Please " "verify that the log directory exists and that " "write permission is set.\n\n", []), @@ -487,69 +591,62 @@ variables_file_name(Dir) -> filename:join(Dir, "variables-"++atom_to_list(node())). %%%----------------------------------------------------------------- -%%% @hidden +%%% @spec run_test(Opts) -> Result +%%% Opts = [tuple()] +%%% Result = [TestResult] | {error,Reason} +%%% +%%% @doc Start tests from the erlang shell or from an erlang program. %%% @equiv ct:run_test/1 +%%%----------------------------------------------------------------- -%% Opts = [OptTuples] -%% OptTuples = {config,CfgFiles} | {dir,TestDirs} | {suite,Suites} | -%% {testcase,Cases} | {spec,TestSpecs} | {allow_user_terms,Bool} | -%% {logdir,LogDir} | {cover,CoverSpecFile} | {step,StepOpts} | -%% {silent_connections,Conns} | {event_handler,EventHandlers} | -%% {include,InclDirs} | {auto_compile,Bool} | -%% {repeat,N} | {duration,DurTime} | {until,StopTime} | {force_stop,Bool} | -%% {decrypt,KeyOrFile} - -run_test(Opt) when is_tuple(Opt) -> - run_test([Opt]); - -run_test(Opts) when is_list(Opts) -> - case lists:keysearch(refresh_logs, 1, Opts) of - {value,{_,RefreshDir}} -> - refresh_logs(?abs(RefreshDir)), - ok; - false -> - Tracing = start_trace(Opts), +run_test(StartOpt) when is_tuple(StartOpt) -> + run_test([StartOpt]); + +run_test(StartOpts) when is_list(StartOpts) -> + case proplists:get_value(refresh_logs, StartOpts) of + undefined -> + Tracing = start_trace(StartOpts), {ok,Cwd} = file:get_cwd(), - io:format("~nCommon Test starting (cwd is ~s)~n~n", [Cwd]), + io:format("~nCommon Test starting (cwd is ~s)~n~n", [Cwd]), Res = - case ct_repeat:loop_test(func, Opts) of + case ct_repeat:loop_test(func, StartOpts) of false -> - case catch run_test1(Opts) of - {'EXIT',Reason} -> + case catch run_test1(StartOpts) of + {'EXIT',Reason} -> file:set_cwd(Cwd), {error,Reason}; - Result -> + Result -> Result end; Result -> Result end, stop_trace(Tracing), - Res + Res; + RefreshDir -> + refresh_logs(?abs(RefreshDir)), + ok end. -run_test1(Opts) -> - LogDir = - case lists:keysearch(logdir, 1, Opts) of - {value,{_,LD}} when is_list(LD) -> LD; - false -> "." - end, - CfgFiles = - case lists:keysearch(config, 1, Opts) of - {value,{_,Files=[File|_]}} when is_list(File) -> - Files; - {value,{_,File=[C|_]}} when is_integer(C) -> - [File]; - {value,{_,[]}} -> - []; - false -> - [] - end, +run_test1(StartOpts) -> + %% label + Label = get_start_opt(label, fun(Lbl) when is_list(Lbl) -> Lbl; + (Lbl) when is_atom(Lbl) -> atom_to_list(Lbl) + end, StartOpts), + %% logdir + LogDir = get_start_opt(logdir, fun(LD) when is_list(LD) -> LD end, + StartOpts), + %% config & userconfig + CfgFiles = ct_config:get_config_file_list(StartOpts), + + %% event handlers EvHandlers = - case lists:keysearch(event_handler, 1, Opts) of - {value,{_,H}} when is_atom(H) -> + case proplists:get_value(event_handler, StartOpts) of + undefined -> + []; + H when is_atom(H) -> [{H,[]}]; - {value,{_,H}} -> + H -> Hs = if is_tuple(H) -> [H]; is_list(H) -> H; @@ -564,41 +661,39 @@ run_test1(Opts) -> {EH,Args}; (_) -> [] - end, Hs)); - _ -> - [] - end, - SilentConns = - case lists:keysearch(silent_connections, 1, Opts) of - {value,{_,all}} -> - []; - {value,{_,Conns}} -> - Conns; - _ -> - undefined - end, - Cover = - case lists:keysearch(cover, 1, Opts) of - {value,{_,CoverFile}} -> - [{cover,?abs(CoverFile)}]; - _ -> - [] + end, Hs)) end, + + %% silent connections + SilentConns = get_start_opt(silent_connections, + fun(all) -> []; + (Conns) -> Conns + end, StartOpts), + %% stylesheet + Stylesheet = get_start_opt(stylesheet, + fun(SS) -> ?abs(SS) end, + StartOpts), + %% code coverage + Cover = get_start_opt(cover, + fun(CoverFile) -> ?abs(CoverFile) end, StartOpts), + + %% timetrap manipulation + MultiplyTT = get_start_opt(multiply_timetraps, value, 1, StartOpts), + ScaleTT = get_start_opt(scale_timetraps, value, false, StartOpts), + + %% auto compile & include files Include = - case lists:keysearch(auto_compile, 1, Opts) of - {value,{auto_compile,ACBool}} -> - application:set_env(common_test, auto_compile, ACBool), - []; - _ -> + case proplists:get_value(auto_compile, StartOpts) of + undefined -> application:set_env(common_test, auto_compile, true), InclDirs = - case lists:keysearch(include, 1, Opts) of - {value,{include,Incl}} when is_list(hd(Incl)) -> - Incl; - {value,{include,Incl}} when is_list(Incl) -> - [Incl]; - false -> - [] + case proplists:get_value(include, StartOpts) of + undefined -> + []; + Incl when is_list(hd(Incl)) -> + Incl; + Incl when is_list(Incl) -> + [Incl] end, case os:getenv("CT_INCLUDE_PATH") of false -> @@ -609,117 +704,174 @@ run_test1(Opts) -> AllInclDirs = InclDirs1++InclDirs, application:set_env(common_test, include, AllInclDirs), AllInclDirs - end + end; + ACBool -> + application:set_env(common_test, auto_compile, ACBool), + [] end, - case lists:keysearch(decrypt, 1, Opts) of - {value,{_,Key={key,_}}} -> + %% decrypt config file + case proplists:get_value(decrypt, StartOpts) of + undefined -> + application:unset_env(common_test, decrypt); + Key={key,_} -> application:set_env(common_test, decrypt, Key); - {value,{_,{file,KeyFile}}} -> - application:set_env(common_test, decrypt, {file,filename:absname(KeyFile)}); - false -> - application:unset_env(common_test, decrypt) + {file,KeyFile} -> + application:set_env(common_test, decrypt, {file,?abs(KeyFile)}) end, - case lists:keysearch(basic_html, 1, Opts) of - {value,{basic_html,BasicHtmlBool}} -> - application:set_env(common_test, basic_html, BasicHtmlBool); - _ -> - application:set_env(common_test, basic_html, false) + %% basic html - used by ct_logs + case proplists:get_value(basic_html, StartOpts) of + undefined -> + application:set_env(common_test, basic_html, false); + BasicHtmlBool -> + application:set_env(common_test, basic_html, BasicHtmlBool) end, - case lists:keysearch(spec, 1, Opts) of - {value,{_,Specs}} -> - Relaxed = - case lists:keysearch(allow_user_terms, 1, Opts) of - {value,{_,true}} -> true; - _ -> false - end, - %% using testspec(s) as input for test - run_spec_file(LogDir, CfgFiles, EvHandlers, Include, Specs, Relaxed, Cover, - replace_opt([{silent_connections,SilentConns}], Opts)); - false -> - case lists:keysearch(prepared_tests, 1, Opts) of + %% stepped execution + Step = get_start_opt(step, value, StartOpts), + + Opts = #opts{label = Label, + cover = Cover, step = Step, logdir = LogDir, config = CfgFiles, + event_handlers = EvHandlers, include = Include, + silent_connections = SilentConns, + stylesheet = Stylesheet, + multiply_timetraps = MultiplyTT, + scale_timetraps = ScaleTT}, + + %% test specification + case proplists:get_value(spec, StartOpts) of + undefined -> + case lists:keysearch(prepared_tests, 1, StartOpts) of {value,{_,{Run,Skip},Specs}} -> % use prepared tests - run_prepared(LogDir, CfgFiles, EvHandlers, - Run, Skip, Cover, - replace_opt([{silent_connections,SilentConns}, - {spec,Specs}],Opts)); - false -> % use dir|suite|case - StepOrCover = - case lists:keysearch(step, 1, Opts) of - {value,Step} -> [Step]; - false -> Cover - end, - run_dir(LogDir, CfgFiles, EvHandlers, StepOrCover, - replace_opt([{silent_connections,SilentConns}], Opts)) - end + run_prepared(Run, Skip, Opts#opts{testspecs = Specs}, + StartOpts); + false -> + run_dir(Opts, StartOpts) + end; + Specs -> + Relaxed = get_start_opt(allow_user_terms, value, false, StartOpts), + %% using testspec(s) as input for test + run_spec_file(Relaxed, Opts#opts{testspecs = Specs}, StartOpts) end. -replace_opt([O={Key,_Val}|Os], Opts) -> - [O | replace_opt(Os, lists:keydelete(Key, 1, Opts))]; -replace_opt([], Opts) -> - Opts. - -run_spec_file(LogDir, CfgFiles, EvHandlers, Include, Specs, Relaxed, Cover, Opts) -> +run_spec_file(Relaxed, + Opts = #opts{testspecs = Specs, config = CfgFiles}, + StartOpts) -> Specs1 = case Specs of [X|_] when is_integer(X) -> [Specs]; _ -> Specs end, - AbsSpecs = lists:map(fun(SF) -> ?abs(SF) end, Specs1), + AbsSpecs = lists:map(fun(SF) -> ?abs(SF) end, Specs1), log_ts_names(AbsSpecs), case catch ct_testspec:collect_tests_from_file(AbsSpecs, Relaxed) of - {error,CTReason} -> + {Error,CTReason} when Error == error ; Error == 'EXIT' -> exit(CTReason); TS -> - {LogDir1,TSCoverFile,CfgFiles1,EvHandlers1,Include1} = - get_data_for_node(TS, node()), - application:set_env(common_test, include, Include++Include1), - LogDir2 = which_logdir(LogDir, LogDir1), - CoverOpt = case {Cover,TSCoverFile} of - {[],undef} -> []; - {_,undef} -> Cover; - {[],_} -> [{cover,TSCoverFile}] - end, - case get_configfiles(CfgFiles++CfgFiles1, [], LogDir2, - EvHandlers++EvHandlers1) of + SpecOpts = get_data_for_node(TS, node()), + Label = choose_val(Opts#opts.label, + SpecOpts#opts.label), + LogDir = choose_val(Opts#opts.logdir, + SpecOpts#opts.logdir), + AllConfig = merge_vals([CfgFiles, SpecOpts#opts.config]), + Cover = choose_val(Opts#opts.cover, + SpecOpts#opts.cover), + MultTT = choose_val(Opts#opts.multiply_timetraps, + SpecOpts#opts.multiply_timetraps), + ScaleTT = choose_val(Opts#opts.scale_timetraps, + SpecOpts#opts.scale_timetraps), + AllEvHs = merge_vals([Opts#opts.event_handlers, + SpecOpts#opts.event_handlers]), + AllInclude = merge_vals([Opts#opts.include, + SpecOpts#opts.include]), + application:set_env(common_test, include, AllInclude), + + case check_and_install_configfiles(AllConfig, + which(logdir,LogDir), + AllEvHs) of ok -> + Opts1 = Opts#opts{label = Label, + cover = Cover, + logdir = which(logdir, LogDir), + config = AllConfig, + event_handlers = AllEvHs, + include = AllInclude, + testspecs = AbsSpecs, + multiply_timetraps = MultTT, + scale_timetraps = ScaleTT}, {Run,Skip} = ct_testspec:prepare_tests(TS, node()), - do_run(Run, Skip, CoverOpt, - replace_opt([{spec,AbsSpecs}], Opts), - LogDir2); + reformat_result(catch do_run(Run, Skip, Opts1, StartOpts)); {error,GCFReason} -> exit(GCFReason) end end. -run_prepared(LogDir, CfgFiles, EvHandlers, Run, Skip, Cover, Opts) -> - case get_configfiles(CfgFiles, [], LogDir, EvHandlers) of +run_prepared(Run, Skip, Opts = #opts{logdir = LogDir, + config = CfgFiles, + event_handlers = EvHandlers}, + StartOpts) -> + LogDir1 = which(logdir, LogDir), + case check_and_install_configfiles(CfgFiles, LogDir1, EvHandlers) of ok -> - do_run(Run, Skip, Cover, Opts, LogDir); + reformat_result(catch do_run(Run, Skip, Opts#opts{logdir = LogDir1}, + StartOpts)); {error,Reason} -> exit(Reason) - end. - -run_dir(LogDir, CfgFiles, EvHandlers, StepOrCover, Opts) -> - AbsCfgFiles = - lists:map(fun(F) -> - AbsName = ?abs(F), - case filelib:is_file(AbsName) of - true -> AbsName; - false -> exit({no_such_file,AbsName}) - end - end, CfgFiles), - - case install([{config,AbsCfgFiles},{event_handler,EvHandlers}], LogDir) of + end. + +check_config_file(Callback, File)-> + case code:is_loaded(Callback) of + false -> + case code:load_file(Callback) of + {module,_} -> ok; + {error,Why} -> exit({cant_load_callback_module,Why}) + end; + _ -> + ok + end, + case Callback:check_parameter(File) of + {ok,{file,File}}-> + ?abs(File); + {ok,{config,_}}-> + File; + {error,{wrong_config,Message}}-> + exit({wrong_config,{Callback,Message}}); + {error,{nofile,File}}-> + exit({no_such_file,?abs(File)}) + end. + +run_dir(Opts = #opts{logdir = LogDir, + config = CfgFiles, + event_handlers = EvHandlers}, StartOpts) -> + LogDir1 = which(logdir, LogDir), + Opts1 = Opts#opts{logdir = LogDir1}, + AbsCfgFiles = + lists:map(fun({Callback,FileList})-> + case code:is_loaded(Callback) of + {file,_Path}-> + ok; + false -> + case code:load_file(Callback) of + {module,Callback}-> + ok; + {error,_}-> + exit({no_such_module,Callback}) + end + end, + {Callback, + lists:map(fun(File)-> + check_config_file(Callback, File) + end, FileList)} + end, CfgFiles), + case install([{config,AbsCfgFiles},{event_handler,EvHandlers}], LogDir1) of ok -> ok; {error,IReason} -> exit(IReason) end, - case lists:keysearch(dir,1,Opts) of + case lists:keysearch(dir, 1, StartOpts) of {value,{_,Dirs=[Dir|_]}} when not is_integer(Dir), length(Dirs)>1 -> %% multiple dirs (no suite) - do_run(tests(Dirs), [], StepOrCover, Opts, LogDir); + reformat_result(catch do_run(tests(Dirs), [], Opts1, StartOpts)); false -> % no dir %% fun for converting suite name to {Dir,Mod} tuple S2M = fun(S) when is_list(S) -> @@ -728,105 +880,135 @@ run_dir(LogDir, CfgFiles, EvHandlers, StepOrCover, Opts) -> (A) -> {".",A} end, - case lists:keysearch(suite, 1, Opts) of + case lists:keysearch(suite, 1, StartOpts) of {value,{_,Suite}} when is_integer(hd(Suite)) ; is_atom(Suite) -> {Dir,Mod} = S2M(Suite), - case listify(proplists:get_value(group, Opts, [])) ++ - listify(proplists:get_value(testcase, Opts, [])) of + case groups_and_cases(proplists:get_value(group, StartOpts), + proplists:get_value(testcase, StartOpts)) of + Error = {error,_} -> + exit(Error); [] -> - do_run(tests(Dir, listify(Mod)), [], StepOrCover, Opts, LogDir); + reformat_result(catch do_run(tests(Dir, listify(Mod)), + [], Opts1, StartOpts)); GsAndCs -> - do_run(tests(Dir, Mod, GsAndCs), [], StepOrCover, Opts, LogDir) + reformat_result(catch do_run(tests(Dir, Mod, GsAndCs), + [], Opts1, StartOpts)) end; {value,{_,Suites}} -> - do_run(tests(lists:map(S2M, Suites)), [], StepOrCover, Opts, LogDir); + reformat_result(catch do_run(tests(lists:map(S2M, Suites)), + [], Opts1, StartOpts)); _ -> exit(no_tests_specified) - end; + end; {value,{_,Dir}} -> - case lists:keysearch(suite, 1, Opts) of + case lists:keysearch(suite, 1, StartOpts) of {value,{_,Suite}} when is_integer(hd(Suite)) ; is_atom(Suite) -> - Mod = if is_atom(Suite) -> Suite; - true -> list_to_atom(Suite) + Mod = if is_atom(Suite) -> Suite; + true -> list_to_atom(Suite) end, - case listify(proplists:get_value(group, Opts, [])) ++ - listify(proplists:get_value(testcase, Opts, [])) of + case groups_and_cases(proplists:get_value(group, StartOpts), + proplists:get_value(testcase, StartOpts)) of + Error = {error,_} -> + exit(Error); [] -> - do_run(tests(Dir, listify(Mod)), [], StepOrCover, Opts, LogDir); + reformat_result(catch do_run(tests(Dir, listify(Mod)), + [], Opts1, StartOpts)); GsAndCs -> - do_run(tests(Dir, Mod, GsAndCs), [], StepOrCover, Opts, LogDir) + reformat_result(catch do_run(tests(Dir, Mod, GsAndCs), + [], Opts1, StartOpts)) end; {value,{_,Suites=[Suite|_]}} when is_list(Suite) -> Mods = lists:map(fun(Str) -> list_to_atom(Str) end, Suites), - do_run(tests(delistify(Dir), Mods), [], StepOrCover, Opts, LogDir); + reformat_result(catch do_run(tests(delistify(Dir), Mods), + [], Opts1, StartOpts)); {value,{_,Suites}} -> - do_run(tests(delistify(Dir), Suites), [], StepOrCover, Opts, LogDir); + reformat_result(catch do_run(tests(delistify(Dir), Suites), + [], Opts1, StartOpts)); false -> % no suite, only dir - do_run(tests(listify(Dir)), [], StepOrCover, Opts, LogDir) - end + reformat_result(catch do_run(tests(listify(Dir)), + [], Opts1, StartOpts)) + end end. %%%----------------------------------------------------------------- -%%% @hidden +%%% @spec run_testspec(TestSpec) -> Result +%%% TestSpec = [term()] %%% +%%% @doc Run test specified by <code>TestSpec</code>. The terms are +%%% the same as those used in test specification files. +%%% @equiv ct:run_testspec/1 +%%%----------------------------------------------------------------- -%% using testspec(s) as input for test run_testspec(TestSpec) -> {ok,Cwd} = file:get_cwd(), io:format("~nCommon Test starting (cwd is ~s)~n~n", [Cwd]), case catch run_testspec1(TestSpec) of - {'EXIT',Reason} -> + {'EXIT',Reason} -> file:set_cwd(Cwd), {error,Reason}; - Result -> + Result -> Result end. run_testspec1(TestSpec) -> - case ct_testspec:collect_tests_from_list(TestSpec,false) of - {error,CTReason} -> + case catch ct_testspec:collect_tests_from_list(TestSpec, false) of + {E,CTReason} when E == error ; E == 'EXIT' -> exit(CTReason); TS -> - {LogDir,TSCoverFile,CfgFiles,EvHandlers,Include} = - get_data_for_node(TS,node()), - case os:getenv("CT_INCLUDE_PATH") of - false -> - application:set_env(common_test, include, Include); - CtInclPath -> - EnvInclude = string:tokens(CtInclPath, [$:,$ ,$,]), - application:set_env(common_test, include, EnvInclude++Include) - end, - CoverOpt = if TSCoverFile == undef -> []; - true -> [{cover,TSCoverFile}] - end, - case get_configfiles(CfgFiles,[],LogDir,EvHandlers) of + Opts = get_data_for_node(TS, node()), + + AllInclude = + case os:getenv("CT_INCLUDE_PATH") of + false -> + Opts#opts.include; + CtInclPath -> + EnvInclude = string:tokens(CtInclPath, [$:,$ ,$,]), + EnvInclude++Opts#opts.include + end, + application:set_env(common_test, include, AllInclude), + LogDir1 = which(logdir,Opts#opts.logdir), + case check_and_install_configfiles(Opts#opts.config, LogDir1, + Opts#opts.event_handlers) of ok -> - {Run,Skip} = ct_testspec:prepare_tests(TS,node()), - do_run(Run,Skip,CoverOpt,[],LogDir); + Opts1 = Opts#opts{testspecs = [], + logdir = LogDir1, + include = AllInclude}, + {Run,Skip} = ct_testspec:prepare_tests(TS, node()), + reformat_result(catch do_run(Run, Skip, Opts1, [])); {error,GCFReason} -> exit(GCFReason) end end. - -get_data_for_node(#testspec{logdir=LogDirs, - cover=CoverFs, - config=Cfgs, - event_handler=EvHs, - include=Incl}, Node) -> - LogDir = case lists:keysearch(Node,1,LogDirs) of - {value,{Node,Dir}} -> Dir; - false -> "." +get_data_for_node(#testspec{label = Labels, + logdir = LogDirs, + cover = CoverFs, + config = Cfgs, + userconfig = UsrCfgs, + event_handler = EvHs, + include = Incl, + multiply_timetraps = MTs, + scale_timetraps = STs}, Node) -> + Label = proplists:get_value(Node, Labels), + LogDir = case proplists:get_value(Node, LogDirs) of + undefined -> "."; + Dir -> Dir end, - Cover = case lists:keysearch(Node,1,CoverFs) of - {value,{Node,CovFile}} -> CovFile; - false -> undef - end, - ConfigFiles = [F || {N,F} <- Cfgs, N==Node], + Cover = proplists:get_value(Node, CoverFs), + MT = proplists:get_value(Node, MTs), + ST = proplists:get_value(Node, STs), + ConfigFiles = [{?ct_config_txt,F} || {N,F} <- Cfgs, N==Node] ++ + [CBF || {N,CBF} <- UsrCfgs, N==Node], EvHandlers = [{H,A} || {N,H,A} <- EvHs, N==Node], Include = [I || {N,I} <- Incl, N==Node], - {LogDir,Cover,ConfigFiles,EvHandlers,Include}. - + #opts{label = Label, + logdir = LogDir, + cover = Cover, + config = ConfigFiles, + event_handlers = EvHandlers, + include = Include, + multiply_timetraps = MT, + scale_timetraps = ST}. refresh_logs(LogDir) -> {ok,Cwd} = file:get_cwd(), @@ -851,11 +1033,27 @@ refresh_logs(LogDir) -> end end. -which_logdir(".",Dir) -> +which(logdir, undefined) -> + "."; +which(logdir, Dir) -> Dir; -which_logdir(Dir,_) -> - Dir. - +which(multiply_timetraps, undefined) -> + 1; +which(multiply_timetraps, MT) -> + MT; +which(scale_timetraps, undefined) -> + false; +which(scale_timetraps, ST) -> + ST. + +choose_val(undefined, V1) -> + V1; +choose_val(V0, _V1) -> + V0. + +merge_vals(Vs) -> + lists:append(Vs). + listify([C|_]=Str) when is_integer(C) -> [Str]; listify(L) when is_list(L) -> L; listify(E) -> [E]. @@ -869,22 +1067,45 @@ delistify(E) -> E. %%% @equiv ct:run/3 run(TestDir, Suite, Cases) -> install([]), - do_run(tests(TestDir, Suite, Cases), []). + reformat_result(catch do_run(tests(TestDir, Suite, Cases), [])). %%%----------------------------------------------------------------- %%% @hidden %%% @equiv ct:run/2 run(TestDir, Suite) when is_list(TestDir), is_integer(hd(TestDir)) -> install([]), - do_run(tests(TestDir, Suite), []). + reformat_result(catch do_run(tests(TestDir, Suite), [])). %%%----------------------------------------------------------------- %%% @hidden %%% @equiv ct:run/1 run(TestDirs) -> install([]), - do_run(tests(TestDirs), []). + reformat_result(catch do_run(tests(TestDirs), [])). + +reformat_result({user_error,Reason}) -> + {error,Reason}; +reformat_result(Result) -> + Result. +suite_to_test(Suite) -> + {filename:dirname(Suite),list_to_atom(filename:rootname(filename:basename(Suite)))}. + +groups_and_cases(Gs, Cs) when ((Gs == undefined) or (Gs == [])) and + ((Cs == undefined) or (Cs == [])) -> + []; +groups_and_cases(Gs, Cs) when Gs == undefined ; Gs == [] -> + [ensure_atom(C) || C <- listify(Cs)]; +groups_and_cases(Gs, Cs) when Cs == undefined ; Cs == [] -> + [{ensure_atom(G),all} || G <- listify(Gs)]; +groups_and_cases(G, Cs) when is_atom(G) -> + [{G,[ensure_atom(C) || C <- listify(Cs)]}]; +groups_and_cases([G], Cs) -> + [{ensure_atom(G),[ensure_atom(C) || C <- listify(Cs)]}]; +groups_and_cases([_,_|_] , Cs) when Cs =/= [] -> + {error,multiple_groups_and_cases}; +groups_and_cases(_Gs, _Cs) -> + {error,incorrect_group_or_case_option}. tests(TestDir, Suites, []) when is_list(TestDir), is_integer(hd(TestDir)) -> [{?testdir(TestDir,Suites),ensure_atom(Suites),all}]; @@ -901,30 +1122,52 @@ tests(TestDir) when is_list(TestDir), is_integer(hd(TestDir)) -> tests(TestDirs) when is_list(TestDirs), is_list(hd(TestDirs)) -> [{?testdir(TestDir,all),all,all} || TestDir <- TestDirs]. -do_run(Tests, Opt) -> - do_run(Tests, [], Opt, [], "."). +do_run(Tests, Misc) when is_list(Misc) -> + do_run(Tests, Misc, "."). + +do_run(Tests, Misc, LogDir) when is_list(Misc) -> + Opts = + case proplists:get_value(step, Misc) of + undefined -> + #opts{}; + StepOpts -> + #opts{step = StepOpts} + end, + Opts1 = + case proplists:get_value(cover, Misc) of + undefined -> + Opts; + CoverFile -> + Opts#opts{cover = CoverFile} + end, + do_run(Tests, [], Opts1#opts{logdir = LogDir}, []). + +do_run(Tests, Skip, Opts, Args) -> + #opts{label = Label, cover = Cover} = Opts, -do_run(Tests, Opt, LogDir) -> - do_run(Tests, [], Opt, [], LogDir). + %% label - used by ct_logs + TestLabel = + if Label == undefined -> undefined; + is_atom(Label) -> atom_to_list(Label); + is_list(Label) -> Label; + true -> undefined + end, + application:set_env(common_test, test_label, TestLabel), -do_run(Tests, Skip, Opt, Args, LogDir) -> case code:which(test_server) of non_existing -> exit({error,no_path_to_test_server}); _ -> - Opt1 = - case lists:keysearch(cover, 1, Opt) of - {value,{_,CoverFile}} -> - case ct_cover:get_spec(CoverFile) of - {error,Reason} -> - exit({error,Reason}); - Spec -> - [{cover_spec,Spec} | - lists:keydelete(cover, 1, Opt)] - end; - _ -> - Opt - end, + Opts1 = if Cover == undefined -> + Opts; + true -> + case ct_cover:get_spec(Cover) of + {error,Reason} -> + exit({error,Reason}); + CoverSpec -> + Opts#opts{coverspec = CoverSpec} + end + end, %% This env variable is used by test_server to determine %% which framework it runs under. case os:getenv("TEST_SERVER_FRAMEWORK") of @@ -935,60 +1178,58 @@ do_run(Tests, Skip, Opt, Args, LogDir) -> Other -> erlang:display(list_to_atom("Note: TEST_SERVER_FRAMEWORK = " ++ Other)) end, - case ct_util:start(LogDir) of + case ct_util:start(Opts#opts.logdir) of {error,interactive_mode} -> io:format("CT is started in interactive mode. " "To exit this mode, run ct:stop_interactive().\n" "To enter the interactive mode again, " "run ct:start_interactive()\n\n",[]), {error,interactive_mode}; - _Pid -> - %% save style sheet info - case lists:keysearch(stylesheet, 1, Args) of - {value,{_,SSFile}} -> - ct_util:set_testdata({stylesheet,SSFile}); - _ -> - ct_util:set_testdata({stylesheet,undefined}) - end, - - case lists:keysearch(silent_connections, 1, Args) of - {value,{silent_connections,undefined}} -> - ok; - {value,{silent_connections,[]}} -> + %% save stylesheet info + ct_util:set_testdata({stylesheet,Opts#opts.stylesheet}), + %% enable silent connections + case Opts#opts.silent_connections of + [] -> Conns = ct_util:override_silence_all_connections(), ct_logs:log("Silent connections", "~p", [Conns]); - {value,{silent_connections,Cs}} -> - Conns = lists:map(fun(S) when is_list(S) -> - list_to_atom(S); - (A) -> A - end, Cs), + Conns when is_list(Conns) -> ct_util:override_silence_connections(Conns), ct_logs:log("Silent connections", "~p", [Conns]); _ -> ok end, - log_ts_names(Args), + log_ts_names(Opts1#opts.testspecs), TestSuites = suite_tuples(Tests), - {SuiteMakeErrors,AllMakeErrors} = + {_TestSuites1,SuiteMakeErrors,AllMakeErrors} = case application:get_env(common_test, auto_compile) of {ok,false} -> - SuitesNotFound = verify_suites(TestSuites), - {SuitesNotFound,SuitesNotFound}; + {TestSuites1,SuitesNotFound} = + verify_suites(TestSuites), + {TestSuites1,SuitesNotFound,SuitesNotFound}; _ -> {SuiteErrs,HelpErrs} = auto_compile(TestSuites), - {SuiteErrs,SuiteErrs++HelpErrs} + {TestSuites,SuiteErrs,SuiteErrs++HelpErrs} end, case continue(AllMakeErrors) of true -> SavedErrors = save_make_errors(SuiteMakeErrors), ct_repeat:log_loop_info(Args), - {Tests1,Skip1} = final_tests(Tests,[],Skip,SavedErrors), - R = do_run_test(Tests1, Skip1, Opt1), - ct_util:stop(normal), - R; + + {Tests1,Skip1} = final_tests(Tests,Skip,SavedErrors), + + R = (catch do_run_test(Tests1, Skip1, Opts1)), + case R of + {EType,_} = Error when EType == user_error ; + EType == error -> + ct_util:stop(clean), + exit(Error); + _ -> + ct_util:stop(normal), + R + end; false -> io:nl(), ct_util:stop(clean), @@ -1012,7 +1253,7 @@ auto_compile(TestSuites) -> case application:get_env(common_test, include) of {ok,UserInclDirs} when length(UserInclDirs) > 0 -> io:format("Including the following directories:~n"), - [begin io:format("~p~n",[UserInclDir]), {i,UserInclDir} end || + [begin io:format("~p~n",[UserInclDir]), {i,UserInclDir} end || UserInclDir <- UserInclDirs]; _ -> [] @@ -1020,11 +1261,11 @@ auto_compile(TestSuites) -> SuiteMakeErrors = lists:flatmap(fun({TestDir,Suite} = TS) -> case run_make(suites, TestDir, Suite, UserInclude) of - {error,{make_failed,Bad}} -> + {error,{make_failed,Bad}} -> [{TS,Bad}]; - {error,_} -> + {error,_} -> [{TS,[filename:join(TestDir,"*_SUITE")]}]; - _ -> + _ -> [] end end, TestSuites), @@ -1048,39 +1289,63 @@ auto_compile(TestSuites) -> true -> % already visited {Done,Failed} end - end, {[],[]}, TestSuites), + end, {[],[]}, TestSuites), {SuiteMakeErrors,lists:reverse(HelpMakeErrors)}. %% verify that specified test suites exist (if auto compile is disabled) verify_suites(TestSuites) -> io:nl(), - Verify = - fun({Dir,Suite},NotFound) -> + Verify = + fun({Dir,Suite}=DS,{Found,NotFound}) -> case locate_test_dir(Dir, Suite) of {ok,TestDir} -> if Suite == all -> - NotFound; + {[DS|Found],NotFound}; true -> - Beam = filename:join(TestDir, atom_to_list(Suite)++".beam"), + Beam = filename:join(TestDir, + atom_to_list(Suite)++".beam"), case filelib:is_regular(Beam) of - true -> - NotFound; - false -> - Name = filename:join(TestDir, atom_to_list(Suite)), - io:format("Suite ~w not found in directory ~s~n", - [Suite,TestDir]), - [{{Dir,Suite},[Name]} | NotFound] + true -> + {[DS|Found],NotFound}; + false -> + case code:is_loaded(Suite) of + {file,SuiteFile} -> + %% test suite is already loaded and + %% since auto_compile == false, + %% let's assume the user has + %% loaded the beam file explicitly + ActualDir = filename:dirname(SuiteFile), + {[{ActualDir,Suite}|Found],NotFound}; + false -> + Name = + filename:join(TestDir, + atom_to_list(Suite)), + io:format(user, + "Suite ~w not found" + "in directory ~s~n", + [Suite,TestDir]), + {Found,[{DS,[Name]}|NotFound]} + end end end; {error,_Reason} -> - io:format("Directory ~s is invalid~n", [Dir]), - Name = filename:join(Dir, atom_to_list(Suite)), - [{{Dir,Suite},[Name]} | NotFound] + case code:is_loaded(Suite) of + {file,SuiteFile} -> + %% test suite is already loaded and since + %% auto_compile == false, let's assume the + %% user has loaded the beam file explicitly + ActualDir = filename:dirname(SuiteFile), + {[{ActualDir,Suite}|Found],NotFound}; + false -> + io:format(user, "Directory ~s is invalid~n", [Dir]), + Name = filename:join(Dir, atom_to_list(Suite)), + {Found,[{DS,[Name]}|NotFound]} + end end end, - lists:reverse(lists:foldl(Verify, [], TestSuites)). - - + {ActualFound,Missing} = lists:foldl(Verify, {[],[]}, TestSuites), + {lists:reverse(ActualFound),lists:reverse(Missing)}. + save_make_errors([]) -> []; save_make_errors(Errors) -> @@ -1096,7 +1361,7 @@ get_bad_suites([{{_TestDir,_Suite},Failed}|Errors], BadSuites) -> get_bad_suites([], BadSuites) -> BadSuites. - + %%%----------------------------------------------------------------- %%% @hidden @@ -1107,7 +1372,7 @@ step(TestDir, Suite, Case) -> %%%----------------------------------------------------------------- %%% @hidden %%% @equiv ct:step/4 -step(TestDir, Suite, Case, Opts) when is_list(TestDir), is_atom(Suite), is_atom(Case), +step(TestDir, Suite, Case, Opts) when is_list(TestDir), is_atom(Suite), is_atom(Case), Suite =/= all, Case =/= all -> do_run([{TestDir,Suite,Case}], [{step,Opts}]). @@ -1121,8 +1386,13 @@ suite_tuples([{TestDir,Suite,_} | Tests]) when is_atom(Suite) -> suite_tuples([]) -> []. -final_tests([{TestDir,Suites,_}|Tests], - Final, Skip, Bad) when is_list(Suites), is_atom(hd(Suites)) -> +final_tests(Tests, Skip, Bad) -> + {Tests1,Skip1} = final_tests1(Tests, [], Skip, Bad), + Skip2 = final_skip(Skip1, []), + {Tests1,Skip2}. + +final_tests1([{TestDir,Suites,_}|Tests], Final, Skip, Bad) when + is_list(Suites), is_atom(hd(Suites)) -> % Separate = % fun(S,{DoSuite,Dont}) -> % case lists:keymember({TestDir,S},1,Bad) of @@ -1140,10 +1410,10 @@ final_tests([{TestDir,Suites,_}|Tests], Skip1 = [{TD,S,"Make failed"} || {{TD,S},_} <- Bad, S1 <- Suites, S == S1, TD == TestDir], - Final1 = [{TestDir,S,all} || S <- Suites], - final_tests(Tests, lists:reverse(Final1)++Final, Skip++Skip1, Bad); + Final1 = [{TestDir,S,all} || S <- Suites], + final_tests1(Tests, lists:reverse(Final1)++Final, Skip++Skip1, Bad); -final_tests([{TestDir,all,all}|Tests], Final, Skip, Bad) -> +final_tests1([{TestDir,all,all}|Tests], Final, Skip, Bad) -> MissingSuites = case lists:keysearch({TestDir,all}, 1, Bad) of {value,{_,Failed}} -> @@ -1153,27 +1423,59 @@ final_tests([{TestDir,all,all}|Tests], Final, Skip, Bad) -> end, Missing = [{TestDir,S,"Make failed"} || S <- MissingSuites], Final1 = [{TestDir,all,all}|Final], - final_tests(Tests, Final1, Skip++Missing, Bad); + final_tests1(Tests, Final1, Skip++Missing, Bad); -final_tests([{TestDir,Suite,Cases}|Tests], - Final, Skip, Bad) when Cases==[]; Cases==all -> - final_tests([{TestDir,[Suite],all}|Tests], Final, Skip, Bad); +final_tests1([{TestDir,Suite,Cases}|Tests], Final, Skip, Bad) when + Cases==[]; Cases==all -> + final_tests1([{TestDir,[Suite],all}|Tests], Final, Skip, Bad); -final_tests([{TestDir,Suite,Cases}|Tests], Final, Skip, Bad) -> +final_tests1([{TestDir,Suite,GrsOrCs}|Tests], Final, Skip, Bad) when + is_list(GrsOrCs) -> case lists:keymember({TestDir,Suite}, 1, Bad) of - false -> - Do = {TestDir,Suite,Cases}, - final_tests(Tests, [Do|Final], Skip, Bad); true -> - Do = {TestDir,Suite,Cases}, - Skip1 = Skip ++ [{TestDir,Suite,Cases,"Make failed"}], - final_tests(Tests, [Do|Final], Skip1, Bad) + Skip1 = Skip ++ [{TestDir,Suite,all,"Make failed"}], + final_tests1(Tests, [{TestDir,Suite,all}|Final], Skip1, Bad); + false -> + GrsOrCs1 = + lists:flatmap( + %% for now, only flat group defs are allowed as + %% start options and test spec terms + fun({all,all}) -> + ct_framework:make_all_conf(TestDir, + Suite, []); + ({skipped,Group,TCs}) -> + [ct_framework:make_conf(TestDir, Suite, + Group, [skipped], TCs)]; + ({Group,TCs}) -> + [ct_framework:make_conf(TestDir, Suite, + Group, [], TCs)]; + (TC) -> + [TC] + end, GrsOrCs), + Do = {TestDir,Suite,GrsOrCs1}, + final_tests1(Tests, [Do|Final], Skip, Bad) end; -final_tests([], Final, Skip, _Bad) -> +final_tests1([], Final, Skip, _Bad) -> {lists:reverse(Final),Skip}. -continue([]) -> +final_skip([{TestDir,Suite,{all,all},Reason}|Skips], Final) -> + SkipConf = ct_framework:make_conf(TestDir, Suite, all, [], all), + Skip = {TestDir,Suite,SkipConf,Reason}, + final_skip(Skips, [Skip|Final]); + +final_skip([{TestDir,Suite,{Group,TCs},Reason}|Skips], Final) -> + Conf = ct_framework:make_conf(TestDir, Suite, Group, [], TCs), + Skip = {TestDir,Suite,Conf,Reason}, + final_skip(Skips, [Skip|Final]); + +final_skip([Skip|Skips], Final) -> + final_skip(Skips, [Skip|Final]); + +final_skip([], Final) -> + lists:reverse(Final). + +continue([]) -> true; continue(_MakeErrors) -> io:nl(), @@ -1214,7 +1516,7 @@ set_group_leader_same_as_shell() -> false end end, - case [P || P <- processes(), GS2or3(P), + case [P || P <- processes(), GS2or3(P), true == lists:keymember(shell,1,element(2,process_info(P,dictionary)))] of [GL|_] -> group_leader(GL, self()); @@ -1238,29 +1540,29 @@ check_and_add([{TestDir0,M,_} | Tests], Added) -> check_and_add([], _) -> ok. -do_run_test(Tests, Skip, Opt) -> +do_run_test(Tests, Skip, Opts) -> case check_and_add(Tests, []) of ok -> ct_util:set_testdata({stats,{0,0,{0,0}}}), ct_util:set_testdata({cover,undefined}), test_server_ctrl:start_link(local), - case lists:keysearch(cover_spec, 1, Opt) of - {value,{_,CovData={CovFile, - CovNodes, - _CovImport, - CovExport, - #cover{app = CovApp, - level = CovLevel, - excl_mods = CovExcl, - incl_mods = CovIncl, - cross = CovCross, - src = _CovSrc}}}} -> + case Opts#opts.coverspec of + CovData={CovFile, + CovNodes, + _CovImport, + CovExport, + #cover{app = CovApp, + level = CovLevel, + excl_mods = CovExcl, + incl_mods = CovIncl, + cross = CovCross, + src = _CovSrc}} -> ct_logs:log("COVER INFO","Using cover specification file: ~s~n" "App: ~w~n" "Cross cover: ~w~n" "Including ~w modules~n" "Excluding ~w modules", - [CovFile,CovApp,CovCross,length(CovIncl),length(CovExcl)]), + [CovFile,CovApp,CovCross,length(CovIncl),length(CovExcl)]), %% cover export file will be used for export and import %% between tests so make sure it doesn't exist initially @@ -1293,33 +1595,38 @@ do_run_test(Tests, Skip, Opt) -> true; _ -> false - end, + end, + %% let test_server expand the test tuples and count no of cases {Suites,NoOfCases} = count_test_cases(Tests, Skip), Suites1 = delete_dups(Suites), NoOfTests = length(Tests), NoOfSuites = length(Suites1), - ct_util:warn_duplicates(Suites1), + ct_util:warn_duplicates(Suites1), {ok,Cwd} = file:get_cwd(), io:format("~nCWD set to: ~p~n", [Cwd]), if NoOfCases == unknown -> - io:format("~nTEST INFO: ~w test(s), ~w suite(s)~n~n", + io:format("~nTEST INFO: ~w test(s), ~w suite(s)~n~n", [NoOfTests,NoOfSuites]), - ct_logs:log("TEST INFO","~w test(s), ~w suite(s)", + ct_logs:log("TEST INFO","~w test(s), ~w suite(s)", [NoOfTests,NoOfSuites]); true -> - io:format("~nTEST INFO: ~w test(s), ~w case(s) in ~w suite(s)~n~n", + io:format("~nTEST INFO: ~w test(s), ~w case(s) in ~w suite(s)~n~n", [NoOfTests,NoOfCases,NoOfSuites]), - ct_logs:log("TEST INFO","~w test(s), ~w case(s) in ~w suite(s)", + ct_logs:log("TEST INFO","~w test(s), ~w case(s) in ~w suite(s)", [NoOfTests,NoOfCases,NoOfSuites]) end, + + test_server_ctrl:multiply_timetraps(Opts#opts.multiply_timetraps), + test_server_ctrl:scale_timetraps(Opts#opts.scale_timetraps), + ct_event:notify(#event{name=start_info, node=node(), data={NoOfTests,NoOfSuites,NoOfCases}}), - CleanUp = add_jobs(Tests, Skip, Opt, []), + CleanUp = add_jobs(Tests, Skip, Opts, []), unlink(whereis(test_server_ctrl)), - catch test_server_ctrl:wait_finish(), - %% check if last testcase has left a "dead" trace window + catch test_server_ctrl:wait_finish(), + %% check if last testcase has left a "dead" trace window %% behind, and if so, kill it case ct_util:get_testdata(interpret) of {_What,kill,{TCPid,AttPid}} -> @@ -1327,8 +1634,8 @@ do_run_test(Tests, Skip, Opt) -> _ -> ok end, - lists:foreach(fun(Suite) -> - maybe_cleanup_interpret(Suite, Opt) + lists:foreach(fun(Suite) -> + maybe_cleanup_interpret(Suite, Opts#opts.step) end, CleanUp); Error -> Error @@ -1344,21 +1651,32 @@ count_test_cases(Tests, Skip) -> SendResult = fun(Me, Result) -> Me ! {no_of_cases,Result} end, TSPid = test_server_ctrl:start_get_totals(SendResult), Ref = erlang:monitor(process, TSPid), - add_jobs(Tests, Skip, [], []), - {Suites,NoOfCases} = count_test_cases1(length(Tests), 0, [], Ref), - erlang:demonitor(Ref), - test_server_ctrl:stop_get_totals(), - {Suites,NoOfCases}. + add_jobs(Tests, Skip, #opts{}, []), + Counted = (catch count_test_cases1(length(Tests), 0, [], Ref)), + erlang:demonitor(Ref, [flush]), + case Counted of + {error,{test_server_died}} = Error -> + throw(Error); + {error,Reason} -> + unlink(whereis(test_server_ctrl)), + test_server_ctrl:stop(), + throw({user_error,Reason}); + Result -> + test_server_ctrl:stop_get_totals(), + Result + end. count_test_cases1(0, N, Suites, _) -> {lists:flatten(Suites), N}; count_test_cases1(Jobs, N, Suites, Ref) -> receive - {no_of_cases,{Ss,N1}} -> + {_,{error,_Reason} = Error} -> + throw(Error); + {no_of_cases,{Ss,N1}} -> count_test_cases1(Jobs-1, add_known(N,N1), [Ss|Suites], Ref); - {'DOWN', Ref, _, _, _} -> - {[],0} - end. + {'DOWN', Ref, _, _, Info} -> + throw({error,{test_server_died,Info}}) + end. add_known(unknown, _) -> unknown; @@ -1367,72 +1685,109 @@ add_known(_, unknown) -> add_known(N, N1) -> N+N1. -add_jobs([{TestDir,all,_}|Tests], Skip, Opt, CleanUp) -> +add_jobs([{TestDir,all,_}|Tests], Skip, Opts, CleanUp) -> Name = get_name(TestDir), case catch test_server_ctrl:add_dir_with_skip(Name, TestDir, skiplist(TestDir,Skip)) of - {'EXIT',_} -> + {'EXIT',_} -> CleanUp; _ -> wait_for_idle(), - add_jobs(Tests, Skip, Opt, CleanUp) + add_jobs(Tests, Skip, Opts, CleanUp) end; -add_jobs([{TestDir,[Suite],all}|Tests], Skip, Opt, CleanUp) when is_atom(Suite) -> - add_jobs([{TestDir,Suite,all}|Tests], Skip, Opt, CleanUp); -add_jobs([{TestDir,Suites,all}|Tests], Skip, Opt, CleanUp) when is_list(Suites) -> +add_jobs([{TestDir,[Suite],all}|Tests], Skip, Opts, CleanUp) when is_atom(Suite) -> + add_jobs([{TestDir,Suite,all}|Tests], Skip, Opts, CleanUp); +add_jobs([{TestDir,Suites,all}|Tests], Skip, Opts, CleanUp) when is_list(Suites) -> Name = get_name(TestDir) ++ ".suites", case catch test_server_ctrl:add_module_with_skip(Name, Suites, skiplist(TestDir,Skip)) of - {'EXIT',_} -> + {'EXIT',_} -> CleanUp; _ -> wait_for_idle(), - add_jobs(Tests, Skip, Opt, CleanUp) + add_jobs(Tests, Skip, Opts, CleanUp) end; -add_jobs([{TestDir,Suite,all}|Tests], Skip, Opt, CleanUp) -> - case maybe_interpret(Suite, all, Opt) of +add_jobs([{TestDir,Suite,all}|Tests], Skip, Opts, CleanUp) -> + case maybe_interpret(Suite, all, Opts) of ok -> Name = get_name(TestDir) ++ "." ++ atom_to_list(Suite), case catch test_server_ctrl:add_module_with_skip(Name, [Suite], skiplist(TestDir,Skip)) of - {'EXIT',_} -> + {'EXIT',_} -> CleanUp; _ -> wait_for_idle(), - add_jobs(Tests, Skip, Opt, [Suite|CleanUp]) + add_jobs(Tests, Skip, Opts, [Suite|CleanUp]) end; Error -> Error end; -add_jobs([{TestDir,Suite,[Case]}|Tests], Skip, Opt, CleanUp) when is_atom(Case) -> - add_jobs([{TestDir,Suite,Case}|Tests], Skip, Opt, CleanUp); -add_jobs([{TestDir,Suite,Cases}|Tests], Skip, Opt, CleanUp) when is_list(Cases) -> - case maybe_interpret(Suite, Cases, Opt) of + +%% group (= conf case in test_server) +add_jobs([{TestDir,Suite,Confs}|Tests], Skip, Opts, CleanUp) when + element(1, hd(Confs)) == conf -> + Group = fun(Conf) -> proplists:get_value(name, element(2, Conf)) end, + TestCases = fun(Conf) -> element(4, Conf) end, + TCTestName = fun(all) -> ""; + ([C]) when is_atom(C) -> "." ++ atom_to_list(C); + (Cs) when is_list(Cs) -> ".cases" + end, + GrTestName = + case Confs of + [Conf] -> + "." ++ atom_to_list(Group(Conf)) ++ TCTestName(TestCases(Conf)); + _ -> + ".groups" + end, + TestName = get_name(TestDir) ++ "." ++ atom_to_list(Suite) ++ GrTestName, + case maybe_interpret(Suite, init_per_group, Opts) of + ok -> + case catch test_server_ctrl:add_conf_with_skip(TestName, Suite, Confs, + skiplist(TestDir,Skip)) of + {'EXIT',_} -> + CleanUp; + _ -> + wait_for_idle(), + add_jobs(Tests, Skip, Opts, [Suite|CleanUp]) + end; + Error -> + Error + end; + +%% test case +add_jobs([{TestDir,Suite,[Case]}|Tests], Skip, Opts, CleanUp) when is_atom(Case) -> + add_jobs([{TestDir,Suite,Case}|Tests], Skip, Opts, CleanUp); + +add_jobs([{TestDir,Suite,Cases}|Tests], Skip, Opts, CleanUp) when is_list(Cases) -> + Cases1 = lists:map(fun({GroupName,_}) when is_atom(GroupName) -> GroupName; + (Case) -> Case + end, Cases), + case maybe_interpret(Suite, Cases1, Opts) of ok -> Name = get_name(TestDir) ++ "." ++ atom_to_list(Suite) ++ ".cases", - case catch test_server_ctrl:add_cases_with_skip(Name, Suite, Cases, + case catch test_server_ctrl:add_cases_with_skip(Name, Suite, Cases1, skiplist(TestDir,Skip)) of - {'EXIT',_} -> + {'EXIT',_} -> CleanUp; _ -> wait_for_idle(), - add_jobs(Tests, Skip, Opt, [Suite|CleanUp]) + add_jobs(Tests, Skip, Opts, [Suite|CleanUp]) end; Error -> Error end; -add_jobs([{TestDir,Suite,Case}|Tests], Skip, Opt, CleanUp) when is_atom(Case) -> - case maybe_interpret(Suite, Case, Opt) of +add_jobs([{TestDir,Suite,Case}|Tests], Skip, Opts, CleanUp) when is_atom(Case) -> + case maybe_interpret(Suite, Case, Opts) of ok -> - Name = get_name(TestDir) ++ "." ++ atom_to_list(Suite) ++ "." ++ + Name = get_name(TestDir) ++ "." ++ atom_to_list(Suite) ++ "." ++ atom_to_list(Case), case catch test_server_ctrl:add_case_with_skip(Name, Suite, Case, skiplist(TestDir,Skip)) of - {'EXIT',_} -> + {'EXIT',_} -> CleanUp; _ -> wait_for_idle(), - add_jobs(Tests, Skip, Opt, [Suite|CleanUp]) + add_jobs(Tests, Skip, Opts, [Suite|CleanUp]) end; Error -> Error @@ -1453,7 +1808,7 @@ wait_for_idle() -> idle -> ok; {'DOWN', Ref, _, _, _} -> error end, - erlang:demonitor(Ref), + erlang:demonitor(Ref, [flush]), ct_util:update_last_run_index(), Result end. @@ -1482,7 +1837,7 @@ get_name(Dir) -> end, Base = filename:basename(TestDir), case filename:basename(filename:dirname(TestDir)) of - "" -> + "" -> Base; TopDir -> TopDir ++ "." ++ Base @@ -1513,15 +1868,15 @@ run_make(Targets, TestDir0, Mod, UserInclude) -> {i,CtInclude}, {i,XmerlInclude}, debug_info], - Result = + Result = if Mod == all ; Targets == helpmods -> case (catch ct_make:all([noexec|ErlFlags])) of - {'EXIT',_} = Failure -> + {'EXIT',_} = Failure -> Failure; MakeInfo -> FileTest = fun(F, suites) -> is_suite(F); - (F, helpmods) -> not is_suite(F); - (_, _) -> true end, + (F, helpmods) -> not is_suite(F) + end, Files = lists:flatmap(fun({F,out_of_date}) -> case FileTest(F, Targets) of true -> [F]; @@ -1535,7 +1890,7 @@ run_make(Targets, TestDir0, Mod, UserInclude) -> true -> (catch ct_make:files([Mod], [load|ErlFlags])) end, - + ok = file:set_cwd(Cwd), %% send finished_make notification ct_event:notify(#event{name=finished_make, @@ -1549,7 +1904,7 @@ run_make(Targets, TestDir0, Mod, UserInclude) -> {error,{make_crashed,TestDir,Reason}}; {error,ModInfo} -> io:format("{error,make_failed}\n", []), - Bad = [filename:join(TestDir, M) || {M,R} <- ModInfo, + Bad = [filename:join(TestDir, M) || {M,R} <- ModInfo, R == error], {error,{make_failed,Bad}} end; @@ -1561,8 +1916,8 @@ run_make(Targets, TestDir0, Mod, UserInclude) -> get_dir(App, Dir) -> filename:join(code:lib_dir(App), Dir). -maybe_interpret(Suite, Cases, [{step,StepOpts}]) -> - %% if other suite has run before this one, check if last testcase +maybe_interpret(Suite, Cases, #opts{step = StepOpts}) when StepOpts =/= undefined -> + %% if other suite has run before this one, check if last testcase %% has left a "dead" trace window behind, and if so, kill it case ct_util:get_testdata(interpret) of {_What,kill,{TCPid,AttPid}} -> @@ -1605,7 +1960,7 @@ maybe_interpret2(Suite, Cases, StepOpts) -> WinOp = case lists:member(keep_inactive, ensure_atom(StepOpts)) of true -> no_kill; false -> kill - end, + end, ct_util:set_testdata({interpret,{{Suite,Cases},WinOp, {undefined,undefined}}}), ok. @@ -1621,37 +1976,44 @@ set_break_on_config(Suite, StepOpts) -> ok end. -maybe_cleanup_interpret(Suite, [{step,_}]) -> - i:iq(Suite); -maybe_cleanup_interpret(_, _) -> - ok. +maybe_cleanup_interpret(_, undefined) -> + ok; +maybe_cleanup_interpret(Suite, _) -> + i:iq(Suite). + +log_ts_names([]) -> + ok; +log_ts_names(Specs) -> + List = lists:map(fun(Name) -> + Name ++ " " + end, Specs), + ct_logs:log("Test Specification file(s)", "~s", + [lists:flatten(List)]). -log_ts_names(Args) -> - case lists:keysearch(spec, 1, Args) of - {value,{_,Specs}} -> - List = lists:map(fun(Name) -> - Name ++ " " - end, Specs), - ct_logs:log("Test Specification file(s)", "~s", - [lists:flatten(List)]); - _ -> - ok - end. - merge_arguments(Args) -> merge_arguments(Args, []). merge_arguments([LogDir={logdir,_}|Args], Merged) -> merge_arguments(Args, handle_arg(replace, LogDir, Merged)); + merge_arguments([CoverFile={cover,_}|Args], Merged) -> merge_arguments(Args, handle_arg(replace, CoverFile, Merged)); -merge_arguments([Arg={_,_}|Args], Merged) -> + +merge_arguments([{'case',TC}|Args], Merged) -> + merge_arguments(Args, handle_arg(merge, {testcase,TC}, Merged)); + +merge_arguments([Arg|Args], Merged) -> merge_arguments(Args, handle_arg(merge, Arg, Merged)); + merge_arguments([], Merged) -> Merged. handle_arg(replace, {Key,Elems}, [{Key,_}|Merged]) -> [{Key,Elems}|Merged]; +handle_arg(merge, {event_handler_init,Elems}, [{event_handler_init,PrevElems}|Merged]) -> + [{event_handler_init,PrevElems++["add"|Elems]}|Merged]; +handle_arg(merge, {userconfig,Elems}, [{userconfig,PrevElems}|Merged]) -> + [{userconfig,PrevElems++["add"|Elems]}|Merged]; handle_arg(merge, {Key,Elems}, [{Key,PrevElems}|Merged]) -> [{Key,PrevElems++Elems}|Merged]; handle_arg(Op, Arg, [Other|Merged]) -> @@ -1659,6 +2021,164 @@ handle_arg(Op, Arg, [Other|Merged]) -> handle_arg(_,Arg,[]) -> [Arg]. +get_start_opt(Key, IfExists, Args) -> + get_start_opt(Key, IfExists, undefined, Args). + +get_start_opt(Key, IfExists, IfNotExists, Args) -> + case lists:keysearch(Key, 1, Args) of + {value,{Key,Val}} when is_function(IfExists) -> + IfExists(Val); + {value,{Key,Val}} when IfExists == value -> + Val; + {value,{Key,_Val}} -> + IfExists; + _ when is_function(IfNotExists) -> + IfNotExists(); + _ -> + IfNotExists + end. + +event_handler_args2opts(Args) -> + case proplists:get_value(event_handler, Args) of + undefined -> + event_handler_args2opts([], Args); + EHs -> + event_handler_args2opts([{list_to_atom(EH),[]} || EH <- EHs], Args) + end. +event_handler_args2opts(Default, Args) -> + case proplists:get_value(event_handler_init, Args) of + undefined -> + Default; + EHs -> + event_handler_init_args2opts(EHs) + end. +event_handler_init_args2opts([EH, Arg, "and" | EHs]) -> + [{list_to_atom(EH),lists:flatten(io_lib:format("~s",[Arg]))} | + event_handler_init_args2opts(EHs)]; +event_handler_init_args2opts([EH, Arg]) -> + [{list_to_atom(EH),lists:flatten(io_lib:format("~s",[Arg]))}]; +event_handler_init_args2opts([]) -> + []. + +%% This function reads pa and pz arguments, converts dirs from relative +%% to absolute, and re-inserts them in the code path. The order of the +%% dirs in the code path remain the same. Note however that since this +%% function is only used for arguments "pre run_test erl_args", the order +%% relative dirs "post run_test erl_args" is not kept! +rel_to_abs(CtArgs) -> + {PA,PZ} = get_pa_pz(CtArgs, [], []), + io:format(user, "~n", []), + [begin + code:del_path(filename:basename(D)), + Abs = filename:absname(D), + code:add_pathz(Abs), + if D /= Abs -> + io:format(user, "Converting ~p to ~p and re-inserting " + "with add_pathz/1~n", + [D, Abs]); + true -> + ok + end + end || D <- PZ], + [begin + code:del_path(filename:basename(D)), + Abs = filename:absname(D), + code:add_patha(Abs), + if D /= Abs -> + io:format(user, "Converting ~p to ~p and re-inserting " + "with add_patha/1~n", + [D, Abs]); + true ->ok + end + end || D <- PA], + io:format(user, "~n", []). + +get_pa_pz([{pa,Dirs} | Args], PA, PZ) -> + get_pa_pz(Args, PA ++ Dirs, PZ); +get_pa_pz([{pz,Dirs} | Args], PA, PZ) -> + get_pa_pz(Args, PA, PZ ++ Dirs); +get_pa_pz([_ | Args], PA, PZ) -> + get_pa_pz(Args, PA, PZ); +get_pa_pz([], PA, PZ) -> + {PA,PZ}. + +%% This function translates ct:run_test/1 start options +%% to run_test start arguments (on the init arguments format) - +%% this is useful mainly for testing the ct_run start functions. +opts2args(EnvStartOpts) -> + lists:flatmap(fun({config,CfgFiles}) -> + [{ct_config,[CfgFiles]}]; + ({userconfig,{CBM,CfgStr=[X|_]}}) when is_integer(X) -> + [{userconfig,[atom_to_list(CBM),CfgStr]}]; + ({userconfig,{CBM,CfgStrs}}) when is_list(CfgStrs) -> + [{userconfig,[atom_to_list(CBM) | CfgStrs]}]; + ({userconfig,UserCfg}) when is_list(UserCfg) -> + Strs = + lists:map(fun({CBM,CfgStr=[X|_]}) when is_integer(X) -> + [atom_to_list(CBM),CfgStr,"and"]; + ({CBM,CfgStrs}) when is_list(CfgStrs) -> + [atom_to_list(CBM) | CfgStrs] ++ ["and"] + end, UserCfg), + [_LastAnd|StrsR] = lists:reverse(lists:flatten(Strs)), + [{userconfig,lists:reverse(StrsR)}]; + ({testcase,Case}) when is_atom(Case) -> + [{'case',[atom_to_list(Case)]}]; + ({testcase,Cases}) -> + [{'case',[atom_to_list(C) || C <- Cases]}]; + ({'case',Cases}) -> + [{'case',[atom_to_list(C) || C <- Cases]}]; + ({allow_user_terms,true}) -> + [{allow_user_terms,[]}]; + ({allow_user_terms,false}) -> + []; + ({auto_compile,false}) -> + [{no_auto_compile,[]}]; + ({auto_compile,true}) -> + []; + ({scale_timetraps,true}) -> + [{scale_timetraps,[]}]; + ({scale_timetraps,false}) -> + []; + ({force_stop,true}) -> + [{force_stop,[]}]; + ({force_stop,false}) -> + []; + ({decrypt,{key,Key}}) -> + [{ct_decrypt_key,[Key]}]; + ({decrypt,{file,File}}) -> + [{ct_decrypt_file,[File]}]; + ({basic_html,true}) -> + ({basic_html,[]}); + ({basic_html,false}) -> + []; + ({event_handler,EH}) when is_atom(EH) -> + [{event_handler,[atom_to_list(EH)]}]; + ({event_handler,EHs}) when is_list(EHs) -> + [{event_handler,[atom_to_list(EH) || EH <- EHs]}]; + ({event_handler,{EH,Arg}}) when is_atom(EH) -> + ArgStr = lists:flatten(io_lib:format("~p", [Arg])), + [{event_handler_init,[atom_to_list(EH),ArgStr]}]; + ({event_handler,{EHs,Arg}}) when is_list(EHs) -> + ArgStr = lists:flatten(io_lib:format("~p", [Arg])), + Strs = lists:map(fun(EH) -> + [atom_to_list(EH),ArgStr,"and"] + end, EHs), + [_LastAnd|StrsR] = lists:reverse(lists:flatten(Strs)), + [{event_handler_init,lists:reverse(StrsR)}]; + ({Opt,As=[A|_]}) when is_atom(A) -> + [{Opt,[atom_to_list(Atom) || Atom <- As]}]; + ({Opt,Strs=[S|_]}) when is_list(S) -> + [{Opt,Strs}]; + ({Opt,A}) when is_atom(A) -> + [{Opt,[atom_to_list(A)]}]; + ({Opt,I}) when is_integer(I) -> + [{Opt,[integer_to_list(I)]}]; + ({Opt,S}) when is_list(S) -> + [{Opt,[S]}]; + (Opt) -> + Opt + end, EnvStartOpts). + locate_test_dir(Dir, Suite) -> TestDir = case ct_util:is_test_dir(Dir) of true -> Dir; @@ -1723,18 +2243,18 @@ start_trace(Args) -> case file:consult(TraceSpec) of {ok,Terms} -> case catch do_trace(Terms) of - ok -> + ok -> true; {_,Error} -> io:format("Warning! Tracing not started. Reason: ~p~n~n", [Error]), false - end; + end; {_,Error} -> io:format("Warning! Tracing not started. Reason: ~p~n~n", [Error]), false - end; + end; false -> false end. @@ -1746,61 +2266,22 @@ do_trace(Terms) -> case dbg:tpl(M,[{'_',[],[{return_trace}]}]) of {error,What} -> exit({error,{tracing_failed,What}}); _ -> ok - end; + end; ({f,M,F}) -> case dbg:tpl(M,F,[{'_',[],[{return_trace}]}]) of {error,What} -> exit({error,{tracing_failed,What}}); _ -> ok - end; + end; (Huh) -> exit({error,{unrecognized_trace_term,Huh}}) end, Terms), ok. - + stop_trace(true) -> dbg:stop_clear(); stop_trace(false) -> ok. -preload() -> - io:format("~nLoading Common Test and Test Server modules...~n~n"), - preload_mod([ct_logs, - ct_make, - ct_telnet, - ct, - ct_master, - ct_testspec, - ct_cover, - ct_master_event, - ct_util, - ct_event, - ct_master_logs, - ct_framework, - teln, - ct_ftp, - ct_rpc, - unix_telnet, - ct_gen_conn, - ct_line, - ct_snmp, - test_server_sup, - test_server, - test_server_ctrl, - test_server_h, - test_server_line, - test_server_node]). - -preload_mod([M|Ms]) -> - case code:is_loaded(M) of - false -> - {module,M} = code:load_file(M), - preload_mod(Ms); - _ -> - ok - end; -preload_mod([]) -> - ok. - ensure_atom(Atom) when is_atom(Atom) -> Atom; ensure_atom(String) when is_list(String), is_integer(hd(String)) -> @@ -1809,4 +2290,3 @@ ensure_atom(List) when is_list(List) -> [ensure_atom(Item) || Item <- List]; ensure_atom(Other) -> Other. - diff --git a/lib/common_test/src/ct_slave.erl b/lib/common_test/src/ct_slave.erl new file mode 100644 index 0000000000..aa3413fa89 --- /dev/null +++ b/lib/common_test/src/ct_slave.erl @@ -0,0 +1,439 @@ +%%-------------------------------------------------------------------- +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% + +%%% @doc Common Test Framework functions for starting and stopping nodes for +%%% Large Scale Testing. +%%% +%%% <p>This module exports functions which are used by the Common Test Master +%%% to start and stop "slave" nodes. It is the default callback module for the +%%% <code>{init, node_start}</code> term of the Test Specification.</p> + +%%---------------------------------------------------------------------- +%% File : ct_slave.erl +%% Description : CT module for starting nodes for large-scale testing. +%% +%% Created : 7 April 2010 +%%---------------------------------------------------------------------- +-module(ct_slave). + +-export([start/1, start/2, start/3, stop/1, stop/2]). + +-export([slave_started/2, slave_ready/2, monitor_master/1]). + +-record(options, {username, password, boot_timeout, init_timeout, + startup_timeout, startup_functions, monitor_master, + kill_if_fail, erl_flags}). + +%%%----------------------------------------------------------------- +%%% @spec start(Node) -> Result +%%% Node = atom() +%%% Result = {ok, NodeName} | +%%% {error, already_started, NodeName} | +%%% {error, started_not_connected, NodeName} | +%%% {error, boot_timeout, NodeName} | +%%% {error, init_timeout, NodeName} | +%%% {error, startup_timeout, NodeName} | +%%% {error, not_alive, NodeName} +%%% NodeName = atom() +%%% @doc Starts an Erlang node with name <code>Node</code> on the local host. +%%% @see start/3 +start(Node) -> + start(gethostname(), Node). + +%%%----------------------------------------------------------------- +%%% @spec start(Host, Node) -> Result +%%% Node = atom() +%%% Host = atom() +%%% Result = {ok, NodeName} | +%%% {error, already_started, NodeName} | +%%% {error, started_not_connected, NodeName} | +%%% {error, boot_timeout, NodeName} | +%%% {error, init_timeout, NodeName} | +%%% {error, startup_timeout, NodeName} | +%%% {error, not_alive, NodeName} +%%% NodeName = atom() +%%% @doc Starts an Erlang node with name <code>Node</code> on host +%%% <code>Host</code> with the default options. +%%% @see start/3 +start(Host, Node) -> + start(Host, Node, []). + +%%%----------------------------------------------------------------- +%%% @spec start(Host, Node, Opts) -> Result +%%% Node = atom() +%%% Host = atom() +%%% Opts = [OptTuples] +%%% OptTuples = {username, Username} | +%%% {password, Password} | +%%% {boot_timeout, BootTimeout} | {init_timeout, InitTimeout} | +%%% {startup_timeout, StartupTimeout} | +%%% {startup_functions, StartupFunctions} | +%%% {monitor_master, Monitor} | +%%% {kill_if_fail, KillIfFail} | +%%% {erl_flags, ErlangFlags} +%%% Username = string() +%%% Password = string() +%%% BootTimeout = integer() +%%% InitTimeout = integer() +%%% StartupTimeout = integer() +%%% StartupFunctions = [StartupFunctionSpec] +%%% StartupFunctionSpec = {Module, Function, Arguments} +%%% Module = atom() +%%% Function = atom() +%%% Arguments = [term] +%%% Monitor = bool() +%%% KillIfFail = bool() +%%% ErlangFlags = string() +%%% Result = {ok, NodeName} | {error, already_started, NodeName} | +%%% {error, started_not_connected, NodeName} | +%%% {error, boot_timeout, NodeName} | +%%% {error, init_timeout, NodeName} | +%%% {error, startup_timeout, NodeName} | +%%% {error, not_alive, NodeName} +%%% NodeName = atom() +%%% @doc Starts an Erlang node with name <code>Node</code> on host +%%% <code>Host</code> as specified by the combination of options in +%%% <code>Opts</code>. +%%% +%%% <p>Options <code>Username</code> and <code>Password</code> will be used +%%% to log in onto the remote host <code>Host</code>. +%%% Username, if omitted, defaults to the current user name, +%%% and password is empty by default.</p> +%%% +%%% <p>A list of functions specified in the <code>Startup</code> option will be +%%% executed after startup of the node. Note that all used modules should be +%%% present in the code path on the <code>Host</code>.</p> +%%% +%%% <p>The timeouts are applied as follows: +%%% <list> +%%% <item> +%%% <code>BootTimeout</code> - time to start the Erlang node, in seconds. +%%% Defaults to 3 seconds. If node does not become pingable within this time, +%%% the result <code>{error, boot_timeout, NodeName}</code> is returned; +%%% </item> +%%% <item> +%%% <code>InitTimeout</code> - time to wait for the node until it calls the +%%% internal callback function informing master about successfull startup. +%%% Defaults to one second. +%%% In case of timed out message the result +%%% <code>{error, init_timeout, NodeName}</code> is returned; +%%% </item> +%%% <item> +%%% <code>StartupTimeout</code> - time to wait intil the node finishes to run +%%% the <code>StartupFunctions</code>. Defaults to one second. +%%% If this timeout occurs, the result +%%% <code>{error, startup_timeout, NodeName}</code> is returned. +%%% </item> +%%% </list></p> +%%% +%%% <p>Option <code>monitor_master</code> specifies, if the slave node should be +%%% stopped in case of master node stop. Defaults to false.</p> +%%% +%%% <p>Option <code>kill_if_fail</code> specifies, if the slave node should be +%%% killed in case of a timeout during initialization or startup. +%%% Defaults to true. Note that node also may be still alive it the boot +%%% timeout occurred, but it will not be killed in this case.</p> +%%% +%%% <p>Option <code>erlang_flags</code> specifies, which flags will be added +%%% to the parameters of the <code>erl</code> executable.</p> +%%% +%%% <p>Special return values are: +%%% <list> +%%% <item><code>{error, already_started, NodeName}</code> - if the node with +%%% the given name is already started on a given host;</item> +%%% <item><code>{error, started_not_connected, NodeName}</code> - if node is +%%% started, but not connected to the master node.</item> +%%% <item><code>{error, not_alive, NodeName}</code> - if node on which the +%%% <code>ct_slave:start/3</code> is called, is not alive. Note that +%%% <code>NodeName</code> is the name of current node in this case.</item> +%%% </list></p> +%%% +start(Host, Node, Options) -> + ENode = enodename(Host, Node), + case erlang:is_alive() of + false-> + {error, not_alive, node()}; + true-> + case is_started(ENode) of + false-> + OptionsRec = fetch_options(Options), + do_start(Host, Node, OptionsRec); + {true, not_connected}-> + {error, started_not_connected, ENode}; + {true, connected}-> + {error, already_started, ENode} + end + end. + +%%% @spec stop(Node) -> Result +%%% Node = atom() +%%% Result = {ok, NodeName} | +%%% {error, not_started, NodeName} | +%%% {error, not_connected, NodeName} | +%%% {error, stop_timeout, NodeName} +%%% NodeName = atom() +%%% @doc Stops the running Erlang node with name <code>Node</code> on +%%% the localhost. +stop(Node) -> + stop(gethostname(), Node). + +%%% @spec stop(Host, Node) -> Result +%%% Host = atom() +%%% Node = atom() +%%% Result = {ok, NodeName} | +%%% {error, not_started, NodeName} | +%%% {error, not_connected, NodeName} | +%%% {error, stop_timeout, NodeName} +%%% NodeName = atom() +%%% @doc Stops the running Erlang node with name <code>Node</code> on +%%% host <code>Host</code>. +stop(Host, Node) -> + ENode = enodename(Host, Node), + case is_started(ENode) of + {true, connected}-> + do_stop(ENode); + {true, not_connected}-> + {error, not_connected, ENode}; + false-> + {error, not_started, ENode} + end. + +%%% fetch an option value from the tagged tuple list with default +get_option_value(Key, OptionList, Default) -> + case lists:keyfind(Key, 1, OptionList) of + false-> + Default; + {Key, Value}-> + Value + end. + +%%% convert option list to the option record, fill all defaults +fetch_options(Options) -> + UserName = get_option_value(username, Options, []), + Password = get_option_value(password, Options, []), + BootTimeout = get_option_value(boot_timeout, Options, 3), + InitTimeout = get_option_value(init_timeout, Options, 1), + StartupTimeout = get_option_value(startup_timeout, Options, 1), + StartupFunctions = get_option_value(startup_functions, Options, []), + Monitor = get_option_value(monitor_master, Options, false), + KillIfFail = get_option_value(kill_if_fail, Options, true), + ErlFlags = get_option_value(erl_flags, Options, []), + #options{username=UserName, password=Password, + boot_timeout=BootTimeout, init_timeout=InitTimeout, + startup_timeout=StartupTimeout, startup_functions=StartupFunctions, + monitor_master=Monitor, kill_if_fail=KillIfFail, erl_flags=ErlFlags}. + +% send a message when slave node is started +% @hidden +slave_started(ENode, MasterPid) -> + MasterPid ! {node_started, ENode}, + ok. + +% send a message when slave node has finished startup +% @hidden +slave_ready(ENode, MasterPid) -> + MasterPid ! {node_ready, ENode}, + ok. + +% start monitoring of the master node +% @hidden +monitor_master(MasterNode) -> + spawn(fun() -> monitor_master_int(MasterNode) end). + +% code of the masterdeath-waiter process +monitor_master_int(MasterNode) -> + erlang:monitor_node(MasterNode, true), + receive + {nodedown, MasterNode}-> + init:stop() + end. + +% check if node is listed in the nodes() +is_connected(ENode) -> + [N||N<-nodes(), N==ENode] == [ENode]. + +% check if node is alive (ping and disconnect if pingable) +is_started(ENode) -> + case is_connected(ENode) of + true-> + {true, connected}; + false-> + case net_adm:ping(ENode) of + pang-> + false; + pong-> + erlang:disconnect_node(ENode), + {true, not_connected} + end + end. + +% make a Erlang node name from name and hostname +enodename(Host, Node) -> + list_to_atom(atom_to_list(Node)++"@"++atom_to_list(Host)). + +% performs actual start of the "slave" node +do_start(Host, Node, Options) -> + ENode = enodename(Host, Node), + Functions = + lists:concat([[{ct_slave, slave_started, [ENode, self()]}], + Options#options.startup_functions, + [{ct_slave, slave_ready, [ENode, self()]}]]), + Functions2 = if + Options#options.monitor_master-> + [{ct_slave, monitor_master, [node()]}|Functions]; + true-> + Functions + end, + MasterHost = gethostname(), + if + MasterHost == Host -> + spawn_local_node(Node, Options); + true-> + spawn_remote_node(Host, Node, Options) + end, + BootTimeout = Options#options.boot_timeout, + InitTimeout = Options#options.init_timeout, + StartupTimeout = Options#options.startup_timeout, + Result = case wait_for_node_alive(ENode, BootTimeout) of + pong-> + call_functions(ENode, Functions2), + receive + {node_started, ENode}-> + receive + {node_ready, ENode}-> + {ok, ENode} + after StartupTimeout*1000-> + {error, startup_timeout, ENode} + end + after InitTimeout*1000 -> + {error, init_timeout, ENode} + end; + pang-> + {error, boot_timeout, ENode} + end, + case Result of + {ok, ENode}-> + ok; + {error, Timeout, ENode} + when ((Timeout==init_timeout) or (Timeout==startup_timeout)) and + Options#options.kill_if_fail-> + do_stop(ENode); + _-> ok + end, + Result. + +% are we using fully qualified hostnames +long_or_short() -> + case net_kernel:longnames() of + true-> + " -name "; + false-> + " -sname " + end. + +% get the localhost's name, depending on the using name policy +gethostname() -> + Hostname = case net_kernel:longnames() of + true-> + net_adm:localhost(); + _-> + {ok, Name}=inet:gethostname(), + Name + end, + list_to_atom(Hostname). + +% get cmd for starting Erlang +get_cmd(Node, Flags) -> + Cookie = erlang:get_cookie(), + "erl -detached -noinput -setcookie "++ atom_to_list(Cookie) ++ + long_or_short() ++ atom_to_list(Node) ++ " " ++ Flags. + +% spawn node locally +spawn_local_node(Node, Options) -> + ErlFlags = Options#options.erl_flags, + Cmd = get_cmd(Node, ErlFlags), + open_port({spawn, Cmd}, [stream]). + +% start crypto and ssh if not yet started +check_for_ssh_running() -> + case application:get_application(crypto) of + undefined-> + application:start(crypto), + case application:get_application(ssh) of + undefined-> + application:start(ssh); + {ok, ssh}-> + ok + end; + {ok, crypto}-> + ok + end. + +% spawn node remotely +spawn_remote_node(Host, Node, Options) -> + Username = Options#options.username, + Password = Options#options.password, + ErlFlags = Options#options.erl_flags, + SSHOptions = case {Username, Password} of + {[], []}-> + []; + {_, []}-> + [{user, Username}]; + {_, _}-> + [{user, Username}, {password, Password}] + end ++ [{silently_accept_hosts, true}], + check_for_ssh_running(), + {ok, SSHConnRef} = ssh:connect(atom_to_list(Host), 22, SSHOptions), + {ok, SSHChannelId} = ssh_connection:session_channel(SSHConnRef, infinity), + ssh_connection:exec(SSHConnRef, SSHChannelId, get_cmd(Node, ErlFlags), infinity). + +% call functions on a remote Erlang node +call_functions(_Node, []) -> + ok; +call_functions(Node, [{M, F, A}|Functions]) -> + rpc:call(Node, M, F, A), + call_functions(Node, Functions). + +% wait N seconds until node is pingable +wait_for_node_alive(_Node, 0) -> + pang; +wait_for_node_alive(Node, N) -> + timer:sleep(1000), + case net_adm:ping(Node) of + pong-> + pong; + pang-> + wait_for_node_alive(Node, N-1) + end. + +% call init:stop on a remote node +do_stop(ENode) -> + spawn(ENode, init, stop, []), + wait_for_node_dead(ENode, 5). + +% wait N seconds until node is disconnected +wait_for_node_dead(Node, 0) -> + {error, stop_timeout, Node}; +wait_for_node_dead(Node, N) -> + timer:sleep(1000), + case lists:member(Node, nodes()) of + true-> + wait_for_node_dead(Node, N-1); + false-> + {ok, Node} + end. diff --git a/lib/common_test/src/ct_snmp.erl b/lib/common_test/src/ct_snmp.erl index 7ff88ad7d3..8fe63e8ed1 100644 --- a/lib/common_test/src/ct_snmp.erl +++ b/lib/common_test/src/ct_snmp.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% 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% %% @@ -332,7 +332,7 @@ set_info(Config) -> register_users(MgrAgentConfName, Users) -> {snmp, SnmpVals} = ct:get_config(MgrAgentConfName), NewSnmpVals = lists:keyreplace(users, 1, SnmpVals, {users, Users}), - ct_util:update_config(MgrAgentConfName, {snmp, NewSnmpVals}), + ct_config:update_config(MgrAgentConfName, {snmp, NewSnmpVals}), setup_users(Users). %%% @spec register_agents(MgrAgentConfName, ManagedAgents) -> ok | {error, Reason} @@ -347,7 +347,7 @@ register_agents(MgrAgentConfName, ManagedAgents) -> {snmp, SnmpVals} = ct:get_config(MgrAgentConfName), NewSnmpVals = lists:keyreplace(managed_agents, 1, SnmpVals, {managed_agents, ManagedAgents}), - ct_util:update_config(MgrAgentConfName, {snmp, NewSnmpVals}), + ct_config:update_config(MgrAgentConfName, {snmp, NewSnmpVals}), setup_managed_agents(ManagedAgents). %%% @spec register_usm_users(MgrAgentConfName, UsmUsers) -> ok | {error, Reason} @@ -361,7 +361,7 @@ register_agents(MgrAgentConfName, ManagedAgents) -> register_usm_users(MgrAgentConfName, UsmUsers) -> {snmp, SnmpVals} = ct:get_config(MgrAgentConfName), NewSnmpVals = lists:keyreplace(users, 1, SnmpVals, {usm_users, UsmUsers}), - ct_util:update_config(MgrAgentConfName, {snmp, NewSnmpVals}), + ct_config:update_config(MgrAgentConfName, {snmp, NewSnmpVals}), EngineID = ct:get_config({MgrAgentConfName, engine_id}, ?ENGINE_ID), setup_usm_users(UsmUsers, EngineID). @@ -376,7 +376,7 @@ unregister_users(MgrAgentConfName) -> ct:get_config({MgrAgentConfName, users})), {snmp, SnmpVals} = ct:get_config(MgrAgentConfName), NewSnmpVals = lists:keyreplace(users, 1, SnmpVals, {users, []}), - ct_util:update_config(MgrAgentConfName, {snmp, NewSnmpVals}), + ct_config:update_config(MgrAgentConfName, {snmp, NewSnmpVals}), takedown_users(Users). %%% @spec unregister_agents(MgrAgentConfName) -> ok | {error, Reason} @@ -393,7 +393,7 @@ unregister_agents(MgrAgentConfName) -> {snmp, SnmpVals} = ct:get_config(MgrAgentConfName), NewSnmpVals = lists:keyreplace(managed_agents, 1, SnmpVals, {managed_agents, []}), - ct_util:update_config(MgrAgentConfName, {snmp, NewSnmpVals}), + ct_config:update_config(MgrAgentConfName, {snmp, NewSnmpVals}), takedown_managed_agents(ManagedAgents). @@ -409,7 +409,7 @@ update_usm_users(MgrAgentConfName, UsmUsers) -> {snmp, SnmpVals} = ct:get_config(MgrAgentConfName), NewSnmpVals = lists:keyreplace(usm_users, 1, SnmpVals, {usm_users, UsmUsers}), - ct_util:update_config(MgrAgentConfName, {snmp, NewSnmpVals}), + ct_config:update_config(MgrAgentConfName, {snmp, NewSnmpVals}), EngineID = ct:get_config({MgrAgentConfName, engine_id}, ?ENGINE_ID), do_update_usm_users(UsmUsers, EngineID). diff --git a/lib/common_test/src/ct_ssh.erl b/lib/common_test/src/ct_ssh.erl index f2b25b1fcd..aebb28bc42 100644 --- a/lib/common_test/src/ct_ssh.erl +++ b/lib/common_test/src/ct_ssh.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009. All Rights Reserved. -%% +%% +%% 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% %% @@ -961,24 +961,25 @@ init(KeyOrName, {ConnType,Addr,Port}, AllOpts) -> ssh -> ssh:connect(Addr, Port, FinalOptions); sftp -> - ssh_sftp:connect(Addr, Port, FinalOptions) + ssh_sftp:start_channel(Addr, Port, FinalOptions) end, case Result of - {ok,SSHRef} -> + Error = {error,_} -> + Error; + Ok -> + SSHRef = element(2, Ok), log(heading(init,KeyOrName), "Opened ~w connection:\nHost: ~p (~p)\nUser: ~p\nPassword: ~p\n", [ConnType,Addr,Port,User,lists:duplicate(length(Password),$*)]), {ok,SSHRef,#state{ssh_ref=SSHRef, conn_type=ConnType, - target=KeyOrName}}; - Error -> - Error + target=KeyOrName}} end. %% @hidden handle_msg(sftp_connect, State) -> #state{ssh_ref=SSHRef, target=Target} = State, log(heading(sftp_connect,Target), "SSH Ref: ~p", [SSHRef]), - {ssh_sftp:connect(SSHRef),State}; + {ssh_sftp:start_channel(SSHRef),State}; handle_msg({session_open,TO}, State) -> #state{ssh_ref=SSHRef, target=Target} = State, @@ -1202,7 +1203,7 @@ terminate(SSHRef, State) -> sftp -> log(heading(disconnect_sftp,State#state.target), "SFTP Ref: ~p",[SSHRef]), - ssh_sftp:stop(SSHRef) + ssh_sftp:stop_channel(SSHRef) end. @@ -1213,7 +1214,6 @@ terminate(SSHRef, State) -> %%% do_recv_response(SSH, Chn, Data, End, Timeout) -> receive - {ssh_cm, SSH, {open,Chn,RemoteChn,{session}}} -> debug("RECVD open"), {ok,{open,Chn,RemoteChn,{session}}}; diff --git a/lib/common_test/src/ct_telnet_client.erl b/lib/common_test/src/ct_telnet_client.erl index 1a12c5e343..d703b39ac5 100644 --- a/lib/common_test/src/ct_telnet_client.erl +++ b/lib/common_test/src/ct_telnet_client.erl @@ -35,8 +35,6 @@ -export([open/1, open/2, open/3, open/4, close/1]). -export([send_data/2, get_data/1]). --define(DBG, false). - -define(TELNET_PORT, 23). -define(OPEN_TIMEOUT,10000). -define(IDLE_TIMEOUT,10000). @@ -287,35 +285,38 @@ get_subcmd([?SE | Rest], Acc) -> get_subcmd([Opt | Rest], Acc) -> get_subcmd(Rest, [Opt | Acc]). - +-ifdef(debug). dbg(_Str,_Args) -> - if ?DBG -> io:format(_Str,_Args); - true -> ok + io:format(_Str,_Args). + +cmd_dbg(_Cmd) -> + case _Cmd of + [?IAC|Cmd1] -> + cmd_dbg(Cmd1); + [Ctrl|Opts] -> + CtrlStr = + case Ctrl of + ?DO -> "DO"; + ?DONT -> "DONT"; + ?WILL -> "WILL"; + ?WONT -> "WONT"; + ?NOP -> "NOP"; + _ -> "CMD" + end, + Opts1 = + case Opts of + [Opt] -> Opt; + _ -> Opts + end, + io:format("~s(~w): ~w\n", [CtrlStr,Ctrl,Opts1]); + Any -> + io:format("Unexpected in cmd_dbg:~n~w~n",[Any]) end. +-else. +dbg(_Str,_Args) -> + ok. + cmd_dbg(_Cmd) -> - if ?DBG -> - case _Cmd of - [?IAC|Cmd1] -> - cmd_dbg(Cmd1); - [Ctrl|Opts] -> - CtrlStr = - case Ctrl of - ?DO -> "DO"; - ?DONT -> "DONT"; - ?WILL -> "WILL"; - ?WONT -> "WONT"; - ?NOP -> "NOP"; - _ -> "CMD" - end, - Opts1 = - case Opts of - [Opt] -> Opt; - _ -> Opts - end, - io:format("~s(~w): ~w\n", [CtrlStr,Ctrl,Opts1]); - Any -> - io:format("Unexpected in cmd_dbg:~n~w~n",[Any]) - end; - true -> ok - end. + ok. +-endif. diff --git a/lib/common_test/src/ct_testspec.erl b/lib/common_test/src/ct_testspec.erl index 4378ec5a52..f5069427a2 100644 --- a/lib/common_test/src/ct_testspec.erl +++ b/lib/common_test/src/ct_testspec.erl @@ -17,7 +17,7 @@ %% %CopyrightEnd% %% -%%% @doc Common Test Framework functions handlig test specifikations. +%%% @doc Common Test Framework functions handling test specifications. %%% %%% <p>This module exports functions that are used within CT to %%% scan and parse test specifikations.</p> @@ -185,7 +185,15 @@ prepare_cases(Node,Dir,Suite,Cases) -> {[{{Node,Dir},{Suite,all}}],SkipAll}; Skipped -> %% note: this adds a test even if only skip is specified - PrepC = lists:foldr(fun({C,{skip,_Cmt}},Acc) -> + PrepC = lists:foldr(fun({{G,Cs},{skip,_Cmt}}, Acc) when + is_atom(G) -> + case lists:keymember(G, 1, Cases) of + true -> + Acc; + false -> + [{skipped,G,Cs}|Acc] + end; + ({C,{skip,_Cmt}},Acc) -> case lists:member(C,Cases) of true -> Acc; @@ -194,7 +202,7 @@ prepare_cases(Node,Dir,Suite,Cases) -> end; (C,Acc) -> [C|Acc] end, [], Cases), - {{{Node,Dir},{Suite,PrepC}},Skipped} + {{{Node,Dir},{Suite,PrepC}},Skipped} end. get_skipped_suites(Node,Dir,Suites) -> @@ -210,7 +218,7 @@ get_skipped_cases(Node,Dir,Suite,Cases) -> case lists:keysearch(all,1,Cases) of {value,{all,{skip,Cmt}}} -> [{{Node,Dir},{Suite,Cmt}}]; - false -> + _ -> get_skipped_cases1(Node,Dir,Suite,Cases) end. @@ -270,33 +278,8 @@ collect_tests(Terms,TestSpec,Relaxed) -> put(relaxed,Relaxed), TestSpec1 = get_global(Terms,TestSpec), TestSpec2 = get_all_nodes(Terms,TestSpec1), - case catch evaluate(Terms,TestSpec2) of - {error,{Node,{M,F,A},Reason}} -> - io:format("Error! Common Test failed to evaluate ~w:~w/~w on ~w. " - "Reason: ~p~n~n", [M,F,A,Node,Reason]); - _ -> ok - end, - add_tests(Terms,TestSpec2). - -evaluate([{eval,NodeRef,{M,F,Args}}|Ts],Spec) -> - Node = ref2node(NodeRef,Spec#testspec.nodes), - case rpc:call(Node,M,F,Args) of - {badrpc,Reason} -> - throw({error,{Node,{M,F,length(Args)},Reason}}); - _ -> - ok - end, - evaluate(Ts,Spec); -evaluate([{eval,{M,F,Args}}|Ts],Spec) -> - case catch apply(M,F,Args) of - {'EXIT',Reason} -> - throw({error,{node(),{M,F,length(Args)},Reason}}); - _ -> - ok - end, - evaluate(Ts,Spec); -evaluate([],_Spec) -> - ok. + {Terms2, TestSpec3} = filter_init_terms(Terms, [], TestSpec2), + add_tests(Terms2,TestSpec3). get_global([{alias,Ref,Dir}|Ts],Spec=#testspec{alias=Refs}) -> get_global(Ts,Spec#testspec{alias=[{Ref,get_absdir(Dir,Spec)}|Refs]}); @@ -305,6 +288,26 @@ get_global([{node,Ref,Node}|Ts],Spec=#testspec{nodes=Refs}) -> get_global([_|Ts],Spec) -> get_global(Ts,Spec); get_global([],Spec) -> Spec. +get_absfile(Callback, FullName,#testspec{spec_dir=SpecDir}) -> + % we need to temporary switch to new cwd here, because + % otherwise config files cannot be found + {ok, OldWd} = file:get_cwd(), + ok = file:set_cwd(SpecDir), + R = Callback:check_parameter(FullName), + ok = file:set_cwd(OldWd), + case R of + {ok, {file, FullName}}-> + File = filename:basename(FullName), + Dir = get_absname(filename:dirname(FullName),SpecDir), + filename:join(Dir,File); + {ok, {config, FullName}}-> + FullName; + {error, {nofile, FullName}}-> + FullName; + {error, {wrong_config, FullName}}-> + FullName + end. + get_absfile(FullName,#testspec{spec_dir=SpecDir}) -> File = filename:basename(FullName), Dir = get_absname(filename:dirname(FullName),SpecDir), @@ -353,6 +356,68 @@ get_all_nodes([_|Ts],Spec) -> get_all_nodes([],Spec) -> Spec. +filter_init_terms([{init, InitOptions}|Ts], NewTerms, Spec)-> + filter_init_terms([{init, list_nodes(Spec), InitOptions}|Ts], NewTerms, Spec); +filter_init_terms([{init, NodeRef, InitOptions}|Ts], NewTerms, Spec) + when is_atom(NodeRef)-> + filter_init_terms([{init, [NodeRef], InitOptions}|Ts], NewTerms, Spec); +filter_init_terms([{init, NodeRefs, InitOption}|Ts], NewTerms, Spec) when is_tuple(InitOption) -> + filter_init_terms([{init, NodeRefs, [InitOption]}|Ts], NewTerms, Spec); +filter_init_terms([{init, [NodeRef|NodeRefs], InitOptions}|Ts], NewTerms, Spec=#testspec{init=InitData})-> + NodeStartOptions = case lists:keyfind(node_start, 1, InitOptions) of + {node_start, NSOptions}-> + case lists:keyfind(callback_module, 1, NSOptions) of + {callback_module, _Callback}-> + NSOptions; + false-> + [{callback_module, ct_slave}|NSOptions] + end; + false-> + [] + end, + EvalTerms = case lists:keyfind(eval, 1, InitOptions) of + {eval, MFA} when is_tuple(MFA)-> + [MFA]; + {eval, MFAs} when is_list(MFAs)-> + MFAs; + false-> + [] + end, + Node = ref2node(NodeRef,Spec#testspec.nodes), + InitData2 = add_option({node_start, NodeStartOptions}, Node, InitData, true), + InitData3 = add_option({eval, EvalTerms}, Node, InitData2, false), + filter_init_terms([{init, NodeRefs, InitOptions}|Ts], NewTerms, Spec#testspec{init=InitData3}); +filter_init_terms([{init, [], _}|Ts], NewTerms, Spec)-> + filter_init_terms(Ts, NewTerms, Spec); +filter_init_terms([Term|Ts], NewTerms, Spec)-> + filter_init_terms(Ts, [Term|NewTerms], Spec); +filter_init_terms([], NewTerms, Spec)-> + {lists:reverse(NewTerms), Spec}. + +add_option([], _, List, _)-> + List; +add_option({Key, Value}, Node, List, WarnIfExists) when is_list(Value)-> + OldOptions = case lists:keyfind(Node, 1, List) of + {Node, Options}-> + Options; + false-> + [] + end, + NewOption = case lists:keyfind(Key, 1, OldOptions) of + {Key, OldOption} when WarnIfExists, OldOption/=[]-> + io:format("There is an option ~w=~w already defined for node ~p, skipping new ~w~n", + [Key, OldOption, Node, Value]), + OldOption; + {Key, OldOption}-> + OldOption ++ Value; + false-> + Value + end, + lists:keystore(Node, 1, List, + {Node, lists:keystore(Key, 1, OldOptions, {Key, NewOption})}); +add_option({Key, Value}, Node, List, WarnIfExists)-> + add_option({Key, [Value]}, Node, List, WarnIfExists). + save_nodes(Nodes,Spec=#testspec{nodes=NodeRefs}) -> NodeRefs1 = lists:foldr(fun(all_nodes,NR) -> @@ -375,6 +440,15 @@ save_nodes(Nodes,Spec=#testspec{nodes=NodeRefs}) -> list_nodes(#testspec{nodes=NodeRefs}) -> lists:map(fun({_Ref,Node}) -> Node end, NodeRefs). + + +%% --------------------------------------------------------- +%% / \ +%% | When adding tests, remember to update valid_terms/0 also! | +%% \ / +%% --------------------------------------------------------- + + %% Associate a "global" logdir with all nodes %% except those with specific logdir, e.g: %% ["/tmp/logdir",{ct1@finwe,"/tmp/logdir2"}] @@ -400,6 +474,24 @@ add_tests([{logdir,Node,Dir}|Ts],Spec) -> add_tests([{logdir,Dir}|Ts],Spec) -> add_tests([{logdir,all_nodes,Dir}|Ts],Spec); +%% --- label --- +add_tests([{label,all_nodes,Lbl}|Ts],Spec) -> + Labels = Spec#testspec.label, + Tests = [{label,N,Lbl} || N <- list_nodes(Spec), + lists:keymember(ref2node(N,Spec#testspec.nodes), + 1,Labels) == false], + add_tests(Tests++Ts,Spec); +add_tests([{label,Nodes,Lbl}|Ts],Spec) when is_list(Nodes) -> + Ts1 = separate(Nodes,label,[Lbl],Ts,Spec#testspec.nodes), + add_tests(Ts1,Spec); +add_tests([{label,Node,Lbl}|Ts],Spec) -> + Labels = Spec#testspec.label, + Labels1 = [{ref2node(Node,Spec#testspec.nodes),Lbl} | + lists:keydelete(ref2node(Node,Spec#testspec.nodes),1,Labels)], + add_tests(Ts,Spec#testspec{label=Labels1}); +add_tests([{label,Lbl}|Ts],Spec) -> + add_tests([{label,all_nodes,Lbl}|Ts],Spec); + %% --- cover --- add_tests([{cover,all_nodes,File}|Ts],Spec) -> Tests = lists:map(fun(N) -> {cover,N,File} end, list_nodes(Spec)), @@ -415,6 +507,36 @@ add_tests([{cover,Node,File}|Ts],Spec) -> add_tests([{cover,File}|Ts],Spec) -> add_tests([{cover,all_nodes,File}|Ts],Spec); +%% --- multiply_timetraps --- +add_tests([{multiply_timetraps,all_nodes,MT}|Ts],Spec) -> + Tests = lists:map(fun(N) -> {multiply_timetraps,N,MT} end, list_nodes(Spec)), + add_tests(Tests++Ts,Spec); +add_tests([{multiply_timetraps,Nodes,MT}|Ts],Spec) when is_list(Nodes) -> + Ts1 = separate(Nodes,multiply_timetraps,[MT],Ts,Spec#testspec.nodes), + add_tests(Ts1,Spec); +add_tests([{multiply_timetraps,Node,MT}|Ts],Spec) -> + MTs = Spec#testspec.multiply_timetraps, + MTs1 = [{ref2node(Node,Spec#testspec.nodes),MT} | + lists:keydelete(ref2node(Node,Spec#testspec.nodes),1,MTs)], + add_tests(Ts,Spec#testspec{multiply_timetraps=MTs1}); +add_tests([{multiply_timetraps,MT}|Ts],Spec) -> + add_tests([{multiply_timetraps,all_nodes,MT}|Ts],Spec); + +%% --- scale_timetraps --- +add_tests([{scale_timetraps,all_nodes,ST}|Ts],Spec) -> + Tests = lists:map(fun(N) -> {scale_timetraps,N,ST} end, list_nodes(Spec)), + add_tests(Tests++Ts,Spec); +add_tests([{scale_timetraps,Nodes,ST}|Ts],Spec) when is_list(Nodes) -> + Ts1 = separate(Nodes,scale_timetraps,[ST],Ts,Spec#testspec.nodes), + add_tests(Ts1,Spec); +add_tests([{scale_timetraps,Node,ST}|Ts],Spec) -> + STs = Spec#testspec.scale_timetraps, + STs1 = [{ref2node(Node,Spec#testspec.nodes),ST} | + lists:keydelete(ref2node(Node,Spec#testspec.nodes),1,STs)], + add_tests(Ts,Spec#testspec{scale_timetraps=STs1}); +add_tests([{scale_timetraps,ST}|Ts],Spec) -> + add_tests([{scale_timetraps,all_nodes,ST}|Ts],Spec); + %% --- config --- add_tests([{config,all_nodes,Files}|Ts],Spec) -> Tests = lists:map(fun(N) -> {config,N,Files} end, list_nodes(Spec)), @@ -434,6 +556,27 @@ add_tests([{config,Node,F}|Ts],Spec) -> add_tests([{config,Files}|Ts],Spec) -> add_tests([{config,all_nodes,Files}|Ts],Spec); + +%% --- userconfig --- +add_tests([{userconfig,all_nodes,CBF}|Ts],Spec) -> + Tests = lists:map(fun(N) -> {userconfig,N,CBF} end, list_nodes(Spec)), + add_tests(Tests++Ts,Spec); +add_tests([{userconfig,Nodes,CBF}|Ts],Spec) when is_list(Nodes) -> + Ts1 = separate(Nodes,userconfig,[CBF],Ts,Spec#testspec.nodes), + add_tests(Ts1,Spec); +add_tests([{userconfig,Node,[{Callback, Config}|CBF]}|Ts],Spec) -> + Cfgs = Spec#testspec.userconfig, + Node1 = ref2node(Node,Spec#testspec.nodes), + add_tests([{userconfig,Node,CBF}|Ts], + Spec#testspec{userconfig=[{Node1,{Callback, + get_absfile(Callback, Config ,Spec)}}|Cfgs]}); +add_tests([{userconfig,_Node,[]}|Ts],Spec) -> + add_tests(Ts,Spec); +add_tests([{userconfig,Node,CBF}|Ts],Spec) -> + add_tests([{userconfig,Node,[CBF]}|Ts],Spec); +add_tests([{userconfig,CBF}|Ts],Spec) -> + add_tests([{userconfig,all_nodes,CBF}|Ts],Spec); + %% --- event_handler --- add_tests([{event_handler,all_nodes,Hs}|Ts],Spec) -> Tests = lists:map(fun(N) -> {event_handler,N,Hs,[]} end, list_nodes(Spec)), @@ -516,6 +659,38 @@ add_tests([{suites,Node,Dir,Ss}|Ts],Spec) -> Ss,Tests), add_tests(Ts,Spec#testspec{tests=Tests1}); +%% --- groups --- +%% Later make it possible to specify group execution properties +%% that will override thse in the suite. Also make it possible +%% create dynamic groups in specification, i.e. to group test cases +%% by means of groups defined only in the test specification. +add_tests([{groups,all_nodes,Dir,Suite,Gs}|Ts],Spec) -> + add_tests([{groups,list_nodes(Spec),Dir,Suite,Gs}|Ts],Spec); +add_tests([{groups,all_nodes,Dir,Suite,Gs,{cases,TCs}}|Ts],Spec) -> + add_tests([{groups,list_nodes(Spec),Dir,Suite,Gs,{cases,TCs}}|Ts],Spec); +add_tests([{groups,Dir,Suite,Gs}|Ts],Spec) -> + add_tests([{groups,all_nodes,Dir,Suite,Gs}|Ts],Spec); +add_tests([{groups,Dir,Suite,Gs,{cases,TCs}}|Ts],Spec) -> + add_tests([{groups,all_nodes,Dir,Suite,Gs,{cases,TCs}}|Ts],Spec); +add_tests([{groups,Nodes,Dir,Suite,Gs}|Ts],Spec) when is_list(Nodes) -> + Ts1 = separate(Nodes,groups,[Dir,Suite,Gs],Ts,Spec#testspec.nodes), + add_tests(Ts1,Spec); +add_tests([{groups,Nodes,Dir,Suite,Gs,{cases,TCs}}|Ts],Spec) when is_list(Nodes) -> + Ts1 = separate(Nodes,groups,[Dir,Suite,Gs,{cases,TCs}],Ts,Spec#testspec.nodes), + add_tests(Ts1,Spec); +add_tests([{groups,Node,Dir,Suite,Gs}|Ts],Spec) -> + Tests = Spec#testspec.tests, + Tests1 = insert_groups(ref2node(Node,Spec#testspec.nodes), + ref2dir(Dir,Spec#testspec.alias), + Suite,Gs,all,Tests), + add_tests(Ts,Spec#testspec{tests=Tests1}); +add_tests([{groups,Node,Dir,Suite,Gs,{cases,TCs}}|Ts],Spec) -> + Tests = Spec#testspec.tests, + Tests1 = insert_groups(ref2node(Node,Spec#testspec.nodes), + ref2dir(Dir,Spec#testspec.alias), + Suite,Gs,TCs,Tests), + add_tests(Ts,Spec#testspec{tests=Tests1}); + %% --- cases --- add_tests([{cases,all_nodes,Dir,Suite,Cs}|Ts],Spec) -> add_tests([{cases,list_nodes(Spec),Dir,Suite,Cs}|Ts],Spec); @@ -546,6 +721,34 @@ add_tests([{skip_suites,Node,Dir,Ss,Cmt}|Ts],Spec) -> Ss,Cmt,Tests), add_tests(Ts,Spec#testspec{tests=Tests1}); +%% --- skip_groups --- +add_tests([{skip_groups,all_nodes,Dir,Suite,Gs,Cmt}|Ts],Spec) -> + add_tests([{skip_groups,list_nodes(Spec),Dir,Suite,Gs,Cmt}|Ts],Spec); +add_tests([{skip_groups,all_nodes,Dir,Suite,Gs,{cases,TCs},Cmt}|Ts],Spec) -> + add_tests([{skip_groups,list_nodes(Spec),Dir,Suite,Gs,{cases,TCs},Cmt}|Ts],Spec); +add_tests([{skip_groups,Dir,Suite,Gs,Cmt}|Ts],Spec) -> + add_tests([{skip_groups,all_nodes,Dir,Suite,Gs,Cmt}|Ts],Spec); +add_tests([{skip_groups,Dir,Suite,Gs,{cases,TCs},Cmt}|Ts],Spec) -> + add_tests([{skip_groups,all_nodes,Dir,Suite,Gs,{cases,TCs},Cmt}|Ts],Spec); +add_tests([{skip_groups,Nodes,Dir,Suite,Gs,Cmt}|Ts],Spec) when is_list(Nodes) -> + Ts1 = separate(Nodes,skip_groups,[Dir,Suite,Gs,Cmt],Ts,Spec#testspec.nodes), + add_tests(Ts1,Spec); +add_tests([{skip_groups,Nodes,Dir,Suite,Gs,{cases,TCs},Cmt}|Ts],Spec) when is_list(Nodes) -> + Ts1 = separate(Nodes,skip_groups,[Dir,Suite,Gs,{cases,TCs},Cmt],Ts,Spec#testspec.nodes), + add_tests(Ts1,Spec); +add_tests([{skip_groups,Node,Dir,Suite,Gs,Cmt}|Ts],Spec) -> + Tests = Spec#testspec.tests, + Tests1 = skip_groups(ref2node(Node,Spec#testspec.nodes), + ref2dir(Dir,Spec#testspec.alias), + Suite,Gs,all,Cmt,Tests), + add_tests(Ts,Spec#testspec{tests=Tests1}); +add_tests([{skip_groups,Node,Dir,Suite,Gs,{cases,TCs},Cmt}|Ts],Spec) -> + Tests = Spec#testspec.tests, + Tests1 = skip_groups(ref2node(Node,Spec#testspec.nodes), + ref2dir(Dir,Spec#testspec.alias), + Suite,Gs,TCs,Cmt,Tests), + add_tests(Ts,Spec#testspec{tests=Tests1}); + %% --- skip_cases --- add_tests([{skip_cases,all_nodes,Dir,Suite,Cs,Cmt}|Ts],Spec) -> add_tests([{skip_cases,list_nodes(Spec),Dir,Suite,Cs,Cmt}|Ts],Spec); @@ -614,8 +817,11 @@ separate([],_,_,_) -> %% Representation: -%% {{Node,Dir},[{Suite1,[case11,case12,...]},{Suite2,[case21,case22,...]},...]} -%% {{Node,Dir},[{Suite1,{skip,Cmt}},{Suite2,[{case21,{skip,Cmt}},case22,...]},...]} +%% {{Node,Dir},[{Suite1,[GrOrCase11,GrOrCase12,...]}, +%% {Suite2,[GrOrCase21,GrOrCase22,...]},...]} +%% {{Node,Dir},[{Suite1,{skip,Cmt}}, +%% {Suite2,[{GrOrCase21,{skip,Cmt}},GrOrCase22,...]},...]} +%% GrOrCase = {GroupName,[Case1,Case2,...]} | Case insert_suites(Node,Dir,[S|Ss],Tests) -> Tests1 = insert_cases(Node,Dir,S,all,Tests), @@ -625,6 +831,54 @@ insert_suites(_Node,_Dir,[],Tests) -> insert_suites(Node,Dir,S,Tests) -> insert_suites(Node,Dir,[S],Tests). +insert_groups(Node,Dir,Suite,Group,Cases,Tests) when is_atom(Group) -> + insert_groups(Node,Dir,Suite,[Group],Cases,Tests); +insert_groups(Node,Dir,Suite,Groups,Cases,Tests) when + ((Cases == all) or is_list(Cases)) and is_list(Groups) -> + case lists:keysearch({Node,Dir},1,Tests) of + {value,{{Node,Dir},[{all,_}]}} -> + Tests; + {value,{{Node,Dir},Suites0}} -> + Suites1 = insert_groups1(Suite, + [{Gr,Cases} || Gr <- Groups], + Suites0), + insert_in_order({{Node,Dir},Suites1},Tests); + false -> + Groups1 = [{Gr,Cases} || Gr <- Groups], + insert_in_order({{Node,Dir},[{Suite,Groups1}]},Tests) + end; +insert_groups(Node,Dir,Suite,Groups,Case,Tests) when is_atom(Case) -> + Cases = if Case == all -> all; true -> [Case] end, + insert_groups(Node,Dir,Suite,Groups,Cases,Tests). + +insert_groups1(_Suite,_Groups,all) -> + all; +insert_groups1(Suite,Groups,Suites0) -> + case lists:keysearch(Suite,1,Suites0) of + {value,{Suite,all}} -> + Suites0; + {value,{Suite,GrAndCases0}} -> + GrAndCases = insert_groups2(Groups,GrAndCases0), + insert_in_order({Suite,GrAndCases},Suites0); + false -> + insert_in_order({Suite,Groups},Suites0) + end. + +insert_groups2(_Groups,all) -> + all; +insert_groups2([Group={GrName,Cases}|Groups],GrAndCases) -> + case lists:keysearch(GrName,1,GrAndCases) of + {value,{GrName,all}} -> + GrAndCases; + {value,{GrName,Cases0}} -> + Cases1 = insert_in_order(Cases,Cases0), + insert_groups2(Groups,insert_in_order({GrName,Cases1},GrAndCases)); + false -> + insert_groups2(Groups,insert_in_order(Group,GrAndCases)) + end; +insert_groups2([],GrAndCases) -> + GrAndCases. + insert_cases(Node,Dir,Suite,Cases,Tests) when is_list(Cases) -> case lists:keysearch({Node,Dir},1,Tests) of {value,{{Node,Dir},[{all,_}]}} -> @@ -659,6 +913,40 @@ skip_suites(_Node,_Dir,[],_Cmt,Tests) -> skip_suites(Node,Dir,S,Cmt,Tests) -> skip_suites(Node,Dir,[S],Cmt,Tests). +skip_groups(Node,Dir,Suite,Group,all,Cmt,Tests) when is_atom(Group) -> + skip_groups(Node,Dir,Suite,[Group],all,Cmt,Tests); +skip_groups(Node,Dir,Suite,Group,Cases,Cmt,Tests) when is_atom(Group) -> + skip_groups(Node,Dir,Suite,[Group],Cases,Cmt,Tests); +skip_groups(Node,Dir,Suite,Groups,Case,Cmt,Tests) when is_atom(Case), + Case =/= all -> + skip_groups(Node,Dir,Suite,Groups,[Case],Cmt,Tests); +skip_groups(Node,Dir,Suite,Groups,Cases,Cmt,Tests) when + ((Cases == all) or is_list(Cases)) and is_list(Groups) -> + Suites = + case lists:keysearch({Node,Dir},1,Tests) of + {value,{{Node,Dir},Suites0}} -> + Suites0; + false -> + [] + end, + Suites1 = skip_groups1(Suite,[{Gr,Cases} || Gr <- Groups],Cmt,Suites), + insert_in_order({{Node,Dir},Suites1},Tests); +skip_groups(Node,Dir,Suite,Groups,Case,Cmt,Tests) when is_atom(Case) -> + Cases = if Case == all -> all; true -> [Case] end, + skip_groups(Node,Dir,Suite,Groups,Cases,Cmt,Tests). + +skip_groups1(Suite,Groups,Cmt,Suites0) -> + SkipGroups = lists:map(fun(Group) -> + {Group,{skip,Cmt}} + end,Groups), + case lists:keysearch(Suite,1,Suites0) of + {value,{Suite,GrAndCases0}} -> + GrAndCases1 = GrAndCases0 ++ SkipGroups, + insert_in_order({Suite,GrAndCases1},Suites0); + false -> + insert_in_order({Suite,SkipGroups},Suites0) + end. + skip_cases(Node,Dir,Suite,Cases,Cmt,Tests) when is_list(Cases) -> Suites = case lists:keysearch({Node,Dir},1,Tests) of @@ -753,21 +1041,34 @@ valid_terms() -> {cover,3}, {config,2}, {config,3}, + {userconfig,2}, + {userconfig,3}, {alias,3}, {logdir,2}, {logdir,3}, + {label,2}, + {label,3}, {event_handler,2}, {event_handler,3}, {event_handler,4}, + {multiply_timetraps,2}, + {multiply_timetraps,3}, + {scale_timetraps,2}, + {scale_timetraps,3}, {include,2}, {include,3}, - {suites,3}, {suites,4}, + {groups,4}, + {groups,5}, + {groups,6}, {cases,4}, {cases,5}, {skip_suites,4}, {skip_suites,5}, + {skip_groups,5}, + {skip_groups,6}, + {skip_groups,7}, {skip_cases,5}, {skip_cases,6} ]. @@ -816,7 +1117,3 @@ common_letters([L|Ls],Term,Count) -> end; common_letters([],_,Count) -> Count. - - - - diff --git a/lib/common_test/src/ct_util.erl b/lib/common_test/src/ct_util.erl index ba3d789f8d..0a434666fa 100644 --- a/lib/common_test/src/ct_util.erl +++ b/lib/common_test/src/ct_util.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -30,10 +30,7 @@ -export([register_connection/4,unregister_connection/1, does_connection_exist/3,get_key_from_name/1]). --export([require/1, require/2, get_config/1, get_config/2, get_config/3, - set_default_config/2, set_default_config/3, delete_default_config/1, - get_all_config/0, update_config/2, - release_allocated/0, close_connections/0]). +-export([close_connections/0]). -export([save_suite_data/3, save_suite_data/2, read_suite_data/1, delete_suite_data/0, delete_suite_data/1, match_delete_suite_data/1, @@ -46,6 +43,8 @@ silence_all_connections/0, silence_connections/1, is_silenced/1, reset_silent_connections/0]). +-export([get_mode/0, create_table/3, read_opts/0]). + -export([set_cwd/1, reset_cwd/0]). -export([parse_table/1]). @@ -56,23 +55,15 @@ -export([is_test_dir/1, get_testdir/2]). --export([encrypt_config_file/2, encrypt_config_file/3, - decrypt_config_file/2, decrypt_config_file/3]). - --export([kill_attached/2, get_attached/1]). +-export([kill_attached/2, get_attached/1, ct_make_ref/0]). -export([warn_duplicates/1]). -include("ct_event.hrl"). -include("ct_util.hrl"). --record(ct_conf,{key,value,ref,name='_UNDEF',default=false}). -%% default = {true,suite} | {true,testcase} | false - -record(suite_data, {key,name,value}). --define(cryptfile, ".ct_config.crypt"). - %%%----------------------------------------------------------------- %%% @spec start(Mode) -> Pid | exit(Error) %%% Mode = normal | interactive @@ -119,7 +110,6 @@ start(Mode,LogDir) -> do_start(Parent,Mode,LogDir) -> process_flag(trap_exit,true), register(ct_util_server,self()), - create_table(?attr_table,bag,#ct_conf.key), create_table(?conn_table,#conn.handle), create_table(?board_table,2), create_table(?suite_table,#suite_data.key), @@ -135,7 +125,6 @@ do_start(Parent,Mode,LogDir) -> Parent ! {self(),Error}, exit(Error) end, - %% start an event manager (if not already started by master) case ct_event:start_link() of {error,{already_started,_}} -> @@ -148,38 +137,34 @@ do_start(Parent,Mode,LogDir) -> ct_event:add_handler([{vts,VtsPid}]) end end, - case read_config_files(Opts) of - ok -> - %% add user handlers - case lists:keysearch(event_handler,1,Opts) of - {value,{_,Handlers}} -> - Add = fun({H,Args}) -> - case catch gen_event:add_handler(?CT_EVMGR_REF,H,Args) of - ok -> ok; - {'EXIT',Why} -> exit(Why); - Other -> exit({event_handler,Other}) - end - end, - case catch lists:foreach(Add,Handlers) of - {'EXIT',Reason} -> - Parent ! {self(),Reason}; - _ -> - ok - end; - false -> + %% start ct_config server + ct_config:start(Mode), + %% add user event handlers + case lists:keysearch(event_handler,1,Opts) of + {value,{_,Handlers}} -> + Add = fun({H,Args}) -> + case catch gen_event:add_handler(?CT_EVMGR_REF,H,Args) of + ok -> ok; + {'EXIT',Why} -> exit(Why); + Other -> exit({event_handler,Other}) + end + end, + case catch lists:foreach(Add,Handlers) of + {'EXIT',Reason} -> + Parent ! {self(),Reason}; + _ -> ok - end, - {StartTime,TestLogDir} = ct_logs:init(Mode), - ct_event:notify(#event{name=test_start, - node=node(), - data={StartTime, - lists:flatten(TestLogDir)}}), - Parent ! {self(),started}, - loop(Mode,[],StartDir); - ReadError -> - Parent ! {self(),ReadError}, - exit(ReadError) - end. + end; + false -> + ok + end, + {StartTime,TestLogDir} = ct_logs:init(Mode), + ct_event:notify(#event{name=test_start, + node=node(), + data={StartTime, + lists:flatten(TestLogDir)}}), + Parent ! {self(),started}, + loop(Mode,[],StartDir). create_table(TableName,KeyPos) -> create_table(TableName,set,KeyPos). @@ -197,106 +182,6 @@ read_opts() -> {error,{bad_installation,Error}} end. -read_config_files(Opts) -> - ConfigFiles = - lists:foldl(fun({config,Files},Acc) -> - Acc ++ Files; - (_,Acc) -> - Acc - end,[],Opts), - read_config_files1(ConfigFiles). - -read_config_files1([ConfigFile|Files]) -> - case file:consult(ConfigFile) of - {ok,Config} -> - set_config(Config), - read_config_files1(Files); - {error,enoent} -> - {user_error,{config_file_error,ConfigFile,enoent}}; - {error,Reason} -> - Key = - case application:get_env(common_test, decrypt) of - {ok,KeyOrFile} -> - case KeyOrFile of - {key,K} -> - K; - {file,F} -> - get_crypt_key_from_file(F) - end; - _ -> - get_crypt_key_from_file() - end, - case Key of - {error,no_crypt_file} -> - {user_error,{config_file_error,ConfigFile,Reason}}; - {error,CryptError} -> - {user_error,{decrypt_file_error,ConfigFile,CryptError}}; - _ when is_list(Key) -> - case decrypt_config_file(ConfigFile, undefined, {key,Key}) of - {ok,CfgBin} -> - case read_config_terms(CfgBin) of - {error,ReadFail} -> - {user_error,{config_file_error,ConfigFile,ReadFail}}; - Config -> - set_config(Config), - read_config_files1(Files) - end; - {error,DecryptFail} -> - {user_error,{decrypt_config_error,ConfigFile,DecryptFail}} - end; - _ -> - {user_error,{bad_decrypt_key,ConfigFile,Key}} - end - end; -read_config_files1([]) -> - ok. - -read_config_terms(Bin) when is_binary(Bin) -> - case catch binary_to_list(Bin) of - {'EXIT',_} -> - {error,invalid_textfile}; - Lines -> - read_config_terms(Lines) - end; -read_config_terms(Lines) when is_list(Lines) -> - read_config_terms1(erl_scan:tokens([], Lines, 0), 1, [], []). - -read_config_terms1({done,{ok,Ts,EL},Rest}, L, Terms, _) -> - case erl_parse:parse_term(Ts) of - {ok,Term} when Rest == [] -> - lists:reverse([Term|Terms]); - {ok,Term} -> - read_config_terms1(erl_scan:tokens([], Rest, 0), - EL+1, [Term|Terms], Rest); - _ -> - {error,{bad_term,{L,EL}}} - end; -read_config_terms1({done,{eof,_},_}, _, Terms, Rest) when Rest == [] -> - lists:reverse(Terms); -read_config_terms1({done,{eof,EL},_}, L, _, _) -> - {error,{bad_term,{L,EL}}}; -read_config_terms1({done,{error,Info,EL},_}, L, _, _) -> - {error,{Info,{L,EL}}}; -read_config_terms1({more,_}, L, Terms, Rest) -> - case string:tokens(Rest, [$\n,$\r,$\t]) of - [] -> - lists:reverse(Terms); - _ -> - {error,{bad_term,L}} - end. - -set_default_config(NewConfig, Scope) -> - call({set_default_config, {NewConfig, Scope}}). - -set_default_config(Name, NewConfig, Scope) -> - call({set_default_config, {Name, NewConfig, Scope}}). - -delete_default_config(Scope) -> - call({delete_default_config, Scope}). - -update_config(Name, Config) -> - call({update_config, {Name, Config}}). - save_suite_data(Key, Value) -> call({save_suite_data, {Key, undefined, Value}}). @@ -342,26 +227,6 @@ loop(Mode,TestData,StartDir) -> ct_logs:make_last_run_index(), return(From,ok), loop(Mode,TestData,StartDir); - {{require,Name,Tag,SubTags},From} -> - Result = do_require(Name,Tag,SubTags), - return(From,Result), - loop(Mode,TestData,StartDir); - {{set_default_config,{Config,Scope}},From} -> - set_config(Config,{true,Scope}), - return(From,ok), - loop(Mode,TestData,StartDir); - {{set_default_config,{Name,Config,Scope}},From} -> - set_config(Name,Config,{true,Scope}), - return(From,ok), - loop(Mode,TestData,StartDir); - {{delete_default_config,Scope},From} -> - delete_config({true,Scope}), - return(From,ok), - loop(Mode,TestData,StartDir); - {{update_config,{Name,NewConfig}},From} -> - update_conf(Name,NewConfig), - return(From,ok), - loop(Mode,TestData,StartDir); {{save_suite_data,{Key,Name,Value}},From} -> ets:insert(?suite_table, #suite_data{key=Key, name=Name, @@ -434,14 +299,14 @@ loop(Mode,TestData,StartDir) -> ct_event:sync_notify(#event{name=test_done, node=node(), data=Time}), - ets:delete(?attr_table), close_connections(ets:tab2list(?conn_table)), ets:delete(?conn_table), ets:delete(?board_table), ets:delete(?suite_table), ct_logs:close(How), - file:set_cwd(StartDir), ct_event:stop(), + ct_config:stop(), + file:set_cwd(StartDir), return(From,ok); {get_mode,From} -> return(From,Mode), @@ -463,6 +328,8 @@ close_connections([#conn{handle=Handle,callback=CB}|Conns]) -> close_connections([]) -> ok. +get_key_from_name(Name)-> + ct_config:get_key_from_name(Name). %%%----------------------------------------------------------------- %%% @spec register_connection(TargetName,Address,Callback,Handle) -> @@ -480,7 +347,7 @@ close_connections([]) -> %%% test is finished by calling <code>Callback:close/1</code>.</p> register_connection(TargetName,Address,Callback,Handle) -> TargetRef = - case get_ref_from_name(TargetName) of + case ct_config:get_ref_from_name(TargetName) of {ok,Ref} -> Ref; _ -> @@ -518,7 +385,7 @@ unregister_connection(Handle) -> %%% %%% @doc Check if a connection already exists. does_connection_exist(TargetName,Address,Callback) -> - case get_ref_from_name(TargetName) of + case ct_config:get_ref_from_name(TargetName) of {ok,TargetRef} -> case ets:select(?conn_table,[{#conn{handle='$1', targetref=TargetRef, @@ -548,7 +415,7 @@ does_connection_exist(TargetName,Address,Callback) -> %%% @doc Return all connections for the <code>Callback</code> on the %%% given target (<code>TargetName</code>). get_connections(TargetName,Callback) -> - case get_ref_from_name(TargetName) of + case ct_config:get_ref_from_name(TargetName) of {ok,Ref} -> {ok,ets:select(?conn_table,[{#conn{handle='$1', address='$2', @@ -568,250 +435,11 @@ get_target_name(ConnPid) -> [], ['$1']}]) of [TargetRef] -> - get_name_from_ref(TargetRef); + ct_config:get_name_from_ref(TargetRef); [] -> {error,{unknown_connection,ConnPid}} end. - -%%%----------------------------------------------------------------- -%%% @hidden -%%% @equiv ct:require/1 -require(Key) when is_atom(Key) -> - require({Key,[]}); -require({Key,SubKeys}) when is_atom(Key) -> - allocate('_UNDEF',Key,to_list(SubKeys)); -require(Key) -> - {error,{invalid,Key}}. - - -%%%----------------------------------------------------------------- -%%% @hidden -%%% @equiv ct:require/2 -require(Name,Key) when is_atom(Key) -> - require(Name,{Key,[]}); -require(Name,{Key,SubKeys}) when is_atom(Name), is_atom(Key) -> - call({require,Name,Key,to_list(SubKeys)}); -require(Name,Keys) -> - {error,{invalid,{Name,Keys}}}. - -to_list(X) when is_list(X) -> X; -to_list(X) -> [X]. - -do_require(Name,Key,SubKeys) when is_list(SubKeys) -> - case get_key_from_name(Name) of - {error,_} -> - allocate(Name,Key,SubKeys); - {ok,Key} -> - %% already allocated - check that it has all required subkeys - Vals = [Val || {_Ref,Val} <- lookup_name(Name)], - case get_subconfig(SubKeys,Vals) of - {ok,_SubMapped} -> - ok; - Error -> - Error - end; - {ok,OtherKey} -> - {error,{name_in_use,Name,OtherKey}} - end. - -allocate(Name,Key,SubKeys) -> - case ets:match_object(?attr_table,#ct_conf{key=Key,name='_UNDEF',_='_'}) of - [] -> - {error,{not_available,Key}}; - Available -> - case allocate_subconfig(Name,SubKeys,Available,false) of - ok -> - ok; - Error -> - Error - end - end. - -allocate_subconfig(Name,SubKeys,[C=#ct_conf{value=Value}|Rest],Found) -> - case do_get_config(SubKeys,Value,[]) of - {ok,_SubMapped} -> - ets:insert(?attr_table,C#ct_conf{name=Name}), - allocate_subconfig(Name,SubKeys,Rest,true); - _Error -> - allocate_subconfig(Name,SubKeys,Rest,Found) - end; -allocate_subconfig(_Name,_SubKeys,[],true) -> - ok; -allocate_subconfig(_Name,SubKeys,[],false) -> - {error,{not_available,SubKeys}}. - - - - -%%%----------------------------------------------------------------- -%%% @hidden -%%% @equiv ct:get_config/1 -get_config(KeyOrName) -> - get_config(KeyOrName,undefined,[]). - -%%%----------------------------------------------------------------- -%%% @hidden -%%% @equiv ct:get_config/2 -get_config(KeyOrName,Default) -> - get_config(KeyOrName,Default,[]). - -%%%----------------------------------------------------------------- -%%% @hidden -%%% @equiv ct:get_config/3 -get_config(KeyOrName,Default,Opts) when is_atom(KeyOrName) -> - case lookup_config(KeyOrName) of - [] -> - Default; - [{_Ref,Val}|_] = Vals -> - case {lists:member(all,Opts),lists:member(element,Opts)} of - {true,true} -> - [{KeyOrName,V} || {_R,V} <- lists:sort(Vals)]; - {true,false} -> - [V || {_R,V} <- lists:sort(Vals)]; - {false,true} -> - {KeyOrName,Val}; - {false,false} -> - Val - end - end; - -get_config({KeyOrName,SubKey},Default,Opts) -> - case lookup_config(KeyOrName) of - [] -> - Default; - Vals -> - Vals1 = case [Val || {_Ref,Val} <- lists:sort(Vals)] of - Result=[L|_] when is_list(L) -> - case L of - [{_,_}|_] -> - Result; - _ -> - [] - end; - _ -> - [] - end, - case get_subconfig([SubKey],Vals1,[],Opts) of - {ok,[{_,SubVal}|_]=SubVals} -> - case {lists:member(all,Opts),lists:member(element,Opts)} of - {true,true} -> - [{{KeyOrName,SubKey},Val} || {_,Val} <- SubVals]; - {true,false} -> - [Val || {_SubKey,Val} <- SubVals]; - {false,true} -> - {{KeyOrName,SubKey},SubVal}; - {false,false} -> - SubVal - end; - _ -> - Default - end - end. - - -get_subconfig(SubKeys,Values) -> - get_subconfig(SubKeys,Values,[],[]). - -get_subconfig(SubKeys,[Value|Rest],Mapped,Opts) -> - case do_get_config(SubKeys,Value,[]) of - {ok,SubMapped} -> - case lists:member(all,Opts) of - true -> - get_subconfig(SubKeys,Rest,Mapped++SubMapped,Opts); - false -> - {ok,SubMapped} - end; - _Error -> - get_subconfig(SubKeys,Rest,Mapped,Opts) - end; -get_subconfig(SubKeys,[],[],_) -> - {error,{not_available,SubKeys}}; -get_subconfig(_SubKeys,[],Mapped,_) -> - {ok,Mapped}. - -do_get_config([Key|Required],Available,Mapped) -> - case lists:keysearch(Key,1,Available) of - {value,{Key,Value}} -> - NewAvailable = lists:keydelete(Key,1,Available), - NewMapped = [{Key,Value}|Mapped], - do_get_config(Required,NewAvailable,NewMapped); - false -> - {error,{not_available,Key}} - end; -do_get_config([],_Available,Mapped) -> - {ok,lists:reverse(Mapped)}. - -get_all_config() -> - ets:select(?attr_table,[{#ct_conf{name='$1',key='$2',value='$3', - default='$4',_='_'}, - [], - [{{'$1','$2','$3','$4'}}]}]). - -lookup_config(KeyOrName) -> - case lookup_name(KeyOrName) of - [] -> - lookup_key(KeyOrName); - Values -> - Values - end. - -lookup_name(Name) -> - ets:select(?attr_table,[{#ct_conf{ref='$1',value='$2',name=Name,_='_'}, - [], - [{{'$1','$2'}}]}]). -lookup_key(Key) -> - ets:select(?attr_table,[{#ct_conf{key=Key,ref='$1',value='$2',name='_UNDEF',_='_'}, - [], - [{{'$1','$2'}}]}]). - -set_config(Config) -> - set_config('_UNDEF',Config,false). - -set_config(Config,Default) -> - set_config('_UNDEF',Config,Default). - -set_config(Name,Config,Default) -> - [ets:insert(?attr_table, - #ct_conf{key=Key,value=Val,ref=ct_make_ref(), - name=Name,default=Default}) || - {Key,Val} <- Config]. - -delete_config(Default) -> - ets:match_delete(?attr_table,#ct_conf{default=Default,_='_'}), - ok. - - -%%%----------------------------------------------------------------- -%%% @spec release_allocated() -> ok -%%% -%%% @doc Release all allocated resources, but don't take down any -%%% connections. -release_allocated() -> - Allocated = ets:select(?attr_table,[{#ct_conf{name='$1',_='_'}, - [{'=/=','$1','_UNDEF'}], - ['$_']}]), - release_allocated(Allocated). -release_allocated([H|T]) -> - ets:delete_object(?attr_table,H), - ets:insert(?attr_table,H#ct_conf{name='_UNDEF'}), - release_allocated(T); -release_allocated([]) -> - ok. - -%%%----------------------------------------------------------------- -%%% @spec -%%% -%%% @doc -update_conf(Name, NewConfig) -> - Old = ets:select(?attr_table,[{#ct_conf{name=Name,_='_'},[],['$_']}]), - lists:foreach(fun(OldElem) -> - NewElem = OldElem#ct_conf{value=NewConfig}, - ets:delete_object(?attr_table, OldElem), - ets:insert(?attr_table, NewElem) - end, Old), - ok. - %%%----------------------------------------------------------------- %%% @spec close_connections() -> ok %%% @@ -995,167 +623,6 @@ get_testdir(Dir, _) -> %%% @spec %%% %%% @doc -encrypt_config_file(SrcFileName, EncryptFileName) -> - case get_crypt_key_from_file() of - {error,_} = E -> - E; - Key -> - encrypt_config_file(SrcFileName, EncryptFileName, {key,Key}) - end. - -%%%----------------------------------------------------------------- -%%% @spec -%%% -%%% @doc -encrypt_config_file(SrcFileName, EncryptFileName, {file,KeyFile}) -> - case get_crypt_key_from_file(KeyFile) of - {error,_} = E -> - E; - Key -> - encrypt_config_file(SrcFileName, EncryptFileName, {key,Key}) - end; - -encrypt_config_file(SrcFileName, EncryptFileName, {key,Key}) -> - crypto:start(), - {K1,K2,K3,IVec} = make_crypto_key(Key), - case file:read_file(SrcFileName) of - {ok,Bin0} -> - Bin1 = term_to_binary({SrcFileName,Bin0}), - Bin2 = case byte_size(Bin1) rem 8 of - 0 -> Bin1; - N -> list_to_binary([Bin1,random_bytes(8-N)]) - end, - EncBin = crypto:des3_cbc_encrypt(K1, K2, K3, IVec, Bin2), - case file:write_file(EncryptFileName, EncBin) of - ok -> - io:format("~s --(encrypt)--> ~s~n", - [SrcFileName,EncryptFileName]), - ok; - {error,Reason} -> - {error,{Reason,EncryptFileName}} - end; - {error,Reason} -> - {error,{Reason,SrcFileName}} - end. - -%%%----------------------------------------------------------------- -%%% @spec -%%% -%%% @doc -decrypt_config_file(EncryptFileName, TargetFileName) -> - case get_crypt_key_from_file() of - {error,_} = E -> - E; - Key -> - decrypt_config_file(EncryptFileName, TargetFileName, {key,Key}) - end. - - -%%%----------------------------------------------------------------- -%%% @spec -%%% -%%% @doc -decrypt_config_file(EncryptFileName, TargetFileName, {file,KeyFile}) -> - case get_crypt_key_from_file(KeyFile) of - {error,_} = E -> - E; - Key -> - decrypt_config_file(EncryptFileName, TargetFileName, {key,Key}) - end; - -decrypt_config_file(EncryptFileName, TargetFileName, {key,Key}) -> - crypto:start(), - {K1,K2,K3,IVec} = make_crypto_key(Key), - case file:read_file(EncryptFileName) of - {ok,Bin} -> - DecBin = crypto:des3_cbc_decrypt(K1, K2, K3, IVec, Bin), - case catch binary_to_term(DecBin) of - {'EXIT',_} -> - {error,bad_file}; - {_SrcFile,SrcBin} -> - case TargetFileName of - undefined -> - {ok,SrcBin}; - _ -> - case file:write_file(TargetFileName, SrcBin) of - ok -> - io:format("~s --(decrypt)--> ~s~n", - [EncryptFileName,TargetFileName]), - ok; - {error,Reason} -> - {error,{Reason,TargetFileName}} - end - end - end; - {error,Reason} -> - {error,{Reason,EncryptFileName}} - end. - - -get_crypt_key_from_file(File) -> - case file:read_file(File) of - {ok,Bin} -> - case catch string:tokens(binary_to_list(Bin), [$\n,$\r]) of - [Key] -> - Key; - _ -> - {error,{bad_crypt_file,File}} - end; - {error,Reason} -> - {error,{Reason,File}} - end. - -get_crypt_key_from_file() -> - CwdFile = filename:join(".",?cryptfile), - {Result,FullName} = - case file:read_file(CwdFile) of - {ok,Bin} -> - {Bin,CwdFile}; - _ -> - case init:get_argument(home) of - {ok,[[Home]]} -> - HomeFile = filename:join(Home,?cryptfile), - case file:read_file(HomeFile) of - {ok,Bin} -> - {Bin,HomeFile}; - _ -> - {{error,no_crypt_file},noent} - end; - _ -> - {{error,no_crypt_file},noent} - end - end, - case FullName of - noent -> - Result; - _ -> - case catch string:tokens(binary_to_list(Result), [$\n,$\r]) of - [Key] -> - io:format("~nCrypt key file: ~s~n", [FullName]), - Key; - _ -> - {error,{bad_crypt_file,FullName}} - end - end. - -make_crypto_key(String) -> - <<K1:8/binary,K2:8/binary>> = First = erlang:md5(String), - <<K3:8/binary,IVec:8/binary>> = erlang:md5([First|lists:reverse(String)]), - {K1,K2,K3,IVec}. - -random_bytes(N) -> - {A,B,C} = now(), - random:seed(A, B, C), - random_bytes_1(N, []). - -random_bytes_1(0, Acc) -> Acc; -random_bytes_1(N, Acc) -> random_bytes_1(N-1, [random:uniform(255)|Acc]). - - -%%%----------------------------------------------------------------- -%%% @spec -%%% -%%% @doc get_attached(TCPid) -> case dbg_iserver:safe_call({get_attpid,TCPid}) of {ok,AttPid} when is_pid(AttPid) -> @@ -1210,7 +677,7 @@ call(Msg) -> ct_util_server ! {Msg,{self(),Ref}}, receive {Ref, Result} -> - erlang:demonitor(MRef), + erlang:demonitor(MRef, [flush]), Result; {'DOWN',MRef,process,_,Reason} -> {error,{ct_util_server_down,Reason}} @@ -1244,37 +711,6 @@ ct_make_ref_loop(N) -> From ! {self(),N}, ct_make_ref_loop(N+1) end. - -get_ref_from_name(Name) -> - case ets:select(?attr_table,[{#ct_conf{name=Name,ref='$1',_='_'}, - [], - ['$1']}]) of - [Ref] -> - {ok,Ref}; - _ -> - {error,{no_such_name,Name}} - end. - -get_name_from_ref(Ref) -> - case ets:select(?attr_table,[{#ct_conf{name='$1',ref=Ref,_='_'}, - [], - ['$1']}]) of - [Name] -> - {ok,Name}; - _ -> - {error,{no_such_ref,Ref}} - end. - -get_key_from_name(Name) -> - case ets:select(?attr_table,[{#ct_conf{name=Name,key='$1',_='_'}, - [], - ['$1']}]) of - [Key|_] -> - {ok,Key}; - _ -> - {error,{no_such_name,Name}} - end. - abs_name(Dir0) -> Abs = filename:absname(Dir0), diff --git a/lib/common_test/src/ct_util.hrl b/lib/common_test/src/ct_util.hrl index c1dc14f943..ee973f6220 100644 --- a/lib/common_test/src/ct_util.hrl +++ b/lib/common_test/src/ct_util.hrl @@ -29,11 +29,16 @@ -record(testspec, {spec_dir, nodes=[], + init=[], + label=[], logdir=["."], cover=[], config=[], + userconfig=[], event_handler=[], include=[], + multiply_timetraps=[], + scale_timetraps=[], alias=[], tests=[]}). @@ -50,3 +55,4 @@ -define(CT_MEVMGR_REF, ct_master_event). -define(missing_suites_info, "missing_suites.info"). +-define(ct_config_txt, ct_config_plain). diff --git a/lib/common_test/src/vts.erl b/lib/common_test/src/vts.erl index ad4845a7c3..2ee982d726 100644 --- a/lib/common_test/src/vts.erl +++ b/lib/common_test/src/vts.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -100,7 +100,7 @@ start_link() -> MRef = erlang:monitor(process,Pid), receive {Pid,started} -> - erlang:demonitor(MRef), + erlang:demonitor(MRef, [flush]), {ok,Pid}; {'DOWN',MRef,process,_,Reason} -> {error,{vts,died,Reason}} @@ -160,11 +160,13 @@ init(Parent) -> loop(State) -> receive - {{init_data,ConfigFiles,EvHandlers,LogDir,Tests},From} -> - ct_install(State), + {{init_data,Config,EvHandlers,LogDir,Tests},From} -> + %% ct:pal("State#state.current_log_dir=~p", [State#state.current_log_dir]), + NewState = State#state{config=Config,event_handler=EvHandlers, + current_log_dir=LogDir,tests=Tests}, + ct_install(NewState), return(From,ok), - loop(#state{config=ConfigFiles,event_handler=EvHandlers, - current_log_dir=LogDir,tests=Tests}); + loop(NewState); {start_page,From} -> return(From,start_page1()), loop(State); @@ -257,7 +259,7 @@ call(Msg) -> Pid ! {Msg,{self(),Ref}}, receive {Ref, Result} -> - erlang:demonitor(MRef), + erlang:demonitor(MRef, [flush]), Result; {'DOWN',MRef,process,_,Reason} -> {error,{process_down,Pid,Reason}} diff --git a/lib/common_test/test/Makefile b/lib/common_test/test/Makefile index 35ba22aa59..f2fe3390cf 100644 --- a/lib/common_test/test/Makefile +++ b/lib/common_test/test/Makefile @@ -27,13 +27,20 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk MODULES= \ ct_test_support \ ct_test_support_eh \ + ct_userconfig_callback \ ct_smoke_test_SUITE \ ct_event_handler_SUITE \ ct_groups_test_1_SUITE \ ct_groups_test_2_SUITE \ + ct_sequence_1_SUITE \ + ct_repeat_1_SUITE \ + ct_testspec_1_SUITE \ ct_skip_SUITE \ ct_error_SUITE \ - ct_test_server_if_1_SUITE + ct_test_server_if_1_SUITE \ + ct_config_SUITE \ + ct_master_SUITE \ + ct_misc_1_SUITE ERL_FILES= $(MODULES:%=%.erl) @@ -64,15 +71,15 @@ EBIN = . #.PHONY: make_emakefile #make_emakefile: -# $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) \ -# '*_SUITE_make' > $(EMAKEFILE) # $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES)\ -# >> $(EMAKEFILE) +# > $(EMAKEFILE) tests debug opt: + erl $(ERL_MAKE_FLAGS) -make clean: rm -f $(TARGET_FILES) +# rm -f $(EMAKEFILE) rm -f core docs: @@ -87,7 +94,7 @@ release_spec: opt release_tests_spec: $(INSTALL_DIR) $(RELSYSDIR) $(INSTALL_DATA) $(ERL_FILES) $(COVERFILE) $(RELSYSDIR) - $(INSTALL_PROGRAM) common_test.spec $(RELSYSDIR) + $(INSTALL_DATA) common_test.spec $(RELSYSDIR) chmod -f -R u+w $(RELSYSDIR) @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) diff --git a/lib/common_test/test/ct_config_SUITE.erl b/lib/common_test/test/ct_config_SUITE.erl new file mode 100644 index 0000000000..fc15abc5bc --- /dev/null +++ b/lib/common_test/test/ct_config_SUITE.erl @@ -0,0 +1,272 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% +%% + +%%%------------------------------------------------------------------- +%%% File: ct_config_SUITE +%%% +%%% Description: +%%% Test configuration handling in Common Test suites. +%%% +%%% The suites used for the test are located in the data directory. +%%%------------------------------------------------------------------- +-module(ct_config_SUITE). + +-compile(export_all). + +-include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct_event.hrl"). + +-define(eh, ct_test_support_eh). + +%%-------------------------------------------------------------------- +%% TEST SERVER CALLBACK FUNCTIONS +%%-------------------------------------------------------------------- + +%%-------------------------------------------------------------------- +%% Description: Since Common Test starts another Test Server +%% instance, the tests need to be performed on a separate node (or +%% there will be clashes with logging processes etc). +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + DataDir = ?config(data_dir, Config), + PathDir = filename:join(DataDir, "config/test"), + Config1 = ct_test_support:init_per_suite([{path_dirs,[PathDir]} | Config]), + PrivDir = ?config(priv_dir, Config1), + ConfigDir = filename:join(PrivDir, "config"), + ok = file:make_dir(ConfigDir), + [{config_dir,ConfigDir} | Config1]. + +end_per_suite(Config) -> + ct_test_support:end_per_suite(Config). + +init_per_testcase(TestCase, Config) -> + ct_test_support:init_per_testcase(TestCase, Config). + +end_per_testcase(install_config = TestCase, Config) -> + ok = rpc:call(proplists:get_value(ct_node, Config), ct_config, stop, []), + ct_test_support:end_per_testcase(TestCase, Config); +end_per_testcase(TestCase, Config) -> + ct_test_support:end_per_testcase(TestCase, Config). + +all(doc) -> + [""]; + +all(suite) -> + [ + require, + install_config, + userconfig_static, + userconfig_dynamic, + testspec_legacy, + testspec_static, + testspec_dynamic + ]. + +%%-------------------------------------------------------------------- +%% TEST CASES +%%-------------------------------------------------------------------- +require(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + run_test(config_static_SUITE, + Config, + {config, filename:join(DataDir, "config/config.txt")}, + ["config_static_SUITE"]). + +install_config(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + CTNode = proplists:get_value(ct_node, Config), + rpc:call(CTNode, ct, install, + [[{config, [filename:join(DataDir, "config/config.txt")]}]]), + case rpc:call(CTNode, ct_config, start, [interactive]) of + Pid when is_pid(Pid) -> + ok + end. + + +userconfig_static(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + run_test(config_static_SUITE, + Config, + {userconfig, {ct_config_xml, filename:join(DataDir, "config/config.xml")}}, + ["config_static_SUITE"]). + +userconfig_dynamic(Config) when is_list(Config) -> + run_test(config_dynamic_SUITE, + Config, + {userconfig, {config_driver, "config_server"}}, + ["config_dynamic_SUITE"]). + +testspec_legacy(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + ConfigDir = ?config(config_dir, Config), + make_spec(DataDir, ConfigDir, + "spec_legacy.spec", + [config_static_SUITE], + [{config, filename:join(DataDir, "config/config.txt")}]), + run_test(config_static_SUITE, + Config, + {spec, filename:join(ConfigDir, "spec_legacy.spec")}, + []), + file:delete(filename:join(ConfigDir, "spec_legacy.spec")). + +testspec_static(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + ConfigDir = ?config(config_dir, Config), + make_spec(DataDir, ConfigDir, + "spec_static.spec", + [config_static_SUITE], + [{userconfig, {ct_config_xml, filename:join(DataDir, "config/config.xml")}}]), + run_test(config_static_SUITE, + Config, + {spec, filename:join(ConfigDir, "spec_static.spec")}, + []), + file:delete(filename:join(ConfigDir, "spec_static.spec")). + +testspec_dynamic(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + ConfigDir = ?config(config_dir, Config), + make_spec(DataDir, ConfigDir, "spec_dynamic.spec", + [config_dynamic_SUITE], + [{userconfig, {config_driver, "config_server"}}]), + run_test(config_dynamic_SUITE, + Config, + {spec, filename:join(ConfigDir, "spec_dynamic.spec")}, + []), + file:delete(filename:join(ConfigDir, "spec_dynamic.spec")). + + + +%%%----------------------------------------------------------------- +%%% HELP FUNCTIONS +%%%----------------------------------------------------------------- +make_spec(DataDir, ConfigDir, Filename, Suites, Config)-> + {ok, Fd} = file:open(filename:join(ConfigDir, Filename), [write]), + ok = file:write(Fd, + io_lib:format("{suites, \"~sconfig/test/\", ~p}.~n", [DataDir, Suites])), + lists:foreach(fun(C)-> ok=file:write(Fd, io_lib:format("~p.~n", [C])) end, Config), + ok = file:close(Fd). + +run_test(Name, Config, CTConfig, SuiteNames)-> + DataDir = ?config(data_dir, Config), + Joiner = fun(Suite) -> filename:join(DataDir, "config/test/"++Suite) end, + Suites = lists:map(Joiner, SuiteNames), + {Opts,ERPid} = setup_env({suite,Suites}, Config, CTConfig), + ok = ct_test_support:run(Opts, Config), + TestEvents = ct_test_support:get_events(ERPid, Config), + ct_test_support:log_events(Name, + reformat_events(TestEvents, ?eh), + ?config(config_dir, Config)), + ExpEvents = events_to_check(Name), + ok = ct_test_support:verify_events(ExpEvents, TestEvents, Config). + +setup_env(Test, Config, CTConfig) -> + Opts0 = ct_test_support:get_opts(Config), + Level = ?config(trace_level, Config), + EvHArgs = [{cbm,ct_test_support},{trace_level,Level}], + Opts = Opts0 ++ [Test,{event_handler,{?eh,EvHArgs}}, CTConfig], + ERPid = ct_test_support:start_event_receiver(Config), + {Opts,ERPid}. + +reformat_events(Events, EH) -> + ct_test_support:reformat(Events, EH). + +%%%----------------------------------------------------------------- +%%% TEST EVENTS +%%%----------------------------------------------------------------- +events_to_check(Test) -> + %% 2 tests (ct:run_test + script_start) is default + events_to_check(Test, 2). + +events_to_check(_, 0) -> + []; +events_to_check(Test, N) -> + expected_events(Test) ++ events_to_check(Test, N-1). + +expected_events(config_static_SUITE)-> +[ + {?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,8}}, + {?eh,tc_start,{config_static_SUITE,init_per_suite}}, + {?eh,tc_done,{config_static_SUITE,init_per_suite,ok}}, + {?eh,tc_start,{config_static_SUITE,test_get_config_simple}}, + {?eh,tc_done,{config_static_SUITE,test_get_config_simple,ok}}, + {?eh,test_stats,{1,0,{0,0}}}, + {?eh,tc_start,{config_static_SUITE,test_get_config_nested}}, + {?eh,tc_done,{config_static_SUITE,test_get_config_nested,ok}}, + {?eh,test_stats,{2,0,{0,0}}}, + {?eh,tc_start,{config_static_SUITE,test_default_suitewide}}, + {?eh,tc_done,{config_static_SUITE,test_default_suitewide,ok}}, + {?eh,test_stats,{3,0,{0,0}}}, + {?eh,tc_start,{config_static_SUITE,test_config_name_already_in_use1}}, + {?eh,tc_done, + {config_static_SUITE,test_config_name_already_in_use1,{skipped,{config_name_already_in_use,[x1]}}}}, + {?eh,test_stats,{3,0,{1,0}}}, + {?eh,tc_start,{config_static_SUITE,test_default_tclocal}}, + {?eh,tc_done,{config_static_SUITE,test_default_tclocal,ok}}, + {?eh,test_stats,{4,0,{1,0}}}, + {?eh,tc_start,{config_static_SUITE,test_config_name_already_in_use2}}, + {?eh,tc_done, + {config_static_SUITE,test_config_name_already_in_use2, + {skipped,{config_name_already_in_use,[x1,alias]}}}}, + {?eh,test_stats,{4,0,{2,0}}}, + {?eh,tc_start,{config_static_SUITE,test_alias_tclocal}}, + {?eh,tc_done,{config_static_SUITE,test_alias_tclocal,ok}}, + {?eh,test_stats,{5,0,{2,0}}}, + {?eh,tc_start,{config_static_SUITE,test_get_config_undefined}}, + {?eh,tc_done,{config_static_SUITE,test_get_config_undefined,ok}}, + {?eh,test_stats,{6,0,{2,0}}}, + {?eh,tc_start,{config_static_SUITE,end_per_suite}}, + {?eh,tc_done,{config_static_SUITE,end_per_suite,ok}}, + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]} +]; + +expected_events(config_dynamic_SUITE)-> +[ + {?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,5}}, + {?eh,tc_start,{config_dynamic_SUITE,init_per_suite}}, + {?eh,tc_done,{config_dynamic_SUITE,init_per_suite,ok}}, + {?eh,tc_start,{config_dynamic_SUITE,test_get_known_variable}}, + {?eh,tc_done, + {config_dynamic_SUITE,test_get_known_variable,ok}}, + {?eh,test_stats,{1,0,{0,0}}}, + {?eh,tc_start,{config_dynamic_SUITE,test_localtime_update}}, + {?eh,tc_done,{config_dynamic_SUITE,test_localtime_update,ok}}, + {?eh,test_stats,{2,0,{0,0}}}, + {?eh,tc_start,{config_dynamic_SUITE,test_server_pid}}, + {?eh,tc_done,{config_dynamic_SUITE,test_server_pid,ok}}, + {?eh,test_stats,{3,0,{0,0}}}, + {?eh,tc_start, + {config_dynamic_SUITE,test_disappearable_variable}}, + {?eh,tc_done, + {config_dynamic_SUITE,test_disappearable_variable,ok}}, + {?eh,test_stats,{4,0,{0,0}}}, + {?eh,tc_start, + {config_dynamic_SUITE,test_disappearable_variable_alias}}, + {?eh,tc_done, + {config_dynamic_SUITE,test_disappearable_variable_alias,ok}}, + {?eh,test_stats,{5,0,{0,0}}}, + {?eh,tc_start,{config_dynamic_SUITE,end_per_suite}}, + {?eh,tc_done,{config_dynamic_SUITE,end_per_suite,ok}}, + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]} +]. diff --git a/lib/common_test/test/ct_config_SUITE_data/config/config.txt b/lib/common_test/test/ct_config_SUITE_data/config/config.txt new file mode 100644 index 0000000000..fcbffcd7f3 --- /dev/null +++ b/lib/common_test/test/ct_config_SUITE_data/config/config.txt @@ -0,0 +1,31 @@ +{x, suite}. +{gen_cfg, + [ + {a,a_value}, + {b,b_value} + ]}. +{gen_cfg2, + [ + {c, "Hello, world!"}, + {d, atom_value}, + {e, {tuple,1,"third value",[]}}, + {f, []}, + {g, [1,atom,"string",13.6,{1,2,3}]} + ]}. +{gen_cfg3, + [ + {h, + [ + {i, third1}, + {j, "Third2"}, + {k, 'THIRD3'} + ]}, + {l, + [ + {m, + [ + {n, "N"}, + {o, 'O'} + ]} + ]} + ]}. diff --git a/lib/common_test/test/ct_config_SUITE_data/config/config.xml b/lib/common_test/test/ct_config_SUITE_data/config/config.xml new file mode 100644 index 0000000000..0a3e5f2e31 --- /dev/null +++ b/lib/common_test/test/ct_config_SUITE_data/config/config.xml @@ -0,0 +1,27 @@ +<config> + <x>suite</x> + <gen_cfg> + <a>a_value</a> + <b>b_value</b> + </gen_cfg> + <gen_cfg2> + <c>"Hello, world!"</c> + <d>atom_value</d> + <e>{tuple,1,"third value",[]}</e> + <f>[]</f> + <g>[1,atom,"string",13.6,{1,2,3}]</g> + </gen_cfg2> + <gen_cfg3> + <h> + <i>third1</i> + <j>"Third2"</j> + <k>'THIRD3'</k> + </h> + <l> + <m> + <n>"N"</n> + <o>'O'</o> + </m> + </l> + </gen_cfg3> +</config> diff --git a/lib/common_test/test/ct_config_SUITE_data/config/test/config_driver.erl b/lib/common_test/test/ct_config_SUITE_data/config/test/config_driver.erl new file mode 100644 index 0000000000..d93faf6ec6 --- /dev/null +++ b/lib/common_test/test/ct_config_SUITE_data/config/test/config_driver.erl @@ -0,0 +1,46 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% +%% + +%%%------------------------------------------------------------------- +%%% File: ct_config_SUITE +%%% +%%% Description: +%%% Config driver used in the CT's tests (config_2_SUITE) +%%%------------------------------------------------------------------- +-module(config_driver). +-export([read_config/1, check_parameter/1]). + +read_config(ServerName)-> + ServerModule = list_to_atom(ServerName), + ServerModule:start(), + ServerModule:get_config(). + +check_parameter(ServerName)-> + ServerModule = list_to_atom(ServerName), + case code:is_loaded(ServerModule) of + {file, _}-> + {ok, {config, ServerName}}; + false-> + case code:load_file(ServerModule) of + {module, ServerModule}-> + {ok, {config, ServerName}}; + {error, nofile}-> + {error, {wrong_config, "File not found: " ++ ServerName ++ ".beam"}} + end + end. diff --git a/lib/common_test/test/ct_config_SUITE_data/config/test/config_dynamic_SUITE.erl b/lib/common_test/test/ct_config_SUITE_data/config/test/config_dynamic_SUITE.erl new file mode 100644 index 0000000000..8ee12a2e4d --- /dev/null +++ b/lib/common_test/test/ct_config_SUITE_data/config/test/config_dynamic_SUITE.erl @@ -0,0 +1,145 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% +%% + +%%%------------------------------------------------------------------- +%%% File: config_dynamic_SUITE +%%% +%%% Description: +%%% Test suite for common_test which tests the userconfig functionality +%%%------------------------------------------------------------------- +-module(config_dynamic_SUITE). + +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +%% This suite will be run with dynamic userconfig +%% test_driver.erl is compliant to ct_config_* callback +%% and test_server is simple server for getting runtime-changing data +%% which will return the list with the following variables: +%% localtime = the erlang:localtime() result in list [{date, Date}, {time, Time}] +%% node = erlang:node() - can be compared in the testcase +%% now = erlang:now() - easier to compare than localtime() +%% config_server_pid - pid of the config server, should NOT change! +%% config_server_vsn - .19 +%% config_server_iteration - a number of iteration config_server's loop done +%% disappearable_variable - hereAmI - will be absent on even iterations + +suite() -> + [ + {timetrap, {seconds,10}} + ]. + +init_per_suite(Config) -> + Config. + +end_per_suite(_) -> + ok. + +all() -> [test_get_known_variable, test_localtime_update, + test_server_pid, test_disappearable_variable, + test_disappearable_variable_alias]. + +init_per_testcase(_, Config) -> + Config. + +end_per_testcase(_, _) -> + ok. + +% test that usual config works +test_get_known_variable(_)-> + Node = erlang:node(), + 0.19 = ct:get_config(config_server_vsn), + Node = ct:get_config(node), + ok. + +% localtime will be updated in 5 seconds, check that +test_localtime_update(_)-> + Seconds = 5, + LT1 = ct:get_config(localtime), + timer:sleep(Seconds*1000), + LT2 = ct:reload_config(localtime), + case is_diff_ok(LT1, LT2, Seconds) of + {false, Actual, Exp}-> + ct:fail(io_lib:format("Time difference ~p is not ok, expected ~p", [Actual, Exp])); + true-> + ok + end. + +% server pid should not change +test_server_pid()-> + [{require, cfvsn, config_server_vsn}]. +test_server_pid(_)-> + Pid = ct:get_config(config_server_pid), + Pid = ct:reload_config(config_server_pid), + Vsn = ct:get_config(config_server_vsn), + % aliases remain after config reloading + Vsn = ct:get_config(cfvsn), + ok. + +% test that variables may disappear from the config_2_SUITE +test_disappearable_variable(_)-> + % ask CT for config_server_iteration variable + Iter = ct:reload_config(config_server_iteration), + % here we should reload this variable in case it's odd + if Iter rem 2 == 1-> + Iter2 = ct:reload_config(config_server_iteration), + Iter2 = Iter+1; + true->ok + end, + % now disappearable_variable should be in place + hereAmI = ct:get_config(disappearable_variable), + % and now it should disappear + undefined = ct:reload_config(disappearable_variable). + +% alias of disappearable_variable should disappear too +test_disappearable_variable_alias(_)-> + % the same rules apply for this testcase as for previous one + Iter = ct:reload_config(config_server_iteration), + Iter2 = if + Iter rem 2 == 1 -> + NewIter = ct:reload_config(config_server_iteration), + NewIter = Iter+1; + true-> + Iter + end, + ct:require(diav, disappearable_variable), + hereAmI = ct:get_config(disappearable_variable), + hereAmI = ct:get_config(diav), + ct:reload_config(disappearable_variable), + undefined = ct:get_config(disappearable_variable), + % after reloading, it's even again + Iter3=ct:get_config(config_server_iteration), + Iter3 = Iter2+1, + % and alias does not exist + undefined = ct:get_config(diav). + +my_dt_to_datetime([{date, D},{time, T}])-> + {D, T}. + +is_diff_ok(DT1, DT2, Seconds)-> + GS1 = calendar:datetime_to_gregorian_seconds(my_dt_to_datetime(DT1)), + GS2 = calendar:datetime_to_gregorian_seconds(my_dt_to_datetime(DT2)), + if + GS2-GS1 > Seconds+Seconds/2; + GS2-GS1 < Seconds-Seconds/2-> + {false, GS2-GS1, Seconds}; + true-> + true + end. diff --git a/lib/common_test/test/ct_config_SUITE_data/config/test/config_server.erl b/lib/common_test/test/ct_config_SUITE_data/config/test/config_server.erl new file mode 100644 index 0000000000..8463fea645 --- /dev/null +++ b/lib/common_test/test/ct_config_SUITE_data/config/test/config_server.erl @@ -0,0 +1,93 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% +%% + +%%%------------------------------------------------------------------- +%%% File: ct_config_SUITE +%%% +%%% Description: +%%% Config server used in the CT's tests (config_2_SUITE) +%%%------------------------------------------------------------------- +-module(config_server). +-export([start/0, stop/0, loop/1, init/1, get_config/0]). + +-define(REGISTERED_NAME, ct_test_config_server). +-define(vsn, 0.19). + +start()-> + case whereis(?REGISTERED_NAME) of + undefined-> + spawn(?MODULE, init, [?REGISTERED_NAME]), + wait(); + _Pid-> + ok + end, + ?REGISTERED_NAME. + +init(Name)-> + register(Name, self()), + loop(0). + +get_config()-> + call(self(), get_config). + +stop()-> + call(self(), stop). + +call(Client, Request)-> + case whereis(?REGISTERED_NAME) of + undefined-> + {error, not_started, Request}; + Pid-> + Pid ! {Client, Request}, + receive + Reply-> + {ok, Reply} + after 4000-> + {error, timeout, Request} + end + end. + +loop(Iteration)-> + receive + {Pid, stop}-> + Pid ! ok; + {Pid, get_config}-> + {D,T} = erlang:localtime(), + Config = + [{localtime, [{date, D}, {time, T}]}, + {node, erlang:node()}, + {config_server_iteration, Iteration}, + {now, erlang:now()}, + {config_server_pid, self()}, + {config_server_vsn, ?vsn}], + Config2 = if Iteration rem 2 == 0-> + Config ++ [{disappearable_variable, hereAmI}]; + true-> Config + end, + Pid ! Config2, + ?MODULE:loop(Iteration+1) + end. + +wait()-> + case whereis(?REGISTERED_NAME) of + undefined-> + wait(); + _Pid-> + ok + end. diff --git a/lib/common_test/test/ct_config_SUITE_data/config/test/config_static_SUITE.erl b/lib/common_test/test/ct_config_SUITE_data/config/test/config_static_SUITE.erl new file mode 100644 index 0000000000..8751a2e8f3 --- /dev/null +++ b/lib/common_test/test/ct_config_SUITE_data/config/test/config_static_SUITE.erl @@ -0,0 +1,123 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% +%% + +%%%------------------------------------------------------------------- +%%% File: config_static_SUITE +%%% +%%% Description: +%%% Test suite for common_test which tests the get_config and require +%%% functionality +%%%------------------------------------------------------------------- +-module(config_static_SUITE). + +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +% The config contains variables: +% x - atom +% gen_cfg - list with two key-values tagged with a and b +% gen_cfg2 - list of five key-values tagged with c, d, e, f and g +% gen_cfg3 - list of two complex key-values taggen with: +% h: three elements inside - i, j and k +% l: m inside, contains n and o + +suite() -> + [ + {timetrap, {seconds,10}}, + %% x1 doesn't exist in cfg-file! + {require, x1, x}, + {require, gen_cfg3}, + {require, alias, gen_cfg}, + %% x1 default value + {x1, {x,suite}} + ]. + +init_per_suite(Config) -> + Config. + +end_per_suite(_) -> + ok. + +all() -> [test_get_config_simple, test_get_config_nested, test_default_suitewide, + test_config_name_already_in_use1, test_default_tclocal, + test_config_name_already_in_use2, test_alias_tclocal, + test_get_config_undefined]. + +init_per_testcase(_, Config) -> + Config. + +end_per_testcase(_, _) -> + ok. + +%% test getting a simple value +test_get_config_simple(_)-> + suite = ct:get_config(x), + ok. + +%% test getting a nested value +test_get_config_nested(_)-> + a_value = ct:get_config({gen_cfg, a}), + ok. + +%% test suite-wide default value +test_default_suitewide(_)-> + suite = ct:get_config(x1), + ok. + +%% should get skipped +test_config_name_already_in_use1() -> + [{timetrap, {seconds,2}}, + {require, x1, x}, + {x1, {x,test2}}]. +test_config_name_already_in_use1(_) -> + ct:fail("Test should've been skipped, you shouldn't see this!"), + ok. + +%% test defaults in a testcase +test_default_tclocal() -> + [{timetrap, {seconds,3}}, + {require, y1, y}, + {y1, {y,test3}}]. +test_default_tclocal(_) -> + test3 = ct:get_config(y1), + ok. + +%% should get skipped +test_config_name_already_in_use2() -> + [{require,alias,something}, + {alias,{something,else}}, + {require, x1, x}, + {x1, {x,test4}}]. +test_config_name_already_in_use2(_) -> + ct:fail("Test should've been skipped, you shouldn't see this!"), + ok. + +%% test aliases +test_alias_tclocal() -> + [{require,newalias,gen_cfg}]. +test_alias_tclocal(_) -> + A = [{a,a_value},{b,b_value}] = ct:get_config(newalias), + A = ct:get_config(gen_cfg), + ok. + +%% test for getting undefined variables +test_get_config_undefined(_) -> + undefined = ct:get_config(y1), + ok. diff --git a/lib/common_test/test/ct_error_SUITE.erl b/lib/common_test/test/ct_error_SUITE.erl index be75d768fc..2fa031b884 100644 --- a/lib/common_test/test/ct_error_SUITE.erl +++ b/lib/common_test/test/ct_error_SUITE.erl @@ -63,7 +63,10 @@ all(suite) -> [ cfg_error, lib_error, - no_compile + no_compile, + timetrap_end_conf, + timetrap_normal, + timetrap_extended ]. @@ -84,17 +87,22 @@ cfg_error(Config) when is_list(Config) -> Join(DataDir, "cfg_error_6_SUITE"), Join(DataDir, "cfg_error_7_SUITE"), Join(DataDir, "cfg_error_8_SUITE"), - Join(DataDir, "cfg_error_9_SUITE") + Join(DataDir, "cfg_error_9_SUITE"), + Join(DataDir, "cfg_error_10_SUITE"), + Join(DataDir, "cfg_error_11_SUITE"), + Join(DataDir, "cfg_error_12_SUITE"), + Join(DataDir, "cfg_error_13_SUITE"), + Join(DataDir, "cfg_error_14_SUITE") ], - {Opts,ERPid} = setup({suite,Suites}, Config), - ok = ct_test_support:run(ct, run_test, [Opts], Config), + {Opts,ERPid} = setup([{suite,Suites}], Config), + ok = ct_test_support:run(Opts, Config), Events = ct_test_support:get_events(ERPid, Config), ct_test_support:log_events(cfg_error, reformat(Events, ?eh), ?config(priv_dir, Config)), - TestEvents = test_events(cfg_error), + TestEvents = events_to_check(cfg_error), ok = ct_test_support:verify_events(TestEvents, Events, Config). @@ -104,15 +112,15 @@ lib_error(Config) when is_list(Config) -> DataDir = ?config(data_dir, Config), Join = fun(D, S) -> filename:join(D, "error/test/"++S) end, Suites = [Join(DataDir, "lib_error_1_SUITE")], - {Opts,ERPid} = setup({suite,Suites}, Config), - ok = ct_test_support:run(ct, run_test, [Opts], Config), + {Opts,ERPid} = setup([{suite,Suites}], Config), + ok = ct_test_support:run(Opts, Config), Events = ct_test_support:get_events(ERPid, Config), ct_test_support:log_events(lib_error, reformat(Events, ?eh), ?config(priv_dir, Config)), - TestEvents = test_events(lib_error), + TestEvents = events_to_check(lib_error), ok = ct_test_support:verify_events(TestEvents, Events, Config). @@ -122,17 +130,75 @@ no_compile(Config) when is_list(Config) -> DataDir = ?config(data_dir, Config), Join = fun(D, S) -> filename:join(D, "error/test/"++S) end, Suites = [Join(DataDir, "no_compile_SUITE")], - {Opts,ERPid} = setup({suite,Suites}, Config), - ok = ct_test_support:run(ct, run_test, [Opts], Config), + {Opts,ERPid} = setup([{suite,Suites}], Config), + ok = ct_test_support:run(Opts, Config), Events = ct_test_support:get_events(ERPid, Config), ct_test_support:log_events(no_compile, reformat(Events, ?eh), ?config(priv_dir, Config)), - TestEvents = test_events(no_compile), + TestEvents = events_to_check(no_compile), ok = ct_test_support:verify_events(TestEvents, Events, Config). +%%%----------------------------------------------------------------- +%%% +timetrap_end_conf(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + Join = fun(D, S) -> filename:join(D, "error/test/"++S) end, + Suites = [Join(DataDir, "timetrap_1_SUITE")], + {Opts,ERPid} = setup([{suite,Suites}], Config), + ok = ct_test_support:run(Opts, Config), + Events = ct_test_support:get_events(ERPid, Config), + + ct_test_support:log_events(timetrap_end_conf, + reformat(Events, ?eh), + ?config(priv_dir, Config)), + + TestEvents = events_to_check(timetrap_end_conf), + ok = ct_test_support:verify_events(TestEvents, Events, Config). + +%%%----------------------------------------------------------------- +%%% +timetrap_normal(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + Join = fun(D, S) -> filename:join(D, "error/test/"++S) end, + Suite = Join(DataDir, "timetrap_2_SUITE"), + {Opts,ERPid} = setup([{suite,Suite}, + {userconfig,{ct_userconfig_callback, + "multiply 1 scale false"}}], + Config), + ok = ct_test_support:run(Opts, Config), + Events = ct_test_support:get_events(ERPid, Config), + + ct_test_support:log_events(timetrap_normal, + reformat(Events, ?eh), + ?config(priv_dir, Config)), + + TestEvents = events_to_check(timetrap_normal), + ok = ct_test_support:verify_events(TestEvents, Events, Config). + +%%%----------------------------------------------------------------- +%%% +timetrap_extended(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + Join = fun(D, S) -> filename:join(D, "error/test/"++S) end, + Suite = Join(DataDir, "timetrap_2_SUITE"), + {Opts,ERPid} = setup([{suite,Suite}, + {multiply_timetraps,2}, + {scale_timetraps,false}, + {userconfig,{ct_userconfig_callback, + "multiply 2 scale false"}}], + Config), + ok = ct_test_support:run(Opts, Config), + Events = ct_test_support:get_events(ERPid, Config), + + ct_test_support:log_events(timetrap_extended, + reformat(Events, ?eh), + ?config(priv_dir, Config)), + + TestEvents = events_to_check(timetrap_extended), + ok = ct_test_support:verify_events(TestEvents, Events, Config). %%%----------------------------------------------------------------- %%% HELP FUNCTIONS @@ -142,7 +208,7 @@ setup(Test, Config) -> Opts0 = ct_test_support:get_opts(Config), Level = ?config(trace_level, Config), EvHArgs = [{cbm,ct_test_support},{trace_level,Level}], - Opts = Opts0 ++ [Test,{event_handler,{?eh,EvHArgs}}], + Opts = Opts0 ++ [{event_handler,{?eh,EvHArgs}}|Test], ERPid = ct_test_support:start_event_receiver(Config), {Opts,ERPid}. @@ -154,11 +220,20 @@ reformat(Events, EH) -> %%%----------------------------------------------------------------- %%% TEST EVENTS %%%----------------------------------------------------------------- +events_to_check(Test) -> + %% 2 tests (ct:run_test + script_start) is default + events_to_check(Test, 2). + +events_to_check(_, 0) -> + []; +events_to_check(Test, N) -> + test_events(Test) ++ events_to_check(Test, N-1). + test_events(cfg_error) -> [ {?eh,start_logging,{'DEF','RUNDIR'}}, {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, - {?eh,start_info,{9,9,33}}, + {?eh,start_info,{14,14,42}}, {?eh,tc_start,{cfg_error_1_SUITE,init_per_suite}}, {?eh,tc_done, @@ -470,6 +545,59 @@ test_events(cfg_error) -> {?eh,tc_start,{cfg_error_9_SUITE,end_per_suite}}, {?eh,tc_done,{cfg_error_9_SUITE,end_per_suite,ok}}, + {?eh,tc_start,{cfg_error_10_SUITE,init_per_suite}}, + {?eh,tc_done,{cfg_error_10_SUITE,init_per_suite, + {failed,{error,fail_init_per_suite}}}}, + {?eh,tc_auto_skip,{cfg_error_10_SUITE,tc1, + {failed,{cfg_error_10_SUITE,init_per_suite, + {failed,fail_init_per_suite}}}}}, + {?eh,test_stats,{12,3,{0,19}}}, + {?eh,tc_auto_skip,{cfg_error_10_SUITE,end_per_suite, + {failed,{cfg_error_10_SUITE,init_per_suite, + {failed,fail_init_per_suite}}}}}, + {?eh,tc_start,{cfg_error_11_SUITE,init_per_suite}}, + {?eh,tc_done,{cfg_error_11_SUITE,init_per_suite,ok}}, + {?eh,tc_start,{cfg_error_11_SUITE,tc1}}, + {?eh,tc_done,{cfg_error_11_SUITE,tc1, + {skipped,{config_name_already_in_use,[dummy0]}}}}, + {?eh,test_stats,{12,3,{1,19}}}, + {?eh,tc_start,{cfg_error_11_SUITE,tc2}}, + {?eh,tc_done,{cfg_error_11_SUITE,tc2,ok}}, + {?eh,test_stats,{13,3,{1,19}}}, + {?eh,tc_start,{cfg_error_11_SUITE,end_per_suite}}, + {?eh,tc_done,{cfg_error_11_SUITE,end_per_suite,ok}}, + {?eh,tc_start,{cfg_error_12_SUITE,tc1}}, + {?eh,tc_done,{cfg_error_12_SUITE,tc1,{failed,{timetrap_timeout,500}}}}, + {?eh,test_stats,{13,4,{1,19}}}, + {?eh,tc_start,{cfg_error_12_SUITE,tc2}}, + {?eh,tc_done,{cfg_error_12_SUITE,tc2,{failed, + {cfg_error_12_SUITE,end_per_testcase, + {timetrap_timeout,500}}}}}, + {?eh,test_stats,{14,4,{1,19}}}, + {?eh,tc_start,{cfg_error_12_SUITE,tc3}}, + {?eh,tc_done,{cfg_error_12_SUITE,tc3,ok}}, + {?eh,test_stats,{15,4,{1,19}}}, + {?eh,tc_start,{cfg_error_12_SUITE,tc4}}, + {?eh,tc_done,{cfg_error_12_SUITE,tc4,{failed, + {cfg_error_12_SUITE,end_per_testcase, + {timetrap_timeout,500}}}}}, + {?eh,test_stats,{16,4,{1,19}}}, + {?eh,tc_start,{cfg_error_13_SUITE,init_per_suite}}, + {?eh,tc_done,{cfg_error_13_SUITE,init_per_suite,ok}}, + {?eh,tc_start,{cfg_error_13_SUITE,tc1}}, + {?eh,tc_done,{cfg_error_13_SUITE,tc1,ok}}, + {?eh,test_stats,{17,4,{1,19}}}, + {?eh,tc_start,{cfg_error_13_SUITE,end_per_suite}}, + {?eh,tc_done,{cfg_error_13_SUITE,end_per_suite,ok}}, + {?eh,tc_start,{cfg_error_14_SUITE,init_per_suite}}, + {?eh,tc_done,{cfg_error_14_SUITE,init_per_suite,ok}}, + {?eh,tc_start,{cfg_error_14_SUITE,tc1}}, + {?eh,tc_done,{cfg_error_14_SUITE,tc1,ok}}, + {?eh,test_stats,{18,4,{1,19}}}, + {?eh,tc_start,{cfg_error_14_SUITE,end_per_suite}}, + {?eh,tc_done,{cfg_error_14_SUITE,end_per_suite, + {comment, + "should succeed since ct_fw cancels timetrap in end_tc"}}}, {?eh,test_done,{'DEF','STOP_TIME'}}, {?eh,stop_logging,[]} ]; @@ -555,4 +683,91 @@ test_events(lib_error) -> ]; test_events(no_compile) -> - []. + []; + +test_events(timetrap_end_conf) -> + [ + {?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,6}}, + {?eh,tc_start,{timetrap_1_SUITE,init_per_suite}}, + {?eh,tc_done,{timetrap_1_SUITE,init_per_suite,ok}}, + {?eh,tc_start,{timetrap_1_SUITE,tc1}}, + {?eh,tc_done, + {timetrap_1_SUITE,tc1,{failed,{timetrap_timeout,1000}}}}, + {?eh,test_stats,{0,1,{0,0}}}, + {?eh,tc_start,{timetrap_1_SUITE,tc2}}, + {?eh,tc_done, + {timetrap_1_SUITE,tc2,{failed,{timetrap_timeout,1000}}}}, + {?eh,test_stats,{0,2,{0,0}}}, + {?eh,tc_start,{timetrap_1_SUITE,tc3}}, + {?eh,tc_done, + {timetrap_1_SUITE,tc3,{failed,{testcase_aborted,testing_end_conf}}}}, + {?eh,test_stats,{0,3,{0,0}}}, + {?eh,tc_start,{timetrap_1_SUITE,tc4}}, + {?eh,tc_done, + {timetrap_1_SUITE,tc4,{failed,{testcase_aborted,testing_end_conf}}}}, + {?eh,test_stats,{0,4,{0,0}}}, + {?eh,tc_start,{timetrap_1_SUITE,tc5}}, + {?eh,tc_done, + {timetrap_1_SUITE,tc5,{failed,{timetrap_timeout,1000}}}}, + {?eh,test_stats,{0,5,{0,0}}}, + {?eh,tc_start,{timetrap_1_SUITE,tc6}}, + {?eh,tc_done, + {timetrap_1_SUITE,tc6,{failed,{testcase_aborted,testing_end_conf}}}}, + {?eh,test_stats,{0,6,{0,0}}}, + {?eh,tc_start,{timetrap_1_SUITE,end_per_suite}}, + {?eh,tc_done,{timetrap_1_SUITE,end_per_suite,ok}}, + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]} + ]; + +test_events(timetrap_normal) -> + [ + {?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,3}}, + {?eh,tc_start,{timetrap_2_SUITE,init_per_suite}}, + {?eh,tc_done,{timetrap_2_SUITE,init_per_suite,ok}}, + {?eh,tc_start,{timetrap_2_SUITE,tc0}}, + {?eh,tc_done, + {timetrap_2_SUITE,tc0,{failed,{timetrap_timeout,3000}}}}, + {?eh,test_stats,{0,1,{0,0}}}, + {?eh,tc_start,{timetrap_2_SUITE,tc1}}, + {?eh,tc_done, + {timetrap_2_SUITE,tc1,{failed,{timetrap_timeout,1000}}}}, + {?eh,test_stats,{0,2,{0,0}}}, + {?eh,tc_start,{timetrap_2_SUITE,tc2}}, + {?eh,tc_done, + {timetrap_2_SUITE,tc2,{failed,{timetrap_timeout,500}}}}, + {?eh,test_stats,{0,3,{0,0}}}, + {?eh,tc_start,{timetrap_2_SUITE,end_per_suite}}, + {?eh,tc_done,{timetrap_2_SUITE,end_per_suite,ok}}, + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]} + ]; + +test_events(timetrap_extended) -> + [ + {?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,3}}, + {?eh,tc_start,{timetrap_2_SUITE,init_per_suite}}, + {?eh,tc_done,{timetrap_2_SUITE,init_per_suite,ok}}, + {?eh,tc_start,{timetrap_2_SUITE,tc0}}, + {?eh,tc_done, + {timetrap_2_SUITE,tc0,{failed,{timetrap_timeout,6000}}}}, + {?eh,test_stats,{0,1,{0,0}}}, + {?eh,tc_start,{timetrap_2_SUITE,tc1}}, + {?eh,tc_done, + {timetrap_2_SUITE,tc1,{failed,{timetrap_timeout,2000}}}}, + {?eh,test_stats,{0,2,{0,0}}}, + {?eh,tc_start,{timetrap_2_SUITE,tc2}}, + {?eh,tc_done, + {timetrap_2_SUITE,tc2,{failed,{timetrap_timeout,1000}}}}, + {?eh,test_stats,{0,3,{0,0}}}, + {?eh,tc_start,{timetrap_2_SUITE,end_per_suite}}, + {?eh,tc_done,{timetrap_2_SUITE,end_per_suite,ok}}, + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]} + ]. diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_10_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_10_SUITE.erl new file mode 100644 index 0000000000..9f9a90372b --- /dev/null +++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_10_SUITE.erl @@ -0,0 +1,123 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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(cfg_error_10_SUITE). + +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +%%-------------------------------------------------------------------- +%% Function: suite() -> Info +%% Info = [tuple()] +%%-------------------------------------------------------------------- +suite() -> + [{timetrap,{seconds,2}}, + {require, dummy0}, {default_config, dummy0, "suite/0"}, + {require, dummy1}, {default_config, dummy1, "suite/0"}, + {require, dummy2}, {default_config, dummy2, "suite/0"}]. + +%%-------------------------------------------------------------------- +%% Function: init_per_suite(Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% Config0 = Config1 = [tuple()] +%% Reason = term() +%%-------------------------------------------------------------------- +init_per_suite() -> + put('$test_server_framework_test', + fun(init_tc, _Default) -> {fail,fail_init_per_suite}; + (_, Default) -> Default + end), + [{require, dummy3}, {default_config, dummy3, "init_per_suite/0"}, + {timetrap,3000}]. + +init_per_suite(Config) -> + Config. + +%%-------------------------------------------------------------------- +%% Function: end_per_suite(Config0) -> void() | {save_config,Config1} +%% Config0 = Config1 = [tuple()] +%%-------------------------------------------------------------------- +end_per_suite(Config) -> + ok. + +%%-------------------------------------------------------------------- +%% Function: init_per_group(GroupName, Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% GroupName = atom() +%% Config0 = Config1 = [tuple()] +%% Reason = term() +%%-------------------------------------------------------------------- +init_per_group(_GroupName, Config) -> + Config. + +%%-------------------------------------------------------------------- +%% Function: end_per_group(GroupName, Config0) -> +%% void() | {save_config,Config1} +%% GroupName = atom() +%% Config0 = Config1 = [tuple()] +%%-------------------------------------------------------------------- +end_per_group(_GroupName, _Config) -> + ok. + +%%-------------------------------------------------------------------- +%% Function: init_per_testcase(TestCase, Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% TestCase = atom() +%% Config0 = Config1 = [tuple()] +%% Reason = term() +%%-------------------------------------------------------------------- +init_per_testcase(_, Config) -> + Config. + +%%-------------------------------------------------------------------- +%% Function: end_per_testcase(TestCase, Config0) -> +%% void() | {save_config,Config1} +%% TestCase = atom() +%% Config0 = Config1 = [tuple()] +%%-------------------------------------------------------------------- +end_per_testcase(_TestCase, _Config) -> + done. + +%%-------------------------------------------------------------------- +%% Function: groups() -> [Group] +%% Group = {GroupName,Properties,GroupsAndTestCases} +%% GroupName = atom() +%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}] +%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase] +%% TestCase = atom() +%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}} +%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail | +%% repeat_until_any_ok | repeat_until_any_fail +%% N = integer() | forever +%%-------------------------------------------------------------------- +groups() -> + []. + +%%-------------------------------------------------------------------- +%% Function: all() -> GroupsAndTestCases | {skip,Reason} +%% GroupsAndTestCases = [{group,GroupName} | TestCase] +%% GroupName = atom() +%% TestCase = atom() +%% Reason = term() +%%-------------------------------------------------------------------- +all() -> + [tc1]. + +tc1(_) -> + exit(should_never_run). diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_11_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_11_SUITE.erl new file mode 100644 index 0000000000..ce94533110 --- /dev/null +++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_11_SUITE.erl @@ -0,0 +1,134 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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(cfg_error_11_SUITE). + +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +%%-------------------------------------------------------------------- +%% Function: suite() -> Info +%% Info = [tuple()] +%%-------------------------------------------------------------------- +suite() -> + [{timetrap,{seconds,2}}, + {require, dummy0}, {default_config, dummy0, "suite/0"}, + {require, dummy1}, {default_config, dummy1, "suite/0"}, + {require, dummy2}, {default_config, dummy2, "suite/0"}]. + + + +%%-------------------------------------------------------------------- +%% Function: init_per_suite(Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% Config0 = Config1 = [tuple()] +%% Reason = term() +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + Config. + +%%-------------------------------------------------------------------- +%% Function: end_per_suite(Config0) -> void() | {save_config,Config1} +%% Config0 = Config1 = [tuple()] +%%-------------------------------------------------------------------- +end_per_suite() -> + put('$test_server_framework_test', + fun(end_tc, _Default) -> {fail,fail_end_per_suite}; + (_, Default) -> Default + end), + [{require, dummy3}, {default_config, dummy3, "end_per_suite/0"}, + {timetrap,3000}]. + +end_per_suite(_Config) -> + ok. + +%%-------------------------------------------------------------------- +%% Function: init_per_group(GroupName, Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% GroupName = atom() +%% Config0 = Config1 = [tuple()] +%% Reason = term() +%%-------------------------------------------------------------------- +init_per_group(_GroupName, Config) -> + Config. + +%%-------------------------------------------------------------------- +%% Function: end_per_group(GroupName, Config0) -> +%% void() | {save_config,Config1} +%% GroupName = atom() +%% Config0 = Config1 = [tuple()] +%%-------------------------------------------------------------------- +end_per_group(_GroupName, _Config) -> + ok. + +%%-------------------------------------------------------------------- +%% Function: init_per_testcase(TestCase, Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% TestCase = atom() +%% Config0 = Config1 = [tuple()] +%% Reason = term() +%%-------------------------------------------------------------------- +init_per_testcase(_, Config) -> + Config. + +%%-------------------------------------------------------------------- +%% Function: end_per_testcase(TestCase, Config0) -> +%% void() | {save_config,Config1} +%% TestCase = atom() +%% Config0 = Config1 = [tuple()] +%%-------------------------------------------------------------------- +end_per_testcase(_TestCase, _Config) -> + done. + +%%-------------------------------------------------------------------- +%% Function: groups() -> [Group] +%% Group = {GroupName,Properties,GroupsAndTestCases} +%% GroupName = atom() +%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}] +%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase] +%% TestCase = atom() +%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}} +%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail | +%% repeat_until_any_ok | repeat_until_any_fail +%% N = integer() | forever +%%-------------------------------------------------------------------- +groups() -> + []. + +%%-------------------------------------------------------------------- +%% Function: all() -> GroupsAndTestCases | {skip,Reason} +%% GroupsAndTestCases = [{group,GroupName} | TestCase] +%% GroupName = atom() +%% TestCase = atom() +%% Reason = term() +%%-------------------------------------------------------------------- +all() -> + [tc1, tc2]. + +tc1() -> + [{require, dummy0}, {default_config, dummy0, "tc1"}]. + +tc1(_) -> + dummy. + +tc2() -> + [{timetrap,1}]. + +tc2(_) -> + dummy. diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_12_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_12_SUITE.erl new file mode 100644 index 0000000000..806d3caf72 --- /dev/null +++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_12_SUITE.erl @@ -0,0 +1,88 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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(cfg_error_12_SUITE). + +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +init_per_testcase(_, Config) -> + Config. + +end_per_testcase(tc2, _Config) -> + timer:sleep(2000), + exit(this_should_not_be_printed); +end_per_testcase(tc4, _Config) -> + timer:sleep(2000), + exit(this_should_not_be_printed); +end_per_testcase(_, _) -> + ok. + +all() -> + [tc1, tc2, tc3, tc4]. + +%%%----------------------------------------------------------------- +tc1() -> + put('$test_server_framework_test', + fun(init_tc, _Default) -> + ct:pal("init_tc(~p): Night time...",[self()]), + timer:sleep(2000), + ct:pal("init_tc(~p): Day time!",[self()]), + exit(this_should_not_be_printed); + (_, Default) -> Default + end), + [{timetrap,500}]. + +tc1(_) -> + exit(this_should_not_be_printed). + +%%%----------------------------------------------------------------- +tc2() -> + [{timetrap,500}]. + +tc2(_) -> + ok. + +%%%----------------------------------------------------------------- +tc3() -> + [{timetrap,500}]. + +tc3(_) -> + put('$test_server_framework_test', + fun(end_tc, _Default) -> + ct:pal("end_tc(~p): Night time...",[self()]), + timer:sleep(1000), + ct:pal("end_tc(~p): Day time!",[self()]); + (_, Default) -> Default + end), + {comment,"should succeed since ct_fw cancels timetrap in end_tc"}. + +%%%----------------------------------------------------------------- +tc4() -> + put('$test_server_framework_test', + fun(end_tc, _Default) -> + ct:pal("end_tc(~p): Night time...",[self()]), + timer:sleep(1000), + ct:pal("end_tc(~p): Day time!",[self()]); + (_, Default) -> Default + end), + [{timetrap,500}]. + +tc4(_) -> + ok. diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_13_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_13_SUITE.erl new file mode 100644 index 0000000000..c8a3c1d15e --- /dev/null +++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_13_SUITE.erl @@ -0,0 +1,47 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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(cfg_error_13_SUITE). + +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +init_per_suite() -> + put('$test_server_framework_test', + fun(end_tc, _Default) -> + ct:pal("end_tc(~p): Night time...",[self()]), + timer:sleep(1000), + ct:pal("end_tc(~p): Day time!",[self()]); + (_, Default) -> Default + end), + [{timetrap,500}]. + +init_per_suite(Config) -> + ct:comment("should succeed since ct_fw cancels timetrap in end_tc"), + Config. + +end_per_suite(_) -> + ok. + +all() -> + [tc1]. + +%%%----------------------------------------------------------------- +tc1(_) -> + dummy. diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_14_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_14_SUITE.erl new file mode 100644 index 0000000000..960d0f61b0 --- /dev/null +++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_14_SUITE.erl @@ -0,0 +1,46 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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(cfg_error_14_SUITE). + +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +init_per_suite(Config) -> + Config. + +end_per_suite() -> + put('$test_server_framework_test', + fun(end_tc, _Default) -> + ct:pal("end_tc(~p): Night time...",[self()]), + timer:sleep(1000), + ct:pal("end_tc(~p): Day time!",[self()]); + (_, Default) -> Default + end), + [{timetrap,500}]. + +end_per_suite(_Config) -> + {comment,"should succeed since ct_fw cancels timetrap in end_tc"}. + +all() -> + [tc1]. + +%%%----------------------------------------------------------------- +tc1(_) -> + dummy. diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_3_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_3_SUITE.erl index bf01bb52d9..08c57887ef 100644 --- a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_3_SUITE.erl +++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_3_SUITE.erl @@ -37,7 +37,8 @@ suite() -> %%-------------------------------------------------------------------- init_per_suite(Config) -> timer:sleep(5000), - Config. + exit(shouldnt_happen). +% Config. %%-------------------------------------------------------------------- %% Function: end_per_suite(Config0) -> void() | {save_config,Config1} diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_1_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_1_SUITE.erl new file mode 100644 index 0000000000..cb3109349b --- /dev/null +++ b/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_1_SUITE.erl @@ -0,0 +1,194 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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(timetrap_1_SUITE). + +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +%%-------------------------------------------------------------------- +%% Function: suite() -> Info +%% Info = [tuple()] +%%-------------------------------------------------------------------- +suite() -> + [{timetrap,{seconds,1}}]. + +%%-------------------------------------------------------------------- +%% Function: init_per_suite(Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% Config0 = Config1 = [tuple()] +%% Reason = term() +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + TabPid = spawn(fun() -> + ets:new(?MODULE, [named_table, set, public]), + ets:insert(?MODULE, {last_case,ok}), + receive _ -> ok end + end), + [{tab,TabPid} | Config]. + +%%-------------------------------------------------------------------- +%% Function: end_per_suite(Config0) -> void() | {save_config,Config1} +%% Config0 = Config1 = [tuple()] +%%-------------------------------------------------------------------- +end_per_suite(Config) -> + exit(?config(tab, Config), kill), + ok. + +%%-------------------------------------------------------------------- +%% Function: init_per_group(GroupName, Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% GroupName = atom() +%% Config0 = Config1 = [tuple()] +%% Reason = term() +%%-------------------------------------------------------------------- +init_per_group(_GroupName, Config) -> + Config. + +%%-------------------------------------------------------------------- +%% Function: end_per_group(GroupName, Config0) -> +%% void() | {save_config,Config1} +%% GroupName = atom() +%% Config0 = Config1 = [tuple()] +%%-------------------------------------------------------------------- +end_per_group(_GroupName, _Config) -> + ok. + +%%-------------------------------------------------------------------- +%% Function: init_per_testcase(TestCase, Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% TestCase = atom() +%% Config0 = Config1 = [tuple()] +%% Reason = term() +%%-------------------------------------------------------------------- +init_per_testcase(TC, Config) -> + {_,_} = process_info(?config(tab, Config), priority), + [{_,ok}] = ets:lookup(?MODULE, last_case), + ets:insert(?MODULE, {last_case,fail}), + init_per_testcase1(TC, Config). + +init_per_testcase1(tc1, Config) -> + [{tc,tc1}|Config]; + +init_per_testcase1(tc2, Config) -> + [{tc,tc2}|Config]; + +init_per_testcase1(tc3, Config) -> + [{tc,tc3}|Config]; + +init_per_testcase1(tc4, Config) -> + [{tc,tc4},{default_timeout,5000}|Config]; + +init_per_testcase1(tc5, Config) -> + [{tc,tc5}|Config]; + +init_per_testcase1(tc6, Config) -> + [{tc,tc6}|Config]. + +%%-------------------------------------------------------------------- +%% Function: end_per_testcase(TestCase, Config0) -> +%% void() | {save_config,Config1} +%% TestCase = atom() +%% Config0 = Config1 = [tuple()] +%%-------------------------------------------------------------------- +end_per_testcase(TC, Config) -> + {_,_} = process_info(?config(tab, Config), priority), + [{_,fail}] = ets:lookup(?MODULE, last_case), + ets:insert(?MODULE, {last_case,ok}), + end_per_testcase1(TC, Config). + +end_per_testcase1(tc1, Config) -> + ct:pal("end_per_testcase(tc1): ~p", [Config]), + tc1 = ?config(tc, Config), + {failed,timetrap_timeout} = ?config(tc_status, Config), + ok; + +end_per_testcase1(tc2, Config) -> + ct:pal("end_per_testcase(tc2): ~p", [Config]), + tc2 = ?config(tc, Config), + {failed,timetrap_timeout} = ?config(tc_status, Config), + timer:sleep(2000); + +end_per_testcase1(tc3, Config) -> + ct:pal("end_per_testcase(tc3): ~p", [Config]), + tc3 = ?config(tc, Config), + {failed,{testcase_aborted,testing_end_conf}} = ?config(tc_status, Config), + ok; + +end_per_testcase1(tc4, Config) -> + ct:pal("end_per_testcase(tc4): ~p", [Config]), + tc4 = ?config(tc, Config), + {failed,{testcase_aborted,testing_end_conf}} = ?config(tc_status, Config), + timer:sleep(2000); + +end_per_testcase1(tc5, Config) -> + ct:pal("end_per_testcase(tc5): ~p", [Config]), + tc5 = ?config(tc, Config), + exit(end_per_tc_fail_after_timeout); + +end_per_testcase1(tc6, Config) -> + ct:pal("end_per_testcase(tc6): ~p", [Config]), + tc6 = ?config(tc, Config), + exit(end_per_tc_fail_after_abort). + +%%-------------------------------------------------------------------- +%% Function: groups() -> [Group] +%% Group = {GroupName,Properties,GroupsAndTestCases} +%% GroupName = atom() +%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}] +%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase] +%% TestCase = atom() +%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}} +%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail | +%% repeat_until_any_ok | repeat_until_any_fail +%% N = integer() | forever +%%-------------------------------------------------------------------- +groups() -> + []. + +%%-------------------------------------------------------------------- +%% Function: all() -> GroupsAndTestCases | {skip,Reason} +%% GroupsAndTestCases = [{group,GroupName} | TestCase] +%% GroupName = atom() +%% TestCase = atom() +%% Reason = term() +%%-------------------------------------------------------------------- +all() -> + [tc1, tc2, tc3, tc4, tc5, tc6]. + +tc1(_) -> + timer:sleep(2000). + +tc2(_) -> + timer:sleep(2000). + +tc3(_) -> + spawn(ct, abort_current_testcase, [testing_end_conf]), + timer:sleep(2000). + +tc4(_) -> + spawn(ct, abort_current_testcase, [testing_end_conf]), + timer:sleep(2000). + +tc5(_) -> + timer:sleep(2000). + +tc6(_) -> + spawn(ct, abort_current_testcase, [testing_end_conf]), + timer:sleep(2000). diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_2_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_2_SUITE.erl new file mode 100644 index 0000000000..99bb400137 --- /dev/null +++ b/lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_2_SUITE.erl @@ -0,0 +1,138 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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(timetrap_2_SUITE). + +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +%%-------------------------------------------------------------------- +%% Function: suite() -> Info +%% Info = [tuple()] +%%-------------------------------------------------------------------- +suite() -> + [{timetrap,{seconds,3}}, + {require,multiply}, + {require,scale}]. + +%%-------------------------------------------------------------------- +%% Function: init_per_suite(Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% Config0 = Config1 = [tuple()] +%% Reason = term() +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + Config. + +%%-------------------------------------------------------------------- +%% Function: end_per_suite(Config0) -> void() | {save_config,Config1} +%% Config0 = Config1 = [tuple()] +%%-------------------------------------------------------------------- +end_per_suite(_Config) -> + ok. + +%%-------------------------------------------------------------------- +%% Function: init_per_group(GroupName, Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% GroupName = atom() +%% Config0 = Config1 = [tuple()] +%% Reason = term() +%%-------------------------------------------------------------------- +init_per_group(_GroupName, Config) -> + Config. + +%%-------------------------------------------------------------------- +%% Function: end_per_group(GroupName, Config0) -> +%% void() | {save_config,Config1} +%% GroupName = atom() +%% Config0 = Config1 = [tuple()] +%%-------------------------------------------------------------------- +end_per_group(_GroupName, _Config) -> + ok. + +%%-------------------------------------------------------------------- +%% Function: init_per_testcase(TestCase, Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% TestCase = atom() +%% Config0 = Config1 = [tuple()] +%% Reason = term() +%%-------------------------------------------------------------------- +init_per_testcase(tc1, Config) -> + ct:timetrap({seconds,1}), + Config; + +init_per_testcase(tc3, Config) -> + ct:timetrap({seconds,1}), + Config; + +init_per_testcase(_TestCase, Config) -> + Config. + +%%-------------------------------------------------------------------- +%% Function: end_per_testcase(TestCase, Config0) -> +%% void() | {save_config,Config1} +%% TestCase = atom() +%% Config0 = Config1 = [tuple()] +%%-------------------------------------------------------------------- +end_per_testcase(_, Config) -> + ok. + +%%-------------------------------------------------------------------- +%% Function: groups() -> [Group] +%% Group = {GroupName,Properties,GroupsAndTestCases} +%% GroupName = atom() +%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}] +%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase] +%% TestCase = atom() +%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}} +%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail | +%% repeat_until_any_ok | repeat_until_any_fail +%% N = integer() | forever +%%-------------------------------------------------------------------- +groups() -> + []. + +%%-------------------------------------------------------------------- +%% Function: all() -> GroupsAndTestCases | {skip,Reason} +%% GroupsAndTestCases = [{group,GroupName} | TestCase] +%% GroupName = atom() +%% TestCase = atom() +%% Reason = term() +%%-------------------------------------------------------------------- +all() -> + [tc0,tc1,tc2]. + +tc0(_) -> + N = list_to_integer(ct:get_config(multiply)), + ct:comment(io_lib:format("TO after ~w sec", [3*N])), + ct:sleep({seconds,5}), + ok. + +tc1(_) -> + N =list_to_integer( ct:get_config(multiply)), + ct:comment(io_lib:format("TO after ~w sec", [1*N])), + ct:sleep({seconds,5}), + ok. + +tc2(_) -> + N = list_to_integer(ct:get_config(multiply)), + ct:comment(io_lib:format("TO after ~w sec", [0.5*N])), + ct:timetrap(500), + ct:sleep(2000), + ok. diff --git a/lib/common_test/test/ct_event_handler_SUITE.erl b/lib/common_test/test/ct_event_handler_SUITE.erl index bafd32f937..00a4c4ded3 100644 --- a/lib/common_test/test/ct_event_handler_SUITE.erl +++ b/lib/common_test/test/ct_event_handler_SUITE.erl @@ -88,7 +88,7 @@ start_stop(Config) when is_list(Config) -> ERPid = ct_test_support:start_event_receiver(Config), - ok = ct_test_support:run(ct, run_test, [Opts], Config), + ok = ct_test_support:run(Opts, Config), Events = ct_test_support:get_events(ERPid, Config), @@ -110,8 +110,7 @@ start_stop(Config) when is_list(Config) -> {eh_A,test_done,{'DEF','STOP_TIME'}}, {eh_A,stop_logging,[]}], - ok = ct_test_support:verify_events(TestEvents, Events, Config), - {comment,"NOTE! Known problem with test_start event!"}. + ok = ct_test_support:verify_events(TestEvents++TestEvents, Events, Config). results(doc) -> @@ -135,7 +134,7 @@ results(Config) when is_list(Config) -> ERPid = ct_test_support:start_event_receiver(Config), - ok = ct_test_support:run(ct, run_test, [Opts], Config), + ok = ct_test_support:run(Opts, Config), Events = ct_test_support:get_events(ERPid, Config), @@ -163,7 +162,7 @@ results(Config) when is_list(Config) -> {eh_A,test_done,{'DEF','STOP_TIME'}}, {eh_A,stop_logging,[]}], - ok = ct_test_support:verify_events(TestEvents, Events, Config). + ok = ct_test_support:verify_events(TestEvents++TestEvents, Events, Config). %%%----------------------------------------------------------------- diff --git a/lib/common_test/test/ct_event_handler_SUITE_data/eh_A.erl b/lib/common_test/test/ct_event_handler_SUITE_data/eh_A.erl index 6e526f15a2..54cf3a22e7 100644 --- a/lib/common_test/test/ct_event_handler_SUITE_data/eh_A.erl +++ b/lib/common_test/test/ct_event_handler_SUITE_data/eh_A.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -44,6 +44,19 @@ %% Description: Whenever a new event handler is added to an event manager, %% this function is called to initialize the event handler. %%-------------------------------------------------------------------- +init(String = [X|_]) when is_integer(X) -> + case erl_scan:string(String++".") of + {ok,Ts,_} -> + case erl_parse:parse_term(Ts) of + {ok,Args} -> + init(Args); + _ -> + init(String) + end; + _ -> + init(String) + end; + init(Args) -> S1 = case lists:keysearch(cbm, 1, Args) of diff --git a/lib/common_test/test/ct_groups_test_1_SUITE.erl b/lib/common_test/test/ct_groups_test_1_SUITE.erl index 1761b773f5..64d61fc104 100644 --- a/lib/common_test/test/ct_groups_test_1_SUITE.erl +++ b/lib/common_test/test/ct_groups_test_1_SUITE.erl @@ -76,14 +76,14 @@ groups_suite_1(Config) when is_list(Config) -> Suite = filename:join(DataDir, "groups_1/test/groups_11_SUITE"), {Opts,ERPid} = setup({suite,Suite}, Config), - ok = ct_test_support:run(ct, run_test, [Opts], Config), + ok = ct_test_support:run(Opts, Config), Events = ct_test_support:get_events(ERPid, Config), ct_test_support:log_events(groups_suite_1, reformat(Events, ?eh), ?config(priv_dir, Config)), - TestEvents = test_events(groups_suite_1), + TestEvents = events_to_check(groups_suite_1), ok = ct_test_support:verify_events(TestEvents, Events, Config). @@ -96,14 +96,14 @@ groups_suite_2(Config) when is_list(Config) -> Suite = filename:join(DataDir, "groups_1/test/groups_12_SUITE"), {Opts,ERPid} = setup({suite,Suite}, Config), - ok = ct_test_support:run(ct, run_test, [Opts], Config), + ok = ct_test_support:run(Opts, Config), Events = ct_test_support:get_events(ERPid, Config), ct_test_support:log_events(groups_suite_2, reformat(Events, ?eh), ?config(priv_dir, Config)), - TestEvents = test_events(groups_suite_2), + TestEvents = events_to_check(groups_suite_2), ok = ct_test_support:verify_events(TestEvents, Events, Config). @@ -117,14 +117,14 @@ groups_suites_1(Config) when is_list(Config) -> filename:join(DataDir, "groups_1/test/groups_12_SUITE")], {Opts,ERPid} = setup({suite,Suites}, Config), - ok = ct_test_support:run(ct, run_test, [Opts], Config), + ok = ct_test_support:run(Opts, Config), Events = ct_test_support:get_events(ERPid, Config), ct_test_support:log_events(groups_suites_1, reformat(Events, ?eh), ?config(priv_dir, Config)), - TestEvents = test_events(groups_suites_1), + TestEvents = events_to_check(groups_suites_1), ok = ct_test_support:verify_events(TestEvents, Events, Config). @@ -137,14 +137,14 @@ groups_dir_1(Config) when is_list(Config) -> Dir = filename:join(DataDir, "groups_1"), {Opts,ERPid} = setup({dir,Dir}, Config), - ok = ct_test_support:run(ct, run_test, [Opts], Config), + ok = ct_test_support:run(Opts, Config), Events = ct_test_support:get_events(ERPid, Config), ct_test_support:log_events(groups_dir_1, reformat(Events, ?eh), ?config(priv_dir, Config)), - TestEvents = test_events(groups_dir_1), + TestEvents = events_to_check(groups_dir_1), ok = ct_test_support:verify_events(TestEvents, Events, Config). %%%----------------------------------------------------------------- @@ -157,14 +157,14 @@ groups_dirs_1(Config) when is_list(Config) -> filename:join(DataDir, "groups_2")], {Opts,ERPid} = setup({dir,Dirs}, Config), - ok = ct_test_support:run(ct, run_test, [Opts], Config), + ok = ct_test_support:run(Opts, Config), Events = ct_test_support:get_events(ERPid, Config), ct_test_support:log_events(groups_dirs_1, reformat(Events, ?eh), ?config(priv_dir, Config)), - TestEvents = test_events(groups_dirs_1), + TestEvents = events_to_check(groups_dirs_1), ok = ct_test_support:verify_events(TestEvents, Events, Config). @@ -188,6 +188,14 @@ reformat(Events, EH) -> %%%----------------------------------------------------------------- %%% TEST EVENTS %%%----------------------------------------------------------------- +events_to_check(Test) -> + %% 2 tests (ct:run_test + script_start) is default + events_to_check(Test, 2). + +events_to_check(_, 0) -> + []; +events_to_check(Test, N) -> + test_events(Test) ++ events_to_check(Test, N-1). test_events(groups_suite_1) -> [{?eh,start_logging,{'DEF','RUNDIR'}}, @@ -327,14 +335,14 @@ test_events(groups_suite_2) -> {?eh,tc_start,{groups_12_SUITE,testcase_2a}}, {?eh,tc_done,{groups_12_SUITE,testcase_2a,ok}}, - [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_3,[{repeat,1}]}}}, - {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_3,[{repeat,1}]},ok}}, + [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_3,[{repeat,2}]}}}, + {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_3,[{repeat,2}]},ok}}, {?eh,tc_start,{groups_12_SUITE,testcase_3a}}, {?eh,tc_done,{groups_12_SUITE,testcase_3a,ok}}, {?eh,tc_start,{groups_12_SUITE,testcase_3b}}, {?eh,tc_done,{groups_12_SUITE,testcase_3b,ok}}, - {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_3,[{repeat,1}]}}}, - {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_3,[{repeat,1}]},ok}}], + {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_3,[{repeat,2}]}}}, + {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_3,[{repeat,2}]},ok}}], [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_3,[]}}}, {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_3,[]},ok}}, @@ -361,12 +369,8 @@ test_events(groups_suite_2) -> {parallel,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_5,[parallel]}}}, {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_5,[parallel]},ok}}, - - %% the done event could come in during the parallel subgroup - %% and we can't test that, yet... - %% {?eh,tc_start,{groups_12_SUITE,testcase_5a}}, - %% {?eh,tc_done,{groups_12_SUITE,testcase_5a,ok}}, - + {?eh,tc_start,{groups_12_SUITE,testcase_5a}}, + {?eh,tc_done,{groups_12_SUITE,testcase_5a,ok}}, {parallel,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_6,[parallel]}}}, {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_6,[parallel]},ok}}, @@ -525,14 +529,14 @@ test_events(groups_suites_1) -> {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_2,[parallel]},ok}}, {?eh,tc_start,{groups_12_SUITE,testcase_2a}}, {?eh,tc_done,{groups_12_SUITE,testcase_2a,ok}}, - [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_3,[{repeat,1}]}}}, - {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_3,[{repeat,1}]},ok}}, + [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_3,[{repeat,2}]}}}, + {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_3,[{repeat,2}]},ok}}, {?eh,tc_start,{groups_12_SUITE,testcase_3a}}, {?eh,tc_done,{groups_12_SUITE,testcase_3a,ok}}, {?eh,tc_start,{groups_12_SUITE,testcase_3b}}, {?eh,tc_done,{groups_12_SUITE,testcase_3b,ok}}, - {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_3,[{repeat,1}]}}}, - {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_3,[{repeat,1}]},ok}}], + {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_3,[{repeat,2}]}}}, + {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_3,[{repeat,2}]},ok}}], [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_3,[]}}}, {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_3,[]},ok}}, {?eh,tc_start,{groups_12_SUITE,testcase_3a}}, @@ -555,12 +559,8 @@ test_events(groups_suites_1) -> {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_4,[]},ok}}, {parallel,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_5,[parallel]}}}, {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_5,[parallel]},ok}}, - - %% the done event could come in during the parallel subgroup - %% and we can't test that, yet... - %% {?eh,tc_start,{groups_12_SUITE,testcase_5a}}, - %% {?eh,tc_done,{groups_12_SUITE,testcase_5a,ok}}, - + {?eh,tc_start,{groups_12_SUITE,testcase_5a}}, + {?eh,tc_done,{groups_12_SUITE,testcase_5a,ok}}, {parallel,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_6,[parallel]}}}, {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_6,[parallel]},ok}}, [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_7,[sequence]}}}, @@ -715,14 +715,14 @@ test_events(groups_dir_1) -> {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_2,[parallel]},ok}}, {?eh,tc_start,{groups_12_SUITE,testcase_2a}}, {?eh,tc_done,{groups_12_SUITE,testcase_2a,ok}}, - [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_3,[{repeat,1}]}}}, - {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_3,[{repeat,1}]},ok}}, + [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_3,[{repeat,2}]}}}, + {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_3,[{repeat,2}]},ok}}, {?eh,tc_start,{groups_12_SUITE,testcase_3a}}, {?eh,tc_done,{groups_12_SUITE,testcase_3a,ok}}, {?eh,tc_start,{groups_12_SUITE,testcase_3b}}, {?eh,tc_done,{groups_12_SUITE,testcase_3b,ok}}, - {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_3,[{repeat,1}]}}}, - {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_3,[{repeat,1}]},ok}}], + {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_3,[{repeat,2}]}}}, + {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_3,[{repeat,2}]},ok}}], [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_3,[]}}}, {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_3,[]},ok}}, {?eh,tc_start,{groups_12_SUITE,testcase_3a}}, @@ -745,12 +745,8 @@ test_events(groups_dir_1) -> {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_4,[]},ok}}, {parallel,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_5,[parallel]}}}, {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_5,[parallel]},ok}}, - - %% the done event could come in during the parallel subgroup - %% and we can't test that, yet... - %% {?eh,tc_start,{groups_12_SUITE,testcase_5a}}, - %% {?eh,tc_done,{groups_12_SUITE,testcase_5a,ok}}, - + {?eh,tc_start,{groups_12_SUITE,testcase_5a}}, + {?eh,tc_done,{groups_12_SUITE,testcase_5a,ok}}, {parallel,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_6,[parallel]}}}, {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_6,[parallel]},ok}}, [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_7,[sequence]}}}, @@ -906,14 +902,14 @@ test_events(groups_dirs_1) -> {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_2,[parallel]},ok}}, {?eh,tc_start,{groups_12_SUITE,testcase_2a}}, {?eh,tc_done,{groups_12_SUITE,testcase_2a,ok}}, - [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_3,[{repeat,1}]}}}, - {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_3,[{repeat,1}]},ok}}, + [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_3,[{repeat,2}]}}}, + {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_3,[{repeat,2}]},ok}}, {?eh,tc_start,{groups_12_SUITE,testcase_3a}}, {?eh,tc_done,{groups_12_SUITE,testcase_3a,ok}}, {?eh,tc_start,{groups_12_SUITE,testcase_3b}}, {?eh,tc_done,{groups_12_SUITE,testcase_3b,ok}}, - {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_3,[{repeat,1}]}}}, - {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_3,[{repeat,1}]},ok}}], + {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_3,[{repeat,2}]}}}, + {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_3,[{repeat,2}]},ok}}], [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_3,[]}}}, {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_3,[]},ok}}, {?eh,tc_start,{groups_12_SUITE,testcase_3a}}, @@ -936,12 +932,8 @@ test_events(groups_dirs_1) -> {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_4,[]},ok}}, {parallel,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_5,[parallel]}}}, {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_5,[parallel]},ok}}, - - %% the done event could come in during the parallel subgroup - %% and we can't test that, yet... - %% {?eh,tc_start,{groups_12_SUITE,testcase_5a}}, - %% {?eh,tc_done,{groups_12_SUITE,testcase_5a,ok}}, - + {?eh,tc_start,{groups_12_SUITE,testcase_5a}}, + {?eh,tc_done,{groups_12_SUITE,testcase_5a,ok}}, {parallel,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_6,[parallel]}}}, {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_6,[parallel]},ok}}, [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_7,[sequence]}}}, @@ -1138,17 +1130,17 @@ test_events(groups_dirs_1) -> {?eh,tc_start,{groups_22_SUITE,testcase_2a}}, {?eh,tc_done,{groups_22_SUITE,testcase_2a,ok}}, [{?eh,tc_start, - {groups_22_SUITE,{init_per_group,test_group_3,[{repeat,1}]}}}, + {groups_22_SUITE,{init_per_group,test_group_3,[{repeat,2}]}}}, {?eh,tc_done, - {groups_22_SUITE,{init_per_group,test_group_3,[{repeat,1}]},ok}}, + {groups_22_SUITE,{init_per_group,test_group_3,[{repeat,2}]},ok}}, {?eh,tc_start,{groups_22_SUITE,testcase_3a}}, {?eh,tc_done,{groups_22_SUITE,testcase_3a,ok}}, {?eh,tc_start,{groups_22_SUITE,testcase_3b}}, {?eh,tc_done,{groups_22_SUITE,testcase_3b,ok}}, {?eh,tc_start, - {groups_22_SUITE,{end_per_group,test_group_3,[{repeat,1}]}}}, + {groups_22_SUITE,{end_per_group,test_group_3,[{repeat,2}]}}}, {?eh,tc_done, - {groups_22_SUITE,{end_per_group,test_group_3,[{repeat,1}]},ok}}], + {groups_22_SUITE,{end_per_group,test_group_3,[{repeat,2}]},ok}}], [{?eh,tc_start, {groups_22_SUITE,{init_per_group,test_group_3,[]}}}, {?eh,tc_done, @@ -1181,12 +1173,8 @@ test_events(groups_dirs_1) -> {groups_22_SUITE,{init_per_group,test_group_5,[parallel]}}}, {?eh,tc_done, {groups_22_SUITE,{init_per_group,test_group_5,[parallel]},ok}}, - - %% the done event could come in during the parallel subgroup - %% and we can't test that, yet... - %% {?eh,tc_start,{groups_22_SUITE,testcase_5a}}, - %% {?eh,tc_done,{groups_22_SUITE,testcase_5a,ok}}, - + {?eh,tc_start,{groups_22_SUITE,testcase_5a}}, + {?eh,tc_done,{groups_22_SUITE,testcase_5a,ok}}, {parallel, [{?eh,tc_start, {groups_22_SUITE,{init_per_group,test_group_6,[parallel]}}}, diff --git a/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_11_SUITE.erl b/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_11_SUITE.erl index c6d50443d0..c69400e938 100644 --- a/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_11_SUITE.erl +++ b/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_11_SUITE.erl @@ -99,6 +99,7 @@ init_per_group(Group, Config) -> {Grs,_} = grs_and_tcs(), case lists:member(Group, Grs) of true -> + ct:comment(Group), init = ?config(suite,Config), [{Group,Group} | Config]; false -> @@ -109,6 +110,7 @@ end_per_group(Group, Config) -> {Grs,_} = grs_and_tcs(), case lists:member(Group, Grs) of true -> + ct:comment(Group), init = ?config(suite,Config), Group = ?config(Group,Config), ok; diff --git a/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_12_SUITE.erl b/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_12_SUITE.erl index b261ef581f..ec90ef95d1 100644 --- a/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_12_SUITE.erl +++ b/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_12_SUITE.erl @@ -37,7 +37,7 @@ groups() -> {test_group_2, [parallel], [testcase_2a, - {test_group_3, [{repeat,1}], + {test_group_3, [{repeat,2}], [testcase_3a, testcase_3b]}, testcase_2b]}, @@ -102,8 +102,8 @@ init_per_group(Group, Config) -> io_lib:format("shuffled, ~w", [S]); {test_group_1b,[{name,test_group_1b},parallel]} -> "parallel"; {test_group_2,[{name,test_group_2},parallel]} -> "parallel"; - {test_group_3,[{name,test_group_3},{repeat,1}]} -> "repeat 1"; - {test_group_3,[{name,test_group_3}]} -> "repeat 0"; + {test_group_3,[{name,test_group_3},{repeat,2}]} -> "repeat 2"; + {test_group_3,[{name,test_group_3}]} -> "repeat 1"; {test_group_4,[{name,test_group_4}]} -> ok; {test_group_5,[{name,test_group_5},parallel]} -> "parallel"; {test_group_6,[{name,test_group_6},parallel]} -> "parallel"; @@ -275,6 +275,10 @@ testcase_5a(Config) -> test_group_5 = ?config(test_group_5,Config), undefined = ?config(testcase_3,Config), testcase_5a = ?config(testcase_5a,Config), + %% increase chance the done event will come + %% during execution of subgroup (could be + %% tricky to handle) + timer:sleep(3), ok. testcase_5b() -> []. diff --git a/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_2/test/groups_22_SUITE.erl b/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_2/test/groups_22_SUITE.erl index 2e19cf6310..ec0adc5df0 100644 --- a/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_2/test/groups_22_SUITE.erl +++ b/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_2/test/groups_22_SUITE.erl @@ -37,7 +37,7 @@ groups() -> {test_group_2, [parallel], [testcase_2a, - {test_group_3, [{repeat,1}], + {test_group_3, [{repeat,2}], [testcase_3a, testcase_3b]}, testcase_2b]}, @@ -102,8 +102,8 @@ init_per_group(Group, Config) -> io_lib:format("shuffled, ~w", [S]); {test_group_1b,[{name,test_group_1b},parallel]} -> "parallel"; {test_group_2,[{name,test_group_2},parallel]} -> "parallel"; - {test_group_3,[{name,test_group_3},{repeat,1}]} -> "repeat 1"; - {test_group_3,[{name,test_group_3}]} -> "repeat 0"; + {test_group_3,[{name,test_group_3},{repeat,2}]} -> "repeat 2"; + {test_group_3,[{name,test_group_3}]} -> "repeat 1"; {test_group_4,[{name,test_group_4}]} -> ok; {test_group_5,[{name,test_group_5},parallel]} -> "parallel"; {test_group_6,[{name,test_group_6},parallel]} -> "parallel"; diff --git a/lib/common_test/test/ct_groups_test_2_SUITE.erl b/lib/common_test/test/ct_groups_test_2_SUITE.erl index 5a60d855b7..c4371501b3 100644 --- a/lib/common_test/test/ct_groups_test_2_SUITE.erl +++ b/lib/common_test/test/ct_groups_test_2_SUITE.erl @@ -60,7 +60,7 @@ all(doc) -> ["Run smoke tests of Common Test."]; all(suite) -> - [missing_conf]. + [missing_conf, repeat_1]. %%-------------------------------------------------------------------- %% TEST CASES @@ -75,16 +75,35 @@ missing_conf(Config) when is_list(Config) -> Suite = filename:join(DataDir, "groups_1/missing_conf_SUITE"), {Opts,ERPid} = setup({suite,Suite}, Config), - ok = ct_test_support:run(ct, run_test, [Opts], Config), + ok = ct_test_support:run(Opts, Config), Events = ct_test_support:get_events(ERPid, Config), ct_test_support:log_events(missing_conf_SUITE, reformat(Events, ?eh), ?config(priv_dir, Config)), - TestEvents = test_events(missing_conf), + TestEvents = events_to_check(missing_conf), ok = ct_test_support:verify_events(TestEvents, Events, Config). - + +%%%----------------------------------------------------------------- +%%% + +repeat_1(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + Suite = filename:join(DataDir, "groups_1/repeat_1_SUITE"), + + {Opts,ERPid} = setup({suite,Suite}, Config), + ok = ct_test_support:run(Opts, Config), + Events = ct_test_support:get_events(ERPid, Config), + + ct_test_support:log_events(repeat_1, + reformat(Events, ?eh), + ?config(priv_dir, Config)), + + TestEvents = events_to_check(repeat_1), + ok = ct_test_support:verify_events(TestEvents, Events, Config). + %%%----------------------------------------------------------------- %%% HELP FUNCTIONS %%%----------------------------------------------------------------- @@ -105,6 +124,127 @@ reformat(Events, EH) -> %%%----------------------------------------------------------------- %%% TEST EVENTS %%%----------------------------------------------------------------- +events_to_check(Test) -> + %% 2 tests (ct:run_test + script_start) is default + events_to_check(Test, 2). + +events_to_check(_, 0) -> + []; +events_to_check(Test, N) -> + test_events(Test) ++ events_to_check(Test, N-1). test_events(missing_conf) -> - exit(must_handle_this). + [ + {?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,2}}, + {?eh,tc_start,{ct_framework,ct_init_per_group}}, + {?eh,tc_done,{ct_framework,ct_init_per_group,ok}}, + {?eh,test_stats,{1,0,{0,0}}}, + {?eh,tc_start,{missing_conf_SUITE,tc1}}, + {?eh,tc_done,{missing_conf_SUITE,tc1,ok}}, + {?eh,test_stats,{2,0,{0,0}}}, + {?eh,tc_start,{missing_conf_SUITE,tc2}}, + {?eh,tc_done,{missing_conf_SUITE,tc2,ok}}, + {?eh,test_stats,{3,0,{0,0}}}, + {?eh,tc_start,{ct_framework,ct_end_per_group}}, + {?eh,tc_done,{ct_framework,ct_end_per_group,ok}}, + {?eh,test_stats,{4,0,{0,0}}}, + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]} + ]; + +test_events(repeat_1) -> + [ + {?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,unknown}}, + {?eh,tc_start,{repeat_1_SUITE,init_per_suite}}, + {?eh,tc_done,{repeat_1_SUITE,init_per_suite,ok}}, + [{?eh,tc_start, + {repeat_1_SUITE,{init_per_group,test_group_1,[{repeat,2}]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{init_per_group,test_group_1,[{repeat,2}]},ok}}, + {?eh,tc_start,{repeat_1_SUITE,testcase_1a}}, + {?eh,tc_done,{repeat_1_SUITE,testcase_1a,ok}}, + {?eh,test_stats,{1,0,{0,0}}}, + {?eh,tc_start,{repeat_1_SUITE,testcase_1b}}, + {?eh,tc_done,{repeat_1_SUITE,testcase_1b,ok}}, + {?eh,test_stats,{2,0,{0,0}}}, + {?eh,tc_start, + {repeat_1_SUITE,{end_per_group,test_group_1,[{repeat,2}]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{end_per_group,test_group_1,[{repeat,2}]},ok}}], + [{?eh,tc_start, + {repeat_1_SUITE,{init_per_group,test_group_1,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{init_per_group,test_group_1,[]},ok}}, + {?eh,tc_start,{repeat_1_SUITE,testcase_1a}}, + {?eh,tc_done,{repeat_1_SUITE,testcase_1a,ok}}, + {?eh,test_stats,{3,0,{0,0}}}, + {?eh,tc_start,{repeat_1_SUITE,testcase_1b}}, + {?eh,tc_done,{repeat_1_SUITE,testcase_1b,ok}}, + {?eh,test_stats,{4,0,{0,0}}}, + {?eh,tc_start, + {repeat_1_SUITE,{end_per_group,test_group_1,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{end_per_group,test_group_1,[]},ok}}], + [{?eh,tc_start, + {repeat_1_SUITE,{init_per_group,test_group_2,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{init_per_group,test_group_2,[]},ok}}, + {?eh,tc_start,{repeat_1_SUITE,testcase_2a}}, + {?eh,tc_done,{repeat_1_SUITE,testcase_2a,ok}}, + {?eh,test_stats,{5,0,{0,0}}}, + {?eh,tc_start,{repeat_1_SUITE,testcase_2b}}, + {?eh,tc_done,{repeat_1_SUITE,testcase_2b,ok}}, + {?eh,test_stats,{6,0,{0,0}}}, + {?eh,tc_start, + {repeat_1_SUITE,{end_per_group,test_group_2,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{end_per_group,test_group_2,[]},ok}}], + [{?eh,tc_start, + {repeat_1_SUITE, + {init_per_group,test_group_3,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE, + {init_per_group,test_group_3,[]}, + ok}}, + {?eh,tc_start,{repeat_1_SUITE,testcase_3a}}, + {?eh,tc_done,{repeat_1_SUITE,testcase_3a,ok}}, + {?eh,test_stats,{7,0,{0,0}}}, + [{?eh,tc_start, + {repeat_1_SUITE, + {init_per_group,test_group_4,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE, + {init_per_group,test_group_4,[]}, + ok}}, + {?eh,tc_start,{repeat_1_SUITE,testcase_4a}}, + {?eh,tc_done,{repeat_1_SUITE,testcase_4a,ok}}, + {?eh,test_stats,{8,0,{0,0}}}, + {?eh,tc_start,{repeat_1_SUITE,testcase_4b}}, + {?eh,tc_done,{repeat_1_SUITE,testcase_4b,ok}}, + {?eh,test_stats,{9,0,{0,0}}}, + {?eh,tc_start, + {repeat_1_SUITE, + {end_per_group,test_group_4,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE, + {end_per_group,test_group_4,[]}, + ok}}], + {?eh,tc_start,{repeat_1_SUITE,testcase_3b}}, + {?eh,tc_done,{repeat_1_SUITE,testcase_3b,ok}}, + {?eh,test_stats,{10,0,{0,0}}}, + {?eh,tc_start, + {repeat_1_SUITE, + {end_per_group,test_group_3,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE, + {end_per_group,test_group_3,[]}, + ok}}], + {?eh,tc_start,{repeat_1_SUITE,end_per_suite}}, + {?eh,tc_done,{repeat_1_SUITE,end_per_suite,ok}}, + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]} + ]. diff --git a/lib/common_test/test/ct_groups_test_2_SUITE_data/cfgs/groups_2.1.cfg b/lib/common_test/test/ct_groups_test_2_SUITE_data/cfgs/groups_2.1.cfg new file mode 100644 index 0000000000..4928505157 --- /dev/null +++ b/lib/common_test/test/ct_groups_test_2_SUITE_data/cfgs/groups_2.1.cfg @@ -0,0 +1 @@ +{dummy_key, "dummy_data"}. diff --git a/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_1/repeat_1_SUITE.erl b/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_1/repeat_1_SUITE.erl new file mode 100644 index 0000000000..b4b9b03ca5 --- /dev/null +++ b/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_1/repeat_1_SUITE.erl @@ -0,0 +1,105 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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(repeat_1_SUITE). + +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +%%==================================================================== +%% COMMON TEST CALLBACK FUNCTIONS +%%==================================================================== + +suite() -> + [{timetrap,{minutes,1}}]. + +groups() -> + [ + {test_group_1, [{repeat,2}], [testcase_1a,testcase_1b]}, + {test_group_2, [{repeat,1}], [testcase_2a,testcase_2b]}, + + {test_group_3, [{repeat_until_all_fail,1}], + [testcase_3a, + {test_group_4, [{repeat_until_any_fail,1}], + [testcase_4a, testcase_4b]}, + testcase_3b]} + ]. + +all() -> + [ + {group, test_group_1}, + {group, test_group_2}, + {group, test_group_3} + ]. + +%%-------------------------------------------------------------------- +%% Suite Configuration +%%-------------------------------------------------------------------- + +init_per_suite(Config) -> + Config. + +end_per_suite(Config) -> + ok. + +%%-------------------------------------------------------------------- +%% Group Configuration +%%-------------------------------------------------------------------- + +init_per_group(Group, Config) -> + Group = proplists:get_value(name,?config(tc_group_properties,Config)), + ct:comment(Group), + Config. + +end_per_group(_Group, _Config) -> + ok. + +%%-------------------------------------------------------------------- +%% Testcase Configuration +%%-------------------------------------------------------------------- + +init_per_testcase(_TestCase, Config) -> + Config. + +end_per_testcase(_TestCase, _Config) -> + ok. + +%%-------------------------------------------------------------------- +%% Testcases +%%-------------------------------------------------------------------- + +testcase_1a(_) -> + ok. +testcase_1b(_) -> + ok. + +testcase_2a(_) -> + ok. +testcase_2b(_) -> + ok. + +testcase_3a(_) -> + ok. +testcase_3b(_) -> + ok. + +testcase_4a(_) -> + ok. +testcase_4b(_) -> + ok. diff --git a/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_2/groups_21_SUITE.erl b/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_2/groups_21_SUITE.erl new file mode 100644 index 0000000000..2533ac8e84 --- /dev/null +++ b/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_2/groups_21_SUITE.erl @@ -0,0 +1,281 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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(groups_21_SUITE). + +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +%%==================================================================== +%% COMMON TEST CALLBACK FUNCTIONS +%%==================================================================== + +suite() -> + [{timetrap,{minutes,1}}]. + +groups() -> + [ + {test_group_1a, [testcase_1a,testcase_1b]}, + + {test_group_1b, [], [testcase_1a,testcase_1b]}, + + {test_group_2, [], [testcase_2a, + + {test_group_3, [], [testcase_3a, + testcase_3b]}, + testcase_2b]}, + + {test_group_4, [{test_group_5, [], [testcase_5a, + + {group, test_group_6}, + + testcase_5b]}]}, + + {test_group_6, [{group, test_group_7}]}, + + {test_group_7, [testcase_7a,testcase_7b]} + ]. + +all() -> + [testcase_1, + {group, test_group_1a}, + {group, test_group_1b}, + testcase_2, + {group, test_group_2}, + testcase_3, + {group, test_group_4}]. + +%% this func only for internal test purposes +grs_and_tcs() -> + {[ + test_group_1a, test_group_1b, + test_group_2, test_group_3, + test_group_4, test_group_5, + test_group_6, test_group_7 + ], + [ + testcase_1, + testcase_1a, testcase_1b, + testcase_2, + testcase_2a, testcase_2b, + testcase_3a, testcase_3b, + testcase_3, + testcase_5a, testcase_5b, + testcase_7a, testcase_7b + ]}. + +%%-------------------------------------------------------------------- +%% Suite Configuration +%%-------------------------------------------------------------------- + +init_per_suite(Config) -> + [{suite,init}|Config]. + +end_per_suite(Config) -> + init = ?config(suite,Config). + +%%-------------------------------------------------------------------- +%% Group Configuration +%%-------------------------------------------------------------------- + +init_per_group(Group, Config) -> + [{name,Group}] = ?config(tc_group_properties,Config), + {Grs,_} = grs_and_tcs(), + case lists:member(Group, Grs) of + true -> + ct:comment(io_lib:format("~w", [Group])), + init = ?config(suite,Config), + [{Group,Group} | Config]; + false -> + ct:fail({bad_group,Group}) + end. + +end_per_group(Group, Config) -> + {Grs,_} = grs_and_tcs(), + case lists:member(Group, Grs) of + true -> + init = ?config(suite,Config), + Group = ?config(Group,Config), + ok; + false -> + ct:fail({bad_group,Group}) + end. + +%%-------------------------------------------------------------------- +%% Testcase Configuration +%%-------------------------------------------------------------------- + +init_per_testcase(TestCase, Config) -> + {_,TCs} = grs_and_tcs(), + case lists:member(TestCase, TCs) of + true -> + init = ?config(suite,Config), + [{TestCase,TestCase} | Config]; + false -> + ct:fail({unknown_testcase,TestCase}) + end. + +end_per_testcase(TestCase, Config) -> + {_,TCs} = grs_and_tcs(), + case lists:member(TestCase, TCs) of + true -> + init = ?config(suite,Config), + TestCase = ?config(TestCase,Config), + ok; + false -> + ct:fail({unknown_testcase,TestCase}) + end. + + +%%-------------------------------------------------------------------- +%% Testcases +%%-------------------------------------------------------------------- + +testcase_1() -> + []. +testcase_1(Config) -> + init = ?config(suite,Config), + testcase_1 = ?config(testcase_1,Config), + ok. + +testcase_1a() -> + []. +testcase_1a(Config) -> + init = ?config(suite,Config), + case ?config(test_group_1a,Config) of + test_group_1a -> ok; + _ -> + case ?config(test_group_1b,Config) of + test_group_1b -> ok; + _ -> ct:fail(no_group_data) + end + end, + testcase_1a = ?config(testcase_1a,Config), + ok. +testcase_1b() -> + []. +testcase_1b(Config) -> + init = ?config(suite,Config), + case ?config(test_group_1a,Config) of + test_group_1a -> ok; + _ -> + case ?config(test_group_1b,Config) of + test_group_1b -> ok; + _ -> ct:fail(no_group_data) + end + end, + undefined = ?config(testcase_1a,Config), + testcase_1b = ?config(testcase_1b,Config), + ok. + +testcase_2() -> + []. +testcase_2(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_1a,Config), + undefined = ?config(test_group_1b,Config), + testcase_2 = ?config(testcase_2,Config), + ok. + +testcase_2a() -> + []. +testcase_2a(Config) -> + init = ?config(suite,Config), + test_group_2 = ?config(test_group_2,Config), + testcase_2a = ?config(testcase_2a,Config), + ok. +testcase_2b() -> + []. +testcase_2b(Config) -> + init = ?config(suite,Config), + test_group_2 = ?config(test_group_2,Config), + undefined = ?config(testcase_2a,Config), + testcase_2b = ?config(testcase_2b,Config), + ok. + +testcase_3a() -> + []. +testcase_3a(Config) -> + init = ?config(suite,Config), + test_group_2 = ?config(test_group_2,Config), + test_group_3 = ?config(test_group_3,Config), + undefined = ?config(testcase_2b,Config), + testcase_3a = ?config(testcase_3a,Config), + ok. +testcase_3b() -> + []. +testcase_3b(Config) -> + init = ?config(suite,Config), + test_group_2 = ?config(test_group_2,Config), + test_group_3 = ?config(test_group_3,Config), + undefined = ?config(testcase_3a,Config), + testcase_3b = ?config(testcase_3b,Config), + ok. + +testcase_3() -> + []. +testcase_3(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_2,Config), + undefined = ?config(test_group_3,Config), + testcase_3 = ?config(testcase_3,Config), + ok. + +testcase_5a() -> + []. +testcase_5a(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_3,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + undefined = ?config(testcase_3,Config), + testcase_5a = ?config(testcase_5a,Config), + ok. +testcase_5b() -> + []. +testcase_5b(Config) -> + init = ?config(suite,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + undefined = ?config(testcase_5a,Config), + testcase_5b = ?config(testcase_5b,Config), + ok. + +testcase_7a() -> + []. +testcase_7a(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_3,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + test_group_6 = ?config(test_group_6,Config), + test_group_7 = ?config(test_group_7,Config), + testcase_7a = ?config(testcase_7a,Config), + ok. +testcase_7b() -> + []. +testcase_7b(Config) -> + init = ?config(suite,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + test_group_6 = ?config(test_group_6,Config), + test_group_7 = ?config(test_group_7,Config), + undefined = ?config(testcase_7a,Config), + testcase_7b = ?config(testcase_7b,Config), + ok. diff --git a/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_2/groups_22_SUITE.erl b/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_2/groups_22_SUITE.erl new file mode 100644 index 0000000000..cd517876df --- /dev/null +++ b/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_2/groups_22_SUITE.erl @@ -0,0 +1,314 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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(groups_22_SUITE). + +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +%%==================================================================== +%% COMMON TEST CALLBACK FUNCTIONS +%%==================================================================== + +suite() -> + [{timetrap,{minutes,1}}]. + +groups() -> + [ + {test_group_1a, [shuffle], [testcase_1a,testcase_1b,testcase_1c]}, + + {test_group_1b, [parallel], [testcase_1a,testcase_1b]}, + + {test_group_2, [parallel], [testcase_2a, + + {test_group_3, [{repeat,1}], + [testcase_3a, testcase_3b]}, + + testcase_2b]}, + + {test_group_4, [{test_group_5, [parallel], [testcase_5a, + + {group, test_group_6}, + + testcase_5b]}]}, + + {test_group_6, [parallel], [{group, test_group_7}]}, + + {test_group_7, [sequence], [testcase_7a,testcase_7b]} + ]. + +all() -> + [{group, test_group_1a}, + {group, test_group_1b}, + testcase_1, + testcase_2, + {group, test_group_2}, + testcase_3, + {group, test_group_4}]. + +%% this func only for internal test purposes +grs_and_tcs() -> + {[ + test_group_1a, test_group_1b, + test_group_2, test_group_3, + test_group_4, test_group_5, + test_group_6, test_group_7 + ], + [ + testcase_1a, testcase_1b, testcase_1c, + testcase_1, + testcase_2, + testcase_2a, testcase_2b, + testcase_3a, testcase_3b, + testcase_3, + testcase_5a, testcase_5b, + testcase_7a, testcase_7b + ]}. + +%%-------------------------------------------------------------------- +%% Suite Configuration +%%-------------------------------------------------------------------- + +init_per_suite(Config) -> + [{suite,init}|Config]. + +end_per_suite(Config) -> + init = ?config(suite,Config). + +%%-------------------------------------------------------------------- +%% Group Configuration +%%-------------------------------------------------------------------- + +init_per_group(Group, Config) -> + Cmt = + case {Group,?config(tc_group_properties,Config)} of + {test_group_1a,[{shuffle,S},{name,test_group_1a}]} -> + io_lib:format("shuffled, ~w", [S]); + {test_group_1b,[{name,test_group_1b},parallel]} -> "parallel"; + {test_group_2,[{name,test_group_2},parallel]} -> "parallel"; + {test_group_3,[{name,test_group_3},{repeat,1}]} -> "repeat 1"; + {test_group_3,[{name,test_group_3}]} -> "repeat 0"; + {test_group_4,[{name,test_group_4}]} -> ok; + {test_group_5,[{name,test_group_5},parallel]} -> "parallel"; + {test_group_6,[{name,test_group_6},parallel]} -> "parallel"; + {test_group_7,[{name,test_group_7},sequence]} -> "sequence" + end, + {Grs,_} = grs_and_tcs(), + case lists:member(Group, Grs) of + true -> + init = ?config(suite,Config), + ct:comment(io_lib:format("~w, ~s", [Group,Cmt])), + [{Group,Group} | Config]; + false -> + ct:fail({bad_group,Group}) + end. + +end_per_group(Group, Config) -> + {Grs,_} = grs_and_tcs(), + case lists:member(Group, Grs) of + true -> + init = ?config(suite,Config), + Group = ?config(Group,Config), + ok; + false -> + ct:fail({bad_group,Group}) + end. + +%%-------------------------------------------------------------------- +%% Testcase Configuration +%%-------------------------------------------------------------------- + +init_per_testcase(TestCase, Config) -> + {_,TCs} = grs_and_tcs(), + case lists:member(TestCase, TCs) of + true -> + init = ?config(suite,Config), + [{TestCase,TestCase} | Config]; + false -> + ct:fail({unknown_testcase,TestCase}) + end. + +end_per_testcase(TestCase, Config) -> + {_,TCs} = grs_and_tcs(), + case lists:member(TestCase, TCs) of + true -> + init = ?config(suite,Config), + TestCase = ?config(TestCase,Config), + ok; + false -> + ct:fail({unknown_testcase,TestCase}) + end. + + +%%-------------------------------------------------------------------- +%% Testcases +%%-------------------------------------------------------------------- + +testcase_1a() -> + []. +testcase_1a(Config) -> + init = ?config(suite,Config), + case ?config(test_group_1a,Config) of + test_group_1a -> ok; + _ -> + case ?config(test_group_1b,Config) of + test_group_1b -> ok; + _ -> ct:fail(no_group_data) + end + end, + testcase_1a = ?config(testcase_1a,Config), + ok. +testcase_1b() -> + []. +testcase_1b(Config) -> + init = ?config(suite,Config), + case ?config(test_group_1a,Config) of + test_group_1a -> ok; + _ -> + case ?config(test_group_1b,Config) of + test_group_1b -> ok; + _ -> ct:fail(no_group_data) + end + end, + undefined = ?config(testcase_1a,Config), + testcase_1b = ?config(testcase_1b,Config), + ok. + +testcase_1c() -> + []. +testcase_1c(Config) -> + init = ?config(suite,Config), + case ?config(test_group_1a,Config) of + test_group_1a -> ok; + _ -> + case ?config(test_group_1b,Config) of + test_group_1b -> ok; + _ -> ct:fail(no_group_data) + end + end, + undefined = ?config(testcase_1b,Config), + testcase_1c = ?config(testcase_1c,Config), + ok. + +testcase_1() -> + []. +testcase_1(Config) -> + init = ?config(suite,Config), + testcase_1 = ?config(testcase_1,Config), + ok. + +testcase_2() -> + []. +testcase_2(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_1a,Config), + undefined = ?config(test_group_1b,Config), + testcase_2 = ?config(testcase_2,Config), + ok. + +testcase_2a() -> + []. +testcase_2a(Config) -> + init = ?config(suite,Config), + test_group_2 = ?config(test_group_2,Config), + testcase_2a = ?config(testcase_2a,Config), + ok. +testcase_2b() -> + []. +testcase_2b(Config) -> + init = ?config(suite,Config), + test_group_2 = ?config(test_group_2,Config), + undefined = ?config(testcase_2a,Config), + testcase_2b = ?config(testcase_2b,Config), + ok. + +testcase_3a() -> + []. +testcase_3a(Config) -> + init = ?config(suite,Config), + test_group_2 = ?config(test_group_2,Config), + test_group_3 = ?config(test_group_3,Config), + undefined = ?config(testcase_2b,Config), + testcase_3a = ?config(testcase_3a,Config), + ok. +testcase_3b() -> + []. +testcase_3b(Config) -> + init = ?config(suite,Config), + test_group_2 = ?config(test_group_2,Config), + test_group_3 = ?config(test_group_3,Config), + undefined = ?config(testcase_3a,Config), + testcase_3b = ?config(testcase_3b,Config), + ok. + +testcase_3() -> + []. +testcase_3(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_2,Config), + undefined = ?config(test_group_3,Config), + testcase_3 = ?config(testcase_3,Config), + ok. + +testcase_5a() -> + []. +testcase_5a(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_3,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + undefined = ?config(testcase_3,Config), + testcase_5a = ?config(testcase_5a,Config), + %% increase chance the done event will come + %% during execution of subgroup (could be + %% tricky to handle) + timer:sleep(3), + ok. +testcase_5b() -> + []. +testcase_5b(Config) -> + init = ?config(suite,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + undefined = ?config(testcase_5a,Config), + testcase_5b = ?config(testcase_5b,Config), + ok. + +testcase_7a() -> + []. +testcase_7a(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_3,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + test_group_6 = ?config(test_group_6,Config), + test_group_7 = ?config(test_group_7,Config), + testcase_7a = ?config(testcase_7a,Config), + ok. +testcase_7b() -> + []. +testcase_7b(Config) -> + init = ?config(suite,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + test_group_6 = ?config(test_group_6,Config), + test_group_7 = ?config(test_group_7,Config), + undefined = ?config(testcase_7a,Config), + testcase_7b = ?config(testcase_7b,Config), + ok. diff --git a/lib/common_test/test/ct_master_SUITE.erl b/lib/common_test/test/ct_master_SUITE.erl new file mode 100644 index 0000000000..e0e1f93db2 --- /dev/null +++ b/lib/common_test/test/ct_master_SUITE.erl @@ -0,0 +1,136 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% +%% + +%%%------------------------------------------------------------------- +%%% File: ct_master_SUITE +%%% +%%% Description: +%%% Test ct_master. +%%% +%%% The suites used for the test are located in the data directory. +%%%------------------------------------------------------------------- +-module(ct_master_SUITE). +-compile(export_all). + +-include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct_event.hrl"). + +-define(eh, ct_test_support_eh). + +%%-------------------------------------------------------------------- +%% TEST SERVER CALLBACK FUNCTIONS +%%-------------------------------------------------------------------- + +%%-------------------------------------------------------------------- +%% Description: Since Common Test starts another Test Server +%% instance, the tests need to be performed on a separate node (or +%% there will be clashes with logging processes etc). +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + Config1 = ct_test_support:init_per_suite(Config), + Config1. + +end_per_suite(Config) -> + ct_test_support:end_per_suite(Config). + +init_per_testcase(TestCase, Config) -> + ct_test_support:init_per_testcase(TestCase, [{master, true}|Config]). + +end_per_testcase(TestCase, Config) -> + ct_test_support:end_per_testcase(TestCase, Config). + +all(doc) -> + [""]; + +all(suite) -> + [ + ct_master_test + ]. + +%%-------------------------------------------------------------------- +%% TEST CASES +%%-------------------------------------------------------------------- +ct_master_test(Config) when is_list(Config)-> + NodeCount = 5, + DataDir = ?config(data_dir, Config), + PrivDir = ?config(priv_dir, Config), + NodeNames = [list_to_atom("testnode_"++integer_to_list(N)) || + N <- lists:seq(1, NodeCount)], + FileName = filename:join(PrivDir, "ct_master_spec.spec"), + Suites = [master_SUITE], + TSFile = make_spec(DataDir, FileName, NodeNames, Suites, Config), + [{TSFile, ok}] = run_test(ct_master_test, FileName, Config), + ok. + +%%%----------------------------------------------------------------- +%%% HELP FUNCTIONS +%%%----------------------------------------------------------------- +make_spec(DataDir, FileName, NodeNames, Suites, Config)-> + {ok, HostName} = inet:gethostname(), + + N = lists:map(fun(NodeName)-> + {node, NodeName, list_to_atom(atom_to_list(NodeName)++"@"++HostName)} + end, + NodeNames), + + C = lists:map(fun(NodeName)-> + Rnd = random:uniform(2), + if Rnd == 1-> + {config, NodeName, filename:join(DataDir, "master/config.txt")}; + true-> + {userconfig, NodeName, {ct_config_xml, filename:join(DataDir, "master/config.xml")}} + end + end, + NodeNames), + + NS = lists:map(fun(NodeName)-> + {init, NodeName, [ + {node_start, [{startup_functions, []}, {monitor_master, true}]}, + {eval, {erlang, nodes, []}} + ] + } + end, + NodeNames), + + S = [{suites, NodeNames, filename:join(DataDir, "master"), Suites}], + + PrivDir = ?config(priv_dir, Config), + LD = lists:map(fun(NodeName)-> + {logdir, NodeName, get_log_dir(PrivDir, NodeName)} + end, + NodeNames) ++ [{logdir, master, PrivDir}], + + ct_test_support:write_testspec(N++C++S++LD++NS, FileName). + +get_log_dir(PrivDir, NodeName)-> + LogDir = filename:join(PrivDir, io_lib:format("slave.~p", [NodeName])), + file:make_dir(LogDir), + LogDir. + +run_test(_Name, FileName, Config)-> + [{FileName, ok}] = ct_test_support:run(ct_master, run, [FileName], Config). + +reformat_events(Events, EH) -> + ct_test_support:reformat(Events, EH). + +%%%----------------------------------------------------------------- +%%% TEST EVENTS +%%%----------------------------------------------------------------- +expected_events(_)-> +[]. diff --git a/lib/common_test/test/ct_master_SUITE_data/master/config.txt b/lib/common_test/test/ct_master_SUITE_data/master/config.txt new file mode 100644 index 0000000000..3baf9e392c --- /dev/null +++ b/lib/common_test/test/ct_master_SUITE_data/master/config.txt @@ -0,0 +1,2 @@ +{a, b}. +{c, d}. diff --git a/lib/common_test/test/ct_master_SUITE_data/master/config.xml b/lib/common_test/test/ct_master_SUITE_data/master/config.xml new file mode 100644 index 0000000000..c031f45f35 --- /dev/null +++ b/lib/common_test/test/ct_master_SUITE_data/master/config.xml @@ -0,0 +1,4 @@ +<config> + <a>b</a> + <c>d</c> +</config> diff --git a/lib/common_test/test/ct_master_SUITE_data/master/master_SUITE.erl b/lib/common_test/test/ct_master_SUITE_data/master/master_SUITE.erl new file mode 100644 index 0000000000..e37ec3659c --- /dev/null +++ b/lib/common_test/test/ct_master_SUITE_data/master/master_SUITE.erl @@ -0,0 +1,57 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% +%% + +%%%------------------------------------------------------------------- +%%% File: master_SUITE +%%% +%%% Description: +%%% Test suite for common_test which tests the ct_master functionality +%%%------------------------------------------------------------------- +-module(master_SUITE). + +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +suite() -> + []. + +init_per_suite(Config) -> + Config. + +end_per_suite(_) -> + ok. + +all() -> [first_testcase, second_testcase, third_testcase]. + +init_per_testcase(_, Config) -> + Config. + +end_per_testcase(_, _) -> + ok. + +first_testcase(_)-> + b = ct:get_config(a). + +second_testcase(_)-> + d = ct:get_config(c). + +third_testcase(_)-> + A = 4, + A = 2*2. diff --git a/lib/common_test/test/ct_misc_1_SUITE.erl b/lib/common_test/test/ct_misc_1_SUITE.erl new file mode 100644 index 0000000000..eb6c6aa101 --- /dev/null +++ b/lib/common_test/test/ct_misc_1_SUITE.erl @@ -0,0 +1,165 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% +%% + +%%%------------------------------------------------------------------- +%%% File: ct_misc_1_SUITE +%%% +%%% Description: +%%% Test misc things in Common Test suites. +%%% +%%% The suites used for the test are located in the data directory. +%%%------------------------------------------------------------------- +-module(ct_misc_1_SUITE). + +-compile(export_all). + +-include_lib("test_server/include/test_server.hrl"). +-include_lib("test_server/include/test_server_line.hrl"). +-include_lib("common_test/include/ct_event.hrl"). + +-define(eh, ct_test_support_eh). + +%%-------------------------------------------------------------------- +%% TEST SERVER CALLBACK FUNCTIONS +%%-------------------------------------------------------------------- + +%%-------------------------------------------------------------------- +%% Description: Since Common Test starts another Test Server +%% instance, the tests need to be performed on a separate node (or +%% there will be clashes with logging processes etc). +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + Config1 = ct_test_support:init_per_suite(Config), + Config1. + +end_per_suite(Config) -> + ct_test_support:end_per_suite(Config). + +init_per_testcase(TestCase, Config) -> + ct_test_support:init_per_testcase(TestCase, Config). + +end_per_testcase(TestCase, Config) -> + ct_test_support:end_per_testcase(TestCase, Config). + +all(doc) -> + [""]; + +all(suite) -> + [ + beam_me_up + ]. + +%%-------------------------------------------------------------------- +%% TEST CASES +%%-------------------------------------------------------------------- + +%%%----------------------------------------------------------------- +%%% +beam_me_up(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + CTNode = ?config(ct_node, Config), + + %% Path = rpc:call(CTNode, code, get_path, []), + %% [_ | Parts] = lists:reverse(filename:split(DataDir)), + %% TSDir = filename:join(lists:reverse(Parts)), + %% true = rpc:call(CTNode, code, del_path, [TSDir]), + + Mods = [beam_1_SUITE, beam_2_SUITE], + Suites = [atom_to_list(M) || M <- Mods], + [{error,_} = rpc:call(CTNode, code, load_file, [M]) || M <- Mods], + + code:add_path(DataDir), + CRes = + [compile:file(filename:join(DataDir,F), + [verbose,report_errors, + report_warnings,binary]) || F <- Suites], + + [{module,_} = rpc:call(CTNode, code, load_binary, + [Mod, atom_to_list(Mod), Bin]) || + {ok,Mod,Bin} <- CRes], + + {Opts,ERPid} = setup([{suite,Suites},{auto_compile,false}], Config), + + ok = ct_test_support:run(ct, run_test, [Opts], Config), + Events = ct_test_support:get_events(ERPid, Config), + + ct_test_support:log_events(beam_me_up, + reformat(Events, ?eh), + ?config(priv_dir, Config)), + + TestEvents = events_to_check(beam_me_up, 1), + ok = ct_test_support:verify_events(TestEvents, Events, Config). + +%%%----------------------------------------------------------------- +%%% HELP FUNCTIONS +%%%----------------------------------------------------------------- + +setup(Test, Config) -> + Opts0 = ct_test_support:get_opts(Config), + Level = ?config(trace_level, Config), + EvHArgs = [{cbm,ct_test_support},{trace_level,Level}], + Opts = Opts0 ++ [{event_handler,{?eh,EvHArgs}}|Test], + ERPid = ct_test_support:start_event_receiver(Config), + {Opts,ERPid}. + +reformat(Events, EH) -> + ct_test_support:reformat(Events, EH). +%reformat(Events, _EH) -> +% Events. + +%%%----------------------------------------------------------------- +%%% TEST EVENTS +%%%----------------------------------------------------------------- +events_to_check(Test) -> + %% 2 tests (ct:run_test + script_start) is default + events_to_check(Test, 2). + +events_to_check(_, 0) -> + []; +events_to_check(Test, N) -> + test_events(Test) ++ events_to_check(Test, N-1). + +test_events(beam_me_up) -> + [ + {?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{2,2,4}}, + {?eh,tc_start,{beam_1_SUITE,init_per_suite}}, + {?eh,tc_done,{beam_1_SUITE,init_per_suite,ok}}, + {?eh,tc_start,{beam_1_SUITE,tc1}}, + {?eh,tc_done,{beam_1_SUITE,tc1,ok}}, + {?eh,test_stats,{1,0,{0,0}}}, + {?eh,tc_start,{beam_1_SUITE,tc2}}, + {?eh,tc_done,{beam_1_SUITE,tc2,{failed,{error,'tc2 failed'}}}}, + {?eh,test_stats,{1,1,{0,0}}}, + {?eh,tc_start,{beam_1_SUITE,end_per_suite}}, + {?eh,tc_done,{beam_1_SUITE,end_per_suite,ok}}, + {?eh,tc_start,{beam_2_SUITE,init_per_suite}}, + {?eh,tc_done,{beam_2_SUITE,init_per_suite,ok}}, + {?eh,tc_start,{beam_2_SUITE,tc1}}, + {?eh,tc_done,{beam_2_SUITE,tc1,ok}}, + {?eh,test_stats,{2,1,{0,0}}}, + {?eh,tc_start,{beam_2_SUITE,tc2}}, + {?eh,tc_done,{beam_2_SUITE,tc2,{failed,{error,'tc2 failed'}}}}, + {?eh,test_stats,{2,2,{0,0}}}, + {?eh,tc_start,{beam_2_SUITE,end_per_suite}}, + {?eh,tc_done,{beam_2_SUITE,end_per_suite,ok}}, + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]} + ]. diff --git a/lib/common_test/test/ct_misc_1_SUITE_data/beam_1_SUITE.erl b/lib/common_test/test/ct_misc_1_SUITE_data/beam_1_SUITE.erl new file mode 100644 index 0000000000..382bdefded --- /dev/null +++ b/lib/common_test/test/ct_misc_1_SUITE_data/beam_1_SUITE.erl @@ -0,0 +1,134 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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(beam_1_SUITE). + +%% Note: This directive should only be used in test suites. +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +%%-------------------------------------------------------------------- +%% COMMON TEST CALLBACK FUNCTIONS +%%-------------------------------------------------------------------- + +%%-------------------------------------------------------------------- +%% Function: suite() -> Info +%% +%% Info = [tuple()] +%% List of key/value pairs. +%% +%% Description: Returns list of tuples to set default properties +%% for the suite. +%% +%% Note: The suite/0 function is only meant to be used to return +%% default data values, not perform any other operations. +%%-------------------------------------------------------------------- +suite() -> + [ + {timetrap,{seconds,10}} + ]. + +%%-------------------------------------------------------------------- +%% Function: init_per_suite(Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% +%% Config0 = Config1 = [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Reason = term() +%% The reason for skipping the suite. +%% +%% Description: Initialization before the suite. +%% +%% Note: This function is free to add any key/value pairs to the Config +%% variable, but should NOT alter/remove any existing entries. +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + Config. + +%%-------------------------------------------------------------------- +%% Function: end_per_suite(Config0) -> void() | {save_config,Config1} +%% +%% Config0 = Config1 = [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% +%% Description: Cleanup after the suite. +%%-------------------------------------------------------------------- +end_per_suite(_Config) -> + ok. + +%%-------------------------------------------------------------------- +%% Function: init_per_testcase(TestCase, Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% +%% TestCase = atom() +%% Name of the test case that is about to run. +%% Config0 = Config1 = [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Reason = term() +%% The reason for skipping the test case. +%% +%% Description: Initialization before each test case. +%% +%% Note: This function is free to add any key/value pairs to the Config +%% variable, but should NOT alter/remove any existing entries. +%%-------------------------------------------------------------------- +init_per_testcase(_TestCase, Config) -> + Config. + +%%-------------------------------------------------------------------- +%% Function: end_per_testcase(TestCase, Config0) -> +%% void() | {save_config,Config1} +%% +%% TestCase = atom() +%% Name of the test case that is finished. +%% Config0 = Config1 = [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% +%% Description: Cleanup after each test case. +%%-------------------------------------------------------------------- +end_per_testcase(_TestCase, _Config) -> + ok. + +%%-------------------------------------------------------------------- +%% Function: all() -> TestCases | {skip,Reason} +%% +%% TestCases = [TestCase | {sequence,SeqName}] +%% TestCase = atom() +%% Name of a test case. +%% SeqName = atom() +%% Name of a test case sequence. +%% Reason = term() +%% The reason for skipping all test cases. +%% +%% Description: Returns the list of test cases that are to be executed. +%%-------------------------------------------------------------------- +all() -> + [tc1, tc2]. + +%%-------------------------------------------------------------------- +%% TEST CASES +%%-------------------------------------------------------------------- + +tc1(_Config) -> + ct:comment("tc1 executed"), + ok. + +tc2(_Config) -> + exit('tc2 failed'). diff --git a/lib/common_test/test/ct_misc_1_SUITE_data/beam_2_SUITE.erl b/lib/common_test/test/ct_misc_1_SUITE_data/beam_2_SUITE.erl new file mode 100644 index 0000000000..70c1f2b471 --- /dev/null +++ b/lib/common_test/test/ct_misc_1_SUITE_data/beam_2_SUITE.erl @@ -0,0 +1,134 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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(beam_2_SUITE). + +%% Note: This directive should only be used in test suites. +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +%%-------------------------------------------------------------------- +%% COMMON TEST CALLBACK FUNCTIONS +%%-------------------------------------------------------------------- + +%%-------------------------------------------------------------------- +%% Function: suite() -> Info +%% +%% Info = [tuple()] +%% List of key/value pairs. +%% +%% Description: Returns list of tuples to set default properties +%% for the suite. +%% +%% Note: The suite/0 function is only meant to be used to return +%% default data values, not perform any other operations. +%%-------------------------------------------------------------------- +suite() -> + [ + {timetrap,{seconds,10}} + ]. + +%%-------------------------------------------------------------------- +%% Function: init_per_suite(Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% +%% Config0 = Config1 = [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Reason = term() +%% The reason for skipping the suite. +%% +%% Description: Initialization before the suite. +%% +%% Note: This function is free to add any key/value pairs to the Config +%% variable, but should NOT alter/remove any existing entries. +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + Config. + +%%-------------------------------------------------------------------- +%% Function: end_per_suite(Config0) -> void() | {save_config,Config1} +%% +%% Config0 = Config1 = [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% +%% Description: Cleanup after the suite. +%%-------------------------------------------------------------------- +end_per_suite(_Config) -> + ok. + +%%-------------------------------------------------------------------- +%% Function: init_per_testcase(TestCase, Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% +%% TestCase = atom() +%% Name of the test case that is about to run. +%% Config0 = Config1 = [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Reason = term() +%% The reason for skipping the test case. +%% +%% Description: Initialization before each test case. +%% +%% Note: This function is free to add any key/value pairs to the Config +%% variable, but should NOT alter/remove any existing entries. +%%-------------------------------------------------------------------- +init_per_testcase(_TestCase, Config) -> + Config. + +%%-------------------------------------------------------------------- +%% Function: end_per_testcase(TestCase, Config0) -> +%% void() | {save_config,Config1} +%% +%% TestCase = atom() +%% Name of the test case that is finished. +%% Config0 = Config1 = [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% +%% Description: Cleanup after each test case. +%%-------------------------------------------------------------------- +end_per_testcase(_TestCase, _Config) -> + ok. + +%%-------------------------------------------------------------------- +%% Function: all() -> TestCases | {skip,Reason} +%% +%% TestCases = [TestCase | {sequence,SeqName}] +%% TestCase = atom() +%% Name of a test case. +%% SeqName = atom() +%% Name of a test case sequence. +%% Reason = term() +%% The reason for skipping all test cases. +%% +%% Description: Returns the list of test cases that are to be executed. +%%-------------------------------------------------------------------- +all() -> + [tc1, tc2]. + +%%-------------------------------------------------------------------- +%% TEST CASES +%%-------------------------------------------------------------------- + +tc1(_Config) -> + ct:comment("tc1 executed"), + ok. + +tc2(_Config) -> + exit('tc2 failed'). diff --git a/lib/common_test/test/ct_repeat_1_SUITE.erl b/lib/common_test/test/ct_repeat_1_SUITE.erl new file mode 100644 index 0000000000..1b4cafc9d3 --- /dev/null +++ b/lib/common_test/test/ct_repeat_1_SUITE.erl @@ -0,0 +1,1537 @@ +%% +%% %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% +%% + +%%%------------------------------------------------------------------- +%%% File: ct_repeat_1_SUITE.erl +%%% +%%% Description: +%%% Test some simple test case group scenarios with repeat. +%%% +%%% The suites used for the test are located in the data directory. +%%%------------------------------------------------------------------- +-module(ct_repeat_1_SUITE). + +-compile(export_all). + +-include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct_event.hrl"). + +-define(eh, ct_test_support_eh). + +%%-------------------------------------------------------------------- +%% TEST SERVER CALLBACK FUNCTIONS +%%-------------------------------------------------------------------- + +%%-------------------------------------------------------------------- +%% Description: Since Common Test starts another Test Server +%% instance, the tests need to be performed on a separate node (or +%% there will be clashes with logging processes etc). +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + Config1 = ct_test_support:init_per_suite(Config), + Config1. + +end_per_suite(Config) -> + ct_test_support:end_per_suite(Config). + +init_per_testcase(TestCase, Config) -> + ct_test_support:init_per_testcase(TestCase, Config). + +end_per_testcase(TestCase, Config) -> + ct_test_support:end_per_testcase(TestCase, Config). + +all(doc) -> + []; + +all(suite) -> + [repeat_cs, + repeat_cs_and_grs, + repeat_seq, + repeat_cs_until_any_ok, + repeat_gr_until_any_ok, + repeat_cs_until_any_fail, + repeat_gr_until_any_fail, + repeat_cs_until_all_ok, + repeat_gr_until_all_ok, + repeat_cs_until_all_fail, + repeat_gr_until_all_fail, + repeat_seq_until_any_fail, + repeat_shuffled_seq_until_any_fail + ]. + +%%-------------------------------------------------------------------- +%% TEST CASES +%%-------------------------------------------------------------------- + +repeat_cs(Config) when is_list(Config) -> + execute(repeat_cs, + "repeat_1_SUITE", repeat_cs, + Config). +%%%------------------------------------------------------------------- +repeat_cs_and_grs(Config) when is_list(Config) -> + execute(repeat_cs_and_grs, + "repeat_1_SUITE", repeat_cs_and_grs, + Config). +%%%------------------------------------------------------------------- +repeat_seq(Config) when is_list(Config) -> + execute(repeat_seq, + "repeat_1_SUITE", repeat_seq, + Config). +%%%------------------------------------------------------------------- +repeat_cs_until_any_ok(Config) when is_list(Config) -> + execute(repeat_cs_until_any_ok, + "repeat_1_SUITE", repeat_cs_until_any_ok, + Config). +%%%------------------------------------------------------------------- +repeat_gr_until_any_ok(Config) when is_list(Config) -> + execute(repeat_gr_until_any_ok, + "repeat_1_SUITE", repeat_gr_until_any_ok, + Config). +%%%------------------------------------------------------------------- +repeat_cs_until_any_fail(Config) when is_list(Config) -> + execute(repeat_cs_until_any_fail, + "repeat_1_SUITE", repeat_cs_until_any_fail, + Config). +%%%------------------------------------------------------------------- +repeat_gr_until_any_fail(Config) when is_list(Config) -> + execute(repeat_gr_until_any_fail, + "repeat_1_SUITE", repeat_gr_until_any_fail, + Config). +%%%------------------------------------------------------------------- +repeat_cs_until_all_ok(Config) when is_list(Config) -> + execute(repeat_cs_until_all_ok, + "repeat_1_SUITE", repeat_cs_until_all_ok, + Config). +%%%------------------------------------------------------------------- +repeat_gr_until_all_ok(Config) when is_list(Config) -> + execute(repeat_gr_until_all_ok, + "repeat_1_SUITE", repeat_gr_until_all_ok, + Config). +%%%------------------------------------------------------------------- +repeat_cs_until_all_fail(Config) when is_list(Config) -> + execute(repeat_cs_until_all_fail, + "repeat_1_SUITE", repeat_cs_until_all_fail, + Config). +%%%------------------------------------------------------------------- +repeat_gr_until_all_fail(Config) when is_list(Config) -> + execute(repeat_gr_until_all_fail, + "repeat_1_SUITE", repeat_gr_until_all_fail, + Config). +%%%------------------------------------------------------------------- +repeat_seq_until_any_fail(Config) when is_list(Config) -> + execute(repeat_seq_until_any_fail, + "repeat_1_SUITE", repeat_seq_until_any_fail, + Config). +%%%------------------------------------------------------------------- +repeat_shuffled_seq_until_any_fail(Config) when is_list(Config) -> + execute(repeat_shuffled_seq_until_any_fail, + "repeat_1_SUITE", repeat_shuffled_seq_until_any_fail, + Config). + +%%%----------------------------------------------------------------- +%%% HELP FUNCTIONS +%%%----------------------------------------------------------------- +execute(TestCase, SuiteName, Group, Config) -> + DataDir = ?config(data_dir, Config), + Suite = filename:join(DataDir, SuiteName), + + {Opts,ERPid} = setup([{suite,Suite},{group,Group},{label,TestCase}], Config), + ok = ct_test_support:run(Opts, Config), + Events = ct_test_support:get_events(ERPid, Config), + + ct_test_support:log_events(TestCase, + reformat(Events, ?eh), + ?config(priv_dir, Config)), + + TestEvents = events_to_check(TestCase), + ok = ct_test_support:verify_events(TestEvents, Events, Config). + +setup(Test, Config) -> + Opts0 = ct_test_support:get_opts(Config), + Level = ?config(trace_level, Config), + EvHArgs = [{cbm,ct_test_support},{trace_level,Level}], + Opts = Opts0 ++ [{event_handler,{?eh,EvHArgs}} | Test], + ERPid = ct_test_support:start_event_receiver(Config), + {Opts,ERPid}. + +reformat(Events, EH) -> + ct_test_support:reformat(Events, EH). +%reformat(Events, _EH) -> +% Events. + +%%%----------------------------------------------------------------- +%%% TEST EVENTS +%%%----------------------------------------------------------------- +events_to_check(Test) -> + %% 2 tests (ct:run_test + script_start) is default + events_to_check(Test, 2). + +events_to_check(_, 0) -> + []; +events_to_check(Test, N) -> + test_events(Test) ++ events_to_check(Test, N-1). + +test_events(repeat_cs) -> + [{?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,unknown}}, + [{?eh,tc_done,{repeat_1_SUITE,{init_per_group,repeat_cs,[]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE,{init_per_group,repeat_cs_1,[]},ok}}, + {?eh,test_stats,{2,0,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE,{end_per_group,repeat_cs_1,[]},ok}}], + [{?eh,tc_done,{repeat_1_SUITE,{init_per_group,repeat_cs_2,[{repeat,2}]},ok}}, + {?eh,test_stats,{4,0,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE,{end_per_group,repeat_cs_2,[{repeat,2}]},ok}}], + [{?eh,tc_done,{repeat_1_SUITE,{init_per_group,repeat_cs_2,[]},ok}}, + {?eh,test_stats,{6,0,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE,{end_per_group,repeat_cs_2,[]},ok}}], + {?eh,tc_done,{repeat_1_SUITE,{end_per_group,repeat_cs,[]},ok}}], + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]}]; + +test_events(repeat_cs_and_grs) -> + [{?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,unknown}}, + [{?eh,tc_done,{repeat_1_SUITE,{init_per_group,repeat_cs_and_grs,[{repeat,2}]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE,{init_per_group,gr_ok_1,[]},ok}}, + {?eh,test_stats,{1,0,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE,{end_per_group,gr_ok_1,[]},ok}}], + {?eh,tc_done,{repeat_1_SUITE,tc_fail_1,{failed,{error,{{badmatch,2},'_'}}}}}, + {?eh,test_stats,{1,1,{0,0}}}, + [{?eh,tc_done,{repeat_1_SUITE,{init_per_group,gr_fail_result,[]},ok}}, + {?eh,test_stats,{2,1,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE,{end_per_group,gr_fail_result,[]}, + {return_group_result,failed}}}], + {?eh,test_stats,{3,1,{0,0}}}, + [{?eh,tc_done,{repeat_1_SUITE,{init_per_group,gr_fail_init,[]}, + {failed,{error,fails_on_purpose}}}}, + {?eh,tc_auto_skip,{repeat_1_SUITE,tc_ok_1, + {failed,{repeat_1_SUITE,init_per_group, + {'EXIT',fails_on_purpose}}}}}, + {?eh,test_stats,{3,1,{0,1}}}, + {?eh,tc_auto_skip,{repeat_1_SUITE,end_per_group, + {failed,{repeat_1_SUITE,init_per_group, + {'EXIT',fails_on_purpose}}}}}], + {?eh,test_stats,{4,1,{0,1}}}, + {?eh,tc_done,{repeat_1_SUITE,{end_per_group,repeat_cs_and_grs,[{repeat,2}]},ok}}], + [{?eh,tc_done,{repeat_1_SUITE,{init_per_group,repeat_cs_and_grs,[]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE,{init_per_group,gr_ok_1,[]},ok}}, + {?eh,test_stats,{5,1,{0,1}}}, + {?eh,tc_done,{repeat_1_SUITE,{end_per_group,gr_ok_1,[]},ok}}], + {?eh,tc_done,{repeat_1_SUITE,tc_fail_1,{failed,{error,{{badmatch,2},'_'}}}}}, + {?eh,test_stats,{5,2,{0,1}}}, + [{?eh,tc_done,{repeat_1_SUITE,{init_per_group,gr_fail_result,[]},ok}}, + {?eh,test_stats,{6,2,{0,1}}}, + {?eh,tc_done,{repeat_1_SUITE,{end_per_group,gr_fail_result,[]}, + {return_group_result,failed}}}], + {?eh,test_stats,{7,2,{0,1}}}, + [{?eh,tc_done,{repeat_1_SUITE,{init_per_group,gr_fail_init,[]}, + {failed,{error,fails_on_purpose}}}}, + {?eh,tc_auto_skip,{repeat_1_SUITE,tc_ok_1, + {failed,{repeat_1_SUITE,init_per_group, + {'EXIT',fails_on_purpose}}}}}, + {?eh,test_stats,{7,2,{0,2}}}, + {?eh,tc_auto_skip,{repeat_1_SUITE,end_per_group, + {failed,{repeat_1_SUITE,init_per_group, + {'EXIT',fails_on_purpose}}}}}], + {?eh,test_stats,{8,2,{0,2}}}, + {?eh,tc_done,{repeat_1_SUITE,{end_per_group,repeat_cs_and_grs,[]},ok}}], + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]} + ]; + +test_events(repeat_seq) -> + [{?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,start_info,{1,1,unknown}}, + [{?eh,tc_done,{repeat_1_SUITE,{init_per_group,repeat_seq,[]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_seq_1,[sequence,{repeat,2}]}, + ok}}, + {?eh,test_stats,{1,0,{0,0}}}, + {?eh,test_stats,{1,1,{0,0}}}, + {?eh,tc_auto_skip,{repeat_1_SUITE,tc_ok_2, + {failed,{repeat_1_SUITE,tc_fail_1}}}}, + {?eh,test_stats,{1,1,{0,1}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_seq_1,[sequence,{repeat,2}]}, + ok}}], + [{?eh,tc_done,{repeat_1_SUITE,{init_per_group,repeat_seq_1, + [sequence]},ok}}, + {?eh,test_stats,{2,2,{0,2}}}, + {?eh,tc_done,{repeat_1_SUITE,{end_per_group,repeat_seq_1, + [sequence]},ok}}], + + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_seq_2,[sequence,{repeat,2}]}, + ok}}, + {?eh,test_stats,{3,2,{0,2}}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,gr_fail_result,[]},ok}}, + {?eh,test_stats,{4,2,{0,2}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,gr_fail_result,[]}, + {return_group_result,failed}}}], + {?eh,tc_auto_skip,{repeat_1_SUITE,tc_ok_2, + {group_result,gr_fail_result,failed}}}, + {?eh,test_stats,{4,2,{0,3}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_seq_2,[sequence,{repeat,2}]}, + ok}}], + [{?eh,tc_done, + {repeat_1_SUITE,{init_per_group,repeat_seq_2,[sequence]},ok}}, + {?eh,test_stats,{6,2,{0,4}}}, + {?eh,tc_done,{repeat_1_SUITE,{end_per_group,repeat_seq_2, + [sequence]},ok}}], + + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_seq_3,[sequence,{repeat,2}]}, + ok}}, + {?eh,test_stats,{7,2,{0,4}}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,gr_fail_init,[]}, + {failed,{error,fails_on_purpose}}}}, + {?eh,test_stats,{7,2,{0,5}}}, + {?eh,tc_auto_skip,{repeat_1_SUITE,end_per_group, + {failed, + {repeat_1_SUITE,init_per_group, + {'EXIT',fails_on_purpose}}}}}], + {?eh,tc_auto_skip,{repeat_1_SUITE,tc_ok_2, + {group_result,gr_fail_init,failed}}}, + {?eh,test_stats,{7,2,{0,6}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_seq_3,[sequence,{repeat,2}]}, + ok}}], + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_seq_3,[sequence]},ok}}, + {?eh,test_stats,{8,2,{0,8}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_seq_3,[sequence]},ok}}], + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_seq_4,[sequence,{repeat,2}]}, + ok}}, + {?eh,test_stats,{8,3,{0,8}}}, + {?eh,tc_auto_skip,{repeat_1_SUITE, + tc_ok_1,{failed,{repeat_1_SUITE,tc_fail_1}}}}, + {?eh,test_stats,{8,3,{0,9}}}, + {?eh,tc_auto_skip,{repeat_1_SUITE, + tc_ok_1,{failed,{repeat_1_SUITE,tc_fail_1}}}}, + {?eh,test_stats,{8,3,{0,10}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_seq_4,[sequence,{repeat,2}]}, + ok}}], + [{?eh,tc_done,{repeat_1_SUITE,{init_per_group,repeat_seq_4,[sequence]},ok}}, + {?eh,test_stats,{8,4,{0,12}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_seq_4,[sequence]},ok}}], + + {?eh,tc_done,{repeat_1_SUITE,{end_per_group,repeat_seq,[]},ok}}], + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]}]; + +test_events(repeat_cs_until_any_ok) -> + [ + {?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,unknown}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_cs_until_any_ok,[]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_cs_until_any_ok_1, + [{repeat_until_any_ok,3}]},ok}}, + {?eh,test_stats,{0,2,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE,tc_fail_then_ok_1, + {failed,{error,failing_this_time}}}}, + {?eh,test_stats,{0,3,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_cs_until_any_ok_1, + [{repeat_until_any_ok,3}]},ok}}], + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_cs_until_any_ok_1, + [{repeat_until_any_ok,2}]},ok}}, + {?eh,test_stats,{0,5,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE,tc_fail_then_ok_1,ok}}, + {?eh,test_stats,{1,5,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_cs_until_any_ok_1, + [{repeat_until_any_ok,2}]},ok}}], + + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_cs_until_any_ok_2, + [{repeat_until_any_ok,3}]},ok}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{2,5,{0,0}}}, + {?eh,test_stats,{2,6,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_cs_until_any_ok_2, + [{repeat_until_any_ok,3}]},ok}}], + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_cs_until_any_ok,[]},ok}}], + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]}]; + +test_events(repeat_gr_until_any_ok) -> + [{?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,unknown}}, + [{?eh,tc_done, + {repeat_1_SUITE,{init_per_group,repeat_gr_until_any_ok,[]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_gr_until_any_ok_1, + [{repeat_until_any_ok,3}]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,gr_fail_result,[]},ok}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,gr_fail_result,[]}, + {return_group_result,failed}}}], + {?eh,tc_done,{repeat_1_SUITE,tc_fail_1, + {failed,{error,{{badmatch,2},'_'}}}}}, + {?eh,test_stats,{1,1,{0,0}}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,gr_fail_init,[]}, + {failed,{error,fails_on_purpose}}}}, + {?eh,test_stats,{1,1,{0,1}}}, + {?eh,tc_auto_skip,{repeat_1_SUITE,end_per_group, + {failed,{repeat_1_SUITE,init_per_group, + {'EXIT',fails_on_purpose}}}}}], + {?eh,test_stats,{1,2,{0,1}}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,gr_fail_result_then_ok,[]},ok}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,gr_fail_result_then_ok,[]}, + {return_group_result,failed}}}], + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_gr_until_any_ok_1, + [{repeat_until_any_ok,3}]},ok}}], + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_gr_until_any_ok_1, + [{repeat_until_any_ok,2}]},ok}}, + %% ... + {?eh,test_stats,{3,4,{0,2}}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,gr_fail_result_then_ok,[]},ok}}, + {?eh,test_stats,{4,4,{0,2}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,gr_fail_result_then_ok,[]},ok}}], + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_gr_until_any_ok_1, + [{repeat_until_any_ok,2}]},ok}}], + + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_gr_until_any_ok_2, + [{repeat_until_any_ok,3}]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE, + {end_per_group,gr_fail_result,[]}, + {return_group_result,failed}}}], + {?eh,tc_done,{repeat_1_SUITE,tc_fail_1, + {failed,{error,{{badmatch,2},'_'}}}}}, + {?eh,test_stats,{5,5,{0,2}}}, + {?eh,tc_done,{repeat_1_SUITE,tc_fail_then_ok_1, + {failed,{error,failing_this_time}}}}, + {?eh,test_stats,{5,6,{0,2}}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,gr_fail_init,[]}, + {failed,{error,fails_on_purpose}}}}, + {?eh,test_stats,{5,6,{0,3}}}, + {?eh,tc_auto_skip,{repeat_1_SUITE,end_per_group, + {failed,{repeat_1_SUITE,init_per_group, + {'EXIT',fails_on_purpose}}}}}], + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_gr_until_any_ok_2, + [{repeat_until_any_ok,3}]},ok}}], + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_gr_until_any_ok_2, + [{repeat_until_any_ok,2}]},ok}}, + {?eh,test_stats,{6,7,{0,3}}}, + {?eh,tc_start,{repeat_1_SUITE,tc_fail_then_ok_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_fail_then_ok_1,ok}}, + {?eh,test_stats,{7,7,{0,3}}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,gr_fail_init,[]}, + {failed,{error,fails_on_purpose}}}}, + {?eh,test_stats,{7,7,{0,4}}}, + {?eh,tc_auto_skip,{repeat_1_SUITE,end_per_group, + {failed,{repeat_1_SUITE,init_per_group, + {'EXIT',fails_on_purpose}}}}}], + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_gr_until_any_ok_2, + [{repeat_until_any_ok,2}]},ok}}], + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_gr_until_any_ok,[]},ok}}], + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]}]; + +test_events(repeat_cs_until_any_fail) -> + [{?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,unknown}}, + {?eh,tc_start,{repeat_1_SUITE,init_per_suite}}, + {?eh,tc_done,{repeat_1_SUITE,init_per_suite,ok}}, + [{?eh,tc_start, + {repeat_1_SUITE,{init_per_group,repeat_cs_until_any_fail,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{init_per_group,repeat_cs_until_any_fail,[]},ok}}, + [{?eh,tc_start, + {repeat_1_SUITE, + {init_per_group,repeat_cs_until_any_fail_1, + [{repeat_until_any_fail,3}]}}}, + {?eh,tc_done, + {repeat_1_SUITE, + {init_per_group,repeat_cs_until_any_fail_1, + [{repeat_until_any_fail,3}]}, + ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{1,0,{0,0}}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_2}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_2,ok}}, + {?eh,test_stats,{2,0,{0,0}}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_then_fail_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_then_fail_1,ok}}, + {?eh,test_stats,{3,0,{0,0}}}, + {?eh,tc_start, + {repeat_1_SUITE, + {end_per_group,repeat_cs_until_any_fail_1, + [{repeat_until_any_fail,3}]}}}, + {?eh,tc_done, + {repeat_1_SUITE, + {end_per_group,repeat_cs_until_any_fail_1, + [{repeat_until_any_fail,3}]}, + ok}}], + [{?eh,tc_start, + {repeat_1_SUITE, + {init_per_group,repeat_cs_until_any_fail_1, + [{repeat_until_any_fail,2}]}}}, + {?eh,tc_done, + {repeat_1_SUITE, + {init_per_group,repeat_cs_until_any_fail_1, + [{repeat_until_any_fail,2}]}, + ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{4,0,{0,0}}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_2}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_2,ok}}, + {?eh,test_stats,{5,0,{0,0}}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_then_fail_1}}, + {?eh,tc_done, + {repeat_1_SUITE,tc_ok_then_fail_1, + {failed,{error,failing_this_time}}}}, + {?eh,test_stats,{5,1,{0,0}}}, + {?eh,tc_start, + {repeat_1_SUITE, + {end_per_group,repeat_cs_until_any_fail_1, + [{repeat_until_any_fail,2}]}}}, + {?eh,tc_done, + {repeat_1_SUITE, + {end_per_group,repeat_cs_until_any_fail_1, + [{repeat_until_any_fail,2}]}, + ok}}], + [{?eh,tc_start, + {repeat_1_SUITE, + {init_per_group,repeat_cs_until_any_fail_2, + [{repeat_until_any_fail,3}]}}}, + {?eh,tc_done, + {repeat_1_SUITE, + {init_per_group,repeat_cs_until_any_fail_2, + [{repeat_until_any_fail,3}]}, + ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_fail_1}}, + {?eh,tc_done, + {repeat_1_SUITE,tc_fail_1, + {failed, + {error, + {{badmatch,2}, + [{repeat_1_SUITE,tc_fail_1,1}, + {repeat_1_SUITE,tc_fail_1,1}, + {test_server,my_apply,3}, + {test_server,ts_tc,3}, + {test_server,run_test_case_eval1,6}, + {test_server,run_test_case_eval,8}]}}}}}, + {?eh,test_stats,{5,2,{0,0}}}, + {?eh,tc_start,{repeat_1_SUITE,tc_fail_2}}, + {?eh,tc_done, + {repeat_1_SUITE,tc_fail_2,{failed,{error,exit_on_purpose}}}}, + {?eh,test_stats,{5,3,{0,0}}}, + {?eh,tc_start, + {repeat_1_SUITE, + {end_per_group,repeat_cs_until_any_fail_2, + [{repeat_until_any_fail,3}]}}}, + {?eh,tc_done, + {repeat_1_SUITE, + {end_per_group,repeat_cs_until_any_fail_2, + [{repeat_until_any_fail,3}]}, + ok}}], + {?eh,tc_start, + {repeat_1_SUITE,{end_per_group,repeat_cs_until_any_fail,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{end_per_group,repeat_cs_until_any_fail,[]},ok}}], + {?eh,tc_start,{repeat_1_SUITE,end_per_suite}}, + {?eh,tc_done,{repeat_1_SUITE,end_per_suite,ok}}, + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]}]; + +test_events(repeat_gr_until_any_fail) -> + [{?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,unknown}}, + {?eh,tc_start,{repeat_1_SUITE,init_per_suite}}, + {?eh,tc_done,{repeat_1_SUITE,init_per_suite,ok}}, + [{?eh,tc_start, + {repeat_1_SUITE,{init_per_group,repeat_gr_until_any_fail,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{init_per_group,repeat_gr_until_any_fail,[]},ok}}, + [{?eh,tc_start, + {repeat_1_SUITE, + {init_per_group,repeat_gr_until_any_fail_1, + [{repeat_until_any_fail,3}]}}}, + {?eh,tc_done, + {repeat_1_SUITE, + {init_per_group,repeat_gr_until_any_fail_1, + [{repeat_until_any_fail,3}]}, + ok}}, + [{?eh,tc_start, + {repeat_1_SUITE,{init_per_group,gr_ok_1,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{init_per_group,gr_ok_1,[]},ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{1,0,{0,0}}}, + {?eh,tc_start, + {repeat_1_SUITE,{end_per_group,gr_ok_1,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{end_per_group,gr_ok_1,[]},ok}}], + {?eh,tc_start,{repeat_1_SUITE,tc_ok_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{2,0,{0,0}}}, + [{?eh,tc_start, + {repeat_1_SUITE,{init_per_group,gr_ok_then_fail_result,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{init_per_group,gr_ok_then_fail_result,[]},ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{3,0,{0,0}}}, + {?eh,tc_start, + {repeat_1_SUITE,{end_per_group,gr_ok_then_fail_result,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{end_per_group,gr_ok_then_fail_result,[]},ok}}], + {?eh,tc_start,{repeat_1_SUITE,tc_ok_2}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_2,ok}}, + {?eh,test_stats,{4,0,{0,0}}}, + {?eh,tc_start, + {repeat_1_SUITE, + {end_per_group,repeat_gr_until_any_fail_1, + [{repeat_until_any_fail,3}]}}}, + {?eh,tc_done, + {repeat_1_SUITE, + {end_per_group,repeat_gr_until_any_fail_1, + [{repeat_until_any_fail,3}]}, + ok}}], + [{?eh,tc_start, + {repeat_1_SUITE, + {init_per_group,repeat_gr_until_any_fail_1, + [{repeat_until_any_fail,2}]}}}, + {?eh,tc_done, + {repeat_1_SUITE, + {init_per_group,repeat_gr_until_any_fail_1, + [{repeat_until_any_fail,2}]}, + ok}}, + [{?eh,tc_start, + {repeat_1_SUITE,{init_per_group,gr_ok_1,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{init_per_group,gr_ok_1,[]},ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{5,0,{0,0}}}, + {?eh,tc_start, + {repeat_1_SUITE,{end_per_group,gr_ok_1,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{end_per_group,gr_ok_1,[]},ok}}], + {?eh,tc_start,{repeat_1_SUITE,tc_ok_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{6,0,{0,0}}}, + [{?eh,tc_start, + {repeat_1_SUITE,{init_per_group,gr_ok_then_fail_result,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{init_per_group,gr_ok_then_fail_result,[]},ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{7,0,{0,0}}}, + {?eh,tc_start, + {repeat_1_SUITE,{end_per_group,gr_ok_then_fail_result,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE, + {end_per_group,gr_ok_then_fail_result,[]}, + {return_group_result,failed}}}], + {?eh,tc_start,{repeat_1_SUITE,tc_ok_2}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_2,ok}}, + {?eh,test_stats,{8,0,{0,0}}}, + {?eh,tc_start, + {repeat_1_SUITE, + {end_per_group,repeat_gr_until_any_fail_1, + [{repeat_until_any_fail,2}]}}}, + {?eh,tc_done, + {repeat_1_SUITE, + {end_per_group,repeat_gr_until_any_fail_1, + [{repeat_until_any_fail,2}]}, + ok}}], + [{?eh,tc_start, + {repeat_1_SUITE, + {init_per_group,repeat_gr_until_any_fail_2, + [{repeat_until_any_fail,3}]}}}, + {?eh,tc_done, + {repeat_1_SUITE, + {init_per_group,repeat_gr_until_any_fail_2, + [{repeat_until_any_fail,3}]}, + ok}}, + [{?eh,tc_start, + {repeat_1_SUITE,{init_per_group,gr_ok_1,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{init_per_group,gr_ok_1,[]},ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{9,0,{0,0}}}, + {?eh,tc_start, + {repeat_1_SUITE,{end_per_group,gr_ok_1,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{end_per_group,gr_ok_1,[]},ok}}], + {?eh,tc_start,{repeat_1_SUITE,tc_ok_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{10,0,{0,0}}}, + [{?eh,tc_start, + {repeat_1_SUITE,{init_per_group,gr_ok_then_fail_init,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{init_per_group,gr_ok_then_fail_init,[]},ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{11,0,{0,0}}}, + {?eh,tc_start, + {repeat_1_SUITE,{end_per_group,gr_ok_then_fail_init,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{end_per_group,gr_ok_then_fail_init,[]},ok}}], + {?eh,tc_start,{repeat_1_SUITE,tc_ok_2}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_2,ok}}, + {?eh,test_stats,{12,0,{0,0}}}, + {?eh,tc_start, + {repeat_1_SUITE, + {end_per_group,repeat_gr_until_any_fail_2, + [{repeat_until_any_fail,3}]}}}, + {?eh,tc_done, + {repeat_1_SUITE, + {end_per_group,repeat_gr_until_any_fail_2, + [{repeat_until_any_fail,3}]}, + ok}}], + [{?eh,tc_start, + {repeat_1_SUITE, + {init_per_group,repeat_gr_until_any_fail_2, + [{repeat_until_any_fail,2}]}}}, + {?eh,tc_done, + {repeat_1_SUITE, + {init_per_group,repeat_gr_until_any_fail_2, + [{repeat_until_any_fail,2}]}, + ok}}, + [{?eh,tc_start, + {repeat_1_SUITE,{init_per_group,gr_ok_1,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{init_per_group,gr_ok_1,[]},ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{13,0,{0,0}}}, + {?eh,tc_start, + {repeat_1_SUITE,{end_per_group,gr_ok_1,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{end_per_group,gr_ok_1,[]},ok}}], + {?eh,tc_start,{repeat_1_SUITE,tc_ok_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{14,0,{0,0}}}, + [{?eh,tc_start, + {repeat_1_SUITE,{init_per_group,gr_ok_then_fail_init,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE, + {init_per_group,gr_ok_then_fail_init,[]}, + {failed,{error,failing_this_time}}}}, + {?eh,tc_auto_skip, + {repeat_1_SUITE,tc_ok_1, + {failed, + {repeat_1_SUITE,init_per_group, + {'EXIT',failing_this_time}}}}}, + {?eh,test_stats,{14,0,{0,1}}}, + {?eh,tc_auto_skip, + {repeat_1_SUITE,end_per_group, + {failed, + {repeat_1_SUITE,init_per_group, + {'EXIT',failing_this_time}}}}}], + {?eh,tc_start,{repeat_1_SUITE,tc_ok_2}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_2,ok}}, + {?eh,test_stats,{15,0,{0,1}}}, + {?eh,tc_start, + {repeat_1_SUITE, + {end_per_group,repeat_gr_until_any_fail_2, + [{repeat_until_any_fail,2}]}}}, + {?eh,tc_done, + {repeat_1_SUITE, + {end_per_group,repeat_gr_until_any_fail_2, + [{repeat_until_any_fail,2}]}, + ok}}], + [{?eh,tc_start, + {repeat_1_SUITE, + {init_per_group,repeat_gr_until_any_fail_3, + [{repeat_until_any_fail,3}]}}}, + {?eh,tc_done, + {repeat_1_SUITE, + {init_per_group,repeat_gr_until_any_fail_3, + [{repeat_until_any_fail,3}]}, + ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_then_fail_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_then_fail_1,ok}}, + {?eh,test_stats,{16,0,{0,1}}}, + [{?eh,tc_start, + {repeat_1_SUITE,{init_per_group,gr_ok_1,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{init_per_group,gr_ok_1,[]},ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{17,0,{0,1}}}, + {?eh,tc_start, + {repeat_1_SUITE,{end_per_group,gr_ok_1,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{end_per_group,gr_ok_1,[]},ok}}], + {?eh,tc_start,{repeat_1_SUITE,tc_ok_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{18,0,{0,1}}}, + {?eh,tc_start, + {repeat_1_SUITE, + {end_per_group,repeat_gr_until_any_fail_3, + [{repeat_until_any_fail,3}]}}}, + {?eh,tc_done, + {repeat_1_SUITE, + {end_per_group,repeat_gr_until_any_fail_3, + [{repeat_until_any_fail,3}]}, + ok}}], + [{?eh,tc_start, + {repeat_1_SUITE, + {init_per_group,repeat_gr_until_any_fail_3, + [{repeat_until_any_fail,2}]}}}, + {?eh,tc_done, + {repeat_1_SUITE, + {init_per_group,repeat_gr_until_any_fail_3, + [{repeat_until_any_fail,2}]}, + ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_then_fail_1}}, + {?eh,tc_done, + {repeat_1_SUITE,tc_ok_then_fail_1, + {failed,{error,failing_this_time}}}}, + {?eh,test_stats,{18,1,{0,1}}}, + [{?eh,tc_start, + {repeat_1_SUITE,{init_per_group,gr_ok_1,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{init_per_group,gr_ok_1,[]},ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{19,1,{0,1}}}, + {?eh,tc_start, + {repeat_1_SUITE,{end_per_group,gr_ok_1,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{end_per_group,gr_ok_1,[]},ok}}], + {?eh,tc_start,{repeat_1_SUITE,tc_ok_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{20,1,{0,1}}}, + {?eh,tc_start, + {repeat_1_SUITE, + {end_per_group,repeat_gr_until_any_fail_3, + [{repeat_until_any_fail,2}]}}}, + {?eh,tc_done, + {repeat_1_SUITE, + {end_per_group,repeat_gr_until_any_fail_3, + [{repeat_until_any_fail,2}]}, + ok}}], + {?eh,tc_start, + {repeat_1_SUITE,{end_per_group,repeat_gr_until_any_fail,[]}}}, + {?eh,tc_done, + {repeat_1_SUITE,{end_per_group,repeat_gr_until_any_fail,[]},ok}}], + {?eh,tc_start,{repeat_1_SUITE,end_per_suite}}, + {?eh,tc_done,{repeat_1_SUITE,end_per_suite,ok}}, + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]}]; + +test_events(repeat_cs_until_all_ok) -> + [{?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,unknown}}, + [{?eh,tc_done,{repeat_1_SUITE,{init_per_group,repeat_cs_until_all_ok,[]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_cs_until_all_ok_1, + [{repeat_until_all_ok,3}]},ok}}, + {?eh,tc_done,{repeat_1_SUITE,tc_fail_then_ok_1, + {failed,{error,failing_this_time}}}}, + {?eh,test_stats,{0,1,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{1,1,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE,tc_fail_then_ok_2, + {failed,{error,failing_this_time}}}}, + {?eh,test_stats,{1,2,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_cs_until_all_ok_1, + [{repeat_until_all_ok,3}]},ok}}], + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_cs_until_all_ok_1, + [{repeat_until_all_ok,2}]},ok}}, + {?eh,tc_done,{repeat_1_SUITE,tc_fail_then_ok_1,ok}}, + {?eh,test_stats,{2,2,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{3,2,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE,tc_fail_then_ok_2,ok}}, + {?eh,test_stats,{4,2,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_cs_until_all_ok_1, + [{repeat_until_all_ok,2}]},ok}}], + + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_cs_until_all_ok_2, + [{repeat_until_all_ok,3}]},ok}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_2,ok}}, + {?eh,test_stats,{6,2,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_cs_until_all_ok_2, + [{repeat_until_all_ok,3}]},ok}}], + + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_cs_until_all_ok,[]},ok}}], + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]}]; + +test_events(repeat_gr_until_all_ok) -> + [{?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,unknown}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_gr_until_all_ok,[]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_gr_until_all_ok_1, + [{repeat_until_all_ok,3}]},ok}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{1,0,{0,0}}}, + [{?eh,tc_done,{repeat_1_SUITE,{init_per_group,gr_ok_1,[]},ok}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{2,0,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE,{end_per_group,gr_ok_1,[]},ok}}], + {?eh,tc_done,{repeat_1_SUITE,tc_fail_then_ok_1, + {failed,{error,failing_this_time}}}}, + {?eh,test_stats,{2,1,{0,0}}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,gr_fail_result_then_ok,[]},ok}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{3,1,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,gr_fail_result_then_ok,[]}, + {return_group_result,failed}}}], + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_gr_until_all_ok_1, + [{repeat_until_all_ok,3}]},ok}}], + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_gr_until_all_ok_1, + [{repeat_until_all_ok,2}]},ok}}, + {?eh,test_stats,{5,1,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE,tc_fail_then_ok_1,ok}}, + {?eh,test_stats,{6,1,{0,0}}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,gr_fail_result_then_ok,[]},ok}}, + {?eh,test_stats,{7,1,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,gr_fail_result_then_ok,[]},ok}}], + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_gr_until_all_ok_1, + [{repeat_until_all_ok,2}]},ok}}], + + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_gr_until_all_ok_2, + [{repeat_until_all_ok,3}]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,gr_fail_init_then_ok,[]}, + {failed,{error,failing_this_time}}}}, + {?eh,tc_auto_skip,{repeat_1_SUITE,tc_ok_1, + {failed,{repeat_1_SUITE,init_per_group, + {'EXIT',failing_this_time}}}}}, + {?eh,test_stats,{7,1,{0,1}}}, + {?eh,tc_auto_skip,{repeat_1_SUITE,end_per_group, + {failed,{repeat_1_SUITE,init_per_group, + {'EXIT',failing_this_time}}}}}], + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{8,1,{0,1}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_gr_until_all_ok_2, + [{repeat_until_all_ok,3}]},ok}}], + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_gr_until_all_ok_2, + [{repeat_until_all_ok,2}]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,gr_fail_init_then_ok,[]},ok}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{9,1,{0,1}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,gr_fail_init_then_ok,[]},ok}}], + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{10,1,{0,1}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_gr_until_all_ok_2, + [{repeat_until_all_ok,2}]},ok}}], + + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_gr_until_all_ok_3, + [{repeat_until_all_ok,3}]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE,{init_per_group,gr_ok_1,[]},ok}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{11,1,{0,1}}}, + {?eh,tc_done,{repeat_1_SUITE,{end_per_group,gr_ok_1,[]},ok}}], + {?eh,tc_done,{repeat_1_SUITE,tc_fail_then_ok_1, + {failed,{error,failing_this_time}}}}, + {?eh,test_stats,{11,2,{0,1}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_gr_until_all_ok_3, + [{repeat_until_all_ok,3}]},ok}}], + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_gr_until_all_ok_3, + [{repeat_until_all_ok,2}]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE,{init_per_group,gr_ok_1,[]},ok}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{12,2,{0,1}}}, + {?eh,tc_done,{repeat_1_SUITE,{end_per_group,gr_ok_1,[]},ok}}], + {?eh,tc_done,{repeat_1_SUITE,tc_fail_then_ok_1,ok}}, + {?eh,test_stats,{13,2,{0,1}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_gr_until_all_ok_3, + [{repeat_until_all_ok,2}]},ok}}], + + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_gr_until_all_ok,[]},ok}}], + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]}]; + +test_events(repeat_cs_until_all_fail) -> + [{?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,unknown}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_cs_until_all_fail,[]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_cs_until_all_fail_1, + [{repeat_until_all_fail,3}]},ok}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_then_fail_1,ok}}, + {?eh,test_stats,{1,0,{0,0}}}, + {?eh,tc_start,{repeat_1_SUITE,tc_fail_1}}, + {?eh,test_stats,{1,1,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_then_fail_2,ok}}, + {?eh,test_stats,{2,1,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_cs_until_all_fail_1, + [{repeat_until_all_fail,3}]},ok}}], + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_cs_until_all_fail_1, + [{repeat_until_all_fail,2}]},ok}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_then_fail_1, + {failed,{error,failing_this_time}}}}, + {?eh,test_stats,{2,2,{0,0}}}, + {?eh,tc_start,{repeat_1_SUITE,tc_fail_1}}, + {?eh,test_stats,{2,3,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_then_fail_2, + {failed,{error,failing_this_time}}}}, + {?eh,test_stats,{2,4,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_cs_until_all_fail_1, + [{repeat_until_all_fail,2}]},ok}}], + + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_cs_until_all_fail_2, + [{repeat_until_all_fail,3}]},ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_fail_1}}, + {?eh,test_stats,{2,5,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_cs_until_all_fail_2, + [{repeat_until_all_fail,3}]},ok}}], + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_cs_until_all_fail,[]},ok}}], + + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]}]; + +test_events(repeat_gr_until_all_fail) -> + [{?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,unknown}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_gr_until_all_fail,[]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_gr_until_all_fail_1, + [{repeat_until_all_fail,3}]},ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_fail_1}}, + {?eh,test_stats,{0,1,{0,0}}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,gr_fail_init,[]}, + {failed,{error,fails_on_purpose}}}}, + {?eh,test_stats,{0,1,{0,1}}}, + {?eh,tc_auto_skip,{repeat_1_SUITE,end_per_group, + {failed,{repeat_1_SUITE,init_per_group, + {'EXIT',fails_on_purpose}}}}}], + {?eh,tc_done,{repeat_1_SUITE,tc_ok_then_fail_1,ok}}, + {?eh,test_stats,{1,1,{0,1}}}, + [{?eh,tc_done,{repeat_1_SUITE,{end_per_group, + gr_ok_then_fail_result,[]},ok}}], + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_gr_until_all_fail_1, + [{repeat_until_all_fail,3}]},ok}}], + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_gr_until_all_fail_1, + [{repeat_until_all_fail,2}]},ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_fail_1}}, + {?eh,test_stats,{2,2,{0,1}}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,gr_fail_init,[]}, + {failed,{error,fails_on_purpose}}}}, + {?eh,test_stats,{2,2,{0,2}}}, + {?eh,tc_auto_skip,{repeat_1_SUITE,end_per_group, + {failed,{repeat_1_SUITE,init_per_group, + {'EXIT',fails_on_purpose}}}}}], + {?eh,tc_done,{repeat_1_SUITE,tc_ok_then_fail_1, + {failed,{error,failing_this_time}}}}, + {?eh,test_stats,{2,3,{0,2}}}, + [{?eh,tc_done,{repeat_1_SUITE,{init_per_group, + gr_ok_then_fail_result,[]},ok}}, + {?eh,test_stats,{3,3,{0,2}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,gr_ok_then_fail_result,[]}, + {return_group_result,failed}}}], + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_gr_until_all_fail_1, + [{repeat_until_all_fail,2}]},ok}}], + + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_gr_until_all_fail_2, + [{repeat_until_all_fail,3}]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE,{end_per_group,gr_ok_then_fail_init,[]},ok}}], + {?eh,tc_start,{repeat_1_SUITE,tc_fail_1}}, + {?eh,test_stats,{4,4,{0,2}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_gr_until_all_fail_2, + [{repeat_until_all_fail,3}]},ok}}], + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_gr_until_all_fail_2, + [{repeat_until_all_fail,2}]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,gr_ok_then_fail_init,[]}, + {failed,{error,failing_this_time}}}}, + {?eh,test_stats,{4,4,{0,3}}}, + {?eh,tc_auto_skip,{repeat_1_SUITE,end_per_group, + {failed,{repeat_1_SUITE,init_per_group, + {'EXIT',failing_this_time}}}}}], + {?eh,tc_start,{repeat_1_SUITE,tc_fail_1}}, + {?eh,test_stats,{4,5,{0,3}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_gr_until_all_fail_2, + [{repeat_until_all_fail,2}]},ok}}], + + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_gr_until_all_fail_3, + [{repeat_until_all_fail,3}]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE, + {end_per_group,gr_fail_result,[]}, + {return_group_result,failed}}}], + {?eh,tc_done,{repeat_1_SUITE,tc_ok_then_fail_1,ok}}, + {?eh,test_stats,{6,5,{0,3}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_gr_until_all_fail_3, + [{repeat_until_all_fail,3}]},ok}}], + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_gr_until_all_fail_3, + [{repeat_until_all_fail,2}]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE, + {end_per_group,gr_fail_result,[]}, + {return_group_result,failed}}}], + {?eh,tc_done,{repeat_1_SUITE,tc_ok_then_fail_1, + {failed,{error,failing_this_time}}}}, + {?eh,test_stats,{7,6,{0,3}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_gr_until_all_fail_3, + [{repeat_until_all_fail,2}]},ok}}], + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_gr_until_all_fail,[]},ok}}], + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]}]; + +test_events(repeat_seq_until_any_fail) -> + [{?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,unknown}}, + + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_seq_until_any_fail,[]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_seq_until_any_fail_1, + [sequence,{repeat_until_any_fail,2}]},ok}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_2,ok}}, + {?eh,test_stats,{2,0,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_seq_until_any_fail_1, + [sequence,{repeat_until_any_fail,2}]},ok}}], + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group, + repeat_seq_until_any_fail_1,[sequence]},ok}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_2,ok}}, + {?eh,test_stats,{4,0,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group, + repeat_seq_until_any_fail_1,[sequence]},ok}}], + + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_seq_until_any_fail_2, + [{repeat_until_any_fail,2},sequence]},ok}}, + {?eh,test_stats,{5,0,{0,0}}}, + [{?eh,tc_done,{repeat_1_SUITE,{end_per_group,gr_ok_1,[]},ok}}], + {?eh,test_stats,{7,0,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_seq_until_any_fail_2, + [{repeat_until_any_fail,2},sequence]},ok}}], + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_seq_until_any_fail_2,[sequence]}, + ok}}, + {?eh,test_stats,{8,0,{0,0}}}, + [{?eh,tc_done,{repeat_1_SUITE,{end_per_group,gr_ok_1,[]},ok}}], + {?eh,test_stats,{10,0,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_seq_until_any_fail_2,[sequence]}, + ok}}], + + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_seq_until_any_fail_3, + [sequence,{repeat_until_any_fail,3}]},ok}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{11,0,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_then_fail_1,ok}}, + {?eh,test_stats,{12,0,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_2,ok}}, + {?eh,test_stats,{13,0,{0,0}}}, + [{?eh,tc_done,{repeat_1_SUITE,{end_per_group,gr_ok_1,[]},ok}}], + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_seq_until_any_fail_3, + [sequence,{repeat_until_any_fail,3}]},ok}}], + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_seq_until_any_fail_3, + [{repeat_until_any_fail,2},sequence]},ok}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{15,0,{0,0}}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_then_fail_1, + {failed,{error,failing_this_time}}}}, + {?eh,test_stats,{15,1,{0,0}}}, + {?eh,tc_auto_skip,{repeat_1_SUITE,tc_ok_2, + {failed,{repeat_1_SUITE,tc_ok_then_fail_1}}}}, + {?eh,test_stats,{15,1,{0,1}}}, + {?eh,tc_auto_skip,{repeat_1_SUITE,tc_ok_1, + {failed,{repeat_1_SUITE,tc_ok_then_fail_1}}}}, + {?eh,test_stats,{15,1,{0,2}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_seq_until_any_fail_3, + [{repeat_until_any_fail,2},sequence]},ok}}], + + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_seq_until_any_fail_4, + [{repeat_until_any_fail,3},sequence]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE,{end_per_group, + gr_ok_then_fail_result,[]},ok}}], + [{?eh,tc_done,{repeat_1_SUITE,{end_per_group,gr_ok_1,[]},ok}}], + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{18,1,{0,2}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_seq_until_any_fail_4, + [{repeat_until_any_fail,3},sequence]},ok}}], + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_seq_until_any_fail_4, + [{repeat_until_any_fail,2},sequence]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE, + {end_per_group,gr_ok_then_fail_result,[]}, + {return_group_result,failed}}}], + {?eh,tc_auto_skip,{repeat_1_SUITE,tc_ok_1, + {group_result,gr_ok_then_fail_result,failed}}}, + {?eh,test_stats,{19,1,{0,3}}}, + {?eh,tc_auto_skip,{repeat_1_SUITE,tc_ok_1, + {group_result,gr_ok_then_fail_result,failed}}}, + {?eh,test_stats,{19,1,{0,4}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_seq_until_any_fail_4, + [{repeat_until_any_fail,2},sequence]},ok}}], + + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_seq_until_any_fail_5, + [{repeat_until_any_fail,3},sequence]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE,{end_per_group,gr_ok_1,[]},ok}}], + [{?eh,tc_done,{repeat_1_SUITE,{end_per_group,gr_ok_then_fail_init,[]},ok}}], + [{?eh,tc_done,{repeat_1_SUITE,{end_per_group,gr_ok_2,[]},ok}}], + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,test_stats,{23,1,{0,4}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_seq_until_any_fail_5, + [{repeat_until_any_fail,3},sequence]},ok}}], + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_seq_until_any_fail_5, + [{repeat_until_any_fail,2},sequence]},ok}}, + [{?eh,tc_done,{repeat_1_SUITE,{end_per_group,gr_ok_1,[]},ok}}], + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,gr_ok_then_fail_init,[]}, + {failed,{error,failing_this_time}}}}, + {?eh,test_stats,{24,1,{0,5}}}, + {?eh,tc_auto_skip,{repeat_1_SUITE,end_per_group, + {failed,{repeat_1_SUITE,init_per_group, + {'EXIT',failing_this_time}}}}}], + {?eh,tc_auto_skip,{repeat_1_SUITE,tc_ok_1, + {group_result,gr_ok_then_fail_init,failed}}}, + {?eh,test_stats,{24,1,{0,6}}}, + {?eh,tc_auto_skip,{repeat_1_SUITE,tc_ok_1, + {group_result,gr_ok_then_fail_init,failed}}}, + {?eh,test_stats,{24,1,{0,7}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_seq_until_any_fail_5, + [{repeat_until_any_fail,2},sequence]},ok}}], + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_seq_until_any_fail,[]},ok}}], + + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]}]; + +%%! Note that when testing shuffled groups, ct_test_support expects +%%! both the start and done event for cases and init/end_per_group +test_events(repeat_shuffled_seq_until_any_fail) -> + [{?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,unknown}}, + + [{?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_shuffled_seq_until_any_fail,[]}, + ok}}, + + {shuffle, + [{?eh,tc_start,{repeat_1_SUITE, + {init_per_group,repeat_shuffled_seq_until_any_fail_1, + [{shuffle,'_'},sequence, + {repeat_until_any_fail,2}]}}}, + {?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_shuffled_seq_until_any_fail_1, + [{shuffle,'_'},sequence, + {repeat_until_any_fail,2}]},ok}}, + {?eh,test_stats,{2,0,{0,0}}}, + {?eh,tc_start,{repeat_1_SUITE, + {end_per_group,repeat_shuffled_seq_until_any_fail_1, + [sequence,shuffle,{repeat_until_any_fail,2}]}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_shuffled_seq_until_any_fail_1, + [sequence,shuffle,{repeat_until_any_fail,2}]},ok}}]}, + {shuffle, + [{?eh,tc_start,{repeat_1_SUITE, + {init_per_group,repeat_shuffled_seq_until_any_fail_1, + [{shuffle,'_'},sequence]}}}, + {?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_shuffled_seq_until_any_fail_1, + [{shuffle,'_'},sequence]},ok}}, + {?eh,test_stats,{4,0,{0,0}}}, + {?eh,tc_start,{repeat_1_SUITE, + {end_per_group,repeat_shuffled_seq_until_any_fail_1, + [{shuffle,repeated},sequence]}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_shuffled_seq_until_any_fail_1, + [{shuffle,repeated},sequence]},ok}}]}, + + {shuffle, + [{?eh,tc_start,{repeat_1_SUITE, + {init_per_group,repeat_shuffled_seq_until_any_fail_2, + [{shuffle,{1,2,3}},{repeat_until_any_fail,2},sequence]}}}, + {?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_shuffled_seq_until_any_fail_2, + [{shuffle,{1,2,3}},{repeat_until_any_fail,2},sequence]}, + ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_2}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_2,ok}}, + [{?eh,tc_start,{repeat_1_SUITE,{end_per_group,gr_ok_1,[]}}}, + {?eh,tc_done,{repeat_1_SUITE,{end_per_group,gr_ok_1,[]},ok}}], + {?eh,test_stats,{7,0,{0,0}}}, + {?eh,tc_start,{repeat_1_SUITE, + {end_per_group,repeat_shuffled_seq_until_any_fail_2, + [{repeat_until_any_fail,2},{shuffle,{1,2,3}},sequence]}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_shuffled_seq_until_any_fail_2, + [{repeat_until_any_fail,2},{shuffle,{1,2,3}},sequence]}, + ok}}]}, + {shuffle, + [{?eh,tc_start,{repeat_1_SUITE, + {init_per_group,repeat_shuffled_seq_until_any_fail_2, + [{shuffle,'_'},sequence]}}}, + {?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_shuffled_seq_until_any_fail_2, + [{shuffle,'_'},sequence]},ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_2}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_2,ok}}, + [{?eh,tc_start,{repeat_1_SUITE,{end_per_group,gr_ok_1,[]}}}, + {?eh,tc_done,{repeat_1_SUITE,{end_per_group,gr_ok_1,[]},ok}}], + {?eh,tc_start,{repeat_1_SUITE, + {end_per_group,repeat_shuffled_seq_until_any_fail_2, + [{shuffle,repeated},sequence]}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_shuffled_seq_until_any_fail_2, + [{shuffle,repeated},sequence]},ok}}]}, + + {shuffle, + [{?eh,tc_start,{repeat_1_SUITE, + {init_per_group,repeat_shuffled_seq_until_any_fail_3, + [{shuffle,'_'},sequence, + {repeat_until_any_fail,3}]}}}, + {?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_shuffled_seq_until_any_fail_3, + [{shuffle,'_'},sequence, + {repeat_until_any_fail,3}]},ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_then_fail_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_then_fail_1,ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_2}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_2,ok}}, + [{?eh,tc_start,{repeat_1_SUITE,{end_per_group,gr_ok_1,[]}}}, + {?eh,tc_done,{repeat_1_SUITE,{end_per_group,gr_ok_1,[]},ok}}], + {?eh,test_stats,{14,0,{0,0}}}, + {?eh,tc_start,{repeat_1_SUITE, + {end_per_group,repeat_shuffled_seq_until_any_fail_3, + [shuffle,sequence,{repeat_until_any_fail,3}]}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_shuffled_seq_until_any_fail_3, + [shuffle,sequence,{repeat_until_any_fail,3}]},ok}}]}, + {shuffle, + [{?eh,tc_start,{repeat_1_SUITE, + {init_per_group,repeat_shuffled_seq_until_any_fail_3, + [{shuffle,'_'},{repeat_until_any_fail,2},sequence]}}}, + {?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_shuffled_seq_until_any_fail_3, + [{shuffle,'_'},{repeat_until_any_fail,2},sequence]}, + ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_then_fail_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_then_fail_1, + {failed,{error,failing_this_time}}}}, + {?eh,tc_start,{repeat_1_SUITE, + {end_per_group,repeat_shuffled_seq_until_any_fail_3, + [{shuffle,repeated},{repeat_until_any_fail,2},sequence]}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_shuffled_seq_until_any_fail_3, + [{shuffle,repeated},{repeat_until_any_fail,2},sequence]}, + ok}}]}, + + {shuffle, + [{?eh,tc_start,{repeat_1_SUITE, + {init_per_group,repeat_shuffled_seq_until_any_fail_4, + [{shuffle,{1,2,3}},{repeat_until_any_fail,3},sequence]}}}, + {?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_shuffled_seq_until_any_fail_4, + [{shuffle,{1,2,3}},{repeat_until_any_fail,3},sequence]}, + ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + [{?eh,tc_start,{repeat_1_SUITE,{end_per_group,gr_ok_1,[]}}}, + {?eh,tc_done,{repeat_1_SUITE,{end_per_group,gr_ok_1,[]},ok}}], + [{?eh,tc_start,{repeat_1_SUITE,{end_per_group, + gr_ok_then_fail_result,[]}}}, + {?eh,tc_done,{repeat_1_SUITE,{end_per_group, + gr_ok_then_fail_result,[]},ok}}], + {?eh,tc_start,{repeat_1_SUITE, + {end_per_group,repeat_shuffled_seq_until_any_fail_4, + [{repeat_until_any_fail,3},sequence,{shuffle,{1,2,3}}]}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_shuffled_seq_until_any_fail_4, + [{repeat_until_any_fail,3},sequence,{shuffle,{1,2,3}}]}, + ok}}]}, + {shuffle, + [{?eh,tc_start,{repeat_1_SUITE, + {init_per_group,repeat_shuffled_seq_until_any_fail_4, + [{shuffle,'_'},{repeat_until_any_fail,2},sequence]}}}, + {?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_shuffled_seq_until_any_fail_4, + [{shuffle,'_'},{repeat_until_any_fail,2},sequence]}, + ok}}, + [{?eh,tc_start,{repeat_1_SUITE, + {end_per_group,gr_ok_then_fail_result,[]}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,gr_ok_then_fail_result,[]}, + {return_group_result,failed}}}], + {?eh,tc_start,{repeat_1_SUITE, + {end_per_group,repeat_shuffled_seq_until_any_fail_4, + [{shuffle,repeated},{repeat_until_any_fail,2},sequence]}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_shuffled_seq_until_any_fail_4, + [{shuffle,repeated},{repeat_until_any_fail,2},sequence]}, + ok}}]}, + + {shuffle, + [{?eh,tc_start,{repeat_1_SUITE, + {init_per_group,repeat_shuffled_seq_until_any_fail_5, + [{shuffle,{1,2,3}},{repeat_until_any_fail,3},sequence]}}}, + {?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_shuffled_seq_until_any_fail_5, + [{shuffle,{1,2,3}},{repeat_until_any_fail,3},sequence]}, + ok}}, + {?eh,tc_start,{repeat_1_SUITE,tc_ok_1}}, + {?eh,tc_done,{repeat_1_SUITE,tc_ok_1,ok}}, + [{?eh,tc_start,{repeat_1_SUITE,{end_per_group,gr_ok_1,[]}}}, + {?eh,tc_done,{repeat_1_SUITE,{end_per_group,gr_ok_1,[]},ok}}], + [{?eh,tc_start,{repeat_1_SUITE,{end_per_group,gr_ok_2,[]}}}, + {?eh,tc_done,{repeat_1_SUITE,{end_per_group,gr_ok_2,[]},ok}}], + [{?eh,tc_start,{repeat_1_SUITE,{end_per_group, + gr_ok_then_fail_init,[]}}}, + {?eh,tc_done,{repeat_1_SUITE,{end_per_group, + gr_ok_then_fail_init,[]},ok}}], + {?eh,tc_start,{repeat_1_SUITE, + {end_per_group,repeat_shuffled_seq_until_any_fail_5, + [{repeat_until_any_fail,3},sequence,{shuffle,{1,2,3}}]}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_shuffled_seq_until_any_fail_5, + [{repeat_until_any_fail,3},sequence,{shuffle,{1,2,3}}]}, + ok}}]}, + {shuffle, + [{?eh,tc_start,{repeat_1_SUITE, + {init_per_group,repeat_shuffled_seq_until_any_fail_5, + [{shuffle,'_'},{repeat_until_any_fail,2}, + sequence]}}}, + {?eh,tc_done,{repeat_1_SUITE, + {init_per_group,repeat_shuffled_seq_until_any_fail_5, + [{shuffle,'_'},{repeat_until_any_fail,2}, + sequence]},ok}}, + [{?eh,tc_auto_skip,{repeat_1_SUITE,end_per_group, + {failed,{repeat_1_SUITE,init_per_group, + {'EXIT',failing_this_time}}}}}], + {?eh,tc_start,{repeat_1_SUITE, + {end_per_group,repeat_shuffled_seq_until_any_fail_5, + [{shuffle,repeated},{repeat_until_any_fail,2},sequence]}}}, + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_shuffled_seq_until_any_fail_5, + [{shuffle,repeated},{repeat_until_any_fail,2},sequence]}, + ok}}]}, + + {?eh,tc_done,{repeat_1_SUITE, + {end_per_group,repeat_shuffled_seq_until_any_fail,[]}, + ok}}], + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]}]. diff --git a/lib/common_test/test/ct_repeat_1_SUITE_data/repeat_1_SUITE.erl b/lib/common_test/test/ct_repeat_1_SUITE_data/repeat_1_SUITE.erl new file mode 100644 index 0000000000..fb8d31edd4 --- /dev/null +++ b/lib/common_test/test/ct_repeat_1_SUITE_data/repeat_1_SUITE.erl @@ -0,0 +1,373 @@ +%%%------------------------------------------------------------------- +%%% @author Peter Andersson <[email protected]> +%%% @copyright (C) 2010, Peter Andersson +%%% @doc +%%% +%%% @end +%%% Created : 11 Aug 2010 by Peter Andersson <[email protected]> +%%%------------------------------------------------------------------- +-module(repeat_1_SUITE). + +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +%%-------------------------------------------------------------------- +%% @spec suite() -> Info +%% Info = [tuple()] +%% @end +%%-------------------------------------------------------------------- +suite() -> + [{timetrap,{seconds,30}}]. + +%%-------------------------------------------------------------------- +%% @spec init_per_suite(Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% Config0 = Config1 = [tuple()] +%% Reason = term() +%% @end +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + spawn(fun() -> db() end), + Config. +%%-------------------------------------------------------------------- +%% @spec end_per_suite(Config0) -> void() | {save_config,Config1} +%% Config0 = Config1 = [tuple()] +%% @end +%%-------------------------------------------------------------------- +end_per_suite(_Config) -> + db(stop, ok), + ok. + +db() -> + register(?MODULE, self()), + db_loop([]). + +db_loop(Dict) -> + receive + {insert,From,Key,Val} -> + From ! {?MODULE,ok}, + db_loop([{Key,Val} | proplists:delete(Key, Dict)]); + {lookup,From,Key} -> + From ! {?MODULE,proplists:get_value(Key, Dict)}, + db_loop(Dict); + {delete,From,Key} -> + From ! {?MODULE,ok}, + db_loop(proplists:delete(Key, Dict)); + {stop,From,_} -> + From ! {?MODULE,ok} + end. + + db(Op, Key, Val) -> + ?MODULE ! {Op,self(),Key,Val}, + receive {?MODULE,Result} -> Result end. + + db(Op, Key) -> + ?MODULE ! {Op,self(),Key}, + receive {?MODULE,Result} -> Result end. + +%%-------------------------------------------------------------------- +%% @spec init_per_group(GroupName, Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% GroupName = atom() +%% Config0 = Config1 = [tuple()] +%% Reason = term() +%% @end +%%-------------------------------------------------------------------- +init_per_group(G, Config) when G == gr_ok_1 ; G == gr_ok_2 ; + G == gr_fail_result; + G == gr_ok_then_fail_result -> + ct:comment(G), + Config; + +init_per_group(G, _Config) when G == gr_fail_init -> + ct:comment(G), + exit(fails_on_purpose); + +init_per_group(G, Config) when G == gr_ok_then_fail_init -> + ct:comment(G), + do_2nd_time(G, + fun() -> exit(failing_this_time) end, + fun() -> Config end); + +init_per_group(G, Config) when G == gr_fail_init_then_ok -> + ct:comment(G), + do_2nd_time(G, + fun() -> Config end, + fun() -> exit(failing_this_time) end); + +init_per_group(G, Config) -> + ct:comment(G), + Config. + +%%-------------------------------------------------------------------- +%% @spec end_per_group(GroupName, Config0) -> +%% void() | {save_config,Config1} +%% GroupName = atom() +%% Config0 = Config1 = [tuple()] +%% @end +%%-------------------------------------------------------------------- +end_per_group(G, _Config) when G == gr_fail_result -> + ct:comment(G), + {return_group_result,failed}; + +end_per_group(G, _Config) when G == gr_ok_then_fail_result -> + ct:comment(G), + do_2nd_time(G, + fun() -> {return_group_result,failed} end, + fun() -> ok end); + +end_per_group(G, _Config) when G == gr_fail_result_then_ok -> + ct:comment(G), + do_2nd_time(G, + fun() -> ok end, + fun() -> {return_group_result,failed} end); + +end_per_group(G, _Config) -> + ct:comment(G), + ok. + +%%-------------------------------------------------------------------- +%% @spec init_per_testcase(TestCase, Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% TestCase = atom() +%% Config0 = Config1 = [tuple()] +%% Reason = term() +%% @end +%%-------------------------------------------------------------------- +init_per_testcase(_TestCase, Config) -> + Config. + +%%-------------------------------------------------------------------- +%% @spec end_per_testcase(TestCase, Config0) -> +%% void() | {save_config,Config1} | {fail,Reason} +%% TestCase = atom() +%% Config0 = Config1 = [tuple()] +%% Reason = term() +%% @end +%%-------------------------------------------------------------------- +end_per_testcase(_TestCase, _Config) -> + ok. + +%%-------------------------------------------------------------------- +%% @spec groups() -> [Group] +%% Group = {GroupName,Properties,GroupsAndTestCases} +%% GroupName = atom() +%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}] +%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase] +%% TestCase = atom() +%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}} +%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail | +%% repeat_until_any_ok | repeat_until_any_fail +%% N = integer() | forever +%% @end +%%-------------------------------------------------------------------- +groups() -> + [ + %%--------------------------------------------------------------- + {repeat_cs, [], [{group,repeat_cs_0}, + {group,repeat_cs_1}, + {group,repeat_cs_2}]}, + {repeat_cs_0, [{repeat,0}], [tc_ok_1,tc_ok_2]}, + {repeat_cs_1, [{repeat,1}], [tc_ok_1,tc_ok_2]}, + {repeat_cs_2, [{repeat,2}], [tc_ok_1,tc_ok_2]}, + + {repeat_cs_and_grs, [{repeat,2}], [{group,gr_ok_1},tc_fail_1, + {group,gr_fail_result},tc_ok_1, + {group,gr_fail_init},tc_ok_2]}, + + %%--------------------------------------------------------------- + {repeat_seq, [], [{group,repeat_seq_1}, + {group,repeat_seq_2}, + {group,repeat_seq_3}, + {group,repeat_seq_4}]}, + {repeat_seq_1, [sequence,{repeat,2}], [tc_ok_1,tc_fail_1,tc_ok_2]}, + {repeat_seq_2, [sequence,{repeat,2}], [tc_ok_1,{group,gr_fail_result},tc_ok_2]}, + {repeat_seq_3, [sequence,{repeat,2}], [tc_ok_1,{group,gr_fail_init},tc_ok_2]}, + {repeat_seq_4, [sequence,{repeat,2}], [tc_fail_1,{group,gr_ok_1},tc_ok_1]}, + + %%--------------------------------------------------------------- + {repeat_cs_until_any_ok, [], [{group,repeat_cs_until_any_ok_1}, + {group,repeat_cs_until_any_ok_2}]}, + {repeat_cs_until_any_ok_1, [{repeat_until_any_ok,3}], [tc_fail_1, + tc_fail_2, + tc_fail_then_ok_1]}, + {repeat_cs_until_any_ok_2, [{repeat_until_any_ok,3}], [tc_ok_1,tc_fail_1]}, + + %%--------------------------------------------------------------- + {repeat_gr_until_any_ok, [], [{group,repeat_gr_until_any_ok_1}, + {group,repeat_gr_until_any_ok_2}]}, + {repeat_gr_until_any_ok_1, [{repeat_until_any_ok,3}], + [{group,gr_fail_result}, tc_fail_1, {group,gr_fail_init}, tc_fail_2, + {group,gr_fail_result_then_ok}]}, + {repeat_gr_until_any_ok_2, [{repeat_until_any_ok,3}], + [{group,gr_fail_result}, tc_fail_1, tc_fail_then_ok_1, + {group,gr_fail_init}]}, + + %%--------------------------------------------------------------- + {repeat_cs_until_any_fail, [], [{group,repeat_cs_until_any_fail_1}, + {group,repeat_cs_until_any_fail_2}]}, + {repeat_cs_until_any_fail_1, [{repeat_until_any_fail,3}], [tc_ok_1, + tc_ok_2, + tc_ok_then_fail_1]}, + {repeat_cs_until_any_fail_2, [{repeat_until_any_fail,3}], [tc_fail_1,tc_fail_2]}, + + %%--------------------------------------------------------------- + {repeat_gr_until_any_fail, [], [{group,repeat_gr_until_any_fail_1}, + {group,repeat_gr_until_any_fail_2}, + {group,repeat_gr_until_any_fail_3}]}, + {repeat_gr_until_any_fail_1, [{repeat_until_any_fail,3}], + [{group,gr_ok_1}, tc_ok_1, {group,gr_ok_then_fail_result}, tc_ok_2]}, + {repeat_gr_until_any_fail_2, [{repeat_until_any_fail,3}], + [{group,gr_ok_1}, tc_ok_1, {group,gr_ok_then_fail_init}, tc_ok_2]}, + {repeat_gr_until_any_fail_3, [{repeat_until_any_fail,3}], [tc_ok_then_fail_1, + {group,gr_ok_1}, + tc_ok_1]}, + + %%--------------------------------------------------------------- + {repeat_cs_until_all_ok, [], [{group,repeat_cs_until_all_ok_1}, + {group,repeat_cs_until_all_ok_2}]}, + {repeat_cs_until_all_ok_1, [{repeat_until_all_ok,3}], [tc_fail_then_ok_1, + tc_ok_1, + tc_fail_then_ok_2]}, + {repeat_cs_until_all_ok_2, [{repeat_until_all_ok,3}], [tc_ok_1,tc_ok_2]}, + + %%--------------------------------------------------------------- + {repeat_gr_until_all_ok, [], [{group,repeat_gr_until_all_ok_1}, + {group,repeat_gr_until_all_ok_2}, + {group,repeat_gr_until_all_ok_3}]}, + {repeat_gr_until_all_ok_1, [{repeat_until_all_ok,3}], + [tc_ok_1, {group,gr_ok_1}, tc_fail_then_ok_1, {group,gr_fail_result_then_ok}]}, + {repeat_gr_until_all_ok_2, [{repeat_until_all_ok,3}], + [{group,gr_fail_init_then_ok}, tc_ok_1]}, + {repeat_gr_until_all_ok_3, [{repeat_until_all_ok,3}], + [{group,gr_ok_1}, tc_fail_then_ok_1]}, + + %%--------------------------------------------------------------- + {repeat_cs_until_all_fail, [], [{group,repeat_cs_until_all_fail_1}, + {group,repeat_cs_until_all_fail_2}]}, + {repeat_cs_until_all_fail_1, [{repeat_until_all_fail,3}], [tc_ok_then_fail_1, + tc_fail_1, + tc_ok_then_fail_2]}, + {repeat_cs_until_all_fail_2, [{repeat_until_all_fail,3}], [tc_fail_1]}, + + %%--------------------------------------------------------------- + {repeat_gr_until_all_fail, [], [{group,repeat_gr_until_all_fail_1}, + {group,repeat_gr_until_all_fail_2}, + {group,repeat_gr_until_all_fail_3}]}, + {repeat_gr_until_all_fail_1, [{repeat_until_all_fail,3}], + [tc_fail_1, {group,gr_fail_init}, tc_ok_then_fail_1, {group,gr_ok_then_fail_result}]}, + {repeat_gr_until_all_fail_2, [{repeat_until_all_fail,3}], + [{group,gr_ok_then_fail_init}, tc_fail_1]}, + {repeat_gr_until_all_fail_3, [{repeat_until_all_fail,3}], + [{group,gr_fail_result}, tc_ok_then_fail_1]}, + + %%--------------------------------------------------------------- + {repeat_seq_until_any_fail, [], [{group,repeat_seq_until_any_fail_1}, + {group,repeat_seq_until_any_fail_2}, + {group,repeat_seq_until_any_fail_3}, + {group,repeat_seq_until_any_fail_4}, + {group,repeat_seq_until_any_fail_5}]}, + {repeat_seq_until_any_fail_1, [sequence,{repeat_until_any_fail,2}], + [tc_ok_1, tc_ok_2]}, + {repeat_seq_until_any_fail_2, [{repeat_until_any_fail,2},sequence], + [tc_ok_1, {group,gr_ok_1}, tc_ok_2]}, + {repeat_seq_until_any_fail_3, [sequence,{repeat_until_any_fail,3}], + [tc_ok_1, tc_ok_then_fail_1, tc_ok_2, {group,gr_ok_1}]}, + {repeat_seq_until_any_fail_4, [{repeat_until_any_fail,3},sequence], + [{group,gr_ok_then_fail_result}, {group,gr_ok_1}, tc_ok_1]}, + {repeat_seq_until_any_fail_5, [{repeat_until_any_fail,3},sequence], + [{group,gr_ok_1}, {group,gr_ok_then_fail_init}, {group,gr_ok_2}, tc_ok_1]}, + + %%--------------------------------------------------------------- + {repeat_shuffled_seq_until_any_fail, [], [{group,repeat_shuffled_seq_until_any_fail_1}, + {group,repeat_shuffled_seq_until_any_fail_2}, + {group,repeat_shuffled_seq_until_any_fail_3}, + {group,repeat_shuffled_seq_until_any_fail_4}, + {group,repeat_shuffled_seq_until_any_fail_5}]}, + {repeat_shuffled_seq_until_any_fail_1, [sequence,shuffle,{repeat_until_any_fail,2}], + [tc_ok_1, tc_ok_2]}, + {repeat_shuffled_seq_until_any_fail_2, [{repeat_until_any_fail,2},{shuffle,{1,2,3}},sequence], + [tc_ok_1, {group,gr_ok_1}, tc_ok_2]}, + {repeat_shuffled_seq_until_any_fail_3, [shuffle,sequence,{repeat_until_any_fail,3}], + [tc_ok_1, tc_ok_then_fail_1, tc_ok_2, {group,gr_ok_1}]}, + {repeat_shuffled_seq_until_any_fail_4, [{repeat_until_any_fail,3},sequence,{shuffle,{1,2,3}}], + [{group,gr_ok_then_fail_result}, {group,gr_ok_1}, tc_ok_1]}, + {repeat_shuffled_seq_until_any_fail_5, [{repeat_until_any_fail,3},sequence,{shuffle,{1,2,3}}], + [{group,gr_ok_1}, {group,gr_ok_then_fail_init}, {group,gr_ok_2}, tc_ok_1]}, + + %%--------------------------------------------------------------- + {gr_ok_1, [], [tc_ok_1]}, + + {gr_ok_2, [], [tc_ok_1]}, + + {gr_fail_init, [], [tc_ok_1]}, + + {gr_fail_result, [], [tc_ok_1]}, + + {gr_ok_then_fail_init, [], [tc_ok_1]}, + + {gr_ok_then_fail_result, [], [tc_ok_1]}, + + {gr_fail_result_then_ok, [], [tc_ok_1]}, + + {gr_fail_init_then_ok, [], [tc_ok_1]} + ]. + +%%-------------------------------------------------------------------- +%% @spec all() -> GroupsAndTestCases | {skip,Reason} +%% GroupsAndTestCases = [{group,GroupName} | TestCase] +%% GroupName = atom() +%% TestCase = atom() +%% Reason = term() +%% @end +%%-------------------------------------------------------------------- +all() -> + []. + +tc_ok_1(_) -> + ok. + +tc_ok_2(_) -> + ok. + +tc_fail_1(_) -> + x=2. + +tc_fail_2(_) -> + exit(exit_on_purpose). + +tc_ok_then_fail_1(_) -> + do_2nd_time(tc_ok_then_fail_1, + fun() -> exit(failing_this_time) end, + fun() -> ok end), + ok. + +tc_ok_then_fail_2(_) -> + do_2nd_time(tc_ok_then_fail_2, + fun() -> exit(failing_this_time) end, + fun() -> ok end), + ok. + +tc_fail_then_ok_1(_) -> + do_2nd_time(tc_fail_then_ok_1, + fun() -> ok end, + fun() -> exit(failing_this_time) end), + ok. + +tc_fail_then_ok_2(_) -> + do_2nd_time(tc_fail_then_ok_2, + fun() -> ok end, + fun() -> exit(failing_this_time) end), + ok. + +do_2nd_time(Case, True, False) -> + case db(lookup, Case) of + undefined -> + db(insert, Case, 1), + False(); + 1 -> + ct:log("This is the second call...", []), + db(delete, Case), + True() + end. diff --git a/lib/common_test/test/ct_sequence_1_SUITE.erl b/lib/common_test/test/ct_sequence_1_SUITE.erl new file mode 100644 index 0000000000..0cf40f106a --- /dev/null +++ b/lib/common_test/test/ct_sequence_1_SUITE.erl @@ -0,0 +1,300 @@ +%% +%% %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% +%% + +%%%------------------------------------------------------------------- +%%% File: ct_sequence_1_SUITE +%%% +%%% Description: +%%% Test sequences +%%% +%%% The suites used for the test are located in the data directory. +%%%------------------------------------------------------------------- +-module(ct_sequence_1_SUITE). + +-compile(export_all). + +-include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct_event.hrl"). + +-define(eh, ct_test_support_eh). + +%%-------------------------------------------------------------------- +%% TEST SERVER CALLBACK FUNCTIONS +%%-------------------------------------------------------------------- + +%%-------------------------------------------------------------------- +%% Description: Since Common Test starts another Test Server +%% instance, the tests need to be performed on a separate node (or +%% there will be clashes with logging processes etc). +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + Config1 = ct_test_support:init_per_suite(Config), + Config1. + +end_per_suite(Config) -> + ct_test_support:end_per_suite(Config). + +init_per_testcase(TestCase, Config) -> + ct_test_support:init_per_testcase(TestCase, Config). + +end_per_testcase(TestCase, Config) -> + ct_test_support:end_per_testcase(TestCase, Config). + +all(suite) -> + [subgroup_return_fail, + subgroup_init_fail, + subgroup_after_failed_case, + case_after_subgroup_return_fail, + case_after_subgroup_fail_init]. + +%%-------------------------------------------------------------------- +%% TEST CASES +%%-------------------------------------------------------------------- + +%%%----------------------------------------------------------------- +%%% + +subgroup_return_fail(Config) when is_list(Config) -> + execute(subgroup_return_fail, + "subgroups_1_SUITE", subgroup_return_fail, + Config). + +%%%----------------------------------------------------------------- +%%% + +subgroup_init_fail(Config) when is_list(Config) -> + execute(subgroup_init_fail, + "subgroups_1_SUITE", subgroup_init_fail, + Config). + +%%%----------------------------------------------------------------- +%%% + +subgroup_after_failed_case(Config) when is_list(Config) -> + execute(subgroup_after_failed_case, + "subgroups_1_SUITE", subgroup_after_failed_case, + Config). + +%%%----------------------------------------------------------------- +%%% + +case_after_subgroup_return_fail(Config) when is_list(Config) -> + execute(case_after_subgroup_return_fail, + "subgroups_1_SUITE", case_after_subgroup_return_fail, + Config). + +%%%----------------------------------------------------------------- +%%% + +case_after_subgroup_fail_init(Config) when is_list(Config) -> + execute(case_after_subgroup_fail_init, + "subgroups_1_SUITE", case_after_subgroup_fail_init, + Config). + +%%%----------------------------------------------------------------- +%%% HELP FUNCTIONS +%%%----------------------------------------------------------------- + +execute(TestCase, SuiteName, Group, Config) -> + DataDir = ?config(data_dir, Config), + Suite = filename:join(DataDir, SuiteName), + + {Opts,ERPid} = setup([{suite,Suite},{group,Group},{label,TestCase}], Config), + ok = ct_test_support:run(Opts, Config), + Events = ct_test_support:get_events(ERPid, Config), + + ct_test_support:log_events(TestCase, + reformat(Events, ?eh), + ?config(priv_dir, Config)), + + TestEvents = events_to_check(TestCase), + ok = ct_test_support:verify_events(TestEvents, Events, Config). + +setup(Test, Config) -> + Opts0 = ct_test_support:get_opts(Config), + Level = ?config(trace_level, Config), + EvHArgs = [{cbm,ct_test_support},{trace_level,Level}], + Opts = Opts0 ++ [{event_handler,{?eh,EvHArgs}} | Test], + ERPid = ct_test_support:start_event_receiver(Config), + {Opts,ERPid}. + +reformat(Events, EH) -> + ct_test_support:reformat(Events, EH). +%reformat(Events, _EH) -> +% Events. + +%%%----------------------------------------------------------------- +%%% TEST EVENTS +%%%----------------------------------------------------------------- +events_to_check(Test) -> + %% 2 tests (ct:run_test + script_start) is default + events_to_check(Test, 2). + +events_to_check(_, 0) -> + []; +events_to_check(Test, N) -> + test_events(Test) ++ events_to_check(Test, N-1). + +test_events(subgroup_return_fail) -> + [ + {?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,2}}, + [{?eh,tc_start, + {subgroups_1_SUITE,{init_per_group,subgroup_return_fail,[sequence]}}}, + {?eh,tc_done, + {subgroups_1_SUITE,{init_per_group,subgroup_return_fail,[sequence]},ok}}, + [{?eh,tc_start, + {subgroups_1_SUITE,{init_per_group,return_fail,[]}}}, + {?eh,tc_done, + {subgroups_1_SUITE,{init_per_group,return_fail,[]},ok}}, + {?eh,tc_start,{subgroups_1_SUITE,failing_tc}}, + {?eh,tc_done, + {subgroups_1_SUITE,failing_tc,{failed,{error,{{badmatch,3},'_'}}}}}, + {?eh,test_stats,{0,1,{0,0}}}, + {?eh,tc_start, + {subgroups_1_SUITE,{end_per_group,return_fail,[]}}}, + {?eh,tc_done,{subgroups_1_SUITE,{end_per_group,return_fail,[]}, + {return_group_result,failed}}}], + {?eh,tc_auto_skip, + {subgroups_1_SUITE,ok_tc,{group_result,return_fail,failed}}}, + {?eh,test_stats,{0,1,{0,1}}}, + {?eh,tc_start, + {subgroups_1_SUITE,{end_per_group,subgroup_return_fail,[sequence]}}}, + {?eh,tc_done, + {subgroups_1_SUITE,{end_per_group,subgroup_return_fail,[sequence]}, + {return_group_result,failed}}}], + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]} + ]; + +test_events(subgroup_init_fail) -> + [ + {?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,2}}, + [{?eh,tc_start, + {subgroups_1_SUITE,{init_per_group,subgroup_init_fail,[sequence]}}}, + {?eh,tc_done, + {subgroups_1_SUITE,{init_per_group,subgroup_init_fail,[sequence]},ok}}, + [{?eh,tc_start,{subgroups_1_SUITE,{init_per_group,fail_init,[]}}}, + {?eh,tc_done,{subgroups_1_SUITE,{init_per_group,fail_init,[]}, + {failed,{error,init_per_group_fails_on_purpose}}}}, + {?eh,tc_auto_skip,{subgroups_1_SUITE,ok_tc, + {failed,{subgroups_1_SUITE,init_per_group, + {'EXIT',init_per_group_fails_on_purpose}}}}}, + {?eh,test_stats,{0,0,{0,1}}}, + {?eh,tc_auto_skip,{subgroups_1_SUITE,end_per_group, + {failed,{subgroups_1_SUITE,init_per_group, + {'EXIT',init_per_group_fails_on_purpose}}}}}], + {?eh,tc_auto_skip,{subgroups_1_SUITE,ok_tc,{group_result,fail_init,failed}}}, + {?eh,test_stats,{0,0,{0,2}}}, + {?eh,tc_start,{subgroups_1_SUITE,{end_per_group,subgroup_init_fail,[sequence]}}}, + {?eh,tc_done,{subgroups_1_SUITE, + {end_per_group,subgroup_init_fail,[sequence]}, + {return_group_result,failed}}}], + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]} + ]; + +test_events(subgroup_after_failed_case) -> + [ + {?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,2}}, + [{?eh,tc_start,{subgroups_1_SUITE, + {init_per_group,subgroup_after_failed_case,[sequence]}}}, + {?eh,tc_done,{subgroups_1_SUITE, + {init_per_group,subgroup_after_failed_case,[sequence]},ok}}, + {?eh,tc_start,{subgroups_1_SUITE,failing_tc}}, + {?eh,tc_done,{subgroups_1_SUITE,failing_tc,{failed,{error,{{badmatch,3},'_'}}}}}, + {?eh,test_stats,{0,1,{0,0}}}, + {?eh,tc_auto_skip,{subgroups_1_SUITE,ok_tc,{failed,{subgroups_1_SUITE,failing_tc}}}}, + {?eh,test_stats,{0,1,{0,1}}}, + {?eh,tc_start,{subgroups_1_SUITE, + {end_per_group,subgroup_after_failed_case,[sequence]}}}, + {?eh,tc_done,{subgroups_1_SUITE, + {end_per_group,subgroup_after_failed_case,[sequence]}, + {return_group_result,failed}}}], + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]} +]; + +test_events(case_after_subgroup_return_fail) -> + [ + {?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,2}}, + [{?eh,tc_start,{subgroups_1_SUITE, + {init_per_group,case_after_subgroup_return_fail,[sequence]}}}, + {?eh,tc_done,{subgroups_1_SUITE, + {init_per_group,case_after_subgroup_return_fail,[sequence]},ok}}, + [{?eh,tc_start,{subgroups_1_SUITE,{init_per_group,return_fail,[]}}}, + {?eh,tc_done,{subgroups_1_SUITE,{init_per_group,return_fail,[]},ok}}, + {?eh,tc_start,{subgroups_1_SUITE,failing_tc}}, + {?eh,tc_done,{subgroups_1_SUITE,failing_tc,{failed,{error,{{badmatch,3},'_'}}}}}, + {?eh,test_stats,{0,1,{0,0}}}, + {?eh,tc_start,{subgroups_1_SUITE,{end_per_group,return_fail,[]}}}, + {?eh,tc_done,{subgroups_1_SUITE,{end_per_group,return_fail,[]}, + {return_group_result,failed}}}], + {?eh,tc_auto_skip,{subgroups_1_SUITE,ok_tc,{group_result,return_fail,failed}}}, + {?eh,test_stats,{0,1,{0,1}}}, + {?eh,tc_start,{subgroups_1_SUITE, + {end_per_group,case_after_subgroup_return_fail,[sequence]}}}, + {?eh,tc_done,{subgroups_1_SUITE, + {end_per_group,case_after_subgroup_return_fail,[sequence]}, + {return_group_result,failed}}}], + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]} + ]; + +test_events(case_after_subgroup_fail_init) -> + [ + {?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,start_info,{1,1,2}}, + [{?eh,tc_start,{subgroups_1_SUITE, + {init_per_group,case_after_subgroup_fail_init,[sequence]}}}, + {?eh,tc_done,{subgroups_1_SUITE, + {init_per_group,case_after_subgroup_fail_init,[sequence]},ok}}, + [{?eh,tc_start,{subgroups_1_SUITE,{init_per_group,fail_init,[]}}}, + {?eh,tc_done,{subgroups_1_SUITE, + {init_per_group,fail_init,[]}, + {failed,{error,init_per_group_fails_on_purpose}}}}, + {?eh,tc_auto_skip,{subgroups_1_SUITE,ok_tc, + {failed, + {subgroups_1_SUITE,init_per_group, + {'EXIT',init_per_group_fails_on_purpose}}}}}, + {?eh,test_stats,{0,0,{0,1}}}, + {?eh,tc_auto_skip,{subgroups_1_SUITE,end_per_group, + {failed, + {subgroups_1_SUITE,init_per_group, + {'EXIT',init_per_group_fails_on_purpose}}}}}], + + {?eh,tc_auto_skip, + {subgroups_1_SUITE,ok_tc,{group_result,fail_init,failed}}}, + {?eh,test_stats,{0,0,{0,2}}}, + {?eh,tc_start,{subgroups_1_SUITE, + {end_per_group,case_after_subgroup_fail_init,[sequence]}}}, + {?eh,tc_done,{subgroups_1_SUITE, + {end_per_group,case_after_subgroup_fail_init,[sequence]}, + {return_group_result,failed}}}], + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,stop_logging,[]} + ]. diff --git a/lib/common_test/test/ct_sequence_1_SUITE_data/subgroups_1_SUITE.erl b/lib/common_test/test/ct_sequence_1_SUITE_data/subgroups_1_SUITE.erl new file mode 100644 index 0000000000..741b1165c1 --- /dev/null +++ b/lib/common_test/test/ct_sequence_1_SUITE_data/subgroups_1_SUITE.erl @@ -0,0 +1,108 @@ +%% +%% %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% +%% +-module(subgroups_1_SUITE). + +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +all() -> + [{group, subgroup_return_fail}, + {group, subgroup_init_fail}, + {group, subgroup_after_failed_case}, + {group, case_after_subgroup_return_fail}, + {group, case_after_subgroup_fail_init}]. + +groups() -> + [{return_fail, [], [failing_tc]}, + {fail_init, [], [ok_tc]}, + {ok_group, [], [ok_tc]}, + + {subgroup_return_fail, [sequence], [{group, return_fail}, {group, ok_group}]}, + + {subgroup_init_fail, [sequence], [{group, fail_init}, {group, ok_group}]}, + + {subgroup_after_failed_case, [sequence], [failing_tc, {group, ok_group}]}, + + {case_after_subgroup_return_fail, [sequence], [{group, return_fail}, ok_tc]}, + + {case_after_subgroup_fail_init, [sequence], [{group, fail_init}, ok_tc]} + ]. + +failed_subgroup(subgroup_return_fail) -> return_fail; +failed_subgroup(subgroup_init_fail) -> fail_init; +failed_subgroup(case_after_subgroup_return_fail) -> return_fail; +failed_subgroup(case_after_subgroup_fail_init) -> fail_init; +failed_subgroup(_) -> undefined. + +init_per_suite(Config) -> + Config. + +end_per_suite(_Config) -> + ok. + +init_per_group(fail_init, Config) -> + ct:comment(fail_init), + exit(init_per_group_fails_on_purpose); + +init_per_group(Group, Config) -> + ct:comment(Group), + [{Group,failed_subgroup(Group)} | Config]. + +end_per_group(subgroup_after_failed_case, Config) -> + ct:comment(subgroup_after_failed_case), + Status = ?config(tc_group_result, Config), + [{subgroups_1_SUITE,failing_tc}] = proplists:get_value(failed, Status), + {return_group_result,failed}; + +end_per_group(Group, Config) when Group == subgroup_return_fail; + Group == subgroup_init_fail; + Group == case_after_subgroup_return_fail; + Group == case_after_subgroup_fail_init -> + ct:comment(Group), + Status = ?config(tc_group_result, Config), + Failed = proplists:get_value(failed, Status), + true = lists:member({group_result,?config(Group,Config)}, Failed), + {return_group_result,failed}; + +end_per_group(return_fail, Config) -> + ct:comment(return_fail), + Status = ?config(tc_group_result, Config), + [{subgroups_1_SUITE,failing_tc}] = proplists:get_value(failed, Status), + {return_group_result,failed}; + +end_per_group(Group, _Config) -> + ct:comment(Group), + ok. + +init_per_testcase(_TestCase, Config) -> + Config. + +end_per_testcase(failing_tc, Config) -> + {failed,_} = proplists:get_value(tc_status, Config), + ok; + +end_per_testcase(_TestCase, _Config) -> + ok. + +failing_tc(_Config) -> + 2=3. + +ok_tc(_Config) -> + ok. diff --git a/lib/common_test/test/ct_skip_SUITE.erl b/lib/common_test/test/ct_skip_SUITE.erl index 9f428723f5..2e02061dec 100644 --- a/lib/common_test/test/ct_skip_SUITE.erl +++ b/lib/common_test/test/ct_skip_SUITE.erl @@ -89,14 +89,14 @@ auto_skip(Config) when is_list(Config) -> ], {Opts,ERPid} = setup({suite,Suites}, Config), - ok = ct_test_support:run(ct, run_test, [Opts], Config), + ok = ct_test_support:run(Opts, Config), Events = ct_test_support:get_events(ERPid, Config), ct_test_support:log_events(auto_skip, reformat(Events, ?eh), ?config(priv_dir, Config)), - TestEvents = test_events(auto_skip), + TestEvents = events_to_check(auto_skip), ok = ct_test_support:verify_events(TestEvents, Events, Config). @@ -112,14 +112,14 @@ user_skip(Config) when is_list(Config) -> Join(DataDir, "user_skip_5_SUITE")], {Opts,ERPid} = setup({suite,Suites}, Config), - ok = ct_test_support:run(ct, run_test, [Opts], Config), + ok = ct_test_support:run(Opts, Config), Events = ct_test_support:get_events(ERPid, Config), ct_test_support:log_events(user_skip, reformat(Events, ?eh), ?config(priv_dir, Config)), - TestEvents = test_events(user_skip), + TestEvents = events_to_check(user_skip), ok = ct_test_support:verify_events(TestEvents, Events, Config). %%%----------------------------------------------------------------- @@ -142,6 +142,15 @@ reformat(Events, EH) -> %%%----------------------------------------------------------------- %%% TEST EVENTS %%%----------------------------------------------------------------- +events_to_check(Test) -> + %% 2 tests (ct:run_test + script_start) is default + events_to_check(Test, 2). + +events_to_check(_, 0) -> + []; +events_to_check(Test, N) -> + test_events(Test) ++ events_to_check(Test, N-1). + test_events(auto_skip) -> [ {?eh,start_logging,{'DEF','RUNDIR'}}, diff --git a/lib/common_test/test/ct_smoke_test_SUITE.erl b/lib/common_test/test/ct_smoke_test_SUITE.erl index f1c695f614..05a2c20695 100644 --- a/lib/common_test/test/ct_smoke_test_SUITE.erl +++ b/lib/common_test/test/ct_smoke_test_SUITE.erl @@ -162,7 +162,7 @@ dir1(Config) when is_list(Config) -> ERPid = ct_test_support:start_event_receiver(Config), - ok = ct_test_support:run(ct, run_test, [Opts], Config), + ok = ct_test_support:run(Opts, Config), Events = ct_test_support:get_events(ERPid, Config), @@ -170,7 +170,7 @@ dir1(Config) when is_list(Config) -> ct_test_support:reformat(Events, ?eh), ?config(priv_dir, Config)), - TestEvents = test_events(dir1), + TestEvents = events_to_check(dir1), ok = ct_test_support:verify_events(TestEvents, Events, Config). %%%----------------------------------------------------------------- @@ -191,7 +191,7 @@ dir2(Config) when is_list(Config) -> ERPid = ct_test_support:start_event_receiver(Config), - ok = ct_test_support:run(ct, run_test, [Opts], Config), + ok = ct_test_support:run(Opts, Config), Events = ct_test_support:get_events(ERPid, Config), @@ -199,7 +199,7 @@ dir2(Config) when is_list(Config) -> ct_test_support:reformat(Events, ?eh), ?config(priv_dir, Config)), - TestEvents = test_events(dir2), + TestEvents = events_to_check(dir2), ok = ct_test_support:verify_events(TestEvents, Events, Config). %%%----------------------------------------------------------------- @@ -221,7 +221,7 @@ dir1_2(Config) when is_list(Config) -> ERPid = ct_test_support:start_event_receiver(Config), - ok = ct_test_support:run(ct, run_test, [Opts], Config), + ok = ct_test_support:run(Opts, Config), Events = ct_test_support:get_events(ERPid, Config), @@ -229,7 +229,7 @@ dir1_2(Config) when is_list(Config) -> ct_test_support:reformat(Events, ?eh), ?config(priv_dir, Config)), - TestEvents = test_events(dir1_2), + TestEvents = events_to_check(dir1_2), ok = ct_test_support:verify_events(TestEvents, Events, Config). %%%----------------------------------------------------------------- @@ -251,7 +251,7 @@ suite11(Config) when is_list(Config) -> ERPid = ct_test_support:start_event_receiver(Config), - ok = ct_test_support:run(ct, run_test, [Opts], Config), + ok = ct_test_support:run(Opts, Config), Events = ct_test_support:get_events(ERPid, Config), @@ -259,7 +259,7 @@ suite11(Config) when is_list(Config) -> ct_test_support:reformat(Events, ?eh), ?config(priv_dir, Config)), - TestEvents = test_events(suite11), + TestEvents = events_to_check(suite11), ok = ct_test_support:verify_events(TestEvents, Events, Config). %%%----------------------------------------------------------------- @@ -280,7 +280,7 @@ suite21(Config) when is_list(Config) -> ERPid = ct_test_support:start_event_receiver(Config), - ok = ct_test_support:run(ct, run_test, [Opts], Config), + ok = ct_test_support:run(Opts, Config), Events = ct_test_support:get_events(ERPid, Config), @@ -288,7 +288,7 @@ suite21(Config) when is_list(Config) -> ct_test_support:reformat(Events, ?eh), ?config(priv_dir, Config)), - TestEvents = test_events(suite21), + TestEvents = events_to_check(suite21), ok = ct_test_support:verify_events(TestEvents, Events, Config). %%%----------------------------------------------------------------- @@ -311,7 +311,7 @@ suite11_21(Config) when is_list(Config) -> ERPid = ct_test_support:start_event_receiver(Config), - ok = ct_test_support:run(ct, run_test, [Opts], Config), + ok = ct_test_support:run(Opts, Config), Events = ct_test_support:get_events(ERPid, Config), @@ -319,7 +319,7 @@ suite11_21(Config) when is_list(Config) -> ct_test_support:reformat(Events, ?eh), ?config(priv_dir, Config)), - TestEvents = test_events(suite11_21), + TestEvents = events_to_check(suite11_21), ok = ct_test_support:verify_events(TestEvents, Events, Config). %%%----------------------------------------------------------------- @@ -342,7 +342,7 @@ tc111(Config) when is_list(Config) -> ERPid = ct_test_support:start_event_receiver(Config), - ok = ct_test_support:run(ct, run_test, [Opts], Config), + ok = ct_test_support:run(Opts, Config), Events = ct_test_support:get_events(ERPid, Config), @@ -350,7 +350,7 @@ tc111(Config) when is_list(Config) -> ct_test_support:reformat(Events, ?eh), ?config(priv_dir, Config)), - TestEvents = test_events(tc111), + TestEvents = events_to_check(tc111), ok = ct_test_support:verify_events(TestEvents, Events, Config). %%%----------------------------------------------------------------- @@ -372,7 +372,7 @@ tc211(Config) when is_list(Config) -> ERPid = ct_test_support:start_event_receiver(Config), - ok = ct_test_support:run(ct, run_test, [Opts], Config), + ok = ct_test_support:run(Opts, Config), Events = ct_test_support:get_events(ERPid, Config), @@ -380,7 +380,7 @@ tc211(Config) when is_list(Config) -> ct_test_support:reformat(Events, ?eh), ?config(priv_dir, Config)), - TestEvents = test_events(tc211), + TestEvents = events_to_check(tc211), ok = ct_test_support:verify_events(TestEvents, Events, Config). %%%----------------------------------------------------------------- @@ -403,7 +403,7 @@ tc111_112(Config) when is_list(Config) -> ERPid = ct_test_support:start_event_receiver(Config), - ok = ct_test_support:run(ct, run_test, [Opts], Config), + ok = ct_test_support:run(Opts, Config), Events = ct_test_support:get_events(ERPid, Config), @@ -411,7 +411,7 @@ tc111_112(Config) when is_list(Config) -> ct_test_support:reformat(Events, ?eh), ?config(priv_dir, Config)), - TestEvents = test_events(tc111_112), + TestEvents = events_to_check(tc111_112), ok = ct_test_support:verify_events(TestEvents, Events, Config). @@ -423,8 +423,16 @@ eh_opts(Config) -> Level = ?config(trace_level, Config), [{event_handler,{?eh,[{cbm,ct_test_support},{trace_level,Level}]}}]. +events_to_check(Test) -> + %% 2 tests (ct:run_test + script_start) is default + events_to_check(Test, 2). -test_events(Test) when Test == dir1 ; Test == dir2 ; +events_to_check(_, 0) -> + []; +events_to_check(Test, N) -> + events(Test) ++ events_to_check(Test, N-1). + +events(Test) when Test == dir1 ; Test == dir2 ; Test == suite11 ; Test == suite21 -> Suite = if Test == dir1 ; Test == suite11 -> happy_11_SUITE; true -> happy_21_SUITE @@ -465,7 +473,7 @@ test_events(Test) when Test == dir1 ; Test == dir2 ; {?eh,test_done,{'DEF','STOP_TIME'}}, {?eh,stop_logging,[]} ]; -test_events(Test) when Test == dir1_2 ; Test == suite11_21 -> +events(Test) when Test == dir1_2 ; Test == suite11_21 -> [ {?eh,start_logging,{'DEF','RUNDIR'}}, {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, @@ -532,7 +540,7 @@ test_events(Test) when Test == dir1_2 ; Test == suite11_21 -> {?eh,stop_logging,[]} ]; -test_events(Test) when Test == tc111 ; Test == tc211 -> +events(Test) when Test == tc111 ; Test == tc211 -> Suite = if Test == tc111 -> happy_11_SUITE; true -> happy_21_SUITE end, [ {?eh,start_logging,{'DEF','RUNDIR'}}, @@ -549,7 +557,7 @@ test_events(Test) when Test == tc111 ; Test == tc211 -> {?eh,stop_logging,[]} ]; -test_events(tc111_112) -> +events(tc111_112) -> [ {?eh,start_logging,{'DEF','RUNDIR'}}, {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE.erl index 069f8c75fc..eb85409073 100644 --- a/lib/common_test/test/ct_test_server_if_1_SUITE.erl +++ b/lib/common_test/test/ct_test_server_if_1_SUITE.erl @@ -87,14 +87,14 @@ ts_if_1(Config) when is_list(Config) -> TestSpecName = ct_test_support:write_testspec(TestSpec, PrivDir, "ts_if_1_spec"), {Opts,ERPid} = setup({spec,TestSpecName}, Config), - ok = ct_test_support:run(ct, run_test, [Opts], Config), + ok = ct_test_support:run(Opts, Config), Events = ct_test_support:get_events(ERPid, Config), ct_test_support:log_events(ts_if_1, reformat(Events, ?eh), PrivDir), - TestEvents = test_events(ts_if_1), + TestEvents = events_to_check(ts_if_1), ok = ct_test_support:verify_events(TestEvents, Events, Config). @@ -119,6 +119,15 @@ reformat(Events, EH) -> %%%----------------------------------------------------------------- %%% TEST EVENTS %%%----------------------------------------------------------------- +events_to_check(Test) -> + %% 2 tests (ct:run_test + script_start) is default + events_to_check(Test, 2). + +events_to_check(_, 0) -> + []; +events_to_check(Test, N) -> + test_events(Test) ++ events_to_check(Test, N-1). + test_events(ts_if_1) -> [ {?eh,start_logging,{'DEF','RUNDIR'}}, @@ -193,14 +202,14 @@ test_events(ts_if_1) -> {?eh,tc_done,{ts_if_1_SUITE,{end_per_group,g2,[parallel]},ok}}]}, {?eh,tc_start,{ts_if_1_SUITE,tc12}}, - {?eh,tc_done,{undefined,undefined,{testcase_aborted,{abort_current_testcase,tc12},'_'}}}, + {?eh,tc_done,{ts_if_1_SUITE,tc12,{failed,{testcase_aborted,'stopping tc12'}}}}, {?eh,test_stats,{2,5,{3,6}}}, {?eh,tc_start,{ts_if_1_SUITE,tc13}}, {?eh,tc_done,{ts_if_1_SUITE,tc13,ok}}, {?eh,test_stats,{3,5,{3,6}}}, {?eh,tc_start,{ts_if_1_SUITE,end_per_suite}}, {?eh,tc_done,{ts_if_1_SUITE,end_per_suite,ok}}, -%%! + {?eh,tc_start,{ts_if_2_SUITE,init_per_suite}}, {?eh,tc_done,{ts_if_2_SUITE,init_per_suite, {failed,{error,{suite0_failed,{exited,suite0_goes_boom}}}}}}, diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_1_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_1_SUITE.erl index 8e90df21ce..47cea190dd 100644 --- a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_1_SUITE.erl +++ b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_1_SUITE.erl @@ -93,6 +93,10 @@ init_per_testcase(_TestCase, Config) -> %%-------------------------------------------------------------------- end_per_testcase(tc2, Config) -> timer:sleep(5000); +end_per_testcase(tc12, Config) -> + ct:comment("end_per_testcase(tc12) called!"), + ct:pal("end_per_testcase(tc12) called!", []), + ok; end_per_testcase(_TestCase, _Config) -> ok. @@ -180,9 +184,9 @@ gtc2(_) -> exit(should_have_been_skipped). tc12(_) -> - F = fun() -> ct:abort_current_testcase({abort_current_testcase,tc12}) end, + F = fun() -> ct:abort_current_testcase('stopping tc12') end, spawn(F), - timer:sleep(500), + timer:sleep(1000), exit(should_have_been_aborted). tc13(_) -> diff --git a/lib/common_test/test/ct_test_support.erl b/lib/common_test/test/ct_test_support.erl index 6148e3280e..7bfb9ffb49 100644 --- a/lib/common_test/test/ct_test_support.erl +++ b/lib/common_test/test/ct_test_support.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -23,12 +23,13 @@ %%% -module(ct_test_support). --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -include_lib("common_test/include/ct_event.hrl"). -export([init_per_suite/1, init_per_suite/2, end_per_suite/1, - init_per_testcase/2, end_per_testcase/2, write_testspec/3, - run/4, get_opts/1, wait_for_ct_stop/1]). + init_per_testcase/2, end_per_testcase/2, + write_testspec/2, write_testspec/3, + run/2, run/4, get_opts/1, wait_for_ct_stop/1]). -export([handle_event/2, start_event_receiver/1, get_events/2, verify_events/3, reformat/2, log_events/3]). @@ -55,17 +56,28 @@ init_per_suite(Config, Level) -> test_server:fail(Reason); {ok,CTNode} -> test_server:format(0, "Node ~p started~n", [CTNode]), + IsCover = test_server:is_cover(), + if IsCover -> + cover:start(CTNode); + true-> + ok + end, DataDir = ?config(data_dir, Config), PrivDir = ?config(priv_dir, Config), %% PrivDir as well as directory of Test Server suites %% have to be in code path on Common Test node. - true = rpc:call(CTNode, code, add_patha, [PrivDir]), [_ | Parts] = lists:reverse(filename:split(DataDir)), TSDir = filename:join(lists:reverse(Parts)), - true = rpc:call(CTNode, code, add_patha, [TSDir]), - test_server:format(Level, "Dirs added to code path (on ~w):~n" - "~s~n~s~n", [CTNode,TSDir,PrivDir]), + AddPathDirs = case ?config(path_dirs, Config) of + undefined -> []; + Ds -> Ds + end, + PathDirs = [PrivDir,TSDir | AddPathDirs], + [true = rpc:call(CTNode, code, add_patha, [D]) || D <- PathDirs], + test_server:format(Level, "Dirs added to code path (on ~w):~n", + [CTNode]), + [io:format("~s~n", [D]) || D <- PathDirs], TraceFile = filename:join(DataDir, "ct.trace"), case file:read_file_info(TraceFile) of @@ -87,6 +99,7 @@ end_per_suite(Config) -> CTNode = ?config(ct_node, Config), PrivDir = ?config(priv_dir, Config), true = rpc:call(CTNode, code, del_path, [filename:join(PrivDir,"")]), + cover:stop(CTNode), slave:stop(CTNode), ok. @@ -95,9 +108,17 @@ end_per_suite(Config) -> init_per_testcase(_TestCase, Config) -> {_,{_,LogDir}} = lists:keysearch(logdir, 1, get_opts(Config)), - test_server:format("See Common Test logs here:\n" - "<a href=\"file://~s/all_runs.html\">~s/all_runs.html</a>", - [LogDir,LogDir]), + case lists:keysearch(master, 1, Config) of + false-> + test_server:format("See Common Test logs here:\n\n" + "<a href=\"file://~s/all_runs.html\">~s/all_runs.html</a>\n" + "<a href=\"file://~s/index.html\">~s/index.html</a>", + [LogDir,LogDir,LogDir,LogDir]); + {value, _}-> + test_server:format("See CT Master Test logs here:\n\n" + "<a href=\"file://~s/master_runs.html\">~s/master_runs.html</a>", + [LogDir,LogDir]) + end, Config. %%%----------------------------------------------------------------- @@ -111,9 +132,10 @@ end_per_testcase(_TestCase, Config) -> %%%----------------------------------------------------------------- %%% - write_testspec(TestSpec, Dir, Name) -> - TSFile = filename:join(Dir, Name), + write_testspec(TestSpec, filename:join(Dir, Name)). + +write_testspec(TestSpec, TSFile) -> {ok,Dev} = file:open(TSFile, [write]), [io:format(Dev, "~p.~n", [Entry]) || Entry <- TestSpec], file:close(Dev), @@ -158,10 +180,32 @@ get_opts(Config) -> %%%----------------------------------------------------------------- %%% +run(Opts, Config) -> + CTNode = ?config(ct_node, Config), + Level = ?config(trace_level, Config), + %% use ct interface + test_server:format(Level, "~n[RUN #1] Calling ct:run_test(~p) on ~p~n", + [Opts, CTNode]), + Result1 = rpc:call(CTNode, ct, run_test, [Opts]), + + %% use run_test interface (simulated) + test_server:format(Level, "Saving start opts on ~p: ~p~n", [CTNode,Opts]), + rpc:call(CTNode, application, set_env, [common_test, run_test_start_opts, Opts]), + test_server:format(Level, "[RUN #2] Calling ct_run:script_start() on ~p~n", [CTNode]), + Result2 = rpc:call(CTNode, ct_run, script_start, []), + case {Result1,Result2} of + {ok,ok} -> + ok; + {E,_} when E =/= ok -> + E; + {_,E} when E =/= ok -> + E + end. + run(M, F, A, Config) -> CTNode = ?config(ct_node, Config), Level = ?config(trace_level, Config), - test_server:format(Level, "Calling ~w:~w(~p) on ~p~n", + test_server:format(Level, "~nCalling ~w:~w(~p) on ~p~n", [M, F, A, CTNode]), rpc:call(CTNode, M, F, A). @@ -231,8 +275,12 @@ verify_events(TEvs, Evs, Config) -> ok end. +verify_events1([TestEv|_], [{TEH,#event{name=stop_logging,node=Node,data=_}}|_], Node, _) + when element(1,TestEv) == TEH, element(2,TestEv) =/= stop_logging -> + test_server:format("Failed to find ~p in the list of events!~n", [TestEv]), + exit({event_not_found,TestEv}); + verify_events1(TEvs = [TestEv | TestEvs], Evs = [_|Events], Node, Config) -> -%% test_server:format("Next expected event: ~p~n", [TestEv]), case catch locate(TestEv, Node, Evs, Config) of nomatch -> verify_events1(TEvs, Events, Node, Config); @@ -332,6 +380,10 @@ locate({parallel,TEvs}, Node, Evs, Config) -> EH == TEH, EvNode == Node, Mod == M, Func == F -> false; + ({EH,#event{name=stop_logging, + node=EvNode,data=_}}) when + EH == TEH, EvNode == Node -> + exit({tc_start_not_found,TEv}); (_) -> true end, Evs1), @@ -345,6 +397,10 @@ locate({parallel,TEvs}, Node, Evs, Config) -> EH == TEH, EvNode == Node, Mod == M, Func == F -> false; + ({EH,#event{name=stop_logging, + node=EvNode,data=_}}) when + EH == TEH, EvNode == Node -> + exit({tc_done_not_found,TEv}); (_) -> true end, Evs2), @@ -388,6 +444,10 @@ locate({parallel,TEvs}, Node, Evs, Config) -> EH == TEH, EvNode == Node, Mod == M, EvGName == GroupName, EvProps == Props -> false; + ({EH,#event{name=stop_logging, + node=EvNode,data=_}}) when + EH == TEH, EvNode == Node -> + exit({tc_start_not_found,TEv}); (_) -> true end, RemEvs), @@ -410,6 +470,10 @@ locate({parallel,TEvs}, Node, Evs, Config) -> EH == TEH, EvNode == Node, Mod == M, EvGName == GroupName, EvProps == Props, Res == R -> false; + ({EH,#event{name=stop_logging, + node=EvNode,data=_}}) when + EH == TEH, EvNode == Node -> + exit({tc_done_not_found,TEv}); (_) -> true end, RemEvs), @@ -429,6 +493,10 @@ locate({parallel,TEvs}, Node, Evs, Config) -> data={Mod,end_per_group,Reason}}}) when EH == TEH, EvNode == Node, Mod == M, Reason == R -> false; + ({EH,#event{name=stop_logging, + node=EvNode,data=_}}) when + EH == TEH, EvNode == Node -> + exit({tc_auto_skip_not_found,TEv}); (_) -> true end, RemEvs), @@ -533,6 +601,10 @@ locate({shuffle,TEvs}, Node, Evs, Config) -> EH == TEH, EvNode == Node, Mod == M, Func == F -> false; + ({EH,#event{name=stop_logging, + node=EvNode,data=_}}) when + EH == TEH, EvNode == Node -> + exit({tc_start_not_found,TEv}); (_) -> true end, Evs1), @@ -576,6 +648,10 @@ locate({shuffle,TEvs}, Node, Evs, Config) -> EH == TEH, EvNode == Node, Mod == M, EvGName == GroupName -> false; + ({EH,#event{name=stop_logging, + node=EvNode,data=_}}) when + EH == TEH, EvNode == Node -> + exit({tc_start_not_found,TEv}); (_) -> true end, RemEvs), @@ -611,6 +687,10 @@ locate({shuffle,TEvs}, Node, Evs, Config) -> EH == TEH, EvNode == Node, Mod == M, EvGName == GroupName, Res == R -> false; + ({EH,#event{name=stop_logging, + node=EvNode,data=_}}) when + EH == TEH, EvNode == Node -> + exit({tc_done_not_found,TEv}); (_) -> true end, RemEvs), @@ -643,6 +723,10 @@ locate({shuffle,TEvs}, Node, Evs, Config) -> data={Mod,end_per_group,Reason}}}) when EH == TEH, EvNode == Node, Mod == M, Reason == R -> false; + ({EH,#event{name=stop_logging, + node=EvNode,data=_}}) when + EH == TEH, EvNode == Node -> + exit({tc_auto_skip_not_found,TEv}); (_) -> true end, RemEvs), @@ -785,7 +869,8 @@ log_events(TC, Events, PrivDir) -> io:format(Dev, "[~n", []), log_events1(Events, Dev, " "), file:close(Dev), - io:format("Events written to logfile: ~p~n", [LogFile]), + io:format("Events written to logfile: <a href=\"file://~s\">~s</a>~n", + [LogFile,LogFile]), io:format(user, "Events written to logfile: ~p~n", [LogFile]). log_events1(Evs, Dev, "") -> diff --git a/lib/common_test/test/ct_test_support_eh.erl b/lib/common_test/test/ct_test_support_eh.erl index fd3ae18746..70f73b9b81 100644 --- a/lib/common_test/test/ct_test_support_eh.erl +++ b/lib/common_test/test/ct_test_support_eh.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009. All Rights Reserved. -%% +%% +%% 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% %% @@ -44,8 +44,20 @@ %% Description: Whenever a new event handler is added to an event manager, %% this function is called to initialize the event handler. %%-------------------------------------------------------------------- +init(String = [X|_]) when is_integer(X) -> + case erl_scan:string(String++".") of + {ok,Ts,_} -> + case erl_parse:parse_term(Ts) of + {ok,Args} -> + init(Args); + _ -> + init(String) + end; + _ -> + init(String) + end; + init(Args) -> - S1 = case lists:keysearch(cbm, 1, Args) of {_,{cbm,CBM}} -> #state{cbm=CBM}; @@ -58,7 +70,8 @@ init(Args) -> _ -> S1 end, - print(S2#state.trace_level, "Event Handler ~w started!~n", [?MODULE]), + print(S2#state.trace_level, "Event Handler ~w started with ~p~n", + [?MODULE,Args]), {ok,S2}. %%-------------------------------------------------------------------- diff --git a/lib/common_test/test/ct_testspec_1_SUITE.erl b/lib/common_test/test/ct_testspec_1_SUITE.erl new file mode 100644 index 0000000000..dc399bfb4c --- /dev/null +++ b/lib/common_test/test/ct_testspec_1_SUITE.erl @@ -0,0 +1,433 @@ +%% +%% %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% +%% + +%%%------------------------------------------------------------------- +%%% File: ct_testspec_1_SUITE +%%% +%%% Description: +%%% Test test specifications +%%% +%%% The suites used for the test are located in the data directory. +%%%------------------------------------------------------------------- +-module(ct_testspec_1_SUITE). + +-compile(export_all). + +-include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct_event.hrl"). + +-define(eh, ct_test_support_eh). + +%%-------------------------------------------------------------------- +%% TEST SERVER CALLBACK FUNCTIONS +%%-------------------------------------------------------------------- + +%%-------------------------------------------------------------------- +%% Description: Since Common Test starts another Test Server +%% instance, the tests need to be performed on a separate node (or +%% there will be clashes with logging processes etc). +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + Config1 = ct_test_support:init_per_suite(Config), + Config1. + +end_per_suite(Config) -> + ct_test_support:end_per_suite(Config). + +init_per_testcase(TestCase, Config) -> + ct_test_support:init_per_testcase(TestCase, Config). + +end_per_testcase(TestCase, Config) -> + ct_test_support:end_per_testcase(TestCase, Config). + +all(doc) -> + ["Run smoke tests of Common Test."]; + +all(suite) -> + [all_suites, skip_all_suites, + suite, skip_suite, + all_testcases, skip_all_testcases, + testcase, skip_testcase, + all_groups, skip_all_groups, + group, skip_group, + group_all_testcases, skip_group_all_testcases, + group_testcase, skip_group_testcase, + topgroup, + subgroup, skip_subgroup, + subgroup_all_testcases, skip_subgroup_all_testcases, + subgroup_testcase, skip_subgroup_testcase, + sub_skipped_by_top, + testcase_in_multiple_groups]. + +%%-------------------------------------------------------------------- +%% TEST CASES +%%-------------------------------------------------------------------- + +%%%----------------------------------------------------------------- +%%% + +all_suites(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "suites_1"), + TestSpec = [{label,"all_suites"}, + {suites,TestDir,all}], + + setup_and_execute(all_suites, TestSpec, Config). + +skip_all_suites(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "suites_1"), + TestSpec = [{label,skip_all_suites}, + {suites,TestDir,all}, + {skip_suites,TestDir,all,"SKIPPED!"}], + + setup_and_execute(skip_all_suites, TestSpec, Config). + +%%%----------------------------------------------------------------- +%%% + +suite(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "suites_1"), + TestSpec = [{label,undefined}, + {suites,TestDir,simple_1_SUITE}], + + setup_and_execute(suite, TestSpec, Config). + +skip_suite(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "suites_1"), + TestSpec = [{suites,TestDir,[simple_1_SUITE,simple_2_SUITE]}, + {skip_suites,TestDir,simple_1_SUITE,"SKIPPED!"}], + + setup_and_execute(skip_suite, TestSpec, Config). + +%%%----------------------------------------------------------------- +%%% + +all_testcases(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "suites_1"), + TestSpec = [{cases,TestDir,simple_1_SUITE,all}], + + setup_and_execute(all_testcases, TestSpec, Config). + +skip_all_testcases(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "suites_1"), + TestSpec = [{suites,TestDir,[simple_1_SUITE]}, + {skip_cases,TestDir,simple_1_SUITE,all,"SKIPPED!"}], + + setup_and_execute(skip_all_testcases, TestSpec, Config). + +%%%----------------------------------------------------------------- +%%% + +testcase(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "suites_1"), + TestSpec = [{cases,TestDir,simple_1_SUITE,tc1}], + + setup_and_execute(testcase, TestSpec, Config). + +skip_testcase(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "suites_1"), + TestSpec = [{cases,TestDir,simple_1_SUITE,[tc1,tc2]}, + {cases,TestDir,simple_2_SUITE,[tc2,tc1]}, + {skip_cases,TestDir,simple_1_SUITE,[tc1],"SKIPPED!"}, + {skip_cases,TestDir,simple_2_SUITE,tc2,"SKIPPED!"}], + + setup_and_execute(skip_testcase, TestSpec, Config). + +%%%----------------------------------------------------------------- +%%% + +all_groups(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "groups_1"), + TestSpec = [{groups,TestDir,groups_11_SUITE,all}], + + setup_and_execute(all_groups, TestSpec, Config). + +skip_all_groups(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "groups_1"), + TestSpec = [{groups,TestDir,groups_11_SUITE,all}, + {skip_groups,TestDir,groups_11_SUITE,all,"SKIPPED!"}], + + setup_and_execute(skip_all_groups, TestSpec, Config). + +%%%----------------------------------------------------------------- +%%% + +group(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "groups_1"), + TestSpec = [{groups,TestDir,groups_11_SUITE,test_group_1a}], + + setup_and_execute(group, TestSpec, Config). + +skip_group(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "groups_1"), + TestSpec = [{groups,TestDir,groups_11_SUITE,[test_group_1a, + test_group_1b]}, + {skip_groups,TestDir,groups_11_SUITE, + [test_group_1b,test_group_2,test_group_7],"SKIPPED!"}], + + setup_and_execute(skip_group, TestSpec, Config). + + +%%%----------------------------------------------------------------- +%%% + +group_all_testcases(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "groups_1"), + TestSpec = [{groups,TestDir,groups_11_SUITE,test_group_1a,{cases,all}}], + + setup_and_execute(group_all_testcases, TestSpec, Config). + +skip_group_all_testcases(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "groups_1"), + TestSpec = [{groups,TestDir,groups_11_SUITE,[test_group_1a, + test_group_1b]}, + {skip_groups,TestDir,groups_11_SUITE, + test_group_1b,{cases,all},"SKIPPED!"}, + {skip_groups,TestDir,groups_11_SUITE, + test_group_1a,{cases,all},"SKIPPED!"}], + + setup_and_execute(skip_group_all_testcases, TestSpec, Config). + +%%%----------------------------------------------------------------- +%%% + +group_testcase(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "groups_1"), + TestSpec = [{groups,TestDir,groups_11_SUITE,test_group_1a,{cases,testcase_1a}}], + + setup_and_execute(group_testcase, TestSpec, Config). + +skip_group_testcase(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "groups_1"), + TestSpec = [{groups,TestDir,groups_11_SUITE,test_group_1a, + {cases,[testcase_1a,testcase_1b]}}, + {groups,TestDir,groups_11_SUITE,test_group_1b, + {cases,[testcase_1b,testcase_1a]}}, + {skip_groups,TestDir,groups_11_SUITE, + test_group_1a,{cases,testcase_1b},"SKIPPED!"}, + {skip_groups,TestDir,groups_11_SUITE, + test_group_1b,{cases,[testcase_1a]},"SKIPPED!"}], + + setup_and_execute(skip_group_testcase, TestSpec, Config). + +%%%----------------------------------------------------------------- +%%% + +topgroup(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "groups_1"), + TestSpec = [{groups,TestDir,groups_12_SUITE,test_group_2}, + {groups,TestDir,groups_12_SUITE,test_group_4}], + + setup_and_execute(topgroup, TestSpec, Config). + +%%%----------------------------------------------------------------- +%%% + +subgroup(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "groups_1"), + TestSpec = [{groups,TestDir,groups_12_SUITE,test_group_3}], + + setup_and_execute(subgroup, TestSpec, Config). + +skip_subgroup(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "groups_1"), + TestSpec = [{groups,TestDir,groups_12_SUITE,[test_group_4]}, + {skip_groups,TestDir,groups_12_SUITE, + test_group_8,"SKIPPED!"}], + + setup_and_execute(skip_subgroup, TestSpec, Config). + +%%%----------------------------------------------------------------- +%%% + +subgroup_all_testcases(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "groups_1"), + TestSpec = [{groups,TestDir,groups_12_SUITE, + test_group_5,{cases,all}}, + {groups,TestDir,groups_12_SUITE, + test_group_3,{cases,all}}], + + setup_and_execute(subgroup_all_testcases, TestSpec, Config). + +skip_subgroup_all_testcases(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "groups_1"), + TestSpec = [{groups,TestDir,groups_12_SUITE,test_group_4}, + {skip_groups,TestDir,groups_12_SUITE, + test_group_5,{cases,all},"SKIPPED!"}], + + setup_and_execute(skip_subgroup_all_testcases, TestSpec, Config). + +%%%----------------------------------------------------------------- +%%% + +subgroup_testcase(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "groups_1"), + TestSpec = [{groups,TestDir,groups_12_SUITE, + test_group_7,{cases,testcase_7a}}, + {groups,TestDir,groups_12_SUITE, + test_group_3,{cases,testcase_3b}}], + + setup_and_execute(subgroup_testcase, TestSpec, Config). + +skip_subgroup_testcase(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "groups_1"), + TestSpec = [{groups,TestDir,groups_12_SUITE,test_group_5}, + {skip_groups,TestDir,groups_12_SUITE, + test_group_7,{cases,[testcase_7a,testcase_7b]},"SKIPPED!"}], + + setup_and_execute(skip_subgroup_testcase, TestSpec, Config). + +%%%----------------------------------------------------------------- +%%% + +%%! +%%! Somewhat weird result from this one: +%%! +sub_skipped_by_top(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "groups_1"), + TestSpec = [{groups,TestDir,groups_12_SUITE,test_group_5}, + {skip_groups,TestDir,groups_12_SUITE,test_group_4,"SKIPPED!"}], + + setup_and_execute(sub_skipped_by_top, TestSpec, Config). + +%%%----------------------------------------------------------------- +%%% + +testcase_in_multiple_groups(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + + TestDir = filename:join(DataDir, "groups_1"), + TestSpec = [{cases,TestDir,groups_12_SUITE,[testcase_1a,testcase_1b]}, + {skip_cases,TestDir,groups_12_SUITE,[testcase_1b],"SKIPPED!"}], + + setup_and_execute(testcase_in_multiple_groups, TestSpec, Config). + +%%%----------------------------------------------------------------- +%%% HELP FUNCTIONS +%%%----------------------------------------------------------------- + +setup_and_execute(TCName, TestSpec, Config) -> + SpecFile = create_spec_file(?config(priv_dir, Config), + TCName, TestSpec), + TestTerms = + case lists:keymember(label, 1, TestSpec) of + true -> [{spec,SpecFile}]; + false -> [{spec,SpecFile},{label,TCName}] + end, + {Opts,ERPid} = setup(TestTerms, Config), + ok = ct_test_support:run(Opts, Config), + TestSpec1 = [{logdir,proplists:get_value(logdir,Opts)}, + {label,proplists:get_value(label,TestTerms)} | TestSpec], + ok = ct_test_support:run(ct, run_testspec, [TestSpec1], Config), + Events = ct_test_support:get_events(ERPid, Config), + + ct_test_support:log_events(TCName, + reformat(Events, ?eh), + ?config(priv_dir, Config)), + + TestEvents = events_to_check(TCName), + ok = ct_test_support:verify_events(TestEvents, Events, Config). + +create_spec_file(SpecDir, TCName, TestSpec) -> + FileName = filename:join(SpecDir, + atom_to_list(TCName)++".spec"), + {ok,Dev} = file:open(FileName, [write]), + [io:format(Dev, "~p.~n", [Term]) || Term <- TestSpec], + file:close(Dev), + io:format("~nTest spec created here~n~n<a href=\"file://~s\">~s</a>~n", + [FileName,FileName]), + FileName. + +setup(Test, Config) when is_tuple(Test) -> + setup([Test], Config); +setup(Tests, Config) -> + Opts0 = ct_test_support:get_opts(Config), + Level = ?config(trace_level, Config), + EvHArgs = [{cbm,ct_test_support},{trace_level,Level}], + Opts = Opts0 ++ Tests ++ [{event_handler,{?eh,EvHArgs}}], + ERPid = ct_test_support:start_event_receiver(Config), + {Opts,ERPid}. + +reformat(Events, EH) -> + ct_test_support:reformat(Events, EH). +%reformat(Events, _EH) -> +% Events. + +%%%----------------------------------------------------------------- +%%% TEST EVENTS +%%%----------------------------------------------------------------- +events_to_check(Test) -> + %% 2 tests (ct:run_test + script_start) is default + events_to_check(Test, 2). + +events_to_check(_, 0) -> + []; +events_to_check(Test, N) -> + test_events(Test) ++ events_to_check(Test, N-1). + +test_events(_) -> + [ + ]. diff --git a/lib/common_test/test/ct_testspec_1_SUITE_data/groups_1/groups_11_SUITE.erl b/lib/common_test/test/ct_testspec_1_SUITE_data/groups_1/groups_11_SUITE.erl new file mode 100644 index 0000000000..4f11d8a0e8 --- /dev/null +++ b/lib/common_test/test/ct_testspec_1_SUITE_data/groups_1/groups_11_SUITE.erl @@ -0,0 +1,281 @@ +%% +%% %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% +%% +-module(groups_11_SUITE). + +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +%%==================================================================== +%% COMMON TEST CALLBACK FUNCTIONS +%%==================================================================== + +suite() -> + [{timetrap,{minutes,1}}]. + +groups() -> + [ + {test_group_1a, [testcase_1a,testcase_1b]}, + + {test_group_1b, [], [testcase_1a,testcase_1b]}, + + {test_group_2, [], [testcase_2a, + + {test_group_3, [], [testcase_3a, + testcase_3b]}, + testcase_2b]}, + + {test_group_4, [{test_group_5, [], [testcase_5a, + + {group, test_group_6}, + + testcase_5b]}]}, + {test_group_6, [{group, test_group_7}]}, + + {test_group_7, [testcase_7a,testcase_7b]} + ]. + +all() -> + [testcase_1, + {group, test_group_1a}, + {group, test_group_1b}, + testcase_2, + {group, test_group_2}, + testcase_3, + {group, test_group_4}]. + +%% this func only for internal test purposes +grs_and_tcs() -> + {[ + test_group_1a, test_group_1b, + test_group_2, test_group_3, + test_group_4, test_group_5, + test_group_6, test_group_7 + ], + [ + testcase_1, + testcase_1a, testcase_1b, + testcase_2, + testcase_2a, testcase_2b, + testcase_3a, testcase_3b, + testcase_3, + testcase_5a, testcase_5b, + testcase_7a, testcase_7b + ]}. + +%%-------------------------------------------------------------------- +%% Suite Configuration +%%-------------------------------------------------------------------- + +init_per_suite(Config) -> + [{suite,init}|Config]. + +end_per_suite(Config) -> + init = ?config(suite,Config). + +%%-------------------------------------------------------------------- +%% Group Configuration +%%-------------------------------------------------------------------- + +init_per_group(Group, Config) -> + [{name,Group}] = ?config(tc_group_properties,Config), + {Grs,_} = grs_and_tcs(), + case lists:member(Group, Grs) of + true -> + ct:comment(Group), + init = ?config(suite,Config), + [{Group,Group} | Config]; + false -> + ct:fail({bad_group,Group}) + end. + +end_per_group(Group, Config) -> + {Grs,_} = grs_and_tcs(), + case lists:member(Group, Grs) of + true -> + ct:comment(Group), + init = ?config(suite,Config), + Group = ?config(Group,Config), + ok; + false -> + ct:fail({bad_group,Group}) + end. + +%%-------------------------------------------------------------------- +%% Testcase Configuration +%%-------------------------------------------------------------------- + +init_per_testcase(TestCase, Config) -> + {_,TCs} = grs_and_tcs(), + case lists:member(TestCase, TCs) of + true -> + init = ?config(suite,Config), + [{TestCase,TestCase} | Config]; + false -> + ct:fail({unknown_testcase,TestCase}) + end. + +end_per_testcase(TestCase, Config) -> + {_,TCs} = grs_and_tcs(), + case lists:member(TestCase, TCs) of + true -> + init = ?config(suite,Config), + TestCase = ?config(TestCase,Config), + ok; + false -> + ct:fail({unknown_testcase,TestCase}) + end. + + +%%-------------------------------------------------------------------- +%% Testcases +%%-------------------------------------------------------------------- + +testcase_1() -> + []. +testcase_1(Config) -> + init = ?config(suite,Config), + testcase_1 = ?config(testcase_1,Config), + ok. + +testcase_1a() -> + []. +testcase_1a(Config) -> + init = ?config(suite,Config), + case ?config(test_group_1a,Config) of + test_group_1a -> ok; + _ -> + case ?config(test_group_1b,Config) of + test_group_1b -> ok; + _ -> ct:fail(no_group_data) + end + end, + testcase_1a = ?config(testcase_1a,Config), + ok. +testcase_1b() -> + []. +testcase_1b(Config) -> + init = ?config(suite,Config), + case ?config(test_group_1a,Config) of + test_group_1a -> ok; + _ -> + case ?config(test_group_1b,Config) of + test_group_1b -> ok; + _ -> ct:fail(no_group_data) + end + end, + undefined = ?config(testcase_1a,Config), + testcase_1b = ?config(testcase_1b,Config), + ok. + +testcase_2() -> + []. +testcase_2(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_1a,Config), + undefined = ?config(test_group_1b,Config), + testcase_2 = ?config(testcase_2,Config), + ok. + +testcase_2a() -> + []. +testcase_2a(Config) -> + init = ?config(suite,Config), + test_group_2 = ?config(test_group_2,Config), + testcase_2a = ?config(testcase_2a,Config), + ok. +testcase_2b() -> + []. +testcase_2b(Config) -> + init = ?config(suite,Config), + test_group_2 = ?config(test_group_2,Config), + undefined = ?config(testcase_2a,Config), + testcase_2b = ?config(testcase_2b,Config), + ok. + +testcase_3a() -> + []. +testcase_3a(Config) -> + init = ?config(suite,Config), + test_group_2 = ?config(test_group_2,Config), + test_group_3 = ?config(test_group_3,Config), + undefined = ?config(testcase_2b,Config), + testcase_3a = ?config(testcase_3a,Config), + ok. +testcase_3b() -> + []. +testcase_3b(Config) -> + init = ?config(suite,Config), + test_group_2 = ?config(test_group_2,Config), + test_group_3 = ?config(test_group_3,Config), + undefined = ?config(testcase_3a,Config), + testcase_3b = ?config(testcase_3b,Config), + ok. + +testcase_3() -> + []. +testcase_3(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_2,Config), + undefined = ?config(test_group_3,Config), + testcase_3 = ?config(testcase_3,Config), + ok. + +testcase_5a() -> + []. +testcase_5a(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_3,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + undefined = ?config(testcase_3,Config), + testcase_5a = ?config(testcase_5a,Config), + ok. +testcase_5b() -> + []. +testcase_5b(Config) -> + init = ?config(suite,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + undefined = ?config(testcase_5a,Config), + testcase_5b = ?config(testcase_5b,Config), + ok. + +testcase_7a() -> + []. +testcase_7a(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_3,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + test_group_6 = ?config(test_group_6,Config), + test_group_7 = ?config(test_group_7,Config), + testcase_7a = ?config(testcase_7a,Config), + ok. +testcase_7b() -> + []. +testcase_7b(Config) -> + init = ?config(suite,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + test_group_6 = ?config(test_group_6,Config), + test_group_7 = ?config(test_group_7,Config), + undefined = ?config(testcase_7a,Config), + testcase_7b = ?config(testcase_7b,Config), + ok. diff --git a/lib/common_test/test/ct_testspec_1_SUITE_data/groups_1/groups_12_SUITE.erl b/lib/common_test/test/ct_testspec_1_SUITE_data/groups_1/groups_12_SUITE.erl new file mode 100644 index 0000000000..69c06f9b83 --- /dev/null +++ b/lib/common_test/test/ct_testspec_1_SUITE_data/groups_1/groups_12_SUITE.erl @@ -0,0 +1,344 @@ +%% +%% %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% +%% +-module(groups_12_SUITE). + +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +%%==================================================================== +%% COMMON TEST CALLBACK FUNCTIONS +%%==================================================================== + +suite() -> + [{timetrap,{minutes,1}}]. + +groups() -> + [ + {test_group_1a, [shuffle], [testcase_1a,testcase_1b,testcase_1c]}, + + {test_group_1b, [parallel], [testcase_1a,testcase_1b]}, + + {test_group_2, [parallel], [testcase_2a, + + {test_group_3, [{repeat,2}], + [testcase_3a, testcase_3b]}, + + testcase_2b]}, + + {test_group_4, [{test_group_5, [parallel], [testcase_5a, + + {group, test_group_6}, + + testcase_5b]}]}, + + {test_group_6, [parallel], [{group, test_group_7}, + {group, test_group_8}]}, + + {test_group_7, [sequence], [testcase_7a,testcase_7b]}, + + {test_group_8, [shuffle,sequence], [testcase_8a,testcase_8b]} + ]. + +all() -> + [{group, test_group_1a}, + {group, test_group_1b}, + testcase_1, + testcase_2, + {group, test_group_2}, + testcase_3, + {group, test_group_4}]. + +%% this func only for internal test purposes +grs_and_tcs() -> + {[ + test_group_1a, test_group_1b, + test_group_2, test_group_3, + test_group_4, test_group_5, + test_group_6, test_group_7, + test_group_8 + ], + [ + testcase_1a, testcase_1b, testcase_1c, + testcase_1, + testcase_2, + testcase_2a, testcase_2b, + testcase_3a, testcase_3b, + testcase_3, + testcase_5a, testcase_5b, + testcase_7a, testcase_7b, + testcase_8a, testcase_8b + ]}. + +%%-------------------------------------------------------------------- +%% Suite Configuration +%%-------------------------------------------------------------------- + +init_per_suite(Config) -> + [{suite,init}|Config]. + +end_per_suite(Config) -> + init = ?config(suite,Config). + +%%-------------------------------------------------------------------- +%% Group Configuration +%%-------------------------------------------------------------------- + +init_per_group(Group, Config) -> + Cmt = + case {Group,?config(tc_group_properties,Config)} of + {test_group_1a,[{shuffle,S},{name,test_group_1a}]} -> + io_lib:format("shuffled, ~w", [S]); + {test_group_1b,[{name,test_group_1b},parallel]} -> "parallel"; + {test_group_2,[{name,test_group_2},parallel]} -> "parallel"; + {test_group_3,[{name,test_group_3},{repeat,2}]} -> "repeat 2"; + {test_group_3,[{name,test_group_3}]} -> "repeat 1"; + {test_group_4,[{name,test_group_4}]} -> ok; + {test_group_5,[{name,test_group_5},parallel]} -> "parallel"; + {test_group_6,[{name,test_group_6},parallel]} -> "parallel"; + {test_group_7,[{name,test_group_7},sequence]} -> "sequence"; + {test_group_8,[{shuffle,_},{name,test_group_8},sequence]} -> + "shuffle & sequence" + end, + {Grs,_} = grs_and_tcs(), + case lists:member(Group, Grs) of + true -> + init = ?config(suite,Config), + ct:comment(io_lib:format("~w, ~s", [Group,Cmt])), + [{Group,Group} | Config]; + false -> + ct:fail({bad_group,Group}) + end. + +end_per_group(Group, Config) -> + {Grs,_} = grs_and_tcs(), + case lists:member(Group, Grs) of + true -> + init = ?config(suite,Config), + Group = ?config(Group,Config), + ok; + false -> + ct:fail({bad_group,Group}) + end. + +%%-------------------------------------------------------------------- +%% Testcase Configuration +%%-------------------------------------------------------------------- + +init_per_testcase(TestCase, Config) -> + {_,TCs} = grs_and_tcs(), + case lists:member(TestCase, TCs) of + true -> + init = ?config(suite,Config), + [{TestCase,TestCase} | Config]; + false -> + ct:fail({unknown_testcase,TestCase}) + end. + +end_per_testcase(TestCase, Config) -> + {_,TCs} = grs_and_tcs(), + case lists:member(TestCase, TCs) of + true -> + init = ?config(suite,Config), + TestCase = ?config(TestCase,Config), + ok; + false -> + ct:fail({unknown_testcase,TestCase}) + end. + + +%%-------------------------------------------------------------------- +%% Testcases +%%-------------------------------------------------------------------- + +testcase_1a() -> + []. +testcase_1a(Config) -> + init = ?config(suite,Config), + case ?config(test_group_1a,Config) of + test_group_1a -> ok; + _ -> + case ?config(test_group_1b,Config) of + test_group_1b -> ok; + _ -> ct:fail(no_group_data) + end + end, + testcase_1a = ?config(testcase_1a,Config), + ok. +testcase_1b() -> + []. +testcase_1b(Config) -> + init = ?config(suite,Config), + case ?config(test_group_1a,Config) of + test_group_1a -> ok; + _ -> + case ?config(test_group_1b,Config) of + test_group_1b -> ok; + _ -> ct:fail(no_group_data) + end + end, + undefined = ?config(testcase_1a,Config), + testcase_1b = ?config(testcase_1b,Config), + ok. + +testcase_1c() -> + []. +testcase_1c(Config) -> + init = ?config(suite,Config), + case ?config(test_group_1a,Config) of + test_group_1a -> ok; + _ -> + case ?config(test_group_1b,Config) of + test_group_1b -> ok; + _ -> ct:fail(no_group_data) + end + end, + undefined = ?config(testcase_1b,Config), + testcase_1c = ?config(testcase_1c,Config), + ok. + +testcase_1() -> + []. +testcase_1(Config) -> + init = ?config(suite,Config), + testcase_1 = ?config(testcase_1,Config), + ok. + +testcase_2() -> + []. +testcase_2(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_1a,Config), + undefined = ?config(test_group_1b,Config), + testcase_2 = ?config(testcase_2,Config), + ok. + +testcase_2a() -> + []. +testcase_2a(Config) -> + init = ?config(suite,Config), + test_group_2 = ?config(test_group_2,Config), + testcase_2a = ?config(testcase_2a,Config), + ok. +testcase_2b() -> + []. +testcase_2b(Config) -> + init = ?config(suite,Config), + test_group_2 = ?config(test_group_2,Config), + undefined = ?config(testcase_2a,Config), + testcase_2b = ?config(testcase_2b,Config), + ok. + +testcase_3a() -> + []. +testcase_3a(Config) -> + init = ?config(suite,Config), + test_group_2 = ?config(test_group_2,Config), + test_group_3 = ?config(test_group_3,Config), + undefined = ?config(testcase_2b,Config), + testcase_3a = ?config(testcase_3a,Config), + ok. +testcase_3b() -> + []. +testcase_3b(Config) -> + init = ?config(suite,Config), + test_group_2 = ?config(test_group_2,Config), + test_group_3 = ?config(test_group_3,Config), + undefined = ?config(testcase_3a,Config), + testcase_3b = ?config(testcase_3b,Config), + ok. + +testcase_3() -> + []. +testcase_3(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_2,Config), + undefined = ?config(test_group_3,Config), + testcase_3 = ?config(testcase_3,Config), + ok. + +testcase_5a() -> + []. +testcase_5a(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_3,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + undefined = ?config(testcase_3,Config), + testcase_5a = ?config(testcase_5a,Config), + %% increase chance the done event will come + %% during execution of subgroup (could be + %% tricky to handle) + timer:sleep(3), + ok. +testcase_5b() -> + []. +testcase_5b(Config) -> + init = ?config(suite,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + undefined = ?config(testcase_5a,Config), + testcase_5b = ?config(testcase_5b,Config), + ok. + +testcase_7a() -> + []. +testcase_7a(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_3,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + test_group_6 = ?config(test_group_6,Config), + test_group_7 = ?config(test_group_7,Config), + testcase_7a = ?config(testcase_7a,Config), + ok. +testcase_7b() -> + []. +testcase_7b(Config) -> + init = ?config(suite,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + test_group_6 = ?config(test_group_6,Config), + test_group_7 = ?config(test_group_7,Config), + undefined = ?config(testcase_7a,Config), + testcase_7b = ?config(testcase_7b,Config), + ok. + +testcase_8a() -> + []. +testcase_8a(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_3,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + test_group_6 = ?config(test_group_6,Config), + test_group_8 = ?config(test_group_8,Config), + testcase_8a = ?config(testcase_8a,Config), + ok. +testcase_8b() -> + []. +testcase_8b(Config) -> + init = ?config(suite,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + test_group_6 = ?config(test_group_6,Config), + test_group_8 = ?config(test_group_8,Config), + undefined = ?config(testcase_8a,Config), + testcase_8b = ?config(testcase_8b,Config), + ok. diff --git a/lib/common_test/test/ct_testspec_1_SUITE_data/groups_2/groups_21_SUITE.erl b/lib/common_test/test/ct_testspec_1_SUITE_data/groups_2/groups_21_SUITE.erl new file mode 100644 index 0000000000..2533ac8e84 --- /dev/null +++ b/lib/common_test/test/ct_testspec_1_SUITE_data/groups_2/groups_21_SUITE.erl @@ -0,0 +1,281 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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(groups_21_SUITE). + +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +%%==================================================================== +%% COMMON TEST CALLBACK FUNCTIONS +%%==================================================================== + +suite() -> + [{timetrap,{minutes,1}}]. + +groups() -> + [ + {test_group_1a, [testcase_1a,testcase_1b]}, + + {test_group_1b, [], [testcase_1a,testcase_1b]}, + + {test_group_2, [], [testcase_2a, + + {test_group_3, [], [testcase_3a, + testcase_3b]}, + testcase_2b]}, + + {test_group_4, [{test_group_5, [], [testcase_5a, + + {group, test_group_6}, + + testcase_5b]}]}, + + {test_group_6, [{group, test_group_7}]}, + + {test_group_7, [testcase_7a,testcase_7b]} + ]. + +all() -> + [testcase_1, + {group, test_group_1a}, + {group, test_group_1b}, + testcase_2, + {group, test_group_2}, + testcase_3, + {group, test_group_4}]. + +%% this func only for internal test purposes +grs_and_tcs() -> + {[ + test_group_1a, test_group_1b, + test_group_2, test_group_3, + test_group_4, test_group_5, + test_group_6, test_group_7 + ], + [ + testcase_1, + testcase_1a, testcase_1b, + testcase_2, + testcase_2a, testcase_2b, + testcase_3a, testcase_3b, + testcase_3, + testcase_5a, testcase_5b, + testcase_7a, testcase_7b + ]}. + +%%-------------------------------------------------------------------- +%% Suite Configuration +%%-------------------------------------------------------------------- + +init_per_suite(Config) -> + [{suite,init}|Config]. + +end_per_suite(Config) -> + init = ?config(suite,Config). + +%%-------------------------------------------------------------------- +%% Group Configuration +%%-------------------------------------------------------------------- + +init_per_group(Group, Config) -> + [{name,Group}] = ?config(tc_group_properties,Config), + {Grs,_} = grs_and_tcs(), + case lists:member(Group, Grs) of + true -> + ct:comment(io_lib:format("~w", [Group])), + init = ?config(suite,Config), + [{Group,Group} | Config]; + false -> + ct:fail({bad_group,Group}) + end. + +end_per_group(Group, Config) -> + {Grs,_} = grs_and_tcs(), + case lists:member(Group, Grs) of + true -> + init = ?config(suite,Config), + Group = ?config(Group,Config), + ok; + false -> + ct:fail({bad_group,Group}) + end. + +%%-------------------------------------------------------------------- +%% Testcase Configuration +%%-------------------------------------------------------------------- + +init_per_testcase(TestCase, Config) -> + {_,TCs} = grs_and_tcs(), + case lists:member(TestCase, TCs) of + true -> + init = ?config(suite,Config), + [{TestCase,TestCase} | Config]; + false -> + ct:fail({unknown_testcase,TestCase}) + end. + +end_per_testcase(TestCase, Config) -> + {_,TCs} = grs_and_tcs(), + case lists:member(TestCase, TCs) of + true -> + init = ?config(suite,Config), + TestCase = ?config(TestCase,Config), + ok; + false -> + ct:fail({unknown_testcase,TestCase}) + end. + + +%%-------------------------------------------------------------------- +%% Testcases +%%-------------------------------------------------------------------- + +testcase_1() -> + []. +testcase_1(Config) -> + init = ?config(suite,Config), + testcase_1 = ?config(testcase_1,Config), + ok. + +testcase_1a() -> + []. +testcase_1a(Config) -> + init = ?config(suite,Config), + case ?config(test_group_1a,Config) of + test_group_1a -> ok; + _ -> + case ?config(test_group_1b,Config) of + test_group_1b -> ok; + _ -> ct:fail(no_group_data) + end + end, + testcase_1a = ?config(testcase_1a,Config), + ok. +testcase_1b() -> + []. +testcase_1b(Config) -> + init = ?config(suite,Config), + case ?config(test_group_1a,Config) of + test_group_1a -> ok; + _ -> + case ?config(test_group_1b,Config) of + test_group_1b -> ok; + _ -> ct:fail(no_group_data) + end + end, + undefined = ?config(testcase_1a,Config), + testcase_1b = ?config(testcase_1b,Config), + ok. + +testcase_2() -> + []. +testcase_2(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_1a,Config), + undefined = ?config(test_group_1b,Config), + testcase_2 = ?config(testcase_2,Config), + ok. + +testcase_2a() -> + []. +testcase_2a(Config) -> + init = ?config(suite,Config), + test_group_2 = ?config(test_group_2,Config), + testcase_2a = ?config(testcase_2a,Config), + ok. +testcase_2b() -> + []. +testcase_2b(Config) -> + init = ?config(suite,Config), + test_group_2 = ?config(test_group_2,Config), + undefined = ?config(testcase_2a,Config), + testcase_2b = ?config(testcase_2b,Config), + ok. + +testcase_3a() -> + []. +testcase_3a(Config) -> + init = ?config(suite,Config), + test_group_2 = ?config(test_group_2,Config), + test_group_3 = ?config(test_group_3,Config), + undefined = ?config(testcase_2b,Config), + testcase_3a = ?config(testcase_3a,Config), + ok. +testcase_3b() -> + []. +testcase_3b(Config) -> + init = ?config(suite,Config), + test_group_2 = ?config(test_group_2,Config), + test_group_3 = ?config(test_group_3,Config), + undefined = ?config(testcase_3a,Config), + testcase_3b = ?config(testcase_3b,Config), + ok. + +testcase_3() -> + []. +testcase_3(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_2,Config), + undefined = ?config(test_group_3,Config), + testcase_3 = ?config(testcase_3,Config), + ok. + +testcase_5a() -> + []. +testcase_5a(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_3,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + undefined = ?config(testcase_3,Config), + testcase_5a = ?config(testcase_5a,Config), + ok. +testcase_5b() -> + []. +testcase_5b(Config) -> + init = ?config(suite,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + undefined = ?config(testcase_5a,Config), + testcase_5b = ?config(testcase_5b,Config), + ok. + +testcase_7a() -> + []. +testcase_7a(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_3,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + test_group_6 = ?config(test_group_6,Config), + test_group_7 = ?config(test_group_7,Config), + testcase_7a = ?config(testcase_7a,Config), + ok. +testcase_7b() -> + []. +testcase_7b(Config) -> + init = ?config(suite,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + test_group_6 = ?config(test_group_6,Config), + test_group_7 = ?config(test_group_7,Config), + undefined = ?config(testcase_7a,Config), + testcase_7b = ?config(testcase_7b,Config), + ok. diff --git a/lib/common_test/test/ct_testspec_1_SUITE_data/groups_2/groups_22_SUITE.erl b/lib/common_test/test/ct_testspec_1_SUITE_data/groups_2/groups_22_SUITE.erl new file mode 100644 index 0000000000..cd517876df --- /dev/null +++ b/lib/common_test/test/ct_testspec_1_SUITE_data/groups_2/groups_22_SUITE.erl @@ -0,0 +1,314 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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(groups_22_SUITE). + +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +%%==================================================================== +%% COMMON TEST CALLBACK FUNCTIONS +%%==================================================================== + +suite() -> + [{timetrap,{minutes,1}}]. + +groups() -> + [ + {test_group_1a, [shuffle], [testcase_1a,testcase_1b,testcase_1c]}, + + {test_group_1b, [parallel], [testcase_1a,testcase_1b]}, + + {test_group_2, [parallel], [testcase_2a, + + {test_group_3, [{repeat,1}], + [testcase_3a, testcase_3b]}, + + testcase_2b]}, + + {test_group_4, [{test_group_5, [parallel], [testcase_5a, + + {group, test_group_6}, + + testcase_5b]}]}, + + {test_group_6, [parallel], [{group, test_group_7}]}, + + {test_group_7, [sequence], [testcase_7a,testcase_7b]} + ]. + +all() -> + [{group, test_group_1a}, + {group, test_group_1b}, + testcase_1, + testcase_2, + {group, test_group_2}, + testcase_3, + {group, test_group_4}]. + +%% this func only for internal test purposes +grs_and_tcs() -> + {[ + test_group_1a, test_group_1b, + test_group_2, test_group_3, + test_group_4, test_group_5, + test_group_6, test_group_7 + ], + [ + testcase_1a, testcase_1b, testcase_1c, + testcase_1, + testcase_2, + testcase_2a, testcase_2b, + testcase_3a, testcase_3b, + testcase_3, + testcase_5a, testcase_5b, + testcase_7a, testcase_7b + ]}. + +%%-------------------------------------------------------------------- +%% Suite Configuration +%%-------------------------------------------------------------------- + +init_per_suite(Config) -> + [{suite,init}|Config]. + +end_per_suite(Config) -> + init = ?config(suite,Config). + +%%-------------------------------------------------------------------- +%% Group Configuration +%%-------------------------------------------------------------------- + +init_per_group(Group, Config) -> + Cmt = + case {Group,?config(tc_group_properties,Config)} of + {test_group_1a,[{shuffle,S},{name,test_group_1a}]} -> + io_lib:format("shuffled, ~w", [S]); + {test_group_1b,[{name,test_group_1b},parallel]} -> "parallel"; + {test_group_2,[{name,test_group_2},parallel]} -> "parallel"; + {test_group_3,[{name,test_group_3},{repeat,1}]} -> "repeat 1"; + {test_group_3,[{name,test_group_3}]} -> "repeat 0"; + {test_group_4,[{name,test_group_4}]} -> ok; + {test_group_5,[{name,test_group_5},parallel]} -> "parallel"; + {test_group_6,[{name,test_group_6},parallel]} -> "parallel"; + {test_group_7,[{name,test_group_7},sequence]} -> "sequence" + end, + {Grs,_} = grs_and_tcs(), + case lists:member(Group, Grs) of + true -> + init = ?config(suite,Config), + ct:comment(io_lib:format("~w, ~s", [Group,Cmt])), + [{Group,Group} | Config]; + false -> + ct:fail({bad_group,Group}) + end. + +end_per_group(Group, Config) -> + {Grs,_} = grs_and_tcs(), + case lists:member(Group, Grs) of + true -> + init = ?config(suite,Config), + Group = ?config(Group,Config), + ok; + false -> + ct:fail({bad_group,Group}) + end. + +%%-------------------------------------------------------------------- +%% Testcase Configuration +%%-------------------------------------------------------------------- + +init_per_testcase(TestCase, Config) -> + {_,TCs} = grs_and_tcs(), + case lists:member(TestCase, TCs) of + true -> + init = ?config(suite,Config), + [{TestCase,TestCase} | Config]; + false -> + ct:fail({unknown_testcase,TestCase}) + end. + +end_per_testcase(TestCase, Config) -> + {_,TCs} = grs_and_tcs(), + case lists:member(TestCase, TCs) of + true -> + init = ?config(suite,Config), + TestCase = ?config(TestCase,Config), + ok; + false -> + ct:fail({unknown_testcase,TestCase}) + end. + + +%%-------------------------------------------------------------------- +%% Testcases +%%-------------------------------------------------------------------- + +testcase_1a() -> + []. +testcase_1a(Config) -> + init = ?config(suite,Config), + case ?config(test_group_1a,Config) of + test_group_1a -> ok; + _ -> + case ?config(test_group_1b,Config) of + test_group_1b -> ok; + _ -> ct:fail(no_group_data) + end + end, + testcase_1a = ?config(testcase_1a,Config), + ok. +testcase_1b() -> + []. +testcase_1b(Config) -> + init = ?config(suite,Config), + case ?config(test_group_1a,Config) of + test_group_1a -> ok; + _ -> + case ?config(test_group_1b,Config) of + test_group_1b -> ok; + _ -> ct:fail(no_group_data) + end + end, + undefined = ?config(testcase_1a,Config), + testcase_1b = ?config(testcase_1b,Config), + ok. + +testcase_1c() -> + []. +testcase_1c(Config) -> + init = ?config(suite,Config), + case ?config(test_group_1a,Config) of + test_group_1a -> ok; + _ -> + case ?config(test_group_1b,Config) of + test_group_1b -> ok; + _ -> ct:fail(no_group_data) + end + end, + undefined = ?config(testcase_1b,Config), + testcase_1c = ?config(testcase_1c,Config), + ok. + +testcase_1() -> + []. +testcase_1(Config) -> + init = ?config(suite,Config), + testcase_1 = ?config(testcase_1,Config), + ok. + +testcase_2() -> + []. +testcase_2(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_1a,Config), + undefined = ?config(test_group_1b,Config), + testcase_2 = ?config(testcase_2,Config), + ok. + +testcase_2a() -> + []. +testcase_2a(Config) -> + init = ?config(suite,Config), + test_group_2 = ?config(test_group_2,Config), + testcase_2a = ?config(testcase_2a,Config), + ok. +testcase_2b() -> + []. +testcase_2b(Config) -> + init = ?config(suite,Config), + test_group_2 = ?config(test_group_2,Config), + undefined = ?config(testcase_2a,Config), + testcase_2b = ?config(testcase_2b,Config), + ok. + +testcase_3a() -> + []. +testcase_3a(Config) -> + init = ?config(suite,Config), + test_group_2 = ?config(test_group_2,Config), + test_group_3 = ?config(test_group_3,Config), + undefined = ?config(testcase_2b,Config), + testcase_3a = ?config(testcase_3a,Config), + ok. +testcase_3b() -> + []. +testcase_3b(Config) -> + init = ?config(suite,Config), + test_group_2 = ?config(test_group_2,Config), + test_group_3 = ?config(test_group_3,Config), + undefined = ?config(testcase_3a,Config), + testcase_3b = ?config(testcase_3b,Config), + ok. + +testcase_3() -> + []. +testcase_3(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_2,Config), + undefined = ?config(test_group_3,Config), + testcase_3 = ?config(testcase_3,Config), + ok. + +testcase_5a() -> + []. +testcase_5a(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_3,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + undefined = ?config(testcase_3,Config), + testcase_5a = ?config(testcase_5a,Config), + %% increase chance the done event will come + %% during execution of subgroup (could be + %% tricky to handle) + timer:sleep(3), + ok. +testcase_5b() -> + []. +testcase_5b(Config) -> + init = ?config(suite,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + undefined = ?config(testcase_5a,Config), + testcase_5b = ?config(testcase_5b,Config), + ok. + +testcase_7a() -> + []. +testcase_7a(Config) -> + init = ?config(suite,Config), + undefined = ?config(test_group_3,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + test_group_6 = ?config(test_group_6,Config), + test_group_7 = ?config(test_group_7,Config), + testcase_7a = ?config(testcase_7a,Config), + ok. +testcase_7b() -> + []. +testcase_7b(Config) -> + init = ?config(suite,Config), + test_group_4 = ?config(test_group_4,Config), + test_group_5 = ?config(test_group_5,Config), + test_group_6 = ?config(test_group_6,Config), + test_group_7 = ?config(test_group_7,Config), + undefined = ?config(testcase_7a,Config), + testcase_7b = ?config(testcase_7b,Config), + ok. diff --git a/lib/common_test/test/ct_testspec_1_SUITE_data/suites_1/simple_1_SUITE.erl b/lib/common_test/test/ct_testspec_1_SUITE_data/suites_1/simple_1_SUITE.erl new file mode 100644 index 0000000000..b789851134 --- /dev/null +++ b/lib/common_test/test/ct_testspec_1_SUITE_data/suites_1/simple_1_SUITE.erl @@ -0,0 +1,146 @@ +%% +%% %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% +%% + +-module(simple_1_SUITE). + +%% Note: This directive should only be used in test suites. +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +%%-------------------------------------------------------------------- +%% COMMON TEST CALLBACK FUNCTIONS +%%-------------------------------------------------------------------- + +%%-------------------------------------------------------------------- +%% Function: suite() -> Info +%% +%% Info = [tuple()] +%% List of key/value pairs. +%% +%% Description: Returns list of tuples to set default properties +%% for the suite. +%% +%% Note: The suite/0 function is only meant to be used to return +%% default data values, not perform any other operations. +%%-------------------------------------------------------------------- +suite() -> + [ + {timetrap,{seconds,10}} + ]. + +%%-------------------------------------------------------------------- +%% Function: init_per_suite(Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% +%% Config0 = Config1 = [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Reason = term() +%% The reason for skipping the suite. +%% +%% Description: Initialization before the suite. +%% +%% Note: This function is free to add any key/value pairs to the Config +%% variable, but should NOT alter/remove any existing entries. +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + [{ips,ips_data} | Config]. + +%%-------------------------------------------------------------------- +%% Function: end_per_suite(Config0) -> void() | {save_config,Config1} +%% +%% Config0 = Config1 = [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% +%% Description: Cleanup after the suite. +%%-------------------------------------------------------------------- +end_per_suite(Config) -> + ips_data = ?config(ips, Config). + +%%-------------------------------------------------------------------- +%% Function: init_per_testcase(TestCase, Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% +%% TestCase = atom() +%% Name of the test case that is about to run. +%% Config0 = Config1 = [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Reason = term() +%% The reason for skipping the test case. +%% +%% Description: Initialization before each test case. +%% +%% Note: This function is free to add any key/value pairs to the Config +%% variable, but should NOT alter/remove any existing entries. +%%-------------------------------------------------------------------- +init_per_testcase(TestCase, Config) -> + [{TestCase,{TestCase,data}} | Config]. + +%%-------------------------------------------------------------------- +%% Function: end_per_testcase(TestCase, Config0) -> +%% void() | {save_config,Config1} +%% +%% TestCase = atom() +%% Name of the test case that is finished. +%% Config0 = Config1 = [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% +%% Description: Cleanup after each test case. +%%-------------------------------------------------------------------- +end_per_testcase(TestCase, Config) -> + {TestCase,data} = ?config(TestCase, Config). + +%%-------------------------------------------------------------------- +%% Function: all() -> TestCases | {skip,Reason} +%% +%% TestCases = [TestCase | {sequence,SeqName}] +%% TestCase = atom() +%% Name of a test case. +%% SeqName = atom() +%% Name of a test case sequence. +%% Reason = term() +%% The reason for skipping all test cases. +%% +%% Description: Returns the list of test cases that are to be executed. +%%-------------------------------------------------------------------- +all() -> + [tc1, + tc2]. + + +%%-------------------------------------------------------------------- +%% TEST CASES +%%-------------------------------------------------------------------- + +tc1() -> + [{userdata,{info, "This is a testcase"}}]. + +tc1(Config) -> + ips_data = ?config(ips, Config), + {tc1,data} = ?config(tc1, Config), + ok. + +tc2() -> + [{timetrap,5000}]. + +tc2(Config) -> + ips_data = ?config(ips, Config), + undefined = ?config(tc1, Config), + {tc2,data} = ?config(tc2, Config), + ok. diff --git a/lib/common_test/test/ct_testspec_1_SUITE_data/suites_1/simple_2_SUITE.erl b/lib/common_test/test/ct_testspec_1_SUITE_data/suites_1/simple_2_SUITE.erl new file mode 100644 index 0000000000..eb7e9cdf7b --- /dev/null +++ b/lib/common_test/test/ct_testspec_1_SUITE_data/suites_1/simple_2_SUITE.erl @@ -0,0 +1,146 @@ +%% +%% %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% +%% + +-module(simple_2_SUITE). + +%% Note: This directive should only be used in test suites. +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). + +%%-------------------------------------------------------------------- +%% COMMON TEST CALLBACK FUNCTIONS +%%-------------------------------------------------------------------- + +%%-------------------------------------------------------------------- +%% Function: suite() -> Info +%% +%% Info = [tuple()] +%% List of key/value pairs. +%% +%% Description: Returns list of tuples to set default properties +%% for the suite. +%% +%% Note: The suite/0 function is only meant to be used to return +%% default data values, not perform any other operations. +%%-------------------------------------------------------------------- +suite() -> + [ + {timetrap,{seconds,10}} + ]. + +%%-------------------------------------------------------------------- +%% Function: init_per_suite(Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% +%% Config0 = Config1 = [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Reason = term() +%% The reason for skipping the suite. +%% +%% Description: Initialization before the suite. +%% +%% Note: This function is free to add any key/value pairs to the Config +%% variable, but should NOT alter/remove any existing entries. +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + [{ips,ips_data} | Config]. + +%%-------------------------------------------------------------------- +%% Function: end_per_suite(Config0) -> void() | {save_config,Config1} +%% +%% Config0 = Config1 = [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% +%% Description: Cleanup after the suite. +%%-------------------------------------------------------------------- +end_per_suite(Config) -> + ips_data = ?config(ips, Config). + +%%-------------------------------------------------------------------- +%% Function: init_per_testcase(TestCase, Config0) -> +%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} +%% +%% TestCase = atom() +%% Name of the test case that is about to run. +%% Config0 = Config1 = [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Reason = term() +%% The reason for skipping the test case. +%% +%% Description: Initialization before each test case. +%% +%% Note: This function is free to add any key/value pairs to the Config +%% variable, but should NOT alter/remove any existing entries. +%%-------------------------------------------------------------------- +init_per_testcase(TestCase, Config) -> + [{TestCase,{TestCase,data}} | Config]. + +%%-------------------------------------------------------------------- +%% Function: end_per_testcase(TestCase, Config0) -> +%% void() | {save_config,Config1} +%% +%% TestCase = atom() +%% Name of the test case that is finished. +%% Config0 = Config1 = [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% +%% Description: Cleanup after each test case. +%%-------------------------------------------------------------------- +end_per_testcase(TestCase, Config) -> + {TestCase,data} = ?config(TestCase, Config). + +%%-------------------------------------------------------------------- +%% Function: all() -> TestCases | {skip,Reason} +%% +%% TestCases = [TestCase | {sequence,SeqName}] +%% TestCase = atom() +%% Name of a test case. +%% SeqName = atom() +%% Name of a test case sequence. +%% Reason = term() +%% The reason for skipping all test cases. +%% +%% Description: Returns the list of test cases that are to be executed. +%%-------------------------------------------------------------------- +all() -> + [tc1, + tc2]. + + +%%-------------------------------------------------------------------- +%% TEST CASES +%%-------------------------------------------------------------------- + +tc1() -> + [{userdata,{info, "This is a testcase"}}]. + +tc1(Config) -> + ips_data = ?config(ips, Config), + {tc1,data} = ?config(tc1, Config), + ok. + +tc2() -> + [{timetrap,5000}]. + +tc2(Config) -> + ips_data = ?config(ips, Config), + undefined = ?config(tc1, Config), + {tc2,data} = ?config(tc2, Config), + ok. diff --git a/lib/common_test/test/ct_userconfig_callback.erl b/lib/common_test/test/ct_userconfig_callback.erl new file mode 100644 index 0000000000..ca51bf240b --- /dev/null +++ b/lib/common_test/test/ct_userconfig_callback.erl @@ -0,0 +1,32 @@ +%%-------------------------------------------------------------------- +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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(ct_userconfig_callback). + +-export([check_parameter/1, read_config/1]). + +read_config(Str) -> + KeyVals = string:tokens(Str, " "), + {ok,read_config1(KeyVals)}. + +read_config1([Key,Val | KeyVals]) -> + [{list_to_atom(Key),Val} | read_config1(KeyVals)]; +read_config1([]) -> + []. + +check_parameter(Str) -> + {ok,{config,Str}}. diff --git a/lib/common_test/vsn.mk b/lib/common_test/vsn.mk index ee07350c55..413ef21df3 100644 --- a/lib/common_test/vsn.mk +++ b/lib/common_test/vsn.mk @@ -1,3 +1,3 @@ -COMMON_TEST_VSN = 1.4.7 +COMMON_TEST_VSN = 1.5.1 diff --git a/lib/compiler/doc/src/compile.xml b/lib/compiler/doc/src/compile.xml index bbd3f1043d..e1f24b602d 100644 --- a/lib/compiler/doc/src/compile.xml +++ b/lib/compiler/doc/src/compile.xml @@ -310,6 +310,23 @@ (there will not even be a warning if there is a mismatch).</p> </item> + <tag><c>{no_auto_import,[F/A, ...]}</c></tag> + <item> + <p>Makes the function <c>F/A</c> no longer beeing + auto-imported from the module <c>erlang</c>, which resolves + BIF name clashes. This option has to be used to resolve name + clashes with BIFs auto-imported before R14A, if one wants to + call the local function with the same name as an + auto-imported BIF without module prefix.</p> + <note> + <p>From R14A and forward, the compiler resolves calls + without module prefix to local or imported functions before + trying auto-imported BIFs. If the BIF is to be + called, use the <c>erlang</c> module prefix in the call, not + <c>{ no_auto_import,[F/A, ...]}</c></p> + </note> + </item> + </taglist> <p>If warnings are turned on (the <c>report_warnings</c> option @@ -338,31 +355,35 @@ <tag><c>nowarn_bif_clash</c></tag> <item> - <p>By default, there will be a compilation error if a - module contains an exported function with the same name - as an auto-imported BIF (such as <c>size/1</c>) AND - there is a call to it without a qualifying module name. - The reason is that the BIF will be called, not - the function in the same module. The recommended way to - eliminate that warning is to use a call with a module - name - either <c>erlang</c> to call the BIF or - <c>?MODULE</c> to call the function in the same module. - The warning can also be turned off using this option, - but that is not recommended.</p> + <p>This option is removed, it will generate a fatal error if used.</p> + + <warning> + <p>Beginning with R14A, the compiler no longer calls the + auto-imported BIF if the name clashes with a local or + explicitly imported function and a call without explicit + module name is issued. Instead the local or imported + function is called. Still accepting <c>nowarn_bif_clash</c> would makes a + module calling functions clashing with autoimported BIFs + compile with both the old and new compilers, but with + completely different semantics, why the option was removed.</p> - <p><em>The use of this option is strongly discouraged, - as code that uses it will probably break in a future - major release (R14 or R15).</em></p> + <p>The use of this option has always been strongly discouraged. + From OTP R14A and forward it's an error to use it.</p> + <p>To resolve BIF clashes, use explicit module names or the + <c>{no_auto_import,[F/A]}</c> compiler directive.</p> + </warning> </item> <tag><c>{nowarn_bif_clash, FAs}</c></tag> <item> - <p>Turns off warnings as <c>nowarn_bif_clash</c> but only - for the mentioned local functions. <c>FAs</c> is a tuple - <c>{Name,Arity}</c> or a list of such tuples.</p> - <p><em>The use of this option is strongly discouraged, - as code that uses it will probably break in a future - major release (R14 or R15).</em></p> + <p>This option is removed, it will generate a fatal error if used.</p> + + <warning> + <p>The use of this option has always been strongly discouraged. + From OTP R14A and forward it's an error to use it.</p> + <p>To resolve BIF clashes, use explicit module names or the + <c>{no_auto_import,[F/A]}</c> compiler directive.</p> + </warning> </item> <tag><c>warn_export_all</c></tag> diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml index 7ea000a895..00ea0da55c 100644 --- a/lib/compiler/doc/src/notes.xml +++ b/lib/compiler/doc/src/notes.xml @@ -31,6 +31,121 @@ <p>This document describes the changes made to the Compiler application.</p> +<section><title>Compiler 4.7.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Eliminated warnings for auto-imported BIF clashes.</p> + <p> + Own Id: OTP-8840</p> + </item> + </list> + </section> + +</section> + +<section><title>Compiler 4.7</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Several problems in the inliner have been fixed.</p> + <p> + Own Id: OTP-8552</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The module binary from EEP31 (and EEP9) is implemented.</p> + <p> + Own Id: OTP-8217</p> + </item> + <item> + <p>Local and imported functions now override the + auto-imported BIFs when the names clash. The pre R14 + behaviour was that auto-imported BIFs would override + local functions. To avoid that old programs change + behaviour, the following will generate an error:</p> + <list><item><p>Doing a call without explicit module name + to a local function having a name clashing with the name + of an auto-imported BIF that was present (and + auto-imported) before OTP R14A</p></item> + <item><p>Explicitly importing a function having a name + clashing with the name of an autoimported BIF that was + present (and autoimported) before OTP R14A</p></item> + <item><p>Using any form of the old compiler directive + <c>nowarn_bif_clash</c></p></item> </list> <p>If the BIF + was added or auto-imported in OTP R14A or later, + overriding it with an import or a local function will + only result in a warning,</p> <p>To resolve clashes, you + can either use the explicit module name <c>erlang</c> to + call the BIF, or you can remove the auto-import of that + specific BIF by using the new compiler directive + <c>-compile({no_auto_import,[F/A]}).</c>, which makes all + calls to the local or imported function without explicit + module name pass without warnings or errors.</p> <p>The + change makes it possible to add auto-imported BIFs + without breaking or silently changing old code in the + future. However some current code ingeniously utilizing + the old behaviour or the <c>nowarn_bif_clash</c> compiler + directive, might need changing to be accepted by the + compiler.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-8579</p> + </item> + <item> + <p>The undocumented, unsupport, and deprecated function + <c>lists:flat_length/1</c> has been removed.</p> + <p> + Own Id: OTP-8584</p> + </item> + <item> + <p>Nested records can now be accessed without + parenthesis. See the Reference Manual for examples. + (Thanks to YAMASHINA Hio and Tuncer Ayaz.)</p> + <p> + Own Id: OTP-8597</p> + </item> + <item> + <p>It is now possible to suppress the warning in code + such as "<c>list_to_integer(S), ok</c>" by assigning the + ignored value "_" like this: "<c>_ = list_to_integer(S), + ok</c>".</p> + <p> + Own Id: OTP-8602</p> + </item> + <item> + <p><c>receive</c> statements that can only read out a + newly created reference are now specially optimized so + that it will execute in constant time regardless of the + number of messages in the receive queue for the process. + That optimization will benefit calls to + <c>gen_server:call()</c>. (See <c>gen:do_call/4</c> for + an example of a receive statement that will be + optimized.)</p> + <p> + Own Id: OTP-8623</p> + </item> + <item> + <p>The compiler optimizes record operations better.</p> + <p> + Own Id: OTP-8668</p> + </item> + </list> + </section> + +</section> + <section><title>Compiler 4.6.5</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/compiler/src/Makefile b/lib/compiler/src/Makefile index 70ddd54145..0f6d2f6193 100644 --- a/lib/compiler/src/Makefile +++ b/lib/compiler/src/Makefile @@ -58,6 +58,7 @@ MODULES = \ beam_listing \ beam_opcodes \ beam_peep \ + beam_receive \ beam_trim \ beam_type \ beam_utils \ diff --git a/lib/compiler/src/beam_asm.erl b/lib/compiler/src/beam_asm.erl index 497c4fa07b..89d64834cf 100644 --- a/lib/compiler/src/beam_asm.erl +++ b/lib/compiler/src/beam_asm.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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% %% %% Purpose : Assembler for threaded Beam. @@ -23,7 +23,7 @@ -export([module/4]). -export([encode/2]). --import(lists, [map/2,member/2,keymember/3,duplicate/2,filter/2]). +-import(lists, [map/2,member/2,keymember/3,duplicate/2]). -include("beam_opcodes.hrl"). module(Code, Abst, SourceFile, Opts) -> @@ -191,11 +191,7 @@ flatten_exports(Exps) -> flatten_imports(Imps) -> list_to_binary(map(fun({M,F,A}) -> <<M:32,F:32,A:32>> end, Imps)). -build_attributes(Opts, SourceFile, Attr0, Essentials) -> - Attr = filter(fun({type,_}) -> false; - ({spec,_}) -> false; - (_) -> true - end, Attr0), +build_attributes(Opts, SourceFile, Attr, Essentials) -> Misc = case member(slim, Opts) of false -> {{Y,Mo,D},{H,Mi,S}} = erlang:universaltime(), @@ -265,7 +261,8 @@ make_op({gc_bif,Bif,Fail,Live,Args,Dest}, Dict) -> Arity = length(Args), BifOp = case Arity of 1 -> gc_bif1; - 2 -> gc_bif2 + 2 -> gc_bif2; + 3 -> gc_bif3 end, encode_op(BifOp, [Fail,Live,{extfunc,erlang,Bif,Arity}|Args++[Dest]],Dict); make_op({bs_add=Op,Fail,[Src1,Src2,Unit],Dest}, Dict) -> diff --git a/lib/compiler/src/beam_block.erl b/lib/compiler/src/beam_block.erl index d4a4ddca8a..9c6f835ab0 100644 --- a/lib/compiler/src/beam_block.erl +++ b/lib/compiler/src/beam_block.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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% %% %% Purpose : Partitions assembly instructions into basic blocks and @@ -140,7 +140,6 @@ collect({move,S,D}) -> {set,[D],[S],move}; collect({put_list,S1,S2,D}) -> {set,[D],[S1,S2],put_list}; collect({put_tuple,A,D}) -> {set,[D],[],{put_tuple,A}}; collect({put,S}) -> {set,[],[S],put}; -collect({put_string,L,S,D}) -> {set,[D],[],{put_string,L,S}}; collect({get_tuple_element,S,I,D}) -> {set,[D],[S],{get_tuple_element,I}}; collect({set_tuple_element,S,D,I}) -> {set,[],[S,D],{set_tuple_element,I}}; collect({get_list,S,D1,D2}) -> {set,[D1,D2],[S],get_list}; @@ -202,9 +201,7 @@ move_allocates_2(Alloc, [], Acc) -> alloc_may_pass({set,_,_,{alloc,_,_}}) -> false; alloc_may_pass({set,_,_,{set_tuple_element,_}}) -> false; alloc_may_pass({set,_,_,put_list}) -> false; -alloc_may_pass({set,_,_,{put_tuple,_}}) -> false; alloc_may_pass({set,_,_,put}) -> false; -alloc_may_pass({set,_,_,{put_string,_,_}}) -> false; alloc_may_pass({set,_,_,_}) -> true. combine_alloc({_,Ns,Nh1,Init}, {_,nostack,Nh2,[]}) -> diff --git a/lib/compiler/src/beam_bool.erl b/lib/compiler/src/beam_bool.erl index dcc6ad4c7c..d9ea6f5a70 100644 --- a/lib/compiler/src/beam_bool.erl +++ b/lib/compiler/src/beam_bool.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% 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% %% %% Purpose: Optimizes booleans in guards. @@ -631,10 +631,10 @@ fetch_reg(V, [{I,V}|_]) -> {x,I}; fetch_reg(V, [_|SRs]) -> fetch_reg(V, SRs). live_regs(Regs) -> - foldl(fun ({I,_}, _) -> I; - ([], Max) -> Max end, - -1, Regs)+1. - + foldl(fun ({I,_}, _) -> + I + end, -1, Regs)+1. + %%% %%% Convert a block to Static Single Assignment (SSA) form. @@ -748,8 +748,7 @@ initialized_regs([{bs_context_to_binary,Src}|Is], Regs) -> initialized_regs([{label,_},{func_info,_,_,Arity}|_], Regs) -> InitRegs = free_vars_regs(Arity), add_init_regs(InitRegs, Regs); -initialized_regs([_|_], Regs) -> Regs; -initialized_regs([], Regs) -> Regs. +initialized_regs([_|_], Regs) -> Regs. add_init_regs([{x,_}=X|T], Regs) -> add_init_regs(T, ordsets:add_element(X, Regs)); diff --git a/lib/compiler/src/beam_dead.erl b/lib/compiler/src/beam_dead.erl index 7b4cd814a2..bb93110176 100644 --- a/lib/compiler/src/beam_dead.erl +++ b/lib/compiler/src/beam_dead.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -281,12 +281,12 @@ forward([{test,is_eq_exact,_,[Dst,Src]}=I,{move,Src,Dst}|Is], D, Lc, Acc) -> forward([I|Is], D, Lc, Acc); forward([{test,is_nil,_,[Dst]}=I,{move,nil,Dst}|Is], D, Lc, Acc) -> forward([I|Is], D, Lc, Acc); -forward([{test,is_eq_exact,_,[_,{atom,_}]}=I|Is], D, Lc, [{label,_}|_]=Acc) -> +forward([{test,is_eq_exact,_,_}=I|Is], D, Lc, Acc) -> case Is of [{label,_}|_] -> forward(Is, D, Lc, [I|Acc]); _ -> forward(Is, D, Lc+1, [{label,Lc},I|Acc]) end; -forward([{test,is_ne_exact,_,[_,{atom,_}]}=I|Is], D, Lc, [{label,_}|_]=Acc) -> +forward([{test,is_ne_exact,_,_}=I|Is], D, Lc, Acc) -> case Is of [{label,_}|_] -> forward(Is, D, Lc, [I|Acc]); _ -> forward(Is, D, Lc+1, [{label,Lc},I|Acc]) @@ -371,10 +371,10 @@ backward([{test,bs_start_match2,{f,To0},Live,[Src|_]=Info,Dst}|Is], D, Acc) -> To = shortcut_bs_start_match(To0, Src, D), I = {test,bs_start_match2,{f,To},Live,Info,Dst}, backward(Is, D, [I|Acc]); -backward([{test,is_eq_exact=Op,{f,To0},[Reg,{atom,Val}]=Ops}|Is], D, Acc) -> +backward([{test,is_eq_exact,{f,To0},[Reg,{atom,Val}]=Ops}|Is], D, Acc) -> To1 = shortcut_bs_test(To0, Is, D), To = shortcut_fail_label(To1, Reg, Val, D), - I = {test,Op,{f,To},Ops}, + I = combine_eqs(To, Ops, D, Acc), backward(Is, D, [I|Acc]); backward([{test,Op,{f,To0},Ops0}|Is], D, Acc) -> To1 = shortcut_bs_test(To0, Is, D), @@ -394,7 +394,10 @@ backward([{test,Op,{f,To0},Ops0}|Is], D, Acc) -> _Code -> To2 end, - I = {test,Op,{f,To},Ops0}, + I = case Op of + is_eq_exact -> combine_eqs(To, Ops0, D, Acc); + _ -> {test,Op,{f,To},Ops0} + end, backward(Is, D, [I|Acc]); backward([{test,Op,{f,To0},Live,Ops0,Dst}|Is], D, Acc) -> To1 = shortcut_bs_test(To0, Is, D), @@ -519,6 +522,41 @@ bif_to_test(Name, Args, Fail) -> not_possible() -> throw(not_possible). +%% combine_eqs(To, Operands, Acc) -> Instruction. +%% Combine two is_eq_exact instructions or (an is_eq_exact +%% instruction and a select_val instruction) to a select_val +%% instruction if possible. +%% +%% Example: +%% +%% is_eq_exact F1 Reg Lit1 select_val Reg F2 [ Lit1 L1 +%% L1: . Lit2 L2 ] +%% . +%% . ==> +%% . +%% F1: is_eq_exact F2 Reg Lit2 F1: is_eq_exact F2 Reg Lit2 +%% L2: .... L2: +%% +combine_eqs(To, [Reg,{Type,_}=Lit1]=Ops, D, [{label,L1}|_]) + when Type =:= atom; Type =:= integer -> + case beam_utils:code_at(To, D) of + [{test,is_eq_exact,{f,F2},[Reg,{Type,_}=Lit2]}, + {label,L2}|_] when Lit1 =/= Lit2 -> + {select_val,Reg,{f,F2},{list,[Lit1,{f,L1},Lit2,{f,L2}]}}; + [{select_val,Reg,{f,F2},{list,[{Type,_}|_]=List0}}|_] -> + List = remove_from_list(Lit1, List0), + {select_val,Reg,{f,F2},{list,[Lit1,{f,L1}|List]}}; + _Is -> + {test,is_eq_exact,{f,To},Ops} + end; +combine_eqs(To, Ops, _D, _Acc) -> + {test,is_eq_exact,{f,To},Ops}. + +remove_from_list(Lit, [Lit,{f,_}|T]) -> + T; +remove_from_list(Lit, [Val,{f,_}=Fail|T]) -> + [Val,Fail|remove_from_list(Lit, T)]; +remove_from_list(_, []) -> []. %% shortcut_bs_test(TargetLabel, [Instruction], D) -> TargetLabel' %% Try to shortcut the failure label for a bit syntax matching. diff --git a/lib/compiler/src/beam_dict.erl b/lib/compiler/src/beam_dict.erl index 4ffe8bc606..a1f994dfbd 100644 --- a/lib/compiler/src/beam_dict.erl +++ b/lib/compiler/src/beam_dict.erl @@ -33,7 +33,7 @@ exports = [] :: [{label(), arity(), label()}], locals = [] :: [{label(), arity(), label()}], imports = gb_trees:empty() :: gb_tree(), %{{M,F,A},Index} - strings = [] :: [string()], %String pool + strings = <<>> :: binary(), %String pool lambdas = [], %[{...}] literals = dict:new() :: dict(), %Format: {Literal,Number} next_atom = 1 :: pos_integer(), @@ -119,10 +119,11 @@ import(Mod0, Name0, Arity, #asm{imports=Imp0,next_import=NextIndex}=D0) string(Str, Dict) when is_list(Str) -> #asm{strings=Strings,string_offset=NextOffset} = Dict, - case old_string(Str, Strings) of + StrBin = list_to_binary(Str), + case old_string(StrBin, Strings) of none -> - NewDict = Dict#asm{strings=Strings++Str, - string_offset=NextOffset+length(Str)}, + NewDict = Dict#asm{strings = <<Strings/binary,StrBin/binary>>, + string_offset=NextOffset+byte_size(StrBin)}, {NextOffset,NewDict}; Offset when is_integer(Offset) -> {NextOffset-Offset,Dict} @@ -187,7 +188,7 @@ import_table(#asm{imports=Imp,next_import=NumImports}) -> ImpTab = [MFA || {MFA,_} <- Sorted], {NumImports,ImpTab}. --spec string_table(bdict()) -> {non_neg_integer(), [string()]}. +-spec string_table(bdict()) -> {non_neg_integer(), binary()}. string_table(#asm{strings=Strings,string_offset=Size}) -> {Size,Strings}. @@ -217,15 +218,12 @@ literal_table(#asm{literals=Tab,next_literal=NumLiterals}) -> my_term_to_binary(Term) -> term_to_binary(Term, [{minor_version,1}]). -%% Search for string Str in the string pool Pool. +%% Search for binary string Str in the binary string pool Pool. %% old_string(Str, Pool) -> none | Index --spec old_string(string(), [string()]) -> 'none' | pos_integer(). - -old_string([C|Str]=Str0, [C|Pool]) -> - case lists:prefix(Str, Pool) of - true -> length(Pool)+1; - false -> old_string(Str0, Pool) - end; -old_string([_|_]=Str, [_|Pool]) -> - old_string(Str, Pool); -old_string([_|_], []) -> none. +-spec old_string(binary(), binary()) -> 'none' | pos_integer(). + +old_string(Str, Pool) -> + case binary:match(Pool, Str) of + nomatch -> none; + {Start,_Length} -> byte_size(Pool) - Start + end. diff --git a/lib/compiler/src/beam_disasm.erl b/lib/compiler/src/beam_disasm.erl index c956f2f000..017ca129b0 100644 --- a/lib/compiler/src/beam_disasm.erl +++ b/lib/compiler/src/beam_disasm.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %%======================================================================= %% Notes: @@ -621,8 +621,7 @@ resolve_names(Fun, Imports, Str, Lbls, Lambdas, Literals, M) -> %% %% New make_fun2/4 instruction added in August 2001 (R8). -%% New put_literal/2 instruction added in Feb 2006 R11B-4. -%% We handle them specially here to avoid adding an argument to +%% We handle it specially here to avoid adding an argument to %% the clause for every instruction. %% @@ -631,8 +630,6 @@ resolve_inst({make_fun2,Args}, _, _, _, Lambdas, _, M) -> {OldIndex,{F,A,_Lbl,_Index,NumFree,OldUniq}} = lists:keyfind(OldIndex, 1, Lambdas), {make_fun2,{M,F,A},OldIndex,OldUniq,NumFree}; -resolve_inst({put_literal,[{u,Index},Dst]},_,_,_,_,Literals,_) -> - {put_literal,{literal,gb_trees:get(Index, Literals)},Dst}; resolve_inst(Instr, Imports, Str, Lbls, _Lambdas, _Literals, _M) -> %% io:format(?MODULE_STRING":resolve_inst ~p.~n", [Instr]), resolve_inst(Instr, Imports, Str, Lbls). @@ -1004,13 +1001,17 @@ resolve_inst({gc_bif2,Args},Imports,_,_) -> [F,Live,Bif,A1,A2,Reg] = resolve_args(Args), {extfunc,_Mod,BifName,_Arity} = lookup(Bif+1,Imports), {gc_bif,BifName,F,Live,[A1,A2],Reg}; +%% +%% New instruction in R14, gc_bif with 3 arguments +%% +resolve_inst({gc_bif3,Args},Imports,_,_) -> + [F,Live,Bif,A1,A2,A3,Reg] = resolve_args(Args), + {extfunc,_Mod,BifName,_Arity} = lookup(Bif+1,Imports), + {gc_bif,BifName,F,Live,[A1,A2,A3],Reg}; %% %% New instructions for creating non-byte aligned binaries. %% -resolve_inst({bs_bits_to_bytes2,[_Arg2,_Arg3]=Args},_,_,_) -> - [A2,A3] = resolve_args(Args), - {bs_bits_to_bytes2,A2,A3}; resolve_inst({bs_final2,[X,Y]},_,_,_) -> {bs_final2,X,Y}; @@ -1096,6 +1097,14 @@ resolve_inst({on_load,[]},_,_,_) -> on_load; %% +%% R14A. +%% +resolve_inst({recv_mark,[Lbl]},_,_,_) -> + {recv_mark,Lbl}; +resolve_inst({recv_set,[Lbl]},_,_,_) -> + {recv_set,Lbl}; + +%% %% Catches instructions that are not yet handled. %% resolve_inst(X,_,_,_) -> ?exit({resolve_inst,X}). diff --git a/lib/compiler/src/beam_flatten.erl b/lib/compiler/src/beam_flatten.erl index d9de7e2495..6c7cb849aa 100644 --- a/lib/compiler/src/beam_flatten.erl +++ b/lib/compiler/src/beam_flatten.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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% %% %% Purpose : Converts intermediate assembly code to final format. @@ -57,7 +57,6 @@ norm({set,[D],[S],fconv}) -> {fconv,S,D}; norm({set,[D],[S1,S2],put_list}) -> {put_list,S1,S2,D}; norm({set,[D],[],{put_tuple,A}}) -> {put_tuple,A,D}; norm({set,[],[S],put}) -> {put,S}; -norm({set,[D],[],{put_string,L,S}}) -> {put_string,L,S,D}; norm({set,[D],[S],{get_tuple_element,I}}) -> {get_tuple_element,S,I,D}; norm({set,[],[S,D],{set_tuple_element,I}}) -> {set_tuple_element,S,D,I}; norm({set,[D1,D2],[S],get_list}) -> {get_list,S,D1,D2}; diff --git a/lib/compiler/src/beam_jump.erl b/lib/compiler/src/beam_jump.erl index 739928f411..3cab55c4cb 100644 --- a/lib/compiler/src/beam_jump.erl +++ b/lib/compiler/src/beam_jump.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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% %% %%% Purpose : Optimise jumps and remove unreachable code. @@ -452,7 +452,6 @@ is_label_used_in_2({set,_,_,Info}, Lbl) -> {'catch',{f,F}} -> F =:= Lbl; {alloc,_,_} -> false; {put_tuple,_} -> false; - {put_string,_,_} -> false; {get_tuple_element,_} -> false; {set_tuple_element,_} -> false; _ when is_atom(Info) -> false diff --git a/lib/compiler/src/beam_peep.erl b/lib/compiler/src/beam_peep.erl index d03ac4b1f4..f39fc50b95 100644 --- a/lib/compiler/src/beam_peep.erl +++ b/lib/compiler/src/beam_peep.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -64,22 +64,7 @@ function({function,Name,Arity,CLabel,Is0}) -> %% InEncoding =:= latin1, OutEncoding =:= unicode; %% InEncoding =:= latin1, OutEncoding =:= utf8 -> %% -%% (2) Code like -%% -%% is_ne_exact Fail Reg Literal1 -%% is_ne_exact Fail Reg Literal2 -%% is_ne_exact Fail Reg Literal3 -%% is_eq_exact UltimateFail Reg Literal4 -%% Fail: .... -%% -%% can be rewritten to -%% -%% select_val Reg UltimateFail [ Literal1 Fail -%% Literal2 Fail -%% Literal3 Fail -%% Literal4 Fail ] -%% -%% (3) A select_val/4 instruction that only verifies that +%% (2) A select_val/4 instruction that only verifies that %% its argument is either 'true' or 'false' can be %% be replaced with an is_boolean/2 instruction. That is: %% @@ -132,7 +117,7 @@ peep([{test,Op,_,Ops}=I|Is], SeenTests0, Acc) -> false -> %% Remember that we have seen this test. SeenTests = gb_sets:insert(Test, SeenTests0), - make_select_val(I, Is, SeenTests, Acc) + peep(Is, SeenTests, [I|Acc]) end end; peep([{select_val,Src,Fail, @@ -151,33 +136,6 @@ peep([I|Is], _, Acc) -> peep(Is, gb_sets:empty(), [I|Acc]); peep([], _, Acc) -> reverse(Acc). -make_select_val({test,is_ne_exact,{f,Fail},[Val,Lit]}=I0, - Is0, SeenTests, Acc) -> - try - Type = case Lit of - {atom,_} -> atom; - {integer,_} -> integer; - _ -> throw(impossible) - end, - {I,Is} = make_select_val_1(Is0, Fail, Val, Type, [Lit,{f,Fail}]), - peep([I|Is], SeenTests, Acc) - catch - impossible -> - peep(Is0, SeenTests, [I0|Acc]) - end; -make_select_val(I, Is, SeenTests, Acc) -> - peep(Is, SeenTests, [I|Acc]). - -make_select_val_1([{test,is_ne_exact,{f,Fail},[Val,{Type,_}=Lit]}|Is], - Fail, Val, Type, Acc) -> - make_select_val_1(Is, Fail, Val, Type, [Lit,{f,Fail}|Acc]); -make_select_val_1([{test,is_eq_exact,{f,UltimateFail},[Val,{Type,_}=Lit]} | - [{label,Fail}|_]=Is], Fail, Val, Type, Acc) -> - Choices = [Lit,{f,Fail}|Acc], - I = {select_val,Val,{f,UltimateFail},{list,Choices}}, - {I,Is}; -make_select_val_1(_Is, _Fail, _Val, _Type, _Acc) -> throw(impossible). - kill_seen(Dst, Seen0) -> gb_sets:from_ordset(kill_seen_1(gb_sets:to_list(Seen0), Dst)). @@ -187,5 +145,3 @@ kill_seen_1([{_,Ops}=Test|T], Dst) -> false -> [Test|kill_seen_1(T, Dst)] end; kill_seen_1([], _) -> []. - - diff --git a/lib/compiler/src/beam_receive.erl b/lib/compiler/src/beam_receive.erl new file mode 100644 index 0000000000..9ed44ad5d7 --- /dev/null +++ b/lib/compiler/src/beam_receive.erl @@ -0,0 +1,388 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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(beam_receive). +-export([module/2]). +-import(lists, [foldl/3,reverse/1,reverse/2]). + +%%% +%%% In code such as: +%%% +%%% Ref = make_ref(), %Or erlang:monitor(process, Pid) +%%% . +%%% . +%%% . +%%% receive +%%% {Ref,Reply} -> Reply +%%% end. +%%% +%%% we know that none of the messages that exist in the message queue +%%% before the call to make_ref/0 can be matched out in the receive +%%% statement. Therefore we can avoid going through the entire message +%%% queue if we introduce two new instructions (here written as +%%% BIFs in pseudo-Erlang): +%%% +%%% recv_mark(SomeUniqInteger), +%%% Ref = make_ref(), +%%% . +%%% . +%%% . +%%% recv_set(SomeUniqInteger), +%%% receive +%%% {Ref,Reply} -> Reply +%%% end. +%%% +%%% The recv_mark/1 instruction will save the current position and +%%% SomeUniqInteger in the process context. The recv_set +%%% instruction will verify that SomeUniqInteger is still stored +%%% in the process context. If it is, it will set the current pointer +%%% for the message queue (the next message to be read out) to the +%%% position that was saved by recv_mark/1. +%%% +%%% The remove_message instruction must be modified to invalidate +%%% the information stored by the previous recv_mark/1, in case there +%%% is another receive executed between the calls to recv_mark/1 and +%%% recv_set/1. +%%% +%%% We use a reference to a label (i.e. a position in the loaded code) +%%% as the SomeUniqInteger. +%%% + +module({Mod,Exp,Attr,Fs0,Lc}, _Opts) -> + Fs = [function(F) || F <- Fs0], + Code = {Mod,Exp,Attr,Fs,Lc}, + {ok,Code}. + +%%% +%%% Local functions. +%%% + +function({function,Name,Arity,Entry,Is}) -> + try + D = beam_utils:index_labels(Is), + {function,Name,Arity,Entry,opt(Is, D, [])} + catch + Class:Error -> + Stack = erlang:get_stacktrace(), + io:fwrite("Function: ~w/~w\n", [Name,Arity]), + erlang:raise(Class, Error, Stack) + end. + +opt([{call_ext,Arity,{extfunc,erlang,Name,Arity}}=I|Is0], D, Acc) -> + case creates_new_ref(Name, Arity) of + true -> + %% The call creates a brand new reference. Now + %% search for a receive statement in the same + %% function that will match against the reference. + case opt_recv(Is0, D) of + no -> + opt(Is0, D, [I|Acc]); + {yes,Is,Lbl} -> + opt(Is, D, [I,{recv_mark,{f,Lbl}}|Acc]) + end; + false -> + opt(Is0, D, [I|Acc]) + end; +opt([I|Is], D, Acc) -> + opt(Is, D, [I|Acc]); +opt([], _, Acc) -> + reverse(Acc). + +%% creates_new_ref(Name, Arity) -> true|false. +%% Return 'true' if the BIF Name/Arity will create a new reference. +creates_new_ref(monitor, 2) -> true; +creates_new_ref(make_ref, 0) -> true; +creates_new_ref(_, _) -> false. + +%% opt_recv([Instruction], LabelIndex) -> no|{yes,[Instruction]} +%% Search for a receive statement that will only retrieve messages +%% that contain the newly created reference (which is currently in {x,0}). +opt_recv(Is, D) -> + R = regs_init_x0(), + L = gb_sets:empty(), + opt_recv(Is, D, R, L, []). + +opt_recv([{label,L}=Lbl,{loop_rec,{f,Fail},_}=Loop|Is], D, R0, _, Acc) -> + R = regs_kill_not_live(0, R0), + case regs_to_list(R) of + [{y,_}=RefReg] -> + %% We now have the new reference in the Y register RefReg + %% and the current instruction is the beginning of a + %% receive statement. We must now verify that only messages + %% that contain the reference will be matched. + case opt_ref_used(Is, RefReg, Fail, D) of + false -> + no; + true -> + RecvSet = {recv_set,{f,L}}, + {yes,reverse(Acc, [RecvSet,Lbl,Loop|Is]),L} + end; + [] -> + no + end; +opt_recv([I|Is], D, R0, L0, Acc) -> + {R,L} = opt_update_regs(I, R0, L0), + case regs_empty(R) of + true -> + %% The reference is no longer alive. There is no + %% point in continuing the search. + no; + false -> + opt_recv(Is, D, R, L, [I|Acc]) + end. + +opt_update_regs({block,Bl}, R, L) -> + {opt_update_regs_bl(Bl, R),L}; +opt_update_regs({call,_,_}, R, L) -> + {regs_kill_not_live(0, R),L}; +opt_update_regs({call_ext,_,_}, R, L) -> + {regs_kill_not_live(0, R),L}; +opt_update_regs({call_fun,_}, R, L) -> + {regs_kill_not_live(0, R),L}; +opt_update_regs({kill,Y}, R, L) -> + {regs_kill([Y], R),L}; +opt_update_regs(send, R, L) -> + {regs_kill_not_live(0, R),L}; +opt_update_regs({'catch',_,{f,Lbl}}, R, L) -> + {R,gb_sets:add(Lbl, L)}; +opt_update_regs({catch_end,_}, R, L) -> + {R,L}; +opt_update_regs({label,Lbl}, R, L) -> + case gb_sets:is_member(Lbl, L) of + false -> + %% We can't allow arbitrary labels (since the receive + %% could be entered without first creating the reference). + {regs_init(),L}; + true -> + %% A catch label for a previously seen catch instruction is OK. + {R,L} + end; +opt_update_regs({try_end,_}, R, L) -> + {R,L}; +opt_update_regs(_I, _R, L) -> + %% Unrecognized instruction. Abort the search. + {regs_init(),L}. + +opt_update_regs_bl([{set,Ds,_,{alloc,Live,_}}|Is], Regs0) -> + Regs1 = regs_kill_not_live(Live, Regs0), + Regs = regs_kill(Ds, Regs1), + opt_update_regs_bl(Is, Regs); +opt_update_regs_bl([{set,[Dst]=Ds,[Src],move}|Is], Regs0) -> + Regs1 = regs_kill(Ds, Regs0), + Regs = case regs_is_member(Src, Regs1) of + false -> Regs1; + true -> regs_add(Dst, Regs1) + end, + opt_update_regs_bl(Is, Regs); +opt_update_regs_bl([{set,Ds,_,_}|Is], Regs0) -> + Regs = regs_kill(Ds, Regs0), + opt_update_regs_bl(Is, Regs); +opt_update_regs_bl([], Regs) -> Regs. + +%% opt_ref_used([Instruction], RefRegister, FailLabel, LabelIndex) -> true|false +%% Return 'true' if it is certain that only messages that contain the same +%% reference as in RefRegister can be matched out. Otherwise return 'false'. +%% +%% Basically, we follow all possible paths through the receive statement. +%% If all paths are safe, we return 'true'. +%% +%% A branch to FailLabel is safe, because it exits the receive statement +%% and no further message may be matched out. +%% +%% If a path hits an comparision between RefRegister and part of the message, +%% that path is safe (any messages that may be matched further down the +%% path is guaranteed to contain the reference). +%% +%% Otherwise, if we hit a 'remove_message' instruction, we give up +%% and return 'false' (the optimization is definitely unsafe). If +%% we hit an unrecognized instruction, we also give up and return +%% 'false' (the optimization may be unsafe). + +opt_ref_used(Is, RefReg, Fail, D) -> + Done = gb_sets:singleton(Fail), + Regs = regs_init_x0(), + try + opt_ref_used_1(Is, RefReg, D, Done, Regs), + true + catch + throw:not_used -> + false + end. + +%% This functions only returns if all paths through the receive +%% statement are safe, and throws an 'not_used' term otherwise. +opt_ref_used_1([{block,Bl}|Is], RefReg, D, Done, Regs0) -> + Regs = opt_ref_used_bl(Bl, Regs0), + opt_ref_used_1(Is, RefReg, D, Done, Regs); +opt_ref_used_1([{test,is_eq_exact,{f,Fail},Args}|Is], RefReg, D, Done0, Regs) -> + Done = opt_ref_used_at(Fail, RefReg, D, Done0, Regs), + case is_ref_msg_comparison(Args, RefReg, Regs) of + false -> + opt_ref_used_1(Is, RefReg, D, Done, Regs); + true -> + %% The instructions that follow (Is) can only be executed + %% if the message contains the same reference as in RefReg. + Done + end; +opt_ref_used_1([{test,is_ne_exact,{f,Fail},Args}|Is], RefReg, D, Done0, Regs) -> + Done = opt_ref_used_1(Is, RefReg, D, Done0, Regs), + case is_ref_msg_comparison(Args, RefReg, Regs) of + false -> + opt_ref_used_at(Fail, RefReg, D, Done, Regs); + true -> + Done + end; +opt_ref_used_1([{test,_,{f,Fail},_}|Is], RefReg, D, Done0, Regs) -> + Done = opt_ref_used_at(Fail, RefReg, D, Done0, Regs), + opt_ref_used_1(Is, RefReg, D, Done, Regs); +opt_ref_used_1([{select_tuple_arity,_,{f,Fail},{list,List}}|_], RefReg, D, Done, Regs) -> + Lbls = [F || {f,F} <- List] ++ [Fail], + opt_ref_used_in_all(Lbls, RefReg, D, Done, Regs); +opt_ref_used_1([{select_val,_,{f,Fail},{list,List}}|_], RefReg, D, Done, Regs) -> + Lbls = [F || {f,F} <- List] ++ [Fail], + opt_ref_used_in_all(Lbls, RefReg, D, Done, Regs); +opt_ref_used_1([{label,Lbl}|Is], RefReg, D, Done, Regs) -> + case gb_sets:is_member(Lbl, Done) of + true -> Done; + false -> opt_ref_used_1(Is, RefReg, D, Done, Regs) + end; +opt_ref_used_1([{loop_rec_end,_}|_], _, _, Done, _) -> + Done; +opt_ref_used_1([_I|_], _RefReg, _D, _Done, _Regs) -> + %% The optimization may be unsafe. + throw(not_used). + +%% is_ref_msg_comparison(Args, RefReg, RegisterSet) -> true|false. +%% Return 'true' if Args denotes a comparison between the +%% reference and message or part of the message. +is_ref_msg_comparison([R,RefReg], RefReg, Regs) -> + regs_is_member(R, Regs); +is_ref_msg_comparison([RefReg,R], RefReg, Regs) -> + regs_is_member(R, Regs); +is_ref_msg_comparison([_,_], _, _) -> false. + +opt_ref_used_in_all([L|Ls], RefReg, D, Done0, Regs) -> + Done = opt_ref_used_at(L, RefReg, D, Done0, Regs), + opt_ref_used_in_all(Ls, RefReg, D, Done, Regs); +opt_ref_used_in_all([], _, _, Done, _) -> Done. + +opt_ref_used_at(Fail, RefReg, D, Done0, Regs) -> + case gb_sets:is_member(Fail, Done0) of + true -> + Done0; + false -> + Is = beam_utils:code_at(Fail, D), + Done = opt_ref_used_1(Is, RefReg, D, Done0, Regs), + gb_sets:add(Fail, Done) + end. + +opt_ref_used_bl([{set,[],[],remove_message}|_], _) -> + %% We have proved that a message that does not depend on the + %% reference can be matched out. + throw(not_used); +opt_ref_used_bl([{set,Ds,Ss,_}|Is], Regs0) -> + case regs_all_members(Ss, Regs0) of + false -> + %% The destination registers may be assigned values that + %% are not dependent on the message being matched. + Regs = regs_kill(Ds, Regs0), + opt_ref_used_bl(Is, Regs); + true -> + %% All the sources depend on the message directly or + %% indirectly. + Regs = regs_add_list(Ds, Regs0), + opt_ref_used_bl(Is, Regs) + end; +opt_ref_used_bl([], Regs) -> Regs. + +%%% +%%% Functions for keeping track of a set of registers. +%%% + +%% regs_init() -> RegisterSet +%% Return an empty set of registers. + +regs_init() -> + {0,0}. + +%% regs_init_x0() -> RegisterSet +%% Return a set that only contains the {x,0} register. + +regs_init_x0() -> + {1 bsl 0,0}. + +%% regs_empty(Register) -> true|false +%% Test whether the register set is empty. + +regs_empty(R) -> + R =:= {0,0}. + +%% regs_kill_not_live(Live, RegisterSet) -> RegisterSet' +%% Kill all registers indicated not live by Live. + +regs_kill_not_live(Live, {Xregs,Yregs}) -> + {Xregs band ((1 bsl Live)-1),Yregs}. + +%% regs_kill([Register], RegisterSet) -> RegisterSet' +%% Kill all registers mentioned in the list of registers. + +regs_kill([{x,N}|Rs], {Xregs,Yregs}) -> + regs_kill(Rs, {Xregs band (bnot (1 bsl N)),Yregs}); +regs_kill([{y,N}|Rs], {Xregs,Yregs}) -> + regs_kill(Rs, {Xregs,Yregs band (bnot (1 bsl N))}); +regs_kill([{fr,_}|Rs], Regs) -> + regs_kill(Rs, Regs); +regs_kill([], Regs) -> Regs. + +regs_add_list(List, Regs) -> + foldl(fun(R, A) -> regs_add(R, A) end, Regs, List). + +%% regs_add(Register, RegisterSet) -> RegisterSet' +%% Add a new register to the set of registers. + +regs_add({x,N}, {Xregs,Yregs}) -> + {Xregs bor (1 bsl N),Yregs}; +regs_add({y,N}, {Xregs,Yregs}) -> + {Xregs,Yregs bor (1 bsl N)}. + +%% regs_all_members([Register], RegisterSet) -> true|false +%% Test whether all of the registers are part of the register set. + +regs_all_members([R|Rs], Regs) -> + regs_is_member(R, Regs) andalso regs_all_members(Rs, Regs); +regs_all_members([], _) -> true. + +%% regs_is_member(Register, RegisterSet) -> true|false +%% Test whether Register is part of the register set. + +regs_is_member({x,N}, {Regs,_}) -> Regs band (1 bsl N) =/= 0; +regs_is_member({y,N}, {_,Regs}) -> Regs band (1 bsl N) =/= 0; +regs_is_member(_, _) -> false. + +%% regs_to_list(RegisterSet) -> [Register] +%% Convert the register set to an explicit list of registers. +regs_to_list({Xregs,Yregs}) -> + regs_to_list_1(Xregs, 0, x, regs_to_list_1(Yregs, 0, y, [])). + +regs_to_list_1(0, _, _, Acc) -> + Acc; +regs_to_list_1(Regs, N, Tag, Acc) when (Regs band 1) =:= 1 -> + regs_to_list_1(Regs bsr 1, N+1, Tag, [{Tag,N}|Acc]); +regs_to_list_1(Regs, N, Tag, Acc) -> + regs_to_list_1(Regs bsr 1, N+1, Tag, Acc). diff --git a/lib/compiler/src/beam_type.erl b/lib/compiler/src/beam_type.erl index ba903a12b6..f83f73b224 100644 --- a/lib/compiler/src/beam_type.erl +++ b/lib/compiler/src/beam_type.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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% %% %% Purpose : Type-based optimisations. @@ -76,9 +76,6 @@ simplify_basic_1([{set,[D],[{integer,Index},Reg],{bif,element,_}}=I0|Is], Ts0, A end, Ts = update(I, Ts0), simplify_basic_1(Is, Ts, [I|Acc]); -simplify_basic_1([{set,[_],[_],{bif,_,{f,0}}}=I|Is], Ts0, Acc) -> - Ts = update(I, Ts0), - simplify_basic_1(Is, Ts, [I|Acc]); simplify_basic_1([{set,[D],[TupleReg],{get_tuple_element,0}}=I|Is0], Ts0, Acc) -> case tdb_find(TupleReg, Ts0) of {tuple,_,[Contents]} -> @@ -118,7 +115,6 @@ simplify_basic_1([{test,is_record,_,[R,{atom,_}=Tag,{integer,Arity}]}=I|Is], Ts0 Ts = update(I, Ts0), simplify_basic_1(Is, Ts, [I|Acc]) end; - simplify_basic_1([I|Is], Ts0, Acc) -> Ts = update(I, Ts0), simplify_basic_1(Is, Ts, [I|Acc]); @@ -183,7 +179,7 @@ simplify_float_1([], Ts, Rs, Acc0) -> {Is,Ts}. opt_fmoves([{set,[{x,_}=R],[{fr,_}]=Src,fmove}=I1, - {set,[{y,_}]=Dst,[{x,_}=R],move}=I2|Is], Acc) -> + {set,[_]=Dst,[{x,_}=R],move}=I2|Is], Acc) -> case beam_utils:is_killed_block(R, Is) of false -> opt_fmoves(Is, [I2,I1|Acc]); true -> opt_fmoves(Is, [{set,Dst,Src,fmove}|Acc]) @@ -253,8 +249,6 @@ flt_need_heap_2({set,_,_,{put_tuple,_}}, H, Fl) -> {[],H+1,Fl}; flt_need_heap_2({set,_,_,put}, H, Fl) -> {[],H+1,Fl}; -flt_need_heap_2({set,_,_,{put_string,L,_Str}}, H, Fl) -> - {[],H+2*L,Fl}; %% Then the "neutral" instructions. We just pass them. flt_need_heap_2({set,[{fr,_}],_,_}, H, Fl) -> {[],H,Fl}; diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl index ac249e6672..761d4ffec0 100644 --- a/lib/compiler/src/beam_utils.erl +++ b/lib/compiler/src/beam_utils.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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 : Common utilities used by several optimization passes. @@ -424,12 +424,6 @@ check_liveness(R, [{bs_add,{f,0},Ss,D}|Is], St) -> false when R =:= D -> {killed,St}; false -> check_liveness(R, Is, St) end; -check_liveness(R, [{bs_bits_to_bytes2,Src,Dst}|Is], St) -> - case R of - Src -> {used,St}; - Dst -> {killed,St}; - _ -> check_liveness(R, Is, St) - end; check_liveness(R, [{bs_put_binary,{f,0},Sz,_,_,Src}|Is], St) -> case member(R, [Sz,Src]) of true -> {used,St}; diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index 1fd61831e0..fb267b35b6 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -18,6 +18,10 @@ -module(beam_validator). +-compile({no_auto_import,[min/2]}). + +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([file/1, files/1]). %% Interface for compiler. @@ -416,6 +420,11 @@ valfun_1({put,Src}, Vst) -> valfun_1({put_string,Sz,_,Dst}, Vst0) when is_integer(Sz) -> Vst = eat_heap(2*Sz, Vst0), set_type_reg(cons, Dst, Vst); +%% Instructions for optimization of selective receives. +valfun_1({recv_mark,{f,Fail}}, Vst) when is_integer(Fail) -> + Vst; +valfun_1({recv_set,{f,Fail}}, Vst) when is_integer(Fail) -> + Vst; %% Misc. valfun_1({'%live',Live}, Vst) -> verify_live(Live, Vst), @@ -752,9 +761,6 @@ valfun_4({bs_utf8_size,{f,Fail},A,Dst}, Vst) -> valfun_4({bs_utf16_size,{f,Fail},A,Dst}, Vst) -> assert_term(A, Vst), set_type_reg({integer,[]}, Dst, branch_state(Fail, Vst)); -valfun_4({bs_bits_to_bytes2,Src,Dst}, Vst) -> - assert_term(Src, Vst), - set_type_reg({integer,[]}, Dst, Vst); valfun_4({bs_bits_to_bytes,{f,Fail},Src,Dst}, Vst) -> assert_term(Src, Vst), set_type_reg({integer,[]}, Dst, branch_state(Fail, Vst)); diff --git a/lib/compiler/src/cerl.erl b/lib/compiler/src/cerl.erl index 74fc0878cf..d1fd9d40e2 100644 --- a/lib/compiler/src/cerl.erl +++ b/lib/compiler/src/cerl.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% ===================================================================== @@ -122,6 +122,9 @@ bitstr_bitsize/1, bitstr_unit/1, bitstr_type/1, bitstr_flags/1]). +-export_type([c_binary/0, c_call/0, c_clause/0, c_cons/0, c_fun/0, c_literal/0, + c_module/0, c_tuple/0, c_values/0, c_var/0, cerl/0, var_name/0]). + %% %% needed by the include file below -- do not move %% diff --git a/lib/compiler/src/cerl_clauses.erl b/lib/compiler/src/cerl_clauses.erl index 5f111a5e05..99fa8dd9d5 100644 --- a/lib/compiler/src/cerl_clauses.erl +++ b/lib/compiler/src/cerl_clauses.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @doc Utility functions for Core Erlang case/receive clauses. @@ -338,10 +338,19 @@ match(P, E, Bs) -> if E =:= any -> {false, Bs}; true -> - case is_data(E) of - true -> + case type(E) of + literal -> + case is_bitstring(concrete(E)) of + false -> + none; + true -> + {false, Bs} + end; + cons -> + none; + tuple -> none; - false -> + _ -> {false, Bs} end end; diff --git a/lib/compiler/src/cerl_inline.erl b/lib/compiler/src/cerl_inline.erl index 191efa3032..c15103999f 100644 --- a/lib/compiler/src/cerl_inline.erl +++ b/lib/compiler/src/cerl_inline.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% Core Erlang inliner. @@ -65,7 +65,6 @@ try_evars/1, try_handler/1, tuple_es/1, tuple_arity/1, type/1, values_es/1, var_name/1]). --import(erlang, [max/2]). -import(lists, [foldl/3, foldr/3, mapfoldl/3, reverse/1]). %% @@ -201,9 +200,9 @@ start(Reply, Tree, Ctxt, Opts) -> false -> ok end, - Size = max(1, proplists:get_value(inline_size, Opts)), - Effort = max(1, proplists:get_value(inline_effort, Opts)), - Unroll = max(1, proplists:get_value(inline_unroll, Opts)), + Size = erlang:max(1, proplists:get_value(inline_size, Opts)), + Effort = erlang:max(1, proplists:get_value(inline_effort, Opts)), + Unroll = erlang:max(1, proplists:get_value(inline_unroll, Opts)), case proplists:get_bool(verbose, Opts) of true -> io:fwrite("Inlining: inline_size=~w inline_effort=~w\n", @@ -1429,17 +1428,26 @@ inline(E, #app{opnds = Opnds, ctxt = Ctxt, loc = L}, Ren, Env, S) -> {E, S}; true -> %% Create local bindings for the parameters to their - %% respective operand structures from the app-structure, and - %% visit the body in the context saved in the structure. + %% respective operand structures from the app-structure. {Rs, Ren1, Env1, S1} = bind_locals(Vs, Opnds, Ren, Env, S), - {E1, S2} = i(fun_body(E), Ctxt, Ren1, Env1, S1), + + %% function_clause exceptions that have been inlined + %% into another function (or even into the same function) + %% will not work properly. The v3_kernel pass will + %% take care of it, but we will need to help it by + %% removing any function_name annotations on match_fail + %% primops that we inline. + E1 = kill_function_name_anns(fun_body(E)), + + %% Visit the body in the context saved in the structure. + {E2, S2} = i(E1, Ctxt, Ren1, Env1, S1), %% Create necessary bindings and/or set flags. - {E2, S3} = make_let_bindings(Rs, E1, S2), + {E3, S3} = make_let_bindings(Rs, E2, S2), %% Lastly, flag the application as inlined, since the inlining %% attempt was not aborted before we reached this point. - {E2, st__set_app_inlined(L, S3)} + {E3, st__set_app_inlined(L, S3)} end. %% For the (possibly renamed) argument variables to an inlined call, @@ -2370,6 +2378,19 @@ kill_id_anns([A | As]) -> kill_id_anns([]) -> []. +kill_function_name_anns(Body) -> + F = fun(P) -> + case type(P) of + primop -> + Ann = get_ann(P), + Ann1 = lists:keydelete(function_name, 1, Ann), + set_ann(P, Ann1); + _ -> + P + end + end, + cerl_trees:map(F, Body). + %% ===================================================================== %% General utilities diff --git a/lib/compiler/src/cerl_trees.erl b/lib/compiler/src/cerl_trees.erl index 7a2057713e..1e3755025f 100644 --- a/lib/compiler/src/cerl_trees.erl +++ b/lib/compiler/src/cerl_trees.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @doc Basic functions on Core Erlang abstract syntax trees. @@ -73,14 +73,12 @@ depth(T) -> [] -> 0; Gs -> - 1 + lists:foldl(fun (G, A) -> max(depth_1(G), A) end, 0, Gs) + 1 + lists:foldl(fun (G, A) -> erlang:max(depth_1(G), A) end, 0, Gs) end. depth_1(Ts) -> - lists:foldl(fun (T, A) -> max(depth(T), A) end, 0, Ts). + lists:foldl(fun (T, A) -> erlang:max(depth(T), A) end, 0, Ts). -max(X, Y) when X > Y -> X; -max(_, Y) -> Y. %% @spec size(Tree::cerl()) -> integer() diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl index b853800d73..26da3ecad2 100644 --- a/lib/compiler/src/compile.erl +++ b/lib/compiler/src/compile.erl @@ -29,6 +29,8 @@ %% Erlc interface. -export([compile/3,compile_beam/3,compile_asm/3,compile_core/3]). +-export_type([option/0]). + -include("erl_compile.hrl"). -include("core_parse.hrl"). @@ -39,8 +41,7 @@ -type option() :: atom() | {atom(), term()} | {'d', atom(), term()}. --type line() :: integer(). --type err_info() :: {line(), module(), term()}. %% ErrorDescriptor +-type err_info() :: {erl_scan:line(), module(), term()}. %% ErrorDescriptor -type errors() :: [{file:filename(), [err_info()]}]. -type warnings() :: [{file:filename(), [err_info()]}]. -type mod_ret() :: {'ok', module()} @@ -68,7 +69,7 @@ file(File) -> file(File, ?DEFAULT_OPTIONS). --spec file(module() | file:filename(), [option()]) -> comp_ret(). +-spec file(module() | file:filename(), [option()] | option()) -> comp_ret(). file(File, Opts) when is_list(Opts) -> do_compile({file,File}, Opts++env_default_opts()); @@ -86,6 +87,8 @@ forms(Forms, Opt) when is_atom(Opt) -> %% would have generated a Beam file, false otherwise (if only a binary or a %% listing file would have been generated). +-spec output_generated([option()]) -> boolean(). + output_generated(Opts) -> noenv_output_generated(Opts++env_default_opts()). @@ -94,6 +97,8 @@ output_generated(Opts) -> %% for default options. %% +-spec noenv_file(module() | file:filename(), [option()] | option()) -> comp_ret(). + noenv_file(File, Opts) when is_list(Opts) -> do_compile({file,File}, Opts); noenv_file(File, Opt) -> @@ -104,6 +109,8 @@ noenv_forms(Forms, Opts) when is_list(Opts) -> noenv_forms(Forms, Opt) when is_atom(Opt) -> noenv_forms(Forms, [Opt|?DEFAULT_OPTIONS]). +-spec noenv_output_generated([option()]) -> boolean(). + noenv_output_generated(Opts) -> any(fun ({save_binary,_F}) -> true; (_Other) -> false @@ -162,13 +169,12 @@ expand_opt(report, Os) -> [report_errors,report_warnings|Os]; expand_opt(return, Os) -> [return_errors,return_warnings|Os]; -expand_opt(r11, Os) -> - [no_stack_trimming,no_binaries,no_constant_pool|Os]; +expand_opt(r12, Os) -> + [no_recv_opt|Os]; +expand_opt(r13, Os) -> + [no_recv_opt|Os]; expand_opt({debug_info_key,_}=O, Os) -> [encrypt_debug_info,O|Os]; -expand_opt(no_binaries=O, Os) -> - %%Turn off the entire type optimization pass. - [no_topt,O|Os]; expand_opt(no_float_opt, Os) -> %%Turn off the entire type optimization pass. [no_topt|Os]; @@ -215,16 +221,16 @@ format_error({module_name,Mod,Filename}) -> [Mod,Filename]). %% The compile state record. --record(compile, {filename="", - dir="", - base="", - ifile="", - ofile="", +-record(compile, {filename="" :: file:filename(), + dir="" :: file:filename(), + base="" :: file:filename(), + ifile="" :: file:filename(), + ofile="" :: file:filename(), module=[], code=[], core_code=[], abstract_code=[], %Abstract code for debugger. - options=[], + options=[] :: [option()], errors=[], warnings=[]}). @@ -295,15 +301,6 @@ fold_comp([{Name,Pass}|Ps], Run, St0) -> end; fold_comp([], _Run, St) -> {ok,St}. -os_process_size() -> - case os:type() of - {unix, sunos} -> - Size = os:cmd("ps -o vsz -p " ++ os:getpid() ++ " | tail -1"), - list_to_integer(lib:nonl(Size)); - _ -> - 0 - end. - run_tc({Name,Fun}, St) -> Before0 = statistics(runtime), Val = (catch Fun(St)), @@ -312,9 +309,8 @@ run_tc({Name,Fun}, St) -> {After_c, _} = After0, Mem0 = erts_debug:flat_size(Val)*erlang:system_info(wordsize), Mem = lists:flatten(io_lib:format("~.1f kB", [Mem0/1024])), - Sz = lists:flatten(io_lib:format("~.1f MB", [os_process_size()/1024])), - io:format(" ~-30s: ~10.2f s ~12s ~10s\n", - [Name,(After_c-Before_c) / 1000,Mem,Sz]), + io:format(" ~-30s: ~10.2f s ~12s\n", + [Name,(After_c-Before_c) / 1000,Mem]), Val. comp_ret_ok(#compile{code=Code,warnings=Warn0,module=Mod,options=Opts}=St) -> @@ -371,7 +367,7 @@ mpf(Ms) -> [{File,[M || {F,M} <- Ms, F =:= File]} || File <- lists:usort([F || {F,_} <- Ms])]. -%% passes(form|file, [Option]) -> [{Name,PassFun}] +%% passes(forms|file, [Option]) -> [{Name,PassFun}] %% Figure out which passes that need to be run. passes(forms, Opts) -> @@ -590,7 +586,7 @@ core_passes() -> kernel_passes() -> %% Destructive setelement/3 optimization and core lint. - [{unless,no_constant_pool,?pass(core_dsetel_module)}, %Not safe without constant pool. + [?pass(core_dsetel_module), {iff,dsetel,{listing,"dsetel"}}, {iff,clint,?pass(core_lint_module)}, @@ -626,6 +622,8 @@ asm_passes() -> {iff,dclean,{listing,"clean"}}, {unless,no_bsm_opt,{pass,beam_bsm}}, {iff,dbsm,{listing,"bsm"}}, + {unless,no_recv_opt,{pass,beam_receive}}, + {iff,drecv,{listing,"recv"}}, {unless,no_stack_trimming,{pass,beam_trim}}, {iff,dtrim,{listing,"trim"}}, {pass,beam_flatten}]}, @@ -826,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; @@ -835,7 +837,6 @@ get_core_transforms(Opts) -> [M || {core_transform,M} <- Opts]. core_transforms(St) -> %% The options field holds the complete list of options at this - Ts = get_core_transforms(St#compile.options), foldl_core_transforms(St, Ts). @@ -909,13 +910,8 @@ expand_module(#compile{code=Code,options=Opts0}=St0) -> {ok,St0#compile{module=Mod,options=Opts,code={Mod,Exp,Forms}}}. core_module(#compile{code=Code0,options=Opts}=St) -> - case v3_core:module(Code0, Opts) of - {ok,Code,Ws} -> - {ok,St#compile{code=Code,warnings=St#compile.warnings ++ Ws}}; - {error,Es,Ws} -> - {error,St#compile{warnings=St#compile.warnings ++ Ws, - errors=St#compile.errors ++ Es}} - end. + {ok,Code,Ws} = v3_core:module(Code0, Opts), + {ok,St#compile{code=Code,warnings=St#compile.warnings ++ Ws}}. core_fold_module(#compile{code=Code0,options=Opts,warnings=Warns}=St) -> {ok,Code,Ws} = sys_core_fold:module(Code0, Opts), @@ -1184,12 +1180,12 @@ write_binary(Name, Bin, St) -> %% report_errors(State) -> ok %% report_warnings(State) -> ok -report_errors(St) -> - case member(report_errors, St#compile.options) of +report_errors(#compile{options=Opts,errors=Errors}) -> + case member(report_errors, Opts) of true -> foreach(fun ({{F,_L},Eds}) -> list_errors(F, Eds); ({F,Eds}) -> list_errors(F, Eds) end, - St#compile.errors); + Errors); false -> ok end. diff --git a/lib/compiler/src/compiler.app.src b/lib/compiler/src/compiler.app.src index b0311365c4..4ac879c9a4 100644 --- a/lib/compiler/src/compiler.app.src +++ b/lib/compiler/src/compiler.app.src @@ -1,19 +1,19 @@ % This is an -*- erlang -*- file. %% %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% {application, compiler, @@ -33,6 +33,7 @@ beam_listing, beam_opcodes, beam_peep, + beam_receive, beam_trim, beam_type, beam_utils, diff --git a/lib/compiler/src/erl_bifs.erl b/lib/compiler/src/erl_bifs.erl index e87bb276de..f8128702dd 100644 --- a/lib/compiler/src/erl_bifs.erl +++ b/lib/compiler/src/erl_bifs.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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: Information about the Erlang built-in functions. @@ -65,6 +65,8 @@ is_pure(erlang, 'xor', 2) -> true; is_pure(erlang, abs, 1) -> true; is_pure(erlang, atom_to_binary, 2) -> true; is_pure(erlang, atom_to_list, 1) -> true; +is_pure(erlang, binary_part, 2) -> true; +is_pure(erlang, binary_part, 3) -> true; is_pure(erlang, binary_to_atom, 2) -> true; is_pure(erlang, binary_to_list, 1) -> true; is_pure(erlang, binary_to_list, 3) -> true; diff --git a/lib/compiler/src/genop.tab b/lib/compiler/src/genop.tab index 6874054495..63527bda8f 100644 --- a/lib/compiler/src/genop.tab +++ b/lib/compiler/src/genop.tab @@ -1,19 +1,19 @@ # # %CopyrightBegin% -# -# Copyright Ericsson AB 1998-2009. All Rights Reserved. -# +# +# Copyright Ericsson AB 1998-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% # BEAM_FORMAT_NUMBER=0 @@ -132,7 +132,7 @@ BEAM_FORMAT_NUMBER=0 # # Building terms. # -68: put_string/3 +68: -put_string/3 69: put_list/3 70: put_tuple/2 71: put/1 @@ -208,7 +208,7 @@ BEAM_FORMAT_NUMBER=0 # New instructions in R10B. 109: bs_init2/6 -110: bs_bits_to_bytes/3 +110: -bs_bits_to_bytes/3 111: bs_add/5 112: apply/1 113: apply_last/2 @@ -274,3 +274,9 @@ BEAM_FORMAT_NUMBER=0 # R13B03 149: on_load/0 + +# R14A + +150: recv_mark/1 +151: recv_set/1 +152: gc_bif3/7 diff --git a/lib/compiler/src/rec_env.erl b/lib/compiler/src/rec_env.erl index 9b73e08ad8..31a1f8b0b7 100644 --- a/lib/compiler/src/rec_env.erl +++ b/lib/compiler/src/rec_env.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% @author Richard Carlsson <[email protected]> @@ -32,7 +32,7 @@ get/2, is_defined/2, is_empty/1, keys/1, lookup/2, new_key/1, new_key/2, new_keys/2, new_keys/3, size/1, to_list/1]). --import(erlang, [max/2]). +-export_type([environment/0]). -ifdef(DEBUG). -export([test/1, test_custom/1, test_custom/2]). @@ -586,7 +586,7 @@ new_key(N, R, _T, F, Env) -> new_key(generate(N, R1), R1, 0, F, Env). start_range(Env) -> - max(env_size(Env) * ?START_RANGE_FACTOR, ?MINIMUM_RANGE). + erlang:max(env_size(Env) * ?START_RANGE_FACTOR, ?MINIMUM_RANGE). %% The previous key might or might not be used to compute the next key %% to be tried. It is currently not used. diff --git a/lib/compiler/src/sys_core_dsetel.erl b/lib/compiler/src/sys_core_dsetel.erl index c38eab7b42..f6696992b9 100644 --- a/lib/compiler/src/sys_core_dsetel.erl +++ b/lib/compiler/src/sys_core_dsetel.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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 : Using dsetelement to make multiple-field record updates @@ -57,8 +57,6 @@ %% if X1 is used exactly once. %% Thus, we need to track variable usage. %% -%% NOTE: This pass must NOT be used if the no_constant_pool option is used. -%% -module(sys_core_dsetel). diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl index 068478496b..96015fbe58 100644 --- a/lib/compiler/src/sys_core_fold.erl +++ b/lib/compiler/src/sys_core_fold.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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% %% %% Purpose : Constant folding optimisation for Core @@ -602,15 +602,23 @@ count_bits_1(Int, Bits) -> count_bits_1(Int bsr 64, Bits+64). %% a rewritten expression consisting of a sequence of %% the arguments only is returned. -useless_call(effect, #c_call{module=#c_literal{val=Mod}, +useless_call(effect, #c_call{anno=Anno, + module=#c_literal{val=Mod}, name=#c_literal{val=Name}, args=Args}=Call) -> A = length(Args), case erl_bifs:is_safe(Mod, Name, A) of false -> case erl_bifs:is_pure(Mod, Name, A) of - true -> add_warning(Call, result_ignored); - false -> ok + true -> + case member(result_not_wanted, Anno) of + false -> + add_warning(Call, result_ignored); + true -> + ok + end; + false -> + ok end, no; true -> @@ -1030,6 +1038,8 @@ fold_non_lit_args(Call, lists, append, [Arg1,Arg2], _) -> eval_append(Call, Arg1, Arg2); fold_non_lit_args(Call, erlang, setelement, [Arg1,Arg2,Arg3], _) -> eval_setelement(Call, Arg1, Arg2, Arg3); +fold_non_lit_args(Call, erlang, is_record, [Arg1,Arg2,Arg3], Sub) -> + eval_is_record(Call, Arg1, Arg2, Arg3, Sub); fold_non_lit_args(Call, erlang, N, Args, Sub) -> NumArgs = length(Args), case erl_internal:comp_op(N, NumArgs) of @@ -1186,19 +1196,22 @@ eval_element(Call, #c_literal{val=Pos}, #c_tuple{es=Es}, _Types) when is_integer true -> eval_failure(Call, badarg) end; -%% eval_element(Call, #c_literal{val=Pos}, #c_var{name=V}, Types) -%% when is_integer(Pos) -> -%% case orddict:find(V, Types#sub.t) of -%% {ok,#c_tuple{es=Elements}} -> -%% if -%% 1 =< Pos, Pos =< length(Elements) -> -%% lists:nth(Pos, Elements); -%% true -> -%% eval_failure(Call, badarg) -%% end; -%% error -> -%% Call -%% end; +eval_element(Call, #c_literal{val=Pos}, #c_var{name=V}, Types) + when is_integer(Pos) -> + case orddict:find(V, Types#sub.t) of + {ok,#c_tuple{es=Elements}} -> + if + 1 =< Pos, Pos =< length(Elements) -> + case lists:nth(Pos, Elements) of + #c_alias{var=Alias} -> Alias; + Res -> Res + end; + true -> + eval_failure(Call, badarg) + end; + error -> + Call + end; eval_element(Call, Pos, Tuple, _Types) -> case is_not_integer(Pos) orelse is_not_tuple(Tuple) of true -> @@ -1207,6 +1220,20 @@ eval_element(Call, Pos, Tuple, _Types) -> Call end. +%% eval_is_record(Call, Var, Tag, Size, Types) -> Val. +%% Evaluates is_record/3 using type information. +%% +eval_is_record(Call, #c_var{name=V}, #c_literal{val=NeededTag}=Lit, + #c_literal{val=Size}, Types) -> + case orddict:find(V, Types#sub.t) of + {ok,#c_tuple{es=[#c_literal{val=Tag}|_]=Es}} -> + Lit#c_literal{val=Tag =:= NeededTag andalso + length(Es) =:= Size}; + _ -> + Call + end; +eval_is_record(Call, _, _, _, _) -> Call. + %% is_not_integer(Core) -> true | false. %% Returns true if Core is definitely not an integer. @@ -2806,7 +2833,8 @@ format_error({no_effect,{erlang,F,A}}) -> end, flatten(io_lib:format(Fmt, Args)); format_error(result_ignored) -> - "the result of the expression is ignored"; + "the result of the expression is ignored " + "(suppress the warning by assigning the expression to the _ variable)"; format_error(useless_building) -> "a term is constructed, but never used"; format_error(bin_opt_alias) -> diff --git a/lib/compiler/src/sys_core_inline.erl b/lib/compiler/src/sys_core_inline.erl index c8d75b80c6..9f93acb666 100644 --- a/lib/compiler/src/sys_core_inline.erl +++ b/lib/compiler/src/sys_core_inline.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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 : Function inlining optimisation for Core. @@ -41,11 +41,9 @@ -module(sys_core_inline). -%%-compile({inline,{match_fail_fun,0}}). - -export([module/2]). --import(lists, [member/2,map/2,foldl/3,mapfoldl/3]). +-import(lists, [member/2,map/2,foldl/3,mapfoldl/3,keydelete/3]). -include("core_parse.hrl"). @@ -178,11 +176,9 @@ weight_func(_Core, Acc) -> Acc + 1. %% function_clause match_fail (if they have one). match_fail_fun() -> - fun (#c_primop{name=#c_literal{val=match_fail}, - args=[#c_tuple{es=[#c_literal{val=function_clause}|As]}]}=P) -> - Fail = #c_tuple{es=[#c_literal{val=case_clause}, - #c_tuple{es=As}]}, - P#c_primop{args=[Fail]}; + fun (#c_primop{anno=Anno0,name=#c_literal{val=match_fail}}=P) -> + Anno = keydelete(function_name, 1, Anno0), + P#c_primop{anno=Anno}; (Other) -> Other end. @@ -201,7 +197,7 @@ kill_id_anns(Body) -> (Expr) -> %% Mark everything as compiler generated to suppress %% bogus warnings. - A = [compiler_generated|core_lib:get_anno(Expr)], + A = compiler_generated(core_lib:get_anno(Expr)), core_lib:set_anno(Expr, A) end, Body). @@ -210,3 +206,8 @@ kill_id_anns_1([{'id',_}|As]) -> kill_id_anns_1([A|As]) -> [A|kill_id_anns_1(As)]; kill_id_anns_1([]) -> []. + +compiler_generated([compiler_generated|_]=Anno) -> + Anno; +compiler_generated(Anno) -> + [compiler_generated|Anno -- [compiler_generated]]. diff --git a/lib/compiler/src/sys_pre_expand.erl b/lib/compiler/src/sys_pre_expand.erl index f80d03dfac..480954adac 100644 --- a/lib/compiler/src/sys_pre_expand.erl +++ b/lib/compiler/src/sys_pre_expand.erl @@ -403,16 +403,21 @@ expr({'fun',Line,Body}, St) -> expr({call,Line,{atom,La,N}=Atom,As0}, St0) -> {As,St1} = expr_list(As0, St0), Ar = length(As), - case erl_internal:bif(N, Ar) of - true -> - {{call,Line,{remote,La,{atom,La,erlang},Atom},As},St1}; - false -> - case imported(N, Ar, St1) of - {yes,Mod} -> - {{call,Line,{remote,La,{atom,La,Mod},Atom},As},St1}; - no -> - {{call,Line,Atom,As},St1} - end + case defined(N,Ar,St1) of + true -> + {{call,Line,Atom,As},St1}; + _ -> + case imported(N, Ar, St1) of + {yes,Mod} -> + {{call,Line,{remote,La,{atom,La,Mod},Atom},As},St1}; + no -> + case erl_internal:bif(N, Ar) of + true -> + {{call,Line,{remote,La,{atom,La,erlang},Atom},As},St1}; + false -> %% This should have been handled by erl_lint + {{call,Line,Atom,As},St1} + end + end end; expr({call,Line,{record_field,_,_,_}=M,As0}, St0) -> expr({call,Line,expand_package(M, St0),As0}, St0); @@ -685,3 +690,6 @@ imported(F, A, St) -> {ok,Mod} -> {yes,Mod}; error -> no end. + +defined(F, A, St) -> + ordsets:is_element({F,A}, St#expand.defined). diff --git a/lib/compiler/src/v3_codegen.erl b/lib/compiler/src/v3_codegen.erl index 83113d1652..948937c438 100644 --- a/lib/compiler/src/v3_codegen.erl +++ b/lib/compiler/src/v3_codegen.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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% %% %% Purpose : Code generator for Beam. @@ -209,7 +209,6 @@ need_heap_1(#l{ke={set,_,Val}}, H) -> {[],H + case Val of {cons,_} -> 2; {tuple,Es} -> 1 + length(Es); - {string,S} -> 2 * length(S); _Other -> 0 end}; need_heap_1(#l{ke={bif,dsetelement,_As,_Rs},i=I}, H) -> @@ -1191,7 +1190,12 @@ trap_bif(_, _, _) -> false. bif_cg(bs_context_to_binary=Instr, [Src0], [], Le, Vdb, Bef, St0) -> [Src] = cg_reg_args([Src0], Bef), - {[{Instr,Src}],clear_dead(Bef, Le#l.i, Vdb), St0}; + case is_register(Src) of + false -> + {[],clear_dead(Bef, Le#l.i, Vdb), St0}; + true -> + {[{Instr,Src}],clear_dead(Bef, Le#l.i, Vdb), St0} + end; bif_cg(dsetelement, [Index0,Tuple0,New0], _Rs, Le, Vdb, Bef, St0) -> [New,Tuple,{integer,Index1}] = cg_reg_args([New0,Tuple0,Index0], Bef), Index = Index1-1, @@ -1424,8 +1428,6 @@ set_cg([{var,R}], Con, Le, Vdb, Bef, St) -> [{put_tuple,length(Es),Ret}] ++ cg_build_args(Es, Bef); {var,V} -> % Normally removed by kernel optimizer. [{move,fetch_var(V, Int),Ret}]; - {string,Str} = String -> - [{put_string,length(Str),String,Ret}]; Other -> [{move,Other,Ret}] end, @@ -2022,6 +2024,10 @@ fetch_stack(V, [_|Stk], I) -> fetch_stack(V, Stk, I+1). on_stack(V, Stk) -> keymember(V, 1, Stk). +is_register({x,_}) -> true; +is_register({yy,_}) -> true; +is_register(_) -> false. + %% put_catch(CatchTag, Stack) -> Stack' %% drop_catch(CatchTag, Stack) -> Stack' %% Special interface for putting and removing catch tags, to ensure that diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl index dfe15de4ff..f6bb45787c 100644 --- a/lib/compiler/src/v3_core.erl +++ b/lib/compiler/src/v3_core.erl @@ -122,14 +122,13 @@ | iclause() | ifun() | iletrec() | imatch() | iprimop() | iprotect() | ireceive1() | ireceive2() | iset() | itry(). --type error() :: {file:filename(), [{integer(), module(), term()}]}. -type warning() :: {file:filename(), [{integer(), module(), term()}]}. -record(core, {vcount=0 :: non_neg_integer(), %Variable counter fcount=0 :: non_neg_integer(), %Function counter in_guard=false :: boolean(), %In guard or not. + wanted=true :: boolean(), %Result wanted or not. opts :: [compile:option()], %Options. - es=[] :: [error()], %Errors. ws=[] :: [warning()], %Warnings. file=[{file,""}]}). %File @@ -140,46 +139,41 @@ | {attribute, integer(), attribute(), _}. -spec module({module(), [fa()], [form()]}, [compile:option()]) -> - {'ok',cerl:c_module(),[warning()]} | {'error',[error()],[warning()]}. + {'ok',cerl:c_module(),[warning()]}. module({Mod,Exp,Forms}, Opts) -> Cexp = map(fun ({_N,_A} = NA) -> #c_var{name=NA} end, Exp), - {Kfs0,As0,Es,Ws,_File} = foldl(fun (F, Acc) -> - form(F, Acc, Opts) - end, {[],[],[],[],[]}, Forms), + {Kfs0,As0,Ws,_File} = foldl(fun (F, Acc) -> + form(F, Acc, Opts) + end, {[],[],[],[]}, Forms), Kfs = reverse(Kfs0), As = reverse(As0), - case Es of - [] -> - {ok,#c_module{name=#c_literal{val=Mod},exports=Cexp,attrs=As,defs=Kfs},Ws}; - _ -> - {error,Es,Ws} - end. + {ok,#c_module{name=#c_literal{val=Mod},exports=Cexp,attrs=As,defs=Kfs},Ws}. -form({function,_,_,_,_}=F0, {Fs,As,Es0,Ws0,File}, Opts) -> - {F,Es,Ws} = function(F0, Es0, Ws0, File, Opts), - {[F|Fs],As,Es,Ws,File}; -form({attribute,_,file,{File,_Line}}, {Fs,As,Es,Ws,_}, _Opts) -> - {Fs,As,Es,Ws,File}; -form({attribute,_,_,_}=F, {Fs,As,Es,Ws,File}, _Opts) -> - {Fs,[attribute(F)|As],Es,Ws,File}. +form({function,_,_,_,_}=F0, {Fs,As,Ws0,File}, Opts) -> + {F,Ws} = function(F0, Ws0, File, Opts), + {[F|Fs],As,Ws,File}; +form({attribute,_,file,{File,_Line}}, {Fs,As,Ws,_}, _Opts) -> + {Fs,As,Ws,File}; +form({attribute,_,_,_}=F, {Fs,As,Ws,File}, _Opts) -> + {Fs,[attribute(F)|As],Ws,File}. attribute({attribute,Line,Name,Val}) -> {#c_literal{val=Name, anno=[Line]}, #c_literal{val=Val, anno=[Line]}}. -function({function,_,Name,Arity,Cs0}, Es0, Ws0, File, Opts) -> +function({function,_,Name,Arity,Cs0}, Ws0, File, Opts) -> %%ok = io:fwrite("~p - ", [{Name,Arity}]), - St0 = #core{vcount=0,opts=Opts,es=Es0,ws=Ws0,file=[{file,File}]}, + St0 = #core{vcount=0,opts=Opts,ws=Ws0,file=[{file,File}]}, {B0,St1} = body(Cs0, Name, Arity, St0), %%ok = io:fwrite("1", []), %%ok = io:fwrite("~w:~p~n", [?LINE,B0]), {B1,St2} = ubody(B0, St1), %%ok = io:fwrite("2", []), %%ok = io:fwrite("~w:~p~n", [?LINE,B1]), - {B2,#core{es=Es,ws=Ws}} = cbody(B1, St2), + {B2,#core{ws=Ws}} = cbody(B1, St2), %%ok = io:fwrite("3~n", []), %%ok = io:fwrite("~w:~p~n", [?LINE,B2]), - {{#c_var{name={Name,Arity}},B2},Es,Ws}. + {{#c_var{name={Name,Arity}},B2},Ws}. body(Cs0, Name, Arity, St0) -> Anno = lineno_anno(element(2, hd(Cs0)), St0), @@ -213,10 +207,7 @@ clause({clause,Lc,H0,G0,B0}, St0) -> catch throw:nomatch -> St = add_warning(Lc, nomatch, St0), - {noclause,St}; %Bad pattern - throw:no_binaries -> - St = add_error(Lc, no_binaries, St0), - {noclause,St} + {noclause,St} %Bad pattern end. clause_arity({clause,_,H0,_,_}) -> length(H0). @@ -496,22 +487,18 @@ expr({tuple,L,Es0}, St0) -> {Es1,Eps,St1} = safe_list(Es0, St0), A = lineno_anno(L, St1), {ann_c_tuple(A, Es1),Eps,St1}; -expr({bin,L,Es0}, #core{opts=Opts}=St0) -> - St1 = case member(no_binaries, Opts) of - false -> St0; - true -> add_error(L, no_binaries, St0) - end, - try expr_bin(Es0, lineno_anno(L, St1), St1) of +expr({bin,L,Es0}, St0) -> + try expr_bin(Es0, lineno_anno(L, St0), St0) of {_,_,_}=Res -> Res catch throw:bad_binary -> - St2 = add_warning(L, bad_binary, St1), - LineAnno = lineno_anno(L, St2), + St = add_warning(L, bad_binary, St0), + LineAnno = lineno_anno(L, St), As = [#c_literal{anno=LineAnno,val=badarg}], {#icall{anno=#a{anno=LineAnno}, %Must have an #a{} module=#c_literal{anno=LineAnno,val=erlang}, name=#c_literal{anno=LineAnno,val=error}, - args=As},[],St2} + args=As},[],St} end; expr({block,_,Es0}, St0) -> %% Inline the block directly. @@ -587,10 +574,14 @@ expr({'fun',L,{function,F,A},{_,_,_}=Id}, St) -> {#c_var{anno=Lanno++[{id,Id}],name={F,A}},[],St}; expr({'fun',L,{clauses,Cs},Id}, St) -> fun_tq(Id, Cs, L, St); -expr({call,L,{remote,_,M,F},As0}, St0) -> +expr({call,L,{remote,_,M,F},As0}, #core{wanted=Wanted}=St0) -> {[M1,F1|As1],Aps,St1} = safe_list([M,F|As0], St0), Lanno = lineno_anno(L, St1), - {#icall{anno=#a{anno=Lanno},module=M1,name=F1,args=As1},Aps,St1}; + Anno = case Wanted of + false -> [result_not_wanted|Lanno]; + true -> Lanno + end, + {#icall{anno=#a{anno=Anno},module=M1,name=F1,args=As1},Aps,St1}; expr({call,Lc,{atom,Lf,F},As0}, St0) -> {As1,Aps,St1} = safe_list(As0, St0), Op = #c_var{anno=lineno_anno(Lf, St1),name={F,length(As1)}}, @@ -603,27 +594,28 @@ expr({call,L,FunExp,As0}, St0) -> expr({match,L,P0,E0}, St0) -> %% First fold matches together to create aliases. {P1,E1} = fold_match(E0, P0), - {E2,Eps,St1} = novars(E1, St0), + St1 = case P1 of + {var,_,'_'} -> St0#core{wanted=false}; + _ -> St0 + end, + {E2,Eps,St2} = novars(E1, St1), + St3 = St2#core{wanted=St0#core.wanted}, P2 = try - pattern(P1, St1) + pattern(P1, St3) catch throw:Thrown -> Thrown end, - {Fpat,St2} = new_var(St1), + {Fpat,St4} = new_var(St3), Fc = fail_clause([Fpat], c_tuple([#c_literal{val=badmatch},Fpat])), - Lanno = lineno_anno(L, St2), + Lanno = lineno_anno(L, St4), case P2 of nomatch -> - St = add_warning(L, nomatch, St2), - {#icase{anno=#a{anno=Lanno}, - args=[E2],clauses=[],fc=Fc},Eps,St}; - no_binaries -> - St = add_error(L, no_binaries, St2), + St = add_warning(L, nomatch, St4), {#icase{anno=#a{anno=Lanno}, args=[E2],clauses=[],fc=Fc},Eps,St}; Other when not is_atom(Other) -> - {#imatch{anno=#a{anno=Lanno},pat=P2,arg=E2,fc=Fc},Eps,St2} + {#imatch{anno=#a{anno=Lanno},pat=P2,arg=E2,fc=Fc},Eps,St4} end; expr({op,_,'++',{lc,Llc,E,Qs},More}, St0) -> %% Optimise '++' here because of the list comprehension algorithm. @@ -1443,15 +1435,10 @@ pattern({cons,L,H,T}, St) -> ann_c_cons(lineno_anno(L, St), pattern(H, St), pattern(T, St)); pattern({tuple,L,Ps}, St) -> ann_c_tuple(lineno_anno(L, St), pattern_list(Ps, St)); -pattern({bin,L,Ps}, #core{opts=Opts}=St) -> - case member(no_binaries, Opts) of - false -> - %% We don't create a #ibinary record here, since there is - %% no need to hold any used/new annotations in a pattern. - #c_binary{anno=lineno_anno(L, St),segments=pat_bin(Ps, St)}; - true -> - throw(no_binaries) - end; +pattern({bin,L,Ps}, St) -> + %% We don't create a #ibinary record here, since there is + %% no need to hold any used/new annotations in a pattern. + #c_binary{anno=lineno_anno(L, St),segments=pat_bin(Ps, St)}; pattern({match,_,P1,P2}, St) -> pat_alias(pattern(P1, St), pattern(P2, St)). @@ -1558,17 +1545,21 @@ new_vars_1(N, Anno, St0, Vs) when N > 0 -> new_vars_1(0, _, St, Vs) -> {Vs,St}. function_clause(Ps, Name) -> - fail_clause(Ps, c_tuple([#c_literal{anno=[{name,Name}], - val=function_clause}|Ps])). -function_clause(Ps, Anno, Name) -> - fail_clause(Ps, ann_c_tuple(Anno, - [#c_literal{anno=[{name,Name}], - val=function_clause}|Ps])). - -fail_clause(Pats, A) -> + function_clause(Ps, [], Name). + +function_clause(Ps, LineAnno, Name) -> + FcAnno = [{function_name,Name}], + fail_clause(Ps, FcAnno, + ann_c_tuple(LineAnno, [#c_literal{val=function_clause}|Ps])). + +fail_clause(Pats, Arg) -> + fail_clause(Pats, [], Arg). + +fail_clause(Pats, Anno, Arg) -> #iclause{anno=#a{anno=[compiler_generated]}, pats=Pats,guard=[], - body=[#iprimop{anno=#a{},name=#c_literal{val=match_fail},args=[A]}]}. + body=[#iprimop{anno=#a{anno=Anno},name=#c_literal{val=match_fail}, + args=[Arg]}]}. ubody(B, St) -> uexpr(B, [], St). @@ -2098,39 +2089,25 @@ is_simple(#c_literal{}) -> true; is_simple(#c_cons{hd=H,tl=T}) -> is_simple(H) andalso is_simple(T); is_simple(#c_tuple{es=Es}) -> is_simple_list(Es); -is_simple(#c_binary{segments=Es}) -> is_simp_bin(Es); is_simple(_) -> false. -spec is_simple_list([cerl:cerl()]) -> boolean(). is_simple_list(Es) -> lists:all(fun is_simple/1, Es). --spec is_simp_bin([cerl:cerl()]) -> boolean(). - -is_simp_bin(Es) -> - lists:all(fun (#c_bitstr{val=E,size=S}) -> - is_simple(E) andalso is_simple(S) - end, Es). - %%% %%% Handling of warnings. %%% --type err_desc() :: 'bad_binary' | 'no_binaries' | 'nomatch'. +-type err_desc() :: 'bad_binary' | 'nomatch'. -spec format_error(err_desc()) -> nonempty_string(). format_error(nomatch) -> "pattern cannot possibly match"; format_error(bad_binary) -> - "binary construction will fail because of a type mismatch"; -format_error(no_binaries) -> - "bit syntax is not allowed to be used when compatibility with a previous " - "version has been requested". + "binary construction will fail because of a type mismatch". add_warning(Line, Term, #core{ws=Ws,file=[{file,File}]}=St) when Line >= 0 -> St#core{ws=[{File,[{location(Line),?MODULE,Term}]}|Ws]}; add_warning(_, _, St) -> St. - -add_error(Line, Term, #core{es=Es,file=[{file,File}]}=St) -> - St#core{es=[{File,[{location(abs_line(Line)),?MODULE,Term}]}|Es]}. diff --git a/lib/compiler/src/v3_kernel.erl b/lib/compiler/src/v3_kernel.erl index 8568071e57..fbe4d8617e 100644 --- a/lib/compiler/src/v3_kernel.erl +++ b/lib/compiler/src/v3_kernel.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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% %% %% Purpose : Transform Core Erlang to Kernel Erlang @@ -80,7 +80,8 @@ -export([module/2,format_error/1]). --import(lists, [map/2,foldl/3,foldr/3,mapfoldl/3,splitwith/2,member/2,keymember/3]). +-import(lists, [map/2,foldl/3,foldr/3,mapfoldl/3,splitwith/2,member/2, + keymember/3,keyfind/3]). -import(ordsets, [add_element/2,del_element/2,union/2,union/1,subtract/2]). -compile({nowarn_deprecated_function, {erlang,hash,2}}). @@ -126,19 +127,28 @@ copy_anno(Kdst, Ksrc) -> -spec module(cerl:c_module(), [compile:option()]) -> {'ok', #k_mdef{}, [warning()]}. -module(#c_module{anno=A,name=M,exports=Es,attrs=As,defs=Fs}, Options) -> - Lit = case member(no_constant_pool, Options) of - true -> no; - false -> dict:new() - end, - St0 = #kern{lit=Lit}, - {Kfs,St} = mapfoldl(fun function/2, St0, Fs), +module(#c_module{anno=A,name=M,exports=Es,attrs=As,defs=Fs}, _Options) -> + Kas = attributes(As), Kes = map(fun (#c_var{name={_,_}=Fname}) -> Fname end, Es), - Kas = map(fun ({#c_literal{val=N},V}) -> - {N,core_lib:literal_value(V)} end, As), + St0 = #kern{lit=dict:new()}, + {Kfs,St} = mapfoldl(fun function/2, St0, Fs), {ok,#k_mdef{anno=A,name=M#c_literal.val,exports=Kes,attributes=Kas, body=Kfs ++ St#kern.funs},lists:sort(St#kern.ws)}. +attributes([{#c_literal{val=Name},Val}|As]) -> + case include_attribute(Name) of + false -> + attributes(As); + true -> + [{Name,core_lib:literal_value(Val)}|attributes(As)] + end; +attributes([]) -> []. + +include_attribute(type) -> false; +include_attribute(spec) -> false; +include_attribute(opaque) -> false; +include_attribute(_) -> true. + function({#c_var{name={F,Arity}=FA},Body}, St0) -> try St1 = St0#kern{func=FA,ff=undefined,vcount=0,fcount=0,ds=sets:new()}, @@ -240,11 +250,6 @@ expr(#c_var{anno=A,name={_Name,Arity}}=Fname, Sub, St) -> expr(Fun, Sub, St); expr(#c_var{anno=A,name=V}, Sub, St) -> {#k_var{anno=A,name=get_vsub(V, Sub)},[],St}; -expr(#c_literal{anno=A,val=Lit}, Sub, #kern{lit=no}=St) -> - %% No constant pools for compatibility with a previous version. - %% Fully expand the literal. - Core = expand_literal(Lit, A), - expr(Core, Sub, St); expr(#c_literal{}=Lit, Sub, St) -> Core = handle_literal(Lit), expr(Core, Sub, St); @@ -265,9 +270,6 @@ expr(#k_float{}=V, _Sub, St) -> {V,[],St}; expr(#k_atom{}=V, _Sub, St) -> {V,[],St}; -expr(#k_string{}=V, _Sub, St) -> - %% Only for compatibility with a previous version. - {V,[],St}; expr(#c_cons{anno=A,hd=Ch,tl=Ct}, Sub, St0) -> %% Do cons in two steps, first the expressions left to right, then %% any remaining literals right to left. @@ -420,7 +422,7 @@ expr(#c_call{anno=A,module=M0,name=F0,args=Cargs}, Sub, St0) -> {Call,Ap,St} end; expr(#c_primop{anno=A,name=#c_literal{val=match_fail},args=Cargs0}, Sub, St0) -> - Cargs = translate_match_fail(Cargs0, Sub, St0), + Cargs = translate_match_fail(Cargs0, Sub, A, St0), %% This special case will disappear. {Kargs,Ap,St} = atomic_list(Cargs, Sub, St0), Ar = length(Cargs), @@ -447,32 +449,53 @@ expr(#c_catch{anno=A,body=Cb}, Sub, St0) -> %% Handle internal expressions. expr(#ireceive_accept{anno=A}, _Sub, St) -> {#k_receive_accept{anno=A},[],St}. -%% Translate a function_clause to case_clause if it has been moved into -%% another function. -translate_match_fail([#c_tuple{es=[#c_literal{anno=A0, - val=function_clause}|As]}]=Args, - Sub, - #kern{ff=FF}) -> - A = case A0 of - [{name,{Func0,Arity0}}] -> - [{name,{get_fsub(Func0, Arity0, Sub),Arity0}}]; - _ -> - A0 - end, - case {A,FF} of - {[{name,Same}],Same} -> +%% Translate a function_clause exception to a case_clause exception if +%% it has been moved into another function. (A function_clause exception +%% will not work correctly if it is moved into another function, or +%% even if it is invoked not from the top level in the correct function.) +translate_match_fail(Args, Sub, Anno, St) -> + case Args of + [#c_tuple{es=[#c_literal{val=function_clause}|As]}] -> + translate_match_fail_1(Anno, Args, As, Sub, St); + [#c_literal{val=Tuple}] when is_tuple(Tuple) -> + %% The inliner may have created a literal out of + %% the original #c_tuple{}. + case tuple_to_list(Tuple) of + [function_clause|As0] -> + As = [#c_literal{val=E} || E <- As0], + translate_match_fail_1(Anno, Args, As, Sub, St); + _ -> + Args + end; + _ -> + %% Not a function_clause exception. + Args + end. + +translate_match_fail_1(Anno, Args, As, Sub, #kern{ff=FF}) -> + AnnoFunc = case keyfind(function_name, 1, Anno) of + false -> + none; %Force rewrite. + {function_name,{Name,Arity}} -> + {get_fsub(Name, Arity, Sub),Arity} + end, + case {AnnoFunc,FF} of + {Same,Same} -> %% Still in the correct function. Args; - {[{name,{F,_}}],F} -> + {{F,_},F} -> %% Still in the correct function. Args; _ -> - %% Inlining has probably moved the function_clause into another - %% function (where it will not work correctly). - %% Rewrite to a case_clause. + %% Wrong function or no function_name annotation. + %% + %% The inliner has copied the match_fail(function_clause) + %% primop from another function (or from another instance of + %% the current function). match_fail(function_clause) will + %% only work at the top level of the function it was originally + %% defined in, so we will need to rewrite it to a case_clause. [#c_tuple{es=[#c_literal{val=case_clause},#c_tuple{es=As}]}] - end; -translate_match_fail(Args, _, _) -> Args. + end. %% call_type(Module, Function, Arity) -> call | bif | apply | error. %% Classify the call. @@ -980,11 +1003,6 @@ match_var([U|Us], Cs0, Def, St) -> %% according to type, the order is really irrelevant but tries to be %% smart. -match_con(Us, Cs0, Def, #kern{lit=no}=St) -> - %% No constant pool (for compatibility with R11B). - %% We must expand literals. - Cs = [expand_pat_lit_clause(C, true) || C <- Cs0], - match_con_1(Us, Cs, Def, St); match_con(Us, [C], Def, St) -> %% There is only one clause. We can keep literal tuples and %% lists, but we must convert []/integer/float/atom literals @@ -1783,7 +1801,6 @@ lit_vars(#k_int{}) -> []; lit_vars(#k_float{}) -> []; lit_vars(#k_atom{}) -> []; %%lit_vars(#k_char{}) -> []; -lit_vars(#k_string{}) -> []; lit_vars(#k_nil{}) -> []; lit_vars(#k_cons{hd=H,tl=T}) -> union(lit_vars(H), lit_vars(T)); @@ -1845,48 +1862,20 @@ handle_literal(#c_literal{anno=A,val=V}) -> case V of [_|_] -> #k_literal{anno=A,val=V}; + [] -> + #k_nil{anno=A}; V when is_tuple(V) -> #k_literal{anno=A,val=V}; V when is_bitstring(V) -> #k_literal{anno=A,val=V}; - _ -> - expand_literal(V, A) + V when is_integer(V) -> + #k_int{anno=A,val=V}; + V when is_float(V) -> + #k_float{anno=A,val=V}; + V when is_atom(V) -> + #k_atom{anno=A,val=V} end. -%% expand_literal(Literal, Anno) -> CoreTerm | KernelTerm -%% Fully expand the literal. Atomic terms such as integers are directly -%% translated to the Kernel Erlang format, while complex terms are kept -%% in the Core Erlang format (but the content is recursively processed). - -expand_literal([H|T]=V, A) when is_integer(H), 0 =< H, H =< 255 -> - case is_print_char_list(T) of - false -> - #c_cons{anno=A,hd=#k_int{anno=A,val=H},tl=expand_literal(T, A)}; - true -> - #k_string{anno=A,val=V} - end; -expand_literal([H|T], A) -> - #c_cons{anno=A,hd=expand_literal(H, A),tl=expand_literal(T, A)}; -expand_literal([], A) -> - #k_nil{anno=A}; -expand_literal(V, A) when is_tuple(V) -> - #c_tuple{anno=A,es=expand_literal_list(tuple_to_list(V), A)}; -expand_literal(V, A) when is_integer(V) -> - #k_int{anno=A,val=V}; -expand_literal(V, A) when is_float(V) -> - #k_float{anno=A,val=V}; -expand_literal(V, A) when is_atom(V) -> - #k_atom{anno=A,val=V}. - -expand_literal_list([H|T], A) -> - [expand_literal(H, A)|expand_literal_list(T, A)]; -expand_literal_list([], _) -> []. - -is_print_char_list([H|T]) when is_integer(H), 0 =< H, H =< 255 -> - is_print_char_list(T); -is_print_char_list([]) -> true; -is_print_char_list(_) -> false. - make_list(Es) -> foldr(fun(E, Acc) -> #c_cons{hd=E,tl=Acc} diff --git a/lib/compiler/src/v3_kernel_pp.erl b/lib/compiler/src/v3_kernel_pp.erl index b1ca907d11..a300dd283f 100644 --- a/lib/compiler/src/v3_kernel_pp.erl +++ b/lib/compiler/src/v3_kernel_pp.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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% %% %% Purpose : Kernel Erlang (naive) prettyprinter @@ -80,7 +80,6 @@ format_1(#k_atom{val=A}, _Ctxt) -> core_atom(A); format_1(#k_float{val=F}, _Ctxt) -> float_to_list(F); format_1(#k_int{val=I}, _Ctxt) -> integer_to_list(I); format_1(#k_nil{}, _Ctxt) -> "[]"; -format_1(#k_string{val=S}, _Ctxt) -> io_lib:write_string(S); format_1(#k_var{name=V}, _Ctxt) -> if is_atom(V) -> case atom_to_list(V) of diff --git a/lib/compiler/src/v3_life.erl b/lib/compiler/src/v3_life.erl index 0adeaca8fa..a7a4d4dc91 100644 --- a/lib/compiler/src/v3_life.erl +++ b/lib/compiler/src/v3_life.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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% %% %% Purpose : Convert annotated kernel expressions to annotated beam format. @@ -66,21 +66,27 @@ functions([], Acc) -> reverse(Acc). %% function(Kfunc) -> Func. function(#k_fdef{func=F,arity=Ar,vars=Vs,body=Kb}) -> - %ok = io:fwrite("life ~w: ~p~n~p~n", [?LINE,{F,Ar},Kb]), - As = var_list(Vs), - Vdb0 = foldl(fun ({var,N}, Vdb) -> new_var(N, 0, Vdb) end, [], As), - %% Force a top-level match! - B0 = case Kb of - #k_match{} -> Kb; - _ -> - Ka = get_kanno(Kb), - #k_match{anno=#k{us=Ka#k.us,ns=[],a=Ka#k.a}, - vars=Vs,body=Kb,ret=[]} - end, - put(guard_refc, 0), - {B1,_,Vdb1} = body(B0, 1, Vdb0), - erase(guard_refc), - {function,F,Ar,As,B1,Vdb1}. + try + As = var_list(Vs), + Vdb0 = foldl(fun ({var,N}, Vdb) -> new_var(N, 0, Vdb) end, [], As), + %% Force a top-level match! + B0 = case Kb of + #k_match{} -> Kb; + _ -> + Ka = get_kanno(Kb), + #k_match{anno=#k{us=Ka#k.us,ns=[],a=Ka#k.a}, + vars=Vs,body=Kb,ret=[]} + end, + put(guard_refc, 0), + {B1,_,Vdb1} = body(B0, 1, Vdb0), + erase(guard_refc), + {function,F,Ar,As,B1,Vdb1} + catch + Class:Error -> + Stack = erlang:get_stacktrace(), + io:fwrite("Function: ~w/~w\n", [F,Ar]), + erlang:raise(Class, Error, Stack) + end. %% body(Kbody, I, Vdb) -> {[Expr],MaxI,Vdb}. %% Handle a body, need special cases for transforming match_fails. @@ -355,8 +361,6 @@ match_fail(#k_literal{anno=Anno,val={Atom,Val}}, I, A) when is_atom(Atom) -> match_fail(#k_tuple{anno=Anno,es=[#k_atom{val=Atom},#k_literal{val=Val}]}, I, A); match_fail(#k_literal{anno=Anno,val={Atom}}, I, A) when is_atom(Atom) -> match_fail(#k_tuple{anno=Anno,es=[#k_atom{val=Atom}]}, I, A); -match_fail(#k_literal{anno=Anno,val=Atom}, I, A) when is_atom(Atom) -> - match_fail(#k_atom{anno=Anno,val=Atom}, I, A); match_fail(#k_tuple{es=[#k_atom{val=function_clause}|As]}, I, A) -> #l{ke={match_fail,{function_clause,literal_list(As, [])}},i=I,a=A}; match_fail(#k_tuple{es=[#k_atom{val=badmatch},Val]}, I, A) -> @@ -412,7 +416,6 @@ literal(#k_int{val=I}, _) -> {integer,I}; literal(#k_float{val=F}, _) -> {float,F}; literal(#k_atom{val=N}, _) -> {atom,N}; %%literal(#k_char{val=C}, _) -> {char,C}; -literal(#k_string{val=S}, _) -> {string,S}; literal(#k_nil{}, _) -> nil; literal(#k_cons{hd=H,tl=T}, Ctxt) -> {cons,[literal(H, Ctxt),literal(T, Ctxt)]}; @@ -437,7 +440,6 @@ literal2(#k_int{val=I}, _) -> {integer,I}; literal2(#k_float{val=F}, _) -> {float,F}; literal2(#k_atom{val=N}, _) -> {atom,N}; %%literal2(#k_char{val=C}, _) -> {char,C}; -literal2(#k_string{val=S}, _) -> {string,S}; literal2(#k_nil{}, _) -> nil; literal2(#k_cons{hd=H,tl=T}, Ctxt) -> {cons,[literal2(H, Ctxt),literal2(T, Ctxt)]}; diff --git a/lib/compiler/test/Makefile b/lib/compiler/test/Makefile index ad2f63e9e5..2d08e71e09 100644 --- a/lib/compiler/test/Makefile +++ b/lib/compiler/test/Makefile @@ -53,16 +53,24 @@ NO_OPT= \ record \ trycatch -R11= \ +INLINE= \ andor \ apply \ + bs_bincomp \ + bs_bit_binaries \ + bs_construct \ + bs_match \ + bs_utf \ + core_fold \ float \ fun \ + guard \ + lc \ match \ + misc \ num_bif \ receive \ - record \ - trycatch + record CORE_MODULES = \ bs_shadowed_size_var \ @@ -73,8 +81,8 @@ NO_OPT_MODULES= $(NO_OPT:%=%_no_opt_SUITE) NO_OPT_ERL_FILES= $(NO_OPT_MODULES:%=%.erl) POST_OPT_MODULES= $(NO_OPT:%=%_post_opt_SUITE) POST_OPT_ERL_FILES= $(POST_OPT_MODULES:%=%.erl) -R11_MODULES= $(R11:%=%_r11_SUITE) -R11_ERL_FILES= $(R11_MODULES:%=%.erl) +INLINE_MODULES= $(INLINE:%=%_inline_SUITE) +INLINE_ERL_FILES= $(INLINE_MODULES:%=%.erl) ERL_FILES= $(MODULES:%=%.erl) @@ -103,15 +111,15 @@ EBIN = . # Targets # ---------------------------------------------------- -make_emakefile: $(NO_OPT_ERL_FILES) $(POST_OPT_ERL_FILES) $(R11_ERL_FILES) +make_emakefile: $(NO_OPT_ERL_FILES) $(POST_OPT_ERL_FILES) $(INLINE_ERL_FILES) $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) \ > $(EMAKEFILE) $(ERL_TOP)/make/make_emakefile +no_copt +no_postopt $(ERL_COMPILE_FLAGS) \ -o$(EBIN) $(NO_OPT_MODULES) >> $(EMAKEFILE) $(ERL_TOP)/make/make_emakefile +no_copt $(ERL_COMPILE_FLAGS) \ -o$(EBIN) $(POST_OPT_MODULES) >> $(EMAKEFILE) - $(ERL_TOP)/make/make_emakefile +r11 $(ERL_COMPILE_FLAGS) \ - -o$(EBIN) $(R11_MODULES) >> $(EMAKEFILE) + $(ERL_TOP)/make/make_emakefile +inline $(ERL_COMPILE_FLAGS) \ + -o$(EBIN) $(INLINE_MODULES) >> $(EMAKEFILE) tests debug opt: make_emakefile erl $(ERL_MAKE_FLAGS) -make @@ -133,7 +141,7 @@ docs: %_post_opt_SUITE.erl: %_SUITE.erl sed -e 's;-module($(basename $<));-module($(basename $@));' $< > $@ -%_r11_SUITE.erl: %_SUITE.erl +%_inline_SUITE.erl: %_SUITE.erl sed -e 's;-module($(basename $<));-module($(basename $@));' $< > $@ # ---------------------------------------------------- @@ -148,7 +156,7 @@ release_tests_spec: make_emakefile $(INSTALL_DATA) compiler.dynspec compiler.cover \ $(EMAKEFILE) $(ERL_FILES) $(CORE_FILES) $(RELSYSDIR) $(INSTALL_DATA) $(NO_OPT_ERL_FILES) $(POST_OPT_ERL_FILES) \ - $(R11_ERL_FILES) $(RELSYSDIR) + $(INLINE_ERL_FILES) $(RELSYSDIR) chmod -f -R u+w $(RELSYSDIR) @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) diff --git a/lib/compiler/test/andor_SUITE.erl b/lib/compiler/test/andor_SUITE.erl index a460d54239..84cfd16e60 100644 --- a/lib/compiler/test/andor_SUITE.erl +++ b/lib/compiler/test/andor_SUITE.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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(andor_SUITE). @@ -141,6 +141,10 @@ t_and_or(Config) when is_list(Config) -> ok. +-define(GUARD(E), if E -> true; + true -> false + end). + t_andalso(Config) when is_list(Config) -> Bs = [true,false], Ps = [{X,Y} || X <- Bs, Y <- Bs], @@ -151,6 +155,11 @@ t_andalso(Config) when is_list(Config) -> ?line false = false andalso true, ?line false = false andalso false, + ?line true = ?GUARD(true andalso true), + ?line false = ?GUARD(true andalso false), + ?line false = ?GUARD(false andalso true), + ?line false = ?GUARD(false andalso false), + ?line false = false andalso glurf, ?line false = false andalso exit(exit_now), @@ -176,6 +185,11 @@ t_orelse(Config) when is_list(Config) -> ?line true = false orelse true, ?line false = false orelse false, + ?line true = ?GUARD(true orelse true), + ?line true = ?GUARD(true orelse false), + ?line true = ?GUARD(false orelse true), + ?line false = ?GUARD(false orelse false), + ?line true = true orelse glurf, ?line true = true orelse exit(exit_now), diff --git a/lib/compiler/test/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl index 5c2797170b..caaa587006 100644 --- a/lib/compiler/test/bs_match_SUITE.erl +++ b/lib/compiler/test/bs_match_SUITE.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -30,7 +30,8 @@ multiple_uses/1,zero_label/1,followed_by_catch/1, matching_meets_construction/1,simon/1,matching_and_andalso/1, otp_7188/1,otp_7233/1,otp_7240/1,otp_7498/1, - match_string/1,zero_width/1,bad_size/1,haystack/1]). + match_string/1,zero_width/1,bad_size/1,haystack/1, + cover_beam_bool/1]). -export([coverage_id/1]). @@ -45,7 +46,7 @@ all(suite) -> wfbm,degenerated_match,bs_sum,coverage,multiple_uses,zero_label, followed_by_catch,matching_meets_construction,simon,matching_and_andalso, otp_7188,otp_7233,otp_7240,otp_7498,match_string,zero_width,bad_size, - haystack]. + haystack,cover_beam_bool]. init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) -> Dog = test_server:timetrap(?t:minutes(1)), @@ -302,15 +303,15 @@ partitioned_bs_match(Config) when is_list(Config) -> ?line error = partitioned_bs_match(10, <<7,8,15,13>>), ?line error = partitioned_bs_match(100, {a,tuple,is,'not',a,binary}), ?line ok = partitioned_bs_match(0, <<>>), - ?line {'EXIT',{function_clause,[{?MODULE,partitioned_bs_match,[-1,blurf]}|_]}} = - (catch partitioned_bs_match(-1, blurf)), - ?line {'EXIT',{function_clause,[{?MODULE,partitioned_bs_match,[-1,<<1,2,3>>]}|_]}} = - (catch partitioned_bs_match(-1, <<1,2,3>>)), - + ?line fc(partitioned_bs_match, [-1,blurf], + catch partitioned_bs_match(-1, blurf)), + ?line fc(partitioned_bs_match, [-1,<<1,2,3>>], + catch partitioned_bs_match(-1, <<1,2,3>>)), ?line {17,<<1,2,3>>} = partitioned_bs_match_2(1, <<17,1,2,3>>), ?line {7,<<1,2,3>>} = partitioned_bs_match_2(7, <<17,1,2,3>>), - ?line {'EXIT',{function_clause,[{?MODULE,partitioned_bs_match_2,[4,<<0:17>>]}|_]}} = - (catch partitioned_bs_match_2(4, <<0:17>>)), + + ?line fc(partitioned_bs_match_2, [4,<<0:17>>], + catch partitioned_bs_match_2(4, <<0:17>>)), ok. partitioned_bs_match(_, <<42:8,T/binary>>) -> @@ -327,12 +328,10 @@ partitioned_bs_match_2(Len, <<_:8,T/binary>>) -> function_clause(Config) when is_list(Config) -> ?line ok = function_clause_1(<<0,7,0,7,42>>), - ?line {'EXIT',{function_clause, - [{?MODULE,function_clause_1,[<<0,1,2,3>>]}|_]}} = - (catch function_clause_1(<<0,1,2,3>>)), - ?line {'EXIT',{function_clause, - [{?MODULE,function_clause_1,[<<0,1,2,3>>]}|_]}} = - (catch function_clause_1(<<0,7,0,1,2,3>>)), + ?line fc(function_clause_1, [<<0,1,2,3>>], + catch function_clause_1(<<0,1,2,3>>)), + ?line fc(function_clause_1, [<<0,1,2,3>>], + catch function_clause_1(<<0,7,0,1,2,3>>)), ok. function_clause_1(<<0:8,7:8,T/binary>>) -> @@ -349,22 +348,17 @@ unit(Config) when is_list(Config) -> ?line 99 = peek8(<<99>>), ?line 100 = peek8(<<100,101>>), - ?line {'EXIT',{function_clause,[{?MODULE,peek8,[<<100,101,0:1>>]}|_]}} = - (catch peek8(<<100,101,0:1>>)), + ?line fc(peek8, [<<100,101,0:1>>], catch peek8(<<100,101,0:1>>)), ?line 37484 = peek16(<<37484:16>>), ?line 37489 = peek16(<<37489:16,5566:16>>), - ?line {'EXIT',{function_clause,[{?MODULE,peek16,[<<8>>]}|_]}} = - (catch peek16(<<8>>)), - ?line {'EXIT',{function_clause,[{?MODULE,peek16,[<<42:15>>]}|_]}} = - (catch peek16(<<42:15>>)), - ?line {'EXIT',{function_clause,[{?MODULE,peek16,[<<1,2,3,4,5>>]}|_]}} = - (catch peek16(<<1,2,3,4,5>>)), + ?line fc(peek16, [<<8>>], catch peek16(<<8>>)), + ?line fc(peek16, [<<42:15>>], catch peek16(<<42:15>>)), + ?line fc(peek16, [<<1,2,3,4,5>>], catch peek16(<<1,2,3,4,5>>)), ?line 127 = peek7(<<127:7>>), ?line 100 = peek7(<<100:7,19:7>>), - ?line {'EXIT',{function_clause,[{?MODULE,peek7,[<<1,2>>]}|_]}} = - (catch peek7(<<1,2>>)), + ?line fc(peek7, [<<1,2>>], catch peek7(<<1,2>>)), ok. peek1(<<B:8,_/bitstring>>) -> B. @@ -533,15 +527,13 @@ bs_sum(Config) when is_list(Config) -> ?line 6 = bs_sum_1([1,2,3|0]), ?line 7 = bs_sum_1([1,2,3|one]), - ?line {'EXIT',{function_clause,_}} = (catch bs_sum_1({too,big,tuple})), - ?line {'EXIT',{function_clause,_}} = (catch bs_sum_1([1,2,3|{too,big,tuple}])), + ?line fc(catch bs_sum_1({too,big,tuple})), + ?line fc(catch bs_sum_1([1,2,3|{too,big,tuple}])), ?line [] = sneaky_alias(<<>>), ?line [559,387655] = sneaky_alias(id(<<559:32,387655:32>>)), - ?line {'EXIT',{function_clause,[{?MODULE,sneaky_alias,[<<1>>]}|_]}} = - (catch sneaky_alias(id(<<1>>))), - ?line {'EXIT',{function_clause,[{?MODULE,sneaky_alias,[[1,2,3,4]]}|_]}} = - (catch sneaky_alias(lists:seq(1, 4))), + ?line fc(sneaky_alias, [<<1>>], catch sneaky_alias(id(<<1>>))), + ?line fc(sneaky_alias, [[1,2,3,4]], catch sneaky_alias(lists:seq(1, 4))), ok. bs_sum_1(<<H,T/binary>>) -> H+bs_sum_1(T); @@ -559,9 +551,9 @@ sneaky_alias(<<From:32,L/binary>>) -> [From|sneaky_alias(L)]. coverage(Config) when is_list(Config) -> ?line 0 = coverage_fold(fun(B, A) -> A+B end, 0, <<>>), ?line 6 = coverage_fold(fun(B, A) -> A+B end, 0, <<1,2,3>>), - ?line {'EXIT',{function_clause,_}} = (catch coverage_fold(fun(B, A) -> - A+B - end, 0, [a,b,c])), + ?line fc(catch coverage_fold(fun(B, A) -> + A+B + end, 0, [a,b,c])), ?line {<<>>,not_a_tuple} = coverage_build(<<>>, <<>>, not_a_tuple), ?line {<<16#76,"abc",16#A9,"abc">>,{x,42,43}} = @@ -573,9 +565,8 @@ coverage(Config) when is_list(Config) -> ?line do_coverage_bin_to_term_list([]), ?line do_coverage_bin_to_term_list([lists:seq(0, 10),{a,b,c},<<23:42>>]), - ?line {'EXIT',{function_clause, - [{?MODULE,coverage_bin_to_term_list,[<<0,0,0,7>>]}|_]}} = - (catch do_coverage_bin_to_term_list_1(<<7:32>>)), + ?line fc(coverage_bin_to_term_list, [<<0,0,0,7>>], + catch do_coverage_bin_to_term_list_1(<<7:32>>)), ?line <<>> = coverage_per_key(<<4:32>>), ?line <<$a,$b,$c>> = coverage_per_key(<<7:32,"abc">>), @@ -731,13 +722,12 @@ encode_octet_string(<<OctetString/binary>>, Len) -> simon(Config) when is_list(Config) -> ?line one = simon(blurf, <<>>), ?line two = simon(0, <<42>>), - ?line {'EXIT',{function_clause,[{?MODULE,simon,[17,<<1>>]}|_]}} = (catch simon(17, <<1>>)), - ?line {'EXIT',{function_clause,[{?MODULE,simon,[0,<<1,2,3>>]}|_]}} = (catch simon(0, <<1,2,3>>)), + ?line fc(simon, [17,<<1>>], catch simon(17, <<1>>)), + ?line fc(simon, [0,<<1,2,3>>], catch simon(0, <<1,2,3>>)), ?line one = simon2(blurf, <<9>>), ?line two = simon2(0, <<9,1>>), - ?line {'EXIT',{function_clause,[{?MODULE,simon2,[0,<<9,10,11>>]}|_]}} = - (catch simon2(0, <<9,10,11>>)), + ?line fc(simon2, [0,<<9,10,11>>], catch simon2(0, <<9,10,11>>)), ok. simon(_, <<>>) -> one; @@ -985,6 +975,36 @@ haystack_2(Haystack) -> B end || {X,Y} <- Subs ]. +fc({'EXIT',{function_clause,_}}) -> ok; +fc({'EXIT',{{case_clause,_},_}}) when ?MODULE =:= bs_match_inline_SUITE -> ok. + +fc(Name, Args, {'EXIT',{function_clause,[{?MODULE,Name,Args}|_]}}) -> ok; +fc(Name, Args, {'EXIT',{function_clause,[{?MODULE,Name,Arity}|_]}}) + when length(Args) =:= Arity -> + true = test_server:is_native(?MODULE); +fc(_, Args, {'EXIT',{{case_clause,ActualArgs},_}}) + when ?MODULE =:= bs_match_inline_SUITE -> + Args = tuple_to_list(ActualArgs). + +%% Cover the clause handling bs_context to binary in +%% beam_block:initialized_regs/2. +cover_beam_bool(Config) when is_list(Config) -> + ?line ok = do_cover_beam_bool(<<>>, 3), + ?line <<19>> = do_cover_beam_bool(<<19>>, 2), + ?line <<42>> = do_cover_beam_bool(<<42>>, 1), + ?line <<17>> = do_cover_beam_bool(<<13,17>>, 0), + ok. + +do_cover_beam_bool(Bin, X) when X > 0 -> + if + X =:= 1; X =:= 2 -> + Bin; + true -> + ok + end; +do_cover_beam_bool(<<_,Bin/binary>>, X) -> + do_cover_beam_bool(Bin, X+1). + check(F, R) -> R = F(). diff --git a/lib/compiler/test/bs_utf_SUITE.erl b/lib/compiler/test/bs_utf_SUITE.erl index d93bdef73d..4281874a24 100644 --- a/lib/compiler/test/bs_utf_SUITE.erl +++ b/lib/compiler/test/bs_utf_SUITE.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -314,7 +314,7 @@ coverage(Config) when is_list(Config) -> ?line 0 = coverage_2(<<4096/utf8,65536/utf8,0>>), ?line 1 = coverage_2(<<1024/utf8,1025/utf8,1>>), - ?line {'EXIT',{function_clause,_}} = (catch coverage_3(1)), + ?line fc(catch coverage_3(1)), %% Cover beam_flatten (combining the heap allocation in %% a subsequent test_heap instruction into the bs_init2 @@ -394,3 +394,5 @@ utf32_data() -> <<16#41:32/little,NotIdentical:32/little, 16#0391:32/little,16#2E:32/little>>}. +fc({'EXIT',{function_clause,_}}) -> ok; +fc({'EXIT',{{case_clause,_},_}}) when ?MODULE =:= bs_utf_inline_SUITE -> ok. diff --git a/lib/compiler/test/compilation_SUITE.erl b/lib/compiler/test/compilation_SUITE.erl index d4843c9eba..9c06740816 100644 --- a/lib/compiler/test/compilation_SUITE.erl +++ b/lib/compiler/test/compilation_SUITE.erl @@ -46,7 +46,7 @@ all(suite) -> trycatch_4, opt_crash, otp_5404,otp_5436,otp_5481,otp_5553,otp_5632, otp_5714,otp_5872,otp_6121,otp_6121a,otp_6121b, - otp_7202,otp_7345,on_load + otp_7202,otp_7345,on_load,string_table ]. -define(comp(N), @@ -596,4 +596,15 @@ otp_7345(ObjRef, _RdEnv, Args) -> 10}, id(LlUnitdataReq). +%% Check the generation of the string table. + +string_table(Config) when is_list(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line File = filename:join(DataDir, "string_table.erl"), + ?line {ok,string_table,Beam,[]} = compile:file(File, [return, binary]), + ?line {ok,{string_table,[StringTableChunk]}} = beam_lib:chunks(Beam, ["StrT"]), + ?line {"StrT", <<"stringabletringtable">>} = StringTableChunk, + ok. + + id(I) -> I. diff --git a/lib/compiler/test/compilation_SUITE_data/string_table.erl b/lib/compiler/test/compilation_SUITE_data/string_table.erl new file mode 100644 index 0000000000..1da1d015dd --- /dev/null +++ b/lib/compiler/test/compilation_SUITE_data/string_table.erl @@ -0,0 +1,8 @@ +-module(string_table). +-export([f/1, g/1]). + +f(<<"string">>) -> string; +f(<<"stringtable">>) -> stringtable. + +g(<<"stringtable">>) -> stringtable; +g(<<"table">>) -> table. diff --git a/lib/compiler/test/compile_SUITE.erl b/lib/compiler/test/compile_SUITE.erl index 7c3990a855..e1cc5dafb5 100644 --- a/lib/compiler/test/compile_SUITE.erl +++ b/lib/compiler/test/compile_SUITE.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% %% -module(compile_SUITE). @@ -625,7 +625,7 @@ core(Config) when is_list(Config) -> {raw_abstract_v1,Abstr}}]}} = beam_lib:chunks(Beam, [abstract_code]), {Mod,Abstr} end || Beam <- TestBeams], - ?line Res = p_run(fun(F) -> do_core(F, Outdir) end, Abstr), + ?line Res = test_lib:p_run(fun(F) -> do_core(F, Outdir) end, Abstr), ?line test_server:timetrap_cancel(Dog), Res. @@ -661,7 +661,7 @@ asm(Config) when is_list(Config) -> ?line Wc = filename:join(filename:dirname(code:which(?MODULE)), "*.beam"), ?line TestBeams = filelib:wildcard(Wc), - ?line Res = p_run(fun(F) -> do_asm(F, Outdir) end, TestBeams), + ?line Res = test_lib:p_run(fun(F) -> do_asm(F, Outdir) end, TestBeams), ?line test_server:timetrap_cancel(Dog), Res. @@ -688,35 +688,3 @@ do_asm(Beam, Outdir) -> [M,Class,Error,erlang:get_stacktrace()]), error end. - -%% p_run(fun() -> ok|error, List) -> ok -%% Will fail the test case if there were any errors. - -p_run(Test, List) -> - N = erlang:system_info(schedulers) + 1, - p_run_loop(Test, List, N, [], 0, 0). - -p_run_loop(_, [], _, [], Errors, Ws) -> - case Errors of - 0 -> - case Ws of - 0 -> ok; - 1 -> {comment,"1 core_lint failure"}; - N -> {comment,integer_to_list(N)++" core_lint failures"} - end; - N -> ?t:fail({N,errors}) - end; -p_run_loop(Test, [H|T], N, Refs, Errors, Ws) when length(Refs) < N -> - {_,Ref} = erlang:spawn_monitor(fun() -> exit(Test(H)) end), - p_run_loop(Test, T, N, [Ref|Refs], Errors, Ws); -p_run_loop(Test, List, N, Refs0, Errors0, Ws0) -> - receive - {'DOWN',Ref,process,_,Res} -> - {Errors,Ws} = case Res of - ok -> {Errors0,Ws0}; - error -> {Errors0+1,Ws0}; - warning -> {Errors0,Ws0+1} - end, - Refs = Refs0 -- [Ref], - p_run_loop(Test, List, N, Refs, Errors, Ws) - end. diff --git a/lib/compiler/test/compiler.cover b/lib/compiler/test/compiler.cover index 5ec2408a35..69d284ea6c 100644 --- a/lib/compiler/test/compiler.cover +++ b/lib/compiler/test/compiler.cover @@ -1,3 +1,3 @@ %% -*- erlang -*- -{exclude,[sys_pre_attributes,core_parse]}. +{exclude,[sys_pre_attributes,core_scan,core_parse]}. diff --git a/lib/compiler/test/core_SUITE_data/.gitignore b/lib/compiler/test/core_SUITE_data/.gitignore new file mode 100644 index 0000000000..d11d93d37f --- /dev/null +++ b/lib/compiler/test/core_SUITE_data/.gitignore @@ -0,0 +1 @@ +!*.core diff --git a/lib/compiler/test/error_SUITE.erl b/lib/compiler/test/error_SUITE.erl index cdd2434b25..ec58a0761e 100644 --- a/lib/compiler/test/error_SUITE.erl +++ b/lib/compiler/test/error_SUITE.erl @@ -21,11 +21,133 @@ -include("test_server.hrl"). -export([all/1, - head_mismatch_line/1,r11b_binaries/1,warnings_as_errors/1]). + head_mismatch_line/1,warnings_as_errors/1, bif_clashes/1]). all(suite) -> test_lib:recompile(?MODULE), - [head_mismatch_line,r11b_binaries,warnings_as_errors]. + [head_mismatch_line,warnings_as_errors,bif_clashes]. + + +bif_clashes(Config) when is_list(Config) -> + Ts = [{bif_clashes1, + <<" + -export([t/0]). + t() -> + length([a,b,c]). + + length(X) -> + erlang:length(X). + ">>, + [return_warnings], + {error, + [{4, erl_lint,{call_to_redefined_old_bif,{length,1}}}], []} }], + ?line [] = run(Config, Ts), + Ts1 = [{bif_clashes2, + <<" + -export([t/0]). + -import(x,[length/1]). + t() -> + length([a,b,c]). + ">>, + [return_warnings], + {error, + [{3, erl_lint,{redefine_old_bif_import,{length,1}}}], []} }], + ?line [] = run(Config, Ts1), + Ts00 = [{bif_clashes3, + <<" + -export([t/0]). + -compile({no_auto_import,[length/1]}). + t() -> + length([a,b,c]). + + length(X) -> + erlang:length(X). + ">>, + [return_warnings], + []}], + ?line [] = run(Config, Ts00), + Ts11 = [{bif_clashes4, + <<" + -export([t/0]). + -compile({no_auto_import,[length/1]}). + -import(x,[length/1]). + t() -> + length([a,b,c]). + ">>, + [return_warnings], + []}], + ?line [] = run(Config, Ts11), + Ts000 = [{bif_clashes5, + <<" + -export([t/0]). + t() -> + binary_part(<<1,2,3,4>>,1,2). + + binary_part(X,Y,Z) -> + erlang:binary_part(X,Y,Z). + ">>, + [return_warnings], + {warning, + [{4, erl_lint,{call_to_redefined_bif,{binary_part,3}}}]} }], + ?line [] = run(Config, Ts000), + Ts111 = [{bif_clashes6, + <<" + -export([t/0]). + -import(x,[binary_part/3]). + t() -> + binary_part(<<1,2,3,4>>,1,2). + ">>, + [return_warnings], + {warning, + [{3, erl_lint,{redefine_bif_import,{binary_part,3}}}]} }], + ?line [] = run(Config, Ts111), + Ts2 = [{bif_clashes7, + <<" + -export([t/0]). + -compile({no_auto_import,[length/1]}). + -import(x,[length/1]). + t() -> + length([a,b,c]). + length(X) -> + erlang:length(X). + ">>, + [], + {error, + [{7,erl_lint,{define_import,{length,1}}}], + []} }], + ?line [] = run2(Config, Ts2), + Ts3 = [{bif_clashes8, + <<" + -export([t/1]). + -compile({no_auto_import,[length/1]}). + t(X) when length(X) > 3 -> + length([a,b,c]). + length(X) -> + erlang:length(X). + ">>, + [], + {error, + [{4,erl_lint,{illegal_guard_local_call,{length,1}}}], + []} }], + ?line [] = run2(Config, Ts3), + Ts4 = [{bif_clashes9, + <<" + -export([t/1]). + -compile({no_auto_import,[length/1]}). + -import(x,[length/1]). + t(X) when length(X) > 3 -> + length([a,b,c]). + ">>, + [], + {error, + [{5,erl_lint,{illegal_guard_local_call,{length,1}}}], + []} }], + ?line [] = run2(Config, Ts4), + + ok. + + + %% Tests that a head mismatch is reported on the correct line (OTP-2125). head_mismatch_line(Config) when is_list(Config) -> @@ -42,37 +164,6 @@ get_compilation_errors(Config, Filename) -> ?line {error, [{_Name, E}|_], []} = compile:file(File, [return_errors]), E. -r11b_binaries(Config) when is_list(Config) -> - Ts = [{r11b_binaries, - <<" - t1(Bin) -> - case Bin of - _ when size(Bin) > 20 -> erlang:error(too_long); - <<_,T/binary>> -> t1(T); - <<>> -> ok - end. - - t2(<<_,T/bytes>>) -> - split_binary(T, 4). - - t3(X) -> - <<42,X/binary>>. - - t4(X) -> - <<N:32>> = X, - N. - ">>, - [r11], - {error, - [{5,v3_core,no_binaries}, - {6,v3_core,no_binaries}, - {9,v3_core,no_binaries}, - {13,v3_core,no_binaries}, - {16,v3_core,no_binaries}], - []} }], - ?line [] = run(Config, Ts), - ok. - warnings_as_errors(Config) when is_list(Config) -> Ts = [{warnings_as_errors, <<" @@ -80,7 +171,7 @@ warnings_as_errors(Config) when is_list(Config) -> A = unused, ok. ">>, - [warnings_as_errors], + [export_all,warnings_as_errors], {error, [], [{3,erl_lint,{unused_var,'A'}}]} }], @@ -101,6 +192,24 @@ run(Config, Tests) -> end, lists:foldl(F, [], Tests). +run2(Config, Tests) -> + F = fun({N,P,Ws,E}, BadL) -> + case catch filter(run_test(Config, P, Ws)) of + E -> + BadL; + Bad -> + ?t:format("~nTest ~p failed. Expected~n ~p~n" + "but got~n ~p~n", [N, E, Bad]), + fail() + end + end, + lists:foldl(F, [], Tests). + +filter({error,Es,_Ws}) -> + {error,Es,[]}; +filter(X) -> + X. + %% Compiles a test module and returns the list of errors and warnings. @@ -109,17 +218,29 @@ run_test(Conf, Test0, Warnings) -> ?line DataDir = ?config(priv_dir, Conf), ?line Test = ["-module(errors_test). ", Test0], ?line File = filename:join(DataDir, Filename), - ?line Opts = [binary,export_all,return|Warnings], + ?line Opts = [binary,return_errors|Warnings], ?line ok = file:write_file(File, Test), %% Compile once just to print all errors and warnings. - ?line compile:file(File, [binary,export_all,report|Warnings]), + ?line compile:file(File, [binary,report|Warnings]), %% Test result of compilation. ?line Res = case compile:file(File, Opts) of - {error,[{_File,Es}],Ws} -> + {ok,errors_test,_,[{_File,Ws}]} -> + %io:format("compile:file(~s,~p) ->~n~p~n", + % [File,Opts,Ws]), + {warning,Ws}; + {ok,errors_test,_,[]} -> + %io:format("compile:file(~s,~p) ->~n~p~n", + % [File,Opts,Ws]), + []; + {error,[{XFile,Es}],Ws} = _ZZ when is_list(XFile) -> + %io:format("compile:file(~s,~p) ->~n~p~n", + % [File,Opts,_ZZ]), {error,Es,Ws}; - {error,Es,[{_File,Ws}]} -> + {error,Es,[{_File,Ws}]} = _ZZ-> + %io:format("compile:file(~s,~p) ->~n~p~n", + % [File,Opts,_ZZ]), {error,Es,Ws} end, file:delete(File), diff --git a/lib/compiler/test/float_SUITE.erl b/lib/compiler/test/float_SUITE.erl index 3d2dbf47e9..b48b1daa32 100644 --- a/lib/compiler/test/float_SUITE.erl +++ b/lib/compiler/test/float_SUITE.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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(float_SUITE). @@ -41,7 +41,7 @@ float_sub(A)-> float_mul(0, _, _)-> ok; float_mul(Iter, A, B) when is_float(A), is_float(B) -> - A*B, + _ = A*B, float_mul(Iter-1, A, B). %% Thanks to Mikael Pettersson and Tobias Lindahl (HiPE). @@ -82,6 +82,14 @@ bad_negate(X, Y) when is_float(X) -> Y1 = -Y, %BIF call. {X2, Y1}. +%% Some math functions are not implemented on all platforms. +-define(OPTIONAL(Expected, Expr), + try + Expected = Expr + catch + error:undef -> ok + end). + math_functions(Config) when is_list(Config) -> %% Mostly silly coverage. ?line 0.0 = math:tan(0), @@ -93,6 +101,14 @@ math_functions(Config) when is_list(Config) -> ?line -1.0 = math:cos(math:pi()), ?line 1.0 = math:exp(0), ?line 1.0 = math:pow(math:pi(), 0), + ?line 0.0 = math:log(1), + ?line 0.0 = math:asin(0), + ?line 0.0 = math:acos(1), + ?line ?OPTIONAL(0.0, math:asinh(0)), + ?line ?OPTIONAL(0.0, math:acosh(1)), + ?line ?OPTIONAL(0.0, math:atanh(0)), + ?line ?OPTIONAL(0.0, math:erf(0)), + ?line ?OPTIONAL(1.0, math:erfc(0)), ?line 0.0 = math:tan(id(0)), ?line 0.0 = math:atan2(id(0), 1), @@ -101,6 +117,14 @@ math_functions(Config) when is_list(Config) -> ?line 0.0 = math:tanh(id(0)), ?line 1.0 = math:log10(id(10)), ?line 1.0 = math:exp(id(0)), + ?line 0.0 = math:log(id(1)), + ?line 0.0 = math:asin(id(0)), + ?line 0.0 = math:acos(id(1)), + ?line ?OPTIONAL(0.0, math:asinh(id(0))), + ?line ?OPTIONAL(0.0, math:acosh(id(1))), + ?line ?OPTIONAL(0.0, math:atanh(id(0))), + ?line ?OPTIONAL(0.0, math:erf(id(0))), + ?line ?OPTIONAL(1.0, math:erfc(id(0))), %% Only for coverage (of beam_type.erl). ?line {'EXIT',{undef,_}} = (catch math:fnurfla(0)), diff --git a/lib/compiler/test/guard_SUITE.erl b/lib/compiler/test/guard_SUITE.erl index 5ae41f13e7..8f23bd2e5a 100644 --- a/lib/compiler/test/guard_SUITE.erl +++ b/lib/compiler/test/guard_SUITE.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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(guard_SUITE). @@ -31,7 +31,7 @@ t_is_boolean/1,is_function_2/1, tricky/1,rel_ops/1,literal_type_tests/1, basic_andalso_orelse/1,traverse_dcd/1, - check_qlc_hrl/1,andalso_semi/1,tuple_size/1]). + check_qlc_hrl/1,andalso_semi/1,t_tuple_size/1,binary_part/1]). all(suite) -> test_lib:recompile(?MODULE), @@ -43,7 +43,7 @@ all(suite) -> build_in_guard,old_guard_tests,gbif, t_is_boolean,is_function_2,tricky,rel_ops,literal_type_tests, basic_andalso_orelse,traverse_dcd,check_qlc_hrl,andalso_semi, - tuple_size]. + t_tuple_size,binary_part]. misc(Config) when is_list(Config) -> ?line 42 = case id(42) of @@ -1316,11 +1316,11 @@ cqlc(M, F, As, St) -> andalso_semi(Config) when is_list(Config) -> ?line ok = andalso_semi_foo(0), ?line ok = andalso_semi_foo(1), - ?line {'EXIT',{function_clause,_}} = (catch andalso_semi_foo(2)), + ?line fc(catch andalso_semi_foo(2)), ?line ok = andalso_semi_bar([a,b,c]), ?line ok = andalso_semi_bar(1), - ?line {'EXIT',{function_clause,_}} = (catch andalso_semi_bar([a,b])), + ?line fc(catch andalso_semi_bar([a,b])), ok. andalso_semi_foo(Bar) when is_integer(Bar) andalso Bar =:= 0; Bar =:= 1 -> @@ -1330,10 +1330,10 @@ andalso_semi_bar(Bar) when is_list(Bar) andalso length(Bar) =:= 3; Bar =:= 1 -> ok. -tuple_size(Config) when is_list(Config) -> +t_tuple_size(Config) when is_list(Config) -> ?line 10 = do_tuple_size({1,2,3,4}), - ?line {'EXIT',{function_clause,_}} = (catch do_tuple_size({1,2,3})), - ?line {'EXIT',{function_clause,_}} = (catch do_tuple_size(42)), + ?line fc(catch do_tuple_size({1,2,3})), + ?line fc(catch do_tuple_size(42)), ?line error = ludicrous_tuple_size({a,b,c}), ?line error = ludicrous_tuple_size([a,b,c]), @@ -1362,6 +1362,146 @@ ludicrous_tuple_size(T) when tuple_size(T) =:= 16#FFFFFFFFFFFFFFFF -> ok; ludicrous_tuple_size(_) -> error. +%% +%% The binary_part/2,3 guard BIFs +%% +-define(MASK_ERROR(EXPR),mask_error((catch (EXPR)))). +mask_error({'EXIT',{Err,_}}) -> + Err; +mask_error(Else) -> + Else. + +binary_part(doc) -> + ["Tests the binary_part/2,3 guard (GC) bif's"]; +binary_part(Config) when is_list(Config) -> + %% This is more or less a copy of what the guard_SUITE in emulator + %% does to cover the guard bif's + ?line 1 = bptest(<<1,2,3>>), + ?line 2 = bptest(<<2,1,3>>), + ?line error = bptest(<<1>>), + ?line error = bptest(<<>>), + ?line error = bptest(apa), + ?line 3 = bptest(<<2,3,3>>), + % With one variable (pos) + ?line 1 = bptest(<<1,2,3>>,1), + ?line 2 = bptest(<<2,1,3>>,1), + ?line error = bptest(<<1>>,1), + ?line error = bptest(<<>>,1), + ?line error = bptest(apa,1), + ?line 3 = bptest(<<2,3,3>>,1), + % With one variable (length) + ?line 1 = bptesty(<<1,2,3>>,1), + ?line 2 = bptesty(<<2,1,3>>,1), + ?line error = bptesty(<<1>>,1), + ?line error = bptesty(<<>>,1), + ?line error = bptesty(apa,1), + ?line 3 = bptesty(<<2,3,3>>,2), + % With one variable (whole tuple) + ?line 1 = bptestx(<<1,2,3>>,{1,1}), + ?line 2 = bptestx(<<2,1,3>>,{1,1}), + ?line error = bptestx(<<1>>,{1,1}), + ?line error = bptestx(<<>>,{1,1}), + ?line error = bptestx(apa,{1,1}), + ?line 3 = bptestx(<<2,3,3>>,{1,2}), + % With two variables + ?line 1 = bptest(<<1,2,3>>,1,1), + ?line 2 = bptest(<<2,1,3>>,1,1), + ?line error = bptest(<<1>>,1,1), + ?line error = bptest(<<>>,1,1), + ?line error = bptest(apa,1,1), + ?line 3 = bptest(<<2,3,3>>,1,2), + % Direct (autoimported) call, these will be evaluated by the compiler... + ?line <<2>> = binary_part(<<1,2,3>>,1,1), + ?line <<1>> = binary_part(<<2,1,3>>,1,1), + % Compiler warnings due to constant evaluation expected (3) + ?line badarg = ?MASK_ERROR(binary_part(<<1>>,1,1)), + ?line badarg = ?MASK_ERROR(binary_part(<<>>,1,1)), + ?line badarg = ?MASK_ERROR(binary_part(apa,1,1)), + ?line <<3,3>> = binary_part(<<2,3,3>>,1,2), + % Direct call through apply + ?line <<2>> = apply(erlang,binary_part,[<<1,2,3>>,1,1]), + ?line <<1>> = apply(erlang,binary_part,[<<2,1,3>>,1,1]), + % Compiler warnings due to constant evaluation expected (3) + ?line badarg = ?MASK_ERROR(apply(erlang,binary_part,[<<1>>,1,1])), + ?line badarg = ?MASK_ERROR(apply(erlang,binary_part,[<<>>,1,1])), + ?line badarg = ?MASK_ERROR(apply(erlang,binary_part,[apa,1,1])), + ?line <<3,3>> = apply(erlang,binary_part,[<<2,3,3>>,1,2]), + % Constant propagation + ?line Bin = <<1,2,3>>, + ?line ok = if + binary_part(Bin,1,1) =:= <<2>> -> + ok; + %% Compiler warning, clause cannot match (expected) + true -> + error + end, + ?line ok = if + binary_part(Bin,{1,1}) =:= <<2>> -> + ok; + %% Compiler warning, clause cannot match (expected) + true -> + error + end, + ok. + + +bptest(B) when length(B) =:= 1337 -> + 1; +bptest(B) when binary_part(B,{1,1}) =:= <<2>> -> + 1; +bptest(B) when erlang:binary_part(B,1,1) =:= <<1>> -> + 2; +bptest(B) when erlang:binary_part(B,{1,2}) =:= <<3,3>> -> + 3; +bptest(_) -> + error. + +bptest(B,A) when length(B) =:= A -> + 1; +bptest(B,A) when binary_part(B,{A,1}) =:= <<2>> -> + 1; +bptest(B,A) when erlang:binary_part(B,A,1) =:= <<1>> -> + 2; +bptest(B,A) when erlang:binary_part(B,{A,2}) =:= <<3,3>> -> + 3; +bptest(_,_) -> + error. + +bptestx(B,A) when length(B) =:= A -> + 1; +bptestx(B,A) when binary_part(B,A) =:= <<2>> -> + 1; +bptestx(B,A) when erlang:binary_part(B,A) =:= <<1>> -> + 2; +bptestx(B,A) when erlang:binary_part(B,A) =:= <<3,3>> -> + 3; +bptestx(_,_) -> + error. + +bptesty(B,A) when length(B) =:= A -> + 1; +bptesty(B,A) when binary_part(B,{1,A}) =:= <<2>> -> + 1; +bptesty(B,A) when erlang:binary_part(B,1,A) =:= <<1>> -> + 2; +bptesty(B,A) when erlang:binary_part(B,{1,A}) =:= <<3,3>> -> + 3; +bptesty(_,_) -> + error. + +bptest(B,A,_C) when length(B) =:= A -> + 1; +bptest(B,A,C) when binary_part(B,{A,C}) =:= <<2>> -> + 1; +bptest(B,A,C) when erlang:binary_part(B,A,C) =:= <<1>> -> + 2; +bptest(B,A,C) when erlang:binary_part(B,{A,C}) =:= <<3,3>> -> + 3; +bptest(_,_,_) -> + error. + + + %% Call this function to turn off constant propagation. id(I) -> I. @@ -1374,3 +1514,6 @@ check(F, Result) -> io:format(" Got: ~p\n", [Other]), test_server:fail() end. + +fc({'EXIT',{function_clause,_}}) -> ok; +fc({'EXIT',{{case_clause,_},_}}) when ?MODULE =:= guard_inline_SUITE -> ok. diff --git a/lib/compiler/test/inline_SUITE_data/decode1.erl b/lib/compiler/test/inline_SUITE_data/decode1.erl index d51bedcb2e..9b4fc071a3 100644 --- a/lib/compiler/test/inline_SUITE_data/decode1.erl +++ b/lib/compiler/test/inline_SUITE_data/decode1.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %---------------------------------------------------------------------- @@ -37,25 +37,25 @@ FrameList = [89,128,0,8,132,0,26,133,133,0,38,148,94, 128,0,2,129,128,92,128,0,2,0,0,112,128,0, 10,194,69,0,0,0,0,0,18,52,95], - Frame = concat_binary([list_to_binary([89]),list_to_binary([128]), - list_to_binary([0]),list_to_binary([8]), - list_to_binary([132]),list_to_binary([0]), - list_to_binary([26]),list_to_binary([133]), - list_to_binary([133]),list_to_binary([0]), - list_to_binary([38]),list_to_binary([148]), - list_to_binary([94]),list_to_binary([128]), - list_to_binary([0]),list_to_binary([2]), - list_to_binary([129]),list_to_binary([128]), - list_to_binary([92]),list_to_binary([128]), - list_to_binary([0]),list_to_binary([2]), - list_to_binary([0]),list_to_binary([0]), - list_to_binary([112]),list_to_binary([128]), - list_to_binary([0]),list_to_binary([10]), - list_to_binary([194]),list_to_binary([69]), - list_to_binary([0]),list_to_binary([0]), - list_to_binary([0]),list_to_binary([0]), - list_to_binary([0]),list_to_binary([18]), - list_to_binary([52]),list_to_binary([95])]), + Frame = list_to_binary([list_to_binary([89]),list_to_binary([128]), + list_to_binary([0]),list_to_binary([8]), + list_to_binary([132]),list_to_binary([0]), + list_to_binary([26]),list_to_binary([133]), + list_to_binary([133]),list_to_binary([0]), + list_to_binary([38]),list_to_binary([148]), + list_to_binary([94]),list_to_binary([128]), + list_to_binary([0]),list_to_binary([2]), + list_to_binary([129]),list_to_binary([128]), + list_to_binary([92]),list_to_binary([128]), + list_to_binary([0]),list_to_binary([2]), + list_to_binary([0]),list_to_binary([0]), + list_to_binary([112]),list_to_binary([128]), + list_to_binary([0]),list_to_binary([10]), + list_to_binary([194]),list_to_binary([69]), + list_to_binary([0]),list_to_binary([0]), + list_to_binary([0]),list_to_binary([0]), + list_to_binary([0]),list_to_binary([18]), + list_to_binary([52]),list_to_binary([95])]), R = loop(2,0,Frame), {R,R =:= {0,[{ie,112,itu_t_standard,ignore,10,<<194,69,0,0,0,0,0,18,52,95>>}, diff --git a/lib/compiler/test/lc_SUITE.erl b/lib/compiler/test/lc_SUITE.erl index e62b2cd77e..40bf67e1fa 100644 --- a/lib/compiler/test/lc_SUITE.erl +++ b/lib/compiler/test/lc_SUITE.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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(lc_SUITE). @@ -66,8 +66,7 @@ basic(Config) when is_list(Config) -> ?line {'EXIT',_} = (catch [X || X <- L1, list_to_atom(X) == dum]), ?line [] = [X || X <- L1, X+1 < 2], ?line {'EXIT',_} = (catch [X || X <- L1, odd(X)]), - ?line {'EXIT',{function_clause,[{?MODULE,_,[x]}|_]}} = - (catch [E || E <- id(x)]), + ?line fc([x], catch [E || E <- id(x)]), ok. tuple_list() -> @@ -160,3 +159,10 @@ empty_generator(Config) when is_list(Config) -> id(I) -> I. +fc(Args, {'EXIT',{function_clause,[{?MODULE,_,Args}|_]}}) -> ok; +fc(Args, {'EXIT',{function_clause,[{?MODULE,Name,Arity}|_]}}) + when length(Args) =:= Arity -> + true = test_server:is_native(?MODULE); +fc(Args, {'EXIT',{{case_clause,ActualArgs},_}}) + when ?MODULE =:= lc_inline_SUITE -> + Args = tuple_to_list(ActualArgs). diff --git a/lib/compiler/test/match_SUITE.erl b/lib/compiler/test/match_SUITE.erl index 20969c0b26..fd51b777ac 100644 --- a/lib/compiler/test/match_SUITE.erl +++ b/lib/compiler/test/match_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% 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(match_SUITE). @@ -21,14 +21,14 @@ -export([all/1, pmatch/1,mixed/1,aliases/1,match_in_call/1, untuplify/1,shortcut_boolean/1,letify_guard/1, - selectify/1]). + selectify/1,underscore/1]). -include("test_server.hrl"). all(suite) -> test_lib:recompile(?MODULE), [pmatch,mixed,aliases,match_in_call,untuplify,shortcut_boolean, - letify_guard,selectify]. + letify_guard,selectify,underscore]. pmatch(Config) when is_list(Config) -> ?line ok = doit(1), @@ -112,6 +112,12 @@ aliases(Config) when is_list(Config) -> ?line {42,42,42,42} = multiple_aliases_1(42), ?line {7,7,7} = multiple_aliases_2(7), ?line {{a,b},{a,b},{a,b}} = multiple_aliases_3({a,b}), + + %% Lists/literals. + ?line {a,b} = list_alias1([a,b]), + ?line {a,b} = list_alias2([a,b]), + ?line {a,b} = list_alias3([a,b]), + ok. str_alias(V) -> @@ -206,6 +212,15 @@ multiple_aliases_2((A=B)=(A=C)) -> multiple_aliases_3((A={_,_}=B)={_,_}=C) -> {A,B,C}. +list_alias1([a,b]=[X,Y]) -> + {X,Y}. + +list_alias2([X,Y]=[a,b]) -> + {X,Y}. + +list_alias3([X,b]=[a,Y]) -> + {X,Y}. + %% OTP-7018. match_in_call(Config) when is_list(Config) -> @@ -352,4 +367,16 @@ sel_same_value2(V) when V =:= 42; V =:= 43 -> sel_same_value2(_) -> error. +underscore(Config) when is_list(Config) -> + case Config of + [] -> + %% Assignment to _ at the end of a construct. + _ = length(Config); + [_|_] -> + %% Assignment to _ at the end of a construct. + _ = list_to_tuple(Config) + end, + _ = is_list(Config), + ok. + id(I) -> I. diff --git a/lib/compiler/test/misc_SUITE.erl b/lib/compiler/test/misc_SUITE.erl index e096571d50..450a4e279d 100644 --- a/lib/compiler/test/misc_SUITE.erl +++ b/lib/compiler/test/misc_SUITE.erl @@ -1,29 +1,46 @@ %% %% %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 %% 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(misc_SUITE). -export([all/1,init_per_testcase/2,fin_per_testcase/2, tobias/1,empty_string/1,md5/1,silly_coverage/1, - confused_literals/1,integer_encoding/1]). + confused_literals/1,integer_encoding/1,override_bif/1]). -include("test_server.hrl"). +%% For the override_bif testcase. +%% NB, no other testcases in this testsuite can use these without erlang:prefix! +-compile({no_auto_import,[abs/1]}). +-compile({no_auto_import,[binary_part/3]}). +-compile({no_auto_import,[binary_part/2]}). +-import(test_lib,[binary_part/2]). + +%% This should do no harm (except for fun byte_size/1 which does not, by design, work with import +-compile({no_auto_import,[byte_size/1]}). +-import(erlang,[byte_size/1]). + + + +%% Include an opaque declaration to cover the stripping of +%% opaque types from attributes in v3_kernel. +-opaque misc_SUITE_test_cases() :: [atom()]. + init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) -> Dog = test_server:timetrap(?t:minutes(10)), [{watchdog,Dog}|Config]. @@ -33,10 +50,44 @@ fin_per_testcase(Case, Config) when is_atom(Case), is_list(Config) -> ?t:timetrap_cancel(Dog), ok. +-spec all(any()) -> misc_SUITE_test_cases(). + all(suite) -> test_lib:recompile(?MODULE), [tobias,empty_string,md5,silly_coverage,confused_literals, - integer_encoding]. + integer_encoding, override_bif]. + + +%% +%% Functions that override new and old bif's +%% +abs(_N) -> + dummy_abs. + +binary_part(_,_,_) -> + dummy_bp. + +% Make sure that auto-imported BIF's are overridden correctly + +override_bif(suite) -> + []; +override_bif(doc) -> + ["Test dat local functions and imports override auto-imported BIFs."]; +override_bif(Config) when is_list(Config) -> + ?line dummy_abs = abs(1), + ?line dummy_bp = binary_part(<<"hello">>,1,1), + ?line dummy = binary_part(<<"hello">>,{1,1}), + ?line 1 = erlang:abs(1), + ?line <<"e">> = erlang:binary_part(<<"hello">>,1,1), + ?line <<"e">> = erlang:binary_part(<<"hello">>,{1,1}), + F = fun(X) when byte_size(X) =:= 4 -> + four; + (X) -> + byte_size(X) + end, + ?line four = F(<<1,2,3,4>>), + ?line 5 = F(<<1,2,3,4,5>>), + ok. %% A bug reported by Tobias Lindahl for a development version of R11B. @@ -92,13 +143,23 @@ md5_1(Beam) -> silly_coverage(Config) when is_list(Config) -> %% sys_core_fold, sys_core_setel, v3_kernel BadCoreErlang = {c_module,[], - name,exports,attrs, + name,[],[], [{{c_var,[],{foo,2}},seriously_bad_body}]}, ?line expect_error(fun() -> sys_core_fold:module(BadCoreErlang, []) end), ?line expect_error(fun() -> sys_core_dsetel:module(BadCoreErlang, []) end), ?line expect_error(fun() -> v3_kernel:module(BadCoreErlang, []) end), - %% v3_codgen + %% v3_life + BadKernel = {k_mdef,[],?MODULE, + [{foo,0}], + [], + [{k_fdef, + {k,[],[],[]}, + f,0,[], + seriously_bad_body}]}, + ?line expect_error(fun() -> v3_life:module(BadKernel, []) end), + + %% v3_codegen CodegenInput = {?MODULE,[{foo,0}],[],[{function,foo,0,[a|b],a,b}]}, ?line expect_error(fun() -> v3_codegen:module(CodegenInput, []) end), @@ -154,6 +215,17 @@ silly_coverage(Config) when is_list(Config) -> {test,bs_get_binary2,{f,99},0,[{x,0},{atom,all},1,[]],{x,0}}, {block,[a|b]}]}],0}, ?line expect_error(fun() -> beam_bsm:module(BsmInput, []) end), + + %% beam_receive. + ReceiveInput = {?MODULE,[{foo,0}],[], + [{function,foo,0,2, + [{label,1}, + {func_info,{atom,?MODULE},{atom,foo},0}, + {label,2}, + {call_ext,0,{extfunc,erlang,make_ref,0}}, + {block,[a|b]}]}],0}, + ?line expect_error(fun() -> beam_receive:module(ReceiveInput, []) end), + ok. expect_error(Fun) -> diff --git a/lib/compiler/test/num_bif_SUITE.erl b/lib/compiler/test/num_bif_SUITE.erl index c246f56611..912f7366dd 100644 --- a/lib/compiler/test/num_bif_SUITE.erl +++ b/lib/compiler/test/num_bif_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% 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(num_bif_SUITE). @@ -166,7 +166,7 @@ t_list_to_float_safe(Config) when is_list(Config) -> t_list_to_float_risky(Config) when is_list(Config) -> ?line Many_Ones = lists:duplicate(25000, $1), - ?line list_to_float("2."++Many_Ones), + ?line _ = list_to_float("2."++Many_Ones), ?line {'EXIT', {badarg, _}} = (catch list_to_float("2"++Many_Ones)), ok. @@ -186,7 +186,7 @@ t_list_to_integer(Config) when is_list(Config) -> %% Bignums. ?line 123456932798748738738 = list_to_integer("123456932798748738738"), - ?line list_to_integer(lists:duplicate(2000, $1)), + ?line _ = list_to_integer(lists:duplicate(2000, $1)), ok. %% Tests round/1. diff --git a/lib/compiler/test/pmod_SUITE.erl b/lib/compiler/test/pmod_SUITE.erl index 293e110c45..13503ce905 100644 --- a/lib/compiler/test/pmod_SUITE.erl +++ b/lib/compiler/test/pmod_SUITE.erl @@ -38,8 +38,8 @@ fin_per_testcase(Case, Config) when is_atom(Case), is_list(Config) -> basic(Config) when is_list(Config) -> ?line basic_1(Config, []), -% ?line basic_1(Config, [inline]), -% ?line basic_1(Config, [{inline,500},inline]), + ?line basic_1(Config, [inline]), + ?line basic_1(Config, [{inline,500},inline]), ok. basic_1(Config, Opts) -> diff --git a/lib/compiler/test/receive_SUITE.erl b/lib/compiler/test/receive_SUITE.erl index cb8833759a..fca3f0387b 100644 --- a/lib/compiler/test/receive_SUITE.erl +++ b/lib/compiler/test/receive_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% 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% %% %%% Purpose : Compiles various modules with tough code @@ -21,7 +21,7 @@ -module(receive_SUITE). -export([all/1,init_per_testcase/2,fin_per_testcase/2, - recv/1,coverage/1,otp_7980/1]). + recv/1,coverage/1,otp_7980/1,ref_opt/1]). -include("test_server.hrl"). @@ -36,7 +36,7 @@ fin_per_testcase(_Case, Config) -> all(suite) -> test_lib:recompile(?MODULE), - [recv,coverage,otp_7980]. + [recv,coverage,otp_7980,ref_opt]. -record(state, {ena = true}). @@ -157,5 +157,52 @@ otp_7980_add_clients(Count) -> end, N - 1 end, Count, [1,2,3]). - + +ref_opt(Config) when is_list(Config) -> + case ?MODULE of + receive_SUITE -> ref_opt_1(Config); + _ -> {skip,"Enough to run this case once."} + end. + +ref_opt_1(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line PrivDir = ?config(priv_dir, Config), + ?line Sources = filelib:wildcard(filename:join([DataDir,"ref_opt","*.erl"])), + ?line test_lib:p_run(fun(Src) -> + do_ref_opt(Src, PrivDir) + end, Sources), + ok. + +do_ref_opt(Source, PrivDir) -> + try + {ok,Mod} = c:c(Source, [{outdir,PrivDir}]), + ok = Mod:Mod(), + Base = filename:rootname(filename:basename(Source), ".erl"), + BeamFile = filename:join(PrivDir, Base), + {beam_file,Mod,_,_,_,Code} = beam_disasm:file(BeamFile), + case Base of + "no_"++_ -> + [] = collect_recv_opt_instrs(Code); + "yes_"++_ -> + [{recv_mark,{f,L}},{recv_set,{f,L}}] = + collect_recv_opt_instrs(Code) + end, + ok + catch Class:Error -> + io:format("~s: ~p ~p\n~p\n", + [Source,Class,Error,erlang:get_stacktrace()]), + error + end. + +collect_recv_opt_instrs(Code) -> + L = [ [I || I <- Is, + begin + case I of + {recv_mark,{f,_}} -> true; + {recv_set,{f,_}} -> true; + _ -> false + end + end] || {function,_,_,_,Is} <- Code], + lists:append(L). + id(I) -> I. diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/no_1.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/no_1.erl new file mode 100644 index 0000000000..bc63dac437 --- /dev/null +++ b/lib/compiler/test/receive_SUITE_data/ref_opt/no_1.erl @@ -0,0 +1,99 @@ +-module(no_1). +-compile(export_all). + +?MODULE() -> + ok. + +f1(X) -> + Ref = make_ref(), + receive + _ when [X] =:= Ref -> + ok + end. + +f2(X, Y) -> + _Ref = make_ref(), + receive + _ when X =:= Y -> + ok + end. + +f3(X) -> + Ref = make_ref(), + receive + _ when X =:= Ref -> + ok + end. + +f4(X) -> + Ref = make_ref(), + receive + {X,_} when not X =:= Ref -> + ok + end. + +f5(X) -> + Ref = make_ref(), + receive + {Y,_} when X =:= Y; Y =:= Ref -> + ok + end. + +f6(X) -> + Ref = make_ref(), + receive + {Y,_} when Y =:= Ref; Ref =:= X -> + ok + end. + +f7(X) -> + Ref = make_ref(), + receive + {Y,_} when Y =:= Ref; not (X =:= Ref) -> + ok + end. + +f8(X) -> + Ref = make_ref(), + receive + {Y,_} when not (X =:= Ref); Y =:= Ref -> + ok + end. + +f9(X) -> + Ref = make_ref(), + receive + {Y,_} when (not (X =:= Ref)) or (Y =:= Ref) -> + ok + end. + +f10(X, Y) -> + Ref = make_ref(), + receive + {Z,_} when not (X =:= Y andalso Z =:= Ref) -> + ok + end. + +f11(X, Y) -> + Ref = make_ref(), + receive + {Z,_} when not ((X =:= Y) and (Z =:= Ref)) -> + ok + end. + +f12(X, Y) -> + Ref = make_ref(), + receive + {Z,_} when not ((Z =:= Ref) and (X =:= Y)) -> + ok + end. + +f13() -> + Ref = make_ref(), + RefCopy = id(Ref), + receive + _ when hd([RefCopy]) =:= Ref -> + ok + end. + +id(I) -> I. diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/no_2.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/no_2.erl new file mode 100644 index 0000000000..bc8d30c2ac --- /dev/null +++ b/lib/compiler/test/receive_SUITE_data/ref_opt/no_2.erl @@ -0,0 +1,26 @@ +-module(no_2). +-compile(export_all). + +?MODULE() -> + ok. + +f1() -> + Ref = make_ref(), + receive + {'DOWN',Ref} -> + ok; + {'DOWN',_} -> + ok + end. + +f2(Pid, Msg) -> + Ref = erlang:monitor(process, Pid), + Pid ! Msg, + receive + {ok,Ref,Reply} -> + {ok,Reply}; + {error,Ref,Reply} -> + {error,Reply}; + {error,A,B} -> + {error,A,B} + end. diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/no_3.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/no_3.erl new file mode 100644 index 0000000000..44cf8d7f71 --- /dev/null +++ b/lib/compiler/test/receive_SUITE_data/ref_opt/no_3.erl @@ -0,0 +1,14 @@ +-module(no_3). +-compile(export_all). + +?MODULE() -> + ok. + +f(X) -> + Ref = case X of + false -> ref; + true -> make_ref() + end, + receive + Ref -> ok + end. diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_1.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_1.erl new file mode 100644 index 0000000000..e2ebe234c1 --- /dev/null +++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_1.erl @@ -0,0 +1,12 @@ +-module(yes_1). +-compile(export_all). + +?MODULE() -> + ok. + +f() -> + Ref = make_ref(), + receive + {Ref,Reply} -> + Reply + end. diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_2.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_2.erl new file mode 100644 index 0000000000..6077cdcab9 --- /dev/null +++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_2.erl @@ -0,0 +1,13 @@ +-module(yes_2). +-compile(export_all). + +?MODULE() -> + ok. + +f(Pid, Msg) -> + Ref = make_ref(), + Pid ! Msg, + receive + {Ref,Reply} -> + Reply + end. diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_3.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_3.erl new file mode 100644 index 0000000000..28efc542ae --- /dev/null +++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_3.erl @@ -0,0 +1,16 @@ +-module(yes_3). +-compile(export_all). + +?MODULE() -> + ok. + +f(Pid, Msg) -> + Ref = make_ref(), + do_send(Pid, Msg), + receive + {Ref,Reply} -> + Reply + end. + +do_send(Pid, Msg) -> + Pid ! Msg. diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_4.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_4.erl new file mode 100644 index 0000000000..d1ba4832c7 --- /dev/null +++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_4.erl @@ -0,0 +1,16 @@ +-module(yes_4). +-compile(export_all). + +?MODULE() -> + ok. + +f(Pid, Msg) -> + Ref = make_ref(), + catch do_send(Pid, Msg), + receive + {Ref,Reply} -> + Reply + end. + +do_send(Pid, Msg) -> + Pid ! Msg. diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_5.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_5.erl new file mode 100644 index 0000000000..3f02fba6a6 --- /dev/null +++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_5.erl @@ -0,0 +1,46 @@ +-module(yes_5). +-compile(export_all). + +?MODULE() -> + ok. + +do_call(Process, Label, Request, Timeout) -> + Node = case Process of + {_S, N} when is_atom(N) -> + N; + _ when is_pid(Process) -> + node(Process) + end, + try erlang:monitor(process, Process) of + Mref -> + catch erlang:send(Process, {Label, {self(), Mref}, Request}, + [noconnect]), + receive + {Mref, Reply} -> + erlang:demonitor(Mref, [flush]), + {ok, Reply}; + {'DOWN', Mref, _, _, noconnection} -> + exit({nodedown, Node}); + {'DOWN', Mref, _, _, Reason} -> + exit(Reason) + after Timeout -> + erlang:demonitor(Mref), + receive + {'DOWN', Mref, _, _, _} -> true + after 0 -> true + end, + exit(timeout) + end + catch + error:_ -> + monitor_node(Node, true), + receive + {nodedown, Node} -> + monitor_node(Node, false), + exit({nodedown, Node}) + after 0 -> + Tag = make_ref(), + Process ! {Label, {self(), Tag}, Request}, + ?MODULE:wait_resp(Node, Tag, Timeout) + end + end. diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_6.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_6.erl new file mode 100644 index 0000000000..c54b636aa6 --- /dev/null +++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_6.erl @@ -0,0 +1,15 @@ +-module(yes_6). +-compile(export_all). + +?MODULE() -> + ok. + +f(Pid, Msg) -> + Ref = erlang:monitor(process, Pid), + Pid ! Msg, + receive + {ok,Ref,Reply} -> + {ok,Reply}; + {error,Ref,Reply} -> + {error,Reply} + end. diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_7.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_7.erl new file mode 100644 index 0000000000..849eab1746 --- /dev/null +++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_7.erl @@ -0,0 +1,12 @@ +-module(yes_7). +-compile(export_all). + +?MODULE() -> + ok. + +f(X, Y) -> + Ref = make_ref(), + receive + {Z,_} when X =:= Y, Ref =:= Z -> + ok + end. diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_8.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_8.erl new file mode 100644 index 0000000000..a47fe8cfbf --- /dev/null +++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_8.erl @@ -0,0 +1,15 @@ +-module(yes_8). +-compile(export_all). + +?MODULE() -> + ok. + +%% Cover use of floating point registers. + +f(Pid, X) when is_float(X) -> + Ref = make_ref(), + Pid ! {X+3}, + receive + Ref -> + ok + end. diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_9.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_9.erl new file mode 100644 index 0000000000..97fce5e734 --- /dev/null +++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_9.erl @@ -0,0 +1,13 @@ +-module(yes_9). +-compile(export_all). + +?MODULE() -> + ok. + +f(Fun) -> + Ref = make_ref(), + Fun(), + receive + {Ref,Reply} -> + Reply + end. diff --git a/lib/compiler/test/record_SUITE.erl b/lib/compiler/test/record_SUITE.erl index bd2ffd7f65..f26ff769c7 100644 --- a/lib/compiler/test/record_SUITE.erl +++ b/lib/compiler/test/record_SUITE.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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 : Test records. @@ -24,7 +24,7 @@ -export([all/1,init_per_testcase/2,fin_per_testcase/2, errors/1,record_test_2/1,record_test_3/1,record_access_in_guards/1, - guard_opt/1,eval_once/1,foobar/1,missing_test_heap/1]). + guard_opt/1,eval_once/1,foobar/1,missing_test_heap/1, nested_access/1]). init_per_testcase(_Case, Config) -> ?line Dog = test_server:timetrap(test_server:minutes(2)), @@ -38,7 +38,7 @@ fin_per_testcase(_Case, Config) -> all(suite) -> test_lib:recompile(?MODULE), [errors,record_test_2,record_test_3,record_access_in_guards, - guard_opt,eval_once,foobar,missing_test_heap]. + guard_opt,eval_once,foobar,missing_test_heap,nested_access]. -record(foo, {a,b,c,d}). -record(bar, {a,b,c,d}). @@ -522,4 +522,29 @@ missing_test_heap_1(A = #foo_rec {foo_1 = _B, foo_3 = C + 1, foo_2 = D + 1}. +-record(nrec0, {name = <<"nested0">>}). +-record(nrec1, {name = <<"nested1">>, nrec0=#nrec0{}}). +-record(nrec2, {name = <<"nested2">>, nrec1=#nrec1{}}). + +nested_access(Config) when is_list(Config) -> + N0 = #nrec0{}, + N1 = #nrec1{}, + N2 = #nrec2{}, + ?line <<"nested0">> = N0#nrec0.name, + ?line <<"nested1">> = N1#nrec1.name, + ?line <<"nested2">> = N2#nrec2.name, + ?line <<"nested0">> = N1#nrec1.nrec0#nrec0.name, + ?line <<"nested0">> = N2#nrec2.nrec1#nrec1.nrec0#nrec0.name, + ?line <<"nested1">> = N2#nrec2.nrec1#nrec1.name, + ?line <<"nested0">> = ((N2#nrec2.nrec1)#nrec1.nrec0)#nrec0.name, + + N1a = N2#nrec2.nrec1#nrec1{name = <<"nested1a">>}, + ?line <<"nested1a">> = N1a#nrec1.name, + + N2a = N2#nrec2.nrec1#nrec1.nrec0#nrec0{name = <<"nested0a">>}, + N2b = ((N2#nrec2.nrec1)#nrec1.nrec0)#nrec0{name = <<"nested0a">>}, + ?line <<"nested0a">> = N2a#nrec0.name, + ?line N2a = N2b, + ok. + id(I) -> I. diff --git a/lib/compiler/test/test_lib.erl b/lib/compiler/test/test_lib.erl index 3099538071..d8799952a9 100644 --- a/lib/compiler/test/test_lib.erl +++ b/lib/compiler/test/test_lib.erl @@ -1,26 +1,26 @@ %% %% %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 %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% -module(test_lib). -include("test_server.hrl"). - --export([recompile/1,opt_opts/1,get_data_dir/1,smoke_disasm/1]). +-compile({no_auto_import,[binary_part/2]}). +-export([recompile/1,opt_opts/1,get_data_dir/1,smoke_disasm/1,p_run/2,binary_part/2]). recompile(Mod) when is_atom(Mod) -> case whereis(cover_server) of @@ -56,10 +56,9 @@ opt_opts(Mod) -> (no_new_binaries) -> true; (no_new_apply) -> true; (no_gc_bifs) -> true; - (no_constant_pool) -> true; (no_stack_trimming) -> true; - (no_binaries) -> true; (debug_info) -> true; + (inline) -> true; (_) -> false end, Opts). @@ -71,5 +70,41 @@ get_data_dir(Config) -> Data0 = ?config(data_dir, Config), {ok,Data1,_} = regexp:sub(Data0, "_no_opt_SUITE", "_SUITE"), {ok,Data2,_} = regexp:sub(Data1, "_post_opt_SUITE", "_SUITE"), - {ok,Data,_} = regexp:sub(Data2, "_r11_SUITE", "_SUITE"), + {ok,Data,_} = regexp:sub(Data2, "_inline_SUITE", "_SUITE"), Data. + +%% p_run(fun(Data) -> ok|error, List) -> ok +%% Will fail the test case if there were any errors. + +p_run(Test, List) -> + N = erlang:system_info(schedulers) + 1, + p_run_loop(Test, List, N, [], 0, 0). + +p_run_loop(_, [], _, [], Errors, Ws) -> + case Errors of + 0 -> + case Ws of + 0 -> ok; + 1 -> {comment,"1 warning"}; + N -> {comment,integer_to_list(N)++" warnings"} + end; + N -> ?t:fail({N,errors}) + end; +p_run_loop(Test, [H|T], N, Refs, Errors, Ws) when length(Refs) < N -> + {_,Ref} = erlang:spawn_monitor(fun() -> exit(Test(H)) end), + p_run_loop(Test, T, N, [Ref|Refs], Errors, Ws); +p_run_loop(Test, List, N, Refs0, Errors0, Ws0) -> + receive + {'DOWN',Ref,process,_,Res} -> + {Errors,Ws} = case Res of + ok -> {Errors0,Ws0}; + error -> {Errors0+1,Ws0}; + warning -> {Errors0,Ws0+1} + end, + Refs = Refs0 -- [Ref], + p_run_loop(Test, List, N, Refs, Errors, Ws) + end. + +%% This is for the misc_SUITE:override_bif testcase +binary_part(_A,_B) -> + dummy. diff --git a/lib/compiler/test/warnings_SUITE.erl b/lib/compiler/test/warnings_SUITE.erl index 6e60ab88cb..5ed8836c70 100644 --- a/lib/compiler/test/warnings_SUITE.erl +++ b/lib/compiler/test/warnings_SUITE.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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(warnings_SUITE). @@ -375,7 +375,12 @@ effect(Config) when is_list(Config) -> comp_op -> X =:= 2; cookie -> - erlang:get_cookie() + erlang:get_cookie(); + result_ignore -> + _ = list_to_integer(X); + warn_lc_4 -> + %% No warning because of assignment to _. + [_ = abs(Z) || Z <- [1,2,3]] end, ok. diff --git a/lib/compiler/vsn.mk b/lib/compiler/vsn.mk index a5e6de7b5f..4658eccd19 100644 --- a/lib/compiler/vsn.mk +++ b/lib/compiler/vsn.mk @@ -1 +1 @@ -COMPILER_VSN = 4.6.5 +COMPILER_VSN = 4.7.1 diff --git a/lib/cosEvent/doc/src/notes.xml b/lib/cosEvent/doc/src/notes.xml index 78299a38dc..b6c4531901 100644 --- a/lib/cosEvent/doc/src/notes.xml +++ b/lib/cosEvent/doc/src/notes.xml @@ -33,6 +33,22 @@ </header> <section> + <title>cosEvent 2.1.9</title> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p> + Test suites published.</p> + <p> + Own Id: OTP-8543 Aux Id:</p> + </item> + </list> + </section> + </section> + + <section> <title>cosEvent 2.1.8</title> <section> diff --git a/lib/cosEvent/vsn.mk b/lib/cosEvent/vsn.mk index 8915903bbe..9c00a17100 100644 --- a/lib/cosEvent/vsn.mk +++ b/lib/cosEvent/vsn.mk @@ -1,13 +1 @@ - -COSEVENT_VSN = 2.1.8 - -TICKETS = 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 +COSEVENT_VSN = 2.1.9 diff --git a/lib/cosEventDomain/doc/src/notes.xml b/lib/cosEventDomain/doc/src/notes.xml index 0ad42948af..deb1985c86 100644 --- a/lib/cosEventDomain/doc/src/notes.xml +++ b/lib/cosEventDomain/doc/src/notes.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2001</year><year>2009</year> + <year>2001</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>cosEventDomain Release Notes</title> @@ -32,6 +32,22 @@ </header> <section> + <title>cosEventDomain 1.1.9</title> + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p> + Test suites published.</p> + <p> + Own Id: OTP-8543 Aux Id:</p> + </item> + </list> + </section> + + </section> + + <section> <title>cosEventDomain 1.1.8</title> <section> diff --git a/lib/cosEventDomain/vsn.mk b/lib/cosEventDomain/vsn.mk index 483b130819..bd21133fe5 100644 --- a/lib/cosEventDomain/vsn.mk +++ b/lib/cosEventDomain/vsn.mk @@ -1,13 +1 @@ - -COSEVENTDOMAIN_VSN = 1.1.8 - -TICKETS = 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 +COSEVENTDOMAIN_VSN = 1.1.9 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/doc/src/notes.xml b/lib/cosNotification/doc/src/notes.xml index 29879e95fb..de5a3e5f4c 100644 --- a/lib/cosNotification/doc/src/notes.xml +++ b/lib/cosNotification/doc/src/notes.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2000</year><year>2009</year> + <year>2000</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>cosNotification Release Notes</title> @@ -32,6 +32,31 @@ </header> <section> + <title>cosNotification 1.1.14</title> + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p> + Test suites published.</p> + <p> + Own Id: OTP-8543 Aux Id:</p> + </item> + </list> + </section> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>Added missing trailing bracket to define in hrl-file.</p> + <p>Own id: OTP-8489 Aux Id:</p> + </item> + </list> + </section> + </section> + + <section> <title>cosNotification 1.1.13</title> <section> diff --git a/lib/cosNotification/src/CosNotification_Definitions.hrl b/lib/cosNotification/src/CosNotification_Definitions.hrl index 755b07cd5d..8325b5aa5e 100644 --- a/lib/cosNotification/src/CosNotification_Definitions.hrl +++ b/lib/cosNotification/src/CosNotification_Definitions.hrl @@ -1,20 +1,20 @@ %%---------------------------------------------------------------------- %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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% %% %% @@ -162,7 +162,7 @@ low_val=any:create(orber_tc:long(), ?not_MinConsumerEvents), high_val=any:create(orber_tc:long(), ?not_MaxConsumerEvents) }} -]. +]). diff --git a/lib/cosNotification/vsn.mk b/lib/cosNotification/vsn.mk index fed10ee195..c03f0ef161 100644 --- a/lib/cosNotification/vsn.mk +++ b/lib/cosNotification/vsn.mk @@ -1,15 +1 @@ -COSNOTIFICATION_VSN = 1.1.13 - -TICKETS = 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 +COSNOTIFICATION_VSN = 1.1.14 diff --git a/lib/cosProperty/doc/src/notes.xml b/lib/cosProperty/doc/src/notes.xml index e80c90849f..11e6205ee9 100644 --- a/lib/cosProperty/doc/src/notes.xml +++ b/lib/cosProperty/doc/src/notes.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2000</year><year>2009</year> + <year>2000</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>cosProperty Release Notes</title> @@ -32,6 +32,22 @@ </header> <section> + <title>cosProperty 1.1.12</title> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p> + Test suites published.</p> + <p> + Own Id: OTP-8543 Aux Id:</p> + </item> + </list> + </section> + </section> + + <section> <title>cosProperty 1.1.11</title> <section> diff --git a/lib/cosProperty/vsn.mk b/lib/cosProperty/vsn.mk index c221e6fa4a..ca9a7ca77e 100644 --- a/lib/cosProperty/vsn.mk +++ b/lib/cosProperty/vsn.mk @@ -1,11 +1 @@ -COSPROPERTY_VSN = 1.1.11 - -TICKETS = 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 +COSPROPERTY_VSN = 1.1.12 diff --git a/lib/cosTime/doc/src/notes.xml b/lib/cosTime/doc/src/notes.xml index 9f23a8633c..40ebf42753 100644 --- a/lib/cosTime/doc/src/notes.xml +++ b/lib/cosTime/doc/src/notes.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2000</year><year>2009</year> + <year>2000</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>cosTime Release Notes</title> @@ -33,6 +33,22 @@ </header> <section> + <title>cosTime 1.1.9</title> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p> + Test suites published.</p> + <p> + Own Id: OTP-8543 Aux Id:</p> + </item> + </list> + </section> + </section> + + <section> <title>cosTime 1.1.8</title> <section> diff --git a/lib/cosTime/vsn.mk b/lib/cosTime/vsn.mk index db51bf39b9..429613fb61 100644 --- a/lib/cosTime/vsn.mk +++ b/lib/cosTime/vsn.mk @@ -1,11 +1 @@ -COSTIME_VSN = 1.1.8 - -TICKETS = 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 +COSTIME_VSN = 1.1.9 diff --git a/lib/cosTransactions/doc/src/ch_example.xml b/lib/cosTransactions/doc/src/ch_example.xml index 65350166f0..026bfc467e 100644 --- a/lib/cosTransactions/doc/src/ch_example.xml +++ b/lib/cosTransactions/doc/src/ch_example.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>1999</year><year>2009</year> + <year>1999</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>cosTransactions Examples</title> @@ -83,7 +83,9 @@ module ownResourceImpl { <item><c>commit_one_phase/1</c> - if possible, the Resource should commit all changes made as part of the transaction. This operation can only be used if the Resource is the only child of its parent. </item> <item><c>forget/1</c> - this operation informs the Resource that it is safe to forget any - <term id="Heuristic decisions"><termdef>Heuristic decisions is a unilateral decision by a participant to commit or rollback without receiving the true outcome of the transaction from its parents coordinator.</termdef></term>and the knowledge of the transaction.</item> + <term id="Heuristic decisions"><termdef>Heuristic decisions is a unilateral decision by a participant to commit + or rollback without receiving the true outcome of the transaction from its parent's coordinator.</termdef></term> + and the knowledge of the transaction.</item> <item><c>ownFunctions</c> - all application specific operations.</item> </list> <p>If the participant wants to be notified when a subtransaction commits, we must also implement the following operations diff --git a/lib/cosTransactions/doc/src/notes.xml b/lib/cosTransactions/doc/src/notes.xml index 41a754b034..7586e3c13f 100644 --- a/lib/cosTransactions/doc/src/notes.xml +++ b/lib/cosTransactions/doc/src/notes.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>1999</year><year>2009</year> + <year>1999</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>cosTransactions Release Notes</title> @@ -33,6 +33,30 @@ </header> <section> + <title>cosTransactions 1.2.10</title> + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p> + Test suites published.</p> + <p> + Own Id: OTP-8543 Aux Id:</p> + </item> + </list> + </section> + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>Added missing trailing bracket to define in hrl-file.</p> + <p>Own id: OTP-8489 Aux Id:</p> + </item> + </list> + </section> + </section> + + <section> <title>cosTransactions 1.2.9</title> <section> diff --git a/lib/cosTransactions/src/ETraP_Common.hrl b/lib/cosTransactions/src/ETraP_Common.hrl index 5082282efb..97e88244a3 100644 --- a/lib/cosTransactions/src/ETraP_Common.hrl +++ b/lib/cosTransactions/src/ETraP_Common.hrl @@ -1,20 +1,20 @@ %%-------------------------------------------------------------------- %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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% %% %% @@ -313,7 +313,7 @@ error_logger:error_msg("============ CosTransactions ==============~n" Context#context{self = ID}). -define(tr_set_parents(Context, Parents), - Context#context{parents = Parents). + Context#context{parents = Parents}). -define(tr_add_parent(Context, Parent), Context#context{parents = [Parent] ++ Context#context.parents}). diff --git a/lib/cosTransactions/vsn.mk b/lib/cosTransactions/vsn.mk index 81e360ac2f..82e46f51dd 100644 --- a/lib/cosTransactions/vsn.mk +++ b/lib/cosTransactions/vsn.mk @@ -1,11 +1 @@ -COSTRANSACTIONS_VSN = 1.2.9 - -TICKETS = 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 +COSTRANSACTIONS_VSN = 1.2.10 diff --git a/lib/crypto/c_src/Makefile.in b/lib/crypto/c_src/Makefile.in index 18040a3b26..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_drv.o -DRV_MAKEFILE = $(PRIVDIR)/Makefile +OBJS = $(OBJDIR)/crypto$(TYPEMARKER).o +NIF_MAKEFILE = $(PRIVDIR)/Makefile ifeq ($(findstring win32,$(TARGET)), win32) -DYN_DRIVER = $(LIBDIR)/crypto_drv.dll +NIF_LIB = $(LIBDIR)/crypto$(TYPEMARKER).dll else -DYN_DRIVER = $(LIBDIR)/crypto_drv.so +NIF_LIB = $(LIBDIR)/crypto$(TYPEMARKER).so endif ifeq ($(HOST_OS),) @@ -94,7 +94,7 @@ endif # Targets # ---------------------------------------------------- -debug opt valgrind: $(OBJDIR) $(LIBDIR) $(DYN_DRIVER) +debug opt valgrind: $(OBJDIR) $(LIBDIR) $(NIF_LIB) $(OBJDIR): -@mkdir -p $(OBJDIR) @@ -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_drv.so: $(OBJS) +$(LIBDIR)/crypto$(TYPEMARKER).so: $(OBJS) $(INSTALL_DIR) $(LIBDIR) $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS) $(CRYPTO_LINK_LIB) -$(LIBDIR)/crypto_drv.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 $(DYN_DRIVER) $(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: @@ -128,9 +138,9 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt $(INSTALL_DIR) $(RELSYSDIR)/priv/obj $(INSTALL_DIR) $(RELSYSDIR)/priv/lib - $(INSTALL_DATA) $(DRV_MAKEFILE) $(RELSYSDIR)/priv/obj + $(INSTALL_DATA) $(NIF_MAKEFILE) $(RELSYSDIR)/priv/obj $(INSTALL_PROGRAM) $(OBJS) $(RELSYSDIR)/priv/obj - $(INSTALL_PROGRAM) $(DYN_DRIVER) $(RELSYSDIR)/priv/lib + $(INSTALL_PROGRAM) $(NIF_LIB) $(RELSYSDIR)/priv/lib release_docs_spec: diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c new file mode 100644 index 0000000000..85614a84c2 --- /dev/null +++ b/lib/crypto/c_src/crypto.c @@ -0,0 +1,1556 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 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% + */ + +/* + * Purpose: Dynamically loadable NIF library for cryptography. + * Based on OpenSSL. + */ + +#ifdef __WIN32__ + #include <windows.h> +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "erl_nif.h" + +#define OPENSSL_THREAD_DEFINES +#include <openssl/opensslconf.h> + +#include <openssl/crypto.h> +#include <openssl/des.h> +/* #include <openssl/idea.h> This is not supported on the openssl OTP requires */ +#include <openssl/dsa.h> +#include <openssl/rsa.h> +#include <openssl/aes.h> +#include <openssl/md5.h> +#include <openssl/md4.h> +#include <openssl/sha.h> +#include <openssl/bn.h> +#include <openssl/objects.h> +#include <openssl/rc4.h> +#include <openssl/rc2.h> +#include <openssl/blowfish.h> +#include <openssl/rand.h> + +#ifdef VALGRIND + # include <valgrind/memcheck.h> + +/* libcrypto mixes supplied buffer contents into its entropy pool, + which makes valgrind complain about the use of uninitialized data. + We use this valgrind "request" to make sure that no such seemingly + undefined data is returned. +*/ + # define ERL_VALGRIND_MAKE_MEM_DEFINED(ptr,size) \ + VALGRIND_MAKE_MEM_DEFINED(ptr,size) + + # 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,%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) +#endif + +#ifdef DEBUG + # define ASSERT(e) \ + ((void) ((e) ? 1 : (fprintf(stderr,"Assert '%s' failed at %s:%d\n",\ + #e, __FILE__, __LINE__), abort(), 0))) +#else + # define ASSERT(e) ((void) 1) +#endif + +#ifdef __GNUC__ + # define INLINE __inline__ +#elif defined(__WIN32__) + # define INLINE __forceinline +#else + # define INLINE +#endif + + +#define get_int32(s) ((((unsigned char*) (s))[0] << 24) | \ + (((unsigned char*) (s))[1] << 16) | \ + (((unsigned char*) (s))[2] << 8) | \ + (((unsigned char*) (s))[3])) + +#define put_int32(s,i) \ +{ (s)[0] = (char)(((i) >> 24) & 0xff);\ + (s)[1] = (char)(((i) >> 16) & 0xff);\ + (s)[2] = (char)(((i) >> 8) & 0xff);\ + (s)[3] = (char)((i) & 0xff);\ +} + +/* NIF interface declarations */ +static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info); +static int reload(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info); +static int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data, ERL_NIF_TERM load_info); +static void unload(ErlNifEnv* env, void* priv_data); + +/* The NIFs: */ +static ERL_NIF_TERM info_lib(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM md5(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM md5_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM md5_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM md5_final(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM sha(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM sha_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM sha_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM sha_final(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM md4(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM md4_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM md4_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM md4_final(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM md5_mac_n(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM sha_mac_n(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM des_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM des_ecb_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM des_ede3_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM aes_cfb_128_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM rand_bytes_1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM rand_bytes_3(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM rand_uniform_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM mod_exp_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM dss_verify(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM rsa_verify(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM aes_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM exor(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM rc4_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM rc4_set_key(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM rc4_encrypt_with_state(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM rc2_40_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM rsa_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM dss_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM rsa_public_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM rsa_private_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM dh_generate_parameters_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM dh_check(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM dh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM bf_cfb64_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM bf_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM bf_ecb_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM blowfish_ofb64_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); + + +/* openssl callbacks */ +#ifdef OPENSSL_THREADS +static void locking_function(int mode, int n, const char *file, int line); +static unsigned long id_function(void); +static struct CRYPTO_dynlock_value* dyn_create_function(const char *file, + int line); +static void dyn_lock_function(int mode, struct CRYPTO_dynlock_value* ptr, + const char *file, int line); +static void dyn_destroy_function(struct CRYPTO_dynlock_value *ptr, + const char *file, int line); +#endif /* OPENSSL_THREADS */ + +/* helpers */ +static void hmac_md5(unsigned char *key, int klen, + unsigned char *dbuf, int dlen, + unsigned char *hmacbuf); +static void hmac_sha1(unsigned char *key, int klen, + unsigned char *dbuf, int dlen, + unsigned char *hmacbuf); + +static int library_refc = 0; /* number of users of this dynamic library */ + +static ErlNifFunc nif_funcs[] = { + {"info_lib", 0, info_lib}, + {"md5", 1, md5}, + {"md5_init", 0, md5_init}, + {"md5_update", 2, md5_update}, + {"md5_final", 1, md5_final}, + {"sha", 1, sha}, + {"sha_init", 0, sha_init}, + {"sha_update", 2, sha_update}, + {"sha_final", 1, sha_final}, + {"md4", 1, md4}, + {"md4_init", 0, md4_init}, + {"md4_update", 2, md4_update}, + {"md4_final", 1, md4_final}, + {"md5_mac_n", 3, md5_mac_n}, + {"sha_mac_n", 3, sha_mac_n}, + {"des_cbc_crypt", 4, des_cbc_crypt}, + {"des_ecb_crypt", 3, des_ecb_crypt}, + {"des_ede3_cbc_crypt", 6, des_ede3_cbc_crypt}, + {"aes_cfb_128_crypt", 4, aes_cfb_128_crypt}, + {"rand_bytes", 1, rand_bytes_1}, + {"rand_bytes", 3, rand_bytes_3}, + {"rand_uniform_nif", 2, rand_uniform_nif}, + {"mod_exp_nif", 3, mod_exp_nif}, + {"dss_verify", 4, dss_verify}, + {"rsa_verify", 4, rsa_verify}, + {"aes_cbc_crypt", 4, aes_cbc_crypt}, + {"exor", 2, exor}, + {"rc4_encrypt", 2, rc4_encrypt}, + {"rc4_set_key", 1, rc4_set_key}, + {"rc4_encrypt_with_state", 2, rc4_encrypt_with_state}, + {"rc2_40_cbc_crypt", 4, rc2_40_cbc_crypt}, + {"rsa_sign_nif", 3, rsa_sign_nif}, + {"dss_sign_nif", 3, dss_sign_nif}, + {"rsa_public_crypt", 4, rsa_public_crypt}, + {"rsa_private_crypt", 4, rsa_private_crypt}, + {"dh_generate_parameters_nif", 2, dh_generate_parameters_nif}, + {"dh_check", 1, dh_check}, + {"dh_generate_key_nif", 2, dh_generate_key_nif}, + {"dh_compute_key_nif", 3, dh_compute_key_nif}, + {"bf_cfb64_crypt", 4, bf_cfb64_crypt}, + {"bf_cbc_crypt", 4, bf_cbc_crypt}, + {"bf_ecb_crypt", 3, bf_ecb_crypt}, + {"blowfish_ofb64_encrypt", 3, blowfish_ofb64_encrypt} +}; + +ERL_NIF_INIT(crypto,nif_funcs,load,reload,upgrade,unload) + + +#define MD5_CTX_LEN (sizeof(MD5_CTX)) +#define MD5_LEN 16 +#define MD5_LEN_96 12 +#define MD4_CTX_LEN (sizeof(MD4_CTX)) +#define MD4_LEN 16 +#define SHA_CTX_LEN (sizeof(SHA_CTX)) +#define SHA_LEN 20 +#define SHA_LEN_96 12 +#define HMAC_INT_LEN 64 + +#define HMAC_IPAD 0x36 +#define HMAC_OPAD 0x5c + + +static ErlNifRWLock** lock_vec = NULL; /* Static locks used by openssl */ +static ERL_NIF_TERM atom_true; +static ERL_NIF_TERM atom_false; +static ERL_NIF_TERM atom_sha; +static ERL_NIF_TERM atom_md5; +static ERL_NIF_TERM atom_error; +static ERL_NIF_TERM atom_rsa_pkcs1_padding; +static ERL_NIF_TERM atom_rsa_pkcs1_oaep_padding; +static ERL_NIF_TERM atom_rsa_no_padding; +static ERL_NIF_TERM atom_undefined; + +static ERL_NIF_TERM atom_ok; +static ERL_NIF_TERM atom_not_prime; +static ERL_NIF_TERM atom_not_strong_prime; +static ERL_NIF_TERM atom_unable_to_check_generator; +static ERL_NIF_TERM atom_not_suitable_generator; +static ERL_NIF_TERM atom_check_failed; +static ERL_NIF_TERM atom_unknown; +static ERL_NIF_TERM atom_none; + + +static int is_ok_load_info(ErlNifEnv* env, ERL_NIF_TERM load_info) +{ + int i; + return enif_get_int(env,load_info,&i) && i == 101; +} +static void* crypto_alloc(size_t size) +{ + return enif_alloc(size); +} +static void* crypto_realloc(void* ptr, size_t size) +{ + return enif_realloc(ptr, size); +} +static void crypto_free(void* ptr) +{ + enif_free(ptr); +} + +static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) +{ + ErlNifSysInfo sys_info; + CRYPTO_set_mem_functions(crypto_alloc, crypto_realloc, crypto_free); + + if (!is_ok_load_info(env, load_info)) { + return -1; + } + +#ifdef OPENSSL_THREADS + enif_system_info(&sys_info, sizeof(sys_info)); + + if (sys_info.scheduler_threads > 1) { + int i; + lock_vec = enif_alloc(CRYPTO_num_locks()*sizeof(*lock_vec)); + if (lock_vec==NULL) return -1; + memset(lock_vec,0,CRYPTO_num_locks()*sizeof(*lock_vec)); + + for (i=CRYPTO_num_locks()-1; i>=0; --i) { + lock_vec[i] = enif_rwlock_create("crypto_stat"); + if (lock_vec[i]==NULL) return -1; + } + CRYPTO_set_locking_callback(locking_function); + CRYPTO_set_id_callback(id_function); + CRYPTO_set_dynlock_create_callback(dyn_create_function); + CRYPTO_set_dynlock_lock_callback(dyn_lock_function); + CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function); + } + /* else no need for locks */ +#endif /* OPENSSL_THREADS */ + + atom_true = enif_make_atom(env,"true"); + atom_false = enif_make_atom(env,"false"); + atom_sha = enif_make_atom(env,"sha"); + atom_md5 = enif_make_atom(env,"md5"); + atom_error = enif_make_atom(env,"error"); + atom_rsa_pkcs1_padding = enif_make_atom(env,"rsa_pkcs1_padding"); + atom_rsa_pkcs1_oaep_padding = enif_make_atom(env,"rsa_pkcs1_oaep_padding"); + atom_rsa_no_padding = enif_make_atom(env,"rsa_no_padding"); + atom_undefined = enif_make_atom(env,"undefined"); + atom_ok = enif_make_atom(env,"ok"); + atom_not_prime = enif_make_atom(env,"not_prime"); + atom_not_strong_prime = enif_make_atom(env,"not_strong_prime"); + atom_unable_to_check_generator = enif_make_atom(env,"unable_to_check_generator"); + atom_not_suitable_generator = enif_make_atom(env,"not_suitable_generator"); + atom_check_failed = enif_make_atom(env,"check_failed"); + atom_unknown = enif_make_atom(env,"unknown"); + atom_none = enif_make_atom(env,"none"); + + *priv_data = NULL; + library_refc++; + return 0; +} + +static int reload(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) +{ + if (*priv_data != NULL) { + return -1; /* Don't know how to do that */ + } + if (library_refc == 0) { + /* No support for real library upgrade. The tricky thing is to know + when to (re)set the callbacks for allocation and locking. */ + return -2; + } + if (!is_ok_load_info(env, load_info)) { + return -1; + } + return 0; +} + +static int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data, + ERL_NIF_TERM load_info) +{ + int i; + if (*old_priv_data != NULL) { + return -1; /* Don't know how to do that */ + } + i = reload(env,priv_data,load_info); + if (i != 0) { + return i; + } + library_refc++; + return 0; +} + +static void unload(ErlNifEnv* env, void* priv_data) +{ + if (--library_refc <= 0) { + CRYPTO_cleanup_all_ex_data(); + + if (lock_vec != NULL) { + int i; + for (i=CRYPTO_num_locks()-1; i>=0; --i) { + if (lock_vec[i] != NULL) { + enif_rwlock_destroy(lock_vec[i]); + } + } + enif_free(lock_vec); + } + } + /*else NIF library still used by other (new) module code */ +} + +static ERL_NIF_TERM info_lib(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ + /* [{<<"OpenSSL">>,9470143,<<"OpenSSL 0.9.8k 25 Mar 2009">>}] */ + + static const char libname[] = "OpenSSL"; + unsigned name_sz = strlen(libname); + const char* ver = SSLeay_version(SSLEAY_VERSION); + unsigned ver_sz = strlen(ver); + ERL_NIF_TERM name_term, ver_term; + + memcpy(enif_make_new_binary(env, name_sz, &name_term), libname, name_sz); + memcpy(enif_make_new_binary(env, ver_sz, &ver_term), ver, ver_sz); + + return enif_make_list1(env, enif_make_tuple3(env, name_term, + enif_make_int(env, SSLeay()), + ver_term)); +} + +static ERL_NIF_TERM md5(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Data) */ + ErlNifBinary ibin; + ERL_NIF_TERM ret; + + if (!enif_inspect_iolist_as_binary(env, argv[0], &ibin)) { + return enif_make_badarg(env); + } + MD5((unsigned char *) ibin.data, ibin.size, + enif_make_new_binary(env,MD5_LEN, &ret)); + return ret; +} +static ERL_NIF_TERM md5_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* () */ + ERL_NIF_TERM ret; + MD5_Init((MD5_CTX *) enif_make_new_binary(env, MD5_CTX_LEN, &ret)); + return ret; +} +static ERL_NIF_TERM md5_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Context, Data) */ + MD5_CTX* new_ctx; + ErlNifBinary ctx_bin, data_bin; + ERL_NIF_TERM ret; + if (!enif_inspect_binary(env, argv[0], &ctx_bin) + || ctx_bin.size != MD5_CTX_LEN + || !enif_inspect_iolist_as_binary(env, argv[1], &data_bin)) { + return enif_make_badarg(env); + } + new_ctx = (MD5_CTX*) enif_make_new_binary(env,MD5_CTX_LEN, &ret); + memcpy(new_ctx, ctx_bin.data, MD5_CTX_LEN); + MD5_Update(new_ctx, data_bin.data, data_bin.size); + return ret; +} +static ERL_NIF_TERM md5_final(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Context) */ + ErlNifBinary ctx_bin; + MD5_CTX ctx_clone; + ERL_NIF_TERM ret; + if (!enif_inspect_binary(env, argv[0], &ctx_bin) || ctx_bin.size != MD5_CTX_LEN) { + return enif_make_badarg(env); + } + memcpy(&ctx_clone, ctx_bin.data, MD5_CTX_LEN); /* writable */ + MD5_Final(enif_make_new_binary(env, MD5_LEN, &ret), &ctx_clone); + return ret; +} + +static ERL_NIF_TERM sha(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Data) */ + ErlNifBinary ibin; + ERL_NIF_TERM ret; + + if (!enif_inspect_iolist_as_binary(env, argv[0], &ibin)) { + return enif_make_badarg(env); + } + SHA1((unsigned char *) ibin.data, ibin.size, + enif_make_new_binary(env,SHA_LEN, &ret)); + return ret; +} +static ERL_NIF_TERM sha_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* () */ + ERL_NIF_TERM ret; + SHA1_Init((SHA_CTX *) enif_make_new_binary(env, SHA_CTX_LEN, &ret)); + return ret; +} +static ERL_NIF_TERM sha_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Context, Data) */ + SHA_CTX* new_ctx; + ErlNifBinary ctx_bin, data_bin; + ERL_NIF_TERM ret; + if (!enif_inspect_binary(env, argv[0], &ctx_bin) || ctx_bin.size != SHA_CTX_LEN + || !enif_inspect_iolist_as_binary(env, argv[1], &data_bin)) { + return enif_make_badarg(env); + } + new_ctx = (SHA_CTX*) enif_make_new_binary(env,SHA_CTX_LEN, &ret); + memcpy(new_ctx, ctx_bin.data, SHA_CTX_LEN); + SHA1_Update(new_ctx, data_bin.data, data_bin.size); + return ret; +} +static ERL_NIF_TERM sha_final(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Context) */ + ErlNifBinary ctx_bin; + SHA_CTX ctx_clone; + ERL_NIF_TERM ret; + if (!enif_inspect_binary(env, argv[0], &ctx_bin) || ctx_bin.size != SHA_CTX_LEN) { + return enif_make_badarg(env); + } + memcpy(&ctx_clone, ctx_bin.data, SHA_CTX_LEN); /* writable */ + SHA1_Final(enif_make_new_binary(env, SHA_LEN, &ret), &ctx_clone); + return ret; +} + +static ERL_NIF_TERM md4(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Data) */ + ErlNifBinary ibin; + ERL_NIF_TERM ret; + + if (!enif_inspect_iolist_as_binary(env, argv[0], &ibin)) { + return enif_make_badarg(env); + } + MD4((unsigned char *) ibin.data, ibin.size, + enif_make_new_binary(env,MD4_LEN, &ret)); + return ret; +} +static ERL_NIF_TERM md4_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* () */ + ERL_NIF_TERM ret; + MD4_Init((MD4_CTX *) enif_make_new_binary(env, MD4_CTX_LEN, &ret)); + return ret; +} +static ERL_NIF_TERM md4_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Context, Data) */ + MD4_CTX* new_ctx; + ErlNifBinary ctx_bin, data_bin; + ERL_NIF_TERM ret; + if (!enif_inspect_binary(env, argv[0], &ctx_bin) || ctx_bin.size != MD4_CTX_LEN + || !enif_inspect_iolist_as_binary(env, argv[1], &data_bin)) { + return enif_make_badarg(env); + } + new_ctx = (MD4_CTX*) enif_make_new_binary(env,MD4_CTX_LEN, &ret); + memcpy(new_ctx, ctx_bin.data, MD4_CTX_LEN); + MD4_Update(new_ctx, data_bin.data, data_bin.size); + return ret; +} +static ERL_NIF_TERM md4_final(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Context) */ + ErlNifBinary ctx_bin; + MD4_CTX ctx_clone; + ERL_NIF_TERM ret; + if (!enif_inspect_binary(env, argv[0], &ctx_bin) || ctx_bin.size != MD4_CTX_LEN) { + return enif_make_badarg(env); + } + memcpy(&ctx_clone, ctx_bin.data, MD4_CTX_LEN); /* writable */ + MD4_Final(enif_make_new_binary(env, MD4_LEN, &ret), &ctx_clone); + return ret; +} + +static ERL_NIF_TERM md5_mac_n(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Key, Data, MacSize) */ + unsigned char hmacbuf[SHA_DIGEST_LENGTH]; + ErlNifBinary key, data; + unsigned mac_sz; + ERL_NIF_TERM ret; + + if (!enif_inspect_iolist_as_binary(env, argv[0], &key) + || !enif_inspect_iolist_as_binary(env, argv[1], &data) + || !enif_get_uint(env,argv[2],&mac_sz) || mac_sz > MD5_LEN) { + return enif_make_badarg(env); + } + hmac_md5(key.data, key.size, data.data, data.size, hmacbuf); + memcpy(enif_make_new_binary(env, mac_sz, &ret), hmacbuf, mac_sz); + return ret; +} + +static ERL_NIF_TERM sha_mac_n(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Key, Data, MacSize) */ + unsigned char hmacbuf[SHA_DIGEST_LENGTH]; + ErlNifBinary key, data; + unsigned mac_sz; + ERL_NIF_TERM ret; + + if (!enif_inspect_iolist_as_binary(env, argv[0], &key) + || !enif_inspect_iolist_as_binary(env, argv[1], &data) + || !enif_get_uint(env,argv[2],&mac_sz) || mac_sz > SHA_LEN) { + return enif_make_badarg(env); + } + hmac_sha1(key.data, key.size, data.data, data.size, hmacbuf); + memcpy(enif_make_new_binary(env, mac_sz, &ret), + hmacbuf, mac_sz); + return ret; +} + +static ERL_NIF_TERM des_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Key, Ivec, Text, IsEncrypt) */ + ErlNifBinary key, ivec, text; + DES_key_schedule schedule; + DES_cblock ivec_clone; /* writable copy */ + ERL_NIF_TERM ret; + + if (!enif_inspect_iolist_as_binary(env, argv[0], &key) || key.size != 8 + || !enif_inspect_binary(env, argv[1], &ivec) || ivec.size != 8 + || !enif_inspect_iolist_as_binary(env, argv[2], &text) + || text.size % 8 != 0) { + return enif_make_badarg(env); + } + memcpy(&ivec_clone, ivec.data, 8); + DES_set_key((const_DES_cblock*)key.data, &schedule); + DES_ncbc_encrypt(text.data, enif_make_new_binary(env, text.size, &ret), + text.size, &schedule, &ivec_clone, (argv[3] == atom_true)); + return ret; +} + +static ERL_NIF_TERM des_ecb_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Key, Text/Cipher, IsEncrypt) */ + ErlNifBinary key, text; + DES_key_schedule schedule; + ERL_NIF_TERM ret; + if (!enif_inspect_iolist_as_binary(env, argv[0], &key) || key.size != 8 || + !enif_inspect_iolist_as_binary(env, argv[1], &text) || text.size != 8) { + return enif_make_badarg(env); + } + DES_set_key((const_DES_cblock*)key.data, &schedule); + DES_ecb_encrypt((const_DES_cblock*)text.data, + (DES_cblock*)enif_make_new_binary(env, 8, &ret), + &schedule, (argv[2] == atom_true)); + return ret; +} + +static ERL_NIF_TERM des_ede3_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Key1, Key2, Key3, IVec, Text/Cipher, IsEncrypt) */ + ErlNifBinary key1, key2, key3, ivec, text; + DES_key_schedule schedule1, schedule2, schedule3; + DES_cblock ivec_clone; /* writable copy */ + ERL_NIF_TERM ret; + + if (!enif_inspect_iolist_as_binary(env, argv[0], &key1) || key1.size != 8 + || !enif_inspect_iolist_as_binary(env, argv[1], &key2) || key2.size != 8 + || !enif_inspect_iolist_as_binary(env, argv[2], &key3) || key3.size != 8 + || !enif_inspect_binary(env, argv[3], &ivec) || ivec.size != 8 + || !enif_inspect_iolist_as_binary(env, argv[4], &text) + || text.size % 8 != 0) { + return enif_make_badarg(env); + } + + memcpy(&ivec_clone, ivec.data, 8); + DES_set_key((const_DES_cblock*)key1.data, &schedule1); + DES_set_key((const_DES_cblock*)key2.data, &schedule2); + DES_set_key((const_DES_cblock*)key3.data, &schedule3); + DES_ede3_cbc_encrypt(text.data, enif_make_new_binary(env,text.size,&ret), + text.size, &schedule1, &schedule2, &schedule3, + &ivec_clone, (argv[5] == atom_true)); + return ret; +} + +static ERL_NIF_TERM aes_cfb_128_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Key, IVec, Data, IsEncrypt) */ + ErlNifBinary key, ivec, text; + AES_KEY aes_key; + unsigned char ivec_clone[16]; /* writable copy */ + int new_ivlen = 0; + ERL_NIF_TERM ret; + + if (!enif_inspect_iolist_as_binary(env, argv[0], &key) || key.size != 16 + || !enif_inspect_binary(env, argv[1], &ivec) || ivec.size != 16 + || !enif_inspect_iolist_as_binary(env, argv[2], &text) + || text.size % 16 != 0) { + return enif_make_badarg(env); + } + + memcpy(ivec_clone, ivec.data, 16); + AES_set_encrypt_key(key.data, 128, &aes_key); + AES_cfb128_encrypt((unsigned char *) text.data, + enif_make_new_binary(env, text.size, &ret), + text.size, &aes_key, ivec_clone, &new_ivlen, + (argv[3] == atom_true)); + return ret; +} + +static ERL_NIF_TERM rand_bytes_1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Bytes) */ + unsigned bytes; + unsigned char* data; + ERL_NIF_TERM ret; + if (!enif_get_uint(env, argv[0], &bytes)) { + return enif_make_badarg(env); + } + data = enif_make_new_binary(env, bytes, &ret); + RAND_pseudo_bytes(data, bytes); + ERL_VALGRIND_MAKE_MEM_DEFINED(data, bytes); + return ret; +} +static ERL_NIF_TERM rand_bytes_3(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Bytes, TopMask, BottomMask) */ + unsigned bytes; + unsigned char* data; + unsigned top_mask, bot_mask; + ERL_NIF_TERM ret; + if (!enif_get_uint(env, argv[0], &bytes) + || !enif_get_uint(env, argv[1], &top_mask) + || !enif_get_uint(env, argv[2], &bot_mask)) { + return enif_make_badarg(env); + } + data = enif_make_new_binary(env, bytes, &ret); + RAND_pseudo_bytes(data, bytes); + ERL_VALGRIND_MAKE_MEM_DEFINED(data, bytes); + if (bytes > 0) { + data[bytes-1] |= top_mask; + data[0] |= bot_mask; + } + return ret; +} + +static int get_bn_from_mpint(ErlNifEnv* env, ERL_NIF_TERM term, BIGNUM** bnp) +{ + ErlNifBinary bin; + int sz; + if (!enif_inspect_binary(env,term,&bin)) { + return 0; + } + ERL_VALGRIND_ASSERT_MEM_DEFINED(bin.data, bin.size); + sz = bin.size - 4; + if (sz < 0 || get_int32(bin.data) != sz) { + return 0; + } + *bnp = BN_bin2bn(bin.data+4, sz, NULL); + return 1; +} + +static ERL_NIF_TERM rand_uniform_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Lo,Hi) */ + 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); + } + + bn_to = BN_new(); + BN_sub(bn_to, bn_rand, bn_from); + BN_pseudo_rand_range(bn_rand, bn_to); + BN_add(bn_rand, bn_rand, bn_from); + dlen = BN_num_bytes(bn_rand); + data = enif_make_new_binary(env, dlen+4, &ret); + put_int32(data, dlen); + BN_bn2bin(bn_rand, data+4); + ERL_VALGRIND_MAKE_MEM_DEFINED(data+4, dlen); + BN_free(bn_rand); + BN_free(bn_from); + BN_free(bn_to); + return ret; +} + +static ERL_NIF_TERM mod_exp_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Base,Exponent,Modulo) */ + BIGNUM *bn_base=NULL, *bn_exponent=NULL, *bn_modulo, *bn_result; + BN_CTX *bn_ctx; + unsigned char* ptr; + unsigned dlen; + ERL_NIF_TERM ret; + + if (!get_bn_from_mpint(env, argv[0], &bn_base) + || !get_bn_from_mpint(env, argv[1], &bn_exponent) + || !get_bn_from_mpint(env, argv[2], &bn_modulo)) { + + if (bn_base) BN_free(bn_base); + if (bn_exponent) BN_free(bn_exponent); + return enif_make_badarg(env); + } + bn_result = BN_new(); + bn_ctx = BN_CTX_new(); + BN_mod_exp(bn_result, bn_base, bn_exponent, bn_modulo, bn_ctx); + dlen = BN_num_bytes(bn_result); + ptr = enif_make_new_binary(env, dlen+4, &ret); + put_int32(ptr, dlen); + BN_bn2bin(bn_result, ptr+4); + BN_free(bn_result); + BN_CTX_free(bn_ctx); + BN_free(bn_modulo); + BN_free(bn_exponent); + BN_free(bn_base); + return ret; +} + +static int inspect_mpint(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifBinary* bin) +{ + return enif_inspect_binary(env, term, bin) && + bin->size >= 4 && get_int32(bin->data) == bin->size-4; +} + +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 = NULL, *dsa_q = NULL, *dsa_g = NULL, *dsa_y = NULL; + unsigned char hmacbuf[SHA_DIGEST_LENGTH]; + ERL_NIF_TERM head, tail; + DSA *dsa; + int i; + + if (!inspect_mpint(env, argv[2], &sign_bin) + || !enif_get_list_cell(env, argv[3], &head, &tail) + || !get_bn_from_mpint(env, head, &dsa_p) + || !enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &dsa_q) + || !enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &dsa_g) + || !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)) { + SHA1(data_bin.data+4, data_bin.size-4, hmacbuf); + } + else if (argv[0] == atom_none && enif_inspect_binary(env, argv[1], &data_bin) + && data_bin.size == SHA_DIGEST_LENGTH) { + memcpy(hmacbuf, data_bin.data, SHA_DIGEST_LENGTH); + } + else { + goto badarg; + } + + dsa = DSA_new(); + dsa->p = dsa_p; + dsa->q = dsa_q; + dsa->g = dsa_g; + dsa->priv_key = NULL; + dsa->pub_key = dsa_y; + i = DSA_verify(0, hmacbuf, SHA_DIGEST_LENGTH, + sign_bin.data+4, sign_bin.size-4, dsa); + DSA_free(dsa); + return(i > 0) ? atom_true : atom_false; +} + +static ERL_NIF_TERM rsa_verify(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Type, Data, Signature, Key=[E,N]) */ + ErlNifBinary data_bin, sign_bin; + unsigned char hmacbuf[SHA_DIGEST_LENGTH]; + ERL_NIF_TERM head, tail, ret; + int i, is_sha; + RSA* rsa = RSA_new(); + + if (argv[0] == atom_sha) is_sha = 1; + else if (argv[0] == atom_md5) is_sha = 0; + else goto badarg; + + if (!inspect_mpint(env, argv[1], &data_bin) + || !inspect_mpint(env, argv[2], &sign_bin) + || !enif_get_list_cell(env, argv[3], &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->e) + || !enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->n) + || !enif_is_empty_list(env, tail)) { + badarg: + ret = enif_make_badarg(env); + } + else { + if (is_sha) { + SHA1(data_bin.data+4, data_bin.size-4, hmacbuf); + i = RSA_verify(NID_sha1, hmacbuf, SHA_DIGEST_LENGTH, + sign_bin.data+4, sign_bin.size-4, rsa); + } + else { + MD5(data_bin.data+4, data_bin.size-4, hmacbuf); + i = RSA_verify(NID_md5, hmacbuf, MD5_DIGEST_LENGTH, + sign_bin.data+4, sign_bin.size-4, rsa); + } + ret = (i==1 ? atom_true : atom_false); + } + RSA_free(rsa); + return ret; +} + +static ERL_NIF_TERM aes_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Key, IVec, Data, IsEncrypt) */ + ErlNifBinary key_bin, ivec_bin, data_bin; + AES_KEY aes_key; + unsigned char ivec[16]; + int i; + unsigned char* ret_ptr; + ERL_NIF_TERM ret; + + if (!enif_inspect_iolist_as_binary(env, argv[0], &key_bin) + || (key_bin.size != 16 && key_bin.size != 32) + || !enif_inspect_binary(env, argv[1], &ivec_bin) + || ivec_bin.size != 16 + || !enif_inspect_iolist_as_binary(env, argv[2], &data_bin) + || data_bin.size % 16 != 0) { + + return enif_make_badarg(env); + } + + if (argv[3] == atom_true) { + i = AES_ENCRYPT; + AES_set_encrypt_key(key_bin.data, key_bin.size*8, &aes_key); + } + else { + i = AES_DECRYPT; + AES_set_decrypt_key(key_bin.data, key_bin.size*8, &aes_key); + } + + ret_ptr = enif_make_new_binary(env, data_bin.size, &ret); + memcpy(ivec, ivec_bin.data, 16); /* writable copy */ + AES_cbc_encrypt(data_bin.data, ret_ptr, data_bin.size, &aes_key, ivec, i); + return ret; +} + +static ERL_NIF_TERM exor(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Data1, Data2) */ + ErlNifBinary d1, d2; + unsigned char* ret_ptr; + int i; + ERL_NIF_TERM ret; + + if (!enif_inspect_iolist_as_binary(env,argv[0], &d1) + || !enif_inspect_iolist_as_binary(env,argv[1], &d2) + || d1.size != d2.size) { + return enif_make_badarg(env); + } + ret_ptr = enif_make_new_binary(env, d1.size, &ret); + + for (i=0; i<d1.size; i++) { + ret_ptr[i] = d1.data[i] ^ d2.data[i]; + } + return ret; +} + +static ERL_NIF_TERM rc4_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Key, Data) */ + ErlNifBinary key, data; + RC4_KEY rc4_key; + ERL_NIF_TERM ret; + + if (!enif_inspect_iolist_as_binary(env,argv[0], &key) + || !enif_inspect_iolist_as_binary(env,argv[1], &data)) { + return enif_make_badarg(env); + } + RC4_set_key(&rc4_key, key.size, key.data); + RC4(&rc4_key, data.size, data.data, + enif_make_new_binary(env, data.size, &ret)); + return ret; +} + +static ERL_NIF_TERM rc4_set_key(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Key) */ + ErlNifBinary key; + ERL_NIF_TERM ret; + + if (!enif_inspect_iolist_as_binary(env,argv[0], &key)) { + return enif_make_badarg(env); + } + RC4_set_key((RC4_KEY*)enif_make_new_binary(env, sizeof(RC4_KEY), &ret), + key.size, key.data); + return ret; +} + +static ERL_NIF_TERM rc4_encrypt_with_state(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (State, Data) */ + + ErlNifBinary state, data; + RC4_KEY* rc4_key; + ERL_NIF_TERM new_state, new_data; + + if (!enif_inspect_iolist_as_binary(env,argv[0], &state) + || state.size != sizeof(RC4_KEY) + || !enif_inspect_iolist_as_binary(env,argv[1], &data)) { + return enif_make_badarg(env); + } + rc4_key = (RC4_KEY*)enif_make_new_binary(env, sizeof(RC4_KEY), &new_state); + memcpy(rc4_key, state.data, sizeof(RC4_KEY)); + RC4(rc4_key, data.size, data.data, + enif_make_new_binary(env, data.size, &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[]) +{/* (Key,IVec,Data,IsEncrypt) */ + ErlNifBinary key_bin, ivec_bin, data_bin; + RC2_KEY rc2_key; + ERL_NIF_TERM ret; + + if (!enif_inspect_iolist_as_binary(env, argv[0], &key_bin) + || key_bin.size != 5 + || !enif_inspect_binary(env, argv[1], &ivec_bin) + || ivec_bin.size != 8 + || !enif_inspect_iolist_as_binary(env, argv[2], &data_bin)) { + + return enif_make_badarg(env); + } + + RC2_set_key(&rc2_key, 5, key_bin.data, 40); + RC2_cbc_encrypt(data_bin.data, + enif_make_new_binary(env, data_bin.size, &ret), + data_bin.size, &rc2_key, + ivec_bin.data, + (argv[3] == atom_true)); + + return ret; +} + +static ERL_NIF_TERM rsa_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Type,Data,Key=[E,N,D]) */ + ErlNifBinary data_bin, ret_bin; + ERL_NIF_TERM head, tail; + unsigned char hmacbuf[SHA_DIGEST_LENGTH]; + unsigned rsa_s_len; + RSA *rsa = RSA_new(); + int i, is_sha; + + if (argv[0] == atom_sha) is_sha = 1; + else if (argv[0] == atom_md5) is_sha = 0; + else goto badarg; + + if (!inspect_mpint(env,argv[1],&data_bin) + || !enif_get_list_cell(env, argv[2], &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->e) + || !enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->n) + || !enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->d) + || !enif_is_empty_list(env,tail)) { + badarg: + RSA_free(rsa); + return enif_make_badarg(env); + } + enif_alloc_binary(RSA_size(rsa), &ret_bin); + if (is_sha) { + SHA1(data_bin.data+4, data_bin.size-4, hmacbuf); + ERL_VALGRIND_ASSERT_MEM_DEFINED(hmacbuf, SHA_DIGEST_LENGTH); + i = RSA_sign(NID_sha1, hmacbuf, SHA_DIGEST_LENGTH, + ret_bin.data, &rsa_s_len, rsa); + } + else { + MD5(data_bin.data+4, data_bin.size-4, hmacbuf); + ERL_VALGRIND_ASSERT_MEM_DEFINED(hmacbuf, MD5_DIGEST_LENGTH); + i = RSA_sign(NID_md5, hmacbuf,MD5_DIGEST_LENGTH, + ret_bin.data, &rsa_s_len, rsa); + } + RSA_free(rsa); + if (i) { + ERL_VALGRIND_MAKE_MEM_DEFINED(ret_bin.data, rsa_s_len); + if (rsa_s_len != data_bin.size) { + enif_realloc_binary(&ret_bin, rsa_s_len); + ERL_VALGRIND_ASSERT_MEM_DEFINED(ret_bin.data, rsa_s_len); + } + return enif_make_binary(env,&ret_bin); + } + else { + enif_release_binary(&ret_bin); + return atom_error; + } +} + +static ERL_NIF_TERM dss_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (DigesType, Data, Key=[P,Q,G,PrivKey]) */ + ErlNifBinary data_bin, ret_bin; + ERL_NIF_TERM head, tail; + unsigned char hmacbuf[SHA_DIGEST_LENGTH]; + unsigned int dsa_s_len; + DSA* dsa = DSA_new(); + int i; + + dsa->pub_key = NULL; + if (!enif_get_list_cell(env, argv[2], &head, &tail) + || !get_bn_from_mpint(env, head, &dsa->p) + || !enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &dsa->q) + || !enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &dsa->g) + || !enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &dsa->priv_key) + || !enif_is_empty_list(env,tail)) { + goto badarg; + } + if (argv[0] == atom_sha && inspect_mpint(env, argv[1], &data_bin)) { + SHA1(data_bin.data+4, data_bin.size-4, hmacbuf); + } + else if (argv[0] == atom_none && enif_inspect_binary(env,argv[1],&data_bin) + && data_bin.size == SHA_DIGEST_LENGTH) { + memcpy(hmacbuf, data_bin.data, SHA_DIGEST_LENGTH); + } + else { + badarg: + DSA_free(dsa); + return enif_make_badarg(env); + } + + enif_alloc_binary(DSA_size(dsa), &ret_bin); + i = DSA_sign(NID_sha1, hmacbuf, SHA_DIGEST_LENGTH, + ret_bin.data, &dsa_s_len, dsa); + DSA_free(dsa); + if (i) { + if (dsa_s_len != ret_bin.size) { + enif_realloc_binary(&ret_bin, dsa_s_len); + } + return enif_make_binary(env, &ret_bin); + } + else { + return atom_error; + } +} + +static int rsa_pad(ERL_NIF_TERM term, int* padding) +{ + if (term == atom_rsa_pkcs1_padding) { + *padding = RSA_PKCS1_PADDING; + } + else if (term == atom_rsa_pkcs1_oaep_padding) { + *padding = RSA_PKCS1_OAEP_PADDING; + } + else if (term == atom_rsa_no_padding) { + *padding = RSA_NO_PADDING; + } + else { + return 0; + } + return 1; +} + +static ERL_NIF_TERM rsa_public_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Data, PublKey=[E,N], Padding, IsEncrypt) */ + ErlNifBinary data_bin, ret_bin; + ERL_NIF_TERM head, tail; + int padding, i; + RSA* rsa = RSA_new(); + + if (!enif_inspect_binary(env, argv[0], &data_bin) + || !enif_get_list_cell(env, argv[1], &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->e) + || !enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->n) + || !enif_is_empty_list(env,tail) + || !rsa_pad(argv[2], &padding)) { + + RSA_free(rsa); + return enif_make_badarg(env); + } + + enif_alloc_binary(RSA_size(rsa), &ret_bin); + + if (argv[3] == atom_true) { + 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) { + ERL_VALGRIND_MAKE_MEM_DEFINED(ret_bin.data, i); + } + } + else { + i = RSA_public_decrypt(data_bin.size, data_bin.data, + ret_bin.data, rsa, padding); + if (i > 0) { + ERL_VALGRIND_MAKE_MEM_DEFINED(ret_bin.data, i); + enif_realloc_binary(&ret_bin, i); + } + } + RSA_free(rsa); + if (i > 0) { + return enif_make_binary(env,&ret_bin); + } + else { + enif_release_binary(&ret_bin); + return atom_error; + } +} + +static ERL_NIF_TERM rsa_private_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Data, PublKey=[E,N,D], Padding, IsEncrypt) */ + ErlNifBinary data_bin, ret_bin; + ERL_NIF_TERM head, tail; + int padding, i; + RSA* rsa = RSA_new(); + + if (!enif_inspect_binary(env, argv[0], &data_bin) + || !enif_get_list_cell(env, argv[1], &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->e) + || !enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->n) + || !enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->d) + || !enif_is_empty_list(env,tail) + || !rsa_pad(argv[2], &padding)) { + + RSA_free(rsa); + return enif_make_badarg(env); + } + + enif_alloc_binary(RSA_size(rsa), &ret_bin); + + if (argv[3] == atom_true) { + 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) { + ERL_VALGRIND_MAKE_MEM_DEFINED(ret_bin.data, i); + } + } + else { + i = RSA_private_decrypt(data_bin.size, data_bin.data, + ret_bin.data, rsa, padding); + if (i > 0) { + ERL_VALGRIND_MAKE_MEM_DEFINED(ret_bin.data, i); + enif_realloc_binary(&ret_bin, i); + } + } + RSA_free(rsa); + if (i > 0) { + return enif_make_binary(env,&ret_bin); + } + else { + enif_release_binary(&ret_bin); + return atom_error; + } +} + +static ERL_NIF_TERM dh_generate_parameters_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (PrimeLen, Generator) */ + int prime_len, generator; + DH* dh_params; + int p_len, g_len; + unsigned char *p_ptr, *g_ptr; + ERL_NIF_TERM ret_p, ret_g; + + if (!enif_get_int(env, argv[0], &prime_len) + || !enif_get_int(env, argv[1], &generator)) { + + return enif_make_badarg(env); + } + dh_params = DH_generate_parameters(prime_len, generator, NULL, NULL); + if (dh_params == NULL) { + return atom_error; + } + p_len = BN_num_bytes(dh_params->p); + g_len = BN_num_bytes(dh_params->g); + p_ptr = enif_make_new_binary(env, p_len+4, &ret_p); + g_ptr = enif_make_new_binary(env, g_len+4, &ret_g); + put_int32(p_ptr, p_len); + put_int32(g_ptr, g_len); + BN_bn2bin(dh_params->p, p_ptr+4); + BN_bn2bin(dh_params->g, g_ptr+4); + ERL_VALGRIND_MAKE_MEM_DEFINED(p_ptr+4, p_len); + ERL_VALGRIND_MAKE_MEM_DEFINED(g_ptr+4, g_len); + DH_free(dh_params); + return enif_make_list2(env, ret_p, ret_g); +} + +static ERL_NIF_TERM dh_check(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* ([PrimeLen, Generator]) */ + DH* dh_params = DH_new(); + int i; + ERL_NIF_TERM ret, head, tail; + + if (!enif_get_list_cell(env, argv[0], &head, &tail) + || !get_bn_from_mpint(env, head, &dh_params->p) + || !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); + } + if (DH_check(dh_params, &i)) { + if (i == 0) ret = atom_ok; + else if (i & DH_CHECK_P_NOT_PRIME) ret = atom_not_prime; + else if (i & DH_CHECK_P_NOT_SAFE_PRIME) ret = atom_not_strong_prime; + else if (i & DH_UNABLE_TO_CHECK_GENERATOR) ret = atom_unable_to_check_generator; + else if (i & DH_NOT_SUITABLE_GENERATOR) ret = atom_not_suitable_generator; + else ret = enif_make_tuple2(env, atom_unknown, enif_make_uint(env, i)); + } + else { /* Check Failed */ + ret = enif_make_tuple2(env, atom_error, atom_check_failed); + } + DH_free(dh_params); + return ret; +} + +static ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (PrivKey, DHParams=[P,G]) */ + DH* dh_params = DH_new(); + int pub_len, prv_len; + unsigned char *pub_ptr, *prv_ptr; + ERL_NIF_TERM ret, ret_pub, ret_prv, head, tail; + + if (!(get_bn_from_mpint(env, argv[0], &dh_params->priv_key) + || argv[0] == atom_undefined) + || !enif_get_list_cell(env, argv[1], &head, &tail) + || !get_bn_from_mpint(env, head, &dh_params->p) + || !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); + } + + if (DH_generate_key(dh_params)) { + pub_len = BN_num_bytes(dh_params->pub_key); + prv_len = BN_num_bytes(dh_params->priv_key); + pub_ptr = enif_make_new_binary(env, pub_len+4, &ret_pub); + prv_ptr = enif_make_new_binary(env, prv_len+4, &ret_prv); + put_int32(pub_ptr, pub_len); + put_int32(prv_ptr, prv_len); + BN_bn2bin(dh_params->pub_key, pub_ptr+4); + BN_bn2bin(dh_params->priv_key, prv_ptr+4); + ERL_VALGRIND_MAKE_MEM_DEFINED(pub_ptr+4, pub_len); + ERL_VALGRIND_MAKE_MEM_DEFINED(prv_ptr+4, prv_len); + ret = enif_make_tuple2(env, ret_pub, ret_prv); + } + else { + ret = atom_error; + } + DH_free(dh_params); + return ret; +} + +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 = NULL; + int i; + ErlNifBinary ret_bin; + ERL_NIF_TERM ret, head, tail; + + if (!get_bn_from_mpint(env, argv[0], &pubkey) + || !get_bn_from_mpint(env, argv[1], &dh_params->priv_key) + || !enif_get_list_cell(env, argv[2], &head, &tail) + || !get_bn_from_mpint(env, head, &dh_params->p) + || !enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &dh_params->g) + || !enif_is_empty_list(env, tail)) { + + ret = enif_make_badarg(env); + } + else { + enif_alloc_binary(DH_size(dh_params), &ret_bin); + i = DH_compute_key(ret_bin.data, pubkey, dh_params); + if (i > 0) { + if (i != ret_bin.size) { + enif_realloc_binary(&ret_bin, i); + } + ret = enif_make_binary(env, &ret_bin); + } + else { + ret = atom_error; + } + } + if (pubkey) BN_free(pubkey); + DH_free(dh_params); + return ret; +} + +static ERL_NIF_TERM bf_cfb64_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Key, Ivec, Data, IsEncrypt) */ + ErlNifBinary key_bin, ivec_bin, data_bin; + BF_KEY bf_key; /* blowfish key 8 */ + unsigned char bf_tkey[8]; /* blowfish ivec */ + int bf_n = 0; /* blowfish ivec pos */ + ERL_NIF_TERM ret; + + if (!enif_inspect_iolist_as_binary(env, argv[0], &key_bin) + || !enif_inspect_binary(env, argv[1], &ivec_bin) + || ivec_bin.size != 8 + || !enif_inspect_iolist_as_binary(env, argv[2], &data_bin)) { + return enif_make_badarg(env); + } + + BF_set_key(&bf_key, key_bin.size, key_bin.data); + memcpy(bf_tkey, ivec_bin.data, 8); + BF_cfb64_encrypt(data_bin.data, enif_make_new_binary(env,data_bin.size,&ret), + data_bin.size, &bf_key, bf_tkey, &bf_n, + (argv[3] == atom_true ? BF_ENCRYPT : BF_DECRYPT)); + return ret; +} + +static ERL_NIF_TERM bf_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Key, Ivec, Data, IsEncrypt) */ + ErlNifBinary key_bin, ivec_bin, data_bin; + BF_KEY bf_key; /* blowfish key 8 */ + unsigned char bf_tkey[8]; /* blowfish ivec */ + ERL_NIF_TERM ret; + + if (!enif_inspect_iolist_as_binary(env, argv[0], &key_bin) + || !enif_inspect_binary(env, argv[1], &ivec_bin) + || ivec_bin.size != 8 + || !enif_inspect_iolist_as_binary(env, argv[2], &data_bin) + || data_bin.size % 8 != 0) { + return enif_make_badarg(env); + } + + BF_set_key(&bf_key, key_bin.size, key_bin.data); + memcpy(bf_tkey, ivec_bin.data, 8); + BF_cbc_encrypt(data_bin.data, enif_make_new_binary(env,data_bin.size,&ret), + data_bin.size, &bf_key, bf_tkey, + (argv[3] == atom_true ? BF_ENCRYPT : BF_DECRYPT)); + return ret; +} + +static ERL_NIF_TERM bf_ecb_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Key, Data, IsEncrypt) */ + ErlNifBinary key_bin, data_bin; + BF_KEY bf_key; /* blowfish key 8 */ + ERL_NIF_TERM ret; + + if (!enif_inspect_iolist_as_binary(env, argv[0], &key_bin) + || !enif_inspect_iolist_as_binary(env, argv[1], &data_bin) + || data_bin.size < 8) { + return enif_make_badarg(env); + } + BF_set_key(&bf_key, key_bin.size, key_bin.data); + BF_ecb_encrypt(data_bin.data, enif_make_new_binary(env,data_bin.size,&ret), + &bf_key, (argv[2] == atom_true ? BF_ENCRYPT : BF_DECRYPT)); + return ret; +} + +static ERL_NIF_TERM blowfish_ofb64_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Key, IVec, Data) */ + ErlNifBinary key_bin, ivec_bin, data_bin; + BF_KEY bf_key; /* blowfish key 8 */ + unsigned char bf_tkey[8]; /* blowfish ivec */ + int bf_n = 0; /* blowfish ivec pos */ + ERL_NIF_TERM ret; + + if (!enif_inspect_iolist_as_binary(env, argv[0], &key_bin) + || !enif_inspect_binary(env, argv[1], &ivec_bin) + || ivec_bin.size != 8 + || !enif_inspect_iolist_as_binary(env, argv[2], &data_bin)) { + return enif_make_badarg(env); + } + + BF_set_key(&bf_key, key_bin.size, key_bin.data); + memcpy(bf_tkey, ivec_bin.data, 8); + BF_ofb64_encrypt(data_bin.data, enif_make_new_binary(env,data_bin.size,&ret), + data_bin.size, &bf_key, bf_tkey, &bf_n); + return ret; +} + + + +#ifdef OPENSSL_THREADS /* vvvvvvvvvvvvvvv OPENSSL_THREADS vvvvvvvvvvvvvvvv */ + +static INLINE void locking(int mode, ErlNifRWLock* lock) +{ + switch (mode) { + case CRYPTO_LOCK|CRYPTO_READ: + enif_rwlock_rlock(lock); + break; + case CRYPTO_LOCK|CRYPTO_WRITE: + enif_rwlock_rwlock(lock); + break; + case CRYPTO_UNLOCK|CRYPTO_READ: + enif_rwlock_runlock(lock); + break; + case CRYPTO_UNLOCK|CRYPTO_WRITE: + enif_rwlock_rwunlock(lock); + break; + default: + ASSERT(!"Invalid lock mode"); + } +} + +/* Callback from openssl for static locking + */ +static void locking_function(int mode, int n, const char *file, int line) +{ + ASSERT(n>=0 && n<CRYPTO_num_locks()); + + locking(mode, lock_vec[n]); +} + +/* Callback from openssl for thread id + */ +static unsigned long id_function(void) +{ + return(unsigned long) enif_thread_self(); +} + +/* Callbacks for dynamic locking, not used by current openssl version (0.9.8) + */ +static struct CRYPTO_dynlock_value* dyn_create_function(const char *file, int line) { + return(struct CRYPTO_dynlock_value*) enif_rwlock_create("crypto_dyn"); +} +static void dyn_lock_function(int mode, struct CRYPTO_dynlock_value* ptr,const char *file, int line) +{ + locking(mode, (ErlNifRWLock*)ptr); +} +static void dyn_destroy_function(struct CRYPTO_dynlock_value *ptr, const char *file, int line) +{ + enif_rwlock_destroy((ErlNifRWLock*)ptr); +} + +#endif /* ^^^^^^^^^^^^^^^^^^^^^^ OPENSSL_THREADS ^^^^^^^^^^^^^^^^^^^^^^ */ + +/* HMAC */ + +static void hmac_md5(unsigned char *key, int klen, unsigned char *dbuf, int dlen, + unsigned char *hmacbuf) +{ + MD5_CTX ctx; + char ipad[HMAC_INT_LEN]; + char opad[HMAC_INT_LEN]; + unsigned char nkey[MD5_LEN]; + int i; + + /* Change key if longer than 64 bytes */ + if (klen > HMAC_INT_LEN) { + MD5(key, klen, nkey); + key = nkey; + klen = MD5_LEN; + } + + memset(ipad, '\0', sizeof(ipad)); + memset(opad, '\0', sizeof(opad)); + memcpy(ipad, key, klen); + memcpy(opad, key, klen); + + for (i = 0; i < HMAC_INT_LEN; i++) { + ipad[i] ^= HMAC_IPAD; + opad[i] ^= HMAC_OPAD; + } + + /* inner MD5 */ + MD5_Init(&ctx); + MD5_Update(&ctx, ipad, HMAC_INT_LEN); + MD5_Update(&ctx, dbuf, dlen); + MD5_Final((unsigned char *) hmacbuf, &ctx); + /* outer MD5 */ + MD5_Init(&ctx); + MD5_Update(&ctx, opad, HMAC_INT_LEN); + MD5_Update(&ctx, hmacbuf, MD5_LEN); + MD5_Final((unsigned char *) hmacbuf, &ctx); +} + +static void hmac_sha1(unsigned char *key, int klen, + unsigned char *dbuf, int dlen, + unsigned char *hmacbuf) +{ + SHA_CTX ctx; + char ipad[HMAC_INT_LEN]; + char opad[HMAC_INT_LEN]; + unsigned char nkey[SHA_LEN]; + int i; + + /* Change key if longer than 64 bytes */ + if (klen > HMAC_INT_LEN) { + SHA1(key, klen, nkey); + key = nkey; + klen = SHA_LEN; + } + + memset(ipad, '\0', sizeof(ipad)); + memset(opad, '\0', sizeof(opad)); + memcpy(ipad, key, klen); + memcpy(opad, key, klen); + + for (i = 0; i < HMAC_INT_LEN; i++) { + ipad[i] ^= HMAC_IPAD; + opad[i] ^= HMAC_OPAD; + } + + /* inner SHA */ + SHA1_Init(&ctx); + SHA1_Update(&ctx, ipad, HMAC_INT_LEN); + SHA1_Update(&ctx, dbuf, dlen); + SHA1_Final((unsigned char *) hmacbuf, &ctx); + /* outer SHA */ + SHA1_Init(&ctx); + SHA1_Update(&ctx, opad, HMAC_INT_LEN); + SHA1_Update(&ctx, hmacbuf, SHA_LEN); + SHA1_Final((unsigned char *) hmacbuf, &ctx); +} + diff --git a/lib/crypto/c_src/crypto_drv.c b/lib/crypto/c_src/crypto_drv.c deleted file mode 100644 index 5b6d750dde..0000000000 --- a/lib/crypto/c_src/crypto_drv.c +++ /dev/null @@ -1,1799 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Ericsson AB 1999-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: Dynamically loadable driver for cryptography libraries. - * Based on OpenSSL. - */ - -#ifdef __WIN32__ -#include <windows.h> -#endif - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include "erl_driver.h" - -#define OPENSSL_THREAD_DEFINES -#include <openssl/opensslconf.h> -#ifndef OPENSSL_THREADS -# ifdef __GNUC__ -# warning No thread support by openssl. Driver will use coarse grain locking. -# endif -#endif - -#include <openssl/crypto.h> -#include <openssl/des.h> -/* #include <openssl/idea.h> This is not supported on the openssl OTP requires */ -#include <openssl/dsa.h> -#include <openssl/rsa.h> -#include <openssl/aes.h> -#include <openssl/md5.h> -#include <openssl/md4.h> -#include <openssl/sha.h> -#include <openssl/bn.h> -#include <openssl/objects.h> -#include <openssl/rc4.h> -#include <openssl/rc2.h> -#include <openssl/blowfish.h> -#include <openssl/rand.h> - -#ifdef VALGRIND -# include <valgrind/memcheck.h> - -/* libcrypto mixes supplied buffer contents into its entropy pool, - which makes valgrind complain about the use of uninitialized data. - We use this valgrind "request" to make sure that no such seemingly - undefined data escapes the driver. -*/ -# define ERL_VALGRIND_MAKE_MEM_DEFINED(ptr,size) \ - VALGRIND_MAKE_MEM_DEFINED(ptr,size) - -# 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))) -#else -# define ERL_VALGRIND_MAKE_MEM_DEFINED(ptr,size) -# define ERL_VALGRIND_ASSERT_MEM_DEFINED(ptr,size) -#endif - -#ifdef DEBUG -# define ASSERT(e) \ - ((void) ((e) ? 1 : (fprintf(stderr,"Assert '%s' failed at %s:%d\n",\ - #e, __FILE__, __LINE__), abort(), 0))) -#else -# define ASSERT(e) ((void) 1) -#endif - -#ifdef __GNUC__ -# define INLINE __inline__ -#elif defined(__WIN32__) -# define INLINE __forceinline -#else -# define INLINE -#endif - - -#define get_int32(s) ((((unsigned char*) (s))[0] << 24) | \ - (((unsigned char*) (s))[1] << 16) | \ - (((unsigned char*) (s))[2] << 8) | \ - (((unsigned char*) (s))[3])) - -#define put_int32(s,i) \ -{ (s)[0] = (char)(((i) >> 24) & 0xff);\ - (s)[1] = (char)(((i) >> 16) & 0xff);\ - (s)[2] = (char)(((i) >> 8) & 0xff);\ - (s)[3] = (char)((i) & 0xff);\ -} - -/* Driver interface declarations */ -static int init(void); -static void finish(void); -static ErlDrvData start(ErlDrvPort port, char *command); -static void stop(ErlDrvData drv_data); -static int crypto_control(ErlDrvData drv_data, unsigned int command, char *buf, - int len, char **rbuf, int rlen); - -/* openssl callbacks */ -#ifdef OPENSSL_THREADS -static void locking_function(int mode, int n, const char *file, int line); -static unsigned long id_function(void); -static struct CRYPTO_dynlock_value* dyn_create_function(const char *file, - int line); -static void dyn_lock_function(int mode, struct CRYPTO_dynlock_value* ptr, - const char *file, int line); -static void dyn_destroy_function(struct CRYPTO_dynlock_value *ptr, - const char *file, int line); -#endif /* OPENSSL_THREADS */ - -/* helpers */ -static void hmac_md5(char *key, int klen, char *dbuf, int dlen, - char *hmacbuf); -static void hmac_sha1(char *key, int klen, char *dbuf, int dlen, - char *hmacbuf); - -static ErlDrvEntry crypto_driver_entry = { - init, - start, - stop, - NULL, /* output */ - NULL, /* ready_input */ - NULL, /* ready_output */ - "crypto_drv", - finish, - NULL, /* handle */ - crypto_control, - NULL, /* timeout */ - NULL, /* outputv */ - - NULL, /* ready_async */ - NULL, /* flush */ - NULL, /* call */ - NULL, /* event */ - ERL_DRV_EXTENDED_MARKER, - ERL_DRV_EXTENDED_MAJOR_VERSION, - ERL_DRV_EXTENDED_MINOR_VERSION, -#ifdef OPENSSL_THREADS - ERL_DRV_FLAG_USE_PORT_LOCKING, -#else - 0, -#endif - NULL, /* handle2 */ - NULL /* process_exit */ -}; - - -/* Keep the following definitions in alignment with the FUNC_LIST - * in crypto.erl. - */ - -#define DRV_INFO 0 -#define DRV_MD5 1 -#define DRV_MD5_INIT 2 -#define DRV_MD5_UPDATE 3 -#define DRV_MD5_FINAL 4 -#define DRV_SHA 5 -#define DRV_SHA_INIT 6 -#define DRV_SHA_UPDATE 7 -#define DRV_SHA_FINAL 8 -#define DRV_MD5_MAC 9 -#define DRV_MD5_MAC_96 10 -#define DRV_SHA_MAC 11 -#define DRV_SHA_MAC_96 12 -#define DRV_CBC_DES_ENCRYPT 13 -#define DRV_CBC_DES_DECRYPT 14 -#define DRV_EDE3_CBC_DES_ENCRYPT 15 -#define DRV_EDE3_CBC_DES_DECRYPT 16 -#define DRV_AES_CFB_128_ENCRYPT 17 -#define DRV_AES_CFB_128_DECRYPT 18 -#define DRV_RAND_BYTES 19 -#define DRV_RAND_UNIFORM 20 -#define DRV_MOD_EXP 21 -#define DRV_DSS_VERIFY 22 -#define DRV_RSA_VERIFY_SHA 23 -/* #define DRV_RSA_VERIFY_MD5 35 */ -#define DRV_CBC_AES128_ENCRYPT 24 -#define DRV_CBC_AES128_DECRYPT 25 -#define DRV_XOR 26 -#define DRV_RC4_ENCRYPT 27 /* no decrypt needed; symmetric */ -#define DRV_RC4_SETKEY 28 -#define DRV_RC4_ENCRYPT_WITH_STATE 29 -#define DRV_CBC_RC2_40_ENCRYPT 30 -#define DRV_CBC_RC2_40_DECRYPT 31 -#define DRV_CBC_AES256_ENCRYPT 32 -#define DRV_CBC_AES256_DECRYPT 33 -#define DRV_INFO_LIB 34 -/* #define DRV_RSA_VERIFY_SHA 23 */ -#define DRV_RSA_VERIFY_MD5 35 -#define DRV_RSA_SIGN_SHA 36 -#define DRV_RSA_SIGN_MD5 37 -#define DRV_DSS_SIGN 38 -#define DRV_RSA_PUBLIC_ENCRYPT 39 -#define DRV_RSA_PRIVATE_DECRYPT 40 -#define DRV_RSA_PRIVATE_ENCRYPT 41 -#define DRV_RSA_PUBLIC_DECRYPT 42 -#define DRV_DH_GENERATE_PARAMS 43 -#define DRV_DH_CHECK 44 -#define DRV_DH_GENERATE_KEY 45 -#define DRV_DH_COMPUTE_KEY 46 -#define DRV_MD4 47 -#define DRV_MD4_INIT 48 -#define DRV_MD4_UPDATE 49 -#define DRV_MD4_FINAL 50 - -#define SSL_VERSION_0_9_8 0 -#if SSL_VERSION_0_9_8 -#define DRV_SHA256 51 -#define DRV_SHA256_INIT 52 -#define DRV_SHA256_UPDATE 53 -#define DRV_SHA256_FINAL 54 -#define DRV_SHA512 55 -#define DRV_SHA512_INIT 56 -#define DRV_SHA512_UPDATE 57 -#define DRV_SHA512_FINAL 58 -#endif - -#define DRV_BF_CFB64_ENCRYPT 59 -#define DRV_BF_CFB64_DECRYPT 60 -#define DRV_BF_ECB_ENCRYPT 61 -#define DRV_BF_ECB_DECRYPT 62 -#define DRV_BF_OFB64_ENCRYPT 63 -#define DRV_BF_CBC_ENCRYPT 64 -#define DRV_BF_CBC_DECRYPT 65 - -/* #define DRV_CBC_IDEA_ENCRYPT 34 */ -/* #define DRV_CBC_IDEA_DECRYPT 35 */ - -/* Not DRV_DH_GENERATE_PARAMS DRV_DH_CHECK - * Calc RSA_VERIFY_* and RSA_SIGN once */ -#define NUM_CRYPTO_FUNCS 46 - -#define MD5_CTX_LEN (sizeof(MD5_CTX)) -#define MD5_LEN 16 -#define MD5_LEN_96 12 -#define MD4_CTX_LEN (sizeof(MD4_CTX)) -#define MD4_LEN 16 -#define SHA_CTX_LEN (sizeof(SHA_CTX)) -#define SHA_LEN 20 -#define SHA_LEN_96 12 -#define HMAC_INT_LEN 64 - -#define HMAC_IPAD 0x36 -#define HMAC_OPAD 0x5c - -#if SSL_VERSION_0_9_8 -#define SHA256_CTX_LEN (sizeof(SHA256_CTX)) -#define SHA256_LEN 32 - -#define SHA512_CTX_LEN (sizeof(SHA512_CTX)) -#define SHA512_LEN 64 -#endif - -/* INITIALIZATION AFTER LOADING */ - -/* - * This is the init function called after this driver has been loaded. - * It must *not* be declared static. Must return the address to - * the driver entry. - */ - -#if !defined(__WIN32__) -DRIVER_INIT(crypto_drv); -#endif - -DRIVER_INIT(crypto_drv) -{ - return &crypto_driver_entry; -} - -static ErlDrvRWLock** lock_vec = NULL; /* Static locks used by openssl */ - -/* DRIVER INTERFACE */ - -static int init(void) -{ - ErlDrvSysInfo sys_info; - int i; - - CRYPTO_set_mem_functions(driver_alloc, driver_realloc, driver_free); - -#ifdef OPENSSL_THREADS - driver_system_info(&sys_info, sizeof(sys_info)); - - if(sys_info.scheduler_threads > 1) { - lock_vec = driver_alloc(CRYPTO_num_locks()*sizeof(*lock_vec)); - if (lock_vec==NULL) return -1; - memset(lock_vec,0,CRYPTO_num_locks()*sizeof(*lock_vec)); - - for(i=CRYPTO_num_locks()-1; i>=0; --i) { - lock_vec[i] = erl_drv_rwlock_create("crypto_drv_stat"); - if (lock_vec[i]==NULL) return -1; - } - CRYPTO_set_locking_callback(locking_function); - CRYPTO_set_id_callback(id_function); - CRYPTO_set_dynlock_create_callback(dyn_create_function); - CRYPTO_set_dynlock_lock_callback(dyn_lock_function); - CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function); - } - /* else no need for locks */ -#endif /* OPENSSL_THREADS */ - - return 0; -} - -static void finish(void) -{ - /* Moved here from crypto_control() as it's not thread safe */ - CRYPTO_cleanup_all_ex_data(); - - if(lock_vec != NULL) { - int i; - for(i=CRYPTO_num_locks()-1; i>=0; --i) { - if (lock_vec[i] != NULL) { - erl_drv_rwlock_destroy(lock_vec[i]); - } - } - driver_free(lock_vec); - } -} - -static ErlDrvData start(ErlDrvPort port, char *command) -{ - set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY); - return 0; /* not used */ -} - -static void stop(ErlDrvData drv_data) -{ - return; -} - -/* Helper functions for 'crypto_control' -*/ -static INLINE unsigned char* return_binary(char **rbuf, int rlen, int len) -{ - if (len <= rlen) { - return (unsigned char *) *rbuf; - } - else { - ErlDrvBinary* bin; - *rbuf = (char*) (bin = driver_alloc_binary(len)); - return (bin==NULL) ? NULL : (unsigned char *) bin->orig_bytes; - } -} - -static INLINE unsigned char* return_binary_shrink(char **rbuf, int rlen, unsigned char* data, int len) -{ - if ((char *) data == *rbuf) { /* default buffer */ - ASSERT(len <= rlen); - return (unsigned char *) data; - } - else { - ErlDrvBinary* bin = (ErlDrvBinary*) *rbuf; - *rbuf = (char*) (bin=driver_realloc_binary(bin, len)); - return (bin==NULL) ? NULL : (unsigned char *) bin->orig_bytes; - } -} - -/* Nowadays (R13) it does matter what value control returns - * as it may return data in default buffer. - */ -static int crypto_control(ErlDrvData drv_data, unsigned int command, char *buf, - int len, char **rbuf, int rlen) -{ - int klen, dlen, macsize, from_len, to_len, i; - int base_len, exponent_len, modulo_len; - int data_len, dsa_p_len, dsa_q_len; - int dsa_s_len, dsa_g_len, dsa_y_len; - int rsa_e_len, rsa_n_len, rsa_d_len, padding; - int or_mask; - int prime_len, generator; - int privkey_len, pubkey_len, dh_p_len, dh_g_len; - unsigned int rsa_s_len, j; - char *key, *key2, *dbuf; - unsigned char *p; - const_DES_cblock *des_key, *des_key2, *des_key3; - const unsigned char *des_dbuf; - BIGNUM *bn_from, *bn_to, *bn_rand, *bn_result; - BIGNUM *bn_base, *bn_exponent, *bn_modulo; - BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_y; - BIGNUM *rsa_n, *rsa_e, *rsa_d; - BIGNUM *dh_p, *dh_g, *privkey, *pubkey; - DES_cblock *des_ivec; - unsigned char* bin; - DES_key_schedule schedule, schedule2, schedule3; - DH *dh_params; -/* IDEA_KEY_SCHEDULE idea, idea2; */ - char hmacbuf[SHA_DIGEST_LENGTH]; - unsigned char *rsa_s, *dsa_s; - /* char hmacbuf[SHA_LEN]; */ -#if SSL_VERSION_0_9_8 - SHA256_CTX sha256_ctx; - SHA512_CTX sha512_ctx; -#endif - MD5_CTX md5_ctx; - MD4_CTX md4_ctx; - SHA_CTX sha_ctx; - int new_ivlen = 0; - BN_CTX *bn_ctx; - DSA *dsa; - RSA *rsa; - AES_KEY aes_key; - RC4_KEY rc4_key; - RC2_KEY rc2_key; - - switch(command) { - - case DRV_INFO: - bin = return_binary(rbuf,rlen,NUM_CRYPTO_FUNCS); - if (bin==NULL) return -1; - - for (i = 0; i < NUM_CRYPTO_FUNCS; i++) { - bin[i] = i + 1; - } - return NUM_CRYPTO_FUNCS; - - case DRV_MD5: - bin = return_binary(rbuf,rlen,MD5_LEN); - if (bin==NULL) return -1; - MD5((unsigned char *) buf, len, bin); - return MD5_LEN; - - case DRV_MD5_INIT: - bin = return_binary(rbuf,rlen,MD5_CTX_LEN); - if (bin==NULL) return -1; - MD5_Init((MD5_CTX *)bin); - return MD5_CTX_LEN; - - case DRV_MD5_UPDATE: - if (len < MD5_CTX_LEN) - return -1; - bin = return_binary(rbuf,rlen,MD5_CTX_LEN); - if (bin==NULL) return -1; - memcpy(bin, buf, MD5_CTX_LEN); - MD5_Update((MD5_CTX *)bin, buf + MD5_CTX_LEN, - len - MD5_CTX_LEN); - return MD5_CTX_LEN; - - case DRV_MD5_FINAL: - if (len != MD5_CTX_LEN) - return -1; - memcpy(&md5_ctx, buf, MD5_CTX_LEN); /* XXX Use buf only? */ - bin = return_binary(rbuf,rlen,MD5_LEN); - if (bin==NULL) return -1; - MD5_Final(bin, &md5_ctx); - return MD5_LEN; - - case DRV_SHA: - bin = return_binary(rbuf,rlen,SHA_LEN); - if (bin==NULL) return -1; - SHA1((unsigned char *) buf, len, bin); - return SHA_LEN; - - case DRV_SHA_INIT: - bin = return_binary(rbuf,rlen,SHA_CTX_LEN); - if (bin==NULL) return -1; - SHA1_Init((SHA_CTX*)bin); - return SHA_CTX_LEN; - - case DRV_SHA_UPDATE: - if (len < SHA_CTX_LEN) - return -1; - bin = return_binary(rbuf,rlen,SHA_CTX_LEN); - if (bin==NULL) return -1; - memcpy(bin, buf, SHA_CTX_LEN); - SHA1_Update((SHA_CTX*)bin, buf + SHA_CTX_LEN, len - SHA_CTX_LEN); - return SHA_CTX_LEN; - - case DRV_SHA_FINAL: - if (len != SHA_CTX_LEN) - return -1; - memcpy(&sha_ctx, buf, SHA_CTX_LEN); /* XXX Use buf only? */ - bin = return_binary(rbuf,rlen,SHA_LEN); - if (bin==NULL) return -1; - SHA1_Final(bin, &sha_ctx); - return SHA_LEN; - - case DRV_MD5_MAC: - case DRV_MD5_MAC_96: - /* buf = klen[4] key data */ - klen = get_int32(buf); - key = buf + 4; - dlen = len - klen - 4; - dbuf = key + klen; - hmac_md5(key, klen, dbuf, dlen, hmacbuf); - macsize = (command == DRV_MD5_MAC) ? MD5_LEN : MD5_LEN_96; - bin = return_binary(rbuf,rlen,macsize); - if (bin==NULL) return -1; - memcpy(bin, hmacbuf, macsize); - return macsize; - - case DRV_SHA_MAC: - case DRV_SHA_MAC_96: - /* buf = klen[4] key data */ - klen = get_int32(buf); - key = buf + 4; - dlen = len - klen - 4; - dbuf = key + klen; - hmac_sha1(key, klen, dbuf, dlen, hmacbuf); - macsize = (command == DRV_SHA_MAC) ? SHA_LEN : SHA_LEN_96; - bin = return_binary(rbuf,rlen,macsize); - if (bin==NULL) return -1; - memcpy(bin, (unsigned char *) hmacbuf, macsize); - return macsize; - - case DRV_CBC_DES_ENCRYPT: - case DRV_CBC_DES_DECRYPT: - /* buf = key[8] ivec[8] data */ - dlen = len - 16; - if (dlen < 0) - return -1; - if (dlen % 8 != 0) - return -1; - des_key = (const_DES_cblock*) buf; - des_ivec = (DES_cblock*)(buf + 8); - des_dbuf = (unsigned char *) (buf + 16); - bin = return_binary(rbuf,rlen,dlen); - if (bin==NULL) return -1; - DES_set_key(des_key, &schedule); - DES_ncbc_encrypt(des_dbuf, bin, dlen, &schedule, des_ivec, - (command == DRV_CBC_DES_ENCRYPT)); - return dlen; - - case DRV_BF_ECB_ENCRYPT: - case DRV_BF_ECB_DECRYPT: - { - /* buf = klen[4] key data */ - int bf_direction; - const unsigned char *ukey; - const unsigned char *bf_dbuf; /* blowfish input data */ - BF_KEY bf_key; /* blowfish key 8 */ - - klen = get_int32(buf); - ukey = (unsigned char *) buf + 4; - bf_dbuf = ukey + klen; - dlen = len - 4 - klen; - if (dlen < 0) return -1; - BF_set_key(&bf_key, klen, ukey); - bin = return_binary(rbuf,rlen,dlen); - if (bin==NULL) return -1; - bf_direction = command == DRV_BF_ECB_ENCRYPT ? BF_ENCRYPT : BF_DECRYPT; - BF_ecb_encrypt(bf_dbuf, bin, &bf_key, bf_direction); - return dlen; - } - - case DRV_BF_CBC_ENCRYPT: - case DRV_BF_CBC_DECRYPT: - { - /* buf = klen[4] key ivec[8] data */ - unsigned char *ukey; - unsigned char* ivec; - unsigned char bf_tkey[8]; /* blowfish ivec */ - int bf_direction; - const unsigned char *bf_dbuf; /* blowfish input data */ - BF_KEY bf_key; /* blowfish key 8 */ - - klen = get_int32(buf); - ukey = (unsigned char *)buf + 4; - ivec = ukey + klen; - bf_dbuf = ivec + 8; - dlen = len - 4 - klen - 8; - if (dlen < 0) return -1; - BF_set_key(&bf_key, klen, ukey); - memcpy(bf_tkey, ivec, 8); - bin = return_binary(rbuf,rlen,dlen); - if (bin==NULL) return -1; - bf_direction = command == DRV_BF_CBC_ENCRYPT ? BF_ENCRYPT : BF_DECRYPT; - BF_cbc_encrypt(bf_dbuf, bin, dlen, &bf_key, bf_tkey, bf_direction); - return dlen; - } - - case DRV_BF_OFB64_ENCRYPT: - { - /* buf = klen[4] key ivec[8] data */ - unsigned char *ukey; - unsigned char* ivec; - unsigned char bf_tkey[8]; /* blowfish ivec */ - int bf_n; /* blowfish ivec pos */ - const unsigned char *bf_dbuf; /* blowfish input data */ - BF_KEY bf_key; /* blowfish key 8 */ - - klen = get_int32(buf); - ukey = (unsigned char *)buf + 4; - ivec = ukey + klen; - bf_dbuf = ivec + 8; - dlen = len - 4 - klen - 8; - if (dlen < 0) return -1; - BF_set_key(&bf_key, klen, ukey); - memcpy(bf_tkey, ivec, 8); - bin = return_binary(rbuf,rlen,dlen); - if (bin==NULL) return -1; - bf_n = 0; - BF_ofb64_encrypt(bf_dbuf, bin, dlen, &bf_key, bf_tkey, &bf_n); - return dlen; - } - - case DRV_BF_CFB64_ENCRYPT: - case DRV_BF_CFB64_DECRYPT: - { - /* buf = klen[4] key ivec[8] data */ - unsigned char* ivec; - unsigned char bf_tkey[8]; /* blowfish ivec */ - int bf_n; /* blowfish ivec pos */ - int bf_direction; - const unsigned char *bf_dbuf; /* blowfish input data */ - BF_KEY bf_key; /* blowfish key 8 */ - - klen = get_int32(buf); - key = buf + 4; - ivec = (unsigned char *) (key + klen); - bf_dbuf = ivec + 8; - dlen = len - 4 - klen - 8; - if (dlen < 0) return -1; - BF_set_key(&bf_key, klen, (unsigned char *) key); - memcpy(bf_tkey, ivec, 8); - bin = return_binary(rbuf,rlen,dlen); - if (bin==NULL) return -1; - bf_direction = command == DRV_BF_CFB64_ENCRYPT ? BF_ENCRYPT : BF_DECRYPT; - bf_n = 0; - BF_cfb64_encrypt(bf_dbuf, bin, dlen, &bf_key, bf_tkey, &bf_n, bf_direction); - return dlen; - } - -/* case DRV_CBC_IDEA_ENCRYPT: */ -/* case DRV_CBC_IDEA_DECRYPT: */ - /* buf = key[16] ivec[8] data */ -/* dlen = len - 24; */ -/* if (dlen < 0) */ -/* return -1; */ -/* if (dlen % 8 != 0) */ -/* return -1; */ -/* bin = return_binary(rbuf,rlen,dlen); */ -/* idea_set_encrypt_key(buf, &idea); */ -/* if (command == DRV_CBC_IDEA_DECRYPT) { */ -/* idea_set_decrypt_key(&idea, &idea2); */ -/* memcpy(&idea, &idea2, sizeof(idea)); */ -/* } */ -/* idea_cbc_encrypt(buf + 24, bin, dlen, &idea, buf + 8, */ -/* (command == DRV_CBC_IDEA_ENCRYPT)); */ -/* return dlen; */ - - case DRV_CBC_RC2_40_ENCRYPT: - case DRV_CBC_RC2_40_DECRYPT: - /* buf = key[5] ivec[8] data */ - dlen = len - 13; - if (dlen < 0) - return -1; - bin = return_binary(rbuf,rlen,dlen); - if (bin==NULL) return -1; - RC2_set_key(&rc2_key, 5, (unsigned char *) buf, 40); - RC2_cbc_encrypt((unsigned char *) (buf + 13), bin, dlen, &rc2_key, - (unsigned char *) (buf + 5), - (command == DRV_CBC_RC2_40_ENCRYPT)); - return dlen; - - case DRV_EDE3_CBC_DES_ENCRYPT: - case DRV_EDE3_CBC_DES_DECRYPT: - dlen = len - 32; - if (dlen < 0) - return -1; - des_key = (const_DES_cblock*) buf; - des_key2 = (const_DES_cblock*) (buf + 8); - des_key3 = (const_DES_cblock*) (buf + 16); - des_ivec = (DES_cblock*) (buf + 24); - des_dbuf = (unsigned char *) (buf + 32); - bin = return_binary(rbuf,rlen,dlen); - if (bin==NULL) return -1; - DES_set_key(des_key, &schedule); - DES_set_key(des_key2, &schedule2); - DES_set_key(des_key3, &schedule3); - DES_ede3_cbc_encrypt(des_dbuf, bin, dlen, &schedule, - &schedule2, &schedule3, des_ivec, - (command == DRV_EDE3_CBC_DES_ENCRYPT)); - return dlen; - - case DRV_AES_CFB_128_ENCRYPT: - case DRV_AES_CFB_128_DECRYPT: - /* buf = key[16] ivec[16] data */ - dlen = len - 32; - if (dlen < 0) - return -1; - bin = return_binary(rbuf,rlen,dlen); - if (bin==NULL) return -1; - AES_set_encrypt_key((unsigned char *) buf, 128, &aes_key); - AES_cfb128_encrypt((unsigned char *) (buf+32), bin, dlen, &aes_key, - (unsigned char *) (buf+16), &new_ivlen, - (command == DRV_AES_CFB_128_ENCRYPT)); - return dlen; - - case DRV_RC4_ENCRYPT: - /* buf = klen[4] key data */ - klen = get_int32(buf); - key = buf + 4; - dlen = len - klen - 4; - dbuf = key + klen; - bin = return_binary(rbuf,rlen,dlen); - if (bin==NULL) return -1; - RC4_set_key(&rc4_key, klen, (unsigned char *) key); - RC4(&rc4_key, dlen, (unsigned char *) dbuf, bin); - return dlen; - - case DRV_RC4_SETKEY: - /* buf = key */ - dlen = sizeof(rc4_key); - bin = return_binary(rbuf,rlen,dlen); - if (bin==NULL) return -1; - RC4_set_key(&rc4_key, len, (unsigned char *) buf); - memcpy(bin, &rc4_key, dlen); - return dlen; - - case DRV_RC4_ENCRYPT_WITH_STATE: - /* buf = statelength[4] state data, return statelength[4] state data */ - klen = get_int32(buf); - key = buf + 4; - dlen = len - klen - 4; - dbuf = key + klen; - bin = return_binary(rbuf,rlen,len); - if (bin==NULL) return -1; - memcpy(&rc4_key, key, klen); - RC4(&rc4_key, dlen, (unsigned char *) dbuf, bin + klen + 4); - memcpy(bin, buf, 4); - memcpy(bin + 4, &rc4_key, klen); - return len; - - case DRV_RAND_BYTES: - /* buf = <<rlen:32/integer,topmask:8/integer,bottommask:8/integer>> */ - - if (len != 6) - return -1; - dlen = get_int32(buf); - bin = return_binary(rbuf,rlen,dlen); - if (bin==NULL) return -1; - RAND_pseudo_bytes(bin,dlen); - ERL_VALGRIND_MAKE_MEM_DEFINED(bin, dlen); - or_mask = ((unsigned char*)buf)[4]; - bin[dlen-1] |= or_mask; /* topmask */ - or_mask = ((unsigned char*)buf)[5]; - bin[0] |= or_mask; /* bottommask */ - return dlen; - - case DRV_RAND_UNIFORM: - /* buf = <<from_len:32/integer,bn_from:from_len/binary, * - * to_len:32/integer,bn_to:to_len/binary>> */ - if (len < 8) - return -1; - from_len = get_int32(buf); - if (len < (8 + from_len)) - return -1; - to_len = get_int32(buf + 4 + from_len); - if (len != (8 + from_len + to_len)) - return -1; - ERL_VALGRIND_ASSERT_MEM_DEFINED(buf, 4 + from_len + 4 + to_len); - bn_from = BN_new(); - BN_bin2bn((unsigned char *)(buf + 4), from_len, bn_from); - bn_rand = BN_new(); - BN_bin2bn((unsigned char *)(buf + 8 + from_len), to_len, bn_rand); - bn_to = BN_new(); - BN_sub(bn_to, bn_rand, bn_from); - BN_pseudo_rand_range(bn_rand, bn_to); - BN_add(bn_rand, bn_rand, bn_from); - dlen = BN_num_bytes(bn_rand); - bin = return_binary(rbuf,rlen,dlen + 4); - if (bin==NULL) return -1; - put_int32(bin, dlen); - BN_bn2bin(bn_rand,(unsigned char*)(bin + 4)); - ERL_VALGRIND_MAKE_MEM_DEFINED(bin+4, dlen); - BN_free(bn_rand); - BN_free(bn_from); - BN_free(bn_to); - return dlen + 4; - - case DRV_MOD_EXP: - /* buf = <<base_len:32/integer,base/binary, * - * exponent_len:32/integer,exponent/binary, * - * modulo_len:32/integer, modulo/binary>> */ - if (len < 12) - return -1; - base_len = get_int32(buf); - if (len < (12 + base_len)) - return -1; - exponent_len = get_int32(buf + 4 + base_len); - if (len < (12 + base_len + exponent_len)) - return -1; - modulo_len = get_int32(buf + 8 + base_len + exponent_len); - if (len != (12 + base_len + exponent_len + modulo_len)) - return -1; - bn_base = BN_new(); - BN_bin2bn((unsigned char *)(buf + 4), - base_len, bn_base); - bn_exponent = BN_new(); - BN_bin2bn((unsigned char *)(buf + 8 + base_len), - exponent_len, bn_exponent); - bn_modulo = BN_new(); - BN_bin2bn((unsigned char *)(buf + 12 + base_len + exponent_len), - modulo_len, bn_modulo); - bn_result = BN_new(); - bn_ctx = BN_CTX_new(); - BN_mod_exp(bn_result, bn_base, bn_exponent, - bn_modulo, bn_ctx); - dlen = BN_num_bytes(bn_result); - bin = return_binary(rbuf,rlen,dlen + 4); - if (bin==NULL) return -1; - put_int32(bin, dlen); - BN_bn2bin(bn_result,(unsigned char*)(bin + 4)); - BN_free(bn_result); - BN_free(bn_modulo); - BN_free(bn_exponent); - BN_free(bn_base); - BN_CTX_free(bn_ctx); - return dlen + 4; - - case DRV_DSS_VERIFY: - /* buf = <<data_len:32/integer, data:data_len/binary, - * dsa_s_len:32/integer, dsa_s:dsa_s_len/binary, - * dsa_p_len:32/integer, dsa_p:dsa_p_len/binary, - * dsa_q_len:32/integer, dsa_q:dsa_q_len/binary, - * dsa_g_len:32/integer, dsa_g:dsa_g_len/binary, - * dsa_y_len:32/integer, dsa_y:dsa_y_len/binary>> */ - i = 0; - j = 0; - if (len < 24) - return -1; - data_len = get_int32(buf + i + j); - j += data_len; i += 4; - if (len < (24 + j)) - return -1; - dsa_s_len = get_int32(buf + i + j); - j += dsa_s_len; i += 4; - if (len < (24 + j)) - return -1; - dsa_p_len = get_int32(buf + i + j); - j += dsa_p_len; i += 4; - if (len < (24 + j)) - return -1; - dsa_q_len = get_int32(buf + i + j); - j += dsa_q_len; i += 4; - if (len < (24 + j)) - return -1; - dsa_g_len = get_int32(buf + i + j); - j += dsa_g_len; i += 4; - if (len < (24 + j)) - return -1; - dsa_y_len = get_int32(buf + i + j); - j += dsa_y_len; - if (len != (24 + j)) - return -1; - i = 4; - SHA1((unsigned char *) (buf + i), data_len, (unsigned char *) hmacbuf); - i += data_len + 4; - dsa_s = (unsigned char *)(buf + i); - i += (dsa_s_len + 4); - dsa_p = BN_new(); - BN_bin2bn((unsigned char *)(buf + i), dsa_p_len, dsa_p); - i += (dsa_p_len + 4); - dsa_q = BN_new(); - BN_bin2bn((unsigned char *)(buf + i), dsa_q_len, dsa_q); - i += (dsa_q_len + 4); - dsa_g = BN_new(); - BN_bin2bn((unsigned char *)(buf + i), dsa_g_len, dsa_g); - i += (dsa_g_len + 4); - dsa_y = BN_new(); - BN_bin2bn((unsigned char *)(buf + i), dsa_y_len, dsa_y); - dsa = DSA_new(); - dsa->p = dsa_p; - dsa->q = dsa_q; - dsa->g = dsa_g; - dsa->priv_key = NULL; - dsa->pub_key = dsa_y; - i = DSA_verify(0, (unsigned char *) hmacbuf, SHA_DIGEST_LENGTH, - dsa_s, dsa_s_len, dsa); - bin = return_binary(rbuf,rlen,1); - if (bin==NULL) return -1; - - DSA_free(dsa); - bin[0] = (i > 0) ? 1 : 0; - return 1; - - case DRV_DSS_SIGN: - /* buf = <<data_len:32/integer, data:data_len/binary, - * dsa_p_len:32/integer, dsa_p:dsa_p_len/binary, - * dsa_q_len:32/integer, dsa_q:dsa_q_len/binary, - * dsa_g_len:32/integer, dsa_g:dsa_g_len/binary, - * dsa_y_len:32/integer, dsa_y:dsa_y_len/binary, - * dsa_x_len:32/integer, dsa_s:dsa_x_len/binary>> */ - i = 0; - j = 0; - if (len < 20) - return -1; - data_len = get_int32(buf + i + j); - j += data_len; i += 4; - if (len < (20 + j)) - return -1; - dsa_p_len = get_int32(buf + i + j); - j += dsa_p_len; i += 4; - if (len < (20 + j)) - return -1; - dsa_q_len = get_int32(buf + i + j); - j += dsa_q_len; i += 4; - if (len < (20 + j)) - return -1; - dsa_g_len = get_int32(buf + i + j); - j += dsa_g_len; i += 4; - if (len < (20 + j)) - return -1; - dsa_y_len = get_int32(buf + i + j); - j += dsa_y_len; - if (len < (20 + j)) - return -1; - if (len != (20 + j)) - return -1; - - i = 4; - SHA1((unsigned char *) (buf + i), data_len, (unsigned char *) hmacbuf); - i += data_len + 4; - dsa_p = BN_new(); - BN_bin2bn((unsigned char *)(buf + i), dsa_p_len, dsa_p); - i += (dsa_p_len + 4); - dsa_q = BN_new(); - BN_bin2bn((unsigned char *)(buf + i), dsa_q_len, dsa_q); - i += (dsa_q_len + 4); - dsa_g = BN_new(); - BN_bin2bn((unsigned char *)(buf + i), dsa_g_len, dsa_g); - i += (dsa_g_len + 4); - dsa_y = BN_new(); - BN_bin2bn((unsigned char *)(buf + i), dsa_y_len, dsa_y); - /* i += (dsa_y_len + 4); */ - - dsa = DSA_new(); - dsa->p = dsa_p; - dsa->q = dsa_q; - dsa->g = dsa_g; - dsa->priv_key = dsa_y; - dsa->pub_key = NULL; - dlen = DSA_size(dsa); - bin = return_binary(rbuf,rlen, dlen+1); - if (bin==NULL) return -1; - i = DSA_sign(NID_sha1, - (unsigned char *) hmacbuf,SHA_DIGEST_LENGTH, - (unsigned char *) &bin[1], - (unsigned int *) &dsa_s_len, dsa); - DSA_free(dsa); - if (i) { - if (dsa_s_len != dlen) { - bin = return_binary_shrink(rbuf,rlen,bin,dsa_s_len+1); - } - bin[0] = 1; - return dsa_s_len + 1; - } - else { - bin[0] = 0; - return 1; - } - - case DRV_RSA_VERIFY_MD5: - case DRV_RSA_VERIFY_SHA: - /* buf = <<data_len:32/integer, data:data_len/binary, - * rsa_s_len:32/integer, rsa_s:rsa_s_len/binary, - * rsa_e_len:32/integer, rsa_e:rsa_e_len/binary, - * rsa_n_len:32/integer, rsa_n:rsa_n_len/binary>> */ - i = 0; - j = 0; - if (len < 16) - return -1; - data_len = get_int32(buf + i + j); - j += data_len; i += 4; - if (len < (16 + j)) - return -1; - rsa_s_len = get_int32(buf + i + j); - j += rsa_s_len; i += 4; - if (len < (16 + j)) - return -1; - rsa_e_len = get_int32(buf + i + j); - j += rsa_e_len; i += 4; - if (len < (16 + j)) - return -1; - rsa_n_len = get_int32(buf + i + j); - j += rsa_n_len; i += 4; - if (len != (16 + j)) - return -1; - i = 4; - i += (data_len + 4); - rsa_s = (unsigned char *)(buf + i); - i += (rsa_s_len + 4); - rsa_e = BN_new(); - BN_bin2bn((unsigned char *)(buf + i), rsa_e_len, rsa_e); - i += (rsa_e_len + 4); - rsa_n = BN_new(); - BN_bin2bn((unsigned char *)(buf + i), rsa_n_len, rsa_n); - rsa = RSA_new(); - rsa->n = rsa_n; - rsa->e = rsa_e; - i = 4; - if(command == DRV_RSA_VERIFY_SHA) { - SHA1((unsigned char *) (buf + i), data_len, - (unsigned char *) hmacbuf); - i = RSA_verify(NID_sha1, (unsigned char *) hmacbuf, SHA_DIGEST_LENGTH, - rsa_s, rsa_s_len, rsa); - } else { - MD5((unsigned char *) (buf + i), data_len, (unsigned char *) hmacbuf); - i = RSA_verify(NID_md5, (unsigned char *) hmacbuf, MD5_DIGEST_LENGTH, - rsa_s, rsa_s_len, rsa); - } - - bin = return_binary(rbuf,rlen,1); - if (bin==NULL) return -1; - bin[0] = (char)(i & 0xff); - RSA_free(rsa); - return 1; - - case DRV_RSA_SIGN_MD5: - case DRV_RSA_SIGN_SHA: - /* buf = <<data_len:32/integer, data:data_len/binary, - * rsa_e_len:32/integer, rsa_e:rsa_e_len/binary, - * rsa_n_len:32/integer, rsa_n:rsa_n_len/binary, - * rsa_d_len:32/integer, rsa_d:rsa_d_len/binary>> */ - - ERL_VALGRIND_ASSERT_MEM_DEFINED(buf,len); - - i = 0; - j = 0; - - if (len < 16) - return -1; - data_len = get_int32(buf + i + j); - j += data_len; i += 4; - if (len < (16 + j)) - return -1; - rsa_e_len = get_int32(buf + i + j); - j += rsa_e_len; i += 4; - if (len < (16 + j)) - return -1; - rsa_n_len = get_int32(buf + i + j); - j += rsa_n_len; i += 4; - if (len < (16 + j)) - return -1; - rsa_d_len = get_int32(buf + i + j); - j += rsa_d_len; i += 4; - if (len != (16 + j)) - return -1; - - i = 4; - i += (data_len + 4); - rsa_e = BN_new(); - BN_bin2bn((unsigned char *)(buf + i), rsa_e_len, rsa_e); - i += (rsa_e_len + 4); - rsa_n = BN_new(); - BN_bin2bn((unsigned char *)(buf + i), rsa_n_len, rsa_n); - i += (rsa_n_len + 4); - rsa_d = BN_new(); - BN_bin2bn((unsigned char *)(buf + i), rsa_d_len, rsa_d); - i += (rsa_d_len + 4); - - rsa = RSA_new(); - rsa->e = rsa_e; - rsa->n = rsa_n; - rsa->d = rsa_d; - - dlen = RSA_size(rsa); - bin = return_binary(rbuf,rlen,dlen+1); - if (bin==NULL) return -1; - i = 4; - if (command == DRV_RSA_SIGN_MD5) { - MD5((unsigned char *) (buf + i), data_len, (unsigned char *) hmacbuf); - ERL_VALGRIND_ASSERT_MEM_DEFINED(hmacbuf, MD5_DIGEST_LENGTH); - i = RSA_sign(NID_md5, - (unsigned char *) hmacbuf,MD5_DIGEST_LENGTH, - (unsigned char *) &bin[1], - &rsa_s_len, rsa); - } else { - SHA1((unsigned char *) (buf + i), data_len, - (unsigned char *) hmacbuf); - ERL_VALGRIND_ASSERT_MEM_DEFINED(hmacbuf, SHA_DIGEST_LENGTH); - i = RSA_sign(NID_sha1, - (unsigned char *) hmacbuf,SHA_DIGEST_LENGTH, - (unsigned char *) &bin[1], - &rsa_s_len, rsa); - } - RSA_free(rsa); - if (i) { - ERL_VALGRIND_MAKE_MEM_DEFINED(bin+1, rsa_s_len); - if (rsa_s_len != dlen) { - bin = return_binary_shrink(rbuf,rlen,bin,rsa_s_len+1); - ERL_VALGRIND_ASSERT_MEM_DEFINED(bin+1, rsa_s_len); - } - bin[0] = 1; - return rsa_s_len + 1; - } - else { - bin[0] = 0; - return 1; - } - - case DRV_RSA_PRIVATE_DECRYPT: - case DRV_RSA_PRIVATE_ENCRYPT: - /* buf = <<data_len:32/integer, data:data_len/binary, - * rsa_e_len:32/integer, rsa_e:rsa_e_len/binary, - * rsa_n_len:32/integer, rsa_n:rsa_n_len/binary, - * rsa_d_len:32/integer, rsa_d:rsa_d_len/binary, - * pad:8/integer >> */ - - ERL_VALGRIND_ASSERT_MEM_DEFINED(buf,len); - i = 0; - j = 0; - - if (len < 17) - return -1; - data_len = get_int32(buf + i + j); - j += data_len; i += 4; - if (len < (17 + j)) - return -1; - rsa_e_len = get_int32(buf + i + j); - j += rsa_e_len; i += 4; - if (len < (17 + j)) - return -1; - rsa_n_len = get_int32(buf + i + j); - j += rsa_n_len; i += 4; - if (len < (17 + j)) - return -1; - rsa_d_len = get_int32(buf + i + j); - j += rsa_d_len; i += 4; - padding = *(unsigned char *) (buf+i+j); - if (len != (17 + j)) - return -1; - - i = 4; - i += (data_len + 4); - rsa_e = BN_new(); - ERL_VALGRIND_ASSERT_MEM_DEFINED(buf+i,rsa_e_len); - BN_bin2bn((unsigned char *)(buf + i), rsa_e_len, rsa_e); - i += (rsa_e_len + 4); - rsa_n = BN_new(); - ERL_VALGRIND_ASSERT_MEM_DEFINED(buf+i,rsa_n_len); - BN_bin2bn((unsigned char *)(buf + i), rsa_n_len, rsa_n); - i += (rsa_n_len + 4); - rsa_d = BN_new(); - ERL_VALGRIND_ASSERT_MEM_DEFINED(buf+i,rsa_d_len); - BN_bin2bn((unsigned char *)(buf + i), rsa_d_len, rsa_d); - i += (rsa_d_len + 4); - - switch(padding) { - case 0: - padding = RSA_NO_PADDING; - break; - case 1: - padding = RSA_PKCS1_PADDING; - break; - case 2: - padding = RSA_PKCS1_OAEP_PADDING; - break; - case 3: - padding = RSA_SSLV23_PADDING; - break; - default: - return -1; - } - - rsa = RSA_new(); - rsa->e = rsa_e; - rsa->n = rsa_n; - rsa->d = rsa_d; - - dlen = RSA_size(rsa) + 1; - bin = return_binary(rbuf,rlen,dlen); - if (bin==NULL) return -1; - i = 4; - ERL_VALGRIND_ASSERT_MEM_DEFINED(buf+i,data_len); - if(command == DRV_RSA_PRIVATE_DECRYPT) { - i = RSA_private_decrypt(data_len, (unsigned char *) (buf+i), - (unsigned char *) &bin[1], - rsa, padding); - if(i > 0) { - ERL_VALGRIND_MAKE_MEM_DEFINED(&bin[1],i); - bin = return_binary_shrink(rbuf,rlen, bin, i+1); - if (bin==NULL) return -1; - } - } else { - i = RSA_private_encrypt(data_len, (unsigned char *) (buf+i), - (unsigned char *) &bin[1], - rsa, padding); - if(i > 0) { - ERL_VALGRIND_MAKE_MEM_DEFINED(&bin[1],i); - } - } - RSA_free(rsa); - if(i > 0) { - bin[0] = 1; - return i + 1; - } else { - bin[0] = 0; - return 1; - } - break; - - case DRV_RSA_PUBLIC_ENCRYPT: - case DRV_RSA_PUBLIC_DECRYPT: - /* buf = <<data_len:32/integer, data:data_len/binary, - * rsa_e_len:32/integer, rsa_e:rsa_e_len/binary, - * rsa_n_len:32/integer, rsa_n:rsa_n_len/binary, - * pad:8/integer >> */ - - ERL_VALGRIND_ASSERT_MEM_DEFINED(buf,len); - i = 0; - j = 0; - - if (len < 13) - return -1; - data_len = get_int32(buf + i + j); - j += data_len; i += 4; - if (len < (13 + j)) - return -1; - rsa_e_len = get_int32(buf + i + j); - j += rsa_e_len; i += 4; - if (len < (13 + j)) - return -1; - rsa_n_len = get_int32(buf + i + j); - j += rsa_n_len; i += 4; - if (len < (13 + j)) - return -1; - padding = *(unsigned char *) (buf + i + j); - if (len != (13 + j)) - return -1; - - i = 4; - i += (data_len + 4); - rsa_e = BN_new(); - ERL_VALGRIND_ASSERT_MEM_DEFINED(buf+i,rsa_e_len); - BN_bin2bn((unsigned char *)(buf + i), rsa_e_len, rsa_e); - i += (rsa_e_len + 4); - rsa_n = BN_new(); - ERL_VALGRIND_ASSERT_MEM_DEFINED(buf+i,rsa_n_len); - BN_bin2bn((unsigned char *)(buf + i), rsa_n_len, rsa_n); - i += (rsa_n_len + 4); - - switch(padding) { - case 0: - padding = RSA_NO_PADDING; - break; - case 1: - padding = RSA_PKCS1_PADDING; - break; - case 2: - padding = RSA_PKCS1_OAEP_PADDING; - break; - case 3: - padding = RSA_SSLV23_PADDING; - break; - default: - return -1; - } - - rsa = RSA_new(); - rsa->e = rsa_e; - rsa->n = rsa_n; - - dlen = RSA_size(rsa) + 1; - bin = return_binary(rbuf,rlen,dlen); - if (bin==NULL) return -1; - i = 4; - if(command == DRV_RSA_PUBLIC_ENCRYPT) { - ERL_VALGRIND_ASSERT_MEM_DEFINED(buf+i,data_len); - i = RSA_public_encrypt(data_len, (unsigned char *) (buf+i), - (unsigned char *) &bin[1], - rsa, padding); - if (i > 0) { - ERL_VALGRIND_MAKE_MEM_DEFINED(bin+1, i); - } - } else { - i = RSA_public_decrypt(data_len, (unsigned char *) (buf+i), - (unsigned char *) &bin[1], - rsa, padding); - if(i > 0) { - ERL_VALGRIND_MAKE_MEM_DEFINED(bin+1, i); - bin = return_binary_shrink(rbuf,rlen,bin, i+1); - if (bin==NULL) return -1; - } - } - - RSA_free(rsa); - if(i > 0) { - bin[0] = 1; - return i + 1; - } else { -/* ERR_load_crypto_strings(); */ -/* fprintf(stderr, "%d: %s \r\n", __LINE__, ERR_reason_error_string(ERR_get_error())); */ - bin[0] = 0; - return 1; - } - break; - - case DRV_CBC_AES128_ENCRYPT: - case DRV_CBC_AES256_ENCRYPT: - case DRV_CBC_AES128_DECRYPT: - case DRV_CBC_AES256_DECRYPT: - /* buf = key[klen] ivec[klen] data */ - if (command == DRV_CBC_AES256_ENCRYPT || command == DRV_CBC_AES256_DECRYPT) - klen = 32; - else - klen = 16; - dlen = len - klen - 16; - if (dlen < 0) - return -1; - if (dlen % 16 != 0) - return -1; - if (command == DRV_CBC_AES128_ENCRYPT || command == DRV_CBC_AES256_ENCRYPT) { - i = AES_ENCRYPT; - AES_set_encrypt_key((unsigned char *) buf, klen*8, &aes_key); - } else { - i = AES_DECRYPT; - AES_set_decrypt_key((unsigned char *) buf, klen*8, &aes_key); - } - bin = return_binary(rbuf,rlen,dlen); - if (bin==NULL) return -1; - AES_cbc_encrypt((unsigned char *) (buf + klen+16), - (unsigned char *) bin, - dlen, - &aes_key, - (unsigned char *) (buf + klen), - i); - return dlen; - -/* case DRV_CBC_AES128_DECRYPT: */ -/* case DRV_CBC_AES256_DECRYPT: */ -/* /\* buf = key[klen] ivec[16] data *\/ */ -/* if (command == DRV_CBC_AES256_DECRYPT) */ -/* klen = 32; */ -/* else */ -/* klen = 16; */ -/* dlen = len - klen - 16; */ -/* if (dlen < 0) */ -/* return -1; */ -/* *rbuf = (char *)(bin = driver_alloc_binary(dlen)); */ -/* AES_set_decrypt_key((unsigned char *) buf, klen*8, &aes_key); */ -/* AES_cbc_encrypt((unsigned char *) (buf + klen+16), */ -/* (unsigned char *) bin->orig_bytes, */ -/* dlen, */ -/* &aes_key, */ -/* (unsigned char *) (buf + klen), */ -/* AES_DECRYPT); */ -/* return dlen; */ -/* break; */ - - case DRV_XOR: - /* buf = data1, data2 with same size */ - dlen = len / 2; - if (len != dlen * 2) - return -1; - bin = return_binary(rbuf,rlen,dlen); - if (bin==NULL) return -1; - p = bin, - dbuf = buf + dlen; - for (key = buf, key2 = dbuf; key != dbuf; ++key, ++key2, ++p) - *p = *key ^ *key2; - return dlen; - - case DRV_DH_GENERATE_PARAMS: - /* buf = <<PrimeLen:32 Generator:32>> */ - if (len != 8) - return -1; - ERL_VALGRIND_ASSERT_MEM_DEFINED(buf,len); - prime_len = get_int32(buf); - generator = get_int32(buf+4); - dh_params = DH_generate_parameters(prime_len, generator, NULL, NULL); - - if(dh_params) { - dh_p_len = BN_num_bytes(dh_params->p); - dh_g_len = BN_num_bytes(dh_params->g); - dlen = 1 + 4 + 4 + dh_g_len + dh_p_len; - bin = return_binary(rbuf,rlen,dlen); - if (bin==NULL) return -1; - bin[0] = 1; - put_int32(bin+1, dh_p_len); - BN_bn2bin(dh_params->p, bin+5); - ERL_VALGRIND_MAKE_MEM_DEFINED(bin+5,dh_p_len); - put_int32(bin+5+dh_p_len, dh_g_len); - BN_bn2bin(dh_params->g, bin+5+dh_p_len+4); - ERL_VALGRIND_MAKE_MEM_DEFINED(bin+5+dh_p_len+4,dh_g_len); - } else { - dlen = 1; - bin = return_binary(rbuf,rlen,dlen); - if (bin==NULL) return -1; - bin[0] = 0; - } - DH_free(dh_params); - return dlen; - - case DRV_DH_CHECK: - /* buf = <<dh_p_len:32/integer, dh_p:dh_p_len/binary, - * dh_g_len:32/integer, dh_g:dh_g_len/binary>> */ - i = 0; - j = 0; - if(len < 8) return -1; - dh_p_len = get_int32(buf + i + j); - j += dh_p_len; i += 4; - if (len < (8 + j)) return -1; - dh_g_len = get_int32(buf + i + j); - j += dh_g_len; i += 4; - if(len != (8+j)) return -1; - i=4; - dh_p = BN_new(); - BN_bin2bn((unsigned char *)(buf + i), dh_p_len, dh_p); - i += (dh_p_len + 4); - dh_g = BN_new(); - BN_bin2bn((unsigned char *)(buf + i), dh_g_len, dh_g); - /* i += (dsa_g_len + 4); */ - - dh_params = DH_new(); - dh_params->p = dh_p; - dh_params->g = dh_g; - - i=0; - bin = return_binary(rbuf,rlen,4); - if (bin==NULL) return -1; - if(DH_check(dh_params, &i)) { - put_int32(bin, i); - } else { - /* Check Failed */ - put_int32(bin, -1); - } - DH_free(dh_params); - return 4; - - case DRV_DH_GENERATE_KEY: - /* buf = <<key_len:32, key:key_len/binary, * - * dh_p_len:32/integer, dh_p:dh_p_len/binary, * - * dh_g_len:32/integer, dh_g:dh_g_len/binary>> */ - ERL_VALGRIND_ASSERT_MEM_DEFINED(buf,len); - i = 0; - j = 0; - if(len < 12) return -1; - base_len = get_int32(buf + i + j); - j += base_len; i += 4; - if (len < (12 + j)) return -1; - dh_p_len = get_int32(buf + i + j); - j += dh_p_len; i += 4; - if (len < (12 + j)) return -1; - dh_g_len = get_int32(buf + i + j); - j += dh_g_len; i += 4; - if(len != (12 + j)) return -1; - i=4; - i += (base_len + 4); - dh_p = BN_new(); - BN_bin2bn((unsigned char *)(buf + i), dh_p_len, dh_p); - i += (dh_p_len + 4); - dh_g = BN_new(); - BN_bin2bn((unsigned char *)(buf + i), dh_g_len, dh_g); - /* i += (dsa_g_len + 4); */ - - dh_params = DH_new(); - dh_params->p = dh_p; - dh_params->g = dh_g; - if(base_len > 0) { - dh_params->priv_key = BN_new(); - BN_bin2bn((unsigned char *)(buf + i), base_len, - dh_params->priv_key); - } - i=0; - if(DH_generate_key(dh_params)) { - privkey_len = BN_num_bytes(dh_params->priv_key); - pubkey_len = BN_num_bytes(dh_params->pub_key); - dlen = 1 + 4 + 4 + pubkey_len + privkey_len; - bin = return_binary(rbuf,rlen, dlen); - if (bin==NULL) return -1; - bin[0] = 1; - put_int32(bin+1, pubkey_len); - BN_bn2bin(dh_params->pub_key, bin+5); - ERL_VALGRIND_MAKE_MEM_DEFINED(bin+5, pubkey_len); - put_int32(bin+5+pubkey_len, privkey_len); - BN_bn2bin(dh_params->priv_key, bin+5+pubkey_len+4); - ERL_VALGRIND_MAKE_MEM_DEFINED(bin+5+pubkey_len+4, privkey_len); - } else { - dlen = 1; - bin = return_binary(rbuf,rlen,dlen); - if (bin==NULL) return -1; - bin[0] = 0; - } - DH_free(dh_params); - return dlen; - - case DRV_DH_COMPUTE_KEY: - /* buf = <<pubkey_len:32, pubkey:pubkey_len/binary, * - * privkey_len:32, privkey:privkey_len/binary, * - * dh_p_len:32/integer, dh_p:dh_p_len/binary, * - * dh_g_len:32/integer, dh_g:dh_g_len/binary>> */ - i = 0; - j = 0; - if(len < 16) return -1; - pubkey_len = get_int32(buf + i + j); - j += pubkey_len; i += 4; - if (len < (16 + j)) return -1; - privkey_len = get_int32(buf + i + j); - j += privkey_len; i += 4; - if (len < (16 + j)) return -1; - dh_p_len = get_int32(buf + i + j); - j += dh_p_len; i += 4; - if (len < (16 + j)) return -1; - dh_g_len = get_int32(buf + i + j); - j += dh_g_len; i += 4; - if(len != (16 + j)) return -1; - i=4; - pubkey = BN_new(); - BN_bin2bn((unsigned char *)(buf + i), pubkey_len, pubkey); - i += (pubkey_len + 4); - privkey = BN_new(); - BN_bin2bn((unsigned char *)(buf + i), privkey_len, privkey); - i += (privkey_len + 4); - dh_p = BN_new(); - BN_bin2bn((unsigned char *)(buf + i), dh_p_len, dh_p); - i += (dh_p_len + 4); - dh_g = BN_new(); - BN_bin2bn((unsigned char *)(buf + i), dh_g_len, dh_g); - /* i += (dsa_g_len + 4); */ - - dh_params = DH_new(); - dh_params->p = dh_p; - dh_params->g = dh_g; - dh_params->priv_key = privkey; - - klen = DH_size(dh_params); - bin = return_binary(rbuf,rlen,1+klen); - if (bin==NULL) return -1; - i = DH_compute_key(&bin[1], pubkey, dh_params); - DH_free(dh_params); - if (i > 0) { - if (i != klen) { - bin = return_binary_shrink(rbuf,rlen,bin,1+i); - } - bin[0] = 1; - return i + 1; - } - else { - bin[0] = 0; - return 1; - } - - case DRV_MD4: - bin = return_binary(rbuf,rlen,MD4_LEN); - MD4((unsigned char *)buf, len, (unsigned char *)bin); - return MD4_LEN; - - case DRV_MD4_INIT: - bin = return_binary(rbuf,rlen,MD4_CTX_LEN); - MD4_Init((MD4_CTX *) bin); - return MD4_CTX_LEN; - - case DRV_MD4_UPDATE: - if (len < MD4_CTX_LEN) - return -1; - bin = return_binary(rbuf,rlen,MD4_CTX_LEN); - memcpy(bin, buf, MD4_CTX_LEN); - MD4_Update((MD4_CTX *) bin, buf + MD4_CTX_LEN, len - MD4_CTX_LEN); - return MD4_CTX_LEN; - - case DRV_MD4_FINAL: - if (len != MD4_CTX_LEN) - return -1; - memcpy(&md4_ctx, buf, MD4_CTX_LEN); /* XXX Use buf only? */ - bin = return_binary(rbuf,rlen,MD4_LEN); - MD4_Final((unsigned char *)bin, &md4_ctx); - return MD4_LEN; - -#if SSL_VERSION_0_9_8 - case DRV_SHA256: - bin = return_binary(rbuf,rlen,SHA256_LEN); - SHA256(buf, len, bin); - return SHA256_LEN; - - case DRV_SHA256_INIT: - bin = return_binary(rbuf,rlen,SHA256_CTX_LEN); - SHA256_Init((SHA256_CTX *)bin); - return SHA256_CTX_LEN; - - case DRV_SHA256_UPDATE: - if (len < SHA256_CTX_LEN) - return -1; - bin = return_binary(rbuf,rlen,SHA256_CTX_LEN); - memcpy(bin, buf, SHA256_CTX_LEN); - SHA256_Update((SHA256_CTX *)bin, buf + SHA256_CTX_LEN, - len - SHA256_CTX_LEN); - return SHA256_CTX_LEN; - - case DRV_SHA256_FINAL: - if (len != SHA256_CTX_LEN) - return -1; - memcpy(&sha256_ctx, buf, SHA256_CTX_LEN); /* XXX Use buf only? */ - bin = return_binary(rbuf,rlen,SHA256_LEN); - SHA256_Final(bin, &sha256_ctx); - return SHA256_LEN; - - case DRV_SHA512: - bin = return_binary(rbuf,rlen,SHA512_LEN); - SHA512(buf, len, bin); - return SHA512_LEN; - - case DRV_SHA512_INIT: - bin = return_binary(rbuf,rlen,SHA512_CTX_LEN); - SHA512_Init((SHA512_CTX *)bin); - return SHA512_CTX_LEN; - - case DRV_SHA512_UPDATE: - if (len < SHA512_CTX_LEN) - return -1; - bin = return_binary(rbuf,rlen,SHA512_CTX_LEN); - memcpy(bin, buf, SHA512_CTX_LEN); - SHA512_Update((SHA512_CTX *)bin, buf + SHA512_CTX_LEN, - len - SHA512_CTX_LEN); - return SHA512_CTX_LEN; - - case DRV_SHA512_FINAL: - if (len != SHA512_CTX_LEN) - return -1; - memcpy(&sha512_ctx, buf, SHA512_CTX_LEN); /* XXX Use buf only? */ - bin = return_binary(rbuf,rlen,SHA512_LEN)); - SHA512_Final(bin, &sha512_ctx); - return SHA512_LEN; -#endif - - case DRV_INFO_LIB: - {/* <<DrvVer:8, NameSize:8, Name:NameSize/binary, VerNum:32, VerStr/binary>> */ - static const char libname[] = "OpenSSL"; - unsigned name_sz = strlen(libname); - const char* ver = SSLeay_version(SSLEAY_VERSION); - unsigned ver_sz = strlen(ver); - dlen = 1+1+name_sz+4+ver_sz; - bin = return_binary(rbuf, rlen, dlen); - if (bin==NULL) return -1; - p = bin; - *p++ = 0; /* "driver version" for future use */ - *p++ = name_sz; - memcpy(p, libname, name_sz); - p += name_sz; - put_int32(p,SSLeay()); /* OPENSSL_VERSION_NUMBER */ - p += 4; - memcpy(p, ver, ver_sz); - } - return dlen; - - default: - break; - } - return -1; -} - - -#ifdef OPENSSL_THREADS /* vvvvvvvvvvvvvvv OPENSSL_THREADS vvvvvvvvvvvvvvvv */ - -static INLINE void locking(int mode, ErlDrvRWLock* lock) -{ - switch(mode) { - case CRYPTO_LOCK|CRYPTO_READ: - erl_drv_rwlock_rlock(lock); - break; - case CRYPTO_LOCK|CRYPTO_WRITE: - erl_drv_rwlock_rwlock(lock); - break; - case CRYPTO_UNLOCK|CRYPTO_READ: - erl_drv_rwlock_runlock(lock); - break; - case CRYPTO_UNLOCK|CRYPTO_WRITE: - erl_drv_rwlock_rwunlock(lock); - break; - default: - ASSERT(!"Invalid lock mode"); - } -} - -/* Callback from openssl for static locking - */ -static void locking_function(int mode, int n, const char *file, int line) -{ - ASSERT(n>=0 && n<CRYPTO_num_locks()); - - locking(mode, lock_vec[n]); -} - -/* Callback from openssl for thread id - */ -static unsigned long id_function(void) -{ - return (unsigned long) erl_drv_thread_self(); -} - -/* Callbacks for dynamic locking, not used by current openssl version (0.9.8) - */ -static struct CRYPTO_dynlock_value* dyn_create_function(const char *file, int line) -{ - return (struct CRYPTO_dynlock_value*) erl_drv_rwlock_create("crypto_drv_dyn"); -} -static void dyn_lock_function(int mode, struct CRYPTO_dynlock_value* ptr,const char *file, int line) -{ - locking(mode, (ErlDrvRWLock*)ptr); -} -static void dyn_destroy_function(struct CRYPTO_dynlock_value *ptr, const char *file, int line) -{ - erl_drv_rwlock_destroy((ErlDrvRWLock*)ptr); -} - -#endif /* ^^^^^^^^^^^^^^^^^^^^^^ OPENSSL_THREADS ^^^^^^^^^^^^^^^^^^^^^^ */ - -/* HMAC */ - -static void hmac_md5(char *key, int klen, char *dbuf, int dlen, char *hmacbuf) -{ - MD5_CTX ctx; - char ipad[HMAC_INT_LEN]; - char opad[HMAC_INT_LEN]; - unsigned char nkey[MD5_LEN]; - int i; - - /* Change key if longer than 64 bytes */ - if (klen > HMAC_INT_LEN) { - MD5_CTX kctx; - - MD5_Init(&kctx); - MD5_Update(&kctx, key, klen); - MD5_Final(nkey, &kctx); - key = (char *) nkey; - klen = MD5_LEN; - } - - memset(ipad, '\0', sizeof(ipad)); - memset(opad, '\0', sizeof(opad)); - memcpy(ipad, key, klen); - memcpy(opad, key, klen); - - for (i = 0; i < HMAC_INT_LEN; i++) { - ipad[i] ^= HMAC_IPAD; - opad[i] ^= HMAC_OPAD; - } - - /* inner MD5 */ - MD5_Init(&ctx); - MD5_Update(&ctx, ipad, HMAC_INT_LEN); - MD5_Update(&ctx, dbuf, dlen); - MD5_Final((unsigned char *) hmacbuf, &ctx); - /* outer MD5 */ - MD5_Init(&ctx); - MD5_Update(&ctx, opad, HMAC_INT_LEN); - MD5_Update(&ctx, hmacbuf, MD5_LEN); - MD5_Final((unsigned char *) hmacbuf, &ctx); -} - -static void hmac_sha1(char *key, int klen, char *dbuf, int dlen, - char *hmacbuf) -{ - SHA_CTX ctx; - char ipad[HMAC_INT_LEN]; - char opad[HMAC_INT_LEN]; - unsigned char nkey[SHA_LEN]; - int i; - - /* Change key if longer than 64 bytes */ - if (klen > HMAC_INT_LEN) { - SHA_CTX kctx; - - SHA1_Init(&kctx); - SHA1_Update(&kctx, key, klen); - SHA1_Final(nkey, &kctx); - key = (char *) nkey; - klen = SHA_LEN; - } - - memset(ipad, '\0', sizeof(ipad)); - memset(opad, '\0', sizeof(opad)); - memcpy(ipad, key, klen); - memcpy(opad, key, klen); - - for (i = 0; i < HMAC_INT_LEN; i++) { - ipad[i] ^= HMAC_IPAD; - opad[i] ^= HMAC_OPAD; - } - - /* inner SHA */ - SHA1_Init(&ctx); - SHA1_Update(&ctx, ipad, HMAC_INT_LEN); - SHA1_Update(&ctx, dbuf, dlen); - SHA1_Final((unsigned char *) hmacbuf, &ctx); - /* outer SHA */ - SHA1_Init(&ctx); - SHA1_Update(&ctx, opad, HMAC_INT_LEN); - SHA1_Update(&ctx, hmacbuf, SHA_LEN); - SHA1_Final((unsigned char *) hmacbuf, &ctx); -} diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml index cfc6996332..e1431cfd81 100644 --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1999</year><year>2009</year> + <year>1999</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>crypto</title> @@ -35,6 +35,9 @@ <p>References:</p> <list type="bulleted"> <item> + <p>md4: The MD4 Message Digest Algorithm (RFC 1320)</p> + </item> + <item> <p>md5: The MD5 Message Digest Algorithm (RFC 1321)</p> </item> <item> @@ -115,6 +118,52 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]> </desc> </func> <func> + <name>md4(Data) -> Digest</name> + <fsummary>Compute an <c>MD4</c>message digest from <c>Data</c></fsummary> + <type> + <v>Data = iolist() | binary()</v> + <v>Digest = binary()</v> + </type> + <desc> + <p>Computes an <c>MD4</c> message digest from <c>Data</c>, where + the length of the digest is 128 bits (16 bytes).</p> + </desc> + </func> + <func> + <name>md4_init() -> Context</name> + <fsummary>Creates an MD4 context</fsummary> + <type> + <v>Context = binary()</v> + </type> + <desc> + <p>Creates an MD4 context, to be used in subsequent calls to + <c>md4_update/2</c>.</p> + </desc> + </func> + <func> + <name>md4_update(Context, Data) -> NewContext</name> + <fsummary>Update an MD4 <c>Context</c>with <c>Data</c>, and return a <c>NewContext</c></fsummary> + <type> + <v>Data = iolist() | binary()</v> + <v>Context = NewContext = binary()</v> + </type> + <desc> + <p>Updates an MD4 <c>Context</c> with <c>Data</c>, and returns + a <c>NewContext</c>.</p> + </desc> + </func> + <func> + <name>md4_final(Context) -> Digest</name> + <fsummary>Finish the update of an MD4 <c>Context</c>and return the computed <c>MD4</c>message digest</fsummary> + <type> + <v>Context = Digest = binary()</v> + </type> + <desc> + <p>Finishes the update of an MD4 <c>Context</c> and returns + the computed <c>MD4</c> message digest.</p> + </desc> + </func> + <func> <name>md5(Data) -> Digest</name> <fsummary>Compute an <c>MD5</c>message digest from <c>Data</c></fsummary> <type> @@ -339,6 +388,33 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]> </func> <func> + <name>des_ecb_encrypt(Key, Text) -> Cipher</name> + <fsummary>Encrypt <c>Text</c>according to DES in ECB mode</fsummary> + <type> + <v>Key = Text = iolist() | binary()</v> + <v>Cipher = binary()</v> + </type> + <desc> + <p>Encrypts <c>Text</c> according to DES in ECB mode. + <c>Key</c> is the DES key. The lengths of <c>Key</c> and + <c>Text</c> must be 64 bits (8 bytes).</p> + </desc> + </func> + <func> + <name>des_ecb_decrypt(Key, Cipher) -> Text</name> + <fsummary>Decrypt <c>Cipher</c>according to DES in ECB mode</fsummary> + <type> + <v>Key = Cipher = iolist() | binary()</v> + <v>Text = binary()</v> + </type> + <desc> + <p>Decrypts <c>Cipher</c> according to DES in ECB mode. + <c>Key</c> is the DES key. The lengths of <c>Key</c> and + <c>Cipher</c> must be 64 bits (8 bytes).</p> + </desc> + </func> + + <func> <name>blowfish_ecb_encrypt(Key, Text) -> Cipher</name> <fsummary>Encrypt the first 64 bits of <c>Text</c> using Blowfish in ECB mode</fsummary> <type> @@ -679,39 +755,44 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]> <func> <name>dss_sign(Data, Key) -> Signature</name> + <name>dss_sign(DigestType, Data, Key) -> Signature</name> <fsummary>Sign the data using dsa with given private key.</fsummary> <type> - <v>Digest = Mpint</v> + <v>DigestType = sha | none (default is sha)</v> + <v>Data = Mpint | ShaDigest</v> <v>Key = [P, Q, G, X]</v> <v>P, Q, G, X = Mpint</v> <d> Where <c>P</c>, <c>Q</c> and <c>G</c> are the dss parameters and <c>X</c> is the private key.</d> - <v>Mpint = binary()</v> + <v>ShaDigest = binary() with length 20 bytes</v> <v>Signature = binary()</v> </type> <desc> - <p>Calculates the sha digest of the <c>Data</c> - and creates a DSS signature with the private key <c>Key</c> - of the digest.</p> + <p>Creates a DSS signature with the private key <c>Key</c> of a digest. + If <c>DigestType</c> is 'sha', the digest is calculated as SHA1 of <c>Data</c>. + If <c>DigestType</c> is 'none', <c>Data</c> is the precalculated SHA1 digest.</p> </desc> </func> <func> <name>dss_verify(Data, Signature, Key) -> Verified</name> + <name>dss_verify(DigestType, Data, Signature, Key) -> Verified</name> <fsummary>Verify the data and signature using dsa with given public key.</fsummary> <type> <v>Verified = boolean()</v> - <v>Digest, Signature = Mpint</v> + <v>DigestType = sha | none</v> + <v>Data = Mpint | ShaDigest</v> + <v>Signature = Mpint</v> <v>Key = [P, Q, G, Y]</v> <v>P, Q, G, Y = Mpint</v> <d> Where <c>P</c>, <c>Q</c> and <c>G</c> are the dss parameters and <c>Y</c> is the public key.</d> - <v>Mpint = binary()</v> + <v>ShaDigest = binary() with length 20 bytes</v> </type> <desc> - <p>Calculates the sha digest of the <c>Data</c> and verifies that the - digest matches the DSS signature using the public key <c>Key</c>. - </p> + <p>Verifies that a digest matches the DSS signature using the public key <c>Key</c>. + If <c>DigestType</c> is 'sha', the digest is calculated as SHA1 of <c>Data</c>. + If <c>DigestType</c> is 'none', <c>Data</c> is the precalculated SHA1 digest.</p> </desc> </func> diff --git a/lib/crypto/doc/src/notes.xml b/lib/crypto/doc/src/notes.xml index 6b9d1f56f1..3c571eb2a3 100644 --- a/lib/crypto/doc/src/notes.xml +++ b/lib/crypto/doc/src/notes.xml @@ -30,6 +30,93 @@ </header> <p>This document describes the changes made to the Crypto application.</p> +<section><title>Crypto 2.0.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Crypto dialyzer type error in md5_mac and sha_mac.</p> + <p> + Own Id: OTP-8718</p> + </item> + <item> + <p> + RC4 stream cipher didn't work. This since the new NIF + implementation of <c>crypto:rc4_encrypt_with_state/2</c> + introduced in <c>crypto-2.0</c> didn't return an updated + state. (Thanks to Paul Guyot)</p> + <p> + Own Id: OTP-8781</p> + </item> + <item> + <p> + A number of memory leaks in the crypto NIF library have + been fixed.</p> + <p> + Own Id: OTP-8810</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Added erlang:system_info(build_type) which makes it + easier to chose drivers, NIF libraries, etc based on + build type of the runtime system.</p> + <p> + The NIF library for crypto can now be built for valgrind + and/or debug as separate NIF libraries that will be + automatically loaded if the runtime system has been built + with a matching build type.</p> + <p> + Own Id: OTP-8760</p> + </item> + </list> + </section> + +</section> + +<section><title>Crypto 2.0</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + crypto application changed to use NIFs instead of driver.</p> + <p> + Own Id: OTP-8333</p> + </item> + <item> + <p> + des_ecb_encrypt/2 and des_ecb_decrypt/2 has been added to + the crypto module. The crypto:md4/1 function has been + documented.</p> + <p> + Own Id: OTP-8551</p> + </item> + <item> + <p>The undocumented, unsupport, and deprecated function + <c>lists:flat_length/1</c> has been removed.</p> + <p> + Own Id: OTP-8584</p> + </item> + <item> + <p> + New variants of <c>crypto:dss_sign</c> and + <c>crypto:dss_verify</c> with an extra argument to + control how the digest is calculated.</p> + <p> + Own Id: OTP-8700</p> + </item> + </list> + </section> + +</section> + <section><title>Crypto 1.6.4</title> <section><title>Improvements and New Features</title> diff --git a/lib/crypto/priv/Makefile b/lib/crypto/priv/Makefile index b8acdacc00..0989f14c94 100644 --- a/lib/crypto/priv/Makefile +++ b/lib/crypto/priv/Makefile @@ -18,21 +18,21 @@ # ---------------------------------------------------- # THIS MAKEFILE SERVES AS AN EXAMPLE OF -# HOW TO RELINK THE CRYPTO DRIVER +# HOW TO RELINK THE CRYPTO NIF LIBRARY # ---------------------------------------------------- # ---------------------------------------------------- -# Variables for linking a .so driver on unix. +# Variables for linking a .so library on unix. # Note: These may differ between systems. # ---------------------------------------------------- SO_LD = gcc SO_LDFLAGS = -G SO_SSL_LIBDIR = /usr/local/lib -SO_DRIVER = $(LIBDIR)/$(DRIVER_NAME).so +SO_NIFLIB = $(LIBDIR)/$(LIB_NAME).so # ---------------------------------------------------- -# Variables for linking a win32 .dll driver. +# Variables for linking a win32 .dll library. # Note: These may differ between systems. # ---------------------------------------------------- @@ -42,9 +42,9 @@ DLL_LIBDIR = "c:\\OpenSSL\\lib\\VC" DLL_LIBS = libeay32.lib MSVCRT.LIB kernel32.lib \ advapi32.lib gdi32.lib user32.lib \ comctl32.lib comdlg32.lib shell32.lib -DLL_DRIVER = $(LIBDIR)/$(DRIVER_NAME).dll -DLL_EXP = $(LIBDIR)/$(DRIVER_NAME).exp -DLL_LIB = $(LIBDIR)/$(DRIVER_NAME).lib +DLL_NIFLIB = $(LIBDIR)/$(LIB_NAME).dll +DLL_EXP = $(LIBDIR)/$(LIB_NAME).exp +DLL_LIB = $(LIBDIR)/$(LIB_NAME).lib # ---------------------------------------------------- # Common variables @@ -52,27 +52,27 @@ DLL_LIB = $(LIBDIR)/$(DRIVER_NAME).lib OBJDIR = ./ LIBDIR = ../lib -DRIVER_NAME = crypto_drv -OBJS = $(OBJDIR)/crypto_drv.o +LIB_NAME = crypto +OBJS = $(OBJDIR)/crypto.o # ---------------------------------------------------- # Targets # ---------------------------------------------------- -$(SO_DRIVER): $(OBJS) +$(SO_NIFLIB): $(OBJS) $(SO_LD) $(SO_LDFLAGS) -L$(SO_SSL_LIBDIR) -Wl,-R$(SO_SSL_LIBDIR) \ -o $@ $^ -lcrypto -$(DLL_DRIVER): $(OBJS) +$(DLL_NIFLIB): $(OBJS) $(DLL_LD) $(DLL_LDFLAGS) -out:$@ -libpath:$(DLL_LIBDIR) $(OBJS) \ $(DLL_LIBS) -so: $(SO_DRIVER) +so: $(SO_NIFLIB) -dll: $(DLL_DRIVER) +dll: $(DLL_NIFLIB) clean: - rm -f $(SO_DRIVER) $(DLL_DRIVER) + rm -f $(SO_NIFLIB) $(DLL_NIFLIB) rm -f $(DLL_EXP) $(DLL_LIB) rm -f core *~ diff --git a/lib/crypto/src/Makefile b/lib/crypto/src/Makefile index 51092d16a5..0e886ce8bf 100644 --- a/lib/crypto/src/Makefile +++ b/lib/crypto/src/Makefile @@ -1,19 +1,19 @@ # # %CopyrightBegin% -# -# Copyright Ericsson AB 1999-2009. All Rights Reserved. -# +# +# 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% # include $(ERL_TOP)/make/target.mk @@ -57,7 +57,7 @@ APPUP_TARGET= $(EBIN)/$(APPUP_FILE) # ---------------------------------------------------- # FLAGS # ---------------------------------------------------- -ERL_COMPILE_FLAGS += +warn_obsolete_guard +ERL_COMPILE_FLAGS += +warn_obsolete_guard -DCRYPTO_VSN=\"$(VSN)\" # ---------------------------------------------------- # Targets diff --git a/lib/crypto/src/crypto.app.src b/lib/crypto/src/crypto.app.src index a24760a781..5548b6a1b5 100644 --- a/lib/crypto/src/crypto.app.src +++ b/lib/crypto/src/crypto.app.src @@ -1,23 +1,23 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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% %% {application, crypto, - [{description, "CRYPTO version 1"}, + [{description, "CRYPTO version 2"}, {vsn, "%VSN%"}, {modules, [crypto, crypto_app, diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index fa33bad2e0..71fd91cafd 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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% %% @@ -21,7 +21,7 @@ -module(crypto). --export([start/0, stop/0, info/0, info_lib/0]). +-export([start/0, stop/0, info/0, info_lib/0, version/0]). -export([md4/1, md4_init/0, md4_update/2, md4_final/1]). -export([md5/1, md5_init/0, md5_update/2, md5_final/1]). -export([sha/1, sha_init/0, sha_update/2, sha_final/1]). @@ -29,6 +29,7 @@ %-export([sha512/1, sha512_init/0, sha512_update/2, sha512_final/1]). -export([md5_mac/2, md5_mac_96/2, sha_mac/2, sha_mac_96/2]). -export([des_cbc_encrypt/3, des_cbc_decrypt/3, des_cbc_ivec/1]). +-export([des_ecb_encrypt/2, des_ecb_decrypt/2]). -export([des3_cbc_encrypt/5, des3_cbc_decrypt/5]). -export([blowfish_ecb_encrypt/2, blowfish_ecb_decrypt/2]). -export([blowfish_cbc_encrypt/3, blowfish_cbc_decrypt/3]). @@ -39,8 +40,8 @@ -export([exor/2]). -export([rc4_encrypt/2, rc4_set_key/1, rc4_encrypt_with_state/2]). -export([rc2_40_cbc_encrypt/3, rc2_40_cbc_decrypt/3]). --export([dss_verify/3, rsa_verify/3, rsa_verify/4]). --export([dss_sign/2, rsa_sign/2, rsa_sign/3]). +-export([dss_verify/3, dss_verify/4, rsa_verify/3, rsa_verify/4]). +-export([dss_sign/2, dss_sign/3, rsa_sign/2, rsa_sign/3]). -export([rsa_public_encrypt/3, rsa_private_decrypt/3]). -export([rsa_private_encrypt/3, rsa_public_decrypt/3]). -export([dh_generate_key/1, dh_generate_key/2, dh_compute_key/3]). @@ -53,79 +54,6 @@ -export([dh_generate_parameters/2, dh_check/1]). %% Testing see below --define(INFO, 0). --define(MD5, 1). --define(MD5_INIT, 2). --define(MD5_UPDATE, 3). --define(MD5_FINAL, 4). --define(SHA, 5). --define(SHA_INIT, 6). --define(SHA_UPDATE, 7). --define(SHA_FINAL, 8). --define(MD5_MAC, 9). --define(MD5_MAC_96, 10). --define(SHA_MAC, 11). --define(SHA_MAC_96, 12). --define(DES_CBC_ENCRYPT, 13). --define(DES_CBC_DECRYPT, 14). --define(DES_EDE3_CBC_ENCRYPT, 15). --define(DES_EDE3_CBC_DECRYPT, 16). --define(AES_CFB_128_ENCRYPT, 17). --define(AES_CFB_128_DECRYPT, 18). --define(RAND_BYTES, 19). --define(RAND_UNIFORM, 20). --define(MOD_EXP, 21). --define(DSS_VERIFY, 22). --define(RSA_VERIFY_SHA, 23). -%-define(RSA_VERIFY_MD5, 35). --define(AES_CBC_128_ENCRYPT, 24). --define(AES_CBC_128_DECRYPT, 25). --define(XOR, 26). --define(RC4_ENCRYPT, 27). --define(RC4_SET_KEY, 28). --define(RC4_ENCRYPT_WITH_STATE, 29). --define(RC2_40_CBC_ENCRYPT, 30). --define(RC2_40_CBC_DECRYPT, 31). --define(AES_CBC_256_ENCRYPT, 32). --define(AES_CBC_256_DECRYPT, 33). --define(INFO_LIB,34). -%-define(RSA_VERIFY_SHA, 23). --define(RSA_VERIFY_MD5, 35). --define(RSA_SIGN_SHA, 36). --define(RSA_SIGN_MD5, 37). --define(DSS_SIGN, 38). --define(RSA_PUBLIC_ENCRYPT, 39). --define(RSA_PRIVATE_DECRYPT, 40). --define(RSA_PRIVATE_ENCRYPT, 41). --define(RSA_PUBLIC_DECRYPT, 42). --define(DH_GENERATE_PARAMS, 43). --define(DH_CHECK, 44). --define(DH_GENERATE_KEY, 45). --define(DH_COMPUTE_KEY, 46). --define(MD4, 47). --define(MD4_INIT, 48). --define(MD4_UPDATE, 49). --define(MD4_FINAL, 50). - -%% -define(SHA256, 51). -%% -define(SHA256_INIT, 52). -%% -define(SHA256_UPDATE, 53). -%% -define(SHA256_FINAL, 54). -%% -define(SHA512, 55). -%% -define(SHA512_INIT, 56). -%% -define(SHA512_UPDATE, 57). -%% -define(SHA512_FINAL, 58). - --define(BF_CFB64_ENCRYPT, 59). --define(BF_CFB64_DECRYPT, 60). --define(BF_ECB_ENCRYPT, 61). --define(BF_ECB_DECRYPT, 62). --define(BF_OFB64_ENCRYPT, 63). --define(BF_CBC_ENCRYPT, 64). --define(BF_CBC_DECRYPT, 65). - -%% -define(IDEA_CBC_ENCRYPT, 34). -%% -define(IDEA_CBC_DECRYPT, 35). -define(FUNC_LIST, [md4, md4_init, md4_update, md4_final, md5, md5_init, md5_update, md5_final, @@ -135,6 +63,7 @@ md5_mac, md5_mac_96, sha_mac, sha_mac_96, des_cbc_encrypt, des_cbc_decrypt, + des_ecb_encrypt, des_ecb_decrypt, des_ede3_cbc_encrypt, des_ede3_cbc_decrypt, aes_cfb_128_encrypt, aes_cfb_128_decrypt, rand_bytes, @@ -153,6 +82,67 @@ aes_cbc_256_encrypt, aes_cbc_256_decrypt, info_lib]). +-type rsa_digest_type() :: 'md5' | 'sha'. +-type dss_digest_type() :: 'none' | 'sha'. +-type crypto_integer() :: binary() | integer(). + +-define(nif_stub,nif_stub_error(?LINE)). + +-on_load(on_load/0). + +-define(CRYPTO_NIF_VSN,101). + +on_load() -> + LibBaseName = "crypto", + PrivDir = code:priv_dir(crypto), + 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 -> + ArchLibDir = + filename:join([PrivDir, "lib", + erlang:system_info(system_architecture)]), + Candidate = + filelib:wildcard(filename:join([ArchLibDir,LibName ++ "*" ])), + case Candidate of + [] -> Error1; + _ -> + ArchLib = filename:join([ArchLibDir, LibName]), + erlang:load_nif(ArchLib, ?CRYPTO_NIF_VSN) + end; + Error1 -> Error1 + end, + case Status of + ok -> ok; + {error, {E, Str}} -> + error_logger:error_msg("Unable to load crypto library. Failed with error:~n\"~p, ~s\"~n" + "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}). + start() -> application:start(crypto). @@ -160,15 +150,15 @@ stop() -> application:stop(crypto). info() -> - lists:map(fun(I) -> - lists:nth(I, ?FUNC_LIST) - end, binary_to_list(control(?INFO, []))). + ?FUNC_LIST. -info_lib() -> - <<_DrvVer:8, NameSize:8, Name:NameSize/binary, - VerNum:32, VerStr/binary>> = control(?INFO_LIB,[]), - [{Name,VerNum,VerStr}]. +info_lib() -> ?nif_stub. +%% Crypto app version history: +%% (no version): Driver implementation +%% 2.0 : NIF implementation, requires OTP R14 +version() -> ?CRYPTO_VSN. + %% Below Key and Data are binaries or IO-lists. IVec is a binary. %% Output is always a binary. Context is a binary. @@ -179,73 +169,43 @@ info_lib() -> %% %% MD5 %% -md5(Data) -> - control(?MD5, Data). -md5_init() -> - control(?MD5_INIT, []). +-spec md5(iodata()) -> binary(). +-spec md5_init() -> binary(). +-spec md5_update(binary(), iodata()) -> binary(). +-spec md5_final(binary()) -> binary(). -md5_update(Context, Data) -> - control(?MD5_UPDATE, [Context, Data]). - -md5_final(Context) -> - control(?MD5_FINAL, Context). +md5(_Data) -> ?nif_stub. +md5_init() -> ?nif_stub. +md5_update(_Context, _Data) -> ?nif_stub. +md5_final(_Context) -> ?nif_stub. %% %% MD4 %% -md4(Data) -> - control(?MD4, Data). - -md4_init() -> - control(?MD4_INIT, []). +-spec md4(iodata()) -> binary(). +-spec md4_init() -> binary(). +-spec md4_update(binary(), iodata()) -> binary(). +-spec md4_final(binary()) -> binary(). -md4_update(Context, Data) -> - control(?MD4_UPDATE, [Context, Data]). - -md4_final(Context) -> - control(?MD4_FINAL, Context). +md4(_Data) -> ?nif_stub. +md4_init() -> ?nif_stub. +md4_update(_Context, _Data) -> ?nif_stub. +md4_final(_Context) -> ?nif_stub. %% %% SHA %% -sha(Data) -> - control(?SHA, Data). - -sha_init() -> - control(?SHA_INIT, []). - -sha_update(Context, Data) -> - control(?SHA_UPDATE, [Context, Data]). - -sha_final(Context) -> - control(?SHA_FINAL, Context). +-spec sha(iodata()) -> binary(). +-spec sha_init() -> binary(). +-spec sha_update(binary(), iodata()) -> binary(). +-spec sha_final(binary()) -> binary(). -%% sha256 and sha512 requires openssl-0.9.8 removed for now +sha(_Data) -> ?nif_stub. +sha_init() -> ?nif_stub. +sha_update(_Context, _Data) -> ?nif_stub. +sha_final(_Context) -> ?nif_stub. -%% sha256(Data) -> -%% control(?SHA256, Data). - -%% sha256_init() -> -%% control(?SHA256_INIT, []). - -%% sha256_update(Context, Data) -> -%% control(?SHA256_UPDATE, [Context, Data]). - -%% sha256_final(Context) -> -%% control(?SHA256_FINAL, Context). - -%% sha512(Data) -> -%% control(?SHA512, Data). - -%% sha512_init() -> -%% control(?SHA512_INIT, []). - -%% sha512_update(Context, Data) -> -%% control(?SHA512_UPDATE, [Context, Data]). - -%% sha512_final(Context) -> -%% control(?SHA512_FINAL, Context). %% %% MESSAGE AUTHENTICATION CODES @@ -254,21 +214,31 @@ sha_final(Context) -> %% %% MD5_MAC %% +-spec md5_mac(iodata(), iodata()) -> binary(). +-spec md5_mac_96(iodata(), iodata()) -> binary(). + md5_mac(Key, Data) -> - control_bin(?MD5_MAC, Key, Data). + md5_mac_n(Key,Data,16). md5_mac_96(Key, Data) -> - control_bin(?MD5_MAC_96, Key, Data). + md5_mac_n(Key,Data,12). +md5_mac_n(_Key,_Data,_MacSz) -> ?nif_stub. + %% %% SHA_MAC %% +-spec sha_mac(iodata(), iodata()) -> binary(). +-spec sha_mac_96(iodata(), iodata()) -> binary(). + sha_mac(Key, Data) -> - control_bin(?SHA_MAC, Key, Data). + sha_mac_n(Key,Data,20). sha_mac_96(Key, Data) -> - control_bin(?SHA_MAC_96, Key, Data). + sha_mac_n(Key,Data,12). +sha_mac_n(_Key,_Data,_MacSz) -> ?nif_stub. + %% %% CRYPTO FUNCTIONS %% @@ -276,11 +246,16 @@ sha_mac_96(Key, Data) -> %% %% DES - in cipher block chaining mode (CBC) %% +-spec des_cbc_encrypt(iodata(), binary(), iodata()) -> binary(). +-spec des_cbc_decrypt(iodata(), binary(), iodata()) -> binary(). + des_cbc_encrypt(Key, IVec, Data) -> - control(?DES_CBC_ENCRYPT, [Key, IVec, Data]). + des_cbc_crypt(Key, IVec, Data, true). des_cbc_decrypt(Key, IVec, Data) -> - control(?DES_CBC_DECRYPT, [Key, IVec, Data]). + des_cbc_crypt(Key, IVec, Data, false). + +des_cbc_crypt(_Key, _IVec, _Data, _IsEncrypt) -> ?nif_stub. %% %% dec_cbc_ivec(Data) -> binary() @@ -288,6 +263,8 @@ des_cbc_decrypt(Key, IVec, Data) -> %% Returns the IVec to be used in the next iteration of %% des_cbc_[encrypt|decrypt]. %% +-spec des_cbc_ivec(iodata()) -> binary(). + des_cbc_ivec(Data) when is_binary(Data) -> {_, IVec} = split_binary(Data, size(Data) - 8), IVec; @@ -295,76 +272,101 @@ des_cbc_ivec(Data) when is_list(Data) -> des_cbc_ivec(list_to_binary(Data)). %% +%% DES - in electronic codebook mode (ECB) +%% +-spec des_ecb_encrypt(iodata(), iodata()) -> binary(). +-spec des_ecb_decrypt(iodata(), iodata()) -> binary(). + +des_ecb_encrypt(Key, Data) -> + des_ecb_crypt(Key, Data, true). +des_ecb_decrypt(Key, Data) -> + des_ecb_crypt(Key, Data, false). +des_ecb_crypt(_Key, _Data, _IsEncrypt) -> ?nif_stub. + +%% %% DES3 - in cipher block chaining mode (CBC) %% +-spec des3_cbc_encrypt(iodata(), iodata(), iodata(), binary(), iodata()) -> + binary(). +-spec des3_cbc_decrypt(iodata(), iodata(), iodata(), binary(), iodata()) -> + binary(). + des3_cbc_encrypt(Key1, Key2, Key3, IVec, Data) -> des_ede3_cbc_encrypt(Key1, Key2, Key3, IVec, Data). des_ede3_cbc_encrypt(Key1, Key2, Key3, IVec, Data) -> - %%io:format("des_ede3_cbc_encrypt: size(Data)=~p\n", [size(list_to_binary([Data]))]), - control(?DES_EDE3_CBC_ENCRYPT, [Key1, Key2, Key3, IVec, Data]). + des_ede3_cbc_crypt(Key1, Key2, Key3, IVec, Data, true). des3_cbc_decrypt(Key1, Key2, Key3, IVec, Data) -> des_ede3_cbc_decrypt(Key1, Key2, Key3, IVec, Data). des_ede3_cbc_decrypt(Key1, Key2, Key3, IVec, Data) -> - control(?DES_EDE3_CBC_DECRYPT, [Key1, Key2, Key3, IVec, Data]). + des_ede3_cbc_crypt(Key1, Key2, Key3, IVec, Data, false). + +des_ede3_cbc_crypt(_Key1, _Key2, _Key3, _IVec, _Data, _IsEncrypt) -> ?nif_stub. %% %% Blowfish %% -blowfish_ecb_encrypt(Key, Data) when byte_size(Data) >= 8 -> - control_bin(?BF_ECB_ENCRYPT, Key, list_to_binary([Data])). +-spec blowfish_ecb_encrypt(iodata(), iodata()) -> binary(). +-spec blowfish_ecb_decrypt(iodata(), iodata()) -> binary(). +-spec blowfish_cbc_encrypt(iodata(), binary(), iodata()) -> binary(). +-spec blowfish_cbc_decrypt(iodata(), binary(), iodata()) -> binary(). +-spec blowfish_cfb64_encrypt(iodata(), binary(), iodata()) -> binary(). +-spec blowfish_cfb64_decrypt(iodata(), binary(), iodata()) -> binary(). +-spec blowfish_ofb64_encrypt(iodata(), binary(), iodata()) -> binary(). + +blowfish_ecb_encrypt(Key, Data) -> + bf_ecb_crypt(Key,Data, true). + +blowfish_ecb_decrypt(Key, Data) -> + bf_ecb_crypt(Key,Data, false). -blowfish_ecb_decrypt(Key, Data) when byte_size(Data) >= 8 -> - control_bin(?BF_ECB_DECRYPT, Key, list_to_binary([Data])). +bf_ecb_crypt(_Key,_Data,_IsEncrypt) -> ?nif_stub. -blowfish_cbc_encrypt(Key, IVec, Data) when byte_size(Data) rem 8 =:= 0 -> - control_bin(?BF_CBC_ENCRYPT, Key, list_to_binary([IVec, Data])). +blowfish_cbc_encrypt(Key, IVec, Data) -> + bf_cbc_crypt(Key,IVec,Data,true). -blowfish_cbc_decrypt(Key, IVec, Data) when byte_size(Data) rem 8 =:= 0 -> - control_bin(?BF_CBC_DECRYPT, Key, list_to_binary([IVec, Data])). +blowfish_cbc_decrypt(Key, IVec, Data) -> + bf_cbc_crypt(Key,IVec,Data,false). -blowfish_cfb64_encrypt(Key, IVec, Data) when byte_size(IVec) =:= 8 -> - control_bin(?BF_CFB64_ENCRYPT, Key, list_to_binary([IVec, Data])). +bf_cbc_crypt(_Key,_IVec,_Data,_IsEncrypt) -> ?nif_stub. -blowfish_cfb64_decrypt(Key, IVec, Data) when byte_size(IVec) =:= 8 -> - control_bin(?BF_CFB64_DECRYPT, Key, list_to_binary([IVec, Data])). +blowfish_cfb64_encrypt(Key, IVec, Data) -> + bf_cfb64_crypt(Key, IVec, Data, true). -blowfish_ofb64_encrypt(Key, IVec, Data) when byte_size(IVec) =:= 8 -> - control_bin(?BF_OFB64_ENCRYPT, Key, list_to_binary([IVec, Data])). +blowfish_cfb64_decrypt(Key, IVec, Data) -> + bf_cfb64_crypt(Key, IVec, Data, false). + +bf_cfb64_crypt(_Key, _IVec, _Data, _IsEncrypt) -> ?nif_stub. + +blowfish_ofb64_encrypt(_Key, _IVec, _Data) -> ?nif_stub. %% %% AES in cipher feedback mode (CFB) %% +-spec aes_cfb_128_encrypt(iodata(), binary(), iodata()) -> binary(). +-spec aes_cfb_128_decrypt(iodata(), binary(), iodata()) -> binary(). + aes_cfb_128_encrypt(Key, IVec, Data) -> - control(?AES_CFB_128_ENCRYPT, [Key, IVec, Data]). + aes_cfb_128_crypt(Key, IVec, Data, true). aes_cfb_128_decrypt(Key, IVec, Data) -> - control(?AES_CFB_128_DECRYPT, [Key, IVec, Data]). - + aes_cfb_128_crypt(Key, IVec, Data, false). -%% %% -%% %% IDEA - in cipher block chaining mode (CBC) -%% %% -%% idea_cbc_encrypt(Key, IVec, Data) -> -%% control(?IDEA_CBC_ENCRYPT, [Key, IVec, Data]). - -%% idea_cbc_decrypt(Key, IVec, Data) -> -%% control(?IDEA_CBC_DECRYPT, [Key, IVec, Data]). +aes_cfb_128_crypt(_Key, _IVec, _Data, _IsEncrypt) -> ?nif_stub. %% %% RAND - pseudo random numbers using RN_ functions in crypto lib %% +-spec rand_bytes(non_neg_integer()) -> binary(). +-spec rand_uniform(crypto_integer(), crypto_integer()) -> + crypto_integer(). -rand_bytes(Bytes) -> - rand_bytes(Bytes, 0, 0). -rand_bytes(Bytes, Topmask, Bottommask) -> - control(?RAND_BYTES,[<<Bytes:32/integer, - Topmask:8/integer, - Bottommask:8/integer>>]). +rand_bytes(_Bytes) -> ?nif_stub. +rand_bytes(_Bytes, _Topmask, _Bottommask) -> ?nif_stub. rand_uniform(From,To) when is_binary(From), is_binary(To) -> - case control(?RAND_UNIFORM,[From,To]) of + case rand_uniform_nif(From,To) of <<Len:32/integer, MSB, Rest/binary>> when MSB > 127 -> <<(Len + 1):32/integer, 0, MSB, Rest/binary>>; Whatever -> @@ -380,6 +382,8 @@ rand_uniform(From,To) when is_integer(From),is_integer(To) -> Other end. +rand_uniform_nif(_From,_To) -> ?nif_stub. + %% %% mod_exp - utility for rsa generation %% @@ -388,121 +392,142 @@ mod_exp(Base, Exponent, Modulo) erlint(mod_exp(mpint(Base), mpint(Exponent), mpint(Modulo))); mod_exp(Base, Exponent, Modulo) -> - case control(?MOD_EXP,[Base,Exponent,Modulo]) of + case mod_exp_nif(Base,Exponent,Modulo) of <<Len:32/integer, MSB, Rest/binary>> when MSB > 127 -> <<(Len + 1):32/integer, 0, MSB, Rest/binary>>; Whatever -> Whatever end. +mod_exp_nif(_Base,_Exp,_Mod) -> ?nif_stub. + %% %% DSS, RSA - verify %% +-spec dss_verify(binary(), binary(), [binary()]) -> boolean(). +-spec dss_verify(dss_digest_type(), binary(), binary(), [binary()]) -> boolean(). +-spec rsa_verify(binary(), binary(), [binary()]) -> boolean(). +-spec rsa_verify(rsa_digest_type(), binary(), binary(), [binary()]) -> + boolean(). %% Key = [P,Q,G,Y] P,Q,G=DSSParams Y=PublicKey dss_verify(Data,Signature,Key) -> - control(?DSS_VERIFY, [Data,Signature,Key]) == <<1>>. + dss_verify(sha, Data, Signature, Key). +dss_verify(_Type,_Data,_Signature,_Key) -> ?nif_stub. % Key = [E,N] E=PublicExponent N=PublicModulus rsa_verify(Data,Signature,Key) -> rsa_verify(sha, Data,Signature,Key). -rsa_verify(Type,Data,Signature,Key) -> - control(rsa_verify_digest_type(Type), [Data,Signature,Key]) == <<1>>. +rsa_verify(_Type,_Data,_Signature,_Key) -> ?nif_stub. -rsa_verify_digest_type(md5) -> ?RSA_VERIFY_MD5; -rsa_verify_digest_type(sha) -> ?RSA_VERIFY_SHA; -rsa_verify_digest_type(Bad) -> erlang:error(badarg, [Bad]). %% %% DSS, RSA - sign %% %% Key = [P,Q,G,X] P,Q,G=DSSParams X=PrivateKey -dss_sign(Data, Key) -> - <<Ret:8, Signature/binary>> = control(?DSS_SIGN, [Data,Key]), - case Ret of - 1 -> Signature; - 0 -> erlang:error(badkey, [Data, Key]) +-spec dss_sign(binary(), [binary()]) -> binary(). +-spec dss_sign(dss_digest_type(), binary(), [binary()]) -> binary(). +-spec rsa_sign(binary(), [binary()]) -> binary(). +-spec rsa_sign(rsa_digest_type(), binary(), [binary()]) -> binary(). + +dss_sign(Data,Key) -> + dss_sign(sha,Data,Key). +dss_sign(Type, Data, Key) -> + case dss_sign_nif(Type,Data,Key) of + error -> erlang:error(badkey, [Data, Key]); + Sign -> Sign end. +dss_sign_nif(_Type,_Data,_Key) -> ?nif_stub. + %% Key = [E,N,D] E=PublicExponent N=PublicModulus D=PrivateExponent rsa_sign(Data,Key) -> rsa_sign(sha, Data, Key). rsa_sign(Type, Data, Key) -> - <<Ret:8, Signature/binary>> = control(rsa_sign_digest_type(Type), [Data,Key]), - case Ret of - 1 -> Signature; - 0 -> erlang:error(badkey, [Type,Data,Key]) + case rsa_sign_nif(Type,Data,Key) of + error -> erlang:error(badkey, [Type,Data,Key]); + Sign -> Sign end. -rsa_sign_digest_type(md5) -> ?RSA_SIGN_MD5; -rsa_sign_digest_type(sha) -> ?RSA_SIGN_SHA; -rsa_sign_digest_type(Bad) -> erlang:error(badarg, [Bad]). +rsa_sign_nif(_Type,_Data,_Key) -> ?nif_stub. + %% %% rsa_public_encrypt %% rsa_private_decrypt +-type rsa_padding() :: 'rsa_pkcs1_padding' | 'rsa_pkcs1_oaep_padding' | 'rsa_no_padding'. + +-spec rsa_public_encrypt(binary(), [binary()], rsa_padding()) -> + binary(). +-spec rsa_public_decrypt(binary(), [binary()], rsa_padding()) -> + binary(). +-spec rsa_private_encrypt(binary(), [binary()], rsa_padding()) -> + binary(). +-spec rsa_private_decrypt(binary(), [binary()], rsa_padding()) -> + binary(). %% Binary, Key = [E,N] rsa_public_encrypt(BinMesg, Key, Padding) -> - Size = iolist_size(BinMesg), - <<Ret:8, Signature/binary>> = - control(?RSA_PUBLIC_ENCRYPT, [<<Size:32>>,BinMesg,Key,rsa_pad(Padding)]), - case Ret of - 1 -> Signature; - 0 -> erlang:error(encrypt_failed, [BinMesg,Key, Padding]) - end. + case rsa_public_crypt(BinMesg, Key, Padding, true) of + error -> + erlang:error(encrypt_failed, [BinMesg,Key, Padding]); + Sign -> Sign + end. + +rsa_public_crypt(_BinMsg, _Key, _Padding, _IsEncrypt) -> ?nif_stub. %% Binary, Key = [E,N,D] rsa_private_decrypt(BinMesg, Key, Padding) -> - Size = iolist_size(BinMesg), - <<Ret:8, Signature/binary>> = - control(?RSA_PRIVATE_DECRYPT, [<<Size:32>>,BinMesg,Key,rsa_pad(Padding)]), - case Ret of - 1 -> Signature; - 0 -> erlang:error(decrypt_failed, [BinMesg,Key, Padding]) - end. - -rsa_pad(rsa_pkcs1_padding) -> 1; -rsa_pad(rsa_pkcs1_oaep_padding) -> 2; -%% rsa_pad(rsa_sslv23_padding) -> 3; -rsa_pad(rsa_no_padding) -> 0; -rsa_pad(Bad) -> erlang:error(badarg, [Bad]). + case rsa_private_crypt(BinMesg, Key, Padding, false) of + error -> + erlang:error(decrypt_failed, [BinMesg,Key, Padding]); + Sign -> Sign + end. + +rsa_private_crypt(_BinMsg, _Key, _Padding, _IsEncrypt) -> ?nif_stub. + %% Binary, Key = [E,N,D] rsa_private_encrypt(BinMesg, Key, Padding) -> - Size = iolist_size(BinMesg), - <<Ret:8, Signature/binary>> = - control(?RSA_PRIVATE_ENCRYPT, [<<Size:32>>,BinMesg,Key,rsa_pad(Padding)]), - case Ret of - 1 -> Signature; - 0 -> erlang:error(encrypt_failed, [BinMesg,Key, Padding]) - end. + case rsa_private_crypt(BinMesg, Key, Padding, true) of + error -> + erlang:error(encrypt_failed, [BinMesg,Key, Padding]); + Sign -> Sign + end. %% Binary, Key = [E,N] rsa_public_decrypt(BinMesg, Key, Padding) -> - Size = iolist_size(BinMesg), - <<Ret:8, Signature/binary>> = - control(?RSA_PUBLIC_DECRYPT, [<<Size:32>>,BinMesg,Key,rsa_pad(Padding)]), - case Ret of - 1 -> Signature; - 0 -> erlang:error(decrypt_failed, [BinMesg,Key, Padding]) + case rsa_public_crypt(BinMesg, Key, Padding, false) of + error -> + erlang:error(decrypt_failed, [BinMesg,Key, Padding]); + Sign -> Sign end. %% %% AES - with 128 or 256 bit key in cipher block chaining mode (CBC) %% +-spec aes_cbc_128_encrypt(iodata(), binary(), iodata()) -> + binary(). +-spec aes_cbc_128_decrypt(iodata(), binary(), iodata()) -> + binary(). +-spec aes_cbc_256_encrypt(iodata(), binary(), iodata()) -> + binary(). +-spec aes_cbc_256_decrypt(iodata(), binary(), iodata()) -> + binary(). aes_cbc_128_encrypt(Key, IVec, Data) -> - control(?AES_CBC_128_ENCRYPT, [Key, IVec, Data]). + aes_cbc_crypt(Key, IVec, Data, true). aes_cbc_128_decrypt(Key, IVec, Data) -> - control(?AES_CBC_128_DECRYPT, [Key, IVec, Data]). + aes_cbc_crypt(Key, IVec, Data, false). aes_cbc_256_encrypt(Key, IVec, Data) -> - control(?AES_CBC_256_ENCRYPT, [Key, IVec, Data]). + aes_cbc_crypt(Key, IVec, Data, true). aes_cbc_256_decrypt(Key, IVec, Data) -> - control(?AES_CBC_256_DECRYPT, [Key, IVec, Data]). + aes_cbc_crypt(Key, IVec, Data, false). + +aes_cbc_crypt(_Key, _IVec, _Data, _IsEncrypt) -> ?nif_stub. %% %% aes_cbc_ivec(Data) -> binary() @@ -523,31 +548,29 @@ aes_cbc_ivec(Data) when is_list(Data) -> %% NB doesn't check that they are the same size, just concatenates %% them and sends them to the driver %% -exor(A, B) -> - control(?XOR, [A, B]). +-spec exor(iodata(), iodata()) -> binary(). + +exor(_A, _B) -> ?nif_stub. %% %% RC4 - symmetric stream cipher %% -rc4_encrypt(Key, Data) -> - control_bin(?RC4_ENCRYPT, Key, Data). +-spec rc4_encrypt(iodata(), iodata()) -> binary(). -rc4_set_key(Key) -> - control(?RC4_SET_KEY, Key). - -rc4_encrypt_with_state(State, Data) -> - <<Sz:32/integer-big-unsigned, S:Sz/binary, D/binary>> = - control_bin(?RC4_ENCRYPT_WITH_STATE, State, Data), - {S, D}. +rc4_encrypt(_Key, _Data) -> ?nif_stub. +rc4_set_key(_Key) -> ?nif_stub. +rc4_encrypt_with_state(_State, _Data) -> ?nif_stub. %% %% RC2 - 40 bits block cipher %% rc2_40_cbc_encrypt(Key, IVec, Data) -> - control(?RC2_40_CBC_ENCRYPT, [Key, IVec, Data]). + rc2_40_cbc_crypt(Key,IVec,Data,true). rc2_40_cbc_decrypt(Key, IVec, Data) -> - control(?RC2_40_CBC_DECRYPT, [Key, IVec, Data]). + rc2_40_cbc_crypt(Key,IVec,Data,false). + +rc2_40_cbc_crypt(_Key, _IVec, _Data, _IsEncrypt) -> ?nif_stub. %% %% DH Diffie-Hellman functions @@ -562,87 +585,50 @@ rc2_40_cbc_decrypt(Key, IVec, Data) -> %% %% usage: dh_generate_parameters(1024, 2 or 5) -> %% [Prime=mpint(), SharedGenerator=mpint()] -dh_generate_parameters(PrimeLen, Generator) - when is_integer(PrimeLen), is_integer(Generator) -> - case control(?DH_GENERATE_PARAMS, <<PrimeLen:32, Generator:32>>) of - <<0:8, _/binary>> -> - erlang:error(generation_failed, [PrimeLen,Generator]); - <<1:8, PLen0:32, _:PLen0/binary, GLen0:32,_:GLen0/binary>> = Bin -> - PLen = PLen0+4, - GLen = GLen0+4, - <<_:8, PBin:PLen/binary,GBin:GLen/binary>> = Bin, - [PBin, GBin] - end. +dh_generate_parameters(PrimeLen, Generator) -> + case dh_generate_parameters_nif(PrimeLen, Generator) of + error -> erlang:error(generation_failed, [PrimeLen,Generator]); + Ret -> Ret + end. + +dh_generate_parameters_nif(_PrimeLen, _Generator) -> ?nif_stub. %% Checks that the DHParameters are ok. %% DHParameters = [P (Prime)= mpint(), G(Generator) = mpint()] -dh_check(DHParameters) -> - case control(?DH_CHECK, DHParameters) of - <<0:32>> -> ok; - <<_:24,_:1,_:1,_:1,1:1>> -> not_prime; - <<_:24,_:1,_:1,1:1,0:1>> -> not_strong_prime; - <<_:24,_:1,1:1,0:1,0:1>> -> unable_to_check_generator; - <<_:24,1:1,0:1,0:1,0:1>> -> not_suitable_generator; - <<16#FFFF:32>> -> {error, check_failed}; - <<X:32>> -> {unknown, X} - end. +dh_check([_Prime,_Gen]) -> ?nif_stub. %% DHParameters = [P (Prime)= mpint(), G(Generator) = mpint()] %% PrivKey = mpint() +-spec dh_generate_key([binary()]) -> {binary(),binary()}. +-spec dh_generate_key(binary()|undefined, [binary()]) -> + {binary(),binary()}. + dh_generate_key(DHParameters) -> - dh_generate_key(<<0:32>>, DHParameters). + dh_generate_key(undefined, DHParameters). dh_generate_key(PrivateKey, DHParameters) -> - case control(?DH_GENERATE_KEY, [PrivateKey, DHParameters]) of - <<0:8, _/binary>> -> - erlang:error(generation_failed, [PrivateKey,DHParameters]); - Bin = <<1:8, PubLen0:32, _:PubLen0/binary, PrivLen0:32, _:PrivLen0/binary>> -> - PubLen = PubLen0+4, - PrivLen = PrivLen0+4, - <<_:8, PubBin:PubLen/binary,PrivBin:PrivLen/binary>> = Bin, - {PubBin, PrivBin} + case dh_generate_key_nif(PrivateKey, DHParameters) of + error -> erlang:error(generation_failed, [PrivateKey,DHParameters]); + Res -> Res end. +dh_generate_key_nif(_PrivateKey, _DHParameters) -> ?nif_stub. + %% DHParameters = [P (Prime)= mpint(), G(Generator) = mpint()] %% MyPrivKey, OthersPublicKey = mpint() +-spec dh_compute_key(binary(), binary(), [binary()]) -> binary(). + dh_compute_key(OthersPublicKey, MyPrivateKey, DHParameters) -> - case control(?DH_COMPUTE_KEY, [OthersPublicKey, MyPrivateKey, DHParameters]) of - <<0:8, _/binary>> -> - erlang:error(computation_failed, [OthersPublicKey,MyPrivateKey,DHParameters]); - <<1:8, Binary/binary>> -> Binary + case dh_compute_key_nif(OthersPublicKey,MyPrivateKey,DHParameters) of + error -> erlang:error(computation_failed, [OthersPublicKey,MyPrivateKey,DHParameters]); + Ret -> Ret end. +dh_compute_key_nif(_OthersPublicKey, _MyPrivateKey, _DHParameters) -> ?nif_stub. + %% %% LOCAL FUNCTIONS %% -control_bin(Cmd, Key, Data) -> - Sz = iolist_size(Key), - control(Cmd, [<<Sz:32/integer-unsigned>>, Key, Data]). - -control(Cmd, Data) -> - Port = crypto_server:client_port(), - erlang:port_control(Port, Cmd, Data). - - -%% sizehdr(N) -> -%% [(N bsr 24) band 255, -%% (N bsr 16) band 255, -%% (N bsr 8) band 255, -%% N band 255]. - -%% Flat length of IOlist (or binary) -%% flen(L) when binary(L) -> -%% size(L); -%% flen(L) -> -%% flen(L, 0). - -%% flen([H| T], N) when list(H) -> -%% flen(H, flen(T, N)); -%% flen([H| T], N) when binary(H) -> -%% flen(T, N + size(H)); -%% flen([H| T], N) when integer(H), 0 =< H, H =< 255 -> -%% flen(T, N + 1); -%% flen([], N) -> -%% N. + %% large integer in a binary with 32bit length %% MP representaion (SSH2) diff --git a/lib/crypto/src/crypto_server.erl b/lib/crypto/src/crypto_server.erl index 0b1e5c9b02..89650a9f06 100644 --- a/lib/crypto/src/crypto_server.erl +++ b/lib/crypto/src/crypto_server.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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% %% @@ -23,14 +23,12 @@ -behaviour(gen_server). --export([start_link/0,client_port/0]). +-export([start_link/0]). %% Internal exports, call-back functions. -export([init/1,handle_call/3,handle_cast/2,handle_info/2,code_change/3, terminate/2]). -%% Measurements shows that inlining port_names/0 is worth doing. --compile({inline,[{port_names,0}]}). %%% -------------------------------------------------------- %%% Interface Functions. @@ -40,66 +38,8 @@ start_link() -> gen_server:start_link({local, crypto_server}, crypto_server, [], []). init([]) -> - process_flag(trap_exit, true), - erl_ddll:start(), - PrivDir = code:priv_dir(crypto), - LibDir1 = filename:join([PrivDir, "lib"]), - {Status, LibDir} = - case erl_ddll:load_driver(LibDir1, crypto_drv) of - ok -> {ok,LibDir1}; - {error,Error1} -> - LibDir2 = - filename:join(LibDir1, - erlang:system_info(system_architecture)), - Candidate = - filelib:wildcard(filename:join([LibDir2,"crypto_drv*"])), - case Candidate of - [] -> - {{error,Error1},LibDir1}; - _ -> - case erl_ddll:load_driver(LibDir2, crypto_drv) of - ok -> - {ok,LibDir2}; - {error, Error2} -> - {{error,Error2},LibDir2} - end - end - end, - case Status of - ok -> - Cmd = "crypto_drv elibcrypto " ++ - filename:join([LibDir, "elibcrypto"]), - open_ports(Cmd,size(port_names())); - {error, E} -> - Str = erl_ddll:format_error(E), - error_logger:error_msg("Unable to load crypto_drv. Failed with error:~n\"~s\"~nOpenSSL might not be installed on this system.~n",[Str]), - {stop,nodriver} - end. - -open_ports(_,0) -> - {ok, []}; -open_ports(Cmd,N) -> - Port = open_port({spawn, Cmd}, []), - %% check that driver is loaded, linked and working - %% since crypto_drv links towards libcrypto, this is a good thing - %% since libcrypto is known to be bad with backwards compatibility - case catch port_control(Port, 0, []) of - {'EXIT', _} -> - {stop, nodriver}; - _ -> - register(element(N,port_names()), Port), - open_ports(Cmd,N-1) - end. - -port_names() -> - { crypto_drv01, crypto_drv02, crypto_drv03, crypto_drv04, - crypto_drv05, crypto_drv06, crypto_drv07, crypto_drv08, - crypto_drv09, crypto_drv10, crypto_drv11, crypto_drv12, - crypto_drv13, crypto_drv14, crypto_drv15, crypto_drv16 }. - -client_port() -> - element(erlang:system_info(scheduler_id) rem size(port_names()) + 1, - port_names()). + {ok,[]}. + %%% -------------------------------------------------------- @@ -112,11 +52,6 @@ handle_call(_, _, State) -> handle_cast(_, State) -> {noreply, State}. -handle_info({'EXIT', Pid, _Reason}, State) when is_pid(Pid) -> - {noreply, State}; - -handle_info({'EXIT', Port, Reason}, State) when is_port(Port) -> - {stop, {port_died, Reason}, State}; handle_info(_, State) -> {noreply, State}. @@ -124,13 +59,8 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}. terminate(_Reason, _State) -> - close_ports(size(port_names())). + []. -close_ports(0) -> - ok; -close_ports(N) -> - element(N,port_names()) ! {self(), close}, - close_ports(N-1). diff --git a/lib/crypto/test/blowfish_SUITE.erl b/lib/crypto/test/blowfish_SUITE.erl index d4cc167ea9..d117e7cc3d 100644 --- a/lib/crypto/test/blowfish_SUITE.erl +++ b/lib/crypto/test/blowfish_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009. All Rights Reserved. -%% +%% +%% 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% %% @@ -116,7 +116,8 @@ all(suite) -> ecb_test(KeyBytes, ClearBytes, CipherBytes) -> {Key, Clear, Cipher} = {to_bin(KeyBytes), to_bin(ClearBytes), to_bin(CipherBytes)}, - crypto:blowfish_ecb_encrypt(Key, Clear) =:= Cipher. + ?line m(crypto:blowfish_ecb_encrypt(Key, Clear), Cipher), + true. ecb(doc) -> "Test that ECB mode is OK"; @@ -208,3 +209,5 @@ to_bin([], Acc) -> iolist_to_binary(lists:reverse(Acc)); to_bin([C1, C2 | Rest], Acc) -> to_bin(Rest, [(dehex(C1) bsl 4) bor dehex(C2) | Acc]). + +m(X,X) -> ok. diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index 290ef19160..06b284d50d 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% -module(crypto_SUITE). @@ -40,6 +40,7 @@ md5_mac_io/1, des_cbc/1, des_cbc_iter/1, + des_ecb/1, aes_cfb/1, aes_cbc/1, aes_cbc_iter/1, @@ -53,6 +54,7 @@ dh/1, exor_test/1, rc4_test/1, + rc4_stream_test/1, blowfish_cfb64/1, smp/1, cleanup/1]). @@ -78,6 +80,7 @@ all(suite) -> aes_cbc, aes_cbc_iter, des_cbc_iter, + des_ecb, rand_uniform_test, rsa_verify_test, dsa_verify_test, @@ -87,6 +90,7 @@ all(suite) -> dh, exor_test, rc4_test, + rc4_stream_test, mod_exp_test, blowfish_cfb64, smp], @@ -117,7 +121,7 @@ link_test(Config) when is_list(Config) -> link_test_1() -> ?line CryptoPriv = code:priv_dir(crypto), - ?line Wc = filename:join([CryptoPriv,"lib","crypto_drv.*"]), + ?line Wc = filename:join([CryptoPriv,"lib","crypto.*"]), ?line case filelib:wildcard(Wc) of [] -> {skip,"Didn't find the crypto driver"}; [Drv] -> link_test_2(Drv) @@ -439,12 +443,34 @@ des_cbc_iter(Config) when is_list(Config) -> ?line Cipher1 = crypto:des_cbc_encrypt(Key, IVec, Plain1), ?line IVec2 = crypto:des_cbc_ivec(Cipher1), ?line Cipher2 = crypto:des_cbc_encrypt(Key, IVec2, Plain2), - ?line Cipher = concat_binary([Cipher1, Cipher2]), + ?line Cipher = list_to_binary([Cipher1, Cipher2]), ?line m(Cipher, hexstr2bin("e5c7cdde872bf27c43e934008c389c" "0f683788499a7c05f6")). %% %% +des_ecb(doc) -> + "Encrypt and decrypt according to ECB DES and check the result. " + "Example are from FIPS-81."; +des_ecb(suite) -> + []; +des_ecb(Config) when is_list(Config) -> + ?line Key = hexstr2bin("0123456789abcdef"), + ?line Cipher1 = crypto:des_ecb_encrypt(Key, "Now is t"), + ?line m(Cipher1, hexstr2bin("3fa40e8a984d4815")), + ?line Cipher2 = crypto:des_ecb_encrypt(Key, "he time "), + ?line m(Cipher2, hexstr2bin("6a271787ab8883f9")), + ?line Cipher3 = crypto:des_ecb_encrypt(Key, "for all "), + ?line m(Cipher3, hexstr2bin("893d51ec4b563b53")), + ?line Cipher4 = crypto:des_ecb_decrypt(Key, hexstr2bin("3fa40e8a984d4815")), + ?line m(Cipher4, <<"Now is t">>), + ?line Cipher5 = crypto:des_ecb_decrypt(Key, hexstr2bin("6a271787ab8883f9")), + ?line m(Cipher5, <<"he time ">>), + ?line Cipher6 = crypto:des_ecb_decrypt(Key, hexstr2bin("893d51ec4b563b53")), + ?line m(Cipher6, <<"for all ">>). + +%% +%% aes_cfb(doc) -> "Encrypt and decrypt according to AES CFB 128 bit and check " "the result. Example are from NIST SP 800-38A."; @@ -746,18 +772,18 @@ dsa_verify_test(Config) when is_list(Config) -> crypto:mpint(Key) ], - ?line m(crypto:dss_verify(sized_binary(Msg), sized_binary(SigBlob), + ?line m(my_dss_verify(sized_binary(Msg), sized_binary(SigBlob), ValidKey), true), BadMsg = one_bit_wrong(Msg), - ?line m(crypto:dss_verify(sized_binary(BadMsg), sized_binary(SigBlob), + ?line m(my_dss_verify(sized_binary(BadMsg), sized_binary(SigBlob), ValidKey), false), BadSig = one_bit_wrong(SigBlob), - ?line m(crypto:dss_verify(sized_binary(Msg), sized_binary(BadSig), + ?line m(my_dss_verify(sized_binary(Msg), sized_binary(BadSig), ValidKey), false), SizeErr = size(SigBlob) - 13, - BadArg = (catch crypto:dss_verify(sized_binary(Msg), <<SizeErr:32, SigBlob/binary>>, + BadArg = (catch my_dss_verify(sized_binary(Msg), <<SizeErr:32, SigBlob/binary>>, ValidKey)), ?line m(element(1,element(2,BadArg)), badarg), @@ -767,9 +793,12 @@ dsa_verify_test(Config) when is_list(Config) -> crypto:mpint(Key+17) ], - ?line m(crypto:dss_verify(sized_binary(Msg), sized_binary(SigBlob), + ?line m(my_dss_verify(sized_binary(Msg), sized_binary(SigBlob), InValidKey), false). + +one_bit_wrong(List) when is_list(List) -> + lists:map(fun(Bin) -> one_bit_wrong(Bin) end, List); one_bit_wrong(Bin) -> Half = size(Bin) div 2, <<First:Half/binary, Byte:8, Last/binary>> = Bin, @@ -819,16 +848,16 @@ dsa_sign_test(Config) when is_list(Config) -> ParamG = 18320614775012672475365915366944922415598782131828709277168615511695849821411624805195787607930033958243224786899641459701930253094446221381818858674389863050420226114787005820357372837321561754462061849169568607689530279303056075793886577588606958623645901271866346406773590024901668622321064384483571751669, Params = [crypto:mpint(ParamP), crypto:mpint(ParamQ), crypto:mpint(ParamG)], - ?line Sig1 = crypto:dss_sign(sized_binary(Msg), [Params, crypto:mpint(PrivKey)]), + ?line Sig1 = my_dss_sign(sized_binary(Msg), Params ++ [crypto:mpint(PrivKey)]), - ?line m(crypto:dss_verify(sized_binary(Msg), sized_binary(Sig1), - [Params, crypto:mpint(PubKey)]), true), + ?line m(my_dss_verify(sized_binary(Msg), Sig1, + Params ++ [crypto:mpint(PubKey)]), true), - ?line m(crypto:dss_verify(sized_binary(one_bit_wrong(Msg)), sized_binary(Sig1), - [Params, crypto:mpint(PubKey)]), false), + ?line m(my_dss_verify(sized_binary(one_bit_wrong(Msg)), Sig1, + Params ++ [crypto:mpint(PubKey)]), false), - ?line m(crypto:dss_verify(sized_binary(Msg), sized_binary(one_bit_wrong(Sig1)), - [Params, crypto:mpint(PubKey)]), false), + ?line m(my_dss_verify(sized_binary(Msg), one_bit_wrong(Sig1), + Params ++ [crypto:mpint(PubKey)]), false), %%?line Bad = crypto:dss_sign(sized_binary(Msg), [Params, crypto:mpint(PubKey)]), @@ -952,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) -> @@ -1002,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]), @@ -1108,3 +1152,24 @@ zero_bin(N) when is_integer(N) -> <<0:N8/integer>>; zero_bin(B) when is_binary(B) -> zero_bin(size(B)). + +my_dss_verify(Data,[Sign|Tail],Key) -> + Res = my_dss_verify(Data,sized_binary(Sign),Key), + case Tail of + [] -> Res; + _ -> ?line Res = my_dss_verify(Data,Tail,Key) + end; +my_dss_verify(Data,Sign,Key) -> + ?line Res = crypto:dss_verify(Data, Sign, Key), + ?line Res = crypto:dss_verify(sha, Data, Sign, Key), + ?line <<_:32,Raw/binary>> = Data, + ?line Res = crypto:dss_verify(none, crypto:sha(Raw), Sign, Key), + Res. + +my_dss_sign(Data,Key) -> + ?line S1 = crypto:dss_sign(Data, Key), + ?line S2 = crypto:dss_sign(sha, Data, Key), + ?line <<_:32,Raw/binary>> = Data, + ?line S3 = crypto:dss_sign(none, crypto:sha(Raw), Key), + [S1,S2,S3]. + diff --git a/lib/crypto/vsn.mk b/lib/crypto/vsn.mk index 68eecfe759..e3549f0c50 100644 --- a/lib/crypto/vsn.mk +++ b/lib/crypto/vsn.mk @@ -1 +1 @@ -CRYPTO_VSN = 1.6.4 +CRYPTO_VSN = 2.0.1 diff --git a/lib/debugger/doc/src/notes.xml b/lib/debugger/doc/src/notes.xml index afd49e8593..c72a5271ba 100644 --- a/lib/debugger/doc/src/notes.xml +++ b/lib/debugger/doc/src/notes.xml @@ -32,6 +32,46 @@ <p>This document describes the changes made to the Debugger application.</p> +<section><title>Debugger 3.2.4</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Type specs have been added/cleaned up. (Thanks to Kostis + Sagonas.)</p> + <p> + Own Id: OTP-8757</p> + </item> + </list> + </section> + +</section> + +<section><title>Debugger 3.2.3</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Warnings due to new autoimported BIFs removed</p> + <p> + Own Id: OTP-8674 Aux Id: OTP-8579 </p> + </item> + <item> + <p> + The predefined builtin type tid() has been removed. + Instead, ets:tid() should be used.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-8687</p> + </item> + </list> + </section> + +</section> + <section><title>Debugger 3.2.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/debugger/src/dbg_debugged.erl b/lib/debugger/src/dbg_debugged.erl index b56ebef14a..3732c40c73 100644 --- a/lib/debugger/src/dbg_debugged.erl +++ b/lib/debugger/src/dbg_debugged.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% Copyright Ericsson AB 1998-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 @@ -19,6 +19,8 @@ -module(dbg_debugged). %% External exports +%% Avoid warning for local function demonitor/1 clashing with autoimported BIF. +-compile({no_auto_import,[demonitor/1]}). -export([eval/3]). %%==================================================================== diff --git a/lib/debugger/src/dbg_icmd.erl b/lib/debugger/src/dbg_icmd.erl index 7ccb9793a3..a26b16c82d 100644 --- a/lib/debugger/src/dbg_icmd.erl +++ b/lib/debugger/src/dbg_icmd.erl @@ -94,7 +94,7 @@ break_p(Mod, Line, Le, Bs) -> Bool = case Cond of null -> true; {CM, CN} -> - try apply(CM, CN, [Bs]) of + try CM:CN(Bs) of true -> true; false -> false; _Term -> false @@ -245,7 +245,7 @@ handle_int_msg({attached, AttPid}, Status, _Bs, %% Tell attached process in which module evalution is located if - Le==1 -> + Le =:= 1 -> tell_attached({attached, undefined, -1, get(trace)}); true -> tell_attached({attached, M, Line, get(trace)}), @@ -269,7 +269,7 @@ handle_int_msg(detached, _Status, _Bs, _Ieval) -> handle_int_msg({old_code,Mod}, Status, Bs, #ieval{level=Le,module=M}=Ieval) -> if - Status==idle, Le==1 -> + Status =:= idle, Le =:= 1 -> erase([Mod|db]), put(cache, []); true -> @@ -352,9 +352,9 @@ set_stack_trace(true) -> set_stack_trace(all); set_stack_trace(Flag) -> if - Flag==false -> + Flag =:= false -> put(stack, []); - Flag==no_tail; Flag==all -> + Flag =:= no_tail; Flag =:= all -> ignore end, put(trace_stack, Flag), @@ -367,7 +367,7 @@ bindings(Bs, nostack) -> Bs; bindings(Bs, SP) -> case dbg_ieval:stack_level() of - Le when SP>Le -> + Le when SP > Le -> Bs; _ -> dbg_ieval:bindings(SP) @@ -377,7 +377,6 @@ messages() -> {messages, Msgs} = erlang:process_info(get(self), messages), Msgs. - %%==================================================================== %% Evaluating expressions within process context %%==================================================================== @@ -398,7 +397,7 @@ eval_restricted({From,_Mod,Cmd,SP}, Bs) -> From ! {self(), {eval_rsp, Rsp}} end. -eval_nonrestricted({From,Mod,Cmd,SP}, Bs, #ieval{level=Le}) when SP<Le-> +eval_nonrestricted({From,Mod,Cmd,SP}, Bs, #ieval{level=Le}) when SP < Le-> %% Evaluate in stack eval_restricted({From, Mod, Cmd, SP}, Bs), Bs; @@ -424,15 +423,15 @@ eval_nonrestricted({From, _Mod, Cmd, _SP}, Bs, eval_nonrestricted_1({match,_,{var,_,Var},Expr}, Bs, Ieval) -> {value,Res,Bs2} = dbg_ieval:eval_expr(Expr, Bs, Ieval#ieval{last_call=false}), - Bs3 = case lists:keysearch(Var, 1, Bs) of - {value, {Var,_Value}} -> + Bs3 = case lists:keyfind(Var, 1, Bs) of + {Var,_Value} -> lists:keyreplace(Var, 1, Bs2, {Var,Res}); false -> [{Var,Res} | Bs2] end, {Res,Bs3}; eval_nonrestricted_1({var,_,Var}, Bs, _Ieval) -> - Res = case lists:keysearch(Var, 1, Bs) of - {value, {Var, Value}} -> Value; + Res = case lists:keyfind(Var, 1, Bs) of + {Var, Value} -> Value; false -> unbound end, {Res,Bs}; @@ -458,7 +457,6 @@ parse_cmd(Cmd, LineNo) -> {ok,Forms} = erl_parse:parse_exprs(Tokens), Forms. - %%==================================================================== %% Library functions for attached process handling %%==================================================================== @@ -470,13 +468,12 @@ tell_attached(Msg) -> AttPid ! {self(), Msg} end. - %%==================================================================== %% get_binding/2 %%==================================================================== get_binding(Var, Bs) -> - case lists:keysearch(Var, 1, Bs) of - {value, {Var, Value}} -> {value, Value}; + case lists:keyfind(Var, 1, Bs) of + {Var, Value} -> {value, Value}; false -> unbound end. diff --git a/lib/debugger/src/dbg_ieval.erl b/lib/debugger/src/dbg_ieval.erl index c13fda7ac1..476dfd8796 100644 --- a/lib/debugger/src/dbg_ieval.erl +++ b/lib/debugger/src/dbg_ieval.erl @@ -120,9 +120,9 @@ check_exit_msg({'EXIT', Int, Reason}, _Bs, #ieval{level=Le}) -> %% This *must* be interpreter which has terminated, %% we are not linked to anyone else if - Le==1 -> + Le =:= 1 -> exit(Reason); - Le>1 -> + Le > 1 -> exit({Int, Reason}) end; check_exit_msg({'DOWN',_,_,_,Reason}, Bs, @@ -139,9 +139,9 @@ check_exit_msg({'DOWN',_,_,_,Reason}, Bs, %% importance in this case %% If we don't save them, however, post-mortem analysis %% of the process isn't possible - undefined when Le==1 -> % died outside interpreted code + undefined when Le =:= 1 -> % died outside interpreted code {}; - undefined when Le>1 -> + undefined when Le > 1 -> StackBin = term_to_binary(get(stack)), {{Mod, Li}, Bs, StackBin}; @@ -152,9 +152,9 @@ check_exit_msg({'DOWN',_,_,_,Reason}, Bs, dbg_iserver:cast(get(int), {set_exit_info,self(),ExitInfo}), if - Le==1 -> + Le =:= 1 -> exit(Reason); - Le>1 -> + Le > 1 -> exit({get(self), Reason}) end; check_exit_msg(_Msg, _Bs, _Ieval) -> @@ -271,7 +271,7 @@ meta_loop(Debugged, Bs, #ieval{level=Le} = Ieval) -> end; %% Re-entry to Meta from non-interpreted code - {re_entry, Debugged, {eval,{M,F,As}}} when Le==1 -> + {re_entry, Debugged, {eval,{M,F,As}}} when Le =:= 1 -> %% Reset process dictionary %% This is really only necessary if the process left %% interpreted code at a call level > 1 @@ -346,7 +346,7 @@ push(MFA, Bs, #ieval{level=Le,module=Cm,line=Li,last_call=Lc}) -> [] -> put(stack, [Entry]); [_Entry|Entries] -> put(stack, [Entry|Entries]) end; - _ -> % all | no_tail when Lc==false + _ -> % all | no_tail when Lc =:= false put(stack, [Entry|get(stack)]) end. @@ -413,10 +413,10 @@ sublist(L, Start, Length) -> lists:sublist(L, Start, Length). fix_stacktrace2([{_,{{M,F,As1},_,_}}, {_,{{M,F,As2},_,_}}|_]) - when length(As1)==length(As2) -> + when length(As1) =:= length(As2) -> [{M,F,As1}]; fix_stacktrace2([{_,{{Fun,As1},_,_}}, {_,{{Fun,As2},_,_}}|_]) - when length(As1)==length(As2) -> + when length(As1) =:= length(As2) -> [{Fun,As1}]; fix_stacktrace2([{_,{MFA,_,_}}|Entries]) -> [MFA|fix_stacktrace2(Entries)]; @@ -465,9 +465,9 @@ stack_frame(SP, Dir, [{SP, _}|Stack]) -> case Stack of [{Le, {_MFA,Where,Bs}}|_] -> {Le, Where, Bs}; - [] when Dir==up -> + [] when Dir =:= up -> top; - [] when Dir==down -> + [] when Dir =:= down -> bottom end; stack_frame(SP, Dir, [_Entry|Stack]) -> @@ -509,7 +509,7 @@ trace(What, Args, true) -> end, io_lib:format(" (~w) receive " ++ Tail, [Le]); - received when Args==null -> + received when Args =:= null -> io_lib:format("~n", []); received -> % Args=Msg io_lib:format("~n<== ~p~n", [Args]); @@ -586,8 +586,8 @@ eval_mfa(Debugged, M, F, As, Ieval) -> end. eval_function(Mod, Fun, As0, Bs0, _Called, Ieval) when is_function(Fun); - Mod==?MODULE, - Fun==eval_fun -> + Mod =:= ?MODULE, + Fun =:= eval_fun -> #ieval{level=Le, line=Li, last_call=Lc} = Ieval, case lambda(Fun, As0) of {Cs,Module,Name,As,Bs} -> @@ -657,7 +657,7 @@ eval_function(Mod, Name, As0, Bs0, Called, Ieval) -> lambda(eval_fun, [Cs,As,Bs,{Mod,Name}=F]) -> %% Fun defined in interpreted code, called from outside if - length(element(3,hd(Cs))) == length(As) -> + length(element(3,hd(Cs))) =:= length(As) -> db_ref(Mod), %% Adds ref between module and process {Cs,Mod,Name,As,Bs}; true -> @@ -672,7 +672,7 @@ lambda(Fun, As) when is_function(Fun) -> {env, [{Mod,Name},Bs,Cs]} = erlang:fun_info(Fun, env), {arity, Arity} = erlang:fun_info(Fun, arity), if - length(As) == Arity -> + length(As) =:= Arity -> db_ref(Mod), %% Adds ref between module and process {Cs,Mod,Name,As,Bs}; true -> @@ -731,7 +731,7 @@ db_ref(Mod) -> ModDb -> Node = node(get(int)), DbRef = if - Node/=node() -> {Node,ModDb}; + Node =/= node() -> {Node,ModDb}; true -> ModDb end, put([Mod|db], DbRef), @@ -741,13 +741,12 @@ db_ref(Mod) -> DbRef end. - cache(Key, Data) -> put(cache, lists:sublist([{Key,Data}|get(cache)], 5)). cached(Key) -> - case lists:keysearch(Key, 1, get(cache)) of - {value,{Key,Data}} -> Data; + case lists:keyfind(Key, 1, get(cache)) of + {Key,Data} -> Data; false -> false end. @@ -844,7 +843,7 @@ expr({'try',Line,Es,CaseCs,CatchCs,[]}, Bs0, Ieval0) -> case_clauses(Val, CaseCs, Bs, try_clause, Ieval) end catch - Class:Reason when CatchCs=/=[] -> + Class:Reason when CatchCs =/= [] -> catch_clauses({Class,Reason,[]}, CatchCs, Bs0, Ieval) end; expr({'try',Line,Es,CaseCs,CatchCs,As}, Bs0, Ieval0) -> @@ -1498,10 +1497,7 @@ guard(Gs, Bs) -> or_guard(Gs, Bs). or_guard([G|Gs], Bs) -> %% Short-circuit OR. - case and_guard(G, Bs) of - true -> true; - false -> or_guard(Gs, Bs) - end; + and_guard(G, Bs) orelse or_guard(Gs, Bs); or_guard([], _) -> false. and_guard([G|Gs], Bs) -> @@ -1598,8 +1594,7 @@ match1({bin,_,Fs}, B, Bs0, BBs0) when is_bitstring(B) -> try eval_bits:match_bits(Fs, B, Bs1, BBs, fun(L, R, Bs) -> match1(L, R, Bs, BBs) end, fun(E, Bs) -> expr(E, Bs, #ieval{}) end, - false) of - Match -> Match + false) catch _:_ -> throw(nomatch) end; @@ -1687,7 +1682,7 @@ merge_bindings([{Name,V}|B1s], B2s, Ieval) -> case binding(Name, B2s) of {value,V} -> % Already there, and the same merge_bindings(B1s, B2s, Ieval); - {value,_} when Name=='_' -> % Already there, but anonymous + {value,_} when Name =:= '_' -> % Already there, but anonymous B2s1 = lists:keydelete('_', 1, B2s), [{Name,V}|merge_bindings(B1s, B2s1, Ieval)]; {value,_} -> % Already there, but different => badmatch diff --git a/lib/debugger/src/dbg_iload.erl b/lib/debugger/src/dbg_iload.erl index 1216338006..2ae0c333da 100644 --- a/lib/debugger/src/dbg_iload.erl +++ b/lib/debugger/src/dbg_iload.erl @@ -1,64 +1,60 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1998-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(dbg_iload). -%% External exports -export([load_mod/4]). -%% Internal exports --export([load_mod1/4]). - %%==================================================================== %% External exports %%==================================================================== %%-------------------------------------------------------------------- %% load_mod(Mod, File, Binary, Db) -> {ok, Mod} -%% Mod = atom() +%% Mod = module() %% File = string() Source file (including path) %% Binary = binary() %% Db = ETS identifier %% Load a new module into the database. %% -%% We want the loading of a module to be syncronous so no other +%% We want the loading of a module to be synchronous so that no other %% process tries to interpret code in a module not being completely %% loaded. This is achieved as this function is called from %% dbg_iserver. We are suspended until the module has been loaded. %%-------------------------------------------------------------------- +-spec load_mod(Mod, file:filename(), binary(), ets:tid()) -> + {'ok', Mod} when is_subtype(Mod, atom()). + load_mod(Mod, File, Binary, Db) -> Flag = process_flag(trap_exit, true), - Pid = spawn_link(?MODULE, load_mod1, [Mod, File, Binary, Db]), + Pid = spawn_link(fun () -> load_mod1(Mod, File, Binary, Db) end), receive {'EXIT', Pid, What} -> process_flag(trap_exit, Flag), What end. -%%==================================================================== -%% Internal exports -%%==================================================================== +-spec load_mod1(atom(), file:filename(), binary(), ets:tid()) -> no_return(). load_mod1(Mod, File, Binary, Db) -> store_module(Mod, File, Binary, Db), exit({ok, Mod}). - %%==================================================================== %% Internal functions %%==================================================================== @@ -84,7 +80,7 @@ store_module(Mod, File, Binary, Db) -> Attr = store_forms(Forms, Mod, Db, Exp, []), erase(mod_md5), erase(current_function), -% store_funs(Db, Mod), + %% store_funs(Db, Mod), erase(vcount), erase(funs), erase(fun_count), @@ -412,8 +408,7 @@ expr({call,Line,{remote,_,{atom,_,erlang},{atom,_,fault}},[_]=As}) -> {dbg,Line,fault,expr_list(As)}; expr({call,Line,{remote,_,{atom,_,erlang},{atom,_,exit}},[_]=As}) -> {dbg,Line,exit,expr_list(As)}; -expr({call,Line,{remote,_,{atom,_,erlang},{atom,_,apply}},As0}) - when length(As0) == 3 -> +expr({call,Line,{remote,_,{atom,_,erlang},{atom,_,apply}},[_,_,_]=As0}) -> As = expr_list(As0), {apply,Line,As}; expr({call,Line,{remote,_,{atom,_,Mod},{atom,_,Func}},As0}) -> @@ -521,15 +516,9 @@ expr(Other) -> %% here as sys_pre_expand has transformed source. is_guard_test({op,_,Op,L,R}) -> - case erl_internal:comp_op(Op, 2) of - true -> is_gexpr_list([L,R]); - false -> false - end; + erl_internal:comp_op(Op, 2) andalso is_gexpr_list([L,R]); is_guard_test({call,_,{remote,_,{atom,_,erlang},{atom,_,Test}},As}) -> - case erl_internal:type_test(Test, length(As)) of - true -> is_gexpr_list(As); - false -> false - end; + erl_internal:type_test(Test, length(As)) andalso is_gexpr_list(As); is_guard_test({atom,_,true}) -> true; is_guard_test(_) -> false. @@ -546,22 +535,12 @@ is_gexpr({call,_,{remote,_,{atom,_,erlang},{atom,_,F}},As}) -> Ar = length(As), case erl_internal:guard_bif(F, Ar) of true -> is_gexpr_list(As); - false -> - case erl_internal:arith_op(F, Ar) of - true -> is_gexpr_list(As); - false -> false - end + false -> erl_internal:arith_op(F, Ar) andalso is_gexpr_list(As) end; is_gexpr({op,_,Op,A}) -> - case erl_internal:arith_op(Op, 1) of - true -> is_gexpr(A); - false -> false - end; + erl_internal:arith_op(Op, 1) andalso is_gexpr(A); is_gexpr({op,_,Op,A1,A2}) -> - case erl_internal:arith_op(Op, 2) of - true -> is_gexpr_list([A1,A2]); - false -> false - end; + erl_internal:arith_op(Op, 2) andalso is_gexpr_list([A1,A2]); is_gexpr(_) -> false. is_gexpr_list(Es) -> lists:all(fun (E) -> is_gexpr(E) end, Es). diff --git a/lib/debugger/src/dbg_iserver.erl b/lib/debugger/src/dbg_iserver.erl index 4c1e9ccb7b..59188d83a2 100644 --- a/lib/debugger/src/dbg_iserver.erl +++ b/lib/debugger/src/dbg_iserver.erl @@ -155,11 +155,8 @@ handle_call(get_stack_trace, _From, State) -> %% Retrieving information handle_call(snapshot, _From, State) -> - Reply = lists:map(fun(Proc) -> - {Proc#proc.pid, Proc#proc.function, - Proc#proc.status, Proc#proc.info} - end, - State#state.procs), + Reply = [{Proc#proc.pid, Proc#proc.function, + Proc#proc.status, Proc#proc.info} || Proc <- State#state.procs], {reply, Reply, State}; handle_call({get_meta, Pid}, _From, State) -> Reply = case get_proc({pid, Pid}, State#state.procs) of @@ -181,21 +178,21 @@ handle_call({get_attpid, Pid}, _From, State) -> %% Breakpoint handling handle_call({new_break, Point, Options}, _From, State) -> - case lists:keysearch(Point, 1, State#state.breaks) of + case lists:keymember(Point, 1, State#state.breaks) of false -> Break = {Point, Options}, send_all([subscriber, meta, attached], {new_break, Break}, State), Breaks = keyinsert(Break, 1, State#state.breaks), {reply, ok, State#state{breaks=Breaks}}; - {value, _Break} -> + true -> {reply, {error, break_exists}, State} end; handle_call(all_breaks, _From, State) -> {reply, State#state.breaks, State}; handle_call({all_breaks, Mod}, _From, State) -> Reply = lists:filter(fun({{M,_L}, _Options}) -> - if M==Mod -> true; true -> false end + M =/= Mod end, State#state.breaks), {reply, Reply, State}; @@ -276,7 +273,7 @@ handle_call({contents, Mod, Pid}, _From, State) -> Db = State#state.db, [{{Mod, refs}, ModDbs}] = ets:lookup(Db, {Mod, refs}), ModDb = if - Pid==any -> hd(ModDbs); + Pid =:= any -> hd(ModDbs); true -> lists:foldl(fun(T, not_found) -> [{T, Pids}] = ets:lookup(Db, T), @@ -295,7 +292,7 @@ handle_call({raw_contents, Mod, Pid}, _From, State) -> Db = State#state.db, [{{Mod, refs}, ModDbs}] = ets:lookup(Db, {Mod, refs}), ModDb = if - Pid==any -> hd(ModDbs); + Pid =:= any -> hd(ModDbs); true -> lists:foldl(fun(T, not_found) -> [{T, Pids}] = ets:lookup(Db, T), @@ -360,15 +357,15 @@ handle_cast({set_stack_trace, Flag}, State) -> %% Retrieving information handle_cast(clear, State) -> Procs = lists:filter(fun(#proc{status=Status}) -> - if Status==exit -> false; true -> true end + Status =/= exit end, State#state.procs), {noreply, State#state{procs=Procs}}; %% Breakpoint handling handle_cast({delete_break, Point}, State) -> - case lists:keysearch(Point, 1, State#state.breaks) of - {value, _Break} -> + case lists:keymember(Point, 1, State#state.breaks) of + true -> send_all([subscriber, meta, attached], {delete_break, Point}, State), Breaks = lists:keydelete(Point, 1, State#state.breaks), @@ -377,8 +374,8 @@ handle_cast({delete_break, Point}, State) -> {noreply, State} end; handle_cast({break_option, Point, Option, Value}, State) -> - case lists:keysearch(Point, 1, State#state.breaks) of - {value, {Point, Options}} -> + case lists:keyfind(Point, 1, State#state.breaks) of + {Point, Options} -> N = case Option of status -> 1; action -> 2; @@ -399,7 +396,7 @@ handle_cast(no_break, State) -> handle_cast({no_break, Mod}, State) -> send_all([subscriber, meta, attached], {no_break, Mod}, State), Breaks = lists:filter(fun({{M, _L}, _O}) -> - if M==Mod -> false; true -> true end + M =/= Mod end, State#state.breaks), {noreply, State#state{breaks=Breaks}}; @@ -409,7 +406,7 @@ handle_cast({set_status, Meta, Status, Info}, State) -> {true, Proc} = get_proc({meta, Meta}, State#state.procs), send_all(subscriber, {new_status, Proc#proc.pid, Status, Info}, State), if - Status==break -> + Status =:= break -> auto_attach(break, State#state.auto, Proc); true -> ignore end, @@ -526,11 +523,10 @@ code_change(_OldVsn, State, _Extra) -> %% Internal functions %%==================================================================== -auto_attach(Why, Auto, Proc) when is_record(Proc, proc) -> - case Proc#proc.attpid of - AttPid when is_pid(AttPid) -> ignore; - undefined -> - auto_attach(Why, Auto, Proc#proc.pid) +auto_attach(Why, Auto, #proc{attpid = Attpid, pid = Pid}) -> + case Attpid of + undefined -> auto_attach(Why, Auto, Pid); + _ when is_pid(Attpid) -> ignore end; auto_attach(Why, Auto, Pid) when is_pid(Pid) -> case Auto of @@ -545,7 +541,7 @@ auto_attach(Why, Auto, Pid) when is_pid(Pid) -> keyinsert(Tuple1, N, [Tuple2|Tuples]) -> if - element(N, Tuple1)<element(N, Tuple2) -> + element(N, Tuple1) < element(N, Tuple2) -> [Tuple1, Tuple2|Tuples]; true -> [Tuple2 | keyinsert(Tuple1, N, Tuples)] @@ -576,7 +572,7 @@ send_all([], _Msg, _State) -> ok; send_all(subscriber, Msg, State) -> send_all(State#state.subs, Msg); send_all(meta, Msg, State) -> - Metas = lists:map(fun(Proc) -> Proc#proc.meta end, State#state.procs), + Metas = [Proc#proc.meta || Proc <- State#state.procs], send_all(Metas, Msg); send_all(attached, Msg, State) -> AttPids= mapfilter(fun(Proc) -> @@ -600,7 +596,7 @@ get_proc({Type, Pid}, Procs) -> meta -> #proc.meta; attpid -> #proc.attpid end, - case lists:keysearch(Pid, Index, Procs) of - {value, Proc} -> {true, Proc}; - false -> false + case lists:keyfind(Pid, Index, Procs) of + false -> false; + Proc -> {true, Proc} end. diff --git a/lib/debugger/src/dbg_ui_break_win.erl b/lib/debugger/src/dbg_ui_break_win.erl index a56fe36828..0c1e25e703 100644 --- a/lib/debugger/src/dbg_ui_break_win.erl +++ b/lib/debugger/src/dbg_ui_break_win.erl @@ -268,12 +268,7 @@ handle_event({gs, _Id, click, _Data, ["Ok"|_]}, WinInfo) -> IndexL -> Funcs = WinInfo#winInfo.funcs, Breaks = - lists:map(fun(Index) -> - Func = lists:nth(Index+1, - Funcs), - [Mod | Func] - end, - IndexL), + [[Mod|lists:nth(Index+1, Funcs)] || Index <- IndexL], {break, Breaks, enable} end end; diff --git a/lib/debugger/src/dbg_ui_filedialog_win.erl b/lib/debugger/src/dbg_ui_filedialog_win.erl index f7d76076a5..79ccf20946 100644 --- a/lib/debugger/src/dbg_ui_filedialog_win.erl +++ b/lib/debugger/src/dbg_ui_filedialog_win.erl @@ -202,8 +202,7 @@ handle_event({gs, 'Files', doubleclick, _Data, _Arg}, WinInfo) -> handle_event({gs, _Id, click, select, _Arg}, _WinInfo) -> {select, gs:read('Selection', text)}; handle_event({gs, _Id, click, multiselect, _Arg}, WinInfo) -> - Files = lists:map(fun(File) -> untag(File) end, - gs:read('Files', items)), + Files = [untag(File) || File <- gs:read('Files', items)], {multiselect, WinInfo#winInfo.cwd, Files}; handle_event({gs, _Id, click, filter, _Arg}, WinInfo) -> {Cwd, Pattern} = update_win(gs:read('Filter', text), @@ -286,7 +285,7 @@ max_existing([Name | Names]) -> max_existing(Dir, [Name | Names]) -> Dir2 = filename:join(Dir, Name), case filelib:is_file(Dir2, erl_prim_loader) of - true when Names==[] -> {Dir2, []}; + true when Names =:= [] -> {Dir2, []}; true -> max_existing(Dir2, Names); false -> {Dir, [Name | Names]} end. @@ -309,11 +308,8 @@ extra_filter([], _Dir, _Fun) -> []. get_subdirs(Dir) -> case erl_prim_loader:list_dir(Dir) of {ok, FileNames} -> - X = lists:filter(fun(FileName) -> - File = filename:join(Dir, FileName), - filelib:is_dir(File, erl_prim_loader) - end, - FileNames), + X = [FN || FN <- FileNames, + filelib:is_dir(filename:join(Dir, FN), erl_prim_loader)], lists:sort(X); _Error -> [] @@ -335,4 +331,3 @@ compare([], [$/|File]) -> File; compare(_, _) -> error. - diff --git a/lib/debugger/src/dbg_ui_mon.erl b/lib/debugger/src/dbg_ui_mon.erl index 8888075124..82fe210968 100644 --- a/lib/debugger/src/dbg_ui_mon.erl +++ b/lib/debugger/src/dbg_ui_mon.erl @@ -162,7 +162,7 @@ init2(CallingPid, Mode, SFile, GS) -> CallingPid ! {initialization_complete, self()}, if - SFile==default -> + SFile =:= default -> loop(State3); true -> loop(load_settings(SFile, State3)) @@ -226,7 +226,7 @@ loop(State) -> gui_cmd(stopped, State); %% From the GUI - GuiEvent when is_tuple(GuiEvent), element(1, GuiEvent)==gs -> + GuiEvent when is_tuple(GuiEvent), element(1, GuiEvent) =:= gs -> Cmd = dbg_ui_mon_win:handle_event(GuiEvent,State#state.win), State2 = gui_cmd(Cmd, State), loop(State2); @@ -269,7 +269,7 @@ gui_cmd(ignore, State) -> State; gui_cmd(stopped, State) -> if - State#state.starter==true -> int:stop(); + State#state.starter =:= true -> int:stop(); true -> int:auto_attach(false) end, exit(stop); @@ -413,9 +413,9 @@ gui_cmd({'Trace Window', TraceWin}, State) -> State2; gui_cmd({'Auto Attach', When}, State) -> if - When==[] -> int:auto_attach(false); + When =:= [] -> int:auto_attach(false); true -> - Flags = lists:map(fun(Name) -> map(Name) end, When), + Flags = [map(Name) || Name <- When], int:auto_attach(Flags, trace_function(State)) end, State; @@ -676,7 +676,7 @@ load_settings2(Settings, State) -> Break, int:break(Mod, Line), if - Status==inactive -> + Status =:= inactive -> int:disable_break(Mod, Line); true -> ignore end, @@ -700,12 +700,8 @@ save_settings(SFile, State) -> int:auto_attach(), int:stack_trace(), State#state.backtrace, - lists:map(fun(Mod) -> - int:file(Mod) - end, - int:interpreted()), + [int:file(Mod) || Mod <- int:interpreted()], int:all_breaks()}, - Binary = term_to_binary({debugger_settings, Settings}), case file:write_file(SFile, Binary) of ok -> @@ -720,13 +716,12 @@ save_settings(SFile, State) -> %%==================================================================== registered_name(Pid) -> - %% Yield in order to give Pid more time to register its name timer:sleep(200), Node = node(Pid), if - Node==node() -> + Node =:= node() -> case erlang:process_info(Pid, registered_name) of {registered_name, Name} -> Name; _ -> undefined diff --git a/lib/debugger/src/dbg_ui_mon_win.erl b/lib/debugger/src/dbg_ui_mon_win.erl index ba2f94c550..66e59a822a 100644 --- a/lib/debugger/src/dbg_ui_mon_win.erl +++ b/lib/debugger/src/dbg_ui_mon_win.erl @@ -224,8 +224,7 @@ select(MenuItem, Bool) -> %%-------------------------------------------------------------------- add_module(WinInfo, Menu, Mod) -> Modules = WinInfo#winInfo.modules, - case lists:keysearch(Mod, #moduleInfo.module, Modules) of - {value, _ModInfo} -> WinInfo; + case lists:keymember(Mod, #moduleInfo.module, Modules) of false -> %% Create a menu for the module Font = dbg_ui_win:font(normal), @@ -244,7 +243,8 @@ add_module(WinInfo, Menu, Mod) -> gs:config(WinInfo#winInfo.listbox, {add, Mod}), ModInfo = #moduleInfo{module=Mod, menubtn=MenuBtn}, - WinInfo#winInfo{modules=[ModInfo | Modules]} + WinInfo#winInfo{modules=[ModInfo | Modules]}; + true -> WinInfo end. %%-------------------------------------------------------------------- @@ -491,14 +491,13 @@ handle_event({gs, _Id, click, autoattach, _Arg}, WinInfo) -> %% Process grid handle_event({gs, _Id, keypress, _Data, [Key|_]}, WinInfo) when - Key=='Up'; Key=='Down' -> - Dir = if Key=='Up' -> up; Key=='Down' -> down end, + Key =:= 'Up'; Key =:= 'Down' -> + Dir = if Key =:= 'Up' -> up; Key =:= 'Down' -> down end, Row = move(WinInfo, Dir), - if Row>1 -> WinInfo2 = highlight(WinInfo, Row), - {value, #procInfo{pid=Pid}} = - lists:keysearch(Row, #procInfo.row, WinInfo#winInfo.processes), + #procInfo{pid=Pid} = + lists:keyfind(Row, #procInfo.row, WinInfo#winInfo.processes), {focus, Pid, WinInfo2}; true -> ignore @@ -515,10 +514,9 @@ handle_event(_GSEvent, _WinInfo) -> move(WinInfo, Dir) -> Row = WinInfo#winInfo.focus, Last = WinInfo#winInfo.row, - if - Dir==up, Row>1 -> Row-1; - Dir==down, Row<Last -> Row+1; + Dir =:= up, Row > 1 -> Row-1; + Dir =:= down, Row < Last -> Row+1; true -> Row end. @@ -533,7 +531,6 @@ highlight(WinInfo, Row) -> GridLine2 = gs:read(Grid, {obj_at_row, Row}), gs:config(GridLine2, {fg, white}), WinInfo#winInfo{focus=Row}. - %%==================================================================== %% Internal functions @@ -545,7 +542,7 @@ configure(WinInfo, {W, H}) -> Dx = NewW - gs:read(Grid, width), Dy = H-42 - gs:read(Grid, height), if - (Dx+Dy)=/=0 -> + (Dx+Dy) =/= 0 -> gs:config(Grid, [{width, NewW}, {height, H-30}]), Cols = calc_columnwidths(NewW), gs:config(Grid, Cols); @@ -555,10 +552,9 @@ configure(WinInfo, {W, H}) -> calc_columnwidths(Width) -> W = if - Width=<?Wg -> ?Wg; + Width =< ?Wg -> ?Wg; true -> Width end, - First = lists:map(fun (X) -> round(X) end, - [0.13*W, 0.27*W, 0.18*W, 0.18*W]), + First = [round(X) || X <- [0.13*W, 0.27*W, 0.18*W, 0.18*W]], Last = W - lists:sum(First) - 30, {columnwidths, First++[Last]}. diff --git a/lib/debugger/src/dbg_ui_trace_win.erl b/lib/debugger/src/dbg_ui_trace_win.erl index dbf93c7f45..82d4199630 100644 --- a/lib/debugger/src/dbg_ui_trace_win.erl +++ b/lib/debugger/src/dbg_ui_trace_win.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% %% -module(dbg_ui_trace_win). @@ -106,7 +106,7 @@ create_win(GS, Title, TraceWin, Menus) -> gs:read('CodeArea', height) + gs:read('RB1', height) + gs:read('ButtonArea', height) + - max(gs:read('EvalArea', height), + erlang:max(gs:read('EvalArea', height), gs:read('BindArea', height)) + gs:read('RB2', height) + gs:read('TraceArea', height)}), @@ -147,17 +147,17 @@ configure(WinInfo, TraceWin) -> H = gs:read(Win, height), H2 = if - Bu1==close, Bu2==open -> + Bu1 =:= close, Bu2 =:= open -> resize_button_area(open, width, W-4), gs:config('ButtonArea', {height, 30}), H+30; - Bu1==open, Bu2==close -> + Bu1 =:= open, Bu2 =:= close -> gs:config('ButtonArea', [{width, 0}, {height, 0}]), H-30; true -> H end, H3 = if - Ev1==close, Ev2==open, Bi1==open -> + Ev1 =:= close, Ev2 =:= open, Bi1 =:= open -> Wnew1 = round((W-10-4)/2), % W = window/2 - rb - pads Hbi1 = gs:read('BindArea', height), % H = bind area h resize_eval_area(open, width, Wnew1), @@ -167,25 +167,25 @@ configure(WinInfo, TraceWin) -> resize_bind_area(open, width, Wnew1-gs:read('BindArea', width)), H2; - Ev1==close, Ev2==open, Bi1==close -> + Ev1 =:= close, Ev2 =:= open, Bi1 =:= close -> resize_eval_area(open, width, W-4), resize_eval_area(open, height, 200), H2+200; - Ev1==open, Ev2==close, Bi1==open -> + Ev1 =:= open, Ev2 =:= close, Bi1 =:= open -> gs:config('EvalArea', [{width,0}, {height,0}]), gs:config('RB3', [{width, 0}, {height, 0}]), Wnew2 = W-4, resize_bind_area(open, width, Wnew2-gs:read('BindArea', width)), H2; - Ev1==open, Ev2==close, Bi1==close -> + Ev1 =:= open, Ev2 =:= close, Bi1 =:= close -> Hs1 = gs:read('EvalArea', height), gs:config('EvalArea', [{width, 0}, {height, 0}]), H2-Hs1; true -> H2 end, H4 = if - Bi1==close, Bi2==open, Ev2==open -> + Bi1 =:= close, Bi2 =:= open, Ev2 =:= open -> Wnew3 = round((W-10-4)/2), % W = window/2 - rb - pads Hs2 = gs:read('EvalArea', height), % H = eval area h resize_bind_area(open, width, Wnew3), @@ -194,29 +194,29 @@ configure(WinInfo, TraceWin) -> resize_eval_area(open, width, Wnew3-gs:read('EvalArea', width)), H3; - Bi1==close, Bi2==open, Ev2==close -> + Bi1 =:= close, Bi2 =:= open, Ev2 =:= close -> resize_bind_area(open, width, W-4), resize_bind_area(open, height, 200), H3+200; - Bi1==open, Bi2==close, Ev2==open -> + Bi1 =:= open, Bi2 =:= close, Ev2 =:= open -> gs:config('BindArea', [{width, 0}, {height, 0}]), gs:config('RB3', [{width, 0}, {height, 0}]), Wnew4 = W-4, resize_eval_area(open, width, Wnew4-gs:read('EvalArea', width)), H3; - Bi1==open, Bi2==close, Ev2==close -> + Bi1 =:= open, Bi2 =:= close, Ev2 =:= close -> Hbi2 = gs:read('BindArea', height), gs:config('BindArea', [{width, 0}, {height, 0}]), H3-Hbi2; true -> H3 end, H5 = if - Tr1==close, Tr2==open -> + Tr1 =:= close, Tr2 =:= open -> resize_trace_area(open, width, W-4), resize_trace_area(open, height, 200), H4+200; - Tr1==open, Tr2==close -> + Tr1 =:= open, Tr2 =:= close -> Hf = gs:read('TraceArea', height), gs:config('TraceArea', [{width, 0}, {height, 0}]), H4-Hf; @@ -226,10 +226,10 @@ configure(WinInfo, TraceWin) -> RB1old = rb1(OldFlags), RB1new = rb1(NewFlags), if - RB1old==close, RB1new==open -> + RB1old =:= close, RB1new =:= open -> gs:config('RB1', [{width, W-4}, {height, 10}]), gs:config(Win, {height, gs:read(Win, height)+10}); - RB1old==open, RB1new==close -> + RB1old =:= open, RB1new =:= close -> gs:config('RB1', [{width, 0}, {height, 0}, lower]), gs:config(Win, {height, gs:read(Win, height)-10}); true -> ignore @@ -237,10 +237,10 @@ configure(WinInfo, TraceWin) -> RB2old = rb2(OldFlags), RB2new = rb2(NewFlags), if - RB2old==close, RB2new==open -> + RB2old =:= close, RB2new =:= open -> gs:config('RB2', [{width, W-4}, {height, 10}]), gs:config(Win, {height,gs:read(Win, height)+10}); - RB2old==open, RB2new==close -> + RB2old =:= open, RB2new =:= close -> gs:config('RB2', [{width, 0}, {height, 0}, lower]), gs:config(Win, {height, gs:read(Win, height)-10}); true -> ignore @@ -301,15 +301,15 @@ select(MenuItem, Bool) -> %% Cond = null | {Mod, Func} %%-------------------------------------------------------------------- add_break(WinInfo, Menu, {{Mod,Line},[Status|_Options]}=Break) -> - case lists:keysearch(Mod, 1, WinInfo#winInfo.editors) of - {value, {Mod, Editor}} -> + case lists:keyfind(Mod, 1, WinInfo#winInfo.editors) of + {Mod, Editor} -> add_break_to_code(Editor, Line, Status); false -> ignore end, add_break_to_menu(WinInfo, Menu, Break). add_break_to_code(Editor, Line, Status) -> - Color = if Status==active -> red; Status==inactive -> blue end, + Color = if Status =:= active -> red; Status =:= inactive -> blue end, config_editor(Editor, [{overwrite,{{Line,0},"-@- "}}, {fg,{{{Line,0},{Line,lineend}}, Color}}]). @@ -330,8 +330,8 @@ add_break_to_menu(WinInfo, Menu, {Point, [Status|_Options]=Options}) -> %% Cond = null | {Mod, Func} %%-------------------------------------------------------------------- update_break(WinInfo, {{Mod,Line},[Status|_Options]}=Break) -> - case lists:keysearch(Mod, 1, WinInfo#winInfo.editors) of - {value, {Mod, Editor}} -> + case lists:keyfind(Mod, 1, WinInfo#winInfo.editors) of + {Mod, Editor} -> add_break_to_code(Editor, Line, Status); false -> ignore end, @@ -352,8 +352,8 @@ update_break_in_menu(WinInfo, {Point, [Status|_Options]=Options}) -> %% Point = {Mod, Line} %%-------------------------------------------------------------------- delete_break(WinInfo, {Mod,Line}=Point) -> - case lists:keysearch(Mod, 1, WinInfo#winInfo.editors) of - {value, {Mod, Editor}} -> delete_break_from_code(Editor, Line); + case lists:keyfind(Mod, 1, WinInfo#winInfo.editors) of + {Mod, Editor} -> delete_break_from_code(Editor, Line); false -> ignore end, delete_break_from_menu(WinInfo, Point). @@ -379,11 +379,11 @@ clear_breaks(WinInfo) -> clear_breaks(WinInfo, all). clear_breaks(WinInfo, Mod) -> Remove = if - Mod==all -> WinInfo#winInfo.breaks; + Mod =:= all -> WinInfo#winInfo.breaks; true -> lists:filter(fun(#breakInfo{point={Mod2,_L}}) -> if - Mod2==Mod -> true; + Mod2 =:= Mod -> true; true -> false end end, @@ -450,8 +450,8 @@ display(Arg) -> %% Note: remove_code/2 should not be used for currently shown module. %%-------------------------------------------------------------------- is_shown(WinInfo, Mod) -> - case lists:keysearch(Mod, 1, WinInfo#winInfo.editors) of - {value, {Mod, Editor}} -> + case lists:keyfind(Mod, 1, WinInfo#winInfo.editors) of + {Mod, Editor} -> gs:config(Editor, raise), {true, WinInfo#winInfo{editor={Mod, Editor}}}; false -> false @@ -459,24 +459,22 @@ is_shown(WinInfo, Mod) -> show_code(WinInfo, Mod, Contents) -> Editors = WinInfo#winInfo.editors, - {Flag, Editor} = case lists:keysearch(Mod, 1, Editors) of - {value, {Mod, Ed}} -> {existing, Ed}; + {Flag, Editor} = case lists:keyfind(Mod, 1, Editors) of + {Mod, Ed} -> {existing, Ed}; false -> {new, code_editor()} end, - %% Insert code and update breakpoints, if any config_editor(Editor, [raise, clear]), show_code(Editor, Contents), lists:foreach(fun(BreakInfo) -> case BreakInfo#breakInfo.point of - {Mod2, Line} when Mod2==Mod -> + {Mod2, Line} when Mod2 =:= Mod -> Status = BreakInfo#breakInfo.status, add_break_to_code(Editor, Line,Status); _Point -> ignore end end, WinInfo#winInfo.breaks), - case Flag of existing -> WinInfo#winInfo{editor={Mod, Editor}}; @@ -485,7 +483,7 @@ show_code(WinInfo, Mod, Contents) -> editors=[{Mod, Editor} | Editors]} end. -show_code(Editor, Text) when length(Text)>1500 -> +show_code(Editor, Text) when length(Text) > 1500 -> %% Add some text at a time so that other processes may get scheduled Str = string:sub_string(Text, 1, 1500), config_editor(Editor, {insert,{'end', Str}}), @@ -494,21 +492,19 @@ show_code(Editor, Text) -> config_editor(Editor, {insert,{'end',Text}}). show_no_code(WinInfo) -> - {value, {'$top', Editor}} = - lists:keysearch('$top', 1, WinInfo#winInfo.editors), + {'$top', Editor} = lists:keyfind('$top', 1, WinInfo#winInfo.editors), gs:config(Editor, raise), WinInfo#winInfo{editor={'$top', Editor}}. remove_code(WinInfo, Mod) -> Editors = WinInfo#winInfo.editors, - case lists:keysearch(Mod, 1, Editors) of - {value, {Mod, Editor}} -> + case lists:keyfind(Mod, 1, Editors) of + {Mod, Editor} -> gs:destroy(Editor), WinInfo#winInfo{editors=lists:keydelete(Mod, 1, Editors)}; false -> WinInfo end. - %%-------------------------------------------------------------------- %% mark_line(WinInfo, Line, How) -> WinInfo @@ -522,7 +518,7 @@ mark_line(WinInfo, Line, How) -> mark_line2(Editor, WinInfo#winInfo.marked_line, false), mark_line2(Editor, Line, How), if - Line/=0 -> config_editor(Editor, {vscrollpos, Line-5}); + Line =/= 0 -> config_editor(Editor, {vscrollpos, Line-5}); true -> ignore end, WinInfo#winInfo{marked_line=Line}. @@ -537,7 +533,7 @@ mark_line2(Editor, Line, How) -> false -> " " end, Font = if - How==false -> dbg_ui_win:font(normal); + How =:= false -> dbg_ui_win:font(normal); true -> dbg_ui_win:font(bold) end, config_editor(Editor, [{overwrite, {{Line,5}, Prefix}}, @@ -558,10 +554,10 @@ select_line(WinInfo, Line) -> %% help window, it must be checked that it is correct Size = gs:read(Editor, size), if - Line==0 -> + Line =:= 0 -> select_line(Editor, WinInfo#winInfo.selected_line, false), WinInfo#winInfo{selected_line=0}; - Line<Size -> + Line < Size -> select_line(Editor, Line, true), config_editor(Editor, {vscrollpos, Line-5}), WinInfo#winInfo{selected_line=Line}; @@ -712,10 +708,10 @@ handle_event({gs, Editor, buttonpress, code_editor, _Arg}, WinInfo) -> {Row, _} -> {Mod, _Editor} = WinInfo#winInfo.editor, Point = {Mod, Row}, - case lists:keysearch(Point, #breakInfo.point, + case lists:keymember(Point, #breakInfo.point, WinInfo#winInfo.breaks) of - {value, _BreakInfo} -> {break, Point, delete}; - false -> {break, Point, add} + false -> {break, Point, add}; + true -> {break, Point, delete} end; {Row2, _} -> select_line(Editor, Row2, true), @@ -776,7 +772,7 @@ code_editor() -> code_editor(Name, W, H) -> Editor = if - Name==null -> gs:editor('CodeArea', []); + Name =:= null -> gs:editor('CodeArea', []); true -> gs:editor(Name, 'CodeArea', []) end, gs:config(Editor, [{x,5}, {y,30}, {width,W}, {height,H}, @@ -814,8 +810,8 @@ buttons() -> {'Where','WhereButton'}, {'Up','UpButton'}, {'Down','DownButton'}]. is_button(Name) -> - case lists:keysearch(Name, 1, buttons()) of - {value, {Name, Button}} -> {true, Button}; + case lists:keyfind(Name, 1, buttons()) of + {Name, Button} -> {true, Button}; false -> false end. @@ -847,7 +843,7 @@ resize_button_area(open, width, Diff) -> eval_area({Ev,Bi}, X, Y, FrameOpts, Win) -> {W,H} = if - Ev==open -> {289,200}; + Ev =:= open -> {289,200}; true -> {0,0} end, Font = dbg_ui_win:font(normal), @@ -870,7 +866,7 @@ eval_area({Ev,Bi}, X, Y, FrameOpts, Win) -> {font_style,{{{1,0},'end'},Font}}]), gs:config('EvalEditor', {enable, false}), if - Ev==open, Bi==close -> resize_eval_area(Ev, width, 257); + Ev =:= open, Bi =:= close -> resize_eval_area(Ev, width, 257); true -> ignore end. @@ -891,7 +887,7 @@ resize_eval_area(open, Key, Diff) -> bind_area({Ev,Bi}, X, Y, FrameOpts, Win) -> {W,H} = if - Bi==open -> {249,200}; + Bi =:= open -> {249,200}; true -> {0,0} end, gs:frame('BindArea', Win, @@ -908,7 +904,7 @@ bind_area({Ev,Bi}, X, Y, FrameOpts, Win) -> {text,{1,"Name"}}, {text,{2,"Value"}}, {font,Font}]), gs:config('BindGrid', {rows,{1,1}}), if - Bi==open, Ev==close -> resize_bind_area(Bi, width, 297); + Bi =:= open, Ev =:= close -> resize_bind_area(Bi, width, 297); true -> ignore end. @@ -993,15 +989,15 @@ resizebar(Flag, Name, X, Y, W, H, Obj) -> rb1({_Bu,Ev,Bi,Tr}) -> if - Ev==close, Bi==close, Tr==close -> close; + Ev =:= close, Bi =:= close, Tr =:= close -> close; true -> open end. rb2({_Bu,Ev,Bi,Tr}) -> if - Tr==open -> + Tr =:= open -> if - Ev==close, Bi==close -> close; + Ev =:= close, Bi =:= close -> close; true -> open end; true -> close @@ -1009,7 +1005,7 @@ rb2({_Bu,Ev,Bi,Tr}) -> rb3({_Bu,Ev,Bi,_Tr}) -> if - Ev==open, Bi==open -> open; + Ev =:= open, Bi =:= open -> open; true -> close end. @@ -1032,7 +1028,7 @@ config_v() -> gs:config('RB3', {y,Y3}), gs:config('BindArea', {y,Y3}), - Y4 = Y3 + max(gs:read('EvalArea', height), + Y4 = Y3 + erlang:max(gs:read('EvalArea', height), gs:read('BindArea', height)), gs:config('RB2', {y,Y4}), @@ -1061,13 +1057,13 @@ configure(WinInfo, NewW, NewH) -> OldH = 25+gs:read('CodeArea', height)+ gs:read('RB1', height)+ gs:read('ButtonArea', height)+ - max(gs:read('EvalArea', height), gs:read('BindArea', height))+ + erlang:max(gs:read('EvalArea', height), gs:read('BindArea', height))+ gs:read('RB2', height)+ gs:read('TraceArea', height), %% Adjust width unless it is unchanged or less than minimum width if - OldW/=NewW -> + OldW =/= NewW -> {Dcode,Deval,Dbind} = configure_widths(OldW,NewW,Flags), resize_code_area(WinInfo, width, Dcode), case rb1(Flags) of @@ -1090,7 +1086,7 @@ configure(WinInfo, NewW, NewH) -> %% Adjust height unless it is unchanged or less than minimum height if - OldH/=NewH -> + OldH =/= NewH -> {Dcode2,Deval2,Dtrace} = configure_heights(OldH,NewH,Flags), resize_code_area(WinInfo, height, Dcode2), resize_eval_area(Ev, height, Deval2), @@ -1112,16 +1108,16 @@ configure_widths(OldW, NewW, Flags) -> {_Bu,Ev,Bi,_Tr} = Flags, %% Difference between old and new width, considering min window width - Diff = abs(max(OldW,330)-max(NewW,330)), + Diff = abs(erlang:max(OldW,330)-erlang:max(NewW,330)), %% Check how much the frames can be resized in reality Limits = if %% Window larger - NewW>OldW -> + NewW > OldW -> if - Ev==open,Bi==open -> {0,Diff,Diff}; - Ev==open -> {0,Diff,0}; - Bi==open -> {0,0,Diff}; + Ev =:= open, Bi =:= open -> {0,Diff,Diff}; + Ev =:= open -> {0,Diff,0}; + Bi =:= open -> {0,0,Diff}; true -> {Diff,0,0} end; @@ -1129,12 +1125,12 @@ configure_widths(OldW, NewW, Flags) -> %% and current size OldW>NewW -> if - Ev==open,Bi==open -> + Ev =:= open, Bi =:= open -> {0, gs:read('EvalArea',width)-204, gs:read('BindArea',width)-112}; - Ev==open -> {0,Diff,0}; - Bi==open -> {0,0,Diff}; + Ev =:= open -> {0,Diff,0}; + Bi =:= open -> {0,0,Diff}; true -> {Diff,0,0} end end, @@ -1142,13 +1138,13 @@ configure_widths(OldW, NewW, Flags) -> case Limits of %% No Shell or Bind frame, larger window - {T,0,0} when NewW>OldW -> {T,0,0}; + {T,0,0} when NewW > OldW -> {T,0,0}; %% No Shell or Bind frame, smaller window - {T,0,0} when OldW>NewW -> {-T,0,0}; + {T,0,0} when OldW > NewW -> {-T,0,0}; %% Window larger; divide Diff among the frames and return result - {_,Sf,B} when NewW>OldW -> + {_,Sf,B} when NewW > OldW -> {_,Sf2,B2} = divide([{0,0},{0,Sf},{0,B}],Diff), {Sf2+B2,Sf2,B2}; @@ -1166,38 +1162,38 @@ configure_heights(OldH, NewH, Flags) -> %% Difference between old and new height, considering min win height MinH = min_height(Flags), - Diff = abs(max(OldH,MinH)-max(NewH,MinH)), + Diff = abs(erlang:max(OldH,MinH)-erlang:max(NewH,MinH)), %% Check how much the frames can be resized in reality {T,Sf,Ff} = if %% Window larger - NewH>OldH -> + NewH > OldH -> {Diff, if - Ev==close, Bi==close -> 0; + Ev =:= close, Bi =:= close -> 0; true -> Diff end, if - Tr==open -> Diff; + Tr =:= open -> Diff; true -> 0 end}; %% Window smaller; get difference between min size %% and current size - OldH>NewH -> + OldH > NewH -> {gs:read('CodeArea',height)-100, if - Ev==close, Bi==close -> 0; + Ev =:= close, Bi =:= close -> 0; true -> if - Ev==open -> + Ev =:= open -> gs:read('EvalArea',height)-100; - Bi==open -> + Bi =:= open -> gs:read('BindArea',height)-100 end end, if - Tr==open -> gs:read('TraceArea',height)-100; + Tr =:= open -> gs:read('TraceArea',height)-100; true -> 0 end} end, @@ -1251,10 +1247,8 @@ divide(L, Diff) -> if %% All of Diff has been distributed - D==0 -> {T,S,F}; - + D =:= 0 -> {T,S,F}; true -> - %% For each element, try to add as much as possible of D {NewT,Dt} = divide2(D,T,Tmax), {NewS,Ds} = divide2(D,S,Smax), @@ -1296,25 +1290,25 @@ resize(WinInfo, ResizeBar) -> rblimits('RB2',W,H), rblimits('RB3',W,H)). -resizeloop(WI, RB, Prev, {Min1,Max1},{Min2,Max2},{Min3,Max3}) -> +resizeloop(WI, RB, Prev, {Min1,Max1}, {Min2,Max2}, {Min3,Max3}) -> receive - {gs,_,motion,_,[_,Y]} when RB=='RB1', Y>Min1,Y<Max1 -> + {gs,_,motion,_,[_,Y]} when RB =:= 'RB1', Y > Min1, Y < Max1 -> gs:config('RB1', {y,Y}), - resizeloop(WI, RB, Y, {Min1,Max1},{Min2,Max2},{Min3,Max3}); - {gs,_,motion,_,_} when RB=='RB1' -> - resizeloop(WI, RB, Prev,{Min1,Max1},{Min2,Max2},{Min3,Max3}); + resizeloop(WI, RB, Y, {Min1,Max1}, {Min2,Max2}, {Min3,Max3}); + {gs,_,motion,_,_} when RB =:= 'RB1' -> + resizeloop(WI, RB, Prev, {Min1,Max1}, {Min2,Max2}, {Min3,Max3}); - {gs,_,motion,_,[_,Y]} when RB=='RB2', Y>Min2,Y<Max2 -> + {gs,_,motion,_,[_,Y]} when RB =:= 'RB2', Y > Min2, Y < Max2 -> gs:config('RB2', {y,Y}), - resizeloop(WI, RB, Y, {Min1,Max1},{Min2,Max2},{Min3,Max3}); - {gs,_,motion,_,_} when RB=='RB2' -> - resizeloop(WI, RB, Prev,{Min1,Max1},{Min2,Max2},{Min3,Max3}); + resizeloop(WI, RB, Y, {Min1,Max1}, {Min2,Max2}, {Min3,Max3}); + {gs,_,motion,_,_} when RB =:= 'RB2' -> + resizeloop(WI, RB, Prev, {Min1,Max1}, {Min2,Max2}, {Min3,Max3}); - {gs,_,motion,_,[X,_]} when RB=='RB3', X>Min3,X<Max3 -> + {gs,_,motion,_,[X,_]} when RB =:= 'RB3', X > Min3, X < Max3 -> gs:config('RB3', {x,X}), - resizeloop(WI, RB, X, {Min1,Max1},{Min2,Max2},{Min3,Max3}); - {gs,_,motion,_,_} when RB=='RB3' -> - resizeloop(WI, RB, Prev,{Min1,Max1},{Min2,Max2},{Min3,Max3}); + resizeloop(WI, RB, X, {Min1,Max1}, {Min2,Max2}, {Min3,Max3}); + {gs,_,motion,_,_} when RB =:= 'RB3' -> + resizeloop(WI, RB, Prev, {Min1,Max1}, {Min2,Max2}, {Min3,Max3}); {gs,_,buttonrelease,_,_} -> resize_win(WI, RB, Prev) @@ -1329,7 +1323,7 @@ resize_win(WinInfo, 'RB1', Y) -> %% Resize Code, Evaluator and Binding areas resize_code_area(WinInfo, height, -Diff), if - S==close, Bi==close, F==open -> + S =:= close, Bi =:= close, F =:= open -> resize_trace_area(open, height, Diff); true -> resize_eval_area(S, height, Diff), @@ -1388,37 +1382,27 @@ rblimits('RB1',_W,H) -> RB2 = gs:read('RB2',height), FF = gs:read('TraceArea',height), Max = case RB2 of - 0 when FF/=0 -> + 0 when FF =/= 0 -> H-112; _ -> Y = gs:read('RB2',y), - max(Min,Y-140) + erlang:max(Min,Y-140) end, {Min,Max}; rblimits('RB2',_W,H) -> - - %% TraceFrame should not have height <100 + %% TraceFrame should not have height < 100 Max = H-112, - %% Min is decided by a minimum distance to 'RB1' Y = gs:read('RB1',y), - Min = min(Max,Y+140), - + Min = erlang:min(Max,Y+140), {Min,Max}; rblimits('RB3',W,_H) -> - %% Neither CodeArea nor BindArea should occupy %% less than 1/3 of the total window width and EvalFrame should %% be at least 289 pixels wide - {max(round(W/3),289),round(2*W/3)}. - -max(A, B) when A>B -> A; -max(_A, B) -> B. - -min(A, B) when A<B -> A; -min(_A, B) -> B. + {erlang:max(round(W/3),289),round(2*W/3)}. %%==================================================================== @@ -1490,7 +1474,7 @@ helpwin_action(gotoline, default, AttPid, _Editor, Data, Win) -> end, Data; helpwin_action(search, case_sensitive, _AttPid, _Ed, {Pos, CS}, _Win) -> - Bool = if CS==true -> false; CS==false -> true end, + Bool = if CS =:= true -> false; CS =:= false -> true end, {Pos, Bool}; helpwin_action(search, default, _AttPid, Editor, {Pos, CS}, Win) -> gs:config(lbl(Win), {label, {text, ""}}), @@ -1523,13 +1507,9 @@ search(Str, Editor, Max, {Row, Col}, CS) -> lowercase(true, Str) -> Str; lowercase(false, Str) -> - lists:map(fun(Char) -> - if - Char>=$A, Char=<$Z -> Char+32; - true -> Char - end - end, - Str). + [if Char >= $A, Char =< $Z -> Char+32; + true -> Char + end || Char <- Str]. mark_string(Editor, {Row, Col}, Str) -> Between = {{Row,Col}, {Row,Col+length(Str)}}, @@ -1546,10 +1526,9 @@ unmark_string(Editor, {Row, Col}) -> {fg, {Between, black}}]). helpwin(Type, GS, {X, Y}) -> - W = 200, Pad=10, Wbtn = 50, + W = 200, Pad = 10, Wbtn = 50, - Title = - case Type of search -> "Search"; gotoline -> "Go To Line" end, + Title = case Type of search -> "Search"; gotoline -> "Go To Line" end, Win = gs:window(GS, [{title, Title}, {x, X}, {y, Y}, {width, W}, {destroy, true}]), diff --git a/lib/debugger/src/dbg_ui_view.erl b/lib/debugger/src/dbg_ui_view.erl index 075275f196..7350a830a8 100644 --- a/lib/debugger/src/dbg_ui_view.erl +++ b/lib/debugger/src/dbg_ui_view.erl @@ -21,9 +21,6 @@ %% External exports -export([start/2]). -%% Internal exports --export([init/3]). - -record(state, {gs, % term() Graphics system id win, % term() Attach process window data coords, % {X,Y} Mouse point position @@ -42,7 +39,7 @@ start(GS, Mod) -> Title = "View Module " ++ atom_to_list(Mod), case dbg_ui_winman:is_started(Title) of true -> ignore; - false -> spawn(?MODULE, init, [GS, Mod, Title]) + false -> spawn(fun () -> init(GS, Mod, Title) end) end. @@ -51,7 +48,6 @@ start(GS, Mod) -> %%==================================================================== init(GS, Mod, Title) -> - %% Subscribe to messages from the interpreter int:subscribe(), diff --git a/lib/debugger/src/dbg_ui_win.erl b/lib/debugger/src/dbg_ui_win.erl index 9840aa54da..9bed6a1ec5 100644 --- a/lib/debugger/src/dbg_ui_win.erl +++ b/lib/debugger/src/dbg_ui_win.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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(dbg_ui_win). @@ -24,7 +24,6 @@ create_menus/2, select/2, selected/1, add_break/2, update_break/2, delete_break/1, motion/2 - ]). -record(break, {mb, smi, emi, dimi, demi}). @@ -49,11 +48,11 @@ init() -> font(Style) -> GS = init(), Style2 = if - Style==normal -> []; + Style =:= normal -> []; true -> [Style] end, case gs:read(GS, {choose_font, {screen,Style2,12}}) of - Font when element(1, Font)==screen -> + Font when element(1, Font) =:= screen -> Font; _ -> gs:read(GS, {choose_font, {courier,Style2,12}}) @@ -76,13 +75,10 @@ min_size(Font, Strings, MinW, MinH) -> min_size(GS, Font, [String|Strings], MinW, MinH) -> {W, H} = gs:read(GS, {font_wh, {Font, String}}), - min_size(GS, Font, Strings, max(MinW, W), max(MinH, H)); + min_size(GS, Font, Strings, erlang:max(MinW, W), erlang:max(MinH, H)); min_size(_GS, _Font, [], W, H) -> {W, H}. -max(X, Y) when X>Y -> X; -max(_X, Y) -> Y. - %%-------------------------------------------------------------------- %% create_menus(MenuBar, [Menu]) %% MenuBar = gsobj() @@ -171,8 +167,7 @@ select(MenuItem, Bool) -> %%-------------------------------------------------------------------- selected(Menu) -> Children = gs:read(Menu, children), - Selected = lists:filter(fun(Child) -> gs:read(Child, select) end, - Children), + Selected = [gs:read(Child, select) || Child <- Children], lists:map(fun(Child) -> {text, Name} = gs:read(Child, label), list_to_atom(Name) diff --git a/lib/debugger/src/dbg_ui_winman.erl b/lib/debugger/src/dbg_ui_winman.erl index 71023cd0d6..398735a7ca 100644 --- a/lib/debugger/src/dbg_ui_winman.erl +++ b/lib/debugger/src/dbg_ui_winman.erl @@ -120,9 +120,9 @@ init(_Arg) -> {ok, #state{}}. handle_call({is_started, Title}, _From, State) -> - Reply = case lists:keysearch(Title, #win.title, State#state.wins) of - {value, Win} -> {true, Win#win.win}; - false -> false + Reply = case lists:keyfind(Title, #win.title, State#state.wins) of + false -> false; + Win -> {true, Win#win.win} end, {reply, Reply, State}. @@ -134,8 +134,8 @@ handle_cast({insert, Pid, Title, Win}, State) -> handle_cast({clear_process, Title}, State) -> OldWins = State#state.wins, - Wins = case lists:keysearch(Title, #win.title, OldWins) of - {value, #win{owner=Pid}} -> + Wins = case lists:keyfind(Title, #win.title, OldWins) of + #win{owner=Pid} -> Msg = {dbg_ui_winman, destroy}, Pid ! Msg, lists:keydelete(Title, #win.title, OldWins); @@ -147,7 +147,7 @@ handle_cast({clear_process, Title}, State) -> handle_info({'EXIT', Pid, _Reason}, State) -> [Mon | _Wins] = State#state.wins, if - Pid==Mon#win.owner -> {stop, normal, State}; + Pid =:= Mon#win.owner -> {stop, normal, State}; true -> Wins2 = lists:keydelete(Pid, #win.owner, State#state.wins), inform_all(Wins2), diff --git a/lib/debugger/src/dbg_wx_break_win.erl b/lib/debugger/src/dbg_wx_break_win.erl index 5dafb0fbe6..78733c98c8 100644 --- a/lib/debugger/src/dbg_wx_break_win.erl +++ b/lib/debugger/src/dbg_wx_break_win.erl @@ -206,11 +206,7 @@ handle_event(#wx{id=OKorListBox, event=#wxCommand{type=OkorDoubleClick}}, OkorDoubleClick =:= command_listbox_doubleclicked -> Mod = wxComboBox:getValue(Text), {_, IndexL} = wxListBox:getSelections(LB), - Breaks = lists:map(fun(Index) -> - Func = lists:nth(Index+1, Funcs), - [list_to_atom(Mod) | Func] - end, - IndexL), + Breaks = [[list_to_atom(Mod)|lists:nth(Index+1, Funcs)] || Index <- IndexL], wxDialog:destroy(Win), {break, Breaks, enable}; handle_event(#wx{id=?wxID_OK},#winInfo{win=Win,text=Text, entries=Es, trigger=Trigger}) -> diff --git a/lib/debugger/src/dbg_wx_interpret.erl b/lib/debugger/src/dbg_wx_interpret.erl index f711ba679d..ffcfbcf36b 100644 --- a/lib/debugger/src/dbg_wx_interpret.erl +++ b/lib/debugger/src/dbg_wx_interpret.erl @@ -115,11 +115,11 @@ interpret_all(Dir, [File0|Files], Mode, Window, Errors) -> interpret_all(_Dir, [], _Mode, _Window, []) -> true; interpret_all(Dir, [], _Mode, Window, Errors) -> - Msg = lists:map(fun(Name) -> - File = filename:join(Dir, Name), - Error = format_error(int:interpretable(File)), - ["\n ",Name,": ",Error] - end, Errors), + Msg = [begin + File = filename:join(Dir, Name), + Error = format_error(int:interpretable(File)), + ["\n ",Name,": ",Error] + end || Name <- Errors], All = ["Error when interpreting: ", Msg], dbg_wx_win:confirm(Window, lists:flatten(All)), true. diff --git a/lib/debugger/src/dbg_wx_mon.erl b/lib/debugger/src/dbg_wx_mon.erl index 3f55c38d35..6bdec994b1 100644 --- a/lib/debugger/src/dbg_wx_mon.erl +++ b/lib/debugger/src/dbg_wx_mon.erl @@ -170,7 +170,7 @@ init2(CallingPid, Mode, SFile, GS) -> CallingPid ! {initialization_complete, self()}, if - SFile==default -> + SFile =:= default -> loop(State3); true -> loop(load_settings(SFile, State3)) @@ -268,7 +268,7 @@ gui_cmd(ignore, State) -> State; gui_cmd(stopped, State) -> if - State#state.starter==true -> int:stop(); + State#state.starter =:= true -> int:stop(); true -> int:auto_attach(false) end, exit(stop); @@ -420,9 +420,9 @@ gui_cmd({'Trace Window', TraceWin}, State) -> State2; gui_cmd({'Auto Attach', When}, State) -> if - When==[] -> int:auto_attach(false); + When =:= [] -> int:auto_attach(false); true -> - Flags = lists:map(fun(Name) -> map(Name) end, When), + Flags = [map(Name) || Name <- When], int:auto_attach(Flags, trace_function(State)) end, State; @@ -691,12 +691,12 @@ load_settings2(Settings, State) -> Break, int:break(Mod, Line), if - Status==inactive -> + Status =:= inactive -> int:disable_break(Mod, Line); true -> ignore end, if - Action/=enable -> + Action =/= enable -> int:action_at_break(Mod,Line,Action); true -> ignore end, @@ -715,10 +715,7 @@ save_settings(SFile, State) -> int:auto_attach(), int:stack_trace(), State#state.backtrace, - lists:map(fun(Mod) -> - int:file(Mod) - end, - int:interpreted()), + [int:file(Mod) || Mod <- int:interpreted()], int:all_breaks()}, Binary = term_to_binary({debugger_settings, Settings}), @@ -741,7 +738,7 @@ registered_name(Pid) -> Node = node(Pid), if - Node==node() -> + Node =:= node() -> case erlang:process_info(Pid, registered_name) of {registered_name, Name} -> Name; _ -> undefined diff --git a/lib/debugger/src/dbg_wx_mon_win.erl b/lib/debugger/src/dbg_wx_mon_win.erl index 8ad4f4213f..04c3501b8c 100644 --- a/lib/debugger/src/dbg_wx_mon_win.erl +++ b/lib/debugger/src/dbg_wx_mon_win.erl @@ -266,8 +266,7 @@ select(MenuItem, Bool) -> add_module(WinInfo, MenuName, Mod) -> Win = WinInfo#winInfo.window, Modules = WinInfo#winInfo.modules, - case lists:keysearch(Mod, #moduleInfo.module, Modules) of - {value, _ModInfo} -> WinInfo; + case lists:keymember(Mod, #moduleInfo.module, Modules) of false -> %% Create a menu for the module Menu = get(MenuName), @@ -284,8 +283,9 @@ add_module(WinInfo, MenuName, Mod) -> wxListBox:append(WinInfo#winInfo.listbox, atom_to_list(Mod)), ModInfo = #moduleInfo{module=Mod, menubtn={Menu,MenuBtn}}, - WinInfo#winInfo{modules=[ModInfo | Modules]} - end. + WinInfo#winInfo{modules=[ModInfo | Modules]}; + true -> WinInfo + end. %%-------------------------------------------------------------------- %% delete_module(WinInfo, Mod) -> WinInfo @@ -559,8 +559,7 @@ handle_event(#wx{event=#wxCommand{type=command_checkbox_clicked}}, handle_event(#wx{event=#wxList{type=command_list_item_selected, itemIndex=Row}}, WinInfo) -> #winInfo{processes=Pids} = WinInfo, - {value, #procInfo{pid=Pid}} = - lists:keysearch(Row, #procInfo.row, Pids), + #procInfo{pid=Pid} = lists:keyfind(Row, #procInfo.row, Pids), {focus, Pid, WinInfo#winInfo{focus=Row}}; handle_event(#wx{event=#wxList{type=command_list_item_activated}}, _WinInfo) -> diff --git a/lib/debugger/src/dbg_wx_trace.erl b/lib/debugger/src/dbg_wx_trace.erl index f9fdf593c4..6675ea33e7 100644 --- a/lib/debugger/src/dbg_wx_trace.erl +++ b/lib/debugger/src/dbg_wx_trace.erl @@ -180,12 +180,12 @@ init_contents(Breaks, State) -> State#state{win=Win}. -loop(#state{meta=Meta} = State) -> +loop(#state{meta=Meta, win=Win} = State) -> receive %% From the GUI main window - GuiEvent when element(1, GuiEvent)==wx -> + GuiEvent when element(1, GuiEvent) =:= wx -> Cmd = wx:batch(fun() -> - dbg_wx_trace_win:handle_event(GuiEvent,State#state.win) + dbg_wx_trace_win:handle_event(GuiEvent,Win) end), State2 = gui_cmd(Cmd, State), loop(State2); @@ -211,11 +211,11 @@ loop(#state{meta=Meta} = State) -> %% From the dbg_wx_winman process (Debugger window manager) {dbg_ui_winman, update_windows_menu, Data} -> - Window = dbg_wx_trace_win:get_window(State#state.win), + Window = dbg_wx_trace_win:get_window(Win), dbg_wx_winman:update_windows_menu(Window,Data), loop(State); {dbg_ui_winman, destroy} -> - dbg_wx_trace_win:stop(State#state.win), + dbg_wx_trace_win:stop(Win), exit(stop) end. @@ -269,7 +269,7 @@ gui_cmd('Continue', State) -> int:meta(State#state.meta, continue), {Status, Mod, Line} = State#state.status, if - Status==wait_break -> + Status =:= wait_break -> Win = dbg_wx_trace_win:unmark_line(State#state.win), gui_enable_functions(wait_running), State#state{win=Win, status={wait_running,Mod,Line}}; @@ -291,7 +291,7 @@ gui_cmd('Stop', State) -> int:meta(State#state.meta, stop), {Status, Mod, Line} = State#state.status, if - Status==wait_running -> + Status =:= wait_running -> Win = dbg_wx_trace_win:mark_line(State#state.win, Line, break), gui_enable_functions(wait_break), @@ -421,7 +421,7 @@ gui_cmd('Function Break...', State) -> gui_cmd('Enable All', State) -> Breaks = int:all_breaks(), ThisMod = State#state.cm, - lists:foreach(fun ({{Mod, Line}, _Options}) when Mod==ThisMod -> + lists:foreach(fun ({{Mod, Line}, _Options}) when Mod =:= ThisMod -> int:enable_break(Mod, Line); (_Break) -> ignore @@ -431,7 +431,7 @@ gui_cmd('Enable All', State) -> gui_cmd('Disable All', State) -> Breaks = int:all_breaks(), ThisMod = State#state.cm, - lists:foreach(fun ({{Mod, Line}, _Options}) when Mod==ThisMod -> + lists:foreach(fun ({{Mod, Line}, _Options}) when Mod =:= ThisMod -> int:disable_break(Mod, Line); (_Break) -> ignore @@ -458,7 +458,7 @@ gui_cmd({'Trace Window', TraceWin}, State) -> Win = dbg_wx_trace_win:configure(State#state.win, TraceWin), {Status,_,_} = State#state.status, if - Status==break; Status==wait_break -> + Status =:= break; Status =:= wait_break -> gui_enable_btrace(Trace, State#state.stack_trace); true -> ignore end, @@ -467,7 +467,7 @@ gui_cmd({'Stack Trace', [Name]}, State) -> int:meta(State#state.meta, stack_trace, map(Name)), {Status,_,_} = State#state.status, if - Status==break; Status==wait_break -> + Status =:= break; Status =:= wait_break -> gui_enable_btrace(State#state.trace, map(Name)); true -> ignore end, @@ -490,9 +490,9 @@ gui_cmd('Debugger', State) -> gui_cmd({user_command, Cmd}, State) -> {Status, _Mod, _Line} = State#state.status, if - Status==break; - Status==wait_break; - Status==wait_running -> + Status =:= break; + Status =:= wait_break; + Status =:= wait_running -> Cm = State#state.cm, Arg = case State#state.stack of {Cur, Max} when Cur<Max -> {Cm, Cmd, Cur}; @@ -531,14 +531,14 @@ add_break(WI, Coords, Type, Mod, Line) -> int_cmd({interpret, Mod}, State) -> if - Mod==State#state.cm -> + Mod =:= State#state.cm -> State#state{cm_obsolete=true}; true -> State end; int_cmd({no_interpret, Mod}, State) -> if - Mod==State#state.cm -> + Mod =:= State#state.cm -> State#state{cm_obsolete=true}; true -> Win = dbg_wx_trace_win:remove_code(State#state.win, Mod), @@ -584,7 +584,7 @@ meta_cmd({re_entry, dbg_ieval, eval_fun}, State) -> meta_cmd({re_entry, Mod, _Func}, State) -> Obs = State#state.cm_obsolete, case State#state.cm of - Mod when Obs==true -> + Mod when Obs =:= true -> Win = gui_load_module(State#state.win, Mod,State#state.pid), State#state{win=Win, cm_obsolete=false}; Mod -> State; @@ -630,11 +630,11 @@ meta_cmd({func_at, Mod, Line, Cur}, State) -> gui_enable_functions(idle), dbg_wx_trace_win:display(State#state.win, idle), State#state{win=Win, cm=Mod, status={idle,Mod,Line}, stack=Stack}; -meta_cmd({wait_at, Mod, Line, Cur}, #state{status={Status,_,_}}=State) - when Status/=init, Status/=break -> +meta_cmd({wait_at, Mod, Line, Cur}, #state{status={Status,_,_}, win=Win}=State) + when Status =/= init, Status =/= break -> Stack = {Cur,Cur}, gui_enable_functions(wait_running), - dbg_wx_trace_win:display(State#state.win, {wait,Mod,Line}), + dbg_wx_trace_win:display(Win, {wait,Mod,Line}), State#state{status={wait_running,Mod,Line}, stack=Stack}; meta_cmd({wait_at, Mod, Line, Cur}, State) -> Stack = {Cur,Cur}, @@ -675,7 +675,7 @@ meta_cmd({stack_trace, Flag}, State) -> gui_enable_updown(Flag, State#state.stack), {Status,_,_} = State#state.status, if - Status==break; Status==wait_break -> + Status =:= break; Status =:= wait_break -> gui_enable_btrace(State#state.trace, Flag); true -> ignore end, @@ -813,7 +813,7 @@ gui_enable_functions(Status) -> gui_enable_updown(Flag, Stack) -> {Enable, Disable} = if - Flag==false -> {[], ['Up', 'Down']}; + Flag =:= false -> {[], ['Up', 'Down']}; true -> case Stack of {1,1} -> {[], ['Up', 'Down']}; @@ -826,14 +826,14 @@ gui_enable_updown(Flag, Stack) -> dbg_wx_trace_win:enable(Enable, true), dbg_wx_trace_win:enable(Disable, false), if - Enable==[] -> dbg_wx_trace_win:enable(['Where'], false); + Enable =:= [] -> dbg_wx_trace_win:enable(['Where'], false); true -> dbg_wx_trace_win:enable(['Where'], true) end. gui_enable_btrace(Trace, StackTrace) -> Bool = if - Trace==false -> false; - StackTrace==false -> false; + Trace =:= false -> false; + StackTrace =:= false -> false; true -> true end, dbg_wx_trace_win:enable(['Back Trace'], Bool). diff --git a/lib/debugger/src/dbg_wx_trace_win.erl b/lib/debugger/src/dbg_wx_trace_win.erl index 3799acdc1b..720b913024 100755 --- a/lib/debugger/src/dbg_wx_trace_win.erl +++ b/lib/debugger/src/dbg_wx_trace_win.erl @@ -410,11 +410,11 @@ clear_breaks(WinInfo) -> clear_breaks(WinInfo, all). clear_breaks(WinInfo, Mod) -> Remove = if - Mod==all -> WinInfo#winInfo.breaks; + Mod =:= all -> WinInfo#winInfo.breaks; true -> lists:filter(fun(#breakInfo{point={Mod2,_L}}) -> if - Mod2==Mod -> true; + Mod2 =:= Mod -> true; true -> false end end, @@ -481,8 +481,8 @@ display(#winInfo{window=Win, sb=Sb},Arg) -> %% Note: remove_code/2 should not be used for currently shown module. %%-------------------------------------------------------------------- is_shown(WinInfo, Mod) -> - case lists:keysearch(Mod, 1, WinInfo#winInfo.editors) of - {value, {Mod, Editor}} -> + case lists:keyfind(Mod, 1, WinInfo#winInfo.editors) of + {Mod, Editor} -> gs:config(Editor, raise), %% BUGBUG {true, WinInfo#winInfo{editor={Mod, Editor}}}; false -> false @@ -494,7 +494,7 @@ show_code(WinInfo = #winInfo{editor={_, Ed}}, Mod, Contents) -> lists:foreach(fun(BreakInfo) -> case BreakInfo#breakInfo.point of - {Mod2, Line} when Mod2==Mod -> + {Mod2, Line} when Mod2 =:= Mod -> Status = BreakInfo#breakInfo.status, dbg_wx_code:add_break_to_code(Ed, Line,Status); _Point -> ignore @@ -540,10 +540,10 @@ select_line(WinInfo, Line) -> %% help window, it must be checked that it is correct Size = dbg_wx_code:get_no_lines(Ed), if - Line==0 -> + Line =:= 0 -> dbg_wx_code:goto_line(Ed,1), WinInfo#winInfo{selected_line=0}; - Line<Size -> + Line < Size -> dbg_wx_code:goto_line(Ed,Line), WinInfo#winInfo{selected_line=Line}; true -> @@ -632,7 +632,7 @@ handle_event(#wx{id=?SASH_CODE, event=#wxSash{dragRect={_X,_Y,_W,H}}}, Wi) -> Change = CH - H, ChangeH = fun(Item) -> {ItemW, ItemH} = wxSizerItem:getMinSize(Item), - wxSizerItem:setInitSize(Item, ItemW, max(ItemH+Change,-1)) + wxSizerItem:setInitSize(Item, ItemW, erlang:max(ItemH+Change,-1)) end, if Enable -> {IW, IH} = wxSizer:getMinSize(InfoSzr), @@ -694,7 +694,7 @@ handle_event(#wx{id=?SASH_TRACE, event=#wxSash{dragRect={_X,_Y,_W,H}}}, Wi) -> true -> %% Change the Eval and Bindings area ChangeH = fun(Item) -> {ItemW, ItemH} = wxSizerItem:getMinSize(Item), - wxSizerItem:setInitSize(Item, ItemW, max(ItemH+Change,-1)) + wxSizerItem:setInitSize(Item, ItemW, erlang:max(ItemH+Change,-1)) end, {IW, IH} = wxSizer:getMinSize(InfoSzr), [ChangeH(Child) || Child <- wxSizer:getChildren(InfoSzr)], @@ -764,8 +764,8 @@ handle_event(#wx{event=#wxStyledText{type=stc_doubleclick}}, WinInfo = #winInfo{editor={Mod,Ed}}) -> Line = wxStyledTextCtrl:getCurrentLine(Ed), Point = {Mod, Line+1}, - case lists:keysearch(Point, #breakInfo.point,WinInfo#winInfo.breaks) of - {value, _BreakInfo} -> {break, Point, delete}; + case lists:keymember(Point, #breakInfo.point, WinInfo#winInfo.breaks) of + true -> {break, Point, delete}; false -> {break, Point, add} end; @@ -837,7 +837,7 @@ handle_event(#wx{id=?SEARCH_ENTRY, event=#wxCommand{cmdString=Str}}, %% Button area handle_event(#wx{id=ID, event=#wxCommand{type=command_button_clicked}},_Wi) -> - {value, {Button, _}} = lists:keysearch(ID, 2, buttons()), + {Button, _} = lists:keyfind(ID, 2, buttons()), Button; %% Evaluator area @@ -908,8 +908,8 @@ buttons() -> {'Where',?WhereButton}, {'Up',?UpButton}, {'Down',?DownButton}]. is_button(Name) -> - case lists:keysearch(Name, 1, buttons()) of - {value, {Name, Button}} -> {true, Button}; + case lists:keyfind(Name, 1, buttons()) of + {Name, Button} -> {true, Button}; false -> false end. @@ -1021,9 +1021,3 @@ helpwin(Type, WinInfo = #winInfo{sg=Sg =#sub{in=Sa}}) -> search -> wxWindow:setFocus(Sa#sa.search) end, Wi. - -max(X,Y) when X > Y -> X; -max(_,Y) -> Y. - - - diff --git a/lib/debugger/src/dbg_wx_view.erl b/lib/debugger/src/dbg_wx_view.erl index 6d34e5650c..8ff89a4847 100644 --- a/lib/debugger/src/dbg_wx_view.erl +++ b/lib/debugger/src/dbg_wx_view.erl @@ -23,9 +23,6 @@ %% External exports -export([start/2]). -%% Internal exports --export([init/4]). - -record(state, {gs, % term() Graphics system id win, % term() Attach process window data coords, % {X,Y} Mouse point position @@ -46,7 +43,7 @@ start(GS, Mod) -> true -> ignore; false -> Env = wx:get_env(), - spawn_link(?MODULE, init, [GS, Env, Mod, Title]) + spawn_link(fun () -> init(GS, Env, Mod, Title) end) end. @@ -84,7 +81,7 @@ loop(State) -> receive %% From the GUI main window - GuiEvent when element(1, GuiEvent)==wx -> + GuiEvent when element(1, GuiEvent) =:= wx -> Cmd = wx:batch(fun() -> dbg_wx_trace_win:handle_event(GuiEvent, State#state.win) end), @@ -167,7 +164,7 @@ gui_cmd('Function Break...', State) -> gui_cmd('Enable All', State) -> Breaks = int:all_breaks(), ThisMod = State#state.mod, - lists:foreach(fun ({{Mod, Line}, _Options}) when Mod==ThisMod -> + lists:foreach(fun ({{Mod, Line}, _Options}) when Mod =:= ThisMod -> int:enable_break(Mod, Line); (_Break) -> ignore @@ -177,7 +174,7 @@ gui_cmd('Enable All', State) -> gui_cmd('Disable All', State) -> Breaks = int:all_breaks(), ThisMod = State#state.mod, - lists:foreach(fun ({{Mod, Line}, _Options}) when Mod==ThisMod -> + lists:foreach(fun ({{Mod, Line}, _Options}) when Mod =:= ThisMod -> int:disable_break(Mod, Line); (_Break) -> ignore @@ -214,21 +211,19 @@ add_break(GS, Coords, Type, Mod, Line) -> %%--Commands from the interpreter------------------------------------- -int_cmd({new_break, {{Mod,_Line},_Options}=Break}, #state{mod=Mod}=State) -> - Win = dbg_wx_trace_win:add_break(State#state.win, 'Break', Break), - State#state{win=Win}; -int_cmd({delete_break, {Mod,_Line}=Point}, #state{mod=Mod}=State) -> - Win = dbg_wx_trace_win:delete_break(State#state.win, Point), - State#state{win=Win}; -int_cmd({break_options, {{Mod,_Line},_Options}=Break}, #state{mod=Mod}=State) -> - Win = dbg_wx_trace_win:update_break(State#state.win, Break), - State#state{win=Win}; -int_cmd(no_break, State) -> - Win = dbg_wx_trace_win:clear_breaks(State#state.win), - State#state{win=Win}; -int_cmd({no_break, _Mod}, State) -> - Win = dbg_wx_trace_win:clear_breaks(State#state.win), - State#state{win=Win}; +int_cmd({new_break, {{Mod,_Line},_Options}=Break}, + #state{mod = Mod, win = Win}=State) -> + State#state{win = dbg_wx_trace_win:add_break(Win, 'Break', Break)}; +int_cmd({delete_break, {Mod,_Line}=Point}, + #state{mod = Mod, win = Win}=State) -> + State#state{win = dbg_wx_trace_win:delete_break(Win, Point)}; +int_cmd({break_options, {{Mod,_Line},_Options}=Break}, + #state{mod = Mod, win = Win}=State) -> + State#state{win = dbg_wx_trace_win:update_break(Win, Break)}; +int_cmd(no_break, #state{win = Win}=State) -> + State#state{win = dbg_wx_trace_win:clear_breaks(Win)}; +int_cmd({no_break, _Mod}, #state{win = Win}=State) -> + State#state{win = dbg_wx_trace_win:clear_breaks(Win)}; int_cmd(_, State) -> State. diff --git a/lib/debugger/src/dbg_wx_winman.erl b/lib/debugger/src/dbg_wx_winman.erl index 1daabe3435..d0ddfeb51a 100755 --- a/lib/debugger/src/dbg_wx_winman.erl +++ b/lib/debugger/src/dbg_wx_winman.erl @@ -118,9 +118,9 @@ init([]) -> {ok, #state{}}. handle_call({is_started, Title}, _From, State) -> - Reply = case lists:keysearch(Title, #win.title, State#state.wins) of - {value, Win} -> {true, Win#win.win}; - false -> false + Reply = case lists:keyfind(Title, #win.title, State#state.wins) of + false -> false; + Win -> {true, Win#win.win} end, {reply, Reply, State}. @@ -132,8 +132,8 @@ handle_cast({insert, Pid, Title, Win}, State) -> handle_cast({clear_process, Title}, State) -> OldWins = State#state.wins, - Wins = case lists:keysearch(Title, #win.title, OldWins) of - {value, #win{owner=Pid}} -> + Wins = case lists:keyfind(Title, #win.title, OldWins) of + #win{owner=Pid} -> Msg = {dbg_ui_winman, destroy}, Pid ! Msg, lists:keydelete(Title, #win.title, OldWins); @@ -145,7 +145,7 @@ handle_cast({clear_process, Title}, State) -> handle_info({'EXIT', Pid, _Reason}, State) -> [Mon | _Wins] = State#state.wins, if - Pid==Mon#win.owner -> {stop, normal, State}; + Pid =:= Mon#win.owner -> {stop, normal, State}; true -> Wins2 = lists:keydelete(Pid, #win.owner, State#state.wins), inform_all(Wins2), diff --git a/lib/debugger/src/i.erl b/lib/debugger/src/i.erl index 7c2fb22946..476a53482e 100644 --- a/lib/debugger/src/i.erl +++ b/lib/debugger/src/i.erl @@ -31,7 +31,6 @@ iv() -> Vsn = string:substr(filename:basename(code:lib_dir(debugger)), 10), list_to_atom(Vsn). - %% ------------------------------------------- %% Start a new graphical monitor. @@ -288,10 +287,9 @@ ia(X,Y,Z) -> %% ------------------------------------------- ia(Pid,Fnk) -> - case lists:keysearch(Pid, 1, int:snapshot()) of - {value, _PidTuple} -> - int:attach(Pid,Fnk); - false -> no_proc + case lists:keymember(Pid, 1, int:snapshot()) of + false -> no_proc; + true -> int:attach(Pid,Fnk) end. ia(X,Y,Z,Fnk) -> diff --git a/lib/debugger/src/int.erl b/lib/debugger/src/int.erl index eeb4df4a8e..9ee2102a19 100644 --- a/lib/debugger/src/int.erl +++ b/lib/debugger/src/int.erl @@ -261,7 +261,7 @@ del_break_in(Mod, Func, Arity) when is_atom(Mod), is_atom(Func), is_integer(Arit end. first_lines(Clauses) -> - lists:map(fun(Clause) -> first_line(Clause) end, Clauses). + [first_line(Clause) || Clause <- Clauses]. first_line({clause,_L,_Vars,_,Exprs}) -> first_line(Exprs); @@ -469,10 +469,10 @@ contents(Mod, Pid) -> %% Arity = integer() %%-------------------------------------------------------------------- functions(Mod) -> - lists:filter(fun([module_info, _Arity]) -> false; - (_Func) -> true - end, - dbg_iserver:call({functions, Mod})). + [F || F <- dbg_iserver:call({functions, Mod}), functions_1(F)]. + +functions_1([module_info, _Arity]) -> false; +functions_1(_Func) -> true. %%==================================================================== diff --git a/lib/debugger/vsn.mk b/lib/debugger/vsn.mk index 5ce37a6bde..654dc11e20 100644 --- a/lib/debugger/vsn.mk +++ b/lib/debugger/vsn.mk @@ -1 +1 @@ -DEBUGGER_VSN = 3.2.2 +DEBUGGER_VSN = 3.2.4 diff --git a/lib/dialyzer/RELEASE_NOTES b/lib/dialyzer/RELEASE_NOTES index b668142327..62b0c92f97 100644 --- a/lib/dialyzer/RELEASE_NOTES +++ b/lib/dialyzer/RELEASE_NOTES @@ -3,6 +3,19 @@ (in reversed chronological order) ============================================================================== +Version 2.3.0 (in Erlang/OTP R14) +--------------------------------- + - Dialyzer properly supports the new attribute -export_type and checks + that remote types only refer to exported types. A warning is produced + if some files/applications refer to types defined in modules which are + neither in the PLT nor in the analyzed applications. + - Support for detecting data races involving whereis/1 and unregister/1. + - More precise identification of the reason(s) why a record construction + violates the types declared for its fields. + - Fixed bug in the handling of the 'or' guard. + - Better handling of the erlang:element/2 BIF. + - Complete handling of Erlang BIFs. + Version 2.2.0 (in Erlang/OTP R13B04) ------------------------------------ - Much better support for opaque types (thanks to Manouk Manoukian). diff --git a/lib/dialyzer/doc/manual.txt b/lib/dialyzer/doc/manual.txt index dac61b74b1..470ddd6c73 100644 --- a/lib/dialyzer/doc/manual.txt +++ b/lib/dialyzer/doc/manual.txt @@ -297,7 +297,7 @@ Option :: {files, [Filename :: string()]} | {include_dirs, [DirName :: string()]} | {output_file, FileName :: string()} | {output_plt, FileName :: string()} - | {analysis_type, 'success_typings' | 'plt_add' | + | {analysis_type, 'succ_typings' | 'plt_add' | 'plt_build' | 'plt_check' | 'plt_remove'} | {warnings, [WarnOpts]} diff --git a/lib/dialyzer/doc/src/dialyzer.xml b/lib/dialyzer/doc/src/dialyzer.xml index 7f983a2c0d..1ec2ce830a 100644 --- a/lib/dialyzer/doc/src/dialyzer.xml +++ b/lib/dialyzer/doc/src/dialyzer.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>2006</year><year>2009</year> + <year>2006</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>dialyzer</title> @@ -206,7 +206,7 @@ Option : {files, [Filename : string()]} | {include_dirs, [DirName : string()]} | {output_file, FileName : string()} | {output_plt, FileName :: string()} - | {analysis_type, 'success_typings' | 'plt_add' | 'plt_build' | 'plt_check' | 'plt_remove'} + | {analysis_type, 'succ_typings' | 'plt_add' | 'plt_build' | 'plt_check' | 'plt_remove'} | {warnings, [WarnOpts]} | {get_warnings, bool()} diff --git a/lib/dialyzer/doc/src/notes.xml b/lib/dialyzer/doc/src/notes.xml index b6106b928a..ac3857b9ef 100755 --- a/lib/dialyzer/doc/src/notes.xml +++ b/lib/dialyzer/doc/src/notes.xml @@ -31,6 +31,56 @@ <p>This document describes the changes made to the Dialyzer application.</p> +<section><title>Dialyzer 2.3.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Eliminated warnings for auto-imported BIF clashes.</p> + <p> + Own Id: OTP-8840</p> + </item> + </list> + </section> + +</section> + +<section><title>Dialyzer 2.3.0</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Various changes to dialyzer-related files for R14.</p> + <p> + - Dialyzer properly supports the new attribute + -export_type and checks that remote types only refer to + exported types. A warning is produced if some + files/applications refer to types defined in modules + which are neither in the PLT nor in the analyzed + applications.</p> + <p> + - Support for detecting data races involving whereis/1 + and unregister/1.</p> + <p> + - More precise identification of the reason(s) why a + record construction violates the types declared for its + fields.</p> + <p> + - Fixed bug in the handling of the 'or' guard.</p> + <p> + - Better handling of the erlang:element/2 BIF.</p> + <p> + - Complete handling of Erlang BIFs.</p> + <p> + Own Id: OTP-8699</p> + </item> + </list> + </section> + +</section> + <section><title>Dialyzer 2.2.0</title> <section><title>Improvements and New Features</title> diff --git a/lib/dialyzer/src/dialyzer.erl b/lib/dialyzer/src/dialyzer.erl index 3b7b68e8c4..d8fd073ca6 100644 --- a/lib/dialyzer/src/dialyzer.erl +++ b/lib/dialyzer/src/dialyzer.erl @@ -33,8 +33,8 @@ %% NOTE: Only functions exported by this module are available to %% other applications. %%-------------------------------------------------------------------- --export([plain_cl/0, - run/1, +-export([plain_cl/0, + run/1, gui/0, gui/1, plt_info/1, @@ -55,7 +55,7 @@ plain_cl() -> case dialyzer_cl_parse:start() of - {check_init, Opts} -> + {check_init, Opts} -> cl_halt(cl_check_init(Opts), Opts); {plt_info, Opts} -> cl_halt(cl_print_plt_info(Opts), Opts); @@ -72,7 +72,7 @@ plain_cl() -> false -> gui_halt(internal_gui(Type, Opts), Opts) end; - {cl, Opts} -> + {cl, Opts} -> case Opts#options.check_plt of true -> case cl_check_init(Opts#options{get_warnings = false}) of @@ -82,7 +82,7 @@ plain_cl() -> false -> cl_halt(cl(Opts), Opts) end; - {error, Msg} -> + {error, Msg} -> cl_error(Msg) end. @@ -146,7 +146,7 @@ cl(Opts) -> -spec run(dial_options()) -> [dial_warning()]. run(Opts) -> - try dialyzer_options:build([{report_mode, quiet}, + try dialyzer_options:build([{report_mode, quiet}, {erlang_mode, true}|Opts]) of {error, Msg} -> throw({dialyzer_error, Msg}); @@ -161,7 +161,7 @@ run(Opts) -> throw({dialyzer_error, ErrorMsg1}) end catch - throw:{dialyzer_error, ErrorMsg} -> + throw:{dialyzer_error, ErrorMsg} -> erlang:error({dialyzer_error, lists:flatten(ErrorMsg)}) end. @@ -226,7 +226,7 @@ plt_info(Plt) -> %%----------- doit(F) -> - try + try {ok, F()} catch throw:{dialyzer_error, Msg} -> @@ -241,9 +241,9 @@ gui_halt(R, Opts) -> -spec cl_halt({'ok',dial_ret()} | {'error',string()}, #options{}) -> no_return(). -cl_halt({ok, R = ?RET_NOTHING_SUSPICIOUS}, #options{report_mode = quiet}) -> +cl_halt({ok, R = ?RET_NOTHING_SUSPICIOUS}, #options{report_mode = quiet}) -> halt(R); -cl_halt({ok, R = ?RET_DISCREPANCIES}, #options{report_mode = quiet}) -> +cl_halt({ok, R = ?RET_DISCREPANCIES}, #options{report_mode = quiet}) -> halt(R); cl_halt({ok, R = ?RET_NOTHING_SUSPICIOUS}, #options{}) -> io:put_chars("done (passed successfully)\n"), @@ -267,7 +267,7 @@ cl_check_log(Output) -> -spec format_warning(dial_warning()) -> string(). -format_warning({_Tag, {File, Line}, Msg}) when is_list(File), +format_warning({_Tag, {File, Line}, Msg}) when is_list(File), is_integer(Line) -> BaseName = filename:basename(File), String = lists:flatten(message_to_string(Msg)), @@ -290,7 +290,7 @@ message_to_string({app_call, [M, F, Args, Culprit, ExpectedType, FoundType]}) -> message_to_string({bin_construction, [Culprit, Size, Seg, Type]}) -> io_lib:format("Binary construction will fail since the ~s field ~s in" " segment ~s has type ~s\n", [Culprit, Size, Seg, Type]); -message_to_string({call, [M, F, Args, ArgNs, FailReason, +message_to_string({call, [M, F, Args, ArgNs, FailReason, SigArgs, SigRet, Contract]}) -> io_lib:format("The call ~w:~w~s ", [M, F, Args]) ++ call_or_apply_to_string(ArgNs, FailReason, SigArgs, SigRet, Contract); @@ -329,9 +329,9 @@ message_to_string({no_return, [Type|Name]}) -> only_normal -> NameString ++ "has no local return\n"; both -> NameString ++ "has no local return\n" end; -message_to_string({record_constr, [Types, Name]}) -> +message_to_string({record_constr, [RecConstr, FieldDiffs]}) -> io_lib:format("Record construction ~s violates the" - " declared type for #~w{}\n", [Types, Name]); + " declared type of field ~s\n", [RecConstr, FieldDiffs]); message_to_string({record_constr, [Name, Field, Type]}) -> io_lib:format("Record construction violates the declared type for #~w{}" " since ~s cannot be of type ~s\n", [Name, Field, Type]); @@ -358,7 +358,7 @@ message_to_string({contract_diff, [M, F, _A, Contract, Sig]}) -> [M, F, Contract, M, F, Sig]); message_to_string({contract_subtype, [M, F, _A, Contract, Sig]}) -> io_lib:format("Type specification ~w:~w~s" - " is a subtype of the success typing: ~w:~w~s\n", + " is a subtype of the success typing: ~w:~w~s\n", [M, F, Contract, M, F, Sig]); message_to_string({contract_supertype, [M, F, _A, Contract, Sig]}) -> io_lib:format("Type specification ~w:~w~s" @@ -427,7 +427,7 @@ message_to_string({spec_missing, [B, F, A]}) -> %% Auxiliary functions below %%----------------------------------------------------------------------------- -call_or_apply_to_string(ArgNs, FailReason, SigArgs, SigRet, +call_or_apply_to_string(ArgNs, FailReason, SigArgs, SigRet, {IsOverloaded, Contract}) -> PositionString = form_position_string(ArgNs), case FailReason of @@ -442,7 +442,7 @@ call_or_apply_to_string(ArgNs, FailReason, SigArgs, SigRet, " from the success typing arguments: ~s\n", [PositionString, SigArgs]) end; - only_contract -> + only_contract -> case (ArgNs =:= []) orelse IsOverloaded of true -> %% We do not know which arguments caused the failure @@ -494,7 +494,7 @@ form_position_string(ArgNs) -> case ArgNs of [] -> ""; [N1] -> ordinal(N1); - [_,_|_] -> + [_,_|_] -> [Last|Prevs] = lists:reverse(ArgNs), ", " ++ Head = lists:flatten([io_lib:format(", ~s",[ordinal(N)]) || N <- lists:reverse(Prevs)]), diff --git a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl index ab1bbe5ade..3438cc8c7e 100644 --- a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl +++ b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl @@ -96,6 +96,9 @@ loop(#server_state{parent = Parent, legal_warnings = LegalWarnings} = State, end; {AnalPid, ext_calls, NewExtCalls} -> loop(State, Analysis, NewExtCalls); + {AnalPid, ext_types, ExtTypes} -> + send_ext_types(Parent, ExtTypes), + loop(State, Analysis, ExtCalls); {AnalPid, unknown_behaviours, UnknownBehaviour} -> send_unknown_behaviours(Parent, UnknownBehaviour), loop(State, Analysis, ExtCalls); @@ -123,8 +126,7 @@ analysis_start(Parent, Analysis) -> parent = Parent, start_from = Analysis#analysis.start_from, use_contracts = Analysis#analysis.use_contracts, - behaviours = {Analysis#analysis.behaviours_chk, - []} + behaviours = {Analysis#analysis.behaviours_chk, []} }, Files = ordsets:from_list(Analysis#analysis.files), {Callgraph, NoWarn, TmpCServer0} = compile_and_store(Files, State), @@ -132,22 +134,36 @@ analysis_start(Parent, Analysis) -> NewCServer = try NewRecords = dialyzer_codeserver:get_temp_records(TmpCServer0), - OldRecords = dialyzer_plt:get_types(State#analysis_state.plt), + NewExpTypes = dialyzer_codeserver:get_temp_exported_types(TmpCServer0), + OldRecords = dialyzer_plt:get_types(Plt), + OldExpTypes0 = dialyzer_plt:get_exported_types(Plt), MergedRecords = dialyzer_utils:merge_records(NewRecords, OldRecords), + RemMods = + [case Analysis#analysis.start_from of + byte_code -> list_to_atom(filename:basename(F, ".beam")); + src_code -> list_to_atom(filename:basename(F, ".erl")) + end || F <- Files], + OldExpTypes1 = dialyzer_utils:sets_filter(RemMods, OldExpTypes0), + MergedExpTypes = sets:union(NewExpTypes, OldExpTypes1), TmpCServer1 = dialyzer_codeserver:set_temp_records(MergedRecords, TmpCServer0), - TmpCServer2 = dialyzer_utils:process_record_remote_types(TmpCServer1), - dialyzer_contracts:process_contract_remote_types(TmpCServer2) + TmpCServer2 = + dialyzer_codeserver:insert_temp_exported_types(MergedExpTypes, + TmpCServer1), + TmpCServer3 = dialyzer_utils:process_record_remote_types(TmpCServer2), + dialyzer_contracts:process_contract_remote_types(TmpCServer3) catch throw:{error, _ErrorMsg} = Error -> exit(Error) end, - NewPlt = dialyzer_plt:insert_types(Plt, dialyzer_codeserver:get_records(NewCServer)), - State0 = State#analysis_state{plt = NewPlt}, + NewPlt0 = dialyzer_plt:insert_types(Plt, dialyzer_codeserver:get_records(NewCServer)), + ExpTypes = dialyzer_codeserver:get_exported_types(NewCServer), + NewPlt1 = dialyzer_plt:insert_exported_types(NewPlt0, ExpTypes), + State0 = State#analysis_state{plt = NewPlt1}, dump_callgraph(Callgraph, State0, Analysis), State1 = State0#analysis_state{codeserver = NewCServer}, State2 = State1#analysis_state{no_warn_unused = NoWarn}, %% Remove all old versions of the files being analyzed AllNodes = dialyzer_callgraph:all_nodes(Callgraph), - Plt1 = dialyzer_plt:delete_list(NewPlt, AllNodes), + Plt1 = dialyzer_plt:delete_list(NewPlt1, AllNodes), Exports = dialyzer_codeserver:get_exports(NewCServer), NewCallgraph = case Analysis#analysis.race_detection of @@ -155,6 +171,7 @@ analysis_start(Parent, Analysis) -> false -> Callgraph end, State3 = analyze_callgraph(NewCallgraph, State2#analysis_state{plt = Plt1}), + rcv_and_send_ext_types(Parent), NonExports = sets:subtract(sets:from_list(AllNodes), Exports), NonExportsList = sets:to_list(NonExports), Plt3 = dialyzer_plt:delete_list(State3#analysis_state.plt, NonExportsList), @@ -371,14 +388,28 @@ compile_byte(File, Callgraph, CServer, UseContracts) -> store_core(Mod, Core, NoWarn, Callgraph, CServer) -> Exp = get_exports_from_core(Core), + OldExpTypes = dialyzer_codeserver:get_temp_exported_types(CServer), + NewExpTypes = get_exported_types_from_core(Core), + MergedExpTypes = sets:union(NewExpTypes, OldExpTypes), CServer1 = dialyzer_codeserver:insert_exports(Exp, CServer), - {LabeledCore, CServer2} = label_core(Core, CServer1), - store_code_and_build_callgraph(Mod, LabeledCore, Callgraph, CServer2, NoWarn). + CServer2 = dialyzer_codeserver:insert_temp_exported_types(MergedExpTypes, + CServer1), + {LabeledCore, CServer3} = label_core(Core, CServer2), + store_code_and_build_callgraph(Mod, LabeledCore, Callgraph, CServer3, NoWarn). abs_get_nowarn(Abs, M) -> - [{M, F, A} + [{M, F, A} || {attribute, _, compile, {nowarn_unused_function, {F, A}}} <- Abs]. +get_exported_types_from_core(Core) -> + Attrs = cerl:module_attrs(Core), + ExpTypes1 = [cerl:concrete(L2) || {L1, L2} <- Attrs, cerl:is_literal(L1), + cerl:is_literal(L2), + cerl:concrete(L1) =:= 'export_type'], + ExpTypes2 = lists:flatten(ExpTypes1), + M = cerl:atom_val(cerl:module_name(Core)), + sets:from_list([{M, F, A} || {F, A} <- ExpTypes2]). + get_exports_from_core(Core) -> Tree = cerl:from_records(Core), Exports1 = cerl:module_exports(Tree), @@ -390,7 +421,7 @@ label_core(Core, CServer) -> NextLabel = dialyzer_codeserver:get_next_core_label(CServer), CoreTree = cerl:from_records(Core), {LabeledTree, NewNextLabel} = cerl_trees:label(CoreTree, NextLabel), - {cerl:to_records(LabeledTree), + {cerl:to_records(LabeledTree), dialyzer_codeserver:set_next_core_label(NewNextLabel, CServer)}. store_code_and_build_callgraph(Mod, Core, Callgraph, CServer, NoWarn) -> @@ -454,6 +485,20 @@ default_includes(Dir) -> %% Handle Messages %%------------------------------------------------------------------- +rcv_and_send_ext_types(Parent) -> + Self = self(), + Self ! {Self, done}, + ExtTypes = rcv_ext_types(Self, []), + Parent ! {Self, ext_types, ExtTypes}, + ok. + +rcv_ext_types(Self, ExtTypes) -> + receive + {Self, ext_types, ExtType} -> + rcv_ext_types(Self, [ExtType|ExtTypes]); + {Self, done} -> lists:usort(ExtTypes) + end. + send_log(Parent, Msg) -> Parent ! {self(), log, Msg}, ok. @@ -471,11 +516,15 @@ filter_warnings(LegalWarnings, Warnings) -> send_analysis_done(Parent, Plt, DocPlt) -> Parent ! {self(), done, Plt, DocPlt}, ok. - + send_ext_calls(Parent, ExtCalls) -> Parent ! {self(), ext_calls, ExtCalls}, ok. +send_ext_types(Parent, ExtTypes) -> + Parent ! {self(), ext_types, ExtTypes}, + ok. + send_unknown_behaviours(Parent, UnknownBehaviours) -> Parent ! {self(), unknown_behaviours, UnknownBehaviours}, ok. @@ -491,7 +540,7 @@ send_mod_deps(Parent, ModuleDeps) -> Parent ! {self(), mod_deps, ModuleDeps}, ok. -format_bad_calls([{{_, _, _}, {_, module_info, A}}|Left], CodeServer, Acc) +format_bad_calls([{{_, _, _}, {_, module_info, A}}|Left], CodeServer, Acc) when A =:= 0; A =:= 1 -> format_bad_calls(Left, CodeServer, Acc); format_bad_calls([{FromMFA, {M, F, A} = To}|Left], CodeServer, Acc) -> @@ -504,7 +553,7 @@ format_bad_calls([], _CodeServer, Acc) -> Acc. find_call_file_and_line(Tree, MFA) -> - Fun = + Fun = fun(SubTree, Acc) -> case cerl:is_c_call(SubTree) of true -> diff --git a/lib/dialyzer/src/dialyzer_behaviours.erl b/lib/dialyzer/src/dialyzer_behaviours.erl index 4e8dceaa8e..47ce9ba6eb 100644 --- a/lib/dialyzer/src/dialyzer_behaviours.erl +++ b/lib/dialyzer/src/dialyzer_behaviours.erl @@ -34,19 +34,25 @@ translate_behaviour_api_call/5, translatable_behaviours/1, translate_callgraph/3]). +-export_type([behaviour/0, behaviour_api_dict/0]). + %%-------------------------------------------------------------------- -include("dialyzer.hrl"). %%-------------------------------------------------------------------- +-type behaviour() :: atom(). + -record(state, {plt :: dialyzer_plt:plt(), codeserver :: dialyzer_codeserver:codeserver(), - filename :: string(), - behlines :: [{atom(), number()}]}). + filename :: file:filename(), + behlines :: [{behaviour(), non_neg_integer()}]}). + +%%-------------------------------------------------------------------- -spec get_behaviours([module()], dialyzer_codeserver:codeserver()) -> - {[atom()], [atom()]}. + {[behaviour()], [behaviour()]}. get_behaviours(Modules, Codeserver) -> get_behaviours(Modules, Codeserver, [], []). @@ -59,29 +65,37 @@ check_callbacks(Module, Attrs, Plt, Codeserver) -> {Behaviours, BehLines} = get_behaviours(Attrs), case Behaviours of [] -> []; - _ -> {_Var,Code} = - dialyzer_codeserver:lookup_mfa_code({Module,module_info,0}, - Codeserver), - File = get_file(cerl:get_ann(Code)), - State = #state{plt = Plt, codeserver = Codeserver, filename = File, - behlines = BehLines}, - Warnings = get_warnings(Module, Behaviours, State), - [add_tag_file_line(Module, W, State) || W <- Warnings] + _ -> + MFA = {Module,module_info,0}, + {_Var,Code} = dialyzer_codeserver:lookup_mfa_code(MFA, Codeserver), + File = get_file(cerl:get_ann(Code)), + State = #state{plt = Plt, codeserver = Codeserver, filename = File, + behlines = BehLines}, + Warnings = get_warnings(Module, Behaviours, State), + [add_tag_file_line(Module, W, State) || W <- Warnings] end. --spec translatable_behaviours(cerl:c_module()) -> [{atom(),[_]}]. +-spec translatable_behaviours(cerl:c_module()) -> behaviour_api_dict(). translatable_behaviours(Tree) -> Attrs = cerl:module_attrs(Tree), {Behaviours, _BehLines} = get_behaviours(Attrs), [{B, Calls} || B <- Behaviours, (Calls = behaviour_api_calls(B)) =/= []]. --spec get_behaviour_apis([atom()]) -> [mfa()]. +-spec get_behaviour_apis([behaviour()]) -> [mfa()]. get_behaviour_apis(Behaviours) -> get_behaviour_apis(Behaviours, []). --spec translate_behaviour_api_call(_, _, _, _, _) -> _. +-spec translate_behaviour_api_call(dialyzer_races:mfa_or_funlbl(), + [erl_types:erl_type()], + [dialyzer_races:core_vars()], + module(), + behaviour_api_dict()) -> + {dialyzer_races:mfa_or_funlbl(), + [erl_types:erl_type()], + [dialyzer_races:core_vars()]} + | 'plain_call'. translate_behaviour_api_call(_Fun, _ArgTypes, _Args, _Module, []) -> plain_call; @@ -101,8 +115,9 @@ translate_behaviour_api_call({Module, Fun, Arity}, ArgTypes, Args, translate_behaviour_api_call(_Fun, _ArgTypes, _Args, _Module, _BehApiInfo) -> plain_call. --spec translate_callgraph([{atom(), _}], atom(), dialyzer_callgraph:callgraph()) - -> dialyzer_callgraph:callgraph(). +-spec translate_callgraph(behaviour_api_dict(), atom(), + dialyzer_callgraph:callgraph()) -> + dialyzer_callgraph:callgraph(). translate_callgraph([{Behaviour,_}|Behaviours], Module, Callgraph) -> UsedCalls = [Call || {_From, {M, _F, _A}} = Call <- @@ -156,9 +171,11 @@ check_all_callbacks(Module, Behaviour, Callbacks, State) -> check_all_callbacks(_Module, _Behaviour, [], _State, Acc) -> Acc; -check_all_callbacks(Module, Behaviour, [{Fun, Arity, Spec}|Rest], State, Acc) -> - Records = dialyzer_codeserver:get_records(State#state.codeserver), - case parse_spec(Spec, Records) of +check_all_callbacks(Module, Behaviour, [{Fun, Arity, Spec}|Rest], + #state{codeserver = CServer} = State, Acc) -> + Records = dialyzer_codeserver:get_records(CServer), + ExpTypes = dialyzer_codeserver:get_exported_types(CServer), + case parse_spec(Spec, ExpTypes, Records) of {ok, Fun, Type} -> RetType = erl_types:t_fun_range(Type), ArgTypes = erl_types:t_fun_args(Type), @@ -172,7 +189,7 @@ check_all_callbacks(Module, Behaviour, [{Fun, Arity}|Rest], State, Acc) -> Warns = {spec_missing, [Behaviour, Fun, Arity]}, check_all_callbacks(Module, Behaviour, Rest, State, [Warns|Acc]). -parse_spec(String, Records) -> +parse_spec(String, ExpTypes, Records) -> case erl_scan:string(String) of {ok, Tokens, _} -> case erl_parse:parse(Tokens) of @@ -181,7 +198,8 @@ parse_spec(String, Records) -> {attribute, _, 'spec', {{Fun, _}, [TypeForm|_Constraint]}} -> MaybeRemoteType = erl_types:t_from_form(TypeForm), try - Type = erl_types:t_solve_remote(MaybeRemoteType, Records), + Type = erl_types:t_solve_remote(MaybeRemoteType, ExpTypes, + Records), {ok, Fun, Type} catch throw:{error,Msg} -> {spec_remote_error, Msg} @@ -260,7 +278,7 @@ get_line([]) -> -1. get_file([{file, File}|_]) -> File; get_file([_|Tail]) -> get_file(Tail). -%%------------------------------------------------------------------------------ +%%----------------------------------------------------------------------------- get_behaviours([], _Codeserver, KnownAcc, UnknownAcc) -> {KnownAcc, UnknownAcc}; @@ -289,7 +307,7 @@ call_behaviours([Behaviour|Rest], KnownAcc, UnknownAcc) -> _:_ -> call_behaviours(Rest, KnownAcc, [Behaviour | UnknownAcc]) end. -%------------------------------------------------------------------------------- +%------------------------------------------------------------------------------ get_behaviour_apis([], Acc) -> Acc; @@ -298,14 +316,22 @@ get_behaviour_apis([Behaviour | Rest], Acc) -> {{Fun, Arity}, _} <- behaviour_api_calls(Behaviour)], get_behaviour_apis(Rest, MFAs ++ Acc). -%------------------------------------------------------------------------------- +%------------------------------------------------------------------------------ nth_or_0(0, _List, Zero) -> Zero; nth_or_0(N, List, _Zero) -> lists:nth(N, List). -%------------------------------------------------------------------------------- +%------------------------------------------------------------------------------ + +-type behaviour_api_dict()::[{behaviour(), behaviour_api_info()}]. +-type behaviour_api_info()::[{original_fun(), replacement_fun()}]. +-type original_fun()::{atom(), arity()}. +-type replacement_fun()::{atom(), arity(), arg_list()}. +-type arg_list()::[byte()]. + +-spec behaviour_api_calls(behaviour()) -> behaviour_api_info(). behaviour_api_calls(gen_server) -> [{{start_link, 3}, {init, 1, [2]}}, diff --git a/lib/dialyzer/src/dialyzer_callgraph.erl b/lib/dialyzer/src/dialyzer_callgraph.erl index f932f43548..d3de5aaf45 100644 --- a/lib/dialyzer/src/dialyzer_callgraph.erl +++ b/lib/dialyzer/src/dialyzer_callgraph.erl @@ -59,6 +59,8 @@ put_named_tables/2, put_public_tables/2, put_behaviour_api_calls/2, get_behaviour_api_calls/1]). +-export_type([callgraph/0]). + -include("dialyzer.hrl"). %%---------------------------------------------------------------------- diff --git a/lib/dialyzer/src/dialyzer_cl.erl b/lib/dialyzer/src/dialyzer_cl.erl index d533e734db..616e2465dc 100644 --- a/lib/dialyzer/src/dialyzer_cl.erl +++ b/lib/dialyzer/src/dialyzer_cl.erl @@ -29,6 +29,10 @@ -module(dialyzer_cl). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). +%% Avoid warning for local function error/2 clashing with autoimported BIF. +-compile({no_auto_import,[error/2]}). -export([start/1]). -include("dialyzer.hrl"). @@ -38,6 +42,7 @@ {backend_pid :: pid(), erlang_mode = false :: boolean(), external_calls = [] :: [mfa()], + external_types = [] :: [mfa()], legal_warnings = ordsets:new() :: [dial_warn_tag()], mod_deps = dict:new() :: dict(), output = standard_io :: io:device(), @@ -47,7 +52,7 @@ report_mode = normal :: rep_mode(), return_status= ?RET_NOTHING_SUSPICIOUS :: dial_ret(), stored_warnings = [] :: [dial_warning()], - unknown_behaviours = [] :: [atom()] + unknown_behaviours = [] :: [dialyzer_behaviours:behaviour()] }). %%-------------------------------------------------------------------- @@ -538,6 +543,8 @@ cl_loop(State, LogCache) -> return_value(State, NewPlt); {BackendPid, ext_calls, ExtCalls} -> cl_loop(State#cl_state{external_calls = ExtCalls}, LogCache); + {BackendPid, ext_types, ExtTypes} -> + cl_loop(State#cl_state{external_types = ExtTypes}, LogCache); {BackendPid, mod_deps, ModDeps} -> NewState = State#cl_state{mod_deps = ModDeps}, cl_loop(NewState, LogCache); @@ -574,7 +581,7 @@ format_log_cache(LogCache) -> store_warnings(#cl_state{stored_warnings = StoredWarnings} = St, Warnings) -> St#cl_state{stored_warnings = StoredWarnings ++ Warnings}. --spec store_unknown_behaviours(#cl_state{}, [_]) -> #cl_state{}. +-spec store_unknown_behaviours(#cl_state{}, [dialyzer_behaviours:behaviour()]) -> #cl_state{}. store_unknown_behaviours(#cl_state{unknown_behaviours = Behs} = St, Beh) -> St#cl_state{unknown_behaviours = Beh ++ Behs}. @@ -613,6 +620,7 @@ return_value(State = #cl_state{erlang_mode = ErlangMode, false -> print_warnings(State), print_ext_calls(State), + print_ext_types(State), print_unknown_behaviours(State), maybe_close_output_file(State), {RetValue, []}; @@ -649,10 +657,41 @@ do_print_ext_calls(Output, [{M,F,A}|T], Before) -> do_print_ext_calls(_, [], _) -> ok. +print_ext_types(#cl_state{report_mode = quiet}) -> + ok; +print_ext_types(#cl_state{output = Output, + external_calls = Calls, + external_types = Types, + stored_warnings = Warnings, + output_format = Format}) -> + case Types =:= [] of + true -> ok; + false -> + case Warnings =:= [] andalso Calls =:= [] of + true -> io:nl(Output); %% Need to do a newline first + false -> ok + end, + case Format of + formatted -> + io:put_chars(Output, "Unknown types:\n"), + do_print_ext_types(Output, Types, " "); + raw -> + io:put_chars(Output, "%% Unknown types:\n"), + do_print_ext_types(Output, Types, "%% ") + end + end. + +do_print_ext_types(Output, [{M,F,A}|T], Before) -> + io:format(Output, "~s~p:~p/~p\n", [Before,M,F,A]), + do_print_ext_types(Output, T, Before); +do_print_ext_types(_, [], _) -> + ok. + %%print_unknown_behaviours(#cl_state{report_mode = quiet}) -> %% ok; print_unknown_behaviours(#cl_state{output = Output, external_calls = Calls, + external_types = Types, stored_warnings = Warnings, unknown_behaviours = DupBehaviours, legal_warnings = LegalWarnings, @@ -662,7 +701,7 @@ print_unknown_behaviours(#cl_state{output = Output, false -> ok; true -> Behaviours = lists:usort(DupBehaviours), - case Warnings =:= [] andalso Calls =:= [] of + case Warnings =:= [] andalso Calls =:= [] andalso Types =:= [] of true -> io:nl(Output); %% Need to do a newline first false -> ok end, diff --git a/lib/dialyzer/src/dialyzer_cl_parse.erl b/lib/dialyzer/src/dialyzer_cl_parse.erl index 9a522e906a..0160b84abc 100644 --- a/lib/dialyzer/src/dialyzer_cl_parse.erl +++ b/lib/dialyzer/src/dialyzer_cl_parse.erl @@ -20,6 +20,8 @@ -module(dialyzer_cl_parse). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([start/0]). -export([collect_args/1]). % used also by typer_options.erl diff --git a/lib/dialyzer/src/dialyzer_codeserver.erl b/lib/dialyzer/src/dialyzer_codeserver.erl index 3bc5fadc21..b2097f7e53 100644 --- a/lib/dialyzer/src/dialyzer_codeserver.erl +++ b/lib/dialyzer/src/dialyzer_codeserver.erl @@ -21,7 +21,7 @@ %%%------------------------------------------------------------------- %%% File : dialyzer_codeserver.erl %%% Author : Tobias Lindahl <[email protected]> -%%% Description : +%%% Description : %%% %%% Created : 4 Apr 2005 by Tobias Lindahl <[email protected]> %%%------------------------------------------------------------------- @@ -29,15 +29,19 @@ -export([delete/1, finalize_contracts/2, + finalize_exported_types/2, finalize_records/2, get_contracts/1, - get_exports/1, + get_exported_types/1, + get_exports/1, get_records/1, get_next_core_label/1, get_temp_contracts/1, + get_temp_exported_types/1, get_temp_records/1, - insert/3, - insert_exports/2, + insert/3, + insert_exports/2, + insert_temp_exported_types/2, is_exported/2, lookup_mod_code/2, lookup_mfa_code/2, @@ -52,17 +56,21 @@ store_contracts/3, store_temp_contracts/3]). +-export_type([codeserver/0]). + -include("dialyzer.hrl"). %%-------------------------------------------------------------------- --record(codeserver, {table_pid :: pid(), - exports = sets:new() :: set(), % set(mfa()) - next_core_label = 0 :: label(), - records = dict:new() :: dict(), - temp_records = dict:new() :: dict(), - contracts = dict:new() :: dict(), - temp_contracts = dict:new() :: dict()}). +-record(codeserver, {table_pid :: pid(), + exported_types = sets:new() :: set(), % set(mfa()) + temp_exported_types = sets:new() :: set(), % set(mfa()) + exports = sets:new() :: set(), % set(mfa()) + next_core_label = 0 :: label(), + records = dict:new() :: dict(), + temp_records = dict:new() :: dict(), + contracts = dict:new() :: dict(), + temp_contracts = dict:new() :: dict()}). -opaque codeserver() :: #codeserver{}. @@ -78,12 +86,17 @@ new() -> delete(#codeserver{table_pid = TablePid}) -> table__delete(TablePid). --spec insert(module(), cerl:c_module(), codeserver()) -> codeserver(). +-spec insert(atom(), cerl:c_module(), codeserver()) -> codeserver(). insert(Mod, ModCode, CS) -> NewTablePid = table__insert(CS#codeserver.table_pid, Mod, ModCode), CS#codeserver{table_pid = NewTablePid}. +-spec insert_temp_exported_types(set(), codeserver()) -> codeserver(). + +insert_temp_exported_types(Set, CS) -> + CS#codeserver{temp_exported_types = Set}. + -spec insert_exports([mfa()], codeserver()) -> codeserver(). insert_exports(List, #codeserver{exports = Exports} = CS) -> @@ -96,12 +109,27 @@ insert_exports(List, #codeserver{exports = Exports} = CS) -> is_exported(MFA, #codeserver{exports = Exports}) -> sets:is_element(MFA, Exports). +-spec get_exported_types(codeserver()) -> set(). % set(mfa()) + +get_exported_types(#codeserver{exported_types = ExpTypes}) -> + ExpTypes. + +-spec get_temp_exported_types(codeserver()) -> set(). + +get_temp_exported_types(#codeserver{temp_exported_types = TempExpTypes}) -> + TempExpTypes. + -spec get_exports(codeserver()) -> set(). % set(mfa()) get_exports(#codeserver{exports = Exports}) -> Exports. --spec lookup_mod_code(module(), codeserver()) -> cerl:c_module(). +-spec finalize_exported_types(set(), codeserver()) -> codeserver(). + +finalize_exported_types(Set, CS) -> + CS#codeserver{exported_types = Set, temp_exported_types = sets:new()}. + +-spec lookup_mod_code(atom(), codeserver()) -> cerl:c_module(). lookup_mod_code(Mod, CS) when is_atom(Mod) -> table__lookup(CS#codeserver.table_pid, Mod). @@ -121,7 +149,7 @@ get_next_core_label(#codeserver{next_core_label = NCL}) -> set_next_core_label(NCL, CS) -> CS#codeserver{next_core_label = NCL}. --spec store_records(module(), dict(), codeserver()) -> codeserver(). +-spec store_records(atom(), dict(), codeserver()) -> codeserver(). store_records(Mod, Dict, #codeserver{records = RecDict} = CS) when is_atom(Mod) -> @@ -130,7 +158,7 @@ store_records(Mod, Dict, #codeserver{records = RecDict} = CS) false -> CS#codeserver{records = dict:store(Mod, Dict, RecDict)} end. --spec lookup_mod_records(module(), codeserver()) -> dict(). +-spec lookup_mod_records(atom(), codeserver()) -> dict(). lookup_mod_records(Mod, #codeserver{records = RecDict}) when is_atom(Mod) -> @@ -139,12 +167,12 @@ lookup_mod_records(Mod, #codeserver{records = RecDict}) {ok, Dict} -> Dict end. --spec get_records(codeserver()) -> dict(). +-spec get_records(codeserver()) -> dict(). get_records(#codeserver{records = RecDict}) -> RecDict. --spec store_temp_records(module(), dict(), codeserver()) -> codeserver(). +-spec store_temp_records(atom(), dict(), codeserver()) -> codeserver(). store_temp_records(Mod, Dict, #codeserver{temp_records = TempRecDict} = CS) when is_atom(Mod) -> @@ -153,7 +181,7 @@ store_temp_records(Mod, Dict, #codeserver{temp_records = TempRecDict} = CS) false -> CS#codeserver{temp_records = dict:store(Mod, Dict, TempRecDict)} end. --spec get_temp_records(codeserver()) -> dict(). +-spec get_temp_records(codeserver()) -> dict(). get_temp_records(#codeserver{temp_records = TempRecDict}) -> TempRecDict. @@ -163,12 +191,12 @@ get_temp_records(#codeserver{temp_records = TempRecDict}) -> set_temp_records(Dict, CS) -> CS#codeserver{temp_records = Dict}. --spec finalize_records(dict(), codeserver()) -> codeserver(). +-spec finalize_records(dict(), codeserver()) -> codeserver(). finalize_records(Dict, CS) -> CS#codeserver{records = Dict, temp_records = dict:new()}. --spec store_contracts(module(), dict(), codeserver()) -> codeserver(). +-spec store_contracts(atom(), dict(), codeserver()) -> codeserver(). store_contracts(Mod, Dict, #codeserver{contracts = C} = CS) when is_atom(Mod) -> case dict:size(Dict) =:= 0 of @@ -176,7 +204,7 @@ store_contracts(Mod, Dict, #codeserver{contracts = C} = CS) when is_atom(Mod) -> false -> CS#codeserver{contracts = dict:store(Mod, Dict, C)} end. --spec lookup_mod_contracts(module(), codeserver()) -> dict(). +-spec lookup_mod_contracts(atom(), codeserver()) -> dict(). lookup_mod_contracts(Mod, #codeserver{contracts = ContDict}) when is_atom(Mod) -> @@ -185,7 +213,7 @@ lookup_mod_contracts(Mod, #codeserver{contracts = ContDict}) {ok, Dict} -> Dict end. --spec lookup_mfa_contract(mfa(), codeserver()) -> +-spec lookup_mfa_contract(mfa(), codeserver()) -> 'error' | {'ok', dialyzer_contracts:file_contract()}. lookup_mfa_contract({M,_F,_A} = MFA, #codeserver{contracts = ContDict}) -> @@ -194,12 +222,12 @@ lookup_mfa_contract({M,_F,_A} = MFA, #codeserver{contracts = ContDict}) -> {ok, Dict} -> dict:find(MFA, Dict) end. --spec get_contracts(codeserver()) -> dict(). +-spec get_contracts(codeserver()) -> dict(). get_contracts(#codeserver{contracts = ContDict}) -> ContDict. --spec store_temp_contracts(module(), dict(), codeserver()) -> codeserver(). +-spec store_temp_contracts(atom(), dict(), codeserver()) -> codeserver(). store_temp_contracts(Mod, Dict, #codeserver{temp_contracts = C} = CS) when is_atom(Mod) -> @@ -263,7 +291,7 @@ table__loop(Cached, Map) -> Pid ! {self(), Mod, Ans}, table__loop({Mod, Ans}, Map); {insert, List} -> - NewMap = lists:foldl(fun({Key, Val}, AccMap) -> + NewMap = lists:foldl(fun({Key, Val}, AccMap) -> dict:store(Key, Val, AccMap) end, Map, List), table__loop(Cached, NewMap) diff --git a/lib/dialyzer/src/dialyzer_contracts.erl b/lib/dialyzer/src/dialyzer_contracts.erl index 3486c72748..bf80c6f470 100644 --- a/lib/dialyzer/src/dialyzer_contracts.erl +++ b/lib/dialyzer/src/dialyzer_contracts.erl @@ -21,7 +21,7 @@ -module(dialyzer_contracts). -export([check_contract/2, - check_contracts/3, + check_contracts/3, contracts_without_fun/3, contract_to_string/1, get_invalid_contract_warnings/3, @@ -33,6 +33,8 @@ process_contract_remote_types/1, store_tmp_contract/5]). +-export_type([file_contract/0, plt_contracts/0]). + %%----------------------------------------------------------------------- -include("dialyzer.hrl"). @@ -50,7 +52,7 @@ %% to expand records and/or remote types that they might contain. %%----------------------------------------------------------------------- --type tmp_contract_fun() :: fun((dict()) -> contract_pair()). +-type tmp_contract_fun() :: fun((set(), dict()) -> contract_pair()). -record(tmp_contract, {contract_funs = [] :: [tmp_contract_fun()], forms = [] :: [{_, _}]}). @@ -104,13 +106,13 @@ contract_to_string(#contract{forms = Forms}) -> contract_to_string_1([{Contract, []}]) -> strip_fun(erl_types:t_form_to_string(Contract)); contract_to_string_1([{Contract, []}|Rest]) -> - strip_fun(erl_types:t_form_to_string(Contract)) ++ "\n ; " + strip_fun(erl_types:t_form_to_string(Contract)) ++ "\n ; " ++ contract_to_string_1(Rest); contract_to_string_1([{Contract, Constraints}]) -> - strip_fun(erl_types:t_form_to_string(Contract)) ++ " when " + strip_fun(erl_types:t_form_to_string(Contract)) ++ " when " ++ constraints_to_string(Constraints); contract_to_string_1([{Contract, Constraints}|Rest]) -> - strip_fun(erl_types:t_form_to_string(Contract)) ++ " when " + strip_fun(erl_types:t_form_to_string(Contract)) ++ " when " ++ constraints_to_string(Constraints) ++ ";" ++ contract_to_string_1(Rest). @@ -128,7 +130,7 @@ constraints_to_string([{type, _, constraint, [{atom, _, What}, Types]}]) -> sequence([erl_types:t_form_to_string(T) || T <- Types], ",") ++ ")"; constraints_to_string([{type, _, constraint, [{atom, _, What}, Types]}|Rest]) -> atom_to_list(What) ++ "(" ++ - sequence([erl_types:t_form_to_string(T) || T <- Types], ",") + sequence([erl_types:t_form_to_string(T) || T <- Types], ",") ++ "), " ++ constraints_to_string(Rest). sequence([], _Delimiter) -> ""; @@ -140,10 +142,11 @@ sequence([H|T], Delimiter) -> H ++ Delimiter ++ sequence(T, Delimiter). process_contract_remote_types(CodeServer) -> TmpContractDict = dialyzer_codeserver:get_temp_contracts(CodeServer), + ExpTypes = dialyzer_codeserver:get_exported_types(CodeServer), RecordDict = dialyzer_codeserver:get_records(CodeServer), ContractFun = fun({_M, _F, _A}, {File, #tmp_contract{contract_funs = CFuns, forms = Forms}}) -> - NewCs = [CFun(RecordDict) || CFun <- CFuns], + NewCs = [CFun(ExpTypes, RecordDict) || CFun <- CFuns], Args = general_domain(NewCs), {File, #contract{contracts = NewCs, args = Args, forms = Forms}} end, @@ -153,21 +156,21 @@ process_contract_remote_types(CodeServer) -> end, NewContractDict = dict:map(ModuleFun, TmpContractDict), dialyzer_codeserver:finalize_contracts(NewContractDict, CodeServer). - + -spec check_contracts([{mfa(), file_contract()}], dialyzer_callgraph:callgraph(), dict()) -> plt_contracts(). check_contracts(Contracts, Callgraph, FunTypes) -> FoldFun = - fun(Label, Type, NewContracts) -> + fun(Label, Type, NewContracts) -> {ok, {M,F,A} = MFA} = dialyzer_callgraph:lookup_name(Label, Callgraph), case orddict:find(MFA, Contracts) of - {ok, {_FileLine, Contract}} -> + {ok, {_FileLine, Contract}} -> case check_contract(Contract, Type) of ok -> case erl_bif_types:is_known(M, F, A) of true -> - %% Disregard the contracts since + %% Disregard the contracts since %% this is a known function. NewContracts; false -> @@ -184,8 +187,8 @@ check_contracts(Contracts, Callgraph, FunTypes) -> -spec check_contract(#contract{}, erl_types:erl_type()) -> 'ok' | {'error', term()}. check_contract(#contract{contracts = Contracts}, SuccType) -> - try - Contracts1 = [{Contract, insert_constraints(Constraints, dict:new())} + try + Contracts1 = [{Contract, insert_constraints(Constraints, dict:new())} || {Contract, Constraints} <- Contracts], Contracts2 = [erl_types:t_subst(Contract, Dict) || {Contract, Dict} <- Contracts1], @@ -194,7 +197,7 @@ check_contract(#contract{contracts = Contracts}, SuccType) -> error -> {error, {overlapping_contract, []}}; ok -> - InfList = [erl_types:t_inf(Contract, SuccType, opaque) + InfList = [erl_types:t_inf(Contract, SuccType, opaque) || Contract <- Contracts2], case check_contract_inf_list(InfList, SuccType) of {error, _} = Invalid -> Invalid; @@ -226,7 +229,7 @@ check_contract_inf_list([FunType|Left], SuccType) -> STRange = erl_types:t_fun_range(SuccType), case erl_types:t_is_none_or_unit(STRange) of true -> ok; - false -> + false -> Range = erl_types:t_fun_range(FunType), case erl_types:t_is_none(erl_types:t_inf(STRange, Range, opaque)) of true -> check_contract_inf_list(Left, SuccType); @@ -258,9 +261,9 @@ check_extraneous_1(Contract, SuccType) -> process_contracts(OverContracts, Args) -> process_contracts(OverContracts, Args, erl_types:t_none()). - + process_contracts([OverContract|Left], Args, AccRange) -> - NewAccRange = + NewAccRange = case process_contract(OverContract, Args) of error -> AccRange; {ok, Range} -> erl_types:t_sup(AccRange, Range) @@ -273,12 +276,12 @@ process_contracts([], _Args, AccRange) -> process_contract({Contract, Constraints}, CallTypes0) -> CallTypesFun = erl_types:t_fun(CallTypes0, erl_types:t_any()), - ContArgsFun = erl_types:t_fun(erl_types:t_fun_args(Contract), + ContArgsFun = erl_types:t_fun(erl_types:t_fun_args(Contract), erl_types:t_any()), ?debug("Instance: Contract: ~s\n Arguments: ~s\n", - [erl_types:t_to_string(ContArgsFun), + [erl_types:t_to_string(ContArgsFun), erl_types:t_to_string(CallTypesFun)]), - case solve_constraints(ContArgsFun, CallTypesFun, Constraints) of + case solve_constraints(ContArgsFun, CallTypesFun, Constraints) of {ok, VarDict} -> {ok, erl_types:t_subst(erl_types:t_fun_range(Contract), VarDict)}; error -> error @@ -288,7 +291,7 @@ solve_constraints(Contract, Call, Constraints) -> %% First make sure the call follows the constraints CDict = insert_constraints(Constraints, dict:new()), Contract1 = erl_types:t_subst(Contract, CDict), - %% Just a safe over-approximation. + %% Just a safe over-approximation. %% TODO: Find the types for type variables properly ContrArgs = erl_types:t_fun_args(Contract1), CallArgs = erl_types:t_fun_args(Call), @@ -309,7 +312,7 @@ solve_constraints(Contract, Call, Constraints) -> -spec contracts_without_fun(dict(), [_], dialyzer_callgraph:callgraph()) -> [dial_warning()]. contracts_without_fun(Contracts, AllFuns0, Callgraph) -> - AllFuns1 = [{dialyzer_callgraph:lookup_name(Label, Callgraph), Arity} + AllFuns1 = [{dialyzer_callgraph:lookup_name(Label, Callgraph), Arity} || {Label, Arity} <- AllFuns0], AllFuns2 = [{M, F, A} || {{ok, {M, F, _}}, A} <- AllFuns1], AllContractMFAs = dict:fetch_keys(Contracts), @@ -351,46 +354,49 @@ contract_from_form(Forms, RecDict) -> {CFuns, Forms1} = contract_from_form(Forms, RecDict, [], []), #tmp_contract{contract_funs = CFuns, forms = Forms1}. -contract_from_form([{type, _, 'fun', [_, _]} = Form | Left], RecDict, +contract_from_form([{type, _, 'fun', [_, _]} = Form | Left], RecDict, TypeAcc, FormAcc) -> - TypeFun = - fun(AllRecords) -> + TypeFun = + fun(ExpTypes, AllRecords) -> Type = erl_types:t_from_form(Form, RecDict), - NewType = erl_types:t_solve_remote(Type, AllRecords), + NewType = erl_types:t_solve_remote(Type, ExpTypes, AllRecords), {NewType, []} end, NewTypeAcc = [TypeFun | TypeAcc], NewFormAcc = [{Form, []} | FormAcc], contract_from_form(Left, RecDict, NewTypeAcc, NewFormAcc); -contract_from_form([{type, _L1, bounded_fun, +contract_from_form([{type, _L1, bounded_fun, [{type, _L2, 'fun', [_, _]} = Form, Constr]}| Left], RecDict, TypeAcc, FormAcc) -> - TypeFun = - fun(AllRecords) -> - Constr1 = [constraint_from_form(C, RecDict, AllRecords) || C <- Constr], + TypeFun = + fun(ExpTypes, AllRecords) -> + Constr1 = [constraint_from_form(C, RecDict, ExpTypes, AllRecords) + || C <- Constr], VarDict = insert_constraints(Constr1, dict:new()), Type = erl_types:t_from_form(Form, RecDict, VarDict), - NewType = erl_types:t_solve_remote(Type, AllRecords), + NewType = erl_types:t_solve_remote(Type, ExpTypes, AllRecords), {NewType, Constr1} - end, + end, NewTypeAcc = [TypeFun | TypeAcc], NewFormAcc = [{Form, Constr} | FormAcc], contract_from_form(Left, RecDict, NewTypeAcc, NewFormAcc); -contract_from_form([], _RecDict, TypeAcc, FormAcc) -> +contract_from_form([], _RecDict, TypeAcc, FormAcc) -> {lists:reverse(TypeAcc), lists:reverse(FormAcc)}. -constraint_from_form({type, _, constraint, [{atom, _, is_subtype}, - [Type1, Type2]]}, RecDict, AllRecords) -> +constraint_from_form({type, _, constraint, [{atom, _, is_subtype}, + [Type1, Type2]]}, RecDict, + ExpTypes, AllRecords) -> T1 = erl_types:t_from_form(Type1, RecDict), T2 = erl_types:t_from_form(Type2, RecDict), - T3 = erl_types:t_solve_remote(T1, AllRecords), - T4 = erl_types:t_solve_remote(T2, AllRecords), + T3 = erl_types:t_solve_remote(T1, ExpTypes, AllRecords), + T4 = erl_types:t_solve_remote(T2, ExpTypes, AllRecords), {subtype, T3, T4}; -constraint_from_form({type, _, constraint, [{atom,_,Name}, List]}, _RecDict, _) -> +constraint_from_form({type, _, constraint, [{atom,_,Name}, List]}, _RecDict, + _ExpTypes, _AllRecords) -> N = length(List), throw({error, io_lib:format("Unsupported type guard ~w/~w\n", [Name, N])}). -%% Gets the most general domain of a list of domains of all +%% Gets the most general domain of a list of domains of all %% the overloaded contracts general_domain(List) -> @@ -419,7 +425,7 @@ get_invalid_contract_warnings_modules([Mod|Mods], CodeServer, Plt, Acc) -> get_invalid_contract_warnings_modules([], _CodeServer, _Plt, Acc) -> Acc. -get_invalid_contract_warnings_funs([{MFA, {FileLine, Contract}}|Left], +get_invalid_contract_warnings_funs([{MFA, {FileLine, Contract}}|Left], Plt, RecDict, Acc) -> case dialyzer_plt:lookup(Plt, MFA) of none -> @@ -447,15 +453,15 @@ get_invalid_contract_warnings_funs([{MFA, {FileLine, Contract}}|Left], BifRet = erl_bif_types:type(M, F, A), BifSig = erl_types:t_fun(BifArgs, BifRet), case check_contract(Contract, BifSig) of - {error, _} -> + {error, _} -> [invalid_contract_warning(MFA, FileLine, BifSig, RecDict) |Acc]; ok -> - picky_contract_check(CSig, BifSig, MFA, FileLine, + picky_contract_check(CSig, BifSig, MFA, FileLine, Contract, RecDict, Acc) end; false -> - picky_contract_check(CSig, Sig, MFA, FileLine, Contract, + picky_contract_check(CSig, Sig, MFA, FileLine, Contract, RecDict, Acc) end end, @@ -479,12 +485,12 @@ picky_contract_check(CSig0, Sig0, MFA, FileLine, Contract, RecDict, Acc) -> Sig = erl_types:t_abstract_records(Sig0, RecDict), case erl_types:t_is_equal(CSig, Sig) of true -> Acc; - false -> + false -> case (erl_types:t_is_none(erl_types:t_fun_range(Sig)) andalso erl_types:t_is_unit(erl_types:t_fun_range(CSig))) of true -> Acc; false -> - case extra_contract_warning(MFA, FileLine, Contract, + case extra_contract_warning(MFA, FileLine, Contract, CSig, Sig, RecDict) of no_warning -> Acc; {warning, Warning} -> [Warning|Acc] @@ -503,16 +509,16 @@ extra_contract_warning({M, F, A}, FileLine, Contract, CSig, Sig, RecDict) -> ContractString = contract_to_string(Contract), {Tag, Msg} = case erl_types:t_is_subtype(CSig, Sig) of - true -> - {?WARN_CONTRACT_SUBTYPE, + true -> + {?WARN_CONTRACT_SUBTYPE, {contract_subtype, [M, F, A, ContractString, SigString]}}; false -> case erl_types:t_is_subtype(Sig, CSig) of true -> - {?WARN_CONTRACT_SUPERTYPE, + {?WARN_CONTRACT_SUPERTYPE, {contract_supertype, [M, F, A, ContractString, SigString]}}; false -> - {?WARN_CONTRACT_NOT_EQUAL, + {?WARN_CONTRACT_NOT_EQUAL, {contract_diff, [M, F, A, ContractString, SigString]}} end end, diff --git a/lib/dialyzer/src/dialyzer_dataflow.erl b/lib/dialyzer/src/dialyzer_dataflow.erl index a57d9a96c6..b80c7efc1a 100644 --- a/lib/dialyzer/src/dialyzer_dataflow.erl +++ b/lib/dialyzer/src/dialyzer_dataflow.erl @@ -21,7 +21,7 @@ %%%------------------------------------------------------------------- %%% File : dialyzer_dataflow.erl %%% Author : Tobias Lindahl <[email protected]> -%%% Description : +%%% Description : %%% %%% Created : 19 Apr 2005 by Tobias Lindahl <[email protected]> %%%------------------------------------------------------------------- @@ -30,6 +30,7 @@ -export([get_fun_types/4, get_warnings/5, format_args/3]). +%% Data structure interfaces. -export([state__add_warning/2, state__cleanup/1, state__get_callgraph/1, state__get_races/1, state__get_records/1, state__put_callgraph/2, @@ -38,9 +39,11 @@ %% Debug and test interfaces. -export([get_top_level_signatures/2, pp/1]). +-export_type([state/0]). + -include("dialyzer.hrl"). --import(erl_types, +-import(erl_types, [any_none/1, t_any/0, t_atom/0, t_atom/1, t_atom_vals/1, t_binary/0, t_boolean/0, t_bitstr/0, t_bitstr/2, t_bitstr_concat/1, t_bitstr_match/2, @@ -88,14 +91,15 @@ fun_tab :: dict(), plt :: dialyzer_plt:plt(), opaques :: [erl_types:erl_type()], - races :: dialyzer_races:races(), - records :: dict(), + races = dialyzer_races:new() :: dialyzer_races:races(), + records = dict:new() :: dict(), tree_map :: dict(), warning_mode = false :: boolean(), warnings = [] :: [dial_warning()], work :: {[_], [_], set()}, module :: module(), - behaviour_api_info = [] :: [{atom(),[_]}]}). + behaviour_api_dict = [] :: + dialyzer_behaviours:behaviour_api_dict()}). %% Exported Types @@ -163,20 +167,20 @@ get_top_level_signatures(Code, Records) -> error -> Arity = cerl:fname_arity(V), Type = t_fun(lists:duplicate(Arity, - t_none()), + t_none()), t_none()), dict:store(Label, Type, Acc); {ok, _} -> Acc end end, FunTypes, cerl:module_defs(Tree)), dialyzer_callgraph:delete(Callgraph), - Sigs = [{{cerl:fname_id(V), cerl:fname_arity(V)}, - dict:fetch(get_label(F), FunTypes1)} + Sigs = [{{cerl:fname_id(V), cerl:fname_arity(V)}, + dict:fetch(get_label(F), FunTypes1)} || {V, F} <- cerl:module_defs(Tree)], ordsets:from_list(Sigs). get_def_plt() -> - try + try dialyzer_plt:from_file(dialyzer_plt:get_default_plt()) catch throw:{dialyzer_error, _} -> dialyzer_plt:new() @@ -202,7 +206,7 @@ annotate_module(Code, Plt) -> annotate(Tree, State) -> case cerl:subtrees(Tree) of [] -> set_type(Tree, State); - List -> + List -> NewSubTrees = [[annotate(Subtree, State) || Subtree <- Group] || Group <- List], NewTree = cerl:update_tree(Tree, NewSubTrees), @@ -214,9 +218,9 @@ set_type(Tree, State) -> 'fun' -> Type = state__fun_type(Tree, State), case t_is_any(Type) of - true -> + true -> cerl:set_ann(Tree, delete_ann(typesig, cerl:get_ann(Tree))); - false -> + false -> cerl:set_ann(Tree, append_ann(typesig, Type, cerl:get_ann(Tree))) end; apply -> @@ -224,10 +228,10 @@ set_type(Tree, State) -> unknown -> Tree; ReturnType -> case t_is_any(ReturnType) of - true -> + true -> cerl:set_ann(Tree, delete_ann(type, cerl:get_ann(Tree))); - false -> - cerl:set_ann(Tree, append_ann(type, ReturnType, + false -> + cerl:set_ann(Tree, append_ann(type, ReturnType, cerl:get_ann(Tree))) end end; @@ -236,7 +240,7 @@ set_type(Tree, State) -> end. append_ann(Tag, Val, [X | Xs]) -> - if tuple_size(X) >= 1, element(1, X) =:= Tag -> + if tuple_size(X) >= 1, element(1, X) =:= Tag -> append_ann(Tag, Val, Xs); true -> [X | append_ann(Tag, Val, Xs)] @@ -245,7 +249,7 @@ append_ann(Tag, Val, []) -> [{Tag, Val}]. delete_ann(Tag, [X | Xs]) -> - if tuple_size(X) >= 1, element(1, X) =:= Tag -> + if tuple_size(X) >= 1, element(1, X) =:= Tag -> delete_ann(Tag, Xs); true -> [X | delete_ann(Tag, Xs)] @@ -314,21 +318,21 @@ analyze_loop(#state{callgraph = Callgraph, races = Races} = State) -> {Fun, NewState} -> ArgTypes = state__get_args(Fun, NewState), case any_none(ArgTypes) of - true -> - ?debug("Not handling1 ~w: ~s\n", - [state__lookup_name(get_label(Fun), State), + true -> + ?debug("Not handling1 ~w: ~s\n", + [state__lookup_name(get_label(Fun), State), t_to_string(t_product(ArgTypes))]), analyze_loop(NewState); - false -> + false -> case state__fun_env(Fun, NewState) of - none -> - ?debug("Not handling2 ~w: ~s\n", - [state__lookup_name(get_label(Fun), State), + none -> + ?debug("Not handling2 ~w: ~s\n", + [state__lookup_name(get_label(Fun), State), t_to_string(t_product(ArgTypes))]), analyze_loop(NewState); Map -> - ?debug("Handling fun ~p: ~s\n", - [state__lookup_name(get_label(Fun), State), + ?debug("Handling fun ~p: ~s\n", + [state__lookup_name(get_label(Fun), State), t_to_string(state__fun_type(Fun, NewState))]), NewState1 = state__mark_fun_as_handled(NewState, Fun), Vars = cerl:fun_vars(Fun), @@ -339,19 +343,19 @@ analyze_loop(#state{callgraph = Callgraph, races = Races} = State) -> RaceAnalysis = dialyzer_races:get_race_analysis(Races), NewState3 = case RaceDetection andalso RaceAnalysis of - true -> + true -> NewState2 = state__renew_curr_fun( state__lookup_name(FunLabel, NewState1), FunLabel, NewState1), state__renew_race_list([], 0, NewState2); false -> NewState1 end, - {NewState4, _Map2, BodyType} = + {NewState4, _Map2, BodyType} = traverse(Body, Map1, NewState3), - ?debug("Done analyzing: ~w:~s\n", + ?debug("Done analyzing: ~w:~s\n", [state__lookup_name(get_label(Fun), State), t_to_string(t_fun(ArgTypes, BodyType))]), - NewState5 = + NewState5 = case RaceDetection andalso RaceAnalysis of true -> Races1 = NewState4#state.races, @@ -382,7 +386,7 @@ traverse(Tree, Map, State) -> %% This only happens when checking for illegal record patterns %% so the handling is a bit rudimentary. traverse(cerl:alias_pat(Tree), Map, State); - apply -> + apply -> handle_apply(Tree, Map, State); binary -> Segs = cerl:binary_segments(Tree), @@ -416,7 +420,7 @@ traverse(Tree, Map, State) -> %% By not including the variables in scope we can assure that we %% will get the current function type when using the variables. FoldFun = fun({Var, Fun}, {AccState, AccMap}) -> - {NewAccState, NewAccMap0, FunType} = + {NewAccState, NewAccMap0, FunType} = traverse(Fun, AccMap, AccState), NewAccMap = enter_type(Var, FunType, NewAccMap0), {NewAccState, NewAccMap} @@ -428,7 +432,7 @@ traverse(Tree, Map, State) -> case cerl:unfold_literal(Tree) of Tree -> Type = literal_type(Tree), - NewType = + NewType = case erl_types:t_opaque_match_atom(Type, State#state.opaques) of [Opaque] -> Opaque; _ -> Type @@ -446,8 +450,8 @@ traverse(Tree, Map, State) -> bs_init_writable -> t_from_term(<<>>); Other -> erlang:error({'Unsupported primop', Other}) end, - {State, Map, Type}; - 'receive' -> + {State, Map, Type}; + 'receive' -> handle_receive(Tree, Map, State); seq -> Arg = cerl:seq_arg(Tree), @@ -457,13 +461,13 @@ traverse(Tree, Map, State) -> true -> SMA; false -> - State2 = + State2 = case (t_is_any(ArgType) orelse t_is_simple(ArgType) orelse is_call_to_send(Arg)) of true -> % do not warn in these cases State1; false -> - state__add_warning(State1, ?WARN_UNMATCHED_RETURN, Arg, + state__add_warning(State1, ?WARN_UNMATCHED_RETURN, Arg, {unmatched_return, [format_type(ArgType, State1)]}) end, @@ -481,12 +485,12 @@ traverse(Tree, Map, State) -> var -> ?debug("Looking up unknown variable: ~p\n", [Tree]), case state__lookup_type_for_rec_var(Tree, State) of - error -> + error -> LType = lookup_type(Tree, Map), Opaques = State#state.opaques, case t_opaque_match_record(LType, Opaques) of [Opaque] -> {State, Map, Opaque}; - _ -> + _ -> case t_opaque_match_atom(LType, Opaques) of [Opaque] -> {State, Map, Opaque}; _ -> {State, Map, LType} @@ -506,7 +510,7 @@ traverse_list([Tree|Tail], Map, State, Acc) -> traverse_list(Tail, Map1, State1, [Type|Acc]); traverse_list([], Map, State, Acc) -> {State, Map, lists:reverse(Acc)}. - + %%________________________________________ %% %% Special instructions @@ -518,7 +522,7 @@ handle_apply(Tree, Map, State) -> {State1, Map1, ArgTypes} = traverse_list(Args, Map, State), {State2, Map2, OpType} = traverse(Op, Map1, State1), case any_none(ArgTypes) of - true -> + true -> {State2, Map2, t_none()}; false -> {CallSitesKnown, FunList} = @@ -533,7 +537,7 @@ handle_apply(Tree, Map, State) -> OpType1 = t_inf(OpType, t_fun(Arity, t_any())), case t_is_none(OpType1) of true -> - Msg = {fun_app_no_fun, + Msg = {fun_app_no_fun, [format_cerl(Op), format_type(OpType, State2), Arity]}, State3 = state__add_warning(State2, ?WARN_FAILING_CALL, Tree, Msg), @@ -541,7 +545,7 @@ handle_apply(Tree, Map, State) -> false -> NewArgs = t_inf_lists(ArgTypes, t_fun_args(OpType1)), case any_none(NewArgs) of - true -> + true -> Msg = {fun_app_args, [format_args(Args, ArgTypes, State), format_type(OpType, State)]}, @@ -554,7 +558,7 @@ handle_apply(Tree, Map, State) -> end end; true -> - FunInfoList = [{local, state__fun_info(Fun, State)} + FunInfoList = [{local, state__fun_info(Fun, State)} || Fun <- FunList], handle_apply_or_call(FunInfoList, Args, ArgTypes, Map2, Tree, State1) end @@ -562,7 +566,7 @@ handle_apply(Tree, Map, State) -> handle_apply_or_call(FunInfoList, Args, ArgTypes, Map, Tree, State) -> None = t_none(), - handle_apply_or_call(FunInfoList, Args, ArgTypes, Map, Tree, State, + handle_apply_or_call(FunInfoList, Args, ArgTypes, Map, Tree, State, [None || _ <- ArgTypes], None). handle_apply_or_call([{local, external}|Left], Args, ArgTypes, Map, Tree, State, @@ -577,7 +581,7 @@ handle_apply_or_call([{TypeOfApply, {Fun, Sig, Contr, LocalRet}}|Left], Any = t_any(), AnyArgs = [Any || _ <- Args], GenSig = {AnyArgs, fun(_) -> t_any() end}, - {CArgs, CRange} = + {CArgs, CRange} = case Contr of {value, #contract{args = As} = C} -> {As, fun(FunArgs) -> @@ -627,9 +631,9 @@ handle_apply_or_call([{TypeOfApply, {Fun, Sig, Contr, LocalRet}}|Left], end end, ArgModeMask = [case lists:member(Arg, Opaques) of - true -> opaque; - false -> structured - end || Arg <- ArgTypes], + true -> opaque; + false -> structured + end || Arg <- ArgTypes], NewArgsSig = t_inf_lists_masked(SigArgs, ArgTypes, ArgModeMask), NewArgsContract = t_inf_lists_masked(CArgs, ArgTypes, ArgModeMask), NewArgsBif = t_inf_lists_masked(BifArgs, ArgTypes, ArgModeMask), @@ -637,7 +641,7 @@ handle_apply_or_call([{TypeOfApply, {Fun, Sig, Contr, LocalRet}}|Left], NewArgTypes = t_inf_lists_masked(NewArgTypes0, NewArgsBif, ArgModeMask), BifRet = BifRange(NewArgTypes), {TmpArgTypes, TmpArgsContract} = - case (TypeOfApply == remote) andalso (not IsBIF) of + case (TypeOfApply =:= remote) andalso (not IsBIF) of true -> List1 = lists:zip(CArgs, NewArgTypes), List2 = lists:zip(CArgs, NewArgsContract), @@ -648,16 +652,17 @@ handle_apply_or_call([{TypeOfApply, {Fun, Sig, Contr, LocalRet}}|Left], false -> {NewArgTypes, NewArgsContract} end, ContrRet = CRange(TmpArgTypes), - RetMode = case t_contains_opaque(ContrRet) orelse t_contains_opaque(BifRet) of - true -> opaque; - false -> structured - end, + RetMode = + case t_contains_opaque(ContrRet) orelse t_contains_opaque(BifRet) of + true -> opaque; + false -> structured + end, RetWithoutLocal = t_inf(t_inf(ContrRet, BifRet, RetMode), SigRange, RetMode), ?debug("--------------------------------------------------------\n", []), ?debug("Fun: ~p\n", [Fun]), ?debug("Args: ~s\n", [erl_types:t_to_string(t_product(ArgTypes))]), ?debug("NewArgsSig: ~s\n", [erl_types:t_to_string(t_product(NewArgsSig))]), - ?debug("NewArgsContract: ~s\n", + ?debug("NewArgsContract: ~s\n", [erl_types:t_to_string(t_product(NewArgsContract))]), ?debug("NewArgsBif: ~s\n", [erl_types:t_to_string(t_product(NewArgsBif))]), ?debug("NewArgTypes: ~s\n", [erl_types:t_to_string(t_product(NewArgTypes))]), @@ -677,11 +682,11 @@ handle_apply_or_call([{TypeOfApply, {Fun, Sig, Contr, LocalRet}}|Left], %% respective callback module's function. Module = State#state.module, - BehApiInfo = State#state.behaviour_api_info, + BehApiDict = State#state.behaviour_api_dict, {RealFun, RealArgTypes, RealArgs} = case dialyzer_behaviours:translate_behaviour_api_call(Fun, ArgTypes, Args, Module, - BehApiInfo) of + BehApiDict) of plain_call -> {Fun, ArgTypes, Args}; BehaviourAPI -> BehaviourAPI end, @@ -698,10 +703,10 @@ handle_apply_or_call([{TypeOfApply, {Fun, Sig, Contr, LocalRet}}|Left], FailedSig = any_none(NewArgsSig), FailedContract = any_none([CRange(TmpArgsContract)|NewArgsContract]), FailedBif = any_none([BifRange(NewArgsBif)|NewArgsBif]), - InfSig = t_inf(t_fun(SigArgs, SigRange), + InfSig = t_inf(t_fun(SigArgs, SigRange), t_fun(BifArgs, BifRange(BifArgs))), FailReason = apply_fail_reason(FailedSig, FailedBif, FailedContract), - Msg = get_apply_fail_msg(Fun, Args, ArgTypes, NewArgTypes, InfSig, + Msg = get_apply_fail_msg(Fun, Args, ArgTypes, NewArgTypes, InfSig, Contr, CArgs, State1, FailReason), WarnType = case Msg of {call, _} -> ?WARN_FAILING_CALL; @@ -725,15 +730,15 @@ handle_apply_or_call([{TypeOfApply, {Fun, Sig, Contr, LocalRet}}|Left], remote -> add_bif_warnings(Fun, NewArgTypes, Tree, State2) end, - NewAccArgTypes = + NewAccArgTypes = case FailedConj of true -> AccArgTypes; false -> [t_sup(X, Y) || {X, Y} <- lists:zip(NewArgTypes, AccArgTypes)] end, NewAccRet = t_sup(AccRet, t_inf(RetWithoutLocal, LocalRet, opaque)), - handle_apply_or_call(Left, Args, ArgTypes, Map, Tree, + handle_apply_or_call(Left, Args, ArgTypes, Map, Tree, State3, NewAccArgTypes, NewAccRet); -handle_apply_or_call([], Args, _ArgTypes, Map, _Tree, State, +handle_apply_or_call([], Args, _ArgTypes, Map, _Tree, State, AccArgTypes, AccRet) -> NewMap = enter_type_lists(Args, AccArgTypes, Map), {State, NewMap, AccRet}. @@ -745,13 +750,13 @@ apply_fail_reason(FailedSig, FailedBif, FailedContract) -> true -> both end. -get_apply_fail_msg(Fun, Args, ArgTypes, NewArgTypes, +get_apply_fail_msg(Fun, Args, ArgTypes, NewArgTypes, Sig, Contract, ContrArgs, State, FailReason) -> ArgStrings = format_args(Args, ArgTypes, State), ContractInfo = case Contract of {value, #contract{} = C} -> - {dialyzer_contracts:is_overloaded(C), + {dialyzer_contracts:is_overloaded(C), dialyzer_contracts:contract_to_string(C)}; none -> {false, none} end, @@ -765,7 +770,7 @@ get_apply_fail_msg(Fun, Args, ArgTypes, NewArgTypes, {M, F, _A} -> case is_opaque_type_test_problem(Fun, NewArgTypes, State) of true -> - [Opaque] = NewArgTypes, + [Opaque] = NewArgTypes, {opaque_type_test, [atom_to_list(F), erl_types:t_to_string(Opaque)]}; false -> SigArgs = t_fun_args(Sig), @@ -789,7 +794,7 @@ get_apply_fail_msg(Fun, Args, ArgTypes, NewArgTypes, {call_without_opaque, [M, F, ArgStrings, ExpectedTriples]}; false -> %% there is a structured term clash in some argument {call, [M, F, ArgStrings, - ArgNs, FailReason, + ArgNs, FailReason, format_sig_args(Sig, State), format_type(t_fun_range(Sig), State), ContractInfo]} @@ -797,8 +802,8 @@ get_apply_fail_msg(Fun, Args, ArgTypes, NewArgTypes, end end; Label when is_integer(Label) -> - {apply, [ArgStrings, - ArgNs, FailReason, + {apply, [ArgStrings, + ArgNs, FailReason, format_sig_args(Sig, State), format_type(t_fun_range(Sig), State), ContractInfo]} @@ -826,7 +831,7 @@ is_opaque_type_test_problem(Fun, ArgTypes, State) -> FN =:= is_number; FN =:= is_pid; FN =:= is_port; FN =:= is_reference; FN =:= is_tuple -> [Type] = ArgTypes, - erl_types:t_is_opaque(Type) andalso + erl_types:t_is_opaque(Type) andalso not lists:member(Type, State#state.opaques); _ -> false end. @@ -1043,7 +1048,7 @@ handle_cons(Tree, Map, State) -> Tl = cerl:cons_tl(Tree), {State1, Map1, HdType} = traverse(Hd, Map, State), {State2, Map2, TlType} = traverse(Tl, Map1, State1), - State3 = + State3 = case t_is_none(t_inf(TlType, t_list())) of true -> Msg = {improper_list_constr, [format_type(TlType, State2)]}, @@ -1088,7 +1093,7 @@ handle_let(Tree, Map, #state{callgraph = Callgraph, races = Races} = State) -> case cerl:is_literal(Mod) andalso cerl:concrete(Mod) =:= ets andalso cerl:is_literal(Name) andalso - cerl:concrete(Name) =:= new of + cerl:concrete(Name) =:= new of true -> NewTable = dialyzer_races:get_new_table(State1#state.races), renew_public_tables(Vars, NewTable, @@ -1112,7 +1117,7 @@ handle_module(Tree, Map, State) -> %% By not including the variables in scope we can assure that we %% will get the current function type when using the variables. Defs = cerl:module_defs(Tree), - PartFun = fun({_Var, Fun}) -> + PartFun = fun({_Var, Fun}) -> state__is_escaping(get_label(Fun), State) end, {Defs1, Defs2} = lists:partition(PartFun, Defs), @@ -1143,12 +1148,12 @@ handle_receive(Tree, Map, RaceListSize + 1, State); false -> State end, - {MapList, State2, ReceiveType} = + {MapList, State2, ReceiveType} = handle_clauses(Clauses, ?no_arg, t_any(), t_any(), State1, [], Map, [], []), Map1 = join_maps(MapList, Map), {State3, Map2, TimeoutType} = traverse(Timeout, Map1, State2), - case (t_is_atom(TimeoutType) andalso + case (t_is_atom(TimeoutType) andalso (t_atom_vals(TimeoutType) =:= ['infinity'])) of true -> {State3, Map2, ReceiveType}; @@ -1168,17 +1173,17 @@ handle_try(Tree, Map, State) -> Vars = cerl:try_vars(Tree), Body = cerl:try_body(Tree), Handler = cerl:try_handler(Tree), - {State1, Map1, ArgType} = traverse(Arg, Map, State), + {State1, Map1, ArgType} = traverse(Arg, Map, State), Map2 = mark_as_fresh(Vars, Map1), {SuccState, SuccMap, SuccType} = case bind_pat_vars(Vars, t_to_tlist(ArgType), [], Map2, State1) of {error, _, _, _, _} -> {State1, map__new(), t_none()}; {SuccMap1, VarTypes} -> - %% Try to bind the argument. Will only succeed if + %% Try to bind the argument. Will only succeed if %% it is a simple structured term. SuccMap2 = - case bind_pat_vars_reverse([Arg], [t_product(VarTypes)], [], + case bind_pat_vars_reverse([Arg], [t_product(VarTypes)], [], SuccMap1, State1) of {error, _, _, _, _} -> SuccMap1; {SM, _} -> SM @@ -1212,10 +1217,10 @@ handle_tuple(Tree, Map, State) -> RecFields = t_tuple_args(RecStruct), case bind_pat_vars(Elements, RecFields, [], Map1, State1) of {error, _, ErrorPat, ErrorType, _} -> - Msg = {record_constr, + Msg = {record_constr, [TagVal, format_patterns(ErrorPat), format_type(ErrorType, State1)]}, - State2 = state__add_warning(State1, ?WARN_MATCHING, + State2 = state__add_warning(State1, ?WARN_MATCHING, Tree, Msg), {State2, Map1, t_none()}; {Map2, _ETypes} -> @@ -1224,26 +1229,24 @@ handle_tuple(Tree, Map, State) -> _ -> case state__lookup_record(TagVal, length(Left), State1) of error -> {State1, Map1, TupleType}; - {ok, Prototype} -> - %% io:format("In handle_tuple:\n Prototype = ~p\n", [Prototype]), - InfTupleType = t_inf(Prototype, TupleType), - %% io:format(" TupleType = ~p,\n Inf = ~p\n", [TupleType, InfTupleType]), + {ok, RecType} -> + InfTupleType = t_inf(RecType, TupleType), case t_is_none(InfTupleType) of true -> - Msg = {record_constr, - [format_type(TupleType, State1), TagVal]}, - State2 = state__add_warning(State1, ?WARN_MATCHING, + RecC = format_type(TupleType, State1), + FieldDiffs = format_field_diffs(TupleType, State1), + Msg = {record_constr, [RecC, FieldDiffs]}, + State2 = state__add_warning(State1, ?WARN_MATCHING, Tree, Msg), {State2, Map1, t_none()}; false -> - case bind_pat_vars(Elements, t_tuple_args(Prototype), + case bind_pat_vars(Elements, t_tuple_args(RecType), [], Map1, State1) of {error, bind, ErrorPat, ErrorType, _} -> - %% io:format("error\n", []), - Msg = {record_constr, + Msg = {record_constr, [TagVal, format_patterns(ErrorPat), format_type(ErrorType, State1)]}, - State2 = state__add_warning(State1, ?WARN_MATCHING, + State2 = state__add_warning(State1, ?WARN_MATCHING, Tree, Msg), {State2, Map1, t_none()}; {Map2, ETypes} -> @@ -1305,7 +1308,7 @@ handle_clauses([C|Left], Arg, ArgType, OrigArgType, handle_clauses([], _Arg, _ArgType, _OrigArgType, #state{callgraph = Callgraph, races = Races} = State, CaseTypes, _MapIn, Acc, ClauseAcc) -> - State1 = + State1 = case dialyzer_callgraph:get_race_detection(Callgraph) andalso dialyzer_races:get_race_analysis(Races) of true -> @@ -1313,7 +1316,7 @@ handle_clauses([], _Arg, _ArgType, _OrigArgType, [dialyzer_races:end_case_new(ClauseAcc)| dialyzer_races:get_race_list(Races)], dialyzer_races:get_race_list_size(Races) + 1, State); - false -> State + false -> State end, {lists:reverse(Acc), State1, t_sup(CaseTypes)}. @@ -1324,7 +1327,7 @@ do_clause(C, Arg, ArgType0, OrigArgType, Map, Body = cerl:clause_body(C), RaceDetection = dialyzer_callgraph:get_race_detection(Callgraph), RaceAnalysis = dialyzer_races:get_race_analysis(Races), - State1 = + State1 = case RaceDetection andalso RaceAnalysis of true -> state__renew_fun_args(Pats, State); @@ -1339,7 +1342,7 @@ do_clause(C, Arg, ArgType0, OrigArgType, Map, true -> {error, bind, Pats, ArgType0, ArgType0}; false -> - ArgTypes = + ArgTypes = case t_is_any(ArgType0) of true -> [ArgType0 || _ <- Pats]; false -> t_to_tlist(ArgType0) @@ -1348,7 +1351,7 @@ do_clause(C, Arg, ArgType0, OrigArgType, Map, end, case BindRes of {error, BindOrOpaque, NewPats, Type, OpaqueTerm} -> - ?debug("Failed binding pattern: ~s\nto ~s\n", + ?debug("Failed binding pattern: ~s\nto ~s\n", [cerl_prettypr:format(C), format_type(ArgType0, State1)]), case state__warning_mode(State1) of false -> @@ -1359,7 +1362,7 @@ do_clause(C, Arg, ArgType0, OrigArgType, Map, bind -> format_patterns(Pats); opaque -> format_patterns(NewPats) end, - {Msg, Force} = + {Msg, Force} = case t_is_none(ArgType0) of true -> PatTypes = [PatString, format_type(OrigArgType, State1)], @@ -1375,13 +1378,13 @@ do_clause(C, Arg, ArgType0, OrigArgType, Map, {_, _} -> {{pattern_match_cov, PatTypes}, false} end; false -> - %% Try to find out if this is a default clause in a list + %% Try to find out if this is a default clause in a list %% comprehension and supress this. A real Hack(tm) Force0 = case is_compiler_generated(cerl:get_ann(C)) of true -> case Pats of - [Pat] -> + [Pat] -> case cerl:is_c_cons(Pat) of true -> not (cerl:is_c_var(cerl:cons_hd(Pat)) andalso @@ -1398,9 +1401,9 @@ do_clause(C, Arg, ArgType0, OrigArgType, Map, end, PatTypes = case BindOrOpaque of bind -> [PatString, format_type(ArgType0, State1)]; - opaque -> [PatString, format_type(Type, State1), + opaque -> [PatString, format_type(Type, State1), format_type(OpaqueTerm, State1)] - end, + end, FailedMsg = case BindOrOpaque of bind -> {pattern_match, PatTypes}; opaque -> {opaque_match, PatTypes} @@ -1420,9 +1423,9 @@ do_clause(C, Arg, ArgType0, OrigArgType, Map, case Arg =:= ?no_arg of true -> Map2; false -> - %% Try to bind the argument. Will only succeed if + %% Try to bind the argument. Will only succeed if %% it is a simple structured term. - case bind_pat_vars_reverse([Arg], [t_product(PatTypes)], + case bind_pat_vars_reverse([Arg], [t_product(PatTypes)], [], Map2, State1) of {error, _, _, _, _} -> Map2; {NewMap, _} -> NewMap @@ -1436,11 +1439,11 @@ do_clause(C, Arg, ArgType0, OrigArgType, Map, t_subtract(t_product(t_to_tlist(ArgType0)), GenType) end, case bind_guard(Guard, Map3, State1) of - {error, Reason} -> - ?debug("Failed guard: ~s\n", + {error, Reason} -> + ?debug("Failed guard: ~s\n", [cerl_prettypr:format(C, [{hook, cerl_typean:pp_hook()}])]), PatString = format_patterns(Pats), - DefaultMsg = + DefaultMsg = case Pats =:= [] of true -> {guard_fail, []}; false -> @@ -1470,7 +1473,7 @@ do_clause(C, Arg, ArgType0, OrigArgType, Map, bind_subst(Arg, Pats, Map) -> case cerl:type(Arg) of - values -> + values -> bind_subst_list(cerl:values_es(Arg), Pats, Map); var -> [Pat] = Pats, @@ -1499,16 +1502,16 @@ bind_subst_list([], [], Map) -> %% bind_pat_vars(Pats, Types, Acc, Map, State) -> - try + try bind_pat_vars(Pats, Types, Acc, Map, State, false) - catch + catch throw:Error -> Error % Error = {error, bind | opaque, ErrorPats, ErrorType} end. bind_pat_vars_reverse(Pats, Types, Acc, Map, State) -> - try + try bind_pat_vars(Pats, Types, Acc, Map, State, true) - catch + catch throw:Error -> Error % Error = {error, bind | opaque, ErrorPats, ErrorType} end. @@ -1520,7 +1523,7 @@ bind_pat_vars([Pat|PatLeft], [Type|TypeLeft], Acc, Map, State, Rev) -> AliasPat = cerl:alias_pat(Pat), Var = cerl:alias_var(Pat), Map1 = enter_subst(Var, AliasPat, Map), - {Map2, [PatType]} = bind_pat_vars([AliasPat], [Type], [], + {Map2, [PatType]} = bind_pat_vars([AliasPat], [Type], [], Map1, State, Rev), {enter_type(Var, PatType, Map2), PatType}; binary -> @@ -1541,18 +1544,18 @@ bind_pat_vars([Pat|PatLeft], [Type|TypeLeft], Acc, Map, State, Rev) -> cons -> Cons = t_inf(Type, t_cons()), case t_is_none(Cons) of - true -> + true -> bind_opaque_pats(t_cons(), Type, Pat, Map, State, Rev); false -> - {Map1, [HdType, TlType]} = + {Map1, [HdType, TlType]} = bind_pat_vars([cerl:cons_hd(Pat), cerl:cons_tl(Pat)], - [t_cons_hd(Cons), t_cons_tl(Cons)], + [t_cons_hd(Cons), t_cons_tl(Cons)], [], Map, State, Rev), {Map1, t_cons(HdType, TlType)} end; literal -> Literal = literal_type(Pat), - LiteralOrOpaque = + LiteralOrOpaque = case t_opaque_match_atom(Literal, State#state.opaques) of [Opaque] -> Opaque; _ -> Literal @@ -1564,7 +1567,7 @@ bind_pat_vars([Pat|PatLeft], [Type|TypeLeft], Acc, Map, State, Rev) -> end; tuple -> Es = cerl:tuple_es(Pat), - Prototype = + Prototype = case Es of [] -> t_tuple([]); [Tag|Left] -> @@ -1585,10 +1588,10 @@ bind_pat_vars([Pat|PatLeft], [Type|TypeLeft], Acc, Map, State, Rev) -> false -> SubTuples = t_tuple_subtypes(Tuple), %% Need to call the top function to get the try-catch wrapper - Results = + Results = case Rev of true -> - [bind_pat_vars_reverse(Es, t_tuple_args(SubTuple), [], + [bind_pat_vars_reverse(Es, t_tuple_args(SubTuple), [], Map, State) || SubTuple <- SubTuples]; false -> @@ -1632,12 +1635,12 @@ bind_pat_vars([Pat|PatLeft], [Type|TypeLeft], Acc, Map, State, Rev) -> end, %% Must do inf when binding args to pats. Vars in pats are fresh. VarType2 = t_inf(VarType1, Type), - VarType3 = + VarType3 = case Opaques =/= [] of true -> case t_opaque_match_record(VarType2, Opaques) of [OpaqueRec] -> OpaqueRec; - _ -> + _ -> case t_opaque_match_atom(VarType2, Opaques) of [OpaqueAtom] -> OpaqueAtom; _ -> VarType2 @@ -1648,9 +1651,9 @@ bind_pat_vars([Pat|PatLeft], [Type|TypeLeft], Acc, Map, State, Rev) -> case t_is_none(VarType3) of true -> case t_find_opaque_mismatch(VarType1, Type) of - {ok, T1, T2} -> + {ok, T1, T2} -> bind_error([Pat], T1, T2, opaque); - error -> + error -> bind_error([Pat], Type, t_none(), bind) end; false -> @@ -1752,10 +1755,10 @@ bind_guard(Guard, Map, State) -> end. bind_guard(Guard, Map, Env, Eval, State) -> - ?debug("Handling ~w guard: ~s\n", + ?debug("Handling ~w guard: ~s\n", [Eval, cerl_prettypr:format(Guard, [{noann, true}])]), case cerl:type(Guard) of - binary -> + binary -> {Map, t_binary()}; 'case' -> Arg = cerl:case_arg(Guard), @@ -1793,10 +1796,10 @@ bind_guard(Guard, Map, Env, Eval, State) -> var -> ?debug("Looking for var(~w)...", [cerl_trees:get_label(Guard)]), case dict:find(get_label(Guard), Env) of - error -> + error -> ?debug("Did not find it\n", []), Type = lookup_type(Guard, Map), - Constr = + Constr = case Eval of pos -> t_atom(true); neg -> t_atom(false); @@ -1804,7 +1807,7 @@ bind_guard(Guard, Map, Env, Eval, State) -> end, Inf = t_inf(Constr, Type), {enter_type(Guard, Inf, Map), Inf}; - {ok, Tree} -> + {ok, Tree} -> ?debug("Found it\n", []), {Map1, Type} = bind_guard(Tree, Map, Env, Eval, State), {enter_type(Guard, Type, Map1), Type} @@ -1827,7 +1830,7 @@ handle_guard_call(Guard, Map, Env, Eval, State) -> handle_guard_type_test(Guard, F, Map, Env, Eval, State); {erlang, is_function, 2} -> handle_guard_is_function(Guard, Map, Env, Eval, State); - MFA when (MFA =:= {erlang, internal_is_record, 3}) or + MFA when (MFA =:= {erlang, internal_is_record, 3}) or (MFA =:= {erlang, is_record, 3}) -> handle_guard_is_record(Guard, Map, Env, Eval, State); {erlang, '=:=', 2} -> @@ -1840,7 +1843,7 @@ handle_guard_call(Guard, Map, Env, Eval, State) -> handle_guard_or(Guard, Map, Env, Eval, State); {erlang, 'not', 1} -> handle_guard_not(Guard, Map, Env, Eval, State); - {erlang, Comp, 2} when Comp =:= '<'; Comp =:= '=<'; + {erlang, Comp, 2} when Comp =:= '<'; Comp =:= '=<'; Comp =:= '>'; Comp =:= '>=' -> handle_guard_comp(Guard, Comp, Map, Env, Eval, State); _ -> @@ -1875,7 +1878,7 @@ handle_guard_gen_fun({M, F, A}, Guard, Map, Env, Eval, State) -> List -> List end, Map2 = enter_type_lists(Args, t_inf_lists(BifArgs, As0, Mode), Map1), - Ret = + Ret = case Eval of pos -> t_inf(t_atom(true), BifRet); neg -> t_inf(t_atom(false), BifRet); @@ -1892,14 +1895,14 @@ handle_guard_gen_fun({M, F, A}, Guard, Map, Env, Eval, State) -> end. handle_guard_type_test(Guard, F, Map, Env, Eval, State) -> - [Arg] = cerl:call_args(Guard), + [Arg] = cerl:call_args(Guard), {Map1, ArgType} = bind_guard(Arg, Map, Env, dont_know, State), case bind_type_test(Eval, F, ArgType, State) of - error -> + error -> ?debug("Type test: ~w failed\n", [F]), signal_guard_fail(Guard, [ArgType], State); - {ok, NewArgType, Ret} -> - ?debug("Type test: ~w succeeded, NewType: ~s, Ret: ~s\n", + {ok, NewArgType, Ret} -> + ?debug("Type test: ~w succeeded, NewType: ~s, Ret: ~s\n", [F, t_to_string(NewArgType), t_to_string(Ret)]), {enter_type(Arg, NewArgType, Map1), Ret} end. @@ -1930,13 +1933,13 @@ bind_type_test(Eval, TypeTest, ArgType, State) -> end; neg -> case Mode of - opaque -> + opaque -> Struct = erl_types:t_opaque_structure(ArgType), case t_is_none(t_subtract(Struct, Type)) of true -> error; false -> {ok, ArgType, t_atom(false)} end; - structured -> + structured -> Sub = t_subtract(ArgType, Type), case t_is_none(Sub) of true -> error; @@ -1974,7 +1977,7 @@ handle_guard_comp(Guard, Comp, Map, Env, Eval, State) -> error -> signal_guard_fail(Guard, ArgTypes, State); {ok, NewMap} -> {NewMap, t_atom(true)} end; - {_, _} -> + {_, _} -> handle_guard_gen_fun({erlang, Comp, 2}, Guard, Map, Env, Eval, State) end. @@ -2021,7 +2024,7 @@ handle_guard_is_function(Guard, Map, Env, Eval, State) -> end, FunType = t_inf(FunType0, FunTypeConstr), case t_is_none(FunType) of - true -> + true -> case Eval of pos -> signal_guard_fail(Guard, ArgTypes0, State); neg -> {Map1, t_atom(false)}; @@ -2057,16 +2060,16 @@ handle_guard_is_record(Guard, Map, Env, Eval, State) -> end, Type = t_inf(NewTupleType, RecType, Mode), case t_is_none(Type) of - true -> + true -> case Eval of - pos -> signal_guard_fail(Guard, - [RecType, t_from_term(Tag), + pos -> signal_guard_fail(Guard, + [RecType, t_from_term(Tag), t_from_term(Arity)], State); neg -> {Map1, t_atom(false)}; dont_know -> {Map1, t_atom(false)} end; - false -> + false -> case Eval of pos -> {enter_type(Rec, Type, Map1), t_atom(true)}; neg -> {Map1, t_atom(false)}; @@ -2079,17 +2082,17 @@ handle_guard_eq(Guard, Map, Env, Eval, State) -> case {cerl:type(Arg1), cerl:type(Arg2)} of {literal, literal} -> case cerl:concrete(Arg1) =:= cerl:concrete(Arg2) of - true -> - if + true -> + if Eval =:= pos -> {Map, t_atom(true)}; Eval =:= neg -> throw({fail, none}); Eval =:= dont_know -> {Map, t_atom(true)} end; false -> - if + if Eval =:= neg -> {Map, t_atom(false)}; Eval =:= dont_know -> {Map, t_atom(false)}; - Eval =:= pos -> + Eval =:= pos -> ArgTypes = [t_from_term(cerl:concrete(Arg1)), t_from_term(cerl:concrete(Arg2))], signal_guard_fail(Guard, ArgTypes, State) @@ -2144,7 +2147,7 @@ handle_guard_eqeq(Guard, Map, Env, Eval, State) -> false -> if Eval =:= neg -> {Map, t_atom(false)}; Eval =:= dont_know -> {Map, t_atom(false)}; - Eval =:= pos -> + Eval =:= pos -> ArgTypes = [t_from_term(cerl:concrete(Arg1)), t_from_term(cerl:concrete(Arg2))], signal_guard_fail(Guard, ArgTypes, State) @@ -2161,7 +2164,7 @@ handle_guard_eqeq(Guard, Map, Env, Eval, State) -> bind_eqeq_guard(Guard, Arg1, Arg2, Map, Env, Eval, State) -> {Map1, Type1} = bind_guard(Arg1, Map, Env, dont_know, State), {Map2, Type2} = bind_guard(Arg2, Map1, Env, dont_know, State), - ?debug("Types are:~s =:= ~s\n", [t_to_string(Type1), + ?debug("Types are:~s =:= ~s\n", [t_to_string(Type1), t_to_string(Type2)]), Inf = t_inf(Type1, Type2), case t_is_none(Inf) of @@ -2202,15 +2205,15 @@ bind_eqeq_guard_lit_other(Guard, Arg1, Arg2, Map, Env, State) -> {_, Type} = MT = bind_guard(Arg2, Map, Env, pos, State), case t_is_atom(true, Type) of true -> MT; - false -> + false -> {_, Type0} = bind_guard(Arg2, Map, Env, dont_know, State), signal_guard_fail(Guard, [Type0, t_atom(true)], State) end; - false -> + false -> {Map1, Type} = bind_guard(Arg2, Map, Env, neg, State), case t_is_atom(false, Type) of true -> {Map1, t_atom(true)}; - false -> + false -> {_, Type0} = bind_guard(Arg2, Map, Env, dont_know, State), signal_guard_fail(Guard, [Type0, t_atom(true)], State) end; @@ -2242,11 +2245,11 @@ handle_guard_and(Guard, Map, Env, Eval, State) -> end end; neg -> - {Map1, Type1} = + {Map1, Type1} = try bind_guard(Arg1, Map, Env, neg, State) catch throw:{fail, _} -> bind_guard(Arg2, Map, Env, pos, State) end, - {Map2, Type2} = + {Map2, Type2} = try bind_guard(Arg1, Map, Env, neg, State) catch throw:{fail, _} -> bind_guard(Arg2, Map, Env, pos, State) end, @@ -2272,29 +2275,29 @@ handle_guard_or(Guard, Map, Env, Eval, State) -> [Arg1, Arg2] = cerl:call_args(Guard), case Eval of pos -> - {Map1, Bool1} = + {Map1, Bool1} = try bind_guard(Arg1, Map, Env, pos, State) - catch + catch throw:{fail,_} -> bind_guard(Arg1, Map, Env, dont_know, State) end, - {Map2, Bool2} = + {Map2, Bool2} = try bind_guard(Arg2, Map, Env, pos, State) - catch + catch throw:{fail,_} -> bind_guard(Arg2, Map, Env, dont_know, State) end, case ((t_is_atom(true, Bool1) andalso t_is_boolean(Bool2)) - orelse + orelse (t_is_atom(true, Bool2) andalso t_is_boolean(Bool1))) of true -> {join_maps([Map1, Map2], Map), t_atom(true)}; false -> throw({fail, none}) end; neg -> {Map1, Type1} = bind_guard(Arg1, Map, Env, neg, State), - case t_is_atom(true, Type1) of + case t_is_atom(false, Type1) of false -> throw({fail, none}); true -> {Map2, Type2} = bind_guard(Arg2, Map1, Env, neg, State), - case t_is_atom(true, Type2) of + case t_is_atom(false, Type2) of false -> throw({fail, none}); true -> {Map2, t_atom(false)} end @@ -2311,19 +2314,19 @@ handle_guard_or(Guard, Map, Env, Eval, State) -> handle_guard_not(Guard, Map, Env, Eval, State) -> [Arg] = cerl:call_args(Guard), case Eval of - neg -> + neg -> {Map1, Type} = bind_guard(Arg, Map, Env, pos, State), case t_is_atom(true, Type) of true -> {Map1, t_atom(false)}; false -> throw({fail, none}) end; - pos -> + pos -> {Map1, Type} = bind_guard(Arg, Map, Env, neg, State), case t_is_atom(false, Type) of true -> {Map1, t_atom(true)}; false -> throw({fail, none}) end; - dont_know -> + dont_know -> {Map1, Type} = bind_guard(Arg, Map, Env, dont_know, State), Bool = t_inf(Type, t_boolean()), case t_is_none(Bool) of @@ -2355,10 +2358,10 @@ signal_guard_fail(Guard, ArgTypes, State) -> MFA = {cerl:atom_val(cerl:call_module(Guard)), F, length(Args)}, Msg = case is_infix_op(MFA) of - true -> + true -> [ArgType1, ArgType2] = ArgTypes, [Arg1, Arg2] = Args, - {guard_fail, [format_args_1([Arg1], [ArgType1], State), + {guard_fail, [format_args_1([Arg1], [ArgType1], State), atom_to_list(F), format_args_1([Arg2], [ArgType2], State)]}; false -> @@ -2381,7 +2384,7 @@ is_infix_op({M, F, A}) when is_atom(M), is_atom(F), no_return(). signal_guard_fatal_fail(Guard, ArgTypes, State) -> - Args = cerl:call_args(Guard), + Args = cerl:call_args(Guard), F = cerl:atom_val(cerl:call_name(Guard)), Msg = mk_guard_msg(F, Args, ArgTypes, State), throw({fatal_fail, {Guard, Msg}}). @@ -2392,11 +2395,11 @@ mk_guard_msg(F, Args, ArgTypes, State) -> true -> {opaque_guard, FArgs}; false -> {guard_fail, FArgs} end. - + bind_guard_case_clauses(Arg, Clauses, Map, Env, Eval, State) -> Clauses1 = filter_fail_clauses(Clauses), {GenMap, GenArgType} = bind_guard(Arg, Map, Env, dont_know, State), - bind_guard_case_clauses(GenArgType, GenMap, Arg, Clauses1, Map, Env, Eval, + bind_guard_case_clauses(GenArgType, GenMap, Arg, Clauses1, Map, Env, Eval, t_none(), [], State). filter_fail_clauses([Clause|Left]) -> @@ -2413,7 +2416,7 @@ filter_fail_clauses([Clause|Left]) -> filter_fail_clauses([]) -> []. -bind_guard_case_clauses(GenArgType, GenMap, ArgExpr, [Clause|Left], +bind_guard_case_clauses(GenArgType, GenMap, ArgExpr, [Clause|Left], Map, Env, Eval, AccType, AccMaps, State) -> Pats = cerl:clause_pats(Clause), {NewMap0, ArgType} = @@ -2427,7 +2430,7 @@ bind_guard_case_clauses(GenArgType, GenMap, ArgExpr, [Clause|Left], false -> bind_guard(ArgExpr, Map, Env, neg, State); _ -> {GenMap, GenArgType} end - catch + catch throw:{fail, _} -> {none, GenArgType} end; false -> @@ -2457,7 +2460,7 @@ bind_guard_case_clauses(GenArgType, GenMap, ArgExpr, [Clause|Left], NewGenArgType = t_subtract(GenArgType, GenPatType), case (NewMap1 =:= none) orelse t_is_none(GenArgType) of true -> - bind_guard_case_clauses(NewGenArgType, GenMap, ArgExpr, Left, Map, Env, + bind_guard_case_clauses(NewGenArgType, GenMap, ArgExpr, Left, Map, Env, Eval, AccType, AccMaps, State); false -> {NewAccType, NewAccMaps} = @@ -2467,15 +2470,15 @@ bind_guard_case_clauses(GenArgType, GenMap, ArgExpr, [Clause|Left], true -> throw({fail, none}); false -> ok end, - {NewMap3, CType} = bind_guard(cerl:clause_body(Clause), NewMap2, + {NewMap3, CType} = bind_guard(cerl:clause_body(Clause), NewMap2, Env, Eval, State), case Eval of - pos -> + pos -> case t_is_atom(true, CType) of true -> ok; false -> throw({fail, none}) end; - neg -> + neg -> case t_is_atom(false, CType) of true -> ok; false -> throw({fail, none}) @@ -2487,10 +2490,10 @@ bind_guard_case_clauses(GenArgType, GenMap, ArgExpr, [Clause|Left], catch throw:{fail, _What} -> {AccType, AccMaps} end, - bind_guard_case_clauses(NewGenArgType, GenMap, ArgExpr, Left, Map, Env, + bind_guard_case_clauses(NewGenArgType, GenMap, ArgExpr, Left, Map, Env, Eval, NewAccType, NewAccMaps, State) end; -bind_guard_case_clauses(_GenArgType, _GenMap, _ArgExpr, [], Map, _Env, _Eval, +bind_guard_case_clauses(_GenArgType, _GenMap, _ArgExpr, [], Map, _Env, _Eval, AccType, AccMaps, _State) -> case t_is_none(AccType) of true -> throw({fail, none}); @@ -2576,7 +2579,7 @@ enter_type(Key, Val, {Map, Subst} = MS) -> enter_subst(Key, Val, {Map, Subst} = MS) -> KeyLabel = get_label(Key), case cerl:is_literal(Val) of - true -> + true -> NewMap = dict:store(KeyLabel, literal_type(Val), Map), {NewMap, Subst}; false -> @@ -2598,13 +2601,13 @@ enter_subst(Key, Val, {Map, Subst} = MS) -> end end. -lookup_type(Key, {Map, Subst}) -> +lookup_type(Key, {Map, Subst}) -> lookup(Key, Map, Subst, t_none()). lookup(Key, Map, Subst, AnyNone) -> case cerl:is_literal(Key) of true -> literal_type(Key); - false -> + false -> Label = get_label(Key), case dict:find(Label, Subst) of {ok, NewKey} -> lookup(NewKey, Map, Subst, AnyNone); @@ -2669,7 +2672,7 @@ get_label(T) -> t_is_simple(ArgType) -> t_is_atom(ArgType) orelse t_is_number(ArgType) orelse t_is_port(ArgType) - orelse t_is_pid(ArgType) orelse t_is_reference(ArgType) + orelse t_is_pid(ArgType) orelse t_is_reference(ArgType) orelse t_is_nil(ArgType). %% t_is_structured(ArgType) -> @@ -2687,8 +2690,8 @@ is_call_to_send(Tree) -> Mod = cerl:call_module(Tree), Name = cerl:call_name(Tree), Arity = cerl:call_arity(Tree), - cerl:is_c_atom(Mod) - andalso cerl:is_c_atom(Name) + cerl:is_c_atom(Mod) + andalso cerl:is_c_atom(Name) andalso (cerl:atom_val(Name) =:= '!') andalso (cerl:atom_val(Mod) =:= erlang) andalso (Arity =:= 2) @@ -2714,7 +2717,7 @@ filter_match_fail([Clause] = Cls) -> filter_match_fail([H|T]) -> [H|filter_match_fail(T)]; filter_match_fail([]) -> - %% This can actually happen, for example in + %% This can actually happen, for example in %% receive after 1 -> ok end []. @@ -2731,9 +2734,11 @@ determine_mode(Type, Opaques) -> %%% =========================================================================== state__new(Callgraph, Tree, Plt, Module, Records, BehaviourTranslations) -> + Opaques = erl_types:module_builtin_opaques(Module) ++ + erl_types:t_opaque_from_records(Records), TreeMap = build_tree_map(Tree), Funs = dict:fetch_keys(TreeMap), - FunTab = init_fun_tab(Funs, dict:new(), TreeMap, Callgraph, Plt), + FunTab = init_fun_tab(Funs, dict:new(), TreeMap, Callgraph, Plt, Opaques), Work = init_work([get_label(Tree)]), Env = dict:store(top, map__new(), dict:new()), Opaques = erl_types:module_builtin_opaques(Module) ++ @@ -2741,12 +2746,12 @@ state__new(Callgraph, Tree, Plt, Module, Records, BehaviourTranslations) -> #state{callgraph = Callgraph, envs = Env, fun_tab = FunTab, opaques = Opaques, plt = Plt, races = dialyzer_races:new(), records = Records, warning_mode = false, warnings = [], work = Work, tree_map = TreeMap, - module = Module, behaviour_api_info = BehaviourTranslations}. + module = Module, behaviour_api_dict = BehaviourTranslations}. state__mark_fun_as_handled(#state{fun_tab = FunTab} = State, Fun0) -> Fun = get_label(Fun0), case dict:find(Fun, FunTab) of - {ok, {not_handled, Entry}} -> + {ok, {not_handled, Entry}} -> State#state{fun_tab = dict:store(Fun, Entry, FunTab)}; {ok, {_, _}} -> State @@ -2800,7 +2805,7 @@ state__add_warning(State, Tag, Tree, Msg) -> state__add_warning(#state{warning_mode = false} = State, _, _, _, _) -> State; -state__add_warning(#state{warnings = Warnings, warning_mode = true} = State, +state__add_warning(#state{warnings = Warnings, warning_mode = true} = State, Tag, Tree, Msg, Force) -> Ann = cerl:get_ann(Tree), case Force of @@ -2848,7 +2853,7 @@ state__get_warnings(#state{tree_map = TreeMap, fun_tab = FunTab, {Name, Contract} = case dialyzer_callgraph:lookup_name(FunLbl, Callgraph) of error -> {[], none}; - {ok, {_M, F, A} = MFA} -> + {ok, {_M, F, A} = MFA} -> {[F, A], dialyzer_plt:lookup_contract(Plt, MFA)} end, case t_is_none(Ret) of @@ -2866,19 +2871,19 @@ state__get_warnings(#state{tree_map = TreeMap, fun_tab = FunTab, case classify_returns(Fun) of no_match -> Msg = {no_return, [no_match|Name]}, - state__add_warning(AccState, ?WARN_RETURN_NO_RETURN, + state__add_warning(AccState, ?WARN_RETURN_NO_RETURN, Fun, Msg); only_explicit -> Msg = {no_return, [only_explicit|Name]}, - state__add_warning(AccState, ?WARN_RETURN_ONLY_EXIT, + state__add_warning(AccState, ?WARN_RETURN_ONLY_EXIT, Fun, Msg); only_normal -> Msg = {no_return, [only_normal|Name]}, - state__add_warning(AccState, ?WARN_RETURN_NO_RETURN, + state__add_warning(AccState, ?WARN_RETURN_NO_RETURN, Fun, Msg); both -> Msg = {no_return, [both|Name]}, - state__add_warning(AccState, ?WARN_RETURN_NO_RETURN, + state__add_warning(AccState, ?WARN_RETURN_NO_RETURN, Fun, Msg) end; false -> @@ -2916,10 +2921,10 @@ state__lookup_name(Fun, #state{callgraph = Callgraph}) -> state__lookup_record(Tag, Arity, #state{records = Records}) -> case erl_types:lookup_record(Tag, Arity, Records) of - {ok, Fields} -> + {ok, Fields} -> {ok, t_tuple([t_atom(Tag)| [FieldType || {_FieldName, FieldType} <- Fields]])}; - error -> + error -> error end. @@ -2942,15 +2947,15 @@ build_tree_map(Tree) -> end, cerl_trees:fold(Fun, dict:new(), Tree). -init_fun_tab([top|Left], Dict, TreeMap, Callgraph, Plt) -> +init_fun_tab([top|Left], Dict, TreeMap, Callgraph, Plt, Opaques) -> NewDict = dict:store(top, {not_handled, {[], t_none()}}, Dict), - init_fun_tab(Left, NewDict, TreeMap, Callgraph, Plt); -init_fun_tab([Fun|Left], Dict, TreeMap, Callgraph, Plt) -> + init_fun_tab(Left, NewDict, TreeMap, Callgraph, Plt, Opaques); +init_fun_tab([Fun|Left], Dict, TreeMap, Callgraph, Plt, Opaques) -> Arity = cerl:fun_arity(dict:fetch(Fun, TreeMap)), FunEntry = case dialyzer_callgraph:is_escaping(Fun, Callgraph) of true -> - Args = lists:duplicate(Arity, t_any()), + Args = lists:duplicate(Arity, t_any()), case lookup_fun_sig(Fun, Callgraph, Plt) of none -> {Args, t_unit()}; {value, {RetType, _}} -> @@ -2962,8 +2967,8 @@ init_fun_tab([Fun|Left], Dict, TreeMap, Callgraph, Plt) -> false -> {lists:duplicate(Arity, t_none()), t_unit()} end, NewDict = dict:store(Fun, {not_handled, FunEntry}, Dict), - init_fun_tab(Left, NewDict, TreeMap, Callgraph, Plt); -init_fun_tab([], Dict, _TreeMap, _Callgraph, _Plt) -> + init_fun_tab(Left, NewDict, TreeMap, Callgraph, Plt, Opaques); +init_fun_tab([], Dict, _TreeMap, _Callgraph, _Plt, _Opaques) -> Dict. state__update_fun_env(Tree, Map, #state{envs = Envs} = State) -> @@ -2990,7 +2995,7 @@ state__all_fun_types(#state{fun_tab = FunTab}) -> dict:map(fun(_Fun, {Args, Ret}) -> t_fun(Args, Ret)end, Tab1). state__fun_type(Fun, #state{fun_tab = FunTab}) -> - Label = + Label = if is_integer(Fun) -> Fun; true -> get_label(Fun) end, @@ -3001,10 +3006,10 @@ state__fun_type(Fun, #state{fun_tab = FunTab}) -> t_fun(A, R) end. -state__update_fun_entry(Tree, ArgTypes, Out0, +state__update_fun_entry(Tree, ArgTypes, Out0, #state{fun_tab=FunTab, callgraph=CG, plt=Plt} = State)-> Fun = get_label(Tree), - Out1 = + Out1 = if Fun =:= top -> Out0; true -> case lookup_fun_sig(Fun, CG, Plt) of @@ -3016,15 +3021,15 @@ state__update_fun_entry(Tree, ArgTypes, Out0, case dict:find(Fun, FunTab) of {ok, {ArgTypes, OldOut}} -> case t_is_equal(OldOut, Out) of - true -> - ?debug("Fixpoint for ~w: ~s\n", - [state__lookup_name(Fun, State), + true -> + ?debug("Fixpoint for ~w: ~s\n", + [state__lookup_name(Fun, State), t_to_string(t_fun(ArgTypes, Out))]), State; false -> NewEntry = {ArgTypes, Out}, - ?debug("New Entry for ~w: ~s\n", - [state__lookup_name(Fun, State), + ?debug("New Entry for ~w: ~s\n", + [state__lookup_name(Fun, State), t_to_string(t_fun(ArgTypes, Out))]), NewFunTab = dict:store(Fun, NewEntry, FunTab), State1 = State#state{fun_tab = NewFunTab}, @@ -3033,8 +3038,8 @@ state__update_fun_entry(Tree, ArgTypes, Out0, {ok, {NewArgTypes, _OldOut}} -> %% Can only happen in self-recursive functions. Only update the out type. NewEntry = {NewArgTypes, Out}, - ?debug("New Entry for ~w: ~s\n", - [state__lookup_name(Fun, State), + ?debug("New Entry for ~w: ~s\n", + [state__lookup_name(Fun, State), t_to_string(t_fun(NewArgTypes, Out))]), NewFunTab = dict:store(Fun, NewEntry, FunTab), State1 = State#state{fun_tab = NewFunTab}, @@ -3053,9 +3058,9 @@ state__add_work_from_fun(Tree, #state{callgraph = Callgraph, MFAList -> LabelList = [dialyzer_callgraph:lookup_label(MFA, Callgraph) || MFA <- MFAList], - %% Must filter the result for results in this module. + %% Must filter the result for results in this module. FilteredList = [L || {ok, L} <- LabelList, dict:is_key(L, TreeMap)], - ?debug("~w: Will try to add:~w\n", + ?debug("~w: Will try to add:~w\n", [state__lookup_name(get_label(Tree), State), MFAList]), lists:foldl(fun(L, AccState) -> state__add_work(L, AccState) @@ -3086,15 +3091,15 @@ state__fun_info(external, #state{}) -> external; state__fun_info({_, _, _} = MFA, #state{plt = PLT}) -> {MFA, - dialyzer_plt:lookup(PLT, MFA), + dialyzer_plt:lookup(PLT, MFA), dialyzer_plt:lookup_contract(PLT, MFA), t_any()}; state__fun_info(Fun, #state{callgraph = CG, fun_tab = FunTab, plt = PLT}) -> {Sig, Contract} = case dialyzer_callgraph:lookup_name(Fun, CG) of - error -> + error -> {dialyzer_plt:lookup(PLT, Fun), none}; - {ok, MFA} -> + {ok, MFA} -> {dialyzer_plt:lookup(PLT, MFA), dialyzer_plt:lookup_contract(PLT, MFA)} end, LocalRet = @@ -3122,18 +3127,18 @@ state__find_apply_return(Tree, #state{callgraph = Callgraph} = State) -> forward_args(Fun, ArgTypes, #state{work = Work, fun_tab = FunTab} = State) -> {OldArgTypes, OldOut, Fixpoint} = case dict:find(Fun, FunTab) of - {ok, {not_handled, {OldArgTypes0, OldOut0}}} -> + {ok, {not_handled, {OldArgTypes0, OldOut0}}} -> {OldArgTypes0, OldOut0, false}; {ok, {OldArgTypes0, OldOut0}} -> - {OldArgTypes0, OldOut0, + {OldArgTypes0, OldOut0, t_is_subtype(t_product(ArgTypes), t_product(OldArgTypes0))} end, case Fixpoint of true -> State; - false -> + false -> NewArgTypes = [t_sup(X, Y) || {X, Y} <- lists:zip(ArgTypes, OldArgTypes)], NewWork = add_work(Fun, Work), - ?debug("~w: forwarding args ~s\n", + ?debug("~w: forwarding args ~s\n", [state__lookup_name(Fun, State), t_to_string(t_product(NewArgTypes))]), NewFunTab = dict:store(Fun, {NewArgTypes, OldOut}, FunTab), @@ -3248,7 +3253,7 @@ get_file([_|Tail]) -> get_file(Tail). is_compiler_generated(Ann) -> lists:member(compiler_generated, Ann) orelse (get_line(Ann) < 1). --spec format_args([term()], [erl_types:erl_type()], state()) -> +-spec format_args([cerl:cerl()], [erl_types:erl_type()], state()) -> nonempty_string(). format_args([], [], _State) -> @@ -3256,9 +3261,6 @@ format_args([], [], _State) -> format_args(ArgList, TypeList, State) -> "(" ++ format_args_1(ArgList, TypeList, State) ++ ")". --spec format_args_1([term(),...], [erl_types:erl_type(),...], state()) -> - string(). - format_args_1([Arg], [Type], State) -> format_arg(Arg) ++ format_type(Type, State); format_args_1([Arg|Args], [Type|Types], State) -> @@ -3291,6 +3293,11 @@ format_arg(Arg) -> format_type(Type, #state{records = R}) -> t_to_string(Type, R). +-spec format_field_diffs(erl_types:erl_type(), state()) -> string(). + +format_field_diffs(RecConstruction, #state{records = R}) -> + erl_types:record_field_diffs_to_string(RecConstruction, R). + -spec format_sig_args(erl_types:erl_type(), state()) -> string(). format_sig_args(Type, #state{records = R}) -> @@ -3298,12 +3305,12 @@ format_sig_args(Type, #state{records = R}) -> case SigArgs of [] -> "()"; [SArg|SArgs] -> - lists:flatten("(" ++ t_to_string(SArg, R) + lists:flatten("(" ++ t_to_string(SArg, R) ++ ["," ++ t_to_string(T, R) || T <- SArgs] ++ ")") end. format_cerl(Tree) -> - cerl_prettypr:format(cerl:set_ann(Tree, []), + cerl_prettypr:format(cerl:set_ann(Tree, []), [{hook, dialyzer_utils:pp_hook()}, {noann, true}, {paper, 100000}, %% These guys strip @@ -3366,7 +3373,7 @@ find_terminals(Tree) -> true -> M = cerl:concrete(M0), F = cerl:concrete(F0), - case (erl_bif_types:is_known(M, F, A) + case (erl_bif_types:is_known(M, F, A) andalso t_is_none(erl_bif_types:type(M, F, A))) of true -> {true, false}; false -> {false, true} @@ -3381,12 +3388,12 @@ find_terminals(Tree) -> letrec -> find_terminals(cerl:letrec_body(Tree)); literal -> {false, true}; primop -> {false, false}; %% match_fail, etc. are not explicit exits. - 'receive' -> + 'receive' -> Timeout = cerl:receive_timeout(Tree), Clauses = cerl:receive_clauses(Tree), case (cerl:is_literal(Timeout) andalso (cerl:concrete(Timeout) =:= infinity)) of - true -> + true -> if Clauses =:= [] -> {false, true}; %% A never ending receive. true -> find_terminals_list(Clauses) end; @@ -3454,11 +3461,11 @@ find_rec_warnings_tuple(Tree, State) -> TagVal = cerl:atom_val(Tag), case state__lookup_record(TagVal, length(Left), State) of error -> State; - {ok, Prototype} -> + {ok, Prototype} -> InfTupleType = t_inf(Prototype, TupleType), case t_is_none(InfTupleType) of true -> - Msg = {record_matching, + Msg = {record_matching, [format_patterns([Tree]), TagVal]}, state__add_warning(State, ?WARN_MATCHING, Tree, Msg); false -> @@ -3476,7 +3483,7 @@ find_rec_warnings_tuple(Tree, State) -> %%---------------------------------------------------------------------------- -ifdef(DEBUG_PP). -debug_pp(Tree, true) -> +debug_pp(Tree, true) -> io:put_chars(cerl_prettypr:format(Tree, [{hook, cerl_typean:pp_hook()}])), io:nl(), ok; diff --git a/lib/dialyzer/src/dialyzer_options.erl b/lib/dialyzer/src/dialyzer_options.erl index da0e1f9aaf..010625b7bd 100644 --- a/lib/dialyzer/src/dialyzer_options.erl +++ b/lib/dialyzer/src/dialyzer_options.erl @@ -184,7 +184,7 @@ build_options([], Options) -> assert_filenames(Term, [FileName|Left]) when length(FileName) >= 0 -> case filelib:is_file(FileName) orelse filelib:is_dir(FileName) of true -> ok; - false -> bad_option("No such file or directory", FileName) + false -> bad_option("No such file, directory or application", FileName) end, assert_filenames(Term, Left); assert_filenames(_Term, []) -> diff --git a/lib/dialyzer/src/dialyzer_plt.erl b/lib/dialyzer/src/dialyzer_plt.erl index e387077a46..0f5be3b7f2 100644 --- a/lib/dialyzer/src/dialyzer_plt.erl +++ b/lib/dialyzer/src/dialyzer_plt.erl @@ -21,13 +21,15 @@ %%%------------------------------------------------------------------- %%% File : dialyzer_plt.erl %%% Author : Tobias Lindahl <[email protected]> -%%% Description : Interface to display information in the persistent +%%% Description : Interface to display information in the persistent %%% lookup tables. %%% %%% Created : 23 Jul 2004 by Tobias Lindahl <[email protected]> %%%------------------------------------------------------------------- -module(dialyzer_plt). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([check_plt/3, compute_md5_from_files/1, contains_mfa/2, @@ -39,10 +41,12 @@ from_file/1, get_default_plt/0, get_types/1, + get_exported_types/1, %% insert/3, insert_list/2, insert_contract_list/2, insert_types/2, + insert_exported_types/2, lookup/2, lookup_contract/2, lookup_module/2, @@ -57,6 +61,8 @@ %% Debug utilities -export([pp_non_returning/0, pp_mod/1]). +-export_type([plt/0, plt_info/0]). + %%---------------------------------------------------------------------- -type mod_deps() :: dict(). @@ -70,9 +76,10 @@ %%---------------------------------------------------------------------- --record(plt, {info = table_new() :: dict(), - types = table_new() :: dict(), - contracts = table_new() :: dict()}). +-record(plt, {info = table_new() :: dict(), + types = table_new() :: dict(), + contracts = table_new() :: dict(), + exported_types = sets:new() :: set()}). -opaque plt() :: #plt{}. -include("dialyzer.hrl"). @@ -80,13 +87,14 @@ -type file_md5() :: {file:filename(), binary()}. -type plt_info() :: {[file_md5()], dict()}. --record(file_plt, {version = "" :: string(), - file_md5_list = [] :: [file_md5()], - info = dict:new() :: dict(), - contracts = dict:new() :: dict(), - types = dict:new() :: dict(), - mod_deps :: mod_deps(), - implementation_md5 = [] :: [file_md5()]}). +-record(file_plt, {version = "" :: string(), + file_md5_list = [] :: [file_md5()], + info = dict:new() :: dict(), + contracts = dict:new() :: dict(), + types = dict:new() :: dict(), + exported_types = sets:new() :: set(), + mod_deps :: mod_deps(), + implementation_md5 = [] :: [file_md5()]}). %%---------------------------------------------------------------------- @@ -95,19 +103,23 @@ new() -> #plt{}. --spec delete_module(plt(), module()) -> plt(). +-spec delete_module(plt(), atom()) -> plt(). -delete_module(#plt{info = Info, types = Types, contracts = Contracts}, Mod) -> +delete_module(#plt{info = Info, types = Types, contracts = Contracts, + exported_types = ExpTypes}, Mod) -> #plt{info = table_delete_module(Info, Mod), types = table_delete_module2(Types, Mod), - contracts = table_delete_module(Contracts, Mod)}. + contracts = table_delete_module(Contracts, Mod), + exported_types = table_delete_module1(ExpTypes, Mod)}. -spec delete_list(plt(), [mfa() | integer()]) -> plt(). -delete_list(#plt{info = Info, types = Types, contracts = Contracts}, List) -> +delete_list(#plt{info = Info, types = Types, contracts = Contracts, + exported_types = ExpTypes}, List) -> #plt{info = table_delete_list(Info, List), types = Types, - contracts = table_delete_list(Contracts, List)}. + contracts = table_delete_list(Contracts, List), + exported_types = ExpTypes}. -spec insert_contract_list(plt(), dialyzer_contracts:plt_contracts()) -> plt(). @@ -126,7 +138,7 @@ delete_contract_list(#plt{contracts = Contracts} = PLT, List) -> PLT#plt{contracts = table_delete_list(Contracts, List)}. %% -spec insert(plt(), mfa() | integer(), {_, _}) -> plt(). -%% +%% %% insert(#plt{info = Info} = PLT, Id, Types) -> %% PLT#plt{info = table_insert(Info, Id, Types)}. @@ -150,19 +162,29 @@ lookup(#plt{info = Info}, Label) when is_integer(Label) -> insert_types(PLT, Rec) -> PLT#plt{types = Rec}. +-spec insert_exported_types(plt(), set()) -> plt(). + +insert_exported_types(PLT, Set) -> + PLT#plt{exported_types = Set}. + -spec get_types(plt()) -> dict(). get_types(#plt{types = Types}) -> Types. +-spec get_exported_types(plt()) -> set(). + +get_exported_types(#plt{exported_types = ExpTypes}) -> + ExpTypes. + -type mfa_types() :: {mfa(), erl_types:erl_type(), [erl_types:erl_type()]}. --spec lookup_module(plt(), module()) -> 'none' | {'value', [mfa_types()]}. +-spec lookup_module(plt(), atom()) -> 'none' | {'value', [mfa_types()]}. lookup_module(#plt{info = Info}, M) when is_atom(M) -> table_lookup_module(Info, M). --spec contains_module(plt(), module()) -> boolean(). +-spec contains_module(plt(), atom()) -> boolean(). contains_module(#plt{info = Info, contracts = Cs}, M) when is_atom(M) -> table_contains_module(Info, M) orelse table_contains_module(Cs, M). @@ -170,7 +192,7 @@ contains_module(#plt{info = Info, contracts = Cs}, M) when is_atom(M) -> -spec contains_mfa(plt(), mfa()) -> boolean(). contains_mfa(#plt{info = Info, contracts = Contracts}, MFA) -> - (table_lookup(Info, MFA) =/= none) + (table_lookup(Info, MFA) =/= none) orelse (table_lookup(Contracts, MFA) =/= none). -spec get_default_plt() -> file:filename(). @@ -201,13 +223,14 @@ from_file(FileName, ReturnInfo) -> case get_record_from_file(FileName) of {ok, Rec} -> case check_version(Rec) of - error -> + error -> Msg = io_lib:format("Old PLT file ~s\n", [FileName]), error(Msg); - ok -> + ok -> Plt = #plt{info = Rec#file_plt.info, types = Rec#file_plt.types, - contracts = Rec#file_plt.contracts}, + contracts = Rec#file_plt.contracts, + exported_types = Rec#file_plt.exported_types}, case ReturnInfo of false -> Plt; true -> @@ -217,12 +240,12 @@ from_file(FileName, ReturnInfo) -> end end; {error, Reason} -> - error(io_lib:format("Could not read PLT file ~s: ~p\n", + error(io_lib:format("Could not read PLT file ~s: ~p\n", [FileName, Reason])) end. -type inc_file_err_rsn() :: 'no_such_file' | 'read_error'. --spec included_files(file:filename()) -> {'ok', [file:filename()]} +-spec included_files(file:filename()) -> {'ok', [file:filename()]} | {'error', inc_file_err_rsn()}. included_files(FileName) -> @@ -247,12 +270,12 @@ get_record_from_file(FileName) -> try binary_to_term(Bin) of #file_plt{} = FilePLT -> {ok, FilePLT}; _ -> {error, not_valid} - catch + catch _:_ -> {error, not_valid} end; {error, enoent} -> {error, no_such_file}; - {error, _} -> + {error, _} -> {error, read_error} end. @@ -261,19 +284,22 @@ get_record_from_file(FileName) -> merge_plts(List) -> InfoList = [Info || #plt{info = Info} <- List], TypesList = [Types || #plt{types = Types} <- List], + ExpTypesList = [ExpTypes || #plt{exported_types = ExpTypes} <- List], ContractsList = [Contracts || #plt{contracts = Contracts} <- List], #plt{info = table_merge(InfoList), types = table_merge(TypesList), + exported_types = sets_merge(ExpTypesList), contracts = table_merge(ContractsList)}. -spec to_file(file:filename(), plt(), mod_deps(), {[file_md5()], mod_deps()}) -> 'ok'. to_file(FileName, - #plt{info = Info, types = Types, contracts = Contracts}, + #plt{info = Info, types = Types, contracts = Contracts, + exported_types = ExpTypes}, ModDeps, {MD5, OldModDeps}) -> - NewModDeps = dict:merge(fun(_Key, OldVal, NewVal) -> + NewModDeps = dict:merge(fun(_Key, OldVal, NewVal) -> ordsets:union(OldVal, NewVal) - end, + end, OldModDeps, ModDeps), ImplMd5 = compute_implementation_md5(), Record = #file_plt{version = ?VSN, @@ -281,13 +307,14 @@ to_file(FileName, info = Info, contracts = Contracts, types = Types, + exported_types = ExpTypes, mod_deps = NewModDeps, implementation_md5 = ImplMd5}, Bin = term_to_binary(Record, [compressed]), case file:write_file(FileName, Bin) of ok -> ok; {error, Reason} -> - Msg = io_lib:format("Could not write PLT file ~s: ~w\n", + Msg = io_lib:format("Could not write PLT file ~s: ~w\n", [FileName, Reason]), throw({dialyzer_error, Msg}) end. @@ -295,8 +322,8 @@ to_file(FileName, -type md5_diff() :: [{'differ', atom()} | {'removed', atom()}]. -type check_error() :: 'not_valid' | 'no_such_file' | 'read_error' | {'no_file_to_remove', file:filename()}. - --spec check_plt(file:filename(), [file:filename()], [file:filename()]) -> + +-spec check_plt(file:filename(), [file:filename()], [file:filename()]) -> 'ok' | {'error', check_error()} | {'differ', [file_md5()], md5_diff(), mod_deps()} @@ -306,7 +333,7 @@ check_plt(FileName, RemoveFiles, AddFiles) -> case get_record_from_file(FileName) of {ok, #file_plt{file_md5_list = Md5, mod_deps = ModDeps} = Rec} -> case check_version(Rec) of - ok -> + ok -> case compute_new_md5(Md5, RemoveFiles, AddFiles) of ok -> ok; {differ, NewMd5, DiffMd5} -> {differ, NewMd5, DiffMd5, ModDeps}; @@ -363,7 +390,7 @@ compute_md5_from_files(Files) -> compute_md5_from_file(File) -> case filelib:is_regular(File) of - false -> + false -> Msg = io_lib:format("Not a regular file: ~s\n", [File]), throw({dialyzer_error, Msg}); true -> @@ -394,7 +421,7 @@ init_md5_list_1([{File, _Md5}|Md5Left], [{remove, File}|DiffLeft], Acc) -> init_md5_list_1(Md5Left, DiffLeft, Acc); init_md5_list_1([{File, _Md5} = Entry|Md5Left], [{add, File}|DiffLeft], Acc) -> init_md5_list_1(Md5Left, DiffLeft, [Entry|Acc]); -init_md5_list_1([{File1, _Md5} = Entry|Md5Left] = Md5List, +init_md5_list_1([{File1, _Md5} = Entry|Md5Left] = Md5List, [{Tag, File2}|DiffLeft] = DiffList, Acc) -> case File1 < File2 of true -> init_md5_list_1(Md5Left, DiffList, [Entry|Acc]); @@ -425,7 +452,7 @@ get_specs(#plt{info = Info}) -> beam_file_to_module(Filename) -> list_to_atom(filename:basename(Filename, ".beam")). --spec get_specs(plt(), module(), atom(), arity_patt()) -> 'none' | string(). +-spec get_specs(plt(), atom(), atom(), arity_patt()) -> 'none' | string(). get_specs(#plt{info = Info}, M, F, A) when is_atom(M), is_atom(F) -> MFA = {M, F, A}, @@ -435,7 +462,7 @@ get_specs(#plt{info = Info}, M, F, A) when is_atom(M), is_atom(F) -> end. create_specs([{{M, F, _A}, {Ret, Args}}|Left], M) -> - [io_lib:format("-spec ~w(~s) -> ~s\n", + [io_lib:format("-spec ~w(~s) -> ~s\n", [F, expand_args(Args), erl_types:t_to_string(Ret)]) | create_specs(Left, M)]; create_specs(List = [{{M, _F, _A}, {_Ret, _Args}}| _], _M) -> @@ -475,6 +502,9 @@ table_delete_module(Plt, Mod) -> (_, _) -> true end, Plt). +table_delete_module1(Plt, Mod) -> + sets:filter(fun({M, _F, _A}) -> M =/= Mod end, Plt). + table_delete_module2(Plt, Mod) -> dict:filter(fun(M, _Val) -> M =/= Mod end, Plt). @@ -488,7 +518,7 @@ table_insert_list(Plt, [{Key, Val}|Left]) -> table_insert_list(Plt, []) -> Plt. -table_insert(Plt, Key, {_Ret, _Arg} = Obj) -> +table_insert(Plt, Key, {_Ret, _Arg} = Obj) -> dict:store(Key, Obj, Plt); table_insert(Plt, Key, #contract{} = C) -> dict:store(Key, C, Plt). @@ -526,6 +556,15 @@ table_merge([Plt|Plts], Acc) -> NewAcc = dict:merge(fun(_Key, Val, Val) -> Val end, Plt, Acc), table_merge(Plts, NewAcc). +sets_merge([H|T]) -> + sets_merge(T, H). + +sets_merge([], Acc) -> + Acc; +sets_merge([Plt|Plts], Acc) -> + NewAcc = sets:union(Plt, Acc), + sets_merge(Plts, NewAcc). + %%--------------------------------------------------------------------------- %% Debug utilities. @@ -555,7 +594,7 @@ pp_non_returning() -> [M, F, dialyzer_utils:format_sig(Type)]) end, lists:sort(None)). --spec pp_mod(module()) -> 'ok'. +-spec pp_mod(atom()) -> 'ok'. pp_mod(Mod) when is_atom(Mod) -> PltFile = get_default_plt(), diff --git a/lib/dialyzer/src/dialyzer_races.erl b/lib/dialyzer/src/dialyzer_races.erl index 4972967960..ec8d613b96 100644 --- a/lib/dialyzer/src/dialyzer_races.erl +++ b/lib/dialyzer/src/dialyzer_races.erl @@ -21,7 +21,7 @@ %%%---------------------------------------------------------------------- %%% File : dialyzer_races.erl %%% Author : Maria Christakis <[email protected]> -%%% Description : Utility functions for race condition detection +%%% Description : Utility functions for race condition detection %%% %%% Created : 21 Nov 2008 by Maria Christakis <[email protected]> %%%---------------------------------------------------------------------- @@ -39,6 +39,8 @@ let_tag_new/2, new/0, put_curr_fun/3, put_fun_args/2, put_race_analysis/2, put_race_list/3]). +-export_type([races/0, mfa_or_funlbl/0, core_vars/0]). + -include("dialyzer.hrl"). %%% =========================================================================== @@ -80,7 +82,7 @@ -type call() :: 'whereis' | 'register' | 'unregister' | 'ets_new' | 'ets_lookup' | 'ets_insert' | 'mnesia_dirty_read1' | 'mnesia_dirty_read2' | 'mnesia_dirty_write1' - | 'mnesia_dirty_write2' | 'function_call'. + | 'mnesia_dirty_write2' | 'function_call'. -type race_tag() :: 'whereis_register' | 'whereis_unregister' | 'ets_lookup_insert' | 'mnesia_dirty_read_write'. @@ -157,7 +159,7 @@ %%% =========================================================================== -spec store_race_call(mfa_or_funlbl(), [erl_types:erl_type()], [core_vars()], - file_line(), dialyzer_dataflow:state()) -> + file_line(), dialyzer_dataflow:state()) -> dialyzer_dataflow:state(). store_race_call(Fun, ArgTypes, Args, FileLine, State) -> @@ -166,7 +168,7 @@ store_race_call(Fun, ArgTypes, Args, FileLine, State) -> CurrFunLabel = Races#races.curr_fun_label, RaceTags = Races#races.race_tags, CleanState = dialyzer_dataflow:state__records_only(State), - {NewRaceList, NewRaceListSize, NewRaceTags, NewTable} = + {NewRaceList, NewRaceListSize, NewRaceTags, NewTable} = case CurrFun of {_Module, module_info, A} when A =:= 0 orelse A =:= 1 -> {[], 0, RaceTags, no_t}; @@ -422,7 +424,7 @@ fixup_race_forward_pullout(CurrFun, CurrFunLabel, Calls, Code, RaceList, Races = dialyzer_dataflow:state__get_races(State), {RetCurrFun, RetCurrFunLabel, RetCalls, RetCode, RetRaceList, RetRaceVarMap, RetFunDefVars, RetFunCallVars, - RetFunArgTypes, RetNestingLevel} = + RetFunArgTypes, RetNestingLevel} = fixup_race_forward_helper(NewCurrFun, NewCurrFunLabel, Fun, Int, NewCalls, NewCalls, [#curr_fun{status = out, mfa = NewCurrFun, @@ -576,7 +578,7 @@ fixup_race_forward(CurrFun, CurrFunLabel, Calls, Code, RaceList, RaceTag -> PublicTables = dialyzer_callgraph:get_public_tables(Callgraph), NamedTables = dialyzer_callgraph:get_named_tables(Callgraph), - WarnVarArgs1 = + WarnVarArgs1 = var_type_analysis(FunDefVars, FunArgTypes, WarnVarArgs, RaceWarnTag, RaceVarMap, dialyzer_dataflow:state__records_only(State)), @@ -598,7 +600,7 @@ fixup_race_forward(CurrFun, CurrFunLabel, Calls, Code, RaceList, [#warn_call{call_name = ets_insert, args = WarnVarArgs, var_map = RaceVarMap}], [Tab, Names, _, _] = WarnVarArgs, - case IsPublic orelse + case IsPublic orelse compare_var_list(Tab, PublicTables, RaceVarMap) orelse length(Names -- NamedTables) < length(Names) of @@ -636,7 +638,7 @@ fixup_race_forward(CurrFun, CurrFunLabel, Calls, Code, RaceList, #curr_fun{mfa = CurrFun2, label = CurrFunLabel2, var_map = RaceVarMap2, def_vars = FunDefVars2, call_vars = FunCallVars2, arg_types = FunArgTypes2}, - Code2, NestingLevel2} = + Code2, NestingLevel2} = remove_clause(NewRL, #curr_fun{mfa = CurrFun, label = CurrFunLabel, var_map = RaceVarMap1, @@ -648,7 +650,7 @@ fixup_race_forward(CurrFun, CurrFunLabel, Calls, Code, RaceList, RaceVarMap2, FunDefVars2, FunCallVars2, FunArgTypes2, NestingLevel2, false}; false -> - {CurrFun, CurrFunLabel, Tail, NewRL, RaceVarMap1, + {CurrFun, CurrFunLabel, Tail, NewRL, RaceVarMap1, FunDefVars, FunCallVars, FunArgTypes, NewNL, false} end; #end_clause{arg = Arg, pats = Pats, guard = Guard} -> @@ -893,7 +895,7 @@ do_clause(RaceList, WarnVarArgs, RaceWarnTag, RaceVarMap, CurrLevel, PublicTables, NamedTables) -> {DepList, IsPublic, Continue} = get_deplist_paths(fixup_case_path(RaceList, 0), WarnVarArgs, - RaceWarnTag, RaceVarMap, CurrLevel, + RaceWarnTag, RaceVarMap, CurrLevel, PublicTables, NamedTables), {fixup_case_rest_paths(RaceList, 0), DepList, IsPublic, Continue}. @@ -963,7 +965,7 @@ fixup_race_forward_helper(CurrFun, CurrFunLabel, Fun, FunLabel, #curr_fun{mfa = NewCurrFun, label = NewCurrFunLabel, var_map = NewRaceVarMap, def_vars = NewFunDefVars, call_vars = NewFunCallVars, arg_types = NewFunArgTypes}, - NewCode, NewNestingLevel} = + NewCode, NewNestingLevel} = remove_clause(RaceList, #curr_fun{mfa = CurrFun, label = CurrFunLabel, var_map = RaceVarMap, def_vars = FunDefVars, call_vars = FunCallVars, @@ -995,7 +997,7 @@ fixup_race_forward_helper(CurrFun, CurrFunLabel, Fun, FunLabel, arg_types = NewFunTypes}], [#curr_fun{status = in, mfa = Fun, label = FunLabel, var_map = NewRaceVarMap, - def_vars = Args, call_vars = NewFunArgs, + def_vars = Args, call_vars = NewFunArgs, arg_types = NewFunTypes}| lists:reverse(StateRaceList)] ++ RetC, NewRaceVarMap), @@ -1060,7 +1062,7 @@ fixup_race_backward(CurrFun, Calls, CallsToAnalyze, Parents, Height) -> case Height =:= 0 of true -> Parents; false -> - case Calls of + case Calls of [] -> case is_integer(CurrFun) orelse lists:member(CurrFun, Parents) of true -> Parents; @@ -1219,7 +1221,7 @@ are_bound_vars(Vars1, Vars2, RaceVarMap) -> callgraph__renew_tables(Table, Callgraph) -> case Table of {named, NameLabel, Names} -> - PTablesToAdd = + PTablesToAdd = case NameLabel of ?no_label -> []; _Other -> [NameLabel] @@ -1438,7 +1440,7 @@ lists_key_members_lists_helper(Elem, List, N) when is_integer(Elem) -> end; lists_key_members_lists_helper(_Elem, _List, _N) -> [0]. - + lists_key_replace(N, List, NewMember) -> {Before, [_|After]} = lists:split(N - 1, List), Before ++ [NewMember|After]. @@ -1488,7 +1490,7 @@ refine_race_helper(RaceCall, VarArgs, WarnVarArgs, RaceWarnTag, DependencyList, false -> DependencyList end. -remove_clause(RaceList, CurrTuple, Code, NestingLevel) -> +remove_clause(RaceList, CurrTuple, Code, NestingLevel) -> NewRaceList = fixup_case_rest_paths(RaceList, 0), {NewCurrTuple, NewCode} = cleanup_clause_code(CurrTuple, Code, 0, NestingLevel), @@ -1621,7 +1623,7 @@ compare_ets_insert(OldWarnVarArgs, NewWarnVarArgs, RaceVarMap) -> end end, case Bool of - true -> + true -> case any_args(Old4) of true -> case compare_list_vars(Old3, ets_list_args(New3), [], RaceVarMap) of @@ -1690,7 +1692,6 @@ compare_types(VarArgs, WarnVarArgs, RaceWarnTag, RaceVarMap) -> false -> compare_var_list(VA1, WVA1, RaceVarMap) orelse compare_argtypes(VA2, WVA2) - end end; ?WARN_WHEREIS_UNREGISTER -> @@ -1704,7 +1705,6 @@ compare_types(VarArgs, WarnVarArgs, RaceWarnTag, RaceVarMap) -> false -> compare_var_list(VA1, WVA1, RaceVarMap) orelse compare_argtypes(VA2, WVA2) - end end; ?WARN_ETS_LOOKUP_INSERT -> @@ -1716,12 +1716,12 @@ compare_types(VarArgs, WarnVarArgs, RaceWarnTag, RaceVarMap) -> false -> case any_args(WVA2) of true -> compare_var_list(VA1, WVA1, RaceVarMap); - false -> + false -> compare_var_list(VA1, WVA1, RaceVarMap) orelse compare_argtypes(VA2, WVA2) end end, - Bool andalso + Bool andalso (case any_args(VA4) of true -> compare_var_list(VA3, WVA3, RaceVarMap); @@ -2158,7 +2158,7 @@ race_var_map_guard_helper1(Arg, Pats, RaceVarMap, Op) -> _Else -> {RaceVarMap, false} end; false -> {RaceVarMap, false} - end; + end; _Other -> {RaceVarMap, false} end; _Other -> {RaceVarMap, false} @@ -2241,7 +2241,7 @@ var_analysis(FunDefArgs, FunCallArgs, WarnVarArgs, RaceWarnTag) -> [WVA1, WVA2|T] = WarnVarArgs, ArgNos = lists_key_members_lists(WVA1, FunDefArgs), [[lists_get(N, FunCallArgs) || N <- ArgNos], WVA2|T] - end. + end. var_type_analysis(FunDefArgs, FunCallTypes, WarnVarArgs, RaceWarnTag, RaceVarMap, CleanState) -> @@ -2286,7 +2286,7 @@ var_type_analysis(FunDefArgs, FunCallTypes, WarnVarArgs, RaceWarnTag, ets_tuple_argtypes1(lists:nth(N2 + 1, FunVarArgs), [], [], 0), []), FirstVarArg ++ [Vars2, NewWVA4] - + end; ?WARN_MNESIA_DIRTY_READ_WRITE -> [WVA1, WVA2|T] = WarnVarArgs, @@ -2330,7 +2330,7 @@ get_race_warn(Fun, Args, ArgTypes, DepList, State) -> -spec get_race_warnings(races(), dialyzer_dataflow:state()) -> {races(), dialyzer_dataflow:state()}. - + get_race_warnings(#races{race_warnings = RaceWarnings}, State) -> get_race_warnings_helper(RaceWarnings, State). @@ -2430,12 +2430,12 @@ end_clause_new(Arg, Pats, Guard) -> #end_clause{arg = Arg, pats = Pats, guard = Guard}. -spec get_curr_fun(races()) -> mfa_or_funlbl(). - + get_curr_fun(#races{curr_fun = CurrFun}) -> CurrFun. -spec get_curr_fun_args(races()) -> core_args(). - + get_curr_fun_args(#races{curr_fun_args = CurrFunArgs}) -> CurrFunArgs. @@ -2445,17 +2445,17 @@ get_new_table(#races{new_table = Table}) -> Table. -spec get_race_analysis(races()) -> boolean(). - + get_race_analysis(#races{race_analysis = RaceAnalysis}) -> RaceAnalysis. -spec get_race_list(races()) -> code(). - + get_race_list(#races{race_list = RaceList}) -> RaceList. -spec get_race_list_size(races()) -> non_neg_integer(). - + get_race_list_size(#races{race_list_size = RaceListSize}) -> RaceListSize. @@ -2483,10 +2483,10 @@ put_fun_args(Args, #races{curr_fun_args = CurrFunArgs} = Races) -> empty -> Races#races{curr_fun_args = Args}; _Other -> Races end. - + -spec put_race_analysis(boolean(), races()) -> races(). - + put_race_analysis(Analysis, Races) -> Races#races{race_analysis = Analysis}. diff --git a/lib/dialyzer/src/dialyzer_succ_typings.erl b/lib/dialyzer/src/dialyzer_succ_typings.erl index 1ff4783852..8bfc66fc39 100644 --- a/lib/dialyzer/src/dialyzer_succ_typings.erl +++ b/lib/dialyzer/src/dialyzer_succ_typings.erl @@ -435,7 +435,7 @@ format_scc(SCC) -> %% %% ============================================================================ --spec doit(module() | string()) -> 'ok'. +-spec doit(atom() | file:filename()) -> 'ok'. doit(Module) -> {ok, AbstrCode} = dialyzer_utils:get_abstract_code_from_src(Module), diff --git a/lib/dialyzer/src/dialyzer_typesig.erl b/lib/dialyzer/src/dialyzer_typesig.erl index 35b283a00a..3effb1c2e6 100644 --- a/lib/dialyzer/src/dialyzer_typesig.erl +++ b/lib/dialyzer/src/dialyzer_typesig.erl @@ -21,7 +21,7 @@ %%%------------------------------------------------------------------- %%% File : dialyzer_typesig.erl %%% Author : Tobias Lindahl <[email protected]> -%%% Description : +%%% Description : %%% %%% Created : 25 Apr 2005 by Tobias Lindahl <[email protected]> %%%------------------------------------------------------------------- @@ -31,12 +31,12 @@ -export([analyze_scc/5]). -export([get_safe_underapprox/2]). --import(erl_types, +-import(erl_types, [t_any/0, t_atom/0, t_atom_vals/1, t_binary/0, t_bitstr/0, t_bitstr/2, t_bitstr_concat/1, t_boolean/0, t_collect_vars/1, t_cons/2, t_cons_hd/1, t_cons_tl/1, t_float/0, t_from_range/2, t_from_term/1, - t_fun/0, t_fun/2, t_fun_args/1, t_fun_range/1, + t_fun/0, t_fun/2, t_fun_args/1, t_fun_range/1, t_has_var/1, t_inf/2, t_inf/3, t_integer/0, t_is_any/1, t_is_atom/1, t_is_atom/2, t_is_cons/1, t_is_equal/2, @@ -44,7 +44,7 @@ t_is_integer/1, t_non_neg_integer/0, t_is_list/1, t_is_nil/1, t_is_none/1, t_is_number/1, - t_is_subtype/2, t_limit/2, t_list/0, t_list/1, + t_is_subtype/2, t_limit/2, t_list/0, t_list/1, t_list_elements/1, t_nonempty_list/1, t_maybe_improper_list/0, t_module/0, t_number/0, t_number_vals/1, t_opaque_match_record/2, t_opaque_matching_structure/2, @@ -101,7 +101,7 @@ name_map = dict:new() :: dict(), next_label :: label(), non_self_recs = [] :: [label()], - plt :: dialyzer_plt:plt(), + plt :: dialyzer_plt:plt(), prop_types = dict:new() :: dict(), records = dict:new() :: dict(), opaques = [] :: [erl_types:erl_type()], @@ -140,8 +140,8 @@ %% where Def = {Var, Fun} as in the Core Erlang module definitions. %% Records = dict(RecName, {Arity, [{FieldName, FieldType}]}) %% NextLabel - An integer that is higher than any label in the code. -%% CallGraph - A callgraph as produced by dialyzer_callgraph.erl -%% Note: The callgraph must have been built with all the +%% CallGraph - A callgraph as produced by dialyzer_callgraph.erl +%% Note: The callgraph must have been built with all the %% code that the SCC is a part of. %% PLT - A dialyzer PLT. This PLT should contain available information %% about functions that can be called by this SCC. @@ -150,7 +150,7 @@ %%----------------------------------------------------------------------------- -spec analyze_scc(typesig_scc(), label(), - dialyzer_callgraph:callgraph(), + dialyzer_callgraph:callgraph(), dialyzer_plt:plt(), dict()) -> dict(). analyze_scc(SCC, NextLabel, CallGraph, Plt, PropTypes) -> @@ -202,7 +202,7 @@ traverse(Tree, DefinedVars, State) -> {State1, OpType} = traverse(Op, DefinedVars, State0), {State2, FunType} = state__get_fun_prototype(OpType, Arity, State1), State3 = state__store_conj(FunType, eq, OpType, State2), - State4 = state__store_conj(mk_var(Tree), sub, t_fun_range(FunType), + State4 = state__store_conj(mk_var(Tree), sub, t_fun_range(FunType), State3), State5 = state__store_conj_lists(ArgTypes, sub, t_fun_args(FunType), State4), @@ -216,7 +216,7 @@ traverse(Tree, DefinedVars, State) -> end end; binary -> - {State1, SegTypes} = traverse_list(cerl:binary_segments(Tree), + {State1, SegTypes} = traverse_list(cerl:binary_segments(Tree), DefinedVars, State), Type = mk_fun_var(fun(Map) -> TmpSegTypes = lookup_type_list(SegTypes, Map), @@ -227,7 +227,7 @@ traverse(Tree, DefinedVars, State) -> Size = cerl:bitstr_size(Tree), UnitVal = cerl:int_val(cerl:bitstr_unit(Tree)), Val = cerl:bitstr_val(Tree), - {State1, [SizeType, ValType]} = + {State1, [SizeType, ValType]} = traverse_list([Size, Val], DefinedVars, State), {State2, TypeConstr} = case cerl:bitstr_bitsize(Tree) of @@ -250,7 +250,7 @@ traverse(Tree, DefinedVars, State) -> case state__is_in_match(State1) of true -> Flags = cerl:concrete(cerl:bitstr_flags(Tree)), - mk_fun_var(bitstr_val_constr(SizeType, UnitVal, Flags), + mk_fun_var(bitstr_val_constr(SizeType, UnitVal, Flags), [SizeType]); false -> t_integer() end; @@ -282,7 +282,7 @@ traverse(Tree, DefinedVars, State) -> false -> ConsVar = mk_var(Tree), ConsType = mk_fun_var(fun(Map) -> - t_cons(lookup_type(HdVar, Map), + t_cons(lookup_type(HdVar, Map), lookup_type(TlVar, Map)) end, [HdVar, TlVar]), HdType = mk_fun_var(fun(Map) -> @@ -299,8 +299,8 @@ traverse(Tree, DefinedVars, State) -> true -> t_cons_tl(Cons) end end, [ConsVar]), - State2 = state__store_conj_lists([HdVar, TlVar, ConsVar], sub, - [HdType, TlType, ConsType], + State2 = state__store_conj_lists([HdVar, TlVar, ConsVar], sub, + [HdType, TlType, ConsType], State1), {State2, ConsVar} end; @@ -314,14 +314,14 @@ traverse(Tree, DefinedVars, State) -> error -> t_fun(length(Vars), t_none()); {ok, Dom} -> t_fun(Dom, t_none()) end, - State2 = + State2 = try State1 = case state__add_prop_constrs(Tree, State0) of not_called -> State0; PropState -> PropState end, {BodyState, BodyVar} = traverse(Body, DefinedVars1, State1), - state__store_conj(mk_var(Tree), eq, + state__store_conj(mk_var(Tree), eq, t_fun(mk_var_list(Vars), BodyVar), BodyState) catch throw:error -> @@ -340,7 +340,7 @@ traverse(Tree, DefinedVars, State) -> Arg = cerl:let_arg(Tree), Body = cerl:let_body(Tree), {State1, ArgVars} = traverse(Arg, DefinedVars, State), - State2 = state__store_conj(t_product(mk_var_list(Vars)), eq, + State2 = state__store_conj(t_product(mk_var_list(Vars)), eq, ArgVars, State1), DefinedVars1 = add_def_list(Vars, DefinedVars), traverse(Body, DefinedVars1, State2); @@ -353,12 +353,12 @@ traverse(Tree, DefinedVars, State) -> DefinedVars1 = add_def_list(Vars, DefinedVars), {State2, _} = traverse_list(Funs, DefinedVars1, State1), traverse(Body, DefinedVars1, State2); - literal -> + literal -> %% This is needed for finding records case cerl:unfold_literal(Tree) of - Tree -> + Tree -> Type = t_from_term(cerl:concrete(Tree)), - NewType = + NewType = case erl_types:t_opaque_match_atom(Type, State#state.opaques) of [Opaque] -> Opaque; _ -> Type @@ -370,7 +370,7 @@ traverse(Tree, DefinedVars, State) -> Defs = cerl:module_defs(Tree), Funs = [Fun || {_Var, Fun} <- Defs], Vars = [Var || {Var, _Fun} <- Defs], - DefinedVars1 = add_def_list(Vars, DefinedVars), + DefinedVars1 = add_def_list(Vars, DefinedVars), State1 = state__store_funs(Vars, Funs, State), FoldFun = fun(Fun, AccState) -> {S, _} = traverse(Fun, DefinedVars1, @@ -388,7 +388,7 @@ traverse(Tree, DefinedVars, State) -> 'receive' -> Clauses = filter_match_fail(cerl:receive_clauses(Tree)), Timeout = cerl:receive_timeout(Tree), - case (cerl:is_c_atom(Timeout) andalso + case (cerl:is_c_atom(Timeout) andalso (cerl:atom_val(Timeout) =:= infinity)) of true -> handle_clauses(Clauses, mk_var(Tree), [], DefinedVars, State); @@ -421,7 +421,7 @@ traverse(Tree, DefinedVars, State) -> case t_has_var(Var) of true -> {AccState1, NewVar} = state__mk_var(AccState), - {NewVar, + {NewVar, state__store_conj(Var, eq, NewVar, AccState1)}; false -> {Var, AccState} @@ -431,7 +431,7 @@ traverse(Tree, DefinedVars, State) -> {TmpState, t_tuple(NewEvars)} end, case Elements of - [Tag|Fields] -> + [Tag|Fields] -> case cerl:is_c_atom(Tag) of true -> %% Check if an opaque term is constructed. @@ -534,7 +534,7 @@ handle_try(Tree, DefinedVars, State) -> Handler = cerl:try_handler(Tree), State1 = state__new_constraint_context(State), {ArgBodyState, BodyVar} = - try + try {State2, ArgVar} = traverse(Arg, DefinedVars, State1), DefinedVars1 = add_def_list(Vars, DefinedVars), {State3, BodyVar1} = traverse(Body, DefinedVars1, State2), @@ -542,17 +542,17 @@ handle_try(Tree, DefinedVars, State) -> State3), {State4, BodyVar1} catch - throw:error -> + throw:error -> {State1, t_none()} end, State6 = state__new_constraint_context(ArgBodyState), {HandlerState, HandlerVar} = try - DefinedVars2 = add_def_list([X || X <- EVars, cerl:is_c_var(X)], + DefinedVars2 = add_def_list([X || X <- EVars, cerl:is_c_var(X)], DefinedVars), traverse(Handler, DefinedVars2, State6) catch - throw:error -> + throw:error -> {State6, t_none()} end, ArgBodyCs = state__cs(ArgBodyState), @@ -561,7 +561,7 @@ handle_try(Tree, DefinedVars, State) -> OldCs = state__cs(State), case state__is_in_guard(State) of true -> - Conj1 = mk_conj_constraint_list([ArgBodyCs, + Conj1 = mk_conj_constraint_list([ArgBodyCs, mk_constraint(BodyVar, eq, TreeVar)]), Disj = mk_disj_constraint_list([Conj1, mk_constraint(HandlerVar, eq, TreeVar)]), @@ -573,10 +573,10 @@ handle_try(Tree, DefinedVars, State) -> {NewCs, ReturnVar} = case {t_is_none(BodyVar), t_is_none(HandlerVar)} of {false, false} -> - Conj1 = + Conj1 = mk_conj_constraint_list([ArgBodyCs, mk_constraint(TreeVar, eq, BodyVar)]), - Conj2 = + Conj2 = mk_conj_constraint_list([HandlerCs, mk_constraint(TreeVar, eq, HandlerVar)]), Disj = mk_disj_constraint_list([Conj1, Conj2]), @@ -603,7 +603,7 @@ handle_try(Tree, DefinedVars, State) -> %% Call %% -handle_call(Call, DefinedVars, State) -> +handle_call(Call, DefinedVars, State) -> Args = cerl:call_args(Call), Mod = cerl:call_module(Call), Fun = cerl:call_name(Call), @@ -618,7 +618,7 @@ handle_call(Call, DefinedVars, State) -> case state__lookup_rec_var_in_scope(MFA, State) of error -> case get_bif_constr(MFA, Dst, ArgVars, State1) of - none -> + none -> {get_plt_constr(MFA, Dst, ArgVars, State1), Dst}; C -> {state__store_conj(C, State1), Dst} @@ -647,7 +647,7 @@ get_plt_constr(MFA, Dst, ArgVars, State) -> case PltRes of none -> State; {value, {PltRetType, PltArgTypes}} -> - state__store_conj_lists([Dst|ArgVars], sub, + state__store_conj_lists([Dst|ArgVars], sub, [PltRetType|PltArgTypes], State) end; {value, #contract{args = GenArgs} = C} -> @@ -655,7 +655,7 @@ get_plt_constr(MFA, Dst, ArgVars, State) -> case PltRes of none -> {mk_fun_var(fun(Map) -> - ArgTypes = lookup_type_list(ArgVars, Map), + ArgTypes = lookup_type_list(ArgVars, Map), dialyzer_contracts:get_contract_return(C, ArgTypes) end, ArgVars), GenArgs}; {value, {PltRetType, PltArgTypes}} -> @@ -692,7 +692,7 @@ filter_match_fail([Clause] = Cls) -> filter_match_fail([H|T]) -> [H|filter_match_fail(T)]; filter_match_fail([]) -> - %% This can actually happen, for example in + %% This can actually happen, for example in %% receive after 1 -> ok end []. @@ -714,16 +714,16 @@ handle_clauses(Clauses, TopVar, Arg, Action, DefinedVars, State) -> if length(Clauses) > ?MAX_NOF_CLAUSES -> overflow; true -> [] end, - {State1, CList} = handle_clauses_1(Clauses, TopVar, Arg, DefinedVars, + {State1, CList} = handle_clauses_1(Clauses, TopVar, Arg, DefinedVars, State, SubtrTypeList, []), {NewCs, NewState} = case Action of - none -> + none -> if CList =:= [] -> throw(error); true -> {CList, State1} end; - _ -> - try + _ -> + try {State2, ActionVar} = traverse(Action, DefinedVars, State1), TmpC = mk_constraint(TopVar, eq, ActionVar), ActionCs = mk_conj_constraint_list([state__cs(State2),TmpC]), @@ -740,7 +740,7 @@ handle_clauses(Clauses, TopVar, Arg, Action, DefinedVars, State) -> FinalState = state__new_constraint_context(NewState), {state__store_conj_list([OldCs, NewCList], FinalState), TopVar}. -handle_clauses_1([Clause|Tail], TopVar, Arg, DefinedVars, +handle_clauses_1([Clause|Tail], TopVar, Arg, DefinedVars, State, SubtrTypes, Acc) -> State0 = state__new_constraint_context(State), Pats = cerl:clause_pats(Clause), @@ -749,22 +749,22 @@ handle_clauses_1([Clause|Tail], TopVar, Arg, DefinedVars, NewSubtrTypes = case SubtrTypes =:= overflow of true -> overflow; - false -> + false -> ordsets:add_element(get_safe_underapprox(Pats, Guard), SubtrTypes) end, - try + try DefinedVars1 = add_def_from_tree_list(Pats, DefinedVars), State1 = state__set_in_match(State0, true), {State2, PatVars} = traverse_list(Pats, DefinedVars1, State1), State3 = case Arg =:= [] of true -> State2; - false -> + false -> S = state__store_conj(Arg, eq, t_product(PatVars), State2), case SubtrTypes =:= overflow of true -> S; false -> - SubtrPatVar = mk_fun_var(fun(Map) -> + SubtrPatVar = mk_fun_var(fun(Map) -> TmpType = lookup_type(Arg, Map), t_subtract_list(TmpType, SubtrTypes) end, [Arg]), @@ -772,15 +772,15 @@ handle_clauses_1([Clause|Tail], TopVar, Arg, DefinedVars, end end, State4 = handle_guard(Guard, DefinedVars1, State3), - {State5, BodyVar} = traverse(Body, DefinedVars1, + {State5, BodyVar} = traverse(Body, DefinedVars1, state__set_in_match(State4, false)), State6 = state__store_conj(TopVar, eq, BodyVar, State5), Cs = state__cs(State6), - handle_clauses_1(Tail, TopVar, Arg, DefinedVars, State6, + handle_clauses_1(Tail, TopVar, Arg, DefinedVars, State6, NewSubtrTypes, [Cs|Acc]) catch - throw:error -> - handle_clauses_1(Tail, TopVar, Arg, DefinedVars, + throw:error -> + handle_clauses_1(Tail, TopVar, Arg, DefinedVars, State, NewSubtrTypes, Acc) end; handle_clauses_1([], _TopVar, _Arg, _DefinedVars, State, _SubtrType, Acc) -> @@ -792,7 +792,7 @@ get_safe_underapprox(Pats, Guard) -> try Map1 = cerl_trees:fold(fun(X, Acc) -> case cerl:is_c_var(X) of - true -> + true -> dict:store(cerl_trees:get_label(X), t_any(), Acc); false -> Acc @@ -804,8 +804,8 @@ get_safe_underapprox(Pats, Guard) -> false -> case cerl:is_c_var(Guard) of false -> Map2; - true -> - dict:store(cerl_trees:get_label(Guard), + true -> + dict:store(cerl_trees:get_label(Guard), t_from_term(true), Map2) end end, @@ -819,8 +819,8 @@ get_underapprox_from_guard(Tree, Map) -> True = t_from_term(true), case cerl:type(Tree) of call -> - case {cerl:concrete(cerl:call_module(Tree)), - cerl:concrete(cerl:call_name(Tree)), + case {cerl:concrete(cerl:call_module(Tree)), + cerl:concrete(cerl:call_name(Tree)), length(cerl:call_args(Tree))} of {erlang, is_function, 2} -> [Fun, Arity] = cerl:call_args(Tree), @@ -856,15 +856,15 @@ get_underapprox_from_guard(Tree, Map) -> {erlang, '==', 2} -> throw(dont_know); {erlang, 'and', 2} -> [Arg1, Arg2] = cerl:call_args(Tree), - case ((cerl:is_c_var(Arg1) orelse cerl:is_literal(Arg1)) + case ((cerl:is_c_var(Arg1) orelse cerl:is_literal(Arg1)) andalso (cerl:is_c_var(Arg2) orelse cerl:is_literal(Arg2))) of true -> {Arg1Type, _} = get_underapprox_from_guard(Arg1, Map), {Arg2Type, _} = get_underapprox_from_guard(Arg2, Map), - case (t_is_equal(True, Arg1Type) andalso + case (t_is_equal(True, Arg1Type) andalso t_is_equal(True, Arg2Type)) of - true -> {True, Map}; + true -> {True, Map}; false -> throw(dont_know) end; false -> @@ -876,7 +876,7 @@ get_underapprox_from_guard(Tree, Map) -> end end; var -> - Type = + Type = case dict:find(cerl_trees:get_label(Tree), Map) of error -> throw(dont_know); {ok, T} -> T @@ -931,7 +931,7 @@ bitstr_constr(SizeType, UnitVal) -> MinSize = erl_types:number_min(TmpSizeType), t_bitstr(UnitVal, MinSize * UnitVal) end; - false -> + false -> t_bitstr(UnitVal, 0) end end. @@ -975,9 +975,9 @@ get_safe_underapprox_1([Pat|Left], Acc, Map) -> end; binary -> %% TODO: Can maybe do something here - throw(dont_know); + throw(dont_know); cons -> - {[Hd, Tl], Map1} = + {[Hd, Tl], Map1} = get_safe_underapprox_1([cerl:cons_hd(Pat), cerl:cons_tl(Pat)], [], Map), case t_is_any(Tl) of true -> get_safe_underapprox_1(Left, [t_nonempty_list(Hd)|Acc], Map1); @@ -1020,7 +1020,7 @@ get_safe_underapprox_1([], Acc, Map) -> %% Guards %% -handle_guard(Guard, DefinedVars, State) -> +handle_guard(Guard, DefinedVars, State) -> True = t_from_term(true), State1 = state__set_in_guard(State, true), State2 = state__new_constraint_context(State1), @@ -1039,7 +1039,7 @@ handle_guard(Guard, DefinedVars, State) -> %% %%============================================================================= -get_bif_constr({erlang, Op, 2}, Dst, Args = [Arg1, Arg2], _State) +get_bif_constr({erlang, Op, 2}, Dst, Args = [Arg1, Arg2], _State) when Op =:= '+'; Op =:= '-'; Op =:= '*' -> ReturnType = mk_fun_var(fun(Map) -> TmpArgTypes = lookup_type_list(Args, Map), @@ -1047,14 +1047,14 @@ get_bif_constr({erlang, Op, 2}, Dst, Args = [Arg1, Arg2], _State) end, Args), ArgFun = fun(A, Pos) -> - F = + F = fun(Map) -> DstType = lookup_type(Dst, Map), AType = lookup_type(A, Map), case t_is_integer(DstType) of true -> case t_is_integer(AType) of - true -> + true -> eval_inv_arith(Op, Pos, DstType, AType); false -> %% This must be temporary. @@ -1062,7 +1062,7 @@ get_bif_constr({erlang, Op, 2}, Dst, Args = [Arg1, Arg2], _State) end; false -> case t_is_float(DstType) of - true -> + true -> case t_is_integer(AType) of true -> t_float(); false -> t_number() @@ -1079,9 +1079,9 @@ get_bif_constr({erlang, Op, 2}, Dst, Args = [Arg1, Arg2], _State) mk_conj_constraint_list([mk_constraint(Dst, sub, ReturnType), mk_constraint(Arg1, sub, Arg1FunVar), mk_constraint(Arg2, sub, Arg2FunVar)]); -get_bif_constr({erlang, Op, 2}, Dst, [Arg1, Arg2] = Args, _State) +get_bif_constr({erlang, Op, 2}, Dst, [Arg1, Arg2] = Args, _State) when Op =:= '<'; Op =:= '=<'; Op =:= '>'; Op =:= '>=' -> - ArgFun = + ArgFun = fun(LocalArg1, LocalArg2, LocalOp) -> fun(Map) -> DstType = lookup_type(Dst, Map), @@ -1098,19 +1098,19 @@ get_bif_constr({erlang, Op, 2}, Dst, [Arg1, Arg2] = Args, _State) Max2 = erl_types:number_max(Arg2Type), Min2 = erl_types:number_min(Arg2Type), case LocalOp of - '=<' -> + '=<' -> if IsTrue -> t_from_range(Min1, Max2); IsFalse -> t_from_range(range_inc(Min2), Max1) end; - '<' -> + '<' -> if IsTrue -> t_from_range(Min1, range_dec(Max2)); IsFalse -> t_from_range(Min2, Max1) end; - '>=' -> + '>=' -> if IsTrue -> t_from_range(Min2, Max1); IsFalse -> t_from_range(Min1, range_dec(Max2)) end; - '>' -> + '>' -> if IsTrue -> t_from_range(range_inc(Min2), Max1); IsFalse -> t_from_range(Min1, Max2) end @@ -1131,7 +1131,7 @@ get_bif_constr({erlang, Op, 2}, Dst, [Arg1, Arg2] = Args, _State) DstArgs = [Dst, Arg1, Arg2], Arg1Var = mk_fun_var(Arg1Fun, DstArgs), Arg2Var = mk_fun_var(Arg2Fun, DstArgs), - DstVar = mk_fun_var(fun(Map) -> + DstVar = mk_fun_var(fun(Map) -> TmpArgTypes = lookup_type_list(Args, Map), erl_bif_types:type(erlang, Op, 2, TmpArgTypes) end, Args), @@ -1143,9 +1143,9 @@ get_bif_constr({erlang, '++', 2}, Dst, [Hd, Tl] = Args, _State) -> DstType = lookup_type(Dst, Map), case t_is_cons(DstType) of true -> t_list(t_cons_hd(DstType)); - false -> + false -> case t_is_list(DstType) of - true -> + true -> case t_is_nil(DstType) of true -> DstType; false -> t_list(t_list_elements(DstType)) @@ -1160,7 +1160,7 @@ get_bif_constr({erlang, '++', 2}, Dst, [Hd, Tl] = Args, _State) -> true -> t_sup(t_cons_tl(DstType), DstType); false -> case t_is_list(DstType) of - true -> + true -> case t_is_nil(DstType) of true -> DstType; false -> t_list(t_list_elements(DstType)) @@ -1170,10 +1170,10 @@ get_bif_constr({erlang, '++', 2}, Dst, [Hd, Tl] = Args, _State) -> end end, DstL = [Dst], - HdVar = mk_fun_var(HdFun, DstL), + HdVar = mk_fun_var(HdFun, DstL), TlVar = mk_fun_var(TlFun, DstL), ArgTypes = erl_bif_types:arg_types(erlang, '++', 2), - ReturnType = mk_fun_var(fun(Map) -> + ReturnType = mk_fun_var(fun(Map) -> TmpArgTypes = lookup_type_list(Args, Map), erl_bif_types:type(erlang, '++', 2, TmpArgTypes) end, Args), @@ -1198,7 +1198,7 @@ get_bif_constr({erlang, is_function, 2}, Dst, [Fun, Arity], _State) -> ArgFun = fun(Map) -> DstType = lookup_type(Dst, Map), case t_is_atom(true, DstType) of - true -> + true -> ArityType = lookup_type(Arity, Map), case t_number_vals(ArityType) of unknown -> t_fun(); @@ -1231,7 +1231,7 @@ get_bif_constr({erlang, is_record, 2}, Dst, [Var, Tag] = Args, _State) -> end end, ArgV = mk_fun_var(ArgFun, [Dst]), - DstFun = fun(Map) -> + DstFun = fun(Map) -> TmpArgTypes = lookup_type_list(Args, Map), erl_bif_types:type(erlang, is_record, 2, TmpArgTypes) end, @@ -1241,7 +1241,7 @@ get_bif_constr({erlang, is_record, 2}, Dst, [Var, Tag] = Args, _State) -> mk_constraint(Var, sub, ArgV)]); get_bif_constr({erlang, is_record, 3}, Dst, [Var, Tag, Arity] = Args, State) -> %% TODO: Revise this to make it precise for Tag and Arity. - ArgFun = + ArgFun = fun(Map) -> case t_is_atom(true, lookup_type(Dst, Map)) of true -> @@ -1257,14 +1257,14 @@ get_bif_constr({erlang, is_record, 3}, Dst, [Var, Tag, Arity] = Args, State) -> GenRecord = t_tuple([TagType|AnyElems]), case t_atom_vals(TagType) of [TagVal] -> - case state__lookup_record(State, TagVal, + case state__lookup_record(State, TagVal, ArityVal - 1) of {ok, Type} -> AllOpaques = State#state.opaques, case t_opaque_match_record(Type, AllOpaques) of [Opaque] -> Opaque; _ -> Type - end; + end; error -> GenRecord end; _ -> GenRecord @@ -1279,9 +1279,9 @@ get_bif_constr({erlang, is_record, 3}, Dst, [Var, Tag, Arity] = Args, State) -> end end, ArgV = mk_fun_var(ArgFun, [Tag, Arity, Dst]), - DstFun = fun(Map) -> + DstFun = fun(Map) -> [TmpVar, TmpTag, TmpArity] = TmpArgTypes = lookup_type_list(Args, Map), - TmpArgTypes2 = + TmpArgTypes2 = case lists:member(TmpVar, State#state.opaques) of true -> case t_is_integer(TmpArity) of @@ -1293,7 +1293,7 @@ get_bif_constr({erlang, is_record, 3}, Dst, [Var, Tag, Arity] = Args, State) -> case t_atom_vals(TmpTag) of [TmpTagVal] -> case state__lookup_record(State, TmpTagVal, TmpArityVal - 1) of - {ok, TmpType} -> + {ok, TmpType} -> case t_is_none(t_inf(TmpType, TmpVar, opaque)) of true -> TmpArgTypes; false -> [TmpType, TmpTag, TmpArity] @@ -1312,7 +1312,7 @@ get_bif_constr({erlang, is_record, 3}, Dst, [Var, Tag, Arity] = Args, State) -> end, erl_bif_types:type(erlang, is_record, 3, TmpArgTypes2) end, - DstV = mk_fun_var(DstFun, Args), + DstV = mk_fun_var(DstFun, Args), mk_conj_constraint_list([mk_constraint(Dst, sub, DstV), mk_constraint(Arity, sub, t_integer()), mk_constraint(Tag, sub, t_atom()), @@ -1334,7 +1334,7 @@ get_bif_constr({erlang, 'and', 2}, Dst, [Arg1, Arg2] = Args, _State) -> true -> False; false -> t_boolean() end; - false -> + false -> t_boolean() end end @@ -1349,7 +1349,7 @@ get_bif_constr({erlang, 'and', 2}, Dst, [Arg1, Arg2] = Args, _State) -> case t_is_atom(false, Arg2Type) of true -> False; false -> - case (t_is_atom(true, Arg1Type) + case (t_is_atom(true, Arg1Type) andalso t_is_atom(true, Arg2Type)) of true -> True; false -> t_boolean() @@ -1378,7 +1378,7 @@ get_bif_constr({erlang, 'or', 2}, Dst, [Arg1, Arg2] = Args, _State) -> true -> True; false -> t_boolean() end; - false -> + false -> t_boolean() end end @@ -1393,7 +1393,7 @@ get_bif_constr({erlang, 'or', 2}, Dst, [Arg1, Arg2] = Args, _State) -> case t_is_atom(true, Arg2Type) of true -> True; false -> - case (t_is_atom(false, Arg1Type) + case (t_is_atom(false, Arg1Type) andalso t_is_atom(false, Arg2Type)) of true -> False; false -> t_boolean() @@ -1414,7 +1414,7 @@ get_bif_constr({erlang, 'or', 2}, Dst, [Arg1, Arg2] = Args, _State) -> get_bif_constr({erlang, 'not', 1}, Dst, [Arg] = Args, _State) -> True = t_from_term(true), False = t_from_term(false), - Fun = fun(Var) -> + Fun = fun(Var) -> fun(Map) -> Type = lookup_type(Var, Map), case t_is_atom(true, Type) of @@ -1439,7 +1439,7 @@ get_bif_constr({erlang, '=:=', 2}, Dst, [Arg1, Arg2] = Args, _State) -> OtherVarType = lookup_type(OtherVar, Map), case t_is_atom(true, DstType) of true -> OtherVarType; - false -> + false -> case t_is_atom(false, DstType) of true -> case is_singleton_type(OtherVarType) of @@ -1492,7 +1492,7 @@ get_bif_constr({erlang, '==', 2}, Dst, [Arg1, Arg2] = Args, _State) -> true -> case t_is_number(VarType) of true -> t_number(); - false -> + false -> case t_is_atom(VarType) of true -> VarType; false -> t_any() @@ -1511,7 +1511,8 @@ get_bif_constr({erlang, '==', 2}, Dst, [Arg1, Arg2] = Args, _State) -> mk_conj_constraint_list([mk_constraint(Dst, sub, DstV), mk_constraint(Arg1, sub, ArgV1), mk_constraint(Arg2, sub, ArgV2)]); -get_bif_constr({erlang, element, 2} = _BIF, Dst, Args, State) -> +get_bif_constr({erlang, element, 2} = _BIF, Dst, Args, + #state{cs = Constrs} = State) -> GenType = erl_bif_types:type(erlang, element, 2), case t_is_none(GenType) of true -> ?debug("Bif: ~w failed\n", [_BIF]), throw(error); @@ -1525,9 +1526,14 @@ get_bif_constr({erlang, element, 2} = _BIF, Dst, Args, State) -> erl_bif_types:type(erlang, element, 2, ATs2) end, ReturnType = mk_fun_var(Fun, Args), - ArgTypes = erl_bif_types:arg_types(erlang, element, 2), + ArgTypes = erl_bif_types:arg_types(erlang, element, 2), Cs = mk_constraints(Args, sub, ArgTypes), - mk_conj_constraint_list([mk_constraint(Dst, sub, ReturnType)|Cs]) + NewCs = + case find_element(Args, Constrs) of + 'unknown' -> Cs; + Elem -> [mk_constraint(Dst, eq, Elem)|Cs] + end, + mk_conj_constraint_list([mk_constraint(Dst, sub, ReturnType)|NewCs]) end; get_bif_constr({M, F, A} = _BIF, Dst, Args, State) -> GenType = erl_bif_types:type(M, F, A), @@ -1541,7 +1547,7 @@ get_bif_constr({M, F, A} = _BIF, Dst, Args, State) -> false -> T end end, - ReturnType = mk_fun_var(fun(Map) -> + ReturnType = mk_fun_var(fun(Map) -> TmpArgTypes0 = lookup_type_list(Args, Map), TmpArgTypes = [UnopaqueFun(T) || T<- TmpArgTypes0], erl_bif_types:type(M, F, A, TmpArgTypes) @@ -1561,12 +1567,12 @@ get_bif_constr({M, F, A} = _BIF, Dst, Args, State) -> end end. -eval_inv_arith('+', _Pos, Dst, Arg) -> +eval_inv_arith('+', _Pos, Dst, Arg) -> erl_bif_types:type(erlang, '-', 2, [Dst, Arg]); -eval_inv_arith('*', _Pos, Dst, Arg) -> +eval_inv_arith('*', _Pos, Dst, Arg) -> case t_number_vals(Arg) of [0] -> t_integer(); - _ -> + _ -> TmpRet = erl_bif_types:type(erlang, 'div', 2, [Dst, Arg]), Zero = t_from_term(0), %% If 0 is not part of the result, it cannot be part of the argument. @@ -1575,9 +1581,9 @@ eval_inv_arith('*', _Pos, Dst, Arg) -> true -> TmpRet end end; -eval_inv_arith('-', 1, Dst, Arg) -> +eval_inv_arith('-', 1, Dst, Arg) -> erl_bif_types:type(erlang, '-', 2, [Arg, Dst]); -eval_inv_arith('-', 2, Dst, Arg) -> +eval_inv_arith('-', 2, Dst, Arg) -> erl_bif_types:type(erlang, '+', 2, [Arg, Dst]). range_inc(neg_inf) -> neg_inf; @@ -1614,7 +1620,7 @@ get_bif_test_constr(Dst, Arg, Type, State) -> end; false -> t_from_term(false) end; - false -> + false -> case t_is_subtype(ArgType, Type) of true -> t_from_term(true); false -> t_boolean() @@ -1632,11 +1638,11 @@ get_bif_test_constr(Dst, Arg, Type, State) -> %%============================================================================= solve([Fun], State) -> - ?debug("============ Analyzing Fun: ~w ===========\n", + ?debug("============ Analyzing Fun: ~w ===========\n", [debug_lookup_name(Fun)]), solve_fun(Fun, dict:new(), State); solve([_|_] = SCC, State) -> - ?debug("============ Analyzing SCC: ~w ===========\n", + ?debug("============ Analyzing SCC: ~w ===========\n", [[debug_lookup_name(F) || F <- SCC]]), solve_scc(SCC, dict:new(), State, false). @@ -1655,7 +1661,7 @@ solve_fun(Fun, FunMap, State) -> solve_scc(SCC, Map, State, TryingUnit) -> State1 = state__mark_as_non_self_rec(SCC, State), - Vars0 = [{Fun, state__get_rec_var(Fun, State)} || Fun <- SCC], + Vars0 = [{Fun, state__get_rec_var(Fun, State)} || Fun <- SCC], Vars = [Var || {_, {ok, Var}} <- Vars0], Funs = [Fun || {Fun, {ok, _}} <- Vars0], Types = unsafe_lookup_type_list(Funs, Map), @@ -1682,7 +1688,7 @@ solve_scc(SCC, Map, State, TryingUnit) -> false -> Map2 end; - false -> + false -> ?debug("SCC ~w did not reach fixpoint\n", [SCC]), solve_scc(SCC, Map2, State, TryingUnit) end. @@ -1704,29 +1710,29 @@ scc_fold_fun(F, FunMap, State) -> format_type(NewType)]), NewFunMap. -solve_ref_or_list(#constraint_ref{id = Id, deps = Deps}, +solve_ref_or_list(#constraint_ref{id = Id, deps = Deps}, Map, MapDict, State) -> - {OldLocalMap, Check} = + {OldLocalMap, Check} = case dict:find(Id, MapDict) of error -> {dict:new(), false}; {ok, M} -> {M, true} - end, + end, ?debug("Checking ref to fun: ~w\n", [debug_lookup_name(Id)]), CheckDeps = ordsets:del_element(t_var_name(Id), Deps), case Check andalso maps_are_equal(OldLocalMap, Map, CheckDeps) of - true -> + true -> ?debug("Equal\n", []), {ok, MapDict, Map}; false -> ?debug("Not equal. Solving\n", []), Cs = state__get_cs(Id, State), - Res = + Res = case state__is_self_rec(Id, State) of true -> solve_self_recursive(Cs, Map, MapDict, Id, t_none(), State); false -> solve_ref_or_list(Cs, Map, MapDict, State) end, case Res of - {error, NewMapDict} -> + {error, NewMapDict} -> ?debug("Error solving for function ~p\n", [debug_lookup_name(Id)]), Arity = state__fun_arity(Id, State), FunType = @@ -1755,17 +1761,17 @@ solve_ref_or_list(#constraint_ref{id = Id, deps = Deps}, end; solve_ref_or_list(#constraint_list{type=Type, list = Cs, deps = Deps, id = Id}, Map, MapDict, State) -> - {OldLocalMap, Check} = + {OldLocalMap, Check} = case dict:find(Id, MapDict) of error -> {dict:new(), false}; {ok, M} -> {M, true} end, ?debug("Checking ref to list: ~w\n", [Id]), case Check andalso maps_are_equal(OldLocalMap, Map, Deps) of - true -> + true -> ?debug("~w equal ~w\n", [Type, Id]), {ok, MapDict, Map}; - false -> + false -> ?debug("~w not equal: ~w. Solving\n", [Type, Id]), solve_clist(Cs, Type, Id, Deps, MapDict, Map, State) end. @@ -1793,7 +1799,7 @@ solve_self_recursive(Cs, Map, MapDict, Id, RecType0, State) -> [[{X, format_type(Y)} || {X, Y} <- dict:to_list(NewMap)]]), NewRecType = unsafe_lookup_type(Id, NewMap), case t_is_equal(NewRecType, RecType0) of - true -> + true -> {ok, NewMapDict, enter_type(RecVar, NewRecType, NewMap)}; false -> solve_self_recursive(Cs, Map, MapDict, Id, NewRecType, State) @@ -1801,7 +1807,7 @@ solve_self_recursive(Cs, Map, MapDict, Id, RecType0, State) -> end. solve_clist(Cs, conj, Id, Deps, MapDict, Map, State) -> - case solve_cs(Cs, Map, MapDict, State) of + case solve_cs(Cs, Map, MapDict, State) of {error, _} = Error -> Error; {ok, NewMapDict, NewMap} = Ret -> case Cs of @@ -1821,12 +1827,12 @@ solve_clist(Cs, disj, Id, _Deps, MapDict, Map, State) -> {ok, NewDict, NewMap} -> {{ok, NewMap}, NewDict}; {error, _NewDict} = Error -> Error end - end, + end, {Maps, NewMapDict} = lists:mapfoldl(Fun, MapDict, Cs), case [X || {ok, X} <- Maps] of [] -> {error, NewMapDict}; - MapList -> - NewMap = join_maps(MapList), + MapList -> + NewMap = join_maps(MapList), {ok, dict:store(Id, NewMap, NewMapDict), NewMap} end. @@ -1844,13 +1850,13 @@ solve_cs([#constraint{} = C|Tail], Map, MapDict, State) -> case solve_one_c(C, Map, State#state.opaques) of error -> ?debug("+++++++++++\nFailed: ~s :: ~s ~w ~s :: ~s\n+++++++++++\n", - [format_type(C#constraint.lhs), + [format_type(C#constraint.lhs), format_type(lookup_type(C#constraint.lhs, Map)), C#constraint.op, - format_type(C#constraint.rhs), + format_type(C#constraint.rhs), format_type(lookup_type(C#constraint.rhs, Map))]), {error, MapDict}; - {ok, NewMap} -> + {ok, NewMap} -> solve_cs(Tail, NewMap, MapDict, State) end; solve_cs([], Map, MapDict, _State) -> @@ -1863,7 +1869,7 @@ solve_one_c(#constraint{lhs = Lhs, rhs = Rhs, op = Op}, Map, Opaques) -> ?debug("Solving: ~s :: ~s ~w ~s :: ~s\n\tInf: ~s\n", [format_type(Lhs), format_type(LhsType), Op, format_type(Rhs), format_type(RhsType), format_type(Inf)]), - case t_is_none(Inf) of + case t_is_none(Inf) of true -> error; false -> case Op of @@ -1887,8 +1893,8 @@ solve_subtype(Type, Inf, Map, Opaques) -> try t_unify(Type, Inf, Opaques) of {_, List} -> {ok, enter_type_list(List, Map)} catch - throw:{mismatch, _T1, _T2} -> - ?debug("Mismatch between ~s and ~s\n", + throw:{mismatch, _T1, _T2} -> + ?debug("Mismatch between ~s and ~s\n", [format_type(_T1), format_type(_T2)]), error end. @@ -1936,9 +1942,9 @@ maps_are_equal_1(Map1, Map2, [H|Tail]) -> T2 = lookup_type(H, Map2), case t_is_equal(T1, T2) of true -> maps_are_equal_1(Map1, Map2, Tail); - false -> + false -> ?debug("~w: ~s =/= ~s\n", [H, format_type(T1), format_type(T2)]), - false + false end; maps_are_equal_1(_Map1, _Map2, []) -> true. @@ -1953,7 +1959,7 @@ prune_keys(Map1, Map2, Deps) -> true -> Keys1 = dict:fetch_keys(Map1), case length(Keys1) > NofDeps of - true -> + true -> Set1 = lists:sort(Keys1), Set2 = lists:sort(dict:fetch_keys(Map2)), ordsets:intersection(ordsets:union(Set1, Set2), Deps); @@ -2035,7 +2041,7 @@ lookup_type(Key, Map) -> mk_var(Var) -> case cerl:is_literal(Var) of true -> Var; - false -> + false -> case cerl:is_c_values(Var) of true -> t_product(mk_var_no_lit_list(cerl:values_es(Var))); false -> t_var(cerl_trees:get_label(Var)) @@ -2076,10 +2082,10 @@ state__set_opaques(#state{records = RecDict} = State, {M, _F, _A}) -> state__lookup_record(#state{records = Records}, Tag, Arity) -> case erl_types:lookup_record(Tag, Arity, Records) of - {ok, Fields} -> + {ok, Fields} -> {ok, t_tuple([t_from_term(Tag)| [FieldType || {_FieldName, FieldType} <- Fields]])}; - error -> + error -> error end. @@ -2098,12 +2104,12 @@ state__is_in_guard(#state{in_guard = Bool}) -> state__get_fun_prototype(Op, Arity, State) -> case t_is_fun(Op) of true -> {State, Op}; - false -> + false -> {State1, [Ret|Args]} = state__mk_vars(Arity+1, State), Fun = t_fun(Args, Ret), {State1, Fun} end. - + state__lookup_rec_var_in_scope(MFA, #state{name_map = NameMap}) -> dict:find(MFA, NameMap). @@ -2115,11 +2121,11 @@ state__store_fun_arity(Tree, #state{fun_arities = Map} = State) -> state__fun_arity(Id, #state{fun_arities = Map}) -> dict:fetch(Id, Map). -state__lookup_undef_var(Tree, #state{callgraph = CG, plt = Plt}) -> +state__lookup_undef_var(Tree, #state{callgraph = CG, plt = Plt}) -> Label = cerl_trees:get_label(Tree), case dialyzer_callgraph:lookup_rec_var(Label, CG) of error -> error; - {ok, MFA} -> + {ok, MFA} -> case dialyzer_plt:lookup(Plt, MFA) of none -> error; {value, {RetType, ArgTypes}} -> {ok, t_fun(ArgTypes, RetType)} @@ -2179,7 +2185,7 @@ state__add_prop_constrs(Tree, #state{prop_types = PropTypes} = State) -> case erl_types:any_none(ArgTypes) of true -> not_called; false -> - ?debug("Adding propagated constr: ~s for function ~w\n", + ?debug("Adding propagated constr: ~s for function ~w\n", [format_type(FunType), debug_lookup_name(mk_var(Tree))]), FunVar = mk_var(Tree), state__store_conj(FunVar, sub, FunType, State) @@ -2225,7 +2231,7 @@ state__store_conj_lists_1([], _Op, [], State) -> state__mk_var(#state{next_label = NL} = State) -> {State#state{next_label = NL+1}, t_var(NL)}. - + state__mk_vars(N, #state{next_label = NL} = State) -> NewLabel = NL + N, Vars = [t_var(X) || X <- lists:seq(NL, NewLabel-1)], @@ -2235,7 +2241,7 @@ state__store_constrs(Id, Cs, #state{cmap = Dict} = State) -> NewDict = dict:store(Id, Cs, Dict), State#state{cmap = NewDict}. -state__get_cs(Var, #state{cmap = Dict}) -> +state__get_cs(Var, #state{cmap = Dict}) -> dict:fetch(Var, Dict). %% The functions here will not be treated as self recursive. @@ -2286,7 +2292,7 @@ mk_constraint(Lhs, Op, Rhs) -> %% This constraint is constant. Solve it immediately. case solve_one_c(C, dict:new(), []) of error -> throw(error); - _ -> + _ -> %% This is always true, keep it anyway for logistic reasons C end; @@ -2335,7 +2341,7 @@ mk_constraint_1(Lhs, eq, Rhs) when Lhs < Rhs -> mk_constraint_1(Lhs, eq, Rhs) -> #constraint{lhs = Rhs, op = eq, rhs = Lhs}; mk_constraint_1(Lhs, Op, Rhs) -> - #constraint{lhs = Lhs, op = Op, rhs = Rhs}. + #constraint{lhs = Lhs, op = Op, rhs = Rhs}. mk_constraints([Lhs|LhsTail], Op, [Rhs|RhsTail]) -> [mk_constraint(Lhs, Op, Rhs)|mk_constraints(LhsTail, Op, RhsTail)]; @@ -2350,7 +2356,7 @@ mk_constraint_list(Type, List) -> List2 = ordsets:filter(fun(X) -> get_deps(X) =/= [] end, List1), Deps = calculate_deps(List2), case Deps =:= [] of - true -> #constraint_list{type = conj, + true -> #constraint_list{type = conj, list = [mk_constraint(t_any(), eq, t_any())], deps = []}; false -> #constraint_list{type = Type, list = List2, deps = Deps} @@ -2372,11 +2378,11 @@ update_constraint_list(CL, List) -> %% We expand guard constraints into dijunctive normal form to gain %% precision in simple guards. However, because of the exponential %% growth of this expansion in the presens of disjunctions we can even -%% get into trouble while expanding. +%% get into trouble while expanding. %% %% To limit this we only expand when the number of disjunctions are %% below a certain limit. This limit is currently set based on the -%% behaviour of boolean 'or'. +%% behaviour of boolean 'or'. %% %% V1 = V2 or V3 %% @@ -2395,7 +2401,7 @@ update_constraint_list(CL, List) -> -define(DISJ_NORM_FORM_LIMIT, 28). mk_disj_norm_form(#constraint_list{} = CL) -> - try + try List1 = expand_to_conjunctions(CL), mk_disj_constraint_list(List1) catch @@ -2409,7 +2415,7 @@ expand_to_conjunctions(#constraint_list{type = conj, list = List}) -> true -> [mk_conj_constraint_list(List1)]; false -> case List2 of - [JustOneList] -> + [JustOneList] -> [mk_conj_constraint_list([L|List1]) || L <- JustOneList]; _ -> combine_conj_lists(List2, List1) @@ -2422,7 +2428,7 @@ expand_to_conjunctions(#constraint_list{type = disj, list = List}) -> List1 = [C || C <- List, is_simple_constraint(C)], %% Just an assert. [] = [C || #constraint{} = C <- List1], - Expanded = lists:flatten([expand_to_conjunctions(C) + Expanded = lists:flatten([expand_to_conjunctions(C) || #constraint_list{} = C <- List]), ReturnList = Expanded ++ List1, if length(ReturnList) > ?DISJ_NORM_FORM_LIMIT -> throw(too_many_disj); @@ -2467,7 +2473,7 @@ wrap_simple_constr(#constraint_list{} = C) -> C; wrap_simple_constr(#constraint_ref{} = C) -> C. enumerate_constraints(State) -> - Cs = [mk_constraint_ref(Id, get_deps(state__get_cs(Id, State))) + Cs = [mk_constraint_ref(Id, get_deps(state__get_cs(Id, State))) || Id <- state__scc(State)], {_, _, NewState} = enumerate_constraints(Cs, 0, [], State), NewState. @@ -2475,9 +2481,9 @@ enumerate_constraints(State) -> enumerate_constraints([#constraint_ref{id = Id} = C|Tail], N, Acc, State) -> Cs = state__get_cs(Id, State), {[NewCs], NewN, NewState1} = enumerate_constraints([Cs], N, [], State), - NewState2 = state__store_constrs(Id, NewCs, NewState1), + NewState2 = state__store_constrs(Id, NewCs, NewState1), enumerate_constraints(Tail, NewN+1, [C|Acc], NewState2); -enumerate_constraints([#constraint_list{type = conj, list = List} = C|Tail], +enumerate_constraints([#constraint_list{type = conj, list = List} = C|Tail], N, Acc, State) -> %% Separate the flat constraints from the deep ones to make a %% separate fixpoint interation over the flat ones for speed. @@ -2496,7 +2502,7 @@ enumerate_constraints([#constraint_list{type = conj, list = List} = C|Tail], end, NewAcc = [C#constraint_list{list = NewList, id = {list, N3}}|Acc], enumerate_constraints(Tail, N3+1, NewAcc, State2); -enumerate_constraints([#constraint_list{list = List, type = disj} = C|Tail], +enumerate_constraints([#constraint_list{list = List, type = disj} = C|Tail], N, Acc, State) -> {NewList, NewN, NewState} = enumerate_constraints(List, N, [], State), NewAcc = [C#constraint_list{list = NewList, id = {list, NewN}}|Acc], @@ -2515,7 +2521,7 @@ group_constraints_in_components(Cs, N) -> case find_dep_components(DepList, []) of [_] -> {Cs, N}; [_|_] = Components -> - ConstrComp = [[C || #constraint{deps = D} = C <- Cs, + ConstrComp = [[C || #constraint{deps = D} = C <- Cs, ordsets:is_subset(D, Comp)] || Comp <- Components], lists:mapfoldl(fun(CComp, TmpN) -> @@ -2545,7 +2551,7 @@ find_dep_components([], AccSet, Ungrouped) -> %% Put the fun ref constraints last in any conjunction since we need %% to separate the environment from the interior of the function. order_fun_constraints(State) -> - Cs = [mk_constraint_ref(Id, get_deps(state__get_cs(Id, State))) + Cs = [mk_constraint_ref(Id, get_deps(state__get_cs(Id, State))) || Id <- state__scc(State)], order_fun_constraints(Cs, State). @@ -2565,8 +2571,8 @@ order_fun_constraints([#constraint_list{list = List, type = Type} = C|Tail], case Type of conj -> order_fun_constraints(List, [], [], State); disj -> - FoldFun = fun(X, AccState) -> - {[NewX], NewAccState} = + FoldFun = fun(X, AccState) -> + {[NewX], NewAccState} = order_fun_constraints([X], [], [], AccState), {NewX, NewAccState} end, @@ -2588,7 +2594,7 @@ order_fun_constraints([], Funs, Acc, State) -> is_singleton_non_number_type(Type) -> case t_is_number(Type) of - true -> false; + true -> false; false -> is_singleton_type(Type) end. @@ -2613,6 +2619,41 @@ is_singleton_type(Type) -> end end. +find_element(Args, Cs) -> + [Pos, Tuple] = Args, + case erl_types:t_is_number(Pos) of + true -> + case erl_types:t_number_vals(Pos) of + 'unknown' -> 'unknown'; + [I] -> + case find_constraint(Tuple, Cs) of + 'unknown' -> 'unknown'; + #constraint{lhs = ExTuple} -> + case erl_types:t_is_tuple(ExTuple) of + true -> + Elems = erl_types:t_tuple_args(ExTuple), + Elem = lists:nth(I, Elems), + case erl_types:t_is_var(Elem) of + true -> Elem; + false -> 'unknown' + end; + false -> 'unknown' + end + end; + _ -> 'unknown' + end; + false -> 'unknown' + end. + +find_constraint(_Tuple, []) -> + 'unknown'; +find_constraint(Tuple, [#constraint{op = 'eq', rhs = Tuple} = C|_]) -> + C; +find_constraint(Tuple, [#constraint_list{list = List}|Cs]) -> + find_constraint(Tuple, List ++ Cs); +find_constraint(Tuple, [_|Cs]) -> + find_constraint(Tuple, Cs). + %% ============================================================================ %% %% Pretty printer and debug facilities. @@ -2638,7 +2679,7 @@ format_type(Type) -> -ifdef(DEBUG_NAME_MAP). debug_make_name_map(Vars, Funs) -> Map = get(dialyzer_typesig_map), - NewMap = + NewMap = if Map =:= undefined -> debug_make_name_map(Vars, Funs, dict:new()); true -> debug_make_name_map(Vars, Funs, Map) end, @@ -2676,15 +2717,15 @@ pp_constraints(Cs, State) -> io:nl(), Res. -pp_constraints([List|Tail], Separator, Level, MaxDepth, +pp_constraints([List|Tail], Separator, Level, MaxDepth, State) when is_list(List) -> pp_constraints(List++Tail, Separator, Level, MaxDepth, State); -pp_constraints([#constraint_ref{id = Id}|Left], Separator, +pp_constraints([#constraint_ref{id = Id}|Left], Separator, Level, MaxDepth, State) -> Cs = state__get_cs(Id, State), io:format("%Ref ~w%", [t_var_name(Id)]), pp_constraints([Cs|Left], Separator, Level, MaxDepth, State); -pp_constraints([#constraint{lhs = Lhs, op = Op, rhs = Rhs}], _Separator, +pp_constraints([#constraint{lhs = Lhs, op = Op, rhs = Rhs}], _Separator, Level, MaxDepth, _State) -> io:format("~s ~w ~s", [format_type(Lhs), Op, format_type(Rhs)]), erlang:max(Level, MaxDepth); @@ -2721,7 +2762,7 @@ pp_constrs_scc(_SCC, _State) -> constraints_to_dot_scc(SCC, State) -> io:format("SCC: ~p\n", [SCC]), - Name = lists:flatten([io_lib:format("'~w'", [debug_lookup_name(Fun)]) + Name = lists:flatten([io_lib:format("'~w'", [debug_lookup_name(Fun)]) || Fun <- SCC]), Cs = [state__get_cs(Fun, State) || Fun <- SCC], constraints_to_dot(Cs, Name, State). @@ -2737,22 +2778,22 @@ constraints_to_dot(Cs0, Name, State) -> constraints_to_nodes([{Name, #constraint_list{type = Type, list = List, id=Id}} |Left], N, Level, Graph, Opts, State) -> - N1 = N + length(List), + N1 = N + length(List), NewList = lists:zip(lists:seq(N, N1 - 1), List), Names = [SubName || {SubName, _C} <- NewList], Edges = [{Name, SubName} || SubName <- Names], - ThisNode = [{Name, Opt} || Opt <- [{label, + ThisNode = [{Name, Opt} || Opt <- [{label, lists:flatten(io_lib:format("~w", [Id]))}, {shape, get_shape(Type)}, {level, Level}]], - {NewGraph, NewOpts, N2} = constraints_to_nodes(NewList, N1, Level+1, - [Edges|Graph], + {NewGraph, NewOpts, N2} = constraints_to_nodes(NewList, N1, Level+1, + [Edges|Graph], [ThisNode|Opts], State), constraints_to_nodes(Left, N2, Level, NewGraph, NewOpts, State); constraints_to_nodes([{Name, #constraint{lhs = Lhs, op = Op, rhs = Rhs}}|Left], N, Level, Graph, Opts, State) -> - Label = lists:flatten(io_lib:format("~s ~w ~s", - [format_type(Lhs), Op, + Label = lists:flatten(io_lib:format("~s ~w ~s", + [format_type(Lhs), Op, format_type(Rhs)])), ThisNode = [{Name, Opt} || Opt <- [{label, Label}, {level, Level}]], NewOpts = [ThisNode|Opts], @@ -2761,20 +2802,20 @@ constraints_to_nodes([{Name, #constraint_ref{id = Id0}}|Left], N, Level, Graph, Opts, State) -> Id = debug_lookup_name(Id0), CList = state__get_cs(Id0, State), - ThisNode = [{Name, Opt} || Opt <- [{label, + ThisNode = [{Name, Opt} || Opt <- [{label, lists:flatten(io_lib:format("~w", [Id]))}, {shape, ellipse}, - {level, Level}]], - NewList = [{N, CList}], - {NewGraph, NewOpts, N1} = constraints_to_nodes(NewList, N + 1, Level + 1, + {level, Level}]], + NewList = [{N, CList}], + {NewGraph, NewOpts, N1} = constraints_to_nodes(NewList, N + 1, Level + 1, [{Name, N}|Graph], [ThisNode|Opts], State), constraints_to_nodes(Left, N1, Level, NewGraph, NewOpts, State); constraints_to_nodes([], N, _Level, Graph, Opts, _State) -> {lists:flatten(Graph), lists:flatten(Opts), N}. - + get_shape(conj) -> box; -get_shape(disj) -> diamond. +get_shape(disj) -> diamond. -else. constraints_to_dot_scc(_SCC, _State) -> diff --git a/lib/dialyzer/src/dialyzer_utils.erl b/lib/dialyzer/src/dialyzer_utils.erl index 6ea243c26f..a9da229061 100644 --- a/lib/dialyzer/src/dialyzer_utils.erl +++ b/lib/dialyzer/src/dialyzer_utils.erl @@ -21,7 +21,7 @@ %%%------------------------------------------------------------------- %%% File : dialyzer_utils.erl %%% Author : Tobias Lindahl <[email protected]> -%%% Description : +%%% Description : %%% %%% Created : 5 Dec 2006 by Tobias Lindahl <[email protected]> %%%------------------------------------------------------------------- @@ -42,6 +42,7 @@ merge_records/2, pp_hook/0, process_record_remote_types/1, + sets_filter/2, src_compiler_opts/0 ]). @@ -73,12 +74,11 @@ print_types1([{record, _Name} = Key|T], RecDict) -> -define(debug(D_), ok). -endif. -%% -%% Types that need to be imported from somewhere else -%% +%% ---------------------------------------------------------------------------- --type abstract_code() :: [tuple()]. %% XXX: refine --type comp_options() :: [atom()]. %% XXX: only a resticted set of options used +-type abstract_code() :: [tuple()]. %% XXX: import from somewhere +-type comp_options() :: [compile:option()]. +-type mod_or_fname() :: atom() | file:filename(). %% ============================================================================ %% @@ -86,13 +86,13 @@ print_types1([{record, _Name} = Key|T], RecDict) -> %% %% ============================================================================ --spec get_abstract_code_from_src(atom() | file:filename()) -> +-spec get_abstract_code_from_src(mod_or_fname()) -> {'ok', abstract_code()} | {'error', [string()]}. get_abstract_code_from_src(File) -> get_abstract_code_from_src(File, src_compiler_opts()). --spec get_abstract_code_from_src(atom() | file:filename(), comp_options()) -> +-spec get_abstract_code_from_src(mod_or_fname(), comp_options()) -> {'ok', abstract_code()} | {'error', [string()]}. get_abstract_code_from_src(File, Opts) -> @@ -169,13 +169,13 @@ get_record_and_type_info(AbstractCode) -> Module = get_module(AbstractCode), get_record_and_type_info(AbstractCode, Module, dict:new()). --spec get_record_and_type_info(abstract_code(), atom(), dict()) -> +-spec get_record_and_type_info(abstract_code(), module(), dict()) -> {'ok', dict()} | {'error', string()}. get_record_and_type_info(AbstractCode, Module, RecDict) -> get_record_and_type_info(AbstractCode, Module, [], RecDict). -get_record_and_type_info([{attribute, _, record, {Name, Fields0}}|Left], +get_record_and_type_info([{attribute, _, record, {Name, Fields0}}|Left], Module, Records, RecDict) -> {ok, Fields} = get_record_fields(Fields0, RecDict), Arity = length(Fields), @@ -188,7 +188,7 @@ get_record_and_type_info([{attribute, _, type, {{record, Name}, Fields0, []}} Arity = length(Fields), NewRecDict = dict:store({record, Name}, [{Arity, Fields}], RecDict), get_record_and_type_info(Left, Module, Records, NewRecDict); -get_record_and_type_info([{attribute, _, Attr, {Name, TypeForm}}|Left], +get_record_and_type_info([{attribute, _, Attr, {Name, TypeForm}}|Left], Module, Records, RecDict) when Attr =:= 'type'; Attr =:= 'opaque' -> try @@ -197,7 +197,7 @@ get_record_and_type_info([{attribute, _, Attr, {Name, TypeForm}}|Left], catch throw:{error, _} = Error -> Error end; -get_record_and_type_info([{attribute, _, Attr, {Name, TypeForm, Args}}|Left], +get_record_and_type_info([{attribute, _, Attr, {Name, TypeForm, Args}}|Left], Module, Records, RecDict) when Attr =:= 'type'; Attr =:= 'opaque' -> try @@ -219,7 +219,7 @@ get_record_and_type_info([], _Module, Records, RecDict) -> end. add_new_type(TypeOrOpaque, Name, TypeForm, ArgForms, Module, RecDict) -> - case erl_types:type_is_defined(TypeOrOpaque, Name, RecDict) of + case erl_types:type_is_defined(TypeOrOpaque, Name, RecDict) of true -> throw({error, io_lib:format("Type already defined: ~w\n", [Name])}); false -> @@ -237,7 +237,7 @@ add_new_type(TypeOrOpaque, Name, TypeForm, ArgForms, Module, RecDict) -> get_record_fields(Fields, RecDict) -> get_record_fields(Fields, RecDict, []). -get_record_fields([{typed_record_field, OrdRecField, TypeForm}|Left], +get_record_fields([{typed_record_field, OrdRecField, TypeForm}|Left], RecDict, Acc) -> Name = case OrdRecField of @@ -278,13 +278,16 @@ type_record_fields([RecKey|Recs], RecDict) -> process_record_remote_types(CServer) -> TempRecords = dialyzer_codeserver:get_temp_records(CServer), + TempExpTypes = dialyzer_codeserver:get_temp_exported_types(CServer), RecordFun = fun(Key, Value) -> case Key of {record, _Name} -> FieldFun = fun(_Arity, Fields) -> - [{Name, erl_types:t_solve_remote(Field, TempRecords)} || {Name, Field} <- Fields] + [{Name, erl_types:t_solve_remote(Field, TempExpTypes, + TempRecords)} + || {Name, Field} <- Fields] end, orddict:map(FieldFun, Value); _Other -> Value @@ -295,7 +298,8 @@ process_record_remote_types(CServer) -> dict:map(RecordFun, Record) end, NewRecords = dict:map(ModuleFun, TempRecords), - dialyzer_codeserver:finalize_records(NewRecords, CServer). + CServer1 = dialyzer_codeserver:finalize_records(NewRecords, CServer), + dialyzer_codeserver:finalize_exported_types(TempExpTypes, CServer1). -spec merge_records(dict(), dict()) -> dict(). @@ -308,19 +312,19 @@ merge_records(NewRecords, OldRecords) -> %% %% ============================================================================ --spec get_spec_info(module(), abstract_code(), dict()) -> +-spec get_spec_info(atom(), abstract_code(), dict()) -> {'ok', dict()} | {'error', string()}. get_spec_info(ModName, AbstractCode, RecordsDict) -> get_spec_info(AbstractCode, dict:new(), RecordsDict, ModName, "nofile"). -%% TypeSpec is a list of conditional contracts for a function. +%% TypeSpec is a list of conditional contracts for a function. %% Each contract is of the form {[Argument], Range, [Constraint]} where %% - Argument and Range are in erl_types:erl_type() format and %% - Constraint is of the form {subtype, T1, T2} where T1 and T2 %% are erl_types:erl_type() -get_spec_info([{attribute, Ln, spec, {Id, TypeSpec}}|Left], +get_spec_info([{attribute, Ln, spec, {Id, TypeSpec}}|Left], SpecDict, RecordsDict, ModName, File) when is_list(TypeSpec) -> MFA = case Id of {_, _, _} = T -> T; @@ -335,7 +339,7 @@ get_spec_info([{attribute, Ln, spec, {Id, TypeSpec}}|Left], {ok, {{OtherFile, L},_C}} -> {Mod, Fun, Arity} = MFA, Msg = io_lib:format(" Contract for function ~w:~w/~w " - "already defined in ~s:~w\n", + "already defined in ~s:~w\n", [Mod, Fun, Arity, OtherFile, L]), throw({error, Msg}) catch @@ -353,15 +357,30 @@ get_spec_info([], SpecDict, _RecordsDict, _ModName, _File) -> %% ============================================================================ %% +%% Exported types +%% +%% ============================================================================ + +-spec sets_filter([module()], set()) -> set(). + +sets_filter([], ExpTypes) -> + ExpTypes; +sets_filter([Mod|Mods], ExpTypes) -> + NewExpTypes = sets:filter(fun({M, _F, _A}) -> M =/= Mod end, ExpTypes), + sets_filter(Mods, NewExpTypes). + +%% ============================================================================ +%% %% Util utils %% %% ============================================================================ --spec src_compiler_opts() -> comp_options(). +-spec src_compiler_opts() -> [compile:option(),...]. src_compiler_opts() -> [no_copt, to_core, binary, return_errors, - no_inline, strict_record_tests, strict_record_updates]. + no_inline, strict_record_tests, strict_record_updates, + no_is_record_optimization]. -spec get_module(abstract_code()) -> module(). @@ -381,7 +400,7 @@ cleanup_parse_transforms([]) -> -spec format_errors([{module(), string()}]) -> [string()]. format_errors([{Mod, Errors}|Left]) -> - FormatedError = + FormatedError = [io_lib:format("~s:~w: ~s\n", [Mod, Line, M:format_error(Desc)]) || {Line, M, Desc} <- Errors], [lists:flatten(FormatedError) | format_errors(Left)]; @@ -456,7 +475,7 @@ pp_size(Size, Ctxt, Cont) -> end. pp_opts(Type, Flags) -> - FinalFlags = + FinalFlags = case cerl:atom_val(Type) of binary -> []; float -> keep_endian(cerl:concrete(Flags)); diff --git a/lib/dialyzer/vsn.mk b/lib/dialyzer/vsn.mk index e3e3f6d668..d3574e0a71 100644 --- a/lib/dialyzer/vsn.mk +++ b/lib/dialyzer/vsn.mk @@ -1 +1 @@ -DIALYZER_VSN = 2.2.0 +DIALYZER_VSN = 2.3.1 diff --git a/lib/docbuilder/doc/src/notes.xml b/lib/docbuilder/doc/src/notes.xml index 725aae0a68..019cf1b083 100644 --- a/lib/docbuilder/doc/src/notes.xml +++ b/lib/docbuilder/doc/src/notes.xml @@ -31,6 +31,22 @@ <p>This document describes the changes made to the DocBuilder application.</p> +<section><title>Docbuilder 0.9.8.8</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> Fixed problem with a centered table that was + transformed into an xml document which then produced + mis-formatted html. </p> + <p> + Own Id: OTP-8784</p> + </item> + </list> + </section> + +</section> + <section><title>Docbuilder 0.9.8.7</title> <section><title>Improvements and New Features</title> diff --git a/lib/docbuilder/src/docb_edoc_xml_cb.erl b/lib/docbuilder/src/docb_edoc_xml_cb.erl index 4dba843341..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, @@ -478,31 +471,29 @@ otp_xmlify_a_href("#"++_ = Marker, Es0) -> % <seealso marker="#what"> otp_xmlify_a_href("http:"++_ = URL, Es0) -> % external URL {URL, Es0}; otp_xmlify_a_href("OTPROOT"++AppRef, Es0) -> % <.. marker="App:FileRef - case split(AppRef, "/") of - [AppS, "doc", FileRef1] -> - FileRef = AppS++":"++otp_xmlify_a_fileref(FileRef1, AppS), - [#xmlText{value=Str0} = T] = Es0, - Str = case split(Str0, "/") of - %% //Application - [AppS2] -> - %% AppS2 can differ from AppS - %% Example: xmerl/XMerL - AppS2; - [_AppS,ModRef] -> - case split(ModRef, ":") of - %% //Application/Module - [Module] -> - Module++"(3)"; - %% //Application/Module:Type() - [_Module,_Type] -> - ModRef - end; - %% //Application/Module:Function/Arity - [_AppS,ModFunc,Arity] -> - ModFunc++"/"++Arity - end, - {FileRef, [T#xmlText{value=Str}]} - end; + [AppS, "doc", FileRef1] = split(AppRef, "/"), + FileRef = AppS++":"++otp_xmlify_a_fileref(FileRef1, AppS), + [#xmlText{value=Str0} = T] = Es0, + Str = case split(Str0, "/") of + %% //Application + [AppS2] -> + %% AppS2 can differ from AppS + %% Example: xmerl/XMerL + AppS2; + [_AppS,ModRef] -> + case split(ModRef, ":") of + %% //Application/Module + [Module] -> + Module++"(3)"; + %% //Application/Module:Type() + [_Module,_Type] -> + ModRef + end; + %% //Application/Module:Function/Arity + [_AppS,ModFunc,Arity] -> + ModFunc++"/"++Arity + end, + {FileRef, [T#xmlText{value=Str}]}; otp_xmlify_a_href("../"++File, Es0) -> %% Special case: This kind of relative path is used on some %% places within i.e. EDoc and refers to a file within the same @@ -639,13 +630,13 @@ otp_xmlify_table([#xmlText{} = E|Es]) -> [E | otp_xmlify_table(Es)]; otp_xmlify_table([#xmlElement{name=tbody} = E|Es]) -> otp_xmlify_table(E#xmlElement.content)++otp_xmlify_table(Es); -otp_xmlify_table([#xmlElement{name=tr} = E|Es]) -> +otp_xmlify_table([#xmlElement{name=tr, content=Content}|Es]) -> %% Insert newlines between table rows - otp_xmlify_table(E#xmlElement.content)++[{br,[]}]++otp_xmlify_table(Es); -otp_xmlify_table([#xmlElement{name=th} = E|Es]) -> - [{em, E#xmlElement.content} | otp_xmlify_table(Es)]; -otp_xmlify_table([#xmlElement{name=td} = E|Es]) -> - otp_xmlify_e(E#xmlElement.content) ++ otp_xmlify_table(Es); + otp_xmlify_table(Content)++[{br,[]}]++otp_xmlify_table(Es); +otp_xmlify_table([#xmlElement{name=th, content=Content}|Es]) -> + [{em, Content} | otp_xmlify_table(Es)]; +otp_xmlify_table([#xmlElement{name=td, content=Content}|Es]) -> + otp_xmlify_e(Content) ++ otp_xmlify_table(Es); otp_xmlify_table([]) -> []. @@ -1155,8 +1146,8 @@ get_text(#xmlElement{content=[E]}) -> %% text_only(Es) -> Ts %% Takes a list of xmlElement and xmlText and return a lists of xmlText. -text_only([#xmlElement{} = E |Es]) -> - text_only(E#xmlElement.content) ++ text_only(Es); +text_only([#xmlElement{content = Content}|Es]) -> + text_only(Content) ++ text_only(Es); text_only([#xmlText{} = E |Es]) -> [E | text_only(Es)]; text_only([]) -> diff --git a/lib/docbuilder/src/docb_html.erl b/lib/docbuilder/src/docb_html.erl index 9aea4c8a66..bdfc5ea876 100644 --- a/lib/docbuilder/src/docb_html.erl +++ b/lib/docbuilder/src/docb_html.erl @@ -283,16 +283,16 @@ rule([term|_], {_, [ID], _}, Opts) -> ID, "</strong></em> "]}, Opts}; TermList -> - case lists:keysearch(ID, 1, TermList) of + case lists:keyfind(ID, 1, TermList) of false -> {{drop, ["<em><strong>", ID, "</strong></em> "]}, Opts}; - {value, {ID, Name, _Description, _Resp}} -> + {ID, Name, _Description, _Resp} -> {{drop, ["<em><strong>", Name, "</strong></em> "]}, Opts}; - {value, {ID, Name, _Description}} -> + {ID, Name, _Description} -> {{drop, [ "<em><strong>", Name, "</strong></em> "]}, Opts} @@ -306,16 +306,16 @@ rule([term|_], {_, [ID], _}, Opts) -> TermList -> PartApplication = docb_util:lookup_option(part_application, Opts), - case lists:keysearch(ID, 1, TermList) of + case lists:keyfind(ID, 1, TermList) of false -> {{drop, ["<a href=\"", PartApplication, "_term.html#", ID, "\">", ID, "</a> "]}, Opts}; - {value, {ID, Name, _Description, _Resp}} -> + {ID, Name, _Description, _Resp} -> {{drop, ["<a href=\"", PartApplication, "_term.html#", ID, "\">", Name, "</a> "]}, Opts}; - {value, {ID, Name, _Description}} -> + {ID, Name, _Description} -> {{drop, ["<a href=\"", PartApplication, "_term.html#", ID, "\">", Name, "</a> "]}, Opts} @@ -331,17 +331,16 @@ rule([cite|_], {_, [ID], _}, Opts) -> {{drop, ["<em><strong>", ID, "</strong></em> "]}, Opts}; CiteList -> - case lists:keysearch(ID, 1, CiteList) of + case lists:keyfind(ID, 1, CiteList) of false -> {{drop, ["<em><strong>", ID, "</strong></em> "]}, Opts}; - - {value, {ID, Name, _Description, _Resp}} -> + {ID, Name, _Description, _Resp} -> {{drop, ["<em><strong>", Name, "</strong></em> "]}, Opts}; - {value, {ID, Name, _Description}} -> + {ID, Name, _Description} -> {{drop, ["<em><strong>", Name, "</strong></em> "]}, Opts} @@ -355,18 +354,18 @@ rule([cite|_], {_, [ID], _}, Opts) -> CiteList -> PartApp = docb_util:lookup_option(part_application, Opts), - case lists:keysearch(ID, 1, CiteList) of + case lists:keyfind(ID, 1, CiteList) of false -> {{drop, ["<a href=\"", PartApp, "_cite.html#", ID, "\">", ID, "</a> "]}, Opts}; - {value, {ID, Name, _Description, _Resp}} -> + {ID, Name, _Description, _Resp} -> {{drop, ["<a href=\"", PartApp, "_cite.html#", ID, "\">", Name, "</a> "]}, Opts}; - {value, {ID, Name, _Description}} -> + {ID, Name, _Description} -> {{drop, ["<a href=\"", PartApp, "_cite.html#", ID, "\">", Name, "</a> "]}, @@ -376,7 +375,7 @@ rule([cite|_], {_, [ID], _}, Opts) -> end; rule([code|_], {_, [Type], [{pcdata, _, Code}]}, Opts) -> - case lists:member(Type,["ERL","C","NONE"]) of + case lists:member(Type, ["ERL","C","NONE"]) of true -> {{drop, ["\n<div class=\"example\"><pre>\n", docb_html_util:element_cdata_to_html(Code), "\n</pre></div>\n"]}, Opts}; diff --git a/lib/docbuilder/src/docb_html_util.erl b/lib/docbuilder/src/docb_html_util.erl index b2951706ea..02ce8b52a7 100644 --- a/lib/docbuilder/src/docb_html_util.erl +++ b/lib/docbuilder/src/docb_html_util.erl @@ -136,7 +136,6 @@ copy_pics(Src, Dest, Opts) -> Dir = code:lib_dir(docbuilder), InFile = filename:join([Dir, "etc", Src]), OutFile = docb_util:outfile(Dest, "", Opts), - case filelib:last_modified(OutFile) of 0 -> % File doesn't exist file:copy(InFile, OutFile); @@ -156,10 +155,10 @@ copy_pics(Src, Dest, Opts) -> %%--Resolve header data------------------------------------------------- extract_header_data(Key, {header, [], List}) -> - case lists:keysearch(Key, 1, List) of - {value, {Key, [], []}} -> + case lists:keyfind(Key, 1, List) of + {Key, [], []} -> ""; - {value, {Key, [], [{pcdata, [], Value}]}} -> + {Key, [], [{pcdata, [], Value}]} -> pcdata_to_html(Value); false -> "" @@ -253,7 +252,7 @@ make_anchor_href(HRef) -> {ok, [HRef]} -> %% No `#' in HRef, i.e. only path make_anchor_href(HRef, ""); - {ok, [Path, Fragment]}-> + {ok, [Path, Fragment]} -> make_anchor_href(Path, Fragment) end. @@ -398,10 +397,10 @@ count_sections([]) -> %%--Make a ToC---------------------------------------------------------- format_toc(Toc) -> - lists:map(fun({Number, Title}) -> - [Number, " <a href = \"#", Number, - "\">", Title, "</a><br/>\n"] - end, Toc). + [format_toc1(T) || T <- Toc]. + +format_toc1({Number, Title}) -> + [Number, " <a href = \"#", Number, "\">", Title, "</a><br/>\n"]. %%--Convert HTML ISO Latin 1 characters to ordinary characters---------- diff --git a/lib/docbuilder/src/docb_main.erl b/lib/docbuilder/src/docb_main.erl index ef21f65557..87a1401a02 100644 --- a/lib/docbuilder/src/docb_main.erl +++ b/lib/docbuilder/src/docb_main.erl @@ -55,7 +55,7 @@ process(File, Opts) -> %% If no target format is specified, assume HTML: Tos = if - Tos0==[] -> [html]; + Tos0 =:= [] -> [html]; true -> Tos0 end, @@ -327,12 +327,8 @@ verify(Tree) -> verify(Tree, [], 1). verify({pcdata, Optional, _}, Path, Level) -> verify_optional(Optional, Path, Level); verify({Tag, Optional, Args}, Path, Level) when is_list(Args) -> - case verify_optional(Optional, Path, Level) of - true -> - verify_list(Args, [Tag|Path], Level); - false -> - false - end; + verify_optional(Optional, Path, Level) + andalso verify_list(Args, [Tag|Path], Level); verify(Other, Path, Level) -> verify_error(Other, Path, Level). @@ -342,12 +338,7 @@ verify_error(X, Path, Level) -> false. verify_list([H|T], Path, Level) -> - case verify(H, Path, Level) of - true -> - verify_list(T, Path, Level +1); - false -> - false - end; + verify(H, Path, Level) andalso verify_list(T, Path, Level + 1); verify_list([], _, _) -> true. @@ -419,7 +410,7 @@ edit1_list(_Tag, [], _Op) -> %% Actual transformation of tree structure to desired format. transform(From, To, Opts, File, Tree) -> Filter = if - To==html; To==kwic -> + To =:= html; To =:= kwic -> list_to_atom("docb_tr_" ++ atom_to_list(From) ++ [$2|atom_to_list(To)]); true -> @@ -427,7 +418,7 @@ transform(From, To, Opts, File, Tree) -> [$2|atom_to_list(To)]) end, - case catch apply(Filter, transform, [File, Tree, Opts]) of + case catch Filter:transform(File, Tree, Opts) of %% R5C {'EXIT', {undef, [{Filter, transform, [File, Tree, Opts]}|_]}}-> @@ -459,9 +450,9 @@ transform(From, To, Opts, File, Tree) -> finish_transform(Tree, File, Opts, Filter) -> {Str, NewOpts} = pp(Tree, [], 1, Filter, Opts), Extension = - case catch apply(Filter, extension, [NewOpts]) of + case catch Filter:extension(NewOpts) of {'EXIT', _} -> - apply(Filter, extension, []); + Filter:extension(); Others -> Others end, @@ -606,7 +597,7 @@ include_all(Fd) -> eof -> []; ListOfChars -> - lists:append(ListOfChars, include_all(Fd)) + ListOfChars ++ include_all(Fd) end. extract(File, Fd, StartTag, StopTag, State) -> diff --git a/lib/docbuilder/src/docb_pretty_format.erl b/lib/docbuilder/src/docb_pretty_format.erl index 0c4fb0507b..25dcd8987b 100644 --- a/lib/docbuilder/src/docb_pretty_format.erl +++ b/lib/docbuilder/src/docb_pretty_format.erl @@ -47,7 +47,7 @@ term(Term) -> %% the next line to need an "extra" indent!). term([], Indent) -> {Indent, [$[,$]]}; -term(L, Indent) when list(L) -> +term(L, Indent) when is_list(L) -> case is_string(L) of true -> {Indent, io_lib:write_string(L)}; @@ -59,7 +59,7 @@ term(L, Indent) when list(L) -> write_simple_list(L, Indent) end end; -term(T, Indent) when tuple(T) -> +term(T, Indent) when is_tuple(T) -> case complex_tuple(T) of true -> write_complex_tuple(T, Indent); diff --git a/lib/docbuilder/src/docb_tr_application2html.erl b/lib/docbuilder/src/docb_tr_application2html.erl index 4084cfe6ba..d8cb214d0a 100644 --- a/lib/docbuilder/src/docb_tr_application2html.erl +++ b/lib/docbuilder/src/docb_tr_application2html.erl @@ -119,8 +119,8 @@ transform(File, {application, _Attrs, [Header|Rest]}, Opts0) -> case docb_main:parse1("fascicules", Opts0) of {ok, Parse} -> FascData = get_fasc_data(Parse), - case lists:keysearch(File, 1, FascData) of - {value, {_, _, "YES", _}} -> + case lists:keyfind(File, 1, FascData) of + {_, _, "YES", _} -> OrigFile = docb_util:outfile(File++"_frame", ".html", Opts0), @@ -167,7 +167,7 @@ concat_files([File|Rest], Body, Opts) -> %% Remove the reference manual header [{Ref, [], [_Hdr| NewBody]}] = NewParse, RefParse = [{Ref, [], NewBody}], - lists:append(Body, concat_files(Rest, RefParse, Opts)); + Body ++ concat_files(Rest, RefParse, Opts); errors -> errors end; @@ -216,7 +216,7 @@ make_toc([{lib, Attrs, More}|Rest]) -> make_toc([{com, Attrs, More}|Rest]) -> [{com, Attrs, More}|make_toc(Rest)]; make_toc([{_Tag, _Attrs, More}|Rest]) -> - lists:append(make_toc(More), make_toc(Rest)). + make_toc(More) ++ make_toc(Rest). rule([module|_], {_, [File], _}) -> {"<small><a target=\"document\" href=\"" ++ @@ -280,9 +280,7 @@ get_fasc_data({fascicules, _, Fascs}) -> Fascs). get_avals(Atts) -> - lists:map(fun(Tuple) -> - element(3, Tuple) end, - Atts). + [element(3, Tuple) || Tuple <- Atts]. get_pc_text([{pcdata, _, Text}]) -> Text. diff --git a/lib/docbuilder/src/docb_tr_cite2html.erl b/lib/docbuilder/src/docb_tr_cite2html.erl index 4ecbfa4e91..77f1c4e636 100644 --- a/lib/docbuilder/src/docb_tr_cite2html.erl +++ b/lib/docbuilder/src/docb_tr_cite2html.erl @@ -39,24 +39,22 @@ purge_body([], _) -> purge_body([{pcdata,_Attrs,_More}|Rest], CiteList) -> purge_body(Rest, CiteList); purge_body([{cite,[{"ID","CDATA",ID}],More}|Rest], CiteList) -> - case lists:keysearch(ID, 1, CiteList) of + case lists:keyfind(ID, 1, CiteList) of false -> [{cite, [{"NAME","CDATA",ID}, {"ID","CDATA",ID}], More}| purge_body(Rest, CiteList)]; - {value, {ID, Name, _Description, _Responsible}} -> + {ID, Name, _Description, _Responsible} -> [{cite, [{"NAME","CDATA",Name}, {"ID","CDATA",ID}], More}| purge_body(Rest, CiteList)]; - {value, {ID, Name, _Description}} -> + {ID, Name, _Description} -> [{cite, [{"NAME","CDATA",Name}, {"ID","CDATA",ID}], More}| purge_body(Rest, CiteList)] end; purge_body([{_Tag,_Attrs,More}|Rest], CiteList) -> - lists:append(purge_body(More, CiteList), - purge_body(Rest, CiteList)). + purge_body(More, CiteList) ++ purge_body(Rest, CiteList). rule([header|_], _) -> {drop, ""}; - rule(_, _) -> {drop, ""}. @@ -91,19 +89,19 @@ rule([cite|_], {_,[Name,ID], [{citedef,[],[{pcdata,[],Def}]}]}, Opts) -> false -> []; Value -> Value end, - case lists:keysearch(ID, 1, CiteList) of + case lists:keyfind(ID, 1, CiteList) of false -> {{drop,"\n<dt><a name=\"" ++ ID ++ "\">" ++ "<strong>" ++ ID ++ "</strong></a></dt>\n<dd>" ++ docb_html_util:pcdata_to_html(Def) ++ "\n</dd>\n"}, Opts}; - {value, {ID, Name, Description, _Responsible}} -> + {ID, Name, Description, _Responsible} -> docb_util:message(warning, "Global cite ~s overriding local", [ID]), {{drop,"\n<dt><a name=\"" ++ ID ++ "\">" ++ "<strong>" ++ Name ++ "</strong></a></dt>\n<dd>" ++ docb_html_util:pcdata_to_html(Description) ++ "\n</dd>\n"}, Opts}; - {value, {ID, Name, Description}} -> + {ID, Name, Description} -> docb_util:message(warning, "Global cite ~s overriding local", [ID]), {{drop,"\n<dt><a name=\"" ++ ID ++ "\">" ++ @@ -117,19 +115,19 @@ rule([cite|_], {_,[Name,ID],_}, Opts) -> false -> []; Value -> Value end, - case lists:keysearch(ID, 1, CiteList) of + case lists:keyfind(ID, 1, CiteList) of false -> docb_util:message(error, "The cite ~s has no definition", [ID]), {{drop,"\n<dt><a name=\"" ++ ID ++ "\">" ++ "<strong>" ++ ID ++ "</strong></a></dt>\n<dd>" ++ "??" ++ "\n</dd>\n"}, Opts}; - {value, {ID, Name, Description, _Responsible}} -> + {ID, Name, Description, _Responsible} -> {{drop,"\n<dt><a name=\"" ++ ID ++ "\">" ++ "<strong>" ++ Name ++ "</strong></a></dt>\n<dd>" ++ docb_html_util:pcdata_to_html(Description) ++ "\n</dd>\n"}, Opts}; - {value, {ID, Name, Description}} -> + {ID, Name, Description} -> {{drop,"\n<dt><a name=\"" ++ ID ++ "\">" ++ "<strong>" ++ Name ++ "</strong></a></dt>\n<dd>" ++ docb_html_util:pcdata_to_html(Description) ++ "\n</dd>\n"}, Opts} diff --git a/lib/docbuilder/src/docb_tr_index2html.erl b/lib/docbuilder/src/docb_tr_index2html.erl index bbf419f3ef..312342add2 100644 --- a/lib/docbuilder/src/docb_tr_index2html.erl +++ b/lib/docbuilder/src/docb_tr_index2html.erl @@ -73,9 +73,7 @@ prune_flat([], _) -> []. keep_pcdata(Trees) -> - lists:filter(fun({pcdata, _, _}) -> true; - (_) -> false - end, Trees). + [T || T = {pcdata, _, _} <- Trees]. new_trees(FileFuncs) -> Files0 = [{File, RefType} || {File, RefType, _} <- FileFuncs], diff --git a/lib/docbuilder/src/docb_tr_part2html.erl b/lib/docbuilder/src/docb_tr_part2html.erl index dd44c4a8df..30befe8432 100644 --- a/lib/docbuilder/src/docb_tr_part2html.erl +++ b/lib/docbuilder/src/docb_tr_part2html.erl @@ -93,8 +93,8 @@ transform(File, {part, _Attrs, [Header| Rest]}, Opts0) -> case docb_main:parse1("fascicules", Opts0) of {ok, Parse} -> FascData = get_fasc_data(Parse), - case lists:keysearch(File, 1, FascData) of - {value, {_, _, "YES", _}} -> + case lists:keyfind(File, 1, FascData) of + {_, _, "YES", _} -> OrigFile = docb_util:outfile(File++"_frame", ".html", Opts0), @@ -137,7 +137,7 @@ concat_files([File | Rest], Body, ChLevel, Opts, TP, TOpts, Ext) -> case docb_main:parse1(File, Opts) of {ok, Parse} -> {TopTag, Attrs, [Header = {header, _, HeaderContents} | More]} = Parse, - {value,{title,_,Title}} = lists:keysearch(title,1,HeaderContents), + {title,_,Title} = lists:keyfind(title,1,HeaderContents), NewMore = [{section, [], [{title, [], Title}| More]}], NewParse = {TopTag, Attrs, [Header| NewMore]}, if @@ -156,9 +156,8 @@ concat_files([File | Rest], Body, ChLevel, Opts, TP, TOpts, Ext) -> docb_html_util:number(NewParse, integer_to_list(ChLevel), File), {_, [], [_| NewBody]} = NumberTree, - lists:append(Body, - concat_files(Rest, NewBody, ChLevel+1, Opts, - TP, TOpts, Ext)); + Body ++ concat_files(Rest, NewBody, ChLevel+1, Opts, + TP, TOpts, Ext); errors -> throw({error,"Parse error when building chapter "++File}) end; @@ -232,9 +231,7 @@ get_fasc_data({fascicules, _, Fascs}) -> Fascs). get_avals(Atts) -> - lists:map(fun(Tuple) -> - element(3, Tuple) end, - Atts). + [element(3, Tuple) || Tuple <- Atts]. get_pc_text([{pcdata, _, Text}]) -> Text. diff --git a/lib/docbuilder/src/docb_tr_term2html.erl b/lib/docbuilder/src/docb_tr_term2html.erl index 0a993cebb1..a3c4a5312a 100644 --- a/lib/docbuilder/src/docb_tr_term2html.erl +++ b/lib/docbuilder/src/docb_tr_term2html.erl @@ -39,24 +39,22 @@ purge_body([], _) -> purge_body([{pcdata,_Attrs,_More}|Rest], TermList) -> purge_body(Rest, TermList); purge_body([{term,[{"ID","CDATA",ID}],More}|Rest], TermList) -> - case lists:keysearch(ID, 1, TermList) of + case lists:keyfind(ID, 1, TermList) of false -> [{term,[{"NAME","CDATA",ID},{"ID","CDATA",ID}],More}| purge_body(Rest, TermList)]; - {value, {ID, Name, _Description, _Responsible}} -> + {ID, Name, _Description, _Responsible} -> [{term,[{"NAME","CDATA",Name},{"ID","CDATA",ID}],More}| purge_body(Rest, TermList)]; - {value, {ID, Name, _Description}} -> + {ID, Name, _Description} -> [{term,[{"NAME","CDATA",Name},{"ID","CDATA",ID}],More}| purge_body(Rest, TermList)] end; purge_body([{_Tag,_Attrs,More}|Rest], TermList) -> - lists:append(purge_body(More, TermList), - purge_body(Rest, TermList)). + purge_body(More, TermList) ++ purge_body(Rest, TermList). rule([header|_], _) -> {drop, ""}; - rule(_, _) -> {drop, ""}. @@ -82,19 +80,19 @@ rule([term|_], {_,[Name,ID],[{termdef,[],[{pcdata,[],Def}]}]}, Opts) -> false -> []; Value -> Value end, - case lists:keysearch(ID, 1, TermList) of + case lists:keyfind(ID, 1, TermList) of false -> {{drop,"\n<dt><a name=\"" ++ ID ++ "\">" ++ "<strong>" ++ ID ++ "</strong></a>\n</dt>\n<dd>" ++ docb_html_util:pcdata_to_html(Def) ++ "\n</dd>\n"}, Opts}; - {value, {ID, Name, Description, _Responsible}} -> + {ID, Name, Description, _Responsible} -> docb_util:message(warning, "Global term ~s overriding local", [ID]), {{drop,"\n<dt><a name=\"" ++ ID ++ "\">" ++ "<strong>" ++ Name ++ "</strong></a></dt>\n<dd>" ++ docb_html_util:pcdata_to_html(Description) ++ "\n</dd>\n"}, Opts}; - {value, {ID, Name, Description}} -> + {ID, Name, Description} -> docb_util:message(warning, "Global term ~s overriding local", [ID]), {{drop, "\n<dt><a name=\"" ++ ID ++ "\">" ++ @@ -107,19 +105,19 @@ rule([term|_], {_,[Name,ID],_}, Opts) -> false -> []; Value -> Value end, - case lists:keysearch(ID, 1, TermList) of + case lists:keyfind(ID, 1, TermList) of false -> docb_util:message(error, "The term ~s has no definition", [ID]), {{drop, "\n<dt><a name=\"" ++ ID ++ "\">" ++ "<strong>" ++ ID ++ "</strong></a></dt>\n<dd>" ++ "??" ++ "\n</dd>\n"}, Opts}; - {value, {ID, Name, Description, _Responsible}} -> + {ID, Name, Description, _Responsible} -> {{drop, "\n<dt><a name=\"" ++ ID ++ "\">" ++ "<strong>" ++ Name ++ "</strong></a></dt>\n<dd>" ++ docb_html_util:pcdata_to_html(Description) ++ "\n</dd>\n"}, Opts}; - {value, {ID, Name, Description}} -> + {ID, Name, Description} -> {{drop, "\n<dt><a name=\"" ++ ID ++ "\">" ++ "<strong>" ++ Name ++ "</strong></a></dt>\n<dd>" ++ docb_html_util:pcdata_to_html(Description) ++ "\n</dd>\n"}, Opts} diff --git a/lib/docbuilder/src/docb_transform.erl b/lib/docbuilder/src/docb_transform.erl index a432038adf..9c7561b07b 100644 --- a/lib/docbuilder/src/docb_transform.erl +++ b/lib/docbuilder/src/docb_transform.erl @@ -135,8 +135,8 @@ parse([Opt | _RawOpts], _Opts) -> get_defs(Type, File, Opts) -> Key = {defs,Type}, {PrevDefs, Opts2} = - case lists:keysearch(Key, 1, Opts) of - {value, {_, Defs0}} -> + case lists:keyfind(Key, 1, Opts) of + {_, Defs0} -> {Defs0, lists:keydelete(Key, 1, Opts)}; false -> {[], Opts} diff --git a/lib/docbuilder/src/docb_util.erl b/lib/docbuilder/src/docb_util.erl index 59673ef3a4..9b2eec7733 100644 --- a/lib/docbuilder/src/docb_util.erl +++ b/lib/docbuilder/src/docb_util.erl @@ -61,7 +61,7 @@ html_snippet(What, Opts) -> case lookup_option(html_mod, Opts) of false -> ""; Module -> - case catch apply(Module, What, []) of + case catch Module:What() of HTML when is_list(HTML) -> HTML; {'EXIT', {undef, _}} -> @@ -82,7 +82,7 @@ html_snippet(What, Arg, Opts) -> case lookup_option(html_mod, Opts) of false -> ""; Module -> - case catch apply(Module, What, [Arg]) of + case catch Module:What(Arg) of HTML when is_list(HTML) -> HTML; {'EXIT', {undef, _}} -> @@ -106,8 +106,8 @@ html_snippet(What, Arg, Opts) -> %% lookup_option(Opt, Opts) -> Value | false lookup_option(Opt, Opts) -> - case lists:keysearch(Opt, 1, Opts) of - {value, {Opt,Value}} -> Value; + case lists:keyfind(Opt, 1, Opts) of + {Opt,Value} -> Value; false -> false end. diff --git a/lib/docbuilder/src/docb_xmerl_tree_cb.erl b/lib/docbuilder/src/docb_xmerl_tree_cb.erl index d57f55bff8..bc62069230 100644 --- a/lib/docbuilder/src/docb_xmerl_tree_cb.erl +++ b/lib/docbuilder/src/docb_xmerl_tree_cb.erl @@ -188,8 +188,8 @@ attrs(DTD, Tag, GivenAttrs) -> merge_attrs(Tag, default_attrs(DTD, Tag), GivenAttrs). merge_attrs(Tag, [{NameA, Type, DefVal}|Default], GivenAttrs) -> - Val = case lists:keysearch(NameA, #xmlAttribute.name, GivenAttrs) of - {value, #xmlAttribute{value=Val0}} -> Val0; + Val = case lists:keyfind(NameA, #xmlAttribute.name, GivenAttrs) of + #xmlAttribute{value=Val0} -> Val0; false -> DefVal end, Attr = {attr_name(NameA), Type, attr_val(Type, Val)}, diff --git a/lib/docbuilder/vsn.mk b/lib/docbuilder/vsn.mk index 2852ebcc8b..b23ee521c7 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 - - - +DOCB_VSN = 0.9.8.8 diff --git a/lib/edoc/doc/src/notes.xml b/lib/edoc/doc/src/notes.xml index 74fa2d3ab6..83ad27ed31 100644 --- a/lib/edoc/doc/src/notes.xml +++ b/lib/edoc/doc/src/notes.xml @@ -31,6 +31,21 @@ <p>This document describes the changes made to the EDoc application.</p> +<section><title>Edoc 0.7.6.7</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Edoc now uses the new API functions to <c>inets</c> + instead of the deprecated ones.</p> + <p> + Own Id: OTP-8749</p> + </item> + </list> + </section> + +</section> + <section><title>Edoc 0.7.6.6</title> <section><title>Improvements and New Features</title> diff --git a/lib/edoc/src/edoc_lib.erl b/lib/edoc/src/edoc_lib.erl index 47e61f7932..5b7fb1e0d2 100644 --- a/lib/edoc/src/edoc_lib.erl +++ b/lib/edoc/src/edoc_lib.erl @@ -472,7 +472,7 @@ uri_get_file(File0) -> uri_get_http(URI) -> %% Try using option full_result=false - case catch {ok, http:request(get, {URI,[]}, [], + case catch {ok, httpc:request(get, {URI,[]}, [], [{full_result, false}])} of {'EXIT', _} -> uri_get_http_r10(URI); @@ -482,7 +482,7 @@ uri_get_http(URI) -> uri_get_http_r10(URI) -> %% Try most general form of request - Result = (catch {ok, http:request(get, {URI,[]}, [], [])}), + Result = (catch {ok, httpc:request(get, {URI,[]}, [], [])}), uri_get_http_1(Result, URI). uri_get_http_1(Result, URI) -> diff --git a/lib/edoc/src/edoc_report.erl b/lib/edoc/src/edoc_report.erl index b87c58dde3..ee54c60c90 100644 --- a/lib/edoc/src/edoc_report.erl +++ b/lib/edoc/src/edoc_report.erl @@ -27,6 +27,8 @@ -module(edoc_report). +%% Avoid warning for local function error/2 clashing with autoimported BIF. +-compile({no_auto_import,[error/2]}). -export([error/1, error/2, error/3, diff --git a/lib/edoc/vsn.mk b/lib/edoc/vsn.mk index 2de2641b4a..75e9a5c971 100644 --- a/lib/edoc/vsn.mk +++ b/lib/edoc/vsn.mk @@ -1 +1 @@ -EDOC_VSN = 0.7.6.6 +EDOC_VSN = 0.7.6.7 diff --git a/lib/erl_docgen/doc/src/notes.xml b/lib/erl_docgen/doc/src/notes.xml index ee74e598d9..5b5398fec6 100644 --- a/lib/erl_docgen/doc/src/notes.xml +++ b/lib/erl_docgen/doc/src/notes.xml @@ -29,7 +29,40 @@ <file>notes.xml</file> </header> <p>This document describes the changes made to the erl_docgen application.</p> - <section><title>Erl_Docgen 0.2</title> + <section><title>Erl_Docgen 0.2.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> Fixed the transformation from xml to html of the + funcs block in comref pages. </p> + <p> + Own Id: OTP-8792</p> + </item> + </list> + </section> + +</section> + +<section><title>erl_docgen 0.2.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + The text within code examples (CODE and PRE tags) will not be + space normalized for man pages. + </p> + <p> + Own Id: OTP-8476 + </p> + </item> + </list> + </section> + + </section> + + <section><title>erl_docgen 0.2</title> <section><title>Improvements and New Features</title> <list> 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/priv/xsl/db_man.xsl b/lib/erl_docgen/priv/xsl/db_man.xsl index a2b1e755e2..71c4a66707 100644 --- a/lib/erl_docgen/priv/xsl/db_man.xsl +++ b/lib/erl_docgen/priv/xsl/db_man.xsl @@ -336,6 +336,16 @@ <xsl:text>></xsl:text> </xsl:template> + <!-- Do not noramlize any text within pre and code tags. --> + <xsl:template match="pre/text()"> + <xsl:value-of select="."/> + </xsl:template> + + <xsl:template match="code/text()"> + <xsl:value-of select="."/> + </xsl:template> + + <!-- Replace ' by \&' ans . by \&. --> <xsl:template match="text()"> <xsl:variable name="startstring"> diff --git a/lib/erl_docgen/vsn.mk b/lib/erl_docgen/vsn.mk index 09090f01c9..0bc01f7d49 100644 --- a/lib/erl_docgen/vsn.mk +++ b/lib/erl_docgen/vsn.mk @@ -1,3 +1 @@ -ERL_DOCGEN_VSN = 0.2 - -TICKETS = +ERL_DOCGEN_VSN = 0.2.2 diff --git a/lib/erl_interface/configure.in b/lib/erl_interface/configure.in index 7728cb97be..72ac8c7bbf 100644 --- a/lib/erl_interface/configure.in +++ b/lib/erl_interface/configure.in @@ -288,13 +288,7 @@ case "$threads_disabled" in ;; win32_threads) EI_THREADS="true" - AC_MSG_CHECKING([for __declspec(thread) usability]) - if test "X$GCC" = "Xyes"; then - AC_MSG_RESULT([no]) - else - THR_DEFS="$THR_DEFS -DUSE_DECLSPEC_THREAD" - AC_MSG_RESULT([yes]) - fi + THR_DEFS="$THR_DEFS -D_WIN32_WINNT=0x0500 -DWINVER=0x0500" ;; pthread) EI_THREADS="true" diff --git a/lib/erl_interface/doc/src/ei.xml b/lib/erl_interface/doc/src/ei.xml index 2f65a8c375..d7af7a1b67 100644 --- a/lib/erl_interface/doc/src/ei.xml +++ b/lib/erl_interface/doc/src/ei.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> @@ -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>ei</title> @@ -333,7 +333,7 @@ ei_encode_tuple_header(buf, &i, 0); <desc> <p>This function encodes a list header, with a specified arity. The next <c><![CDATA[arity+1]]></c> terms are the elements - (actually it's <c><![CDATA[arity]]></c> cons cells) and the tail of the + (actually its <c><![CDATA[arity]]></c> cons cells) and the tail of the list. Lists and tuples are encoded recursively, so that a list may contain another list or tuple.</p> <p>E.g. to encode the list <c><![CDATA[[c, d, [e | f]]]]></c>:</p> @@ -581,7 +581,7 @@ ei_x_encode_empty_list(&x); <c><![CDATA[term]]></c> union, it is decoded, and the appropriate field in <c><![CDATA[term->value]]></c> is set, and <c><![CDATA[*index]]></c> is incremented by the term size.</p> - <p>The function returns 0 on successful encoding, -1 on error, + <p>The function returns 0 on successful decoding, -1 on error, and 1 if the term seems alright, but does not fit in the <c><![CDATA[term]]></c> structure. If it returns 0, the <c><![CDATA[index]]></c> will be incremented, and the <c><![CDATA[term]]></c> contains the diff --git a/lib/erl_interface/doc/src/ei_connect.xml b/lib/erl_interface/doc/src/ei_connect.xml index abf705f9e2..f562615ddd 100644 --- a/lib/erl_interface/doc/src/ei_connect.xml +++ b/lib/erl_interface/doc/src/ei_connect.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> @@ -54,7 +54,7 @@ the operation, if the primitive does not complete within the time specified, the function will return an error and <c><![CDATA[erl_errno]]></c> will be set to <c><![CDATA[ETIMEDOUT]]></c>. With - communication primitive is ment an operation on the socket, like + communication primitive is meant an operation on the socket, like <c><![CDATA[connect]]></c>, <c><![CDATA[accept]]></c>, <c><![CDATA[recv]]></c> or <c><![CDATA[send]]></c>.</p> <p>Obviously the timeouts are for implementing fault tolerance, not to keep hard realtime promises. The <c><![CDATA[_tmo]]></c> functions @@ -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> @@ -508,7 +508,7 @@ if (ei_decode_version(result.buff, &index) < 0 same as the port number that was previously bound to the socket.</p> <p><c><![CDATA[addr]]></c> is the 32-bit IP address of the local host.</p> <p>To unregister with epmd, simply close the returned - descriptor. See also <c><![CDATA[ei_unpublish()]]></c>.</p> + descriptor. Do not use <c><![CDATA[ei_unpublish()]]></c>, which is deprecated anyway.</p> <p>On success, the functions return a descriptor connecting the calling process to epmd. On failure, they return -1 and set <c><![CDATA[erl_errno]]></c> to <c><![CDATA[EIO]]></c>.</p> @@ -558,18 +558,21 @@ typedef struct { </func> <func> <name><ret>int</ret><nametext>ei_unpublish(ei_cnode *ec)</nametext></name> - <fsummary>Unpublish a node name</fsummary> + <fsummary>Forcefully unpublish a node name</fsummary> <desc> <p>This function can be called by a process to unregister a - specified node from epmd on the localhost. This may be - useful, for example, when epmd has not detected the failure of a - node, and will not allow the name to be reused. If you use this - function to unregister your own process, be sure to also close - the descriptor that was returned by <c><![CDATA[ei_publish()]]></c>.</p> - <note> - <p>Careless use of this function may have unpredictable - results, if the registered node is in fact still running.</p> - </note> + specified node from epmd on the localhost. This is however usually not + allowed, unless epmd was started with the -relaxed_command_check + flag, which it normally isn't.</p> + + <p>To unregister a node you have published, you should + close the descriptor that was returned by + <c><![CDATA[ei_publish()]]></c>.</p> + + <warning> + <p>This function is deprecated and will be removed in a future + release.</p> + </warning> <p><c><![CDATA[ec]]></c> is the node structure of the node to unregister.</p> <p>If the node was successfully unregistered from epmd, the function returns 0. Otherwise, it returns -1 and sets diff --git a/lib/erl_interface/doc/src/erl_call.xml b/lib/erl_interface/doc/src/erl_call.xml index 2d88e7616a..c597e11481 100644 --- a/lib/erl_interface/doc/src/erl_call.xml +++ b/lib/erl_interface/doc/src/erl_call.xml @@ -4,7 +4,7 @@ <comref> <header> <copyright> - <year>1996</year><year>2009</year> + <year>1996</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>erl_call</title> @@ -61,7 +61,7 @@ <item> <p>(<em>optional</em>): Applies the specified function and returns the result. <c><![CDATA[Mod]]></c> must be specified, however - <em>[]</em> is assumed for unspecified <c><![CDATA[Fun]]></c> and <c><![CDATA[Args]]></c>. <c><![CDATA[Args]]></c> should + <c>start</c> and <c>[]</c> are assumed for unspecified <c><![CDATA[Fun]]></c> and <c><![CDATA[Args]]></c>, respectively. <c><![CDATA[Args]]></c> should be in the same format as for <c><![CDATA[erlang:apply/3]]></c>. Note that this flag takes exactly one argument, so quoting may be necessary in order to group <c><![CDATA[Mod]]></c>, <c><![CDATA[Fun]]></c> diff --git a/lib/erl_interface/doc/src/erl_connect.xml b/lib/erl_interface/doc/src/erl_connect.xml index b2235925b2..bd5e637244 100644 --- a/lib/erl_interface/doc/src/erl_connect.xml +++ b/lib/erl_interface/doc/src/erl_connect.xml @@ -4,7 +4,7 @@ <cref> <header> <copyright> - <year>1996</year><year>2009</year> + <year>1996</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -451,7 +451,7 @@ typedef struct { <p><c><![CDATA[port]]></c> is the local name to register, and should be the same as the port number that was previously bound to the socket.</p> <p>To unregister with epmd, simply close the returned - descriptor. See also <c><![CDATA[erl_unpublish()]]></c>. + descriptor. </p> <p>On success, the functions return a descriptor connecting the calling process to epmd. On failure, they return -1 and set @@ -507,21 +507,24 @@ typedef struct { </func> <func> <name><ret>int</ret><nametext>erl_unpublish(alive)</nametext></name> - <fsummary>Unpublish a node name</fsummary> + <fsummary>Forcefully unpublish a node name</fsummary> <type> <v>char *alive;</v> </type> <desc> - <p>This function can be called by a process to unregister a - specified node name from epmd on the localhost. This may be - useful, for example, when epmd has not detected the failure of a - node, and will not allow the name to be reused. If you use this - function to unregister your own process, be sure to also close - the descriptor that was returned by <c><![CDATA[erl_publish()]]></c>.</p> - <note> - <p>Careless use of this function may have unpredictable - results, if the registered node is in fact still running.</p> - </note> + <p>This function can be called by a process to unregister a + specified node from epmd on the localhost. This is however usually not + allowed, unless epmd was started with the -relaxed_command_check + flag, which it normally isn't.</p> + + <p>To unregister a node you have published, you should instead + close the descriptor that was returned by + <c><![CDATA[ei_publish()]]></c>.</p> + + <warning> + <p>This function is deprecated and will be removed in a future + release.</p> + </warning> <p><c><![CDATA[alive]]></c> is the name of the node to unregister, i.e., the first component of the nodename, without the <c><![CDATA[@hostname]]></c>.</p> <p>If the node was successfully unregistered from epmd, the diff --git a/lib/erl_interface/doc/src/notes.xml b/lib/erl_interface/doc/src/notes.xml index 14aec4a4d9..8e379463ad 100644 --- a/lib/erl_interface/doc/src/notes.xml +++ b/lib/erl_interface/doc/src/notes.xml @@ -30,6 +30,99 @@ </header> <p>This document describes the changes made to the Erl_interface application.</p> +<section><title>Erl_Interface 3.7.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Removed unused variable in <c>ei_decode_term.c</c>.</p> + <p> + Fixed faulty deallocation in <c>erl_call</c>.</p> + <p> + Own Id: OTP-8748</p> + </item> + <item> + <p>ei_connect: correct man page examples (Thanks to + Michael Santos)</p> + <p> + Own Id: OTP-8813</p> + </item> + <item> + <p>ei: prevent overflow in <c>ei_connect_init</c> and + <c>ei_xconnect</c></p> <p>Add length check of the buffer + before copying. (Thanks to Michael Santos)</p> + <p> + Own Id: OTP-8814</p> + </item> + <item> + <p>Remove DECLSPEC feature which fails on Windows Vista + and use the fallback implementation instead.</p> + <p> + Own Id: OTP-8826</p> + </item> + <item> + <p>erl_call: fix multiple buffer overflows (Thanks to + Michael Santos)</p> + <p> + Own Id: OTP-8827</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>Fix incorrect writev iovec buffer handling in + <c>erl_interface</c> (Thanks to Steve Vinoski)</p> + <p> + Own Id: OTP-8837</p> + </item> + </list> + </section> + +</section> + +<section><title>Erl_Interface 3.7</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>compact IEEE 754 double encoding in external binary + format for ei</p> <list><item><p>Implement the compact + IEEE 754 double encoding in external binary format for + ei. Encoding for ei now always produces the NEW_FLOAT_EXT + format. Decoding and term printing handle both the old + ERL_FLOAT_EXT encoding and the new NEW_FLOAT_EXT + encoding. </p></item> <item><p>Legacy erl_interface code + also handles the new encoding, but still produces the + ERL_FLOAT_EXT encoding by default.</p></item> + <item><p>Also enable the DFLAG_NEW_FLOATS distribution + flag.</p></item> <item><p>ei_get_type() will return + ERL_FLOAT_EXT regardless if the external format is + encoded with ERL_FLOAT_EXT or NEW_FLOAT_EXT for + doubles.</p></item> <item><p>Reduce the number of copies + of the code for encoding and decoding doubles throughout + ei and erl_interface by instead calling the ei encoding + and decoding functions wherever possible.</p></item> + <item><p>Restore commented-out float tests in + ei_decode_SUITE and ei_encode_SUITE in + lib/erl_interface/test. Modify them to make them match + the style of other tests in the same suites.</p></item> + </list> <p>These changes are based on an ei float patch + from Serge Aleynikov originally submitted against R12B-2 + in July 2008 and reworked by Steve Vinoski May 2010.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-8684</p> + </item> + </list> + </section> + +</section> + <section><title>Erl_Interface 3.6.5</title> <section><title>Improvements and New Features</title> diff --git a/lib/erl_interface/include/ei.h b/lib/erl_interface/include/ei.h index d1a697615a..466d84bb99 100644 --- a/lib/erl_interface/include/ei.h +++ b/lib/erl_interface/include/ei.h @@ -1,19 +1,19 @@ /* * %CopyrightBegin% - * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. - * + * + * Copyright Ericsson AB 1998-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% */ #ifndef EI_H @@ -110,6 +110,7 @@ #define ERL_SMALL_INTEGER_EXT 'a' #define ERL_INTEGER_EXT 'b' #define ERL_FLOAT_EXT 'c' +#define NEW_FLOAT_EXT 'F' #define ERL_ATOM_EXT 'd' #define ERL_REFERENCE_EXT 'e' #define ERL_NEW_REFERENCE_EXT 'r' @@ -718,11 +719,9 @@ int ei_x_encode_bignum(ei_x_buff *x, mpz_t obj); #define EI_LONGLONG __int64 #define EI_ULONGLONG unsigned __int64 #else -#ifndef VXWORKS #define EI_LONGLONG long long #define EI_ULONGLONG unsigned long long #endif -#endif #ifndef VXWORKS int ei_decode_longlong(const char *buf, int *index, EI_LONGLONG *p); diff --git a/lib/erl_interface/src/connect/ei_connect.c b/lib/erl_interface/src/connect/ei_connect.c index d2d0a7e7c1..99ccba0686 100644 --- a/lib/erl_interface/src/connect/ei_connect.c +++ b/lib/erl_interface/src/connect/ei_connect.c @@ -1,19 +1,19 @@ /* * %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 * 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% */ /* @@ -366,16 +366,16 @@ static int initWinSock(void) WORD wVersionRequested; WSADATA wsaData; int i; - /* FIXME problem for threaded ? */ - static int initialized = 0; + + static LONG volatile initialized = 0; wVersionRequested = MAKEWORD(1, 1); - if (!initialized) { - initialized = 1; + if (InterlockedCompareExchange((LPLONG) &initialized,1L,0L) == 0L) { /* FIXME not terminate, just a message?! */ if ((i = WSAStartup(wVersionRequested, &wsaData))) { EI_TRACE_ERR1("ei_connect_init", "ERROR: can't initialize windows sockets: %d",i); + initialized = 2L; return 0; } @@ -383,10 +383,14 @@ static int initWinSock(void) EI_TRACE_ERR0("initWinSock","ERROR: this version of windows " "sockets not supported"); WSACleanup(); + initialized = 2L; return 0; } + initialized = 3L; + } else while (initialized < 2) { + SwitchToThread(); } - return 1; + return (int) (initialized - 2); } #endif @@ -502,10 +506,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 @@ -1323,7 +1331,8 @@ static int send_name_or_challenge(int fd, char *nodename, put32be(s, (DFLAG_EXTENDED_REFERENCES | DFLAG_EXTENDED_PIDS_PORTS | DFLAG_FUN_TAGS - | DFLAG_NEW_FUN_TAGS)); + | DFLAG_NEW_FUN_TAGS + | DFLAG_NEW_FLOATS)); if (f_chall) put32be(s, challenge); memcpy(s, nodename, strlen(nodename)); @@ -1393,6 +1402,11 @@ static int recv_challenge(int fd, unsigned *challenge, goto error; } + if (!(*flags & DFLAG_NEW_FLOATS)) { + EI_TRACE_ERR0("recv_challenge","<- RECV_CHALLENGE peer cannot " + "handle binary float encoding"); + goto error; + } if (getpeername(fd, (struct sockaddr *) &sin, &sin_len) < 0) { EI_TRACE_ERR0("recv_challenge","<- RECV_CHALLENGE can't get peername"); diff --git a/lib/erl_interface/src/connect/ei_connect_int.h b/lib/erl_interface/src/connect/ei_connect_int.h index 9926f799df..3c42b49b82 100644 --- a/lib/erl_interface/src/connect/ei_connect_int.h +++ b/lib/erl_interface/src/connect/ei_connect_int.h @@ -1,19 +1,19 @@ /* * %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 * 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% */ /* @@ -101,6 +101,7 @@ extern int h_errno; #define DFLAG_FUN_TAGS 16 #define DFLAG_NEW_FUN_TAGS 0x80 #define DFLAG_EXTENDED_PIDS_PORTS 0x100 +#define DFLAG_NEW_FLOATS 0x800 ei_cnode *ei_fd_to_cnode(int fd); int ei_distversion(int fd); diff --git a/lib/erl_interface/src/connect/ei_resolve.c b/lib/erl_interface/src/connect/ei_resolve.c index 42aeab22b1..24a030c468 100644 --- a/lib/erl_interface/src/connect/ei_resolve.c +++ b/lib/erl_interface/src/connect/ei_resolve.c @@ -601,7 +601,7 @@ struct hostent *ei_gethostbyaddr_r(const char *addr, #ifndef HAVE_GETHOSTBYNAME_R return my_gethostbyaddr_r(addr,length,type,hostp,buffer,buflen,h_errnop); #else -#if (defined(__GLIBC__) || (__FreeBSD_version >= 602000)) +#if (defined(__GLIBC__) || (__FreeBSD_version >= 602000) || defined(__DragonFly__)) struct hostent *result; gethostbyaddr_r(addr, length, type, hostp, buffer, buflen, &result, @@ -628,7 +628,7 @@ struct hostent *ei_gethostbyname_r(const char *name, #ifndef HAVE_GETHOSTBYNAME_R return my_gethostbyname_r(name,hostp,buffer,buflen,h_errnop); #else -#if (defined(__GLIBC__) || (__FreeBSD_version >= 602000)) +#if (defined(__GLIBC__) || (__FreeBSD_version >= 602000) || defined(__DragonFly__)) struct hostent *result; gethostbyname_r(name, hostp, buffer, buflen, &result, h_errnop); diff --git a/lib/erl_interface/src/decode/decode_double.c b/lib/erl_interface/src/decode/decode_double.c index 66dbe474ec..ed6e39655e 100644 --- a/lib/erl_interface/src/decode/decode_double.c +++ b/lib/erl_interface/src/decode/decode_double.c @@ -1,19 +1,19 @@ /* * %CopyrightBegin% - * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. - * + * + * Copyright Ericsson AB 1998-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 <stdio.h> @@ -26,14 +26,22 @@ int ei_decode_double(const char *buf, int *index, double *p) { const char *s = buf + *index; const char *s0 = s; - double f; + FloatExt f; - if (get8(s) != ERL_FLOAT_EXT) return -1; - - if (sscanf(s, "%lf", &f) != 1) return -1; + switch (get8(s)) { + case ERL_FLOAT_EXT: + if (sscanf(s, "%lf", &f.d) != 1) return -1; + s += 31; + break; + case NEW_FLOAT_EXT: + /* IEEE 754 format */ + f.val = get64be(s); + break; + default: + return -1; + } - s += 31; - if (p) *p = f; + if (p) *p = f.d; *index += s-s0; return 0; } diff --git a/lib/erl_interface/src/decode/decode_skip.c b/lib/erl_interface/src/decode/decode_skip.c index 316b5bee98..f6c5d861ab 100644 --- a/lib/erl_interface/src/decode/decode_skip.c +++ b/lib/erl_interface/src/decode/decode_skip.c @@ -1,19 +1,19 @@ /* * %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 * 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 "eidef.h" @@ -77,6 +77,7 @@ int ei_skip_term(const char* buf, int* index) if (ei_decode_big(buf, index, NULL) < 0) return -1; break; case ERL_FLOAT_EXT: + case NEW_FLOAT_EXT: if (ei_decode_double(buf, index, NULL) < 0) return -1; break; case ERL_FUN_EXT: diff --git a/lib/erl_interface/src/encode/encode_double.c b/lib/erl_interface/src/encode/encode_double.c index 53f3d52ba6..148a49f73a 100644 --- a/lib/erl_interface/src/encode/encode_double.c +++ b/lib/erl_interface/src/encode/encode_double.c @@ -1,19 +1,19 @@ /* * %CopyrightBegin% - * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. - * + * + * Copyright Ericsson AB 1998-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 <stdio.h> @@ -27,13 +27,13 @@ int ei_encode_double(char *buf, int *index, double p) char *s = buf + *index; char *s0 = s; - if (!buf) s ++; + if (!buf) + s += 9; else { - put8(s,ERL_FLOAT_EXT); - memset(s, 0, 31); - sprintf(s, "%.20e", p); + /* IEEE 754 format */ + put8(s, NEW_FLOAT_EXT); + put64be(s, ((FloatExt*)&p)->val); } - s += 31; *index += s-s0; diff --git a/lib/erl_interface/src/epmd/ei_epmd.h b/lib/erl_interface/src/epmd/ei_epmd.h index 40e5ece572..ccacfed244 100644 --- a/lib/erl_interface/src/epmd/ei_epmd.h +++ b/lib/erl_interface/src/epmd/ei_epmd.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * Copyright Ericsson AB 1998-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 @@ -40,20 +40,13 @@ #define EI_MYPROTO 0 /* tcp/ip */ #endif -/* epmd r3 protocol */ -#ifndef EI_EPMD_ALIVE_REQ -#define EI_EPMD_ALIVE_REQ 'a' -#define EI_EPMD_ALIVE_OK_RESP 'Y' -#define EI_EPMD_PORT_REQ 'p' -#define EI_EPMD_STOP_REQ 's' -#endif - /* epmd r4 */ #ifndef EI_EPMD_ALIVE2_REQ #define EI_EPMD_ALIVE2_REQ 120 #define EI_EPMD_ALIVE2_RESP 121 #define EI_EPMD_PORT2_REQ 122 #define EI_EPMD_PORT2_RESP 119 +#define EI_EPMD_STOP_REQ 's' #endif /* internal functions */ diff --git a/lib/erl_interface/src/epmd/epmd_port.c b/lib/erl_interface/src/epmd/epmd_port.c index 663b38d2d4..698c75c217 100644 --- a/lib/erl_interface/src/epmd/epmd_port.c +++ b/lib/erl_interface/src/epmd/epmd_port.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * Copyright Ericsson AB 1998-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 @@ -92,64 +92,6 @@ int ei_epmd_connect_tmo(struct in_addr *inaddr, unsigned ms) return sd; } -/* get the given node's listen port using old epmd protocol */ -static int ei_epmd_r3_port (struct in_addr *addr, const char *alive, - unsigned ms) -{ - char buf[EPMDBUF]; - char *s = buf; - int len = strlen(alive) + 1; - int fd; - int port; - int res; -#if defined(VXWORKS) - char ntoabuf[32]; -#endif - - put16be(s,len); - put8(s,EI_EPMD_PORT_REQ); - strcpy(s,alive); - - /* connect to epmd */ - if ((fd = ei_epmd_connect_tmo(addr,ms)) < 0) - { - /* ei_epmd_connect_tmo() sets erl_errno */ - return -1; - } - - if ((res = ei_write_fill_t(fd, buf, len+2, ms)) != len+2) { - closesocket(fd); - erl_errno = (res == -2) ? ETIMEDOUT : EIO; - return -1; - } - -#ifdef VXWORKS - /* FIXME use union/macro for level. Correct level? */ - if (ei_tracelevel > 2) { - inet_ntoa_b(*addr,ntoabuf); - EI_TRACE_CONN2("ei_epmd_r3_port", - "-> PORT_REQ alive=%s ip=%s",alive,ntoabuf); - } -#else - EI_TRACE_CONN2("ei_epmd_r3_port", - "-> PORT_REQ alive=%s ip=%s",alive,inet_ntoa(*addr)); -#endif - - if ((res = ei_read_fill_t(fd, buf, 2, ms)) != 2) { - EI_TRACE_ERR0("ei_epmd_r3_port","<- CLOSE"); - closesocket(fd); - erl_errno = (res == -2) ? ETIMEDOUT : EIO; - return -1; - } - closesocket(fd); - s = buf; - port = get16be(s); - - EI_TRACE_CONN1("ei_epmd_r3_port","<- PORT_RESP port=%d",port); - - return port; -} - static int ei_epmd_r4_port (struct in_addr *addr, const char *alive, int *dist, unsigned ms) { @@ -164,6 +106,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); @@ -285,15 +233,6 @@ int ei_epmd_port_tmo (struct in_addr *addr, const char *alive, int *dist, { int i; - /* try the new one first, then the old one */ - i = ei_epmd_r4_port(addr,alive,dist,ms); - - /* -2: new protocol not understood */ - if (i == -2) { - *dist = 0; - i = ei_epmd_r3_port(addr,alive,ms); - } - - return i; + return ei_epmd_r4_port(addr,alive,dist,ms); } diff --git a/lib/erl_interface/src/epmd/epmd_publish.c b/lib/erl_interface/src/epmd/epmd_publish.c index 09b3dce43b..a9b8727747 100644 --- a/lib/erl_interface/src/epmd/epmd_publish.c +++ b/lib/erl_interface/src/epmd/epmd_publish.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * Copyright Ericsson AB 1998-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 @@ -55,62 +55,6 @@ /* publish our listen port and alive name */ /* return the (useless) creation number */ -static int ei_epmd_r3_publish (int port, const char *alive, unsigned ms) -{ - char buf[EPMDBUF]; - char *s = buf; - int fd; - int len = strlen(alive) + 3; - int res,creation; - - s = buf; - put16be(s,len); - put8(s,EI_EPMD_ALIVE_REQ); - put16be(s,port); - strcpy(s, alive); - - if ((fd = ei_epmd_connect_tmo(NULL,ms)) < 0) return fd; - - if ((res = ei_write_fill_t(fd, buf, len+2, ms)) != len+2) { - closesocket(fd); - erl_errno = (res == -2) ? ETIMEDOUT : EIO; - return -1; - } - - EI_TRACE_CONN2("ei_epmd_r3_publish", - "-> ALIVE_REQ alive=%s port=%d",alive,port); - - if ((res = ei_read_fill_t(fd, buf, 3, ms)) != 3) { - closesocket(fd); - erl_errno = (res == -2) ? ETIMEDOUT : EIO; - return -1; - } - - s = buf; - if ((res=get8(s)) != EI_EPMD_ALIVE_OK_RESP) { - EI_TRACE_ERR1("ei_epmd_r3_publish", - "<- ALIVE_NOK result=%d (failure)",res); - closesocket(fd); - erl_errno = EIO; - return -1; - } - - creation = get16be(s); - - EI_TRACE_CONN1("ei_epmd_r3_publish","<- ALIVE_OK creation=%d",creation); - - /* Don't close fd here! It keeps us registered with epmd */ - - /* probably should save fd so we can close it later... */ - /* epmd_saveconn(OPEN,fd,alive); */ - - /* return the creation number, for no good reason */ - /* return creation; */ - - /* no! return the descriptor */ - return fd; -} - /* publish our listen port and alive name */ /* return the (useless) creation number */ /* this protocol is a lot more complex than the old one */ @@ -200,15 +144,7 @@ int ei_epmd_publish(int port, const char *alive) int ei_epmd_publish_tmo(int port, const char *alive, unsigned ms) { - int i; - - /* try the new one first, then the old one */ - i = ei_epmd_r4_publish(port,alive, ms); - - /* -2: new protocol not understood */ - if (i == -2) i = ei_epmd_r3_publish(port,alive, ms); - - return i; + return ei_epmd_r4_publish(port,alive, ms);; } diff --git a/lib/erl_interface/src/legacy/decode_term.c b/lib/erl_interface/src/legacy/decode_term.c index ef29d6f57d..796cebdfef 100644 --- a/lib/erl_interface/src/legacy/decode_term.c +++ b/lib/erl_interface/src/legacy/decode_term.c @@ -1,19 +1,19 @@ /* * %CopyrightBegin% - * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. - * + * + * Copyright Ericsson AB 1998-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 "eidef.h" @@ -59,6 +59,7 @@ int ei_decode_term(const char *buf, int *index, void *t) return ei_decode_long(buf,index,NULL); case ERL_FLOAT_EXT: + case NEW_FLOAT_EXT: return ei_decode_double(buf,index,NULL); case ERL_ATOM_EXT: diff --git a/lib/erl_interface/src/legacy/erl_marshal.c b/lib/erl_interface/src/legacy/erl_marshal.c index 4b5f28178f..18315bfbd3 100644 --- a/lib/erl_interface/src/legacy/erl_marshal.c +++ b/lib/erl_interface/src/legacy/erl_marshal.c @@ -1,19 +1,19 @@ /* * %CopyrightBegin% - * - * Copyright Ericsson AB 1996-2009. All Rights Reserved. - * + * + * Copyright Ericsson AB 1996-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% */ /* @@ -26,6 +26,7 @@ #include <ctype.h> #include <sys/types.h> #include <string.h> +#include <limits.h> #include "erl_interface.h" #include "erl_marshal.h" @@ -102,6 +103,7 @@ void erl_init_marshal(void) cmp_array[ERL_SMALL_INTEGER_EXT] = 1; cmp_array[ERL_INTEGER_EXT] = 1; cmp_array[ERL_FLOAT_EXT] = 1; + cmp_array[NEW_FLOAT_EXT] = 1; cmp_array[ERL_SMALL_BIG_EXT] = 1; cmp_array[ERL_LARGE_BIG_EXT] = 1; cmp_array[ERL_ATOM_EXT] = 2; @@ -124,6 +126,7 @@ void erl_init_marshal(void) cmp_num_class[ERL_SMALL_INTEGER_EXT] = SMALL; cmp_num_class[ERL_INTEGER_EXT] = SMALL; cmp_num_class[ERL_FLOAT_EXT] = FLOAT; + cmp_num_class[NEW_FLOAT_EXT] = FLOAT; cmp_num_class[ERL_SMALL_BIG_EXT] = BIG; cmp_num_class[ERL_LARGE_BIG_EXT] = BIG; init_cmp_num_class_p = 0; @@ -176,26 +179,14 @@ int erl_encode_it(ETERM *ep, unsigned char **ext, int dist) return 0; case ERL_INTEGER: - i = ep->uval.ival.i; - /* ERL_SMALL_BIG */ - if ((i > ERL_MAX) || (i < ERL_MIN)) { - *(*ext)++ = ERL_SMALL_BIG_EXT; - *(*ext)++ = 4; /* four bytes */ - if ((*(*ext)++ = ((i>>31) & 0x01))) /* sign byte */ - i = -i; - *(*ext)++ = i & 0xff; /* LSB first */ - *(*ext)++ = (i >> 8) & 0xff; - *(*ext)++ = (i >> 16) & 0xff; - *(*ext)++ = (i >> 24) & 0x7f; /* Don't include the sign bit */ - return 0; - } + i = ep->uval.ival.i; /* SMALL_INTEGER */ if ((i < 256) && (i >= 0)) { *(*ext)++ = ERL_SMALL_INTEGER_EXT; *(*ext)++ = i & 0xff; return 0; } - /* INTEGER */ + /* R14B: Use all 32 bits of INTEGER_EXT */ *(*ext)++ = ERL_INTEGER_EXT; *(*ext)++ = (i >> 24) & 0xff; *(*ext)++ = (i >> 16) & 0xff; @@ -206,23 +197,23 @@ int erl_encode_it(ETERM *ep, unsigned char **ext, int dist) case ERL_U_INTEGER: u = ep->uval.uival.u; /* ERL_U_SMALL_BIG */ - if (u > ERL_MAX) { - *(*ext)++ = ERL_SMALL_BIG_EXT; - *(*ext)++ = 4; /* four bytes */ - *(*ext)++ = 0; /* sign byte */ - *(*ext)++ = u & 0xff; /* LSB first */ - *(*ext)++ = (u >> 8) & 0xff; - *(*ext)++ = (u >> 16) & 0xff; - *(*ext)++ = (u >> 24) & 0xff; - return 0; + if ((int)u < 0) { + *(*ext)++ = ERL_SMALL_BIG_EXT; + *(*ext)++ = 4; /* four bytes */ + *(*ext)++ = 0; /* sign byte */ + *(*ext)++ = u & 0xff; /* LSB first */ + *(*ext)++ = (u >> 8) & 0xff; + *(*ext)++ = (u >> 16) & 0xff; + *(*ext)++ = (u >> 24) & 0xff; + return 0; } /* SMALL_INTEGER */ - if ((u < 256) && (u >= 0)) { + if (u < 256) { *(*ext)++ = ERL_SMALL_INTEGER_EXT; *(*ext)++ = u & 0xff; return 0; } - /* INTEGER */ + /* R14B: Use all 32 bits of INTEGER_EXT */ *(*ext)++ = ERL_INTEGER_EXT; *(*ext)++ = (u >> 24) & 0xff; *(*ext)++ = (u >> 16) & 0xff; @@ -232,29 +223,28 @@ int erl_encode_it(ETERM *ep, unsigned char **ext, int dist) case ERL_LONGLONG: l = ep->uval.llval.i; /* ERL_SMALL_BIG */ - if ((l > ((long long) ERL_MAX)) || - (l < ((long long) ERL_MIN))) { - *(*ext)++ = ERL_SMALL_BIG_EXT; - *(*ext)++ = 8; /* eight bytes */ - if ((*(*ext)++ = ((l>>63) & 0x01))) /* sign byte */ + if (l > ((long long) INT_MAX) || l < ((long long) INT_MIN)) { + *(*ext)++ = ERL_SMALL_BIG_EXT; + *(*ext)++ = 8; + if ((*(*ext)++ = (l<0))) /* sign byte */ l = -l; - *(*ext)++ = l & 0xff; /* LSB first */ + *(*ext)++ = l & 0xff; /* LSB first */ *(*ext)++ = (l >> 8) & 0xff; *(*ext)++ = (l >> 16) & 0xff; - *(*ext)++ = (l >> 24) & 0xff; - *(*ext)++ = (l >> 32) & 0xff; - *(*ext)++ = (l >> 40) & 0xff; - *(*ext)++ = (l >> 48) & 0xff; - *(*ext)++ = (l >> 56) & 0x7f; /* Don't include the sign bit */ + *(*ext)++ = (l >> 24) & 0xff; + *(*ext)++ = (l >> 32) & 0xff; + *(*ext)++ = (l >> 40) & 0xff; + *(*ext)++ = (l >> 48) & 0xff; + *(*ext)++ = (l >> 56) & 0xff; return 0; } /* SMALL_INTEGER */ if ((l < 256) && (l >= 0)) { - *(*ext)++ = ERL_SMALL_INTEGER_EXT; - *(*ext)++ = l & 0xff; - return 0; + *(*ext)++ = ERL_SMALL_INTEGER_EXT; + *(*ext)++ = l & 0xff; + return 0; } - /* INTEGER */ + /* R14B: Use all 32 bits of INTEGER_EXT */ *(*ext)++ = ERL_INTEGER_EXT; *(*ext)++ = (l >> 24) & 0xff; *(*ext)++ = (l >> 16) & 0xff; @@ -265,7 +255,7 @@ int erl_encode_it(ETERM *ep, unsigned char **ext, int dist) case ERL_U_LONGLONG: ul = ep->uval.ullval.u; /* ERL_U_SMALL_BIG */ - if (ul > ((unsigned long long) ERL_MAX)) { + if (ul > ((unsigned long long) INT_MAX)) { *(*ext)++ = ERL_SMALL_BIG_EXT; *(*ext)++ = 8; /* eight bytes */ *(*ext)++ = 0; /* sign byte */ @@ -285,7 +275,7 @@ int erl_encode_it(ETERM *ep, unsigned char **ext, int dist) *(*ext)++ = ul & 0xff; return 0; } - /* INTEGER */ + /* R14B: Use all 32 bits of INTEGER_EXT */ *(*ext)++ = ERL_INTEGER_EXT; *(*ext)++ = (ul >> 24) & 0xff; *(*ext)++ = (ul >> 16) & 0xff; @@ -730,11 +720,6 @@ static ETERM *erl_decode_it(unsigned char **ext) if (arity > 8) goto big_truncate; - if (arity == 8 && ((*ext)[7] & 0x80) && sign) { - /* MSB already occupied ! */ - goto big_truncate; - } - if (arity == 4 && ((*ext)[3] & 0x80) && !sign) { /* It will fit into an unsigned int !! */ u = (((*ext)[3] << 24)|((*ext)[2])<< 16|((*ext)[1]) << 8 |(**ext)); @@ -745,14 +730,10 @@ static ETERM *erl_decode_it(unsigned char **ext) return ep; } else if (arity == 4 && !((*ext)[3] & 0x80)) { /* It will fit into an int !! - * Note: It comes in "one's-complement notation" */ - if (sign) - i = (int) (~(((*ext)[3] << 24) | ((*ext)[2])<< 16 | - ((*ext)[1]) << 8 | (**ext)) | (unsigned int) sign); - else - i = (int) (((*ext)[3] << 24) | ((*ext)[2])<< 16 | - ((*ext)[1]) << 8 | (**ext)); + i = (int) (((*ext)[3] << 24) | ((*ext)[2])<< 16 | + ((*ext)[1]) << 8 | (**ext)); + if (sign) i = -i; ERL_TYPE(ep) = ERL_INTEGER; ep->uval.ival.i = i; *ext += arity; @@ -778,8 +759,10 @@ static ETERM *erl_decode_it(unsigned char **ext) for(x = 0 ; x < arity ; x++) { l |= ((long long)(*ext)[x]) << ((long long)(8*x)); } - - if (sign) l = (long long) (~l | (unsigned long long) sign); + if (sign) { + l = -l; + if (l > 0) goto big_truncate; + } ERL_TYPE(ep) = ERL_LONGLONG; ep->uval.llval.i = l; @@ -1008,10 +991,13 @@ static ETERM *erl_decode_it(unsigned char **ext) return ep; case ERL_FLOAT_EXT: + case NEW_FLOAT_EXT: ERL_TYPE(ep) = ERL_FLOAT; - if (sscanf((char *) *ext, "%lf", &ff) != 1) + cp = (char *) *ext; + i = -1; + if (ei_decode_double(cp, &i, &ff) == -1) goto failure; - *ext += 31; + *ext += i; ep->uval.fval.f = ff; return ep; @@ -1176,6 +1162,7 @@ unsigned char erl_ext_type(unsigned char *ext) case ERL_LARGE_TUPLE_EXT: return ERL_TUPLE; case ERL_FLOAT_EXT: + case NEW_FLOAT_EXT: return ERL_FLOAT; case ERL_BINARY_EXT: return ERL_BINARY; @@ -1218,6 +1205,7 @@ int erl_ext_size(unsigned char *t) case ERL_BINARY_EXT: case ERL_STRING_EXT: case ERL_FLOAT_EXT: + case NEW_FLOAT_EXT: case ERL_SMALL_BIG_EXT: case ERL_LARGE_BIG_EXT: return 0; @@ -1332,6 +1320,9 @@ static int jump(unsigned char **ext) case ERL_FLOAT_EXT: *ext += 31; break; + case NEW_FLOAT_EXT: + *ext += 8; + break; case ERL_BINARY_EXT: i = (**ext << 24) | ((*ext)[1] << 16) |((*ext)[2] << 8) | (*ext)[3]; *ext += 4+i; @@ -1696,12 +1687,15 @@ static int cmp_exe2(unsigned char **e1, unsigned char **e2) } return 0; case ERL_FLOAT_EXT: - if (sscanf((char *) *e1, "%lf", &ff1) != 1) - return -1; - *e1 += 31; - if (sscanf((char *) *e2, "%lf", &ff2) != 1) - return -1; - *e2 += 31; + case NEW_FLOAT_EXT: + i = -1; + if (ei_decode_double((char *) *e1, &i, &ff1) != 0) + return -1; + *e1 += i; + j = -1; + if (ei_decode_double((char *) *e2, &j, &ff2) != 0) + return -1; + *e2 += j; return cmp_floats(ff1,ff2); case ERL_BINARY_EXT: diff --git a/lib/erl_interface/src/misc/ei_decode_term.c b/lib/erl_interface/src/misc/ei_decode_term.c index 7b95ff232f..75c5dc9460 100644 --- a/lib/erl_interface/src/misc/ei_decode_term.c +++ b/lib/erl_interface/src/misc/ei_decode_term.c @@ -1,19 +1,19 @@ /* * %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 * 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% * @@ -25,16 +25,15 @@ #include "ei_decode_term.h" #include "putget.h" -/* Returns 1 if term is decoded, 0 if term is OK, but not decoded here - and -1 if something is wrong. - ONLY changes index if term is decoded (return value 1)! */ +/* Returns 0 on successful encoding, -1 on error, and 1 if the term seems + alright, but does not fit in the term structure. If it returns 0, the + index will be incremented, and the term contains the decoded term. */ int ei_decode_ei_term(const char* buf, int* index, ei_term* term) { const char* s = buf + *index, * s0 = s; int len, i, n, sign; char c; - double f; if (term == NULL) return -1; c = term->ei_type = get8(s); @@ -46,11 +45,8 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term) term->value.i_val = get32be(s); break; case ERL_FLOAT_EXT: - if (s[30]) return -1; - if (sscanf(s, "%lf", &f) != 1) return -1; - s += 31; - term->value.d_val = f; - break; + case NEW_FLOAT_EXT: + return ei_decode_double(buf, index, &term->value.d_val); case ERL_ATOM_EXT: len = get16be(s); memcpy(term->value.atom_name, s, len); diff --git a/lib/erl_interface/src/misc/ei_portio.c b/lib/erl_interface/src/misc/ei_portio.c index b73ebebbe1..c4e397f1e0 100644 --- a/lib/erl_interface/src/misc/ei_portio.c +++ b/lib/erl_interface/src/misc/ei_portio.c @@ -171,6 +171,8 @@ int ei_writev_fill_t(int fd, const struct iovec *iov, int iovcnt, unsigned } while (i > 0) { if (i < current_iov[0].iov_len) { + char *p = (char*)current_iov[0].iov_base; + current_iov[0].iov_base = p + i; current_iov[0].iov_len -= i; i = 0; } else { diff --git a/lib/erl_interface/src/misc/ei_printterm.c b/lib/erl_interface/src/misc/ei_printterm.c index 8d0eef5e79..98473f780e 100644 --- a/lib/erl_interface/src/misc/ei_printterm.c +++ b/lib/erl_interface/src/misc/ei_printterm.c @@ -1,19 +1,19 @@ /* * %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 * 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% * @@ -272,6 +272,7 @@ static int print_term(FILE* fp, ei_x_buff* x, break; case ERL_FLOAT_EXT: + case NEW_FLOAT_EXT: if (ei_decode_double(buf, index, &d) < 0) goto err; ch_written += xprintf(fp, x, "%f", d); break; diff --git a/lib/erl_interface/src/misc/get_type.c b/lib/erl_interface/src/misc/get_type.c index d67a6a80d3..2a680d0f94 100644 --- a/lib/erl_interface/src/misc/get_type.c +++ b/lib/erl_interface/src/misc/get_type.c @@ -1,19 +1,19 @@ /* * %CopyrightBegin% - * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. - * + * + * Copyright Ericsson AB 1998-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% * @@ -122,7 +122,12 @@ int ei_get_type_internal(const char *buf, const int *index, case ERL_STRING_EXT: *len = get16be(s); break; - + + case ERL_FLOAT_EXT: + case NEW_FLOAT_EXT: + *type = ERL_FLOAT_EXT; + break; + case ERL_LARGE_TUPLE_EXT: case ERL_LIST_EXT: case ERL_BINARY_EXT: diff --git a/lib/erl_interface/src/misc/putget.h b/lib/erl_interface/src/misc/putget.h index 98d9ebb64c..7a43de324b 100644 --- a/lib/erl_interface/src/misc/putget.h +++ b/lib/erl_interface/src/misc/putget.h @@ -1,19 +1,19 @@ /* * %CopyrightBegin% - * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. - * + * + * Copyright Ericsson AB 1998-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% * @@ -54,6 +54,18 @@ (s) += 4; \ } while (0) +#define put64be(s,n) do { \ + (s)[0] = ((n) >> 56) & 0xff; \ + (s)[1] = ((n) >> 48) & 0xff; \ + (s)[2] = ((n) >> 40) & 0xff; \ + (s)[3] = ((n) >> 32) & 0xff; \ + (s)[4] = ((n) >> 24) & 0xff; \ + (s)[5] = ((n) >> 16) & 0xff; \ + (s)[6] = ((n) >> 8) & 0xff; \ + (s)[7] = (n) & 0xff; \ + (s) += 8; \ +} while (0) + #define get8(s) \ ((s) += 1, \ ((unsigned char *)(s))[-1] & 0xff) @@ -82,4 +94,20 @@ (((unsigned char *)(s))[-2] << 8) | \ ((unsigned char *)(s))[-1])) +#define get64be(s) \ + ((s) += 8, \ + (((EI_ULONGLONG)((unsigned char *)(s))[-8] << 56) | \ + ((EI_ULONGLONG)((unsigned char *)(s))[-7] << 48) | \ + ((EI_ULONGLONG)((unsigned char *)(s))[-6] << 40) | \ + ((EI_ULONGLONG)((unsigned char *)(s))[-5] << 32) | \ + ((EI_ULONGLONG)((unsigned char *)(s))[-4] << 24) | \ + ((EI_ULONGLONG)((unsigned char *)(s))[-3] << 16) | \ + ((EI_ULONGLONG)((unsigned char *)(s))[-2] << 8) | \ + (EI_ULONGLONG)((unsigned char *)(s))[-1])) + +typedef union float_ext { + double d; + EI_ULONGLONG val; +} FloatExt; + #endif /* _PUTGET_H */ diff --git a/lib/erl_interface/src/misc/show_msg.c b/lib/erl_interface/src/misc/show_msg.c index 25865d6f8e..14bea5e01f 100644 --- a/lib/erl_interface/src/misc/show_msg.c +++ b/lib/erl_interface/src/misc/show_msg.c @@ -1,19 +1,19 @@ /* * %CopyrightBegin% - * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. - * + * + * Copyright Ericsson AB 1998-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% * @@ -400,6 +400,7 @@ static void show_term(const char *termbuf, int *index, FILE *stream) break; case ERL_FLOAT_EXT: + case NEW_FLOAT_EXT: ei_decode_double(termbuf,index,&fnum); fprintf(stream,"%f",fnum); break; diff --git a/lib/erl_interface/src/prog/erl_call.c b/lib/erl_interface/src/prog/erl_call.c index f0d638324d..448de9aa23 100644 --- a/lib/erl_interface/src/prog/erl_call.c +++ b/lib/erl_interface/src/prog/erl_call.c @@ -123,6 +123,10 @@ static int do_connect(ei_cnode *ec, char *nodename, struct call_flags *flags); static int read_stdin(char **buf); static void split_apply_string(char *str, char **mod, char **fun, char **args); +static void* ei_chk_malloc(size_t size); +static void* ei_chk_calloc(size_t nmemb, size_t size); +static void* ei_chk_realloc(void *old, size_t size); +static char* ei_chk_strdup(char *s); /*************************************************************************** @@ -132,7 +136,6 @@ static void split_apply_string(char *str, char **mod, ***************************************************************************/ /* FIXME isn't VxWorks to handle arguments differently? */ -/* FIXME check errors from malloc */ #if !defined(VXWORKS) int main(int argc, char *argv[]) @@ -165,8 +168,7 @@ int erl_call(int argc, char **argv) usage_arg(progname, "-sname "); } - flags.node = (char *) malloc(strlen(argv[i+1]) + 1); - strcpy(flags.node, argv[i+1]); + flags.node = ei_chk_strdup(argv[i+1]); i++; flags.use_long_name = 0; } else if (strcmp(argv[i], "-name") == 0) { /* -name NAME */ @@ -174,8 +176,7 @@ int erl_call(int argc, char **argv) usage_arg(progname, "-name "); } - flags.node = (char *) malloc(strlen(argv[i+1]) + 1); - strcpy(flags.node, argv[i+1]); + flags.node = ei_chk_strdup(argv[i+1]); i++; flags.use_long_name = 1; } else { @@ -210,16 +211,14 @@ int erl_call(int argc, char **argv) usage_arg(progname, "-c "); } flags.cookiep = 1; - flags.cookie = (char *) malloc(strlen(argv[i+1]) + 1); - strcpy(flags.cookie, argv[i+1]); + flags.cookie = ei_chk_strdup(argv[i+1]); i++; break; case 'n': if (i+1 >= argc) { usage_arg(progname, "-n "); } - flags.node = (char *) malloc(strlen(argv[i+1]) + 1); - strcpy(flags.node, argv[i+1]); + flags.node = ei_chk_strdup(argv[i+1]); flags.use_long_name = 1; i++; break; @@ -227,24 +226,21 @@ int erl_call(int argc, char **argv) if (i+1 >= argc) { usage_arg(progname, "-h "); } - flags.hidden = (char *) malloc(strlen(argv[i+1]) + 1); - strcpy(flags.hidden, argv[i+1]); + flags.hidden = ei_chk_strdup(argv[i+1]); i++; break; case 'x': if (i+1 >= argc) { usage_arg(progname, "-x "); } - flags.script = (char *) malloc(strlen(argv[i+1]) + 1); - strcpy(flags.script, argv[i+1]); + flags.script = ei_chk_strdup(argv[i+1]); i++; break; case 'a': if (i+1 >= argc) { usage_arg(progname, "-a "); } - flags.apply = (char *) malloc(strlen(argv[i+1]) + 1); - strcpy(flags.apply, argv[i+1]); + flags.apply = ei_chk_strdup(argv[i+1]); i++; break; case '?': @@ -304,8 +300,7 @@ int erl_call(int argc, char **argv) if (flags.hidden == NULL) { /* As default we are c17@gethostname */ i = flags.randomp ? (time(NULL) % 997) : 17; - /* FIXME allocates to small !!! */ - flags.hidden = (char *) malloc(3 + 2 ); /* c17 or cXYZ */ + flags.hidden = (char *) ei_chk_malloc(10 + 2 ); /* c17 or cXYZ */ #if defined(VXWORKS) sprintf(flags.hidden, "c%d", i < 0 ? (int) taskIdSelf() : i); @@ -330,17 +325,25 @@ int erl_call(int argc, char **argv) initWinSock(); #endif - gethostname(h_hostname, EI_MAXHOSTNAMELEN); + if (gethostname(h_hostname, EI_MAXHOSTNAMELEN) < 0) { + fprintf(stderr,"erl_call: failed to get host name: %d\n", errno); + exit(1); + } if ((hp = ei_gethostbyname(h_hostname)) == 0) { fprintf(stderr,"erl_call: can't resolve hostname %s\n", h_hostname); exit(1); } - /* If shortnames cut of the name at first '.' */ + /* If shortnames, cut off the name at first '.' */ if (flags.use_long_name == 0 && (ct = strchr(hp->h_name, '.')) != NULL) { *ct = '\0'; } - strcpy(h_hostname, hp->h_name); + strncpy(h_hostname, hp->h_name, EI_MAXHOSTNAMELEN); + h_hostname[EI_MAXHOSTNAMELEN] = '\0'; memcpy(&h_ipadr.s_addr, *hp->h_addr_list, sizeof(struct in_addr)); + if (strlen(h_alivename) + strlen(h_hostname) + 2 > sizeof(h_nodename)) { + fprintf(stderr,"erl_call: hostname too long: %s\n", h_hostname); + exit(1); + } sprintf(h_nodename, "%s@%s", h_alivename, h_hostname); if (ei_connect_xinit(&ec, h_hostname, h_alivename, h_nodename, @@ -368,11 +371,16 @@ int erl_call(int argc, char **argv) fprintf(stderr,"erl_call: can't get_hostent(%s)\n", host); exit(1); } - /* If shortnames cut of the name at first '.' */ + /* If shortnames, cut off the name at first '.' */ if (flags.use_long_name == 0 && (ct = strchr(hp->h_name, '.')) != NULL) { *ct = '\0'; } - strcpy(host_name, hp->h_name); + strncpy(host_name, hp->h_name, EI_MAXHOSTNAMELEN); + host_name[EI_MAXHOSTNAMELEN] = '\0'; + if (strlen(flags.node) + strlen(host_name) + 2 > sizeof(nodename)) { + fprintf(stderr,"erl_call: nodename too long: %s\n", flags.node); + exit(1); + } sprintf(nodename, "%s@%s", flags.node, host_name); /* @@ -401,7 +409,7 @@ int erl_call(int argc, char **argv) ei_encode_empty_list(NULL, &i); - p = (char *)malloc(i); + p = (char *)ei_chk_malloc(i); i = 0; /* Reset */ ei_encode_empty_list(p, &i); @@ -426,6 +434,10 @@ int erl_call(int argc, char **argv) if (flags.modp && (modname != NULL)) { char fname[256]; + if (strlen(modname) + 4 + 1 > sizeof(fname)) { + fprintf(stderr,"erl_call: module name too long: %s\n", modname); + exit(1); + } strcpy(fname, modname); strcat(fname, ".erl"); @@ -443,7 +455,7 @@ int erl_call(int argc, char **argv) ei_encode_binary(NULL, &i, module, modsize); ei_encode_empty_list(NULL, &i); - p = (char *)malloc(i); + p = (char *)ei_chk_malloc(i); i = 0; /* Reset */ ei_encode_list_header(p, &i, 2); @@ -476,7 +488,7 @@ int erl_call(int argc, char **argv) ei_encode_empty_list(NULL, &i); ei_encode_empty_list(NULL, &i); - p = (char *)malloc(i); + p = (char *)ei_chk_malloc(i); i = 0; /* Reset */ ei_encode_list_header(p, &i, 2); @@ -521,7 +533,7 @@ int erl_call(int argc, char **argv) ei_encode_binary(NULL, &i, evalbuf, len); ei_encode_empty_list(NULL, &i); - p = (char *)malloc(i); + p = (char *)ei_chk_malloc(i); i = 0; /* Reset */ ei_encode_list_header(p, &i, 1); @@ -719,32 +731,28 @@ static void split_apply_string(char *str, EAT(str); len = str-begin; - *mod = (char *) calloc(len + 1, sizeof(char)); + *mod = (char *) ei_chk_calloc(len + 1, sizeof(char)); memcpy(*mod, begin, len); SKIP_SPACE(str); if (*str == '\0') { - *fun = (char *) calloc(strlen(start)+1, sizeof(char)); - strcpy(*fun, start); - *args = (char *) calloc(strlen(empty_list)+1, sizeof(char)); - strcpy(*args, empty_list); + *fun = ei_chk_strdup(start); + *args = ei_chk_strdup(empty_list); return; } begin = str; EAT(str); len = str-begin; - *fun = (char *) calloc(len + 1, sizeof(char)); + *fun = (char *) ei_chk_calloc(len + 1, sizeof(char)); memcpy(*fun, begin, len); SKIP_SPACE(str); if (*str == '\0') { - *args = (char *) calloc(strlen(empty_list)+1, sizeof(char)); - strcpy(*args, empty_list); + *args = ei_chk_strdup(empty_list); return; } - *args = (char *) calloc(strlen(str) + 1, sizeof(char)); - strcpy(*args, str); + *args = ei_chk_strdup(str); return; @@ -760,7 +768,7 @@ static int read_stdin(char **buf) int bsize = BUFSIZ; int len = 0; int i; - char *tmp = (char *) malloc(bsize); + char *tmp = (char *) ei_chk_malloc(bsize); while (1) { if ((i = read(0, &tmp[len], bsize-len)) < 0) { @@ -772,7 +780,7 @@ static int read_stdin(char **buf) len += i; if ((len+50) > bsize) { bsize = len * 2; - tmp = (char *) realloc(tmp, bsize); + tmp = (char *) ei_chk_realloc(tmp, bsize); } else { continue; } @@ -809,10 +817,11 @@ static int get_module(char **mbuf, char **mname) } } /* while */ i = tmp - start; - *mname = (char *) calloc(i+1, sizeof(char)); + *mname = (char *) ei_chk_calloc(i+1, sizeof(char)); memcpy(*mname, start, i); } - free(mbuf); /* Allocated in read_stdin() */ + if (*mbuf) + free(*mbuf); /* Allocated in read_stdin() */ return len; @@ -904,3 +913,51 @@ static void initWinSock(void) } } #endif + + +/*************************************************************************** + * + * Utility functions + * + ***************************************************************************/ + +static void* ei_chk_malloc(size_t size) +{ + void *p = malloc(size); + if (p == NULL) { + fprintf(stderr,"erl_call: insufficient memory\n"); + exit(1); + } + return p; +} + +static void* ei_chk_calloc(size_t nmemb, size_t size) +{ + void *p = calloc(nmemb, size); + if (p == NULL) { + fprintf(stderr,"erl_call: insufficient memory\n"); + exit(1); + } + return p; +} + +static void* ei_chk_realloc(void *old, size_t size) +{ + void *p = realloc(old, size); + if (!p) { + fprintf(stderr, "erl_call: cannot reallocate %u bytes of memory from %p\n", + (unsigned) size, old); + exit (1); + } + return p; +} + +static char* ei_chk_strdup(char *s) +{ + char *p = strdup(s); + if (p == NULL) { + fprintf(stderr,"erl_call: insufficient memory\n"); + exit(1); + } + return p; +} diff --git a/lib/erl_interface/test/ei_accept_SUITE.erl b/lib/erl_interface/test/ei_accept_SUITE.erl index bc83d6a62e..a97c874e5f 100644 --- a/lib/erl_interface/test/ei_accept_SUITE.erl +++ b/lib/erl_interface/test/ei_accept_SUITE.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 @@ -31,7 +31,7 @@ all(suite) -> [ei_accept, ei_threaded_accept]. init_per_testcase(_Case, Config) -> - Dog = ?t:timetrap(?t:minutes(0.25)), + Dog = ?t:timetrap(?t:seconds(30)), [{watchdog, Dog}|Config]. fin_per_testcase(_Case, Config) -> @@ -43,8 +43,6 @@ ei_accept(Config) when is_list(Config) -> ?line P = runner:start(?interpret), ?line 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0), -% ?line AMsg={a,[message, with], " strings in it!", [-12, -23], 1.001}, - %% shouldn't this be a bif or function or something? ?line Myname= hd(tl(string:tokens(atom_to_list(node()), "@"))), ?line io:format("Myname ~p ~n", [Myname]), ?line EINode= list_to_atom("c42@"++Myname), @@ -52,9 +50,13 @@ ei_accept(Config) when is_list(Config) -> ?line Self= self(), ?line TermToSend= {call, Self, "Test"}, ?line F= fun() -> - timer:sleep(500), - {any, EINode} ! TermToSend, - Self ! sent_ok, + case waitfornode("c42",20) of + true -> + {any, EINode} ! TermToSend, + Self ! sent_ok; + false -> + Self ! never_published + end, ok end, @@ -72,7 +74,7 @@ ei_accept(Config) when is_list(Config) -> after 1000 -> io:format("timeout ~n") end, - ?line ok= ei_unpublish(P), + ?line runner:finish(P), ok. ei_threaded_accept(Config) when is_list(Config) -> @@ -90,12 +92,29 @@ ei_threaded_accept(Config) when is_list(Config) -> || I <- lists:seq(0, N-1) ], ok. +waitfornode(String,0) -> + io:format("~s never published itself.~n",[String]), + false; +waitfornode(String,N) -> + Registered = [X || {X,_} <- element(2,erl_epmd:names())], + case lists:member(String,Registered) of + true -> + true; + false -> + timer:sleep(1000), + waitfornode(String,N-1) + end. + send_rec_einode(N, TestServerPid) -> ?line Myname= hd(tl(string:tokens(atom_to_list(node()), "@"))), - ?line EINode= list_to_atom("eiacc" ++ integer_to_list(N) ++ "@" ++ Myname), + ?line FirstPart = "eiacc" ++ integer_to_list(N), + ?line EINode= list_to_atom(FirstPart ++ "@" ++ Myname), ?line io:format("EINode ~p ~n", [EINode]), ?line Self= self(), - ?line timer:sleep(10*1000), + ?line case waitfornode(FirstPart,20) of + true -> ok; + false -> test_server:fail({never_published,EINode}) + end, ?line {any, EINode} ! Self, ?line receive {N,_}=X -> @@ -136,13 +155,6 @@ ei_receive(P, Fd) -> {term, T}= get_term(P), T. -ei_unpublish(P) -> - send_command(P, ei_unpublish, []), - case get_term(P) of - {term,{0, _}} -> ok; - {term,{_X, Errno}} -> {error,Errno} - end. - send_command(P, Name, Args) -> runner:send_term(P, {Name,list_to_tuple(Args)}). diff --git a/lib/erl_interface/test/ei_connect_SUITE.erl b/lib/erl_interface/test/ei_connect_SUITE.erl index 56f478edad..fe82a73ef9 100644 --- a/lib/erl_interface/test/ei_connect_SUITE.erl +++ b/lib/erl_interface/test/ei_connect_SUITE.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 @@ -103,10 +103,12 @@ ei_threaded_send(Config) when is_list(Config) -> ?line Einode = filename:join(?config(data_dir, Config), "einode"), ?line N = 15, ?line Host = atom_to_list(node()), - ?line spawn_link(fun() -> start_einode(Einode, N, Host) end), ?line TestServerPid = self(), ?line [ spawn_link(fun() -> rec_einode(I, TestServerPid) end) || I <- lists:seq(0, N-1) ], + ?line [ receive {I,registered} -> ok end + || I <- lists:seq(0, N-1) ], + ?line spawn_link(fun() -> start_einode(Einode, N, Host) end), ?line [ receive I -> ok end || I <- lists:seq(0, N-1) ], ok. @@ -114,6 +116,7 @@ ei_threaded_send(Config) when is_list(Config) -> rec_einode(N, TestServerPid) -> ?line Regname = list_to_atom("mth"++integer_to_list(N)), ?line register(Regname, self()), + ?line TestServerPid ! {N, registered}, ?line io:format("~p waiting~n", [Regname]), ?line receive X -> diff --git a/lib/erl_interface/test/ei_decode_SUITE.erl b/lib/erl_interface/test/ei_decode_SUITE.erl index ea528728ab..09a37409f2 100644 --- a/lib/erl_interface/test/ei_decode_SUITE.erl +++ b/lib/erl_interface/test/ei_decode_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% 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% %% @@ -181,22 +181,9 @@ test_ei_decode_misc(suite) -> []; test_ei_decode_misc(Config) when is_list(Config) -> ?line P = runner:start(?test_ei_decode_misc), -% ?line <<131>> = get_binaries(P), - -% ?line {term,F} = get_term(P), -% ?line match_float(F, 0.0), -% ?line {term,F} = get_term(P), -% ?line match_float(F, 0.0), - -% ?line {term,F} = get_term(P), -% ?line true = match_float(F, -1.0), -% ?line {term,F} = get_term(P), -% ?line true = match_float(F, -1.0), - -% ?line {term,F} = get_term(P), -% ?line true = match_float(F, 1.0), -% ?line {term,F} = get_term(P), -% ?line true = match_float(F, 1.0), + ?line send_term_as_binary(P,0.0), + ?line send_term_as_binary(P,-1.0), + ?line send_term_as_binary(P,1.0), ?line send_term_as_binary(P,false), ?line send_term_as_binary(P,true), @@ -235,14 +222,16 @@ send_integers(P) -> ?line send_term_as_binary(P,256), % INTEGER_EXT smallest pos (*) ?line send_term_as_binary(P,-1), % INTEGER_EXT largest neg - ?line send_term_as_binary(P, 16#07ffffff), % INTEGER_EXT largest (28 bits) - ?line send_term_as_binary(P,-16#08000000), % INTEGER_EXT smallest - ?line send_term_as_binary(P, 16#08000000), % SMALL_BIG_EXT smallest pos(*) - ?line send_term_as_binary(P,-16#08000001), % SMALL_BIG_EXT largest neg (*) - - ?line send_term_as_binary(P, 16#7fffffff), % SMALL_BIG_EXT largest i32 - ?line send_term_as_binary(P,-16#80000000), % SMALL_BIG_EXT smallest i32 + ?line send_term_as_binary(P, 16#07ffffff), % INTEGER_EXT old largest (28 bits) + ?line send_term_as_binary(P,-16#08000000), % INTEGER_EXT old smallest + ?line send_term_as_binary(P, 16#08000000), % SMALL_BIG_EXT old smallest pos(*) + ?line send_term_as_binary(P,-16#08000001), % SMALL_BIG_EXT old largest neg (*) + ?line send_term_as_binary(P, 16#7fffffff), % INTEGER_EXT new largest (32 bits) + ?line send_term_as_binary(P,-16#80000000), % INTEGER_EXT new smallest (32 bis) + ?line send_term_as_binary(P, 16#80000000), % SMALL_BIG_EXT new smallest pos(*) + ?line send_term_as_binary(P,-16#80000001), % SMALL_BIG_EXT new largest neg (*) + case erlang:system_info(wordsize) of 4 -> ?line send_term_as_binary(P, 16#80000000),% SMALL_BIG_EXT u32 @@ -279,15 +268,17 @@ send_integers2(P) -> ?line send_term_as_binary(P,255), % SMALL_INTEGER_EXT largest ?line send_term_as_binary(P,256), % INTEGER_EXT smallest pos (*) ?line send_term_as_binary(P,-1), % INTEGER_EXT largest neg + + ?line send_term_as_binary(P, 16#07ffffff), % INTEGER_EXT old largest (28 bits) + ?line send_term_as_binary(P,-16#08000000), % INTEGER_EXT old smallest + ?line send_term_as_binary(P, 16#08000000), % SMALL_BIG_EXT old smallest pos(*) + ?line send_term_as_binary(P,-16#08000001), % SMALL_BIG_EXT old largest neg (*) - ?line send_term_as_binary(P, 16#07ffffff), % INTEGER_EXT largest (28 bits) - ?line send_term_as_binary(P,-16#08000000), % INTEGER_EXT smallest - ?line send_term_as_binary(P, 16#08000000), % SMALL_BIG_EXT smallest pos(*) - ?line send_term_as_binary(P,-16#08000001), % SMALL_BIG_EXT largest neg (*) + ?line send_term_as_binary(P, 16#7fffffff), % INTEGER_EXT new largest (32 bits) + ?line send_term_as_binary(P,-16#80000000), % INTEGER_EXT new smallest + ?line send_term_as_binary(P, 16#80000000), % SMALL_BIG_EXT new smallest pos(*) + ?line send_term_as_binary(P,-16#80000001), % SMALL_BIG_EXT new largest neg (*) - ?line send_term_as_binary(P, 16#7fffffff), % SMALL_BIG_EXT largest i32 - ?line send_term_as_binary(P,-16#80000000), % SMALL_BIG_EXT smallest i32 - ?line send_term_as_binary(P, 16#80000000),% SMALL_BIG_EXT u32 ?line send_term_as_binary(P, 16#ffffffff),% SMALL_BIG_EXT largest u32 ?line send_term_as_binary(P, 16#7fffffffffff), % largest i48 diff --git a/lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c b/lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c index d81ea88437..b349138ae9 100644 --- a/lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c +++ b/lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c @@ -1,19 +1,19 @@ /* * %CopyrightBegin% - * - * Copyright Ericsson AB 2004-2009. All Rights Reserved. - * + * + * 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% */ @@ -246,13 +246,23 @@ TESTCASE(test_ei_decode_long) EI_DECODE_2 (decode_long, 5, long, 256); EI_DECODE_2 (decode_long, 5, long, -1); + /* Old 28 bit limits for INTEGER_EXT */ EI_DECODE_2 (decode_long, 5, long, 0x07ffffff); EI_DECODE_2 (decode_long, 5, long, -0x08000000); - EI_DECODE_2 (decode_long, 7, long, 0x08000000); - EI_DECODE_2 (decode_long, 7, long, -0x08000001); + EI_DECODE_2 (decode_long, 5, long, 0x08000000); + EI_DECODE_2 (decode_long, 5, long, -0x08000001); - EI_DECODE_2 (decode_long, 7, long, 0x7fffffff); - EI_DECODE_2 (decode_long, 7, long, -ll(0x80000000)); /* Strange :-( */ + /* New 32 bit limits for INTEGER_EXT */ + EI_DECODE_2 (decode_long, 5, long, 0x7fffffff); + EI_DECODE_2 (decode_long, 5, long, -ll(0x80000000)); /* Strange :-( */ + if (sizeof(long) > 4) { + EI_DECODE_2(decode_long, 7, long, 0x80000000); + EI_DECODE_2(decode_long, 7, long, -ll(0x80000001)); + } + else { + EI_DECODE_2_FAIL(decode_long, 7, long, 0x80000000); + EI_DECODE_2_FAIL(decode_long, 7, long, -ll(0x80000001)); + } EI_DECODE_2_FAIL(decode_long, 7, long, 0x80000000); EI_DECODE_2_FAIL(decode_long, 7, long, 0xffffffff); @@ -280,11 +290,13 @@ TESTCASE(test_ei_decode_ulong) EI_DECODE_2 (decode_ulong, 5, unsigned long, 0x07ffffff); EI_DECODE_2_FAIL(decode_ulong, 5, unsigned long, -0x08000000); - EI_DECODE_2 (decode_ulong, 7, unsigned long, 0x08000000); - EI_DECODE_2_FAIL(decode_ulong, 7, unsigned long, -0x08000001); + EI_DECODE_2 (decode_ulong, 5, unsigned long, 0x08000000); + EI_DECODE_2_FAIL(decode_ulong, 5, unsigned long, -0x08000001); - EI_DECODE_2 (decode_ulong, 7, unsigned long, 0x7fffffff); - EI_DECODE_2_FAIL(decode_ulong, 7, unsigned long, -ll(0x80000000)); + EI_DECODE_2 (decode_ulong, 5, unsigned long, 0x7fffffff); + EI_DECODE_2_FAIL(decode_ulong, 5, unsigned long, -ll(0x80000000)); + EI_DECODE_2 (decode_ulong, 7, unsigned long, 0x80000000); + EI_DECODE_2_FAIL(decode_ulong, 7, unsigned long, -ll(0x80000001)); if (sizeof(long) > 4) { EI_DECODE_2 (decode_ulong, 11, unsigned long, ll(0x8000000000000000)); @@ -319,13 +331,14 @@ TESTCASE(test_ei_decode_longlong) EI_DECODE_2 (decode_longlong, 5, EI_LONGLONG, 0x07ffffff); EI_DECODE_2 (decode_longlong, 5, EI_LONGLONG, -0x08000000); - EI_DECODE_2 (decode_longlong, 7, EI_LONGLONG, 0x08000000); - EI_DECODE_2 (decode_longlong, 7, EI_LONGLONG, -0x08000001); - - EI_DECODE_2 (decode_longlong, 7, EI_LONGLONG, 0x7fffffff); - EI_DECODE_2 (decode_longlong, 7, EI_LONGLONG, -ll(0x80000000)); + EI_DECODE_2 (decode_longlong, 5, EI_LONGLONG, 0x08000000); + EI_DECODE_2 (decode_longlong, 5, EI_LONGLONG, -0x08000001); + EI_DECODE_2 (decode_longlong, 5, EI_LONGLONG, 0x7fffffff); + EI_DECODE_2 (decode_longlong, 5, EI_LONGLONG, -ll(0x80000000)); EI_DECODE_2 (decode_longlong, 7, EI_LONGLONG, 0x80000000); + EI_DECODE_2 (decode_longlong, 7, EI_LONGLONG, -ll(0x80000001)); + EI_DECODE_2 (decode_longlong, 7, EI_LONGLONG, 0xffffffff); EI_DECODE_2 (decode_longlong, 9, EI_LONGLONG, ll(0x7fffffffffff)); @@ -352,13 +365,14 @@ TESTCASE(test_ei_decode_ulonglong) EI_DECODE_2 (decode_ulonglong, 5, EI_ULONGLONG, 0x07ffffff); EI_DECODE_2_FAIL(decode_ulonglong, 5, EI_ULONGLONG, -0x08000000); - EI_DECODE_2 (decode_ulonglong, 7, EI_ULONGLONG, 0x08000000); - EI_DECODE_2_FAIL(decode_ulonglong, 7, EI_ULONGLONG, -0x08000001); - - EI_DECODE_2 (decode_ulonglong, 7, EI_ULONGLONG, 0x7fffffff); - EI_DECODE_2_FAIL(decode_ulonglong, 7, EI_ULONGLONG, -ll(0x80000000)); + EI_DECODE_2 (decode_ulonglong, 5, EI_ULONGLONG, 0x08000000); + EI_DECODE_2_FAIL(decode_ulonglong, 5, EI_ULONGLONG, -0x08000001); + EI_DECODE_2 (decode_ulonglong, 5, EI_ULONGLONG, 0x7fffffff); + EI_DECODE_2_FAIL(decode_ulonglong, 5, EI_ULONGLONG, -ll(0x80000000)); EI_DECODE_2 (decode_ulonglong, 7, EI_ULONGLONG, 0x80000000); + EI_DECODE_2_FAIL(decode_ulonglong, 7, EI_ULONGLONG, -0x80000001); + EI_DECODE_2 (decode_ulonglong, 7, EI_ULONGLONG, 0xffffffff); EI_DECODE_2 (decode_ulonglong, 9, EI_ULONGLONG, ll(0x7fffffffffff)); @@ -515,11 +529,10 @@ TESTCASE(test_ei_decode_misc) /* EI_DECODE_0(decode_version); */ -/* - EI_DECODE_2(decode_double, 0.0); - EI_DECODE_2(decode_double, -1.0); - EI_DECODE_2(decode_double, 1.0); -*/ + EI_DECODE_2(decode_double, 32, double, 0.0); + EI_DECODE_2(decode_double, 32, double, -1.0); + EI_DECODE_2(decode_double, 32, double, 1.0); + EI_DECODE_2(decode_boolean, 8, int, 0); EI_DECODE_2(decode_boolean, 7, int, 1); diff --git a/lib/erl_interface/test/ei_encode_SUITE.erl b/lib/erl_interface/test/ei_encode_SUITE.erl index fb790eb7c3..6b9de4f093 100644 --- a/lib/erl_interface/test/ei_encode_SUITE.erl +++ b/lib/erl_interface/test/ei_encode_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% 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% %% @@ -181,20 +181,14 @@ test_ei_encode_misc(Config) when is_list(Config) -> ?line <<131>> = get_binaries(P), -% ?line {term,F} = get_term(P), -% ?line match_float(F, 0.0), -% ?line {term,F} = get_term(P), -% ?line match_float(F, 0.0), + ?line {<<70,_:8/binary>>,F0} = get_buf_and_term(P), + ?line true = match_float(F0, 0.0), -% ?line {term,F} = get_term(P), -% ?line true = match_float(F, -1.0), -% ?line {term,F} = get_term(P), -% ?line true = match_float(F, -1.0), + ?line {<<70,_:8/binary>>,Fn1} = get_buf_and_term(P), + ?line true = match_float(Fn1, -1.0), -% ?line {term,F} = get_term(P), -% ?line true = match_float(F, 1.0), -% ?line {term,F} = get_term(P), -% ?line true = match_float(F, 1.0), + ?line {<<70,_:8/binary>>,Fp1} = get_buf_and_term(P), + ?line true = match_float(Fp1, 1.0), ?line {<<100,0,5,"false">>,false} = get_buf_and_term(P), ?line {<<100,0,4,"true">> ,true} = get_buf_and_term(P), @@ -310,6 +304,8 @@ get_term(P) -> %% +match_float(F, Match) when is_float(F), is_float(Match), F == Match -> + true; match_float(F, Match) when is_float(F), F > Match*0.99, F < Match*1.01 -> true. diff --git a/lib/erl_interface/test/ei_encode_SUITE_data/ei_encode_test.c b/lib/erl_interface/test/ei_encode_SUITE_data/ei_encode_test.c index f8de0b7878..c373658152 100644 --- a/lib/erl_interface/test/ei_encode_SUITE_data/ei_encode_test.c +++ b/lib/erl_interface/test/ei_encode_SUITE_data/ei_encode_test.c @@ -1,19 +1,19 @@ /* * %CopyrightBegin% - * - * Copyright Ericsson AB 2004-2009. All Rights Reserved. - * + * + * 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% */ @@ -350,13 +350,13 @@ TESTCASE(test_ei_encode_char) TESTCASE(test_ei_encode_misc) { EI_ENCODE_0(encode_version); -/* + EI_ENCODE_1(encode_double, 0.0); EI_ENCODE_1(encode_double, -1.0); EI_ENCODE_1(encode_double, 1.0); -*/ + EI_ENCODE_1(encode_boolean, 0) /* Only case it should be false */; EI_ENCODE_1(encode_boolean, 1); diff --git a/lib/erl_interface/test/ei_tmo_SUITE.erl b/lib/erl_interface/test/ei_tmo_SUITE.erl index 0c211aa148..e7a2465421 100644 --- a/lib/erl_interface/test/ei_tmo_SUITE.erl +++ b/lib/erl_interface/test/ei_tmo_SUITE.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -349,10 +349,12 @@ make_and_check_dummy() -> -define(DFLAG_ATOM_CACHE,2). -define(DFLAG_EXTENDED_REFERENCES,4). -define(DFLAG_EXTENDED_PIDS_PORTS,16#100). +-define(DFLAG_NEW_FLOATS,16#800). -define(DFLAG_DIST_MONITOR,8). %% From R9 and forward extended references is compulsory --define(COMPULSORY_DFLAGS, (?DFLAG_EXTENDED_REFERENCES bor ?DFLAG_EXTENDED_PIDS_PORTS)). +%% From 14 and forward new float is compulsory +-define(COMPULSORY_DFLAGS, (?DFLAG_EXTENDED_REFERENCES bor ?DFLAG_EXTENDED_PIDS_PORTS bor ?DFLAG_NEW_FLOATS)). -define(shutdown(X), exit(X)). -define(int16(X), [((X) bsr 8) band 16#ff, (X) band 16#ff]). diff --git a/lib/erl_interface/test/ei_tmo_SUITE_data/ei_tmo_test.c b/lib/erl_interface/test/ei_tmo_SUITE_data/ei_tmo_test.c index 2cc9af975d..db90b1810e 100644 --- a/lib/erl_interface/test/ei_tmo_SUITE_data/ei_tmo_test.c +++ b/lib/erl_interface/test/ei_tmo_SUITE_data/ei_tmo_test.c @@ -1,19 +1,19 @@ /* * %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 * 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% */ @@ -65,7 +65,7 @@ static void debugf_open(int number) { char filename[1024]; sprintf(filename,"ei_tmo_test%d.debug",number); -#if !defined(VXWORKS) && !defined(__WIN32__) && !defined(_OSE_) +#if !defined(VXWORKS) && !defined(__WIN32__) close(2); #endif debugfile = fopen(filename,"a"); diff --git a/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c b/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c index 6b2ec8f766..f273efd532 100644 --- a/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c +++ b/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c @@ -63,32 +63,108 @@ TESTCASE(build_terms) report(1); } +static int abs_and_sign(ETERM* v, unsigned long long* av, int* sign) +{ + long long sv; + switch (ERL_TYPE(v)) { + case ERL_INTEGER: sv = ERL_INT_VALUE(v); break; + case ERL_U_INTEGER: *av = ERL_INT_UVALUE(v); *sign = 0; return 1; + case ERL_LONGLONG: sv = ERL_LL_VALUE(v); break; + case ERL_U_LONGLONG: *av = ERL_LL_UVALUE(v); *sign = 0; return 1; + default: return 0; + } + if (sv < 0) { + *av = -sv; + *sign = 1; + } + else { + *av = sv; + *sign = 0; + } + return 1; +} + +/* Shouldn't erl_match() cope with this? +*/ +static int eq_ints(ETERM* a, ETERM* b) +{ + unsigned long long a_abs, b_abs; + int a_sign, b_sign; + return abs_and_sign(a, &a_abs, &a_sign) && abs_and_sign(b, &b_abs, &b_sign) + && (a_abs == b_abs) && (a_sign == b_sign); +} + +static void encode_decode(ETERM* original, const char* text) +{ + static unsigned char encoded[16*1024]; + ETERM* new_terms; + int bytes = erl_encode(original, encoded); + + if (bytes == 0) { + fail("failed to encode terms"); + } + else if (bytes > sizeof(encoded)) { + fail("encoded terms buffer overflow"); + } + else if ((new_terms = erl_decode(encoded)) == NULL) { + fail("failed to decode terms"); + } + else if (!erl_match(original, new_terms) && !eq_ints(original, new_terms)) { + erl_print_term(stderr, original); + fprintf(stderr, "(%i) != (%i)", ERL_TYPE(original), ERL_TYPE(new_terms)); + erl_print_term(stderr, new_terms); + fprintf(stderr, " [%s]\r\n", text); + fail("decoded terms didn't match original"); + } + erl_free_term(original); + erl_free_term(new_terms); +} /* * Converts an Erlang term to the external term format and back again. */ TESTCASE(round_trip_conversion) { - ETERM* original; - ETERM* new_terms; - char encoded[16*1024]; - int n; + int n, i; erl_init(NULL, 0); - original = all_types(); - if (erl_encode(original, encoded) == 0) + encode_decode(all_types(), "ALL"); + { - fail("failed to encode terms"); - } else if ((new_terms = erl_decode(encoded)) == NULL) + int v; + for (v = 8; v; v <<= 1) { + for (i=-4; i<4; i++) { + encode_decode(erl_mk_int(v+i), "INT"); + encode_decode(erl_mk_int(-(v+i)), "NEG INT"); + } + } + } { - fail("failed to decode terms"); - } else if (!erl_match(original, new_terms)) + unsigned int v; + for (v = 8; v; v <<= 1) { + for (i=-4; i<4; i++) { + encode_decode(erl_mk_uint(v+i), "UINT"); + } + } + } { - fail("decoded terms didn't match original"); + long long v; + for (v = 8; v; v <<= 1) { + for (i=-4; i<4; i++) { + encode_decode(erl_mk_longlong(v+i), "LONGLONG"); + encode_decode(erl_mk_longlong(-(v+i)), "NEG LONGLONG"); + } + } + } + { + unsigned long long v; + for (v = 8; v; v <<= 1) { + for (i=-4; i<4; i++) { + encode_decode(erl_mk_ulonglong(v+i), "ULONGLONG"); + } + } } - erl_free_term(original); - erl_free_term(new_terms); report(1); } diff --git a/lib/erl_interface/vsn.mk b/lib/erl_interface/vsn.mk index 589b9e2f9c..c642cc5002 100644 --- a/lib/erl_interface/vsn.mk +++ b/lib/erl_interface/vsn.mk @@ -1 +1 @@ -EI_VSN = 3.6.5 +EI_VSN = 3.7.1 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/doc/src/notes.xml b/lib/et/doc/src/notes.xml index 8611955d3d..4ce7548414 100644 --- a/lib/et/doc/src/notes.xml +++ b/lib/et/doc/src/notes.xml @@ -36,6 +36,32 @@ one section in this document. The title of each section is the version number of <c>Event Tracer (ET)</c>.</p> +<section><title>ET 1.4.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> Fixed broken links in the documentation. </p> + <p> + Own Id: OTP-8796</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Fixed gui crash on windows.</p> + <p> + Own Id: OTP-8830</p> + </item> + </list> + </section> + +</section> + <section><title>ET 1.4</title> <section><title>Improvements and New Features</title> diff --git a/lib/et/src/et_wx_viewer.erl b/lib/et/src/et_wx_viewer.erl index 5cd3563aed..d42f8c0c86 100644 --- a/lib/et/src/et_wx_viewer.erl +++ b/lib/et/src/et_wx_viewer.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 @@ -1233,7 +1233,7 @@ create_main_window(S) -> [{flag, ?wxEXPAND}]), CanvasSizer = wxBoxSizer:new(?wxHORIZONTAL), - Canvas = wxPanel:new(Panel, []), + Canvas = wxPanel:new(Panel, [{style, ?wxFULL_REPAINT_ON_RESIZE}]), {CanvasW,CanvasH} = wxPanel:getSize(Canvas), ScrollBar = wxScrollBar:new(Panel, ?wxID_ANY, [{style, ?wxSB_VERTICAL}]), @@ -1244,7 +1244,13 @@ create_main_window(S) -> wxPanel:connect(Canvas, left_up), wxPanel:connect(Canvas, right_up), wxPanel:connect(Canvas, size), - wxPanel:connect(Canvas, paint), + Self = self(), + wxPanel:connect(Canvas, paint, [{callback, %% Needed on windows + fun(Ev, _) -> + DC = wxPaintDC:new(Canvas), + wxPaintDC:destroy(DC), + Self ! Ev + end}]), wxPanel:connect(Canvas, key_down), wxPanel:connect(Canvas, kill_focus), wxPanel:connect(Canvas, enter_window, [{skip, true}]), @@ -1437,6 +1443,7 @@ create_help_menu(Bar) -> clear_canvas(S) -> DC = wxClientDC:new(S#state.canvas), + wxDC:setBackground(DC, ?wxWHITE_BRUSH), %% Needed on mac wxDC:clear(DC), {CanvasW, CanvasH} = wxPanel:getSize(S#state.canvas), wxSizer:recalcSizes(S#state.canvas_sizer), diff --git a/lib/et/test/Makefile b/lib/et/test/Makefile index 9aedf96ce9..7227ae8fd8 100644 --- a/lib/et/test/Makefile +++ b/lib/et/test/Makefile @@ -72,7 +72,8 @@ release_spec: opt release_tests_spec: opt $(INSTALL_DIR) $(RELSYSDIR) $(INSTALL_DATA) et.spec $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR) - $(INSTALL_PROGRAM) ett $(INSTALL_PROGS) $(RELSYSDIR) + $(INSTALL_SCRIPT) ett $(RELSYSDIR) + $(INSTALL_DATA) $(INSTALL_PROGS) $(RELSYSDIR) # chmod -f -R u+w $(RELSYSDIR) # @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) diff --git a/lib/et/vsn.mk b/lib/et/vsn.mk index 64140ac4ce..b5b7fa52f4 100644 --- a/lib/et/vsn.mk +++ b/lib/et/vsn.mk @@ -1,6 +1 @@ -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 +ET_VSN = 1.4.1 diff --git a/lib/eunit/doc/overview.edoc b/lib/eunit/doc/overview.edoc index 2583f0be25..be05a13fba 100644 --- a/lib/eunit/doc/overview.edoc +++ b/lib/eunit/doc/overview.edoc @@ -913,7 +913,7 @@ To make the descriptions simpler, we first list some definitions: <td>`CleanupX'</td><td>`(X::any(), R::any()) -> any()'</td> </tr> <tr> -<td>`Instantiator'</td><td>`((R::any()) -> Tests) | {with, [AbstractTestFun::((any()) -> any())]}'</td> +<td>`Instantiator'</td><td>`((R::any()) -> Tests | {with, [AbstractTestFun::((any()) -> any())]}'</td> </tr> <tr> <td>`Where'</td><td>`local | spawn | {spawn, Node::atom()}'</td> diff --git a/lib/gs/contribs/bonk/bonk.erl b/lib/gs/contribs/bonk/bonk.erl index 12d94f6c5e..79f01bf659 100644 --- a/lib/gs/contribs/bonk/bonk.erl +++ b/lib/gs/contribs/bonk/bonk.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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% %% @@ -33,10 +33,10 @@ run() -> run([ColorMode]) -> % This is for the start script... run(ColorMode); -run(ColorMode) when atom(ColorMode) -> +run(ColorMode) when is_atom(ColorMode) -> GS = gs:start(), - SoundPid=spawn_link(bonk_sound,start,[]), - {H,M,S}=time(), + SoundPid = spawn_link(bonk_sound,start,[]), + {H,M,S} = time(), random:seed(H*13,M*7,S*3), {SqrPids, Bmps, Colors} = create_board(GS, ColorMode), {ScoreL,_File} = get_highscore(), @@ -96,7 +96,7 @@ init(SoundPid, SqrPids, Bmps, Colors) -> game(SoundPid, SqrPids, Bmps, Colors, Scores) -> receive - {gs, _Square, buttonpress, SqrPid, [1 | _Rest]} when pid(SqrPid) -> + {gs, _Square, buttonpress, SqrPid, [1 | _Rest]} when is_pid(SqrPid) -> SqrPid ! bonk, game(SoundPid, SqrPids, Bmps, Colors, Scores); {gs, _Id, buttonpress, _Data, [Butt | _Rest]} when Butt =/= 1 -> @@ -224,11 +224,9 @@ update_score(SoundPid, SqrPids, Scores) -> send_to_all([], _Msg) -> true; - -send_to_all([Pid|Rest],Msg) when pid(Pid) -> +send_to_all([Pid|Rest],Msg) when is_pid(Pid) -> Pid ! Msg, send_to_all(Rest,Msg); - send_to_all([_Else|Rest],Msg) -> send_to_all(Rest,Msg). @@ -460,7 +458,7 @@ update_scorelist(SoundPid, Scores) -> {ScoreL,FileName} = get_highscore(), New_scorelist=update_scorelist_2(ScoreL, Score, 0, SoundPid), display_highscore(New_scorelist), - case file:open(FileName, write) of + case file:open(FileName, [write]) of {error,_} -> true; {ok,FD} -> @@ -559,7 +557,7 @@ display_about() -> {activebg, BGColor}]), gs:create(text, aboutText, aboutCan, [{width, Wid-30}, {coords, [{15, 0}]}, {fg, TextColor}, {justify, center}]), - case file:open(lists:append(bonk_dir(),"bonk.txt"), read) of + case file:open(lists:append(bonk_dir(),"bonk.txt"), [read]) of {ok, Fd} -> write_text(Fd, "", io:get_line(Fd, "")), file:close(Fd); diff --git a/lib/gs/contribs/othello/othello_adt.erl b/lib/gs/contribs/othello/othello_adt.erl index d1d3ec950b..fb60c30b89 100644 --- a/lib/gs/contribs/othello/othello_adt.erl +++ b/lib/gs/contribs/othello/othello_adt.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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% %% @@ -375,29 +375,29 @@ is_good(Colour,H,Board) -> false. is_good_0(_,_,false,_) -> false; -is_good_0(_,H,D,_) when integer(H), integer(D), H+D<0 -> false; -is_good_0(_,H,D,_) when integer(H), integer(D), H+D>63 -> false; -is_good_0(black,H,D,Board) when integer(H), integer(D) -> +is_good_0(_,H,D,_) when is_integer(H), is_integer(D), H+D<0 -> false; +is_good_0(_,H,D,_) when is_integer(H), is_integer(D), H+D>63 -> false; +is_good_0(black,H,D,Board) when is_integer(H), is_integer(D) -> case element((H+D)+1,Board) of white -> is_good_1(black,H+D,dir(H+D,D),Board); _ -> false end; -is_good_0(white,H,D,Board) when integer(H), integer(D) -> +is_good_0(white,H,D,Board) when is_integer(H), is_integer(D) -> case element((H+D)+1,Board) of black -> is_good_1(white,H+D,dir(H+D,D),Board); _ -> false end. is_good_1(_,_,false,_) -> false; -is_good_1(_,H,D,_) when integer(H), integer(D), H+D<0 -> false; -is_good_1(_,H,D,_) when integer(H), integer(D), H+D>63 -> false; -is_good_1(black,H,D,Board) when integer(H), integer(D) -> +is_good_1(_,H,D,_) when is_integer(H), is_integer(D), H+D<0 -> false; +is_good_1(_,H,D,_) when is_integer(H), is_integer(D), H+D>63 -> false; +is_good_1(black,H,D,Board) when is_integer(H), is_integer(D) -> case element((H+D)+1,Board) of white -> is_good_1(black,H+D,dir(H+D,D),Board); black -> throw(true); _ -> false end; -is_good_1(white,H,D,Board) when integer(H), integer(D) -> +is_good_1(white,H,D,Board) when is_integer(H), is_integer(D) -> case element((H+D)+1,Board) of black -> is_good_1(white,H+D,dir(H+D,D),Board); white -> throw(true); @@ -429,15 +429,15 @@ turn(Colour,H,D,Board) -> Board end. -turn_0(_,H,D,B) when integer(H), integer(D), H+D<0 -> B; -turn_0(_,H,D,B) when integer(H), integer(D), H+D>63 -> B; -turn_0(black,H,D,Board) when integer(H), integer(D) -> +turn_0(_,H,D,B) when is_integer(H), is_integer(D), H+D<0 -> B; +turn_0(_,H,D,B) when is_integer(H), is_integer(D), H+D>63 -> B; +turn_0(black,H,D,Board) when is_integer(H), is_integer(D) -> E = H+D, case element(E+1,Board) of white -> turn_0(black,H+D,D,swap(black,E,Board)); _ -> Board end; -turn_0(white,H,D,Board) when integer(H), integer(D) -> +turn_0(white,H,D,Board) when is_integer(H), is_integer(D) -> E = H+D, case element(E+1,Board) of black -> turn_0(white,H+D,D,swap(white,E,Board)); @@ -450,7 +450,7 @@ turn_0(white,H,D,Board) when integer(H), integer(D) -> %% Neighbours are not changed !! %%------------------------------------------------------- -swap(Colour,Pos,Board) when integer(Pos) -> +swap(Colour,Pos,Board) when is_integer(Pos) -> setelement(Pos+1,Board,Colour). score(Pos) -> score1({col(Pos),row(Pos)}). diff --git a/lib/gs/doc/src/gs.xml b/lib/gs/doc/src/gs.xml index b1c7e505dc..f2182fc673 100644 --- a/lib/gs/doc/src/gs.xml +++ b/lib/gs/doc/src/gs.xml @@ -5,7 +5,7 @@ <header> <copyright> <year>2000</year> - <year>2007</year> + <year>2010</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> @@ -32,6 +32,18 @@ <module>gs</module> <modulesummary>The Graphics System for Erlang.</modulesummary> <description> + <warning> + <p> + GS is not recommended for use in new applications. + Instead we recommend WX for applications that need a + graphical user interface. + </p> + <p> + GS is not maintained and we plan to deprecate and remove it from + the distribution as soon as possible, maybe already in the next + major release (R15). + </p> + </warning> <p>The Graphics System, GS, is easy to learn and designed to be portable to many different platforms.</p> <p>In the description below, the type <c><![CDATA[gsobj()]]></c> denotes a diff --git a/lib/gs/doc/src/gs_chapter1.xml b/lib/gs/doc/src/gs_chapter1.xml index cfcae94f7c..912d6e1ef9 100644 --- a/lib/gs/doc/src/gs_chapter1.xml +++ b/lib/gs/doc/src/gs_chapter1.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2000</year><year>2009</year> + <year>2000</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -31,6 +31,18 @@ <section> <title>Introduction</title> + <warning> + <p> + GS is not recommended for use in new applications. + Instead we recommend WX for applications that need a + graphical user interface. + </p> + <p> + GS is not maintained and we plan to deprecate and remove it from + the distribution as soon as possible, maybe already in the next + major release (R15). + </p> + </warning> <p>This section describes the general graphics interface to Erlang. This system was designed with the following requirements in mind:</p> <list type="bulleted"> <item>a graphics system which is easy to learn</item> diff --git a/lib/gs/doc/src/notes.xml b/lib/gs/doc/src/notes.xml index 8e4032ccc1..744efbd4fc 100644 --- a/lib/gs/doc/src/notes.xml +++ b/lib/gs/doc/src/notes.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> @@ -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>GS Release Notes</title> @@ -30,7 +30,27 @@ </header> <p>This document describes the changes made to the GS application.</p> - <section> + <section><title>GS 1.5.13</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The documentation for GS is updated with the warning that + it should not be used in new applications. GS is planned + to be deprecated soon and might be removed from the + distribution already in the next major release (R15). For + graphical applications we recommend the use of WX + instead.</p> + <p> + Own Id: OTP-8824</p> + </item> + </list> + </section> + +</section> + +<section> <title>GS 1.5.10</title> <section> @@ -47,7 +67,22 @@ </section> </section> - <section><title>GS 1.5.11</title> + <section><title>GS 1.5.12</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Warnings due to new autoimported BIFs removed</p> + <p> + Own Id: OTP-8674 Aux Id: OTP-8579 </p> + </item> + </list> + </section> + +</section> + +<section><title>GS 1.5.11</title> <section><title>Improvements and New Features</title> <list> diff --git a/lib/gs/src/tool_utils.erl b/lib/gs/src/tool_utils.erl index 697dd07151..b07e92c4f0 100644 --- a/lib/gs/src/tool_utils.erl +++ b/lib/gs/src/tool_utils.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% %% @@ -224,11 +224,11 @@ help_win(Type, Parent, Strings) -> {Wbtn0,Hbtn0} = gs:read(Lbl, {font_wh,{Font,"Cancel"}}), %% Compute size of the objects and adjust the graphics accordingly - Wbtn = max(Wbtn0+10, ?Wbtn), - Hbtn = max(Hbtn0+10, ?Hbtn), - Hent = max(Hent0+10, ?Hent), - Wlbl = max(Wlbl0, max(Nbtn*Wbtn+(Nbtn-1)*?PAD, ?Wlbl)), - Hlbl = max(Hlbl0, ?Hlbl), + Wbtn = erlang:max(Wbtn0+10, ?Wbtn), + Hbtn = erlang:max(Hbtn0+10, ?Hbtn), + Hent = erlang:max(Hent0+10, ?Hent), + Wlbl = erlang:max(Wlbl0, erlang:max(Nbtn*Wbtn+(Nbtn-1)*?PAD, ?Wlbl)), + Hlbl = erlang:max(Hlbl0, ?Hlbl), Wwin = ?PAD+Wlbl+?PAD, @@ -297,9 +297,6 @@ data("Yes") -> {helpwin,yes}; data("No") -> {helpwin,no}; data("Cancel") -> {helpwin,cancel}. -max(X, Y) when X>Y -> X; -max(_X, Y) -> Y. - get_coords(Parent, W, H) -> case gs:read(Parent, x) of X when is_integer(X) -> diff --git a/lib/gs/vsn.mk b/lib/gs/vsn.mk index 701d0e178d..4c91857572 100644 --- a/lib/gs/vsn.mk +++ b/lib/gs/vsn.mk @@ -1,2 +1,2 @@ -GS_VSN = 1.5.11 +GS_VSN = 1.5.13 diff --git a/lib/hipe/arm/hipe_arm_pp.erl b/lib/hipe/arm/hipe_arm_pp.erl index 7ce8421994..c4dde31188 100644 --- a/lib/hipe/arm/hipe_arm_pp.erl +++ b/lib/hipe/arm/hipe_arm_pp.erl @@ -1,20 +1,20 @@ %% -*- erlang-indent-level: 2 -*- %% %% %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 %% 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% %% @@ -246,6 +246,11 @@ stop_suffix(StOp) -> 'strb' -> "b" end. +imm8m_decode(Value, 0) -> + Value; +imm8m_decode(Value, Rot) -> + (Value bsr (2 * Rot)) bor (Value bsl (2 * (16 - Rot))). + pp_temp(Dev, Temp=#arm_temp{reg=Reg, type=Type}) -> case hipe_arm:temp_is_precoloured(Temp) of true -> @@ -292,7 +297,7 @@ pp_am1(Dev, Am1) -> io:format(Dev, "#~w", [Imm5]) end; {Imm8,Imm4} -> - io:format(Dev, "#~w, 2*~w", [Imm8,Imm4]) + io:format(Dev, "#~s", [to_hex(imm8m_decode(Imm8, Imm4))]) end. pp_am2(Dev, #am2{src=Src,sign=Sign,offset=Am2Offset}) -> diff --git a/lib/hipe/cerl/cerl_closurean.erl b/lib/hipe/cerl/cerl_closurean.erl index 12771668ac..021acd5b35 100644 --- a/lib/hipe/cerl/cerl_closurean.erl +++ b/lib/hipe/cerl/cerl_closurean.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% ===================================================================== @@ -808,7 +808,7 @@ take_work({Queue0, Set0}) -> is_escape_op(match_fail, 1) -> false; is_escape_op(F, A) when is_atom(F), is_integer(A) -> true. --spec is_escape_op(module(), atom(), arity()) -> boolean(). +-spec is_escape_op(atom(), atom(), arity()) -> boolean(). is_escape_op(erlang, error, 1) -> false; is_escape_op(erlang, error, 2) -> false; @@ -825,7 +825,7 @@ is_escape_op(M, F, A) when is_atom(M), is_atom(F), is_integer(A) -> true. is_literal_op(match_fail, 1) -> true; is_literal_op(F, A) when is_atom(F), is_integer(A) -> false. --spec is_literal_op(module(), atom(), arity()) -> boolean(). +-spec is_literal_op(atom(), atom(), arity()) -> boolean(). is_literal_op(erlang, '+', 2) -> true; is_literal_op(erlang, '-', 2) -> true; diff --git a/lib/hipe/cerl/cerl_messagean.erl b/lib/hipe/cerl/cerl_messagean.erl index 0753376e7d..6dd93adaa3 100644 --- a/lib/hipe/cerl/cerl_messagean.erl +++ b/lib/hipe/cerl/cerl_messagean.erl @@ -1,19 +1,19 @@ %% ===================================================================== %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% 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% %% %% Message analysis of Core Erlang programs. @@ -1043,7 +1043,7 @@ get_deps(L, Dep) -> %% is_escape_op(_F, _A) -> []. --spec is_escape_op(module(), atom(), arity()) -> [arity()]. +-spec is_escape_op(atom(), atom(), arity()) -> [arity()]. is_escape_op(erlang, '!', 2) -> [2]; is_escape_op(erlang, send, 2) -> [2]; @@ -1064,7 +1064,7 @@ is_escape_op(_M, _F, _A) -> []. is_imm_op(match_fail, 1) -> true; is_imm_op(_, _) -> false. --spec is_imm_op(module(), atom(), arity()) -> boolean(). +-spec is_imm_op(atom(), atom(), arity()) -> boolean(). is_imm_op(erlang, self, 0) -> true; is_imm_op(erlang, '=:=', 2) -> true; @@ -1102,4 +1102,4 @@ is_imm_op(erlang, throw, 1) -> true; is_imm_op(erlang, exit, 1) -> true; is_imm_op(erlang, error, 1) -> true; is_imm_op(erlang, error, 2) -> true; -is_imm_op(_, _, _) -> false. +is_imm_op(_M, _F, _A) -> false. diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl index 38342870e5..6eeeab3610 100644 --- a/lib/hipe/cerl/erl_bif_types.erl +++ b/lib/hipe/cerl/erl_bif_types.erl @@ -143,6 +143,51 @@ type(M, F, A) -> -spec type(atom(), atom(), arity(), [erl_types:erl_type()]) -> erl_types:erl_type(). +%%-- binary ------------------------------------------------------------------- +type(binary, at, 2, Xs) -> + strict(arg_types(binary, at, 2), Xs, fun(_) -> t_integer() end); +type(binary, bin_to_list, Arity, Xs) when 1 =< Arity, Arity =< 3 -> + strict(arg_types(binary, bin_to_list, Arity), Xs, + fun(_) -> t_list(t_integer()) end); +type(binary, compile_pattern, 1, Xs) -> + strict(arg_types(binary, compile_pattern, 1), Xs, + fun(_) -> t_tuple([t_atom(bm),t_binary()]) end); +type(binary, copy, Arity, Xs) when Arity =:= 1; Arity =:= 2 -> + strict(arg_types(binary, copy, Arity), Xs, + fun(_) -> t_binary() end); +type(binary, decode_unsigned, Arity, Xs) when Arity =:= 1; Arity =:= 2 -> + strict(arg_types(binary, decode_unsigned, Arity), Xs, + fun(_) -> t_non_neg_integer() end); +type(binary, encode_unsigned, Arity, Xs) when Arity =:= 1; Arity =:= 2 -> + strict(arg_types(binary, encode_unsigned, Arity), Xs, + fun(_) -> t_binary() end); +type(binary, first, 1, Xs) -> + strict(arg_types(binary, first, 1), Xs, fun(_) -> t_non_neg_integer() end); +type(binary, last, 1, Xs) -> + strict(arg_types(binary, last, 1), Xs, fun(_) -> t_non_neg_integer() end); +type(binary, list_to_bin, 1, Xs) -> + type(erlang, list_to_binary, 1, Xs); +type(binary, longest_common_prefix, 1, Xs) -> + strict(arg_types(binary, longest_common_prefix, 1), Xs, + fun(_) -> t_integer() end); +type(binary, longest_common_suffix, 1, Xs) -> + strict(arg_types(binary, longest_common_suffix, 1), Xs, + fun(_) -> t_integer() end); +type(binary, match, Arity, Xs) when Arity =:= 2; Arity =:= 3 -> + strict(arg_types(binary, match, Arity), Xs, + fun(_) -> + t_sup(t_atom('nomatch'), t_binary_canonical_part()) + end); +type(binary, matches, Arity, Xs) when Arity =:= 2; Arity =:= 3 -> + strict(arg_types(binary, matches, Arity), Xs, + fun(_) -> t_list(t_binary_canonical_part()) end); +type(binary, part, 2, Xs) -> + type(erlang, binary_part, 2, Xs); +type(binary, part, 3, Xs) -> + type(erlang, binary_part, 3, Xs); +type(binary, referenced_byte_size, 1, Xs) -> + strict(arg_types(binary, referenced_byte_size, 1), Xs, + fun(_) -> t_non_neg_integer() end); %%-- code --------------------------------------------------------------------- type(code, add_path, 1, Xs) -> strict(arg_types(code, add_path, 1), Xs, @@ -665,6 +710,14 @@ type(erlang, 'bnot', 1, Xs) -> %% strict(arg_types(erlang, 'bnot', 1), Xs, fun (_) -> t_integer() end); type(erlang, abs, 1, Xs) -> strict(arg_types(erlang, abs, 1), Xs, fun ([X]) -> X end); +type(erlang, adler32, 1, Xs) -> + strict(arg_types(erlang, adler32, 1), Xs, fun (_) -> t_adler32() end); +type(erlang, adler32, 2, Xs) -> + strict(arg_types(erlang, adler32, 2), Xs, fun (_) -> t_adler32() end); +type(erlang, adler32_combine, 3, Xs) -> + strict(arg_types(erlang, adler32_combine, 3), Xs, + fun (_) -> t_adler32() end); +type(erlang, append, 2, Xs) -> type(erlang, '++', 2, Xs); % alias type(erlang, append_element, 2, Xs) -> strict(arg_types(erlang, append_element, 2), Xs, fun (_) -> t_tuple() end); type(erlang, apply, 2, Xs) -> @@ -683,6 +736,10 @@ type(erlang, atom_to_binary, 2, Xs) -> strict(arg_types(erlang, atom_to_binary, 2), Xs, fun (_) -> t_binary() end); type(erlang, atom_to_list, 1, Xs) -> strict(arg_types(erlang, atom_to_list, 1), Xs, fun (_) -> t_string() end); +type(erlang, binary_part, 2, Xs) -> + strict(arg_types(erlang, binary_part, 2), Xs, fun (_) -> t_binary() end); +type(erlang, binary_part, 3, Xs) -> + strict(arg_types(erlang, binary_part, 3), Xs, fun (_) -> t_binary() end); type(erlang, binary_to_atom, 2, Xs) -> strict(arg_types(erlang, binary_to_atom, 2), Xs, fun (_) -> t_atom() end); type(erlang, binary_to_existing_atom, 2, Xs) -> @@ -726,11 +783,11 @@ type(erlang, check_process_code, 2, Xs) -> type(erlang, concat_binary, 1, Xs) -> strict(arg_types(erlang, concat_binary, 1), Xs, fun (_) -> t_binary() end); type(erlang, crc32, 1, Xs) -> - strict(arg_types(erlang, crc32, 1), Xs, fun (_) -> t_integer() end); + strict(arg_types(erlang, crc32, 1), Xs, fun (_) -> t_crc32() end); type(erlang, crc32, 2, Xs) -> - strict(arg_types(erlang, crc32, 2), Xs, fun (_) -> t_integer() end); + strict(arg_types(erlang, crc32, 2), Xs, fun (_) -> t_crc32() end); type(erlang, crc32_combine, 3, Xs) -> - strict(arg_types(erlang, crc32_combine, 3), Xs, fun (_) -> t_integer() end); + strict(arg_types(erlang, crc32_combine, 3), Xs, fun (_) -> t_crc32() end); type(erlang, date, 0, _) -> t_date(); type(erlang, decode_packet, 3, Xs) -> @@ -752,6 +809,10 @@ type(erlang, demonitor, 2, Xs) -> type(erlang, disconnect_node, 1, Xs) -> strict(arg_types(erlang, disconnect_node, 1), Xs, fun (_) -> t_boolean() end); type(erlang, display, 1, _) -> t_atom('true'); +type(erlang, display_string, 1, Xs) -> + strict(arg_types(erlang, display_string, 1), Xs, fun(_) -> t_atom('true') end); +type(erlang, display_nl, 0, _) -> + t_atom('true'); type(erlang, dist_exit, 3, Xs) -> strict(arg_types(erlang, dist_exit, 3), Xs, fun (_) -> t_atom('true') end); type(erlang, element, 2, Xs) -> @@ -802,6 +863,8 @@ type(erlang, fun_to_list, 1, Xs) -> type(erlang, garbage_collect, 0, _) -> t_atom('true'); type(erlang, garbage_collect, 1, Xs) -> strict(arg_types(erlang, garbage_collect, 1), Xs, fun (_) -> t_boolean() end); +type(erlang, garbage_collect_message_area, 0, _) -> + t_boolean(); type(erlang, get, 0, _) -> t_list(t_tuple(2)); type(erlang, get, 1, _) -> t_any(); % | t_atom('undefined') type(erlang, get_cookie, 0, _) -> t_atom(); % | t_atom('nocookie') @@ -851,6 +914,9 @@ type(erlang, hd, 1, Xs) -> type(erlang, integer_to_list, 1, Xs) -> strict(arg_types(erlang, integer_to_list, 1), Xs, fun (_) -> t_string() end); +type(erlang, integer_to_list, 2, Xs) -> + strict(arg_types(erlang, integer_to_list, 2), Xs, + fun (_) -> t_string() end); type(erlang, info, 1, Xs) -> type(erlang, system_info, 1, Xs); % alias type(erlang, iolist_size, 1, Xs) -> strict(arg_types(erlang, iolist_size, 1), Xs, @@ -1056,15 +1122,26 @@ type(erlang, list_to_float, 1, Xs) -> type(erlang, list_to_integer, 1, Xs) -> strict(arg_types(erlang, list_to_integer, 1), Xs, fun (_) -> t_integer() end); +type(erlang, list_to_integer, 2, Xs) -> + strict(arg_types(erlang, list_to_integer, 2), Xs, + fun (_) -> t_integer() end); type(erlang, list_to_pid, 1, Xs) -> strict(arg_types(erlang, list_to_pid, 1), Xs, fun (_) -> t_pid() end); type(erlang, list_to_tuple, 1, Xs) -> strict(arg_types(erlang, list_to_tuple, 1), Xs, fun (_) -> t_tuple() end); -type(erlang, loaded, 0, _) -> - t_list(t_atom()); type(erlang, load_module, 2, Xs) -> strict(arg_types(erlang, load_module, 2), Xs, fun ([Mod,_Bin]) -> t_code_load_return(Mod) end); +type(erlang, load_nif, 2, Xs) -> + strict(arg_types(erlang, load_nif, 2), Xs, + fun (_) -> + Reason = t_atoms(['load_failed', 'bad_lib', 'load', + 'reload', 'upgrade', 'old_code']), + RsnPair = t_tuple([Reason, t_string()]), + t_sup(t_atom('ok'), t_tuple([t_atom('error'), RsnPair])) + end); +type(erlang, loaded, 0, _) -> + t_list(t_atom()); type(erlang, localtime, 0, Xs) -> type(erlang, universaltime, 0, Xs); % same type(erlang, localtime_to_universaltime, 1, Xs) -> @@ -1141,6 +1218,10 @@ type(erlang, monitor_node, 2, Xs) -> type(erlang, monitor_node, 3, Xs) -> strict(arg_types(erlang, monitor_node, 3), Xs, fun (_) -> t_atom('true') end); +type(erlang, nif_error, 1, _) -> + t_any(); +type(erlang, nif_error, 2, Xs) -> + strict(arg_types(erlang, nif_error, 2), Xs, fun (_) -> t_any() end); type(erlang, node, 0, _) -> t_node(); type(erlang, node, 1, Xs) -> strict(arg_types(erlang, node, 1), Xs, fun (_) -> t_node() end); @@ -1159,8 +1240,8 @@ type(erlang, phash2, 2, Xs) -> strict(arg_types(erlang, phash2, 2), Xs, fun (_) -> t_non_neg_integer() end); type(erlang, pid_to_list, 1, Xs) -> strict(arg_types(erlang, pid_to_list, 1), Xs, fun (_) -> t_string() end); -type(erlang, port_call, 3, Xs) -> - strict(arg_types(erlang, port_call, 3), Xs, fun (_) -> t_any() end); +type(erlang, port_call, Arity, Xs) when Arity =:= 2; Arity =:= 3 -> + strict(arg_types(erlang, port_call, Arity), Xs, fun (_) -> t_any() end); type(erlang, port_close, 1, Xs) -> strict(arg_types(erlang, port_close, 1), Xs, fun (_) -> t_atom('true') end); @@ -1489,6 +1570,7 @@ type(erlang, statistics, 1, Xs) -> T_statistics_1 end end); +type(erlang, subtract, 2, Xs) -> type(erlang, '--', 2, Xs); % alias type(erlang, suspend_process, 1, Xs) -> strict(arg_types(erlang, suspend_process, 1), Xs, fun (_) -> t_atom('true') end); @@ -1556,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()), @@ -1577,11 +1658,10 @@ 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_sup([t_atom('big'), t_atom('little')]); + t_endian(); ['fullsweep_after'] -> t_tuple([t_atom('fullsweep_after'), t_non_neg_integer()]); ['garbage_collection'] -> @@ -1593,9 +1673,8 @@ type(erlang, system_info, 1, Xs) -> ['heap_type'] -> t_sup([t_atom('private'), t_atom('hybrid')]); ['hipe_architecture'] -> - t_sup([t_atom('amd64'), t_atom('arm'), - t_atom('powerpc'), t_atom('undefined'), - t_atom('ultrasparc'), t_atom('x86')]); + t_atoms(['amd64', 'arm', 'powerpc', 'ppc64', + 'undefined', 'ultrasparc', 'x86']); ['info'] -> t_binary(); ['internal_cpu_topology'] -> %% Undocumented internal feature @@ -1771,11 +1850,21 @@ type(erts_debug, disassemble, 1, Xs) -> fun (_) -> t_sup([t_atom('false'), t_atom('undef'), t_tuple([t_integer(), t_binary(), t_mfa()])]) end); +type(erts_debug, display, 1, _) -> + t_string(); type(erts_debug, dist_ext_to_term, 2, Xs) -> strict(arg_types(erts_debug, dist_ext_to_term, 2), Xs, fun (_) -> t_any() end); +type(erts_debug, dump_monitors, 1, Xs) -> + strict(arg_types(erts_debug, dump_monitors, 1), Xs, + fun(_) -> t_atom('true') end); +type(erts_debug, dump_links, 1, Xs) -> + strict(arg_types(erts_debug, dump_links, 1), Xs, + fun(_) -> t_atom('true') end); type(erts_debug, flat_size, 1, Xs) -> strict(arg_types(erts_debug, flat_size, 1), Xs, fun (_) -> t_integer() end); +type(erts_debug, get_internal_state, 1, _) -> + t_any(); type(erts_debug, lock_counters, 1, Xs) -> strict(arg_types(erts_debug, lock_counters, 1), Xs, fun ([Arg]) -> @@ -1796,6 +1885,8 @@ type(erts_debug, lock_counters, 1, Xs) -> end); type(erts_debug, same, 2, Xs) -> strict(arg_types(erts_debug, same, 2), Xs, fun (_) -> t_boolean() end); +type(erts_debug, set_internal_state, 2, _) -> + t_any(); %%-- ets ---------------------------------------------------------------------- type(ets, all, 0, _) -> t_list(t_tab()); @@ -2085,7 +2176,7 @@ type(hipe_bifs, set_native_address, 3, Xs) -> strict(arg_types(hipe_bifs, set_native_address, 3), Xs, fun (_) -> t_nil() end); type(hipe_bifs, system_crc, 1, Xs) -> - strict(arg_types(hipe_bifs, system_crc, 1), Xs, fun (_) -> t_integer() end); + strict(arg_types(hipe_bifs, system_crc, 1), Xs, fun (_) -> t_crc32() end); type(hipe_bifs, term_to_word, 1, Xs) -> strict(arg_types(hipe_bifs, term_to_word, 1), Xs, fun (_) -> t_integer() end); @@ -2244,8 +2335,7 @@ type(lists, flatten, 1, Xs) -> t_list(); false -> X2 = type(lists, flatten, 1, [t_inf(X1, t_list())]), - t_sup(t_list(t_subtract(X1, t_list())), - X2) + t_sup(t_list(t_subtract(X1, t_list())), X2) end end end); @@ -2256,10 +2346,20 @@ type(lists, flatmap, 2, Xs) -> true -> t_nil(); false -> case check_fun_application(F, [t_list_elements(List)]) of - ok -> - case t_is_cons(List) of - true -> t_nonempty_list(t_list_elements(t_fun_range(F))); - false -> t_list(t_list_elements(t_fun_range(F))) + ok -> + R = t_fun_range(F), + case t_is_nil(R) of + true -> t_nil(); + false -> + Elems = t_list_elements(R), + case t_is_cons(List) of + true -> + case t_is_subtype(t_nil(), R) of + true -> t_list(Elems); + false -> t_nonempty_list(Elems) + end; + false -> t_list(Elems) + end end; error -> case t_is_cons(List) of @@ -3180,6 +3280,53 @@ arith(Op, X1, X2) -> -spec arg_types(atom(), atom(), arity()) -> [erl_types:erl_type()] | 'unknown'. +%%------- binary -------------------------------------------------------------- +arg_types(binary, at, 2) -> + [t_binary(), t_non_neg_integer()]; +arg_types(binary, bin_to_list, 1) -> + [t_binary()]; +arg_types(binary, bin_to_list, 2) -> + [t_binary(), t_binary_part()]; +arg_types(binary, bin_to_list, 3) -> + [t_binary(), t_integer(), t_non_neg_integer()]; +arg_types(binary, compile_pattern, 1) -> + [t_sup(t_binary(), t_list(t_binary()))]; +arg_types(binary, copy, 1) -> + [t_binary()]; +arg_types(binary, copy, 2) -> + [t_binary(), t_non_neg_integer()]; +arg_types(binary, decode_unsigned, 1) -> + [t_binary()]; +arg_types(binary, decode_unsigned, 2) -> + [t_binary(), t_endian()]; +arg_types(binary, encode_unsigned, 1) -> + [t_non_neg_integer()]; +arg_types(binary, encode_unsigned, 2) -> + [t_non_neg_integer(), t_endian()]; +arg_types(binary, first, 1) -> + [t_binary()]; +arg_types(binary, last, 1) -> + [t_binary()]; +arg_types(binary, list_to_bin, 1) -> + arg_types(erlang, list_to_binary, 1); +arg_types(binary, longest_common_prefix, 1) -> + [t_list(t_binary())]; +arg_types(binary, longest_common_suffix, 1) -> + [t_list(t_binary())]; +arg_types(binary, match, 2) -> + [t_binary(), t_binary_pattern()]; +arg_types(binary, match, 3) -> + [t_binary(), t_binary_pattern(), t_binary_options()]; +arg_types(binary, matches, 2) -> + [t_binary(), t_binary_pattern()]; +arg_types(binary, matches, 3) -> + [t_binary(), t_binary_pattern(), t_binary_options()]; +arg_types(binary, part, 2) -> + arg_types(erlang, binary_part, 2); +arg_types(binary, part, 3) -> + arg_types(erlang, binary_part, 3); +arg_types(binary, referenced_byte_size, 1) -> + [t_binary()]; %%------- code ---------------------------------------------------------------- arg_types(code, add_path, 1) -> [t_string()]; @@ -3361,6 +3508,14 @@ arg_types(erlang, 'bnot', 1) -> [t_integer()]; arg_types(erlang, abs, 1) -> [t_number()]; +arg_types(erlang, adler32, 1) -> + [t_iodata()]; +arg_types(erlang, adler32, 2) -> + [t_adler32(), t_iodata()]; +arg_types(erlang, adler32_combine, 3) -> + [t_adler32(), t_adler32(), t_non_neg_integer()]; +arg_types(erlang, append, 2) -> + arg_types(erlang, '++', 2); arg_types(erlang, append_element, 2) -> [t_tuple(), t_any()]; arg_types(erlang, apply, 2) -> @@ -3374,6 +3529,10 @@ arg_types(erlang, atom_to_binary, 2) -> [t_atom(), t_encoding_a2b()]; arg_types(erlang, atom_to_list, 1) -> [t_atom()]; +arg_types(erlang, binary_part, 2) -> + [t_binary(), t_tuple([t_integer(),t_integer()])]; +arg_types(erlang, binary_part, 3) -> + [t_binary(), t_integer(), t_integer()]; arg_types(erlang, binary_to_atom, 2) -> [t_binary(), t_encoding_a2b()]; arg_types(erlang, binary_to_existing_atom, 2) -> @@ -3409,9 +3568,9 @@ arg_types(erlang, concat_binary, 1) -> arg_types(erlang, crc32, 1) -> [t_iodata()]; arg_types(erlang, crc32, 2) -> - [t_integer(), t_iodata()]; + [t_crc32(), t_iodata()]; arg_types(erlang, crc32_combine, 3) -> - [t_integer(), t_integer(), t_integer()]; + [t_crc32(), t_crc32(), t_non_neg_integer()]; arg_types(erlang, date, 0) -> []; arg_types(erlang, decode_packet, 3) -> @@ -3426,6 +3585,10 @@ arg_types(erlang, disconnect_node, 1) -> [t_node()]; arg_types(erlang, display, 1) -> [t_any()]; +arg_types(erlang, display_nl, 0) -> + []; +arg_types(erlang, display_string, 1) -> + [t_string()]; arg_types(erlang, dist_exit, 3) -> [t_pid(), t_dist_exit(), t_sup(t_pid(), t_port())]; arg_types(erlang, element, 2) -> @@ -3462,6 +3625,8 @@ arg_types(erlang, garbage_collect, 0) -> []; arg_types(erlang, garbage_collect, 1) -> [t_pid()]; +arg_types(erlang, garbage_collect_message_area, 0) -> + []; arg_types(erlang, get, 0) -> []; arg_types(erlang, get, 1) -> @@ -3498,6 +3663,8 @@ arg_types(erlang, iolist_size, 1) -> [t_sup(t_iolist(), t_binary())]; arg_types(erlang, integer_to_list, 1) -> [t_integer()]; +arg_types(erlang, integer_to_list, 2) -> + [t_integer(), t_from_range(2, 36)]; arg_types(erlang, is_alive, 0) -> []; arg_types(erlang, is_atom, 1) -> @@ -3558,14 +3725,18 @@ arg_types(erlang, list_to_float, 1) -> [t_list(t_byte())]; arg_types(erlang, list_to_integer, 1) -> [t_list(t_byte())]; +arg_types(erlang, list_to_integer, 2) -> + [t_list(t_byte()), t_from_range(2, 36)]; arg_types(erlang, list_to_pid, 1) -> [t_string()]; arg_types(erlang, list_to_tuple, 1) -> [t_list()]; -arg_types(erlang, loaded, 0) -> - []; arg_types(erlang, load_module, 2) -> [t_atom(), t_binary()]; +arg_types(erlang, load_nif, 2) -> + [t_string(), t_any()]; +arg_types(erlang, loaded, 0) -> + []; arg_types(erlang, localtime, 0) -> []; arg_types(erlang, localtime_to_universaltime, 1) -> @@ -3608,6 +3779,10 @@ arg_types(erlang, monitor_node, 2) -> [t_node(), t_boolean()]; arg_types(erlang, monitor_node, 3) -> [t_node(), t_boolean(), t_list(t_atom('allow_passive_connect'))]; +arg_types(erlang, nif_error, 1) -> + [t_any()]; +arg_types(erlang, nif_error, 2) -> + [t_any(), t_list()]; arg_types(erlang, node, 0) -> []; arg_types(erlang, node, 1) -> @@ -3648,6 +3823,8 @@ arg_types(erlang, phash2, 2) -> [t_any(), t_pos_integer()]; arg_types(erlang, pid_to_list, 1) -> [t_pid()]; +arg_types(erlang, port_call, 2) -> + [t_sup(t_port(), t_atom()), t_any()]; arg_types(erlang, port_call, 3) -> [t_sup(t_port(), t_atom()), t_integer(), t_any()]; arg_types(erlang, port_close, 1) -> @@ -3775,6 +3952,8 @@ arg_types(erlang, statistics, 1) -> t_atom('run_queue'), t_atom('runtime'), t_atom('wall_clock')])]; +arg_types(erlang, subtract, 2) -> + arg_types(erlang, '--', 2); arg_types(erlang, suspend_process, 1) -> [t_pid()]; arg_types(erlang, suspend_process, 2) -> @@ -3854,7 +4033,8 @@ arg_types(erlang, trace_info, 2) -> t_atom('flags'), t_atom('tracer'), %% while the following are items about a func t_atom('traced'), t_atom('match_spec'), t_atom('meta'), - t_atom('meta_match_spec'), t_atom('call_count'), t_atom('all')])]; + t_atom('meta_match_spec'), t_atom('call_count'), + t_atom('call_time'), t_atom('all')])]; arg_types(erlang, trace_pattern, 2) -> [t_sup(t_tuple([t_atom(), t_atom(), t_sup(t_arity(), t_atom('_'))]), t_atom('on_load')), @@ -3863,7 +4043,7 @@ arg_types(erlang, trace_pattern, 3) -> arg_types(erlang, trace_pattern, 2) ++ [t_list(t_sup([t_atom('global'), t_atom('local'), t_atom('meta'), t_tuple([t_atom('meta'), t_pid()]), - t_atom('call_count')]))]; + t_atom('call_count'), t_atom('call_time')]))]; arg_types(erlang, trunc, 1) -> [t_number()]; arg_types(erlang, tuple_size, 1) -> @@ -3897,10 +4077,18 @@ arg_types(erts_debug, breakpoint, 2) -> [t_tuple([t_atom(), t_atom(), t_sup(t_integer(), t_atom('_'))]), t_boolean()]; arg_types(erts_debug, disassemble, 1) -> [t_sup(t_mfa(), t_integer())]; +arg_types(erts_debug, display, 1) -> + [t_any()]; arg_types(erts_debug, dist_ext_to_term, 2) -> [t_tuple(), t_binary()]; +arg_types(erts_debug, dump_monitors, 1) -> + [t_sup([t_pid(),t_atom()])]; +arg_types(erts_debug, dump_links, 1) -> + [t_sup([t_pid(),t_atom(),t_port()])]; arg_types(erts_debug, flat_size, 1) -> [t_any()]; +arg_types(erts_debug, get_internal_state, 1) -> + [t_any()]; arg_types(erts_debug, lock_counters, 1) -> [t_sup([t_atom(enabled), t_atom(info), @@ -3909,6 +4097,8 @@ arg_types(erts_debug, lock_counters, 1) -> t_tuple([t_atom(process_locks), t_boolean()])])]; arg_types(erts_debug, same, 2) -> [t_any(), t_any()]; +arg_types(erts_debug, set_internal_state, 2) -> + [t_any(), t_any()]; %%------- ets ----------------------------------------------------------------- arg_types(ets, all, 0) -> []; @@ -4089,7 +4279,7 @@ arg_types(hipe_bifs, call_count_off, 1) -> arg_types(hipe_bifs, call_count_on, 1) -> [t_mfa()]; arg_types(hipe_bifs, check_crc, 1) -> - [t_integer()]; + [t_crc32()]; arg_types(hipe_bifs, enter_code, 2) -> [t_binary(), t_sup(t_nil(), t_tuple())]; arg_types(hipe_bifs, enter_sdesc, 1) -> @@ -4133,7 +4323,7 @@ arg_types(hipe_bifs, set_funinfo_native_address, 3) -> arg_types(hipe_bifs, set_native_address, 3) -> [t_mfa(), t_integer(), t_boolean()]; arg_types(hipe_bifs, system_crc, 1) -> - [t_integer()]; + [t_crc32()]; arg_types(hipe_bifs, term_to_word, 1) -> [t_any()]; arg_types(hipe_bifs, update_code_size, 3) -> @@ -4447,6 +4637,30 @@ t_httppacket() -> t_sup([t_HttpRequest(), t_HttpResponse(), t_HttpHeader(), t_atom('http_eoh'), t_HttpError()]). +t_endian() -> + t_sup([t_atom('big'), t_atom('little')]). + +%% ===================================================================== +%% Types for the binary module +%% ===================================================================== + +t_binary_part() -> + t_tuple([t_non_neg_integer(),t_integer()]). + +t_binary_canonical_part() -> + t_tuple([t_non_neg_integer(),t_non_neg_integer()]). + +t_binary_pattern() -> + t_sup([t_binary(), + t_list(t_binary()), + t_binary_compiled_pattern()]). + +t_binary_compiled_pattern() -> + t_tuple([t_atom('cp'),t_binary()]). + +t_binary_options() -> + t_list(t_tuple([t_atom('scope'),t_binary_part()])). + %% ===================================================================== %% HTTP types documented in R12B-4 %% ===================================================================== @@ -4529,12 +4743,18 @@ t_code_loaded_fname_or_status() -> %% These are used for the built-in functions of 'erlang' %% ===================================================================== +t_adler32() -> + t_non_neg_integer(). + +t_crc32() -> + t_non_neg_integer(). + t_decode_packet_option() -> t_sup([t_tuple([t_atom('packet_size'), t_non_neg_integer()]), t_tuple([t_atom('line_length'), t_non_neg_integer()])]). t_decode_packet_type() -> - t_sup(t_inet_setoption_packettype(), t_atom('httph')). + t_sup([t_inet_setoption_packettype(), t_atom('httph'), t_atom('httph_bin')]). t_dist_exit() -> t_sup([t_atom('kill'), t_atom('noconnection'), t_atom('normal')]). diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl index b4d80d359a..9a40be6d14 100644 --- a/lib/hipe/cerl/erl_types.erl +++ b/lib/hipe/cerl/erl_types.erl @@ -178,7 +178,7 @@ t_remote/3, t_string/0, t_struct_from_opaque/2, - t_solve_remote/2, + t_solve_remote/3, t_subst/2, t_subtract/2, t_subtract_list/2, @@ -205,11 +205,14 @@ t_var_name/1, %% t_assign_variables_to_subtype/2, type_is_defined/3, + record_field_diffs_to_string/2, subst_all_vars_to_any/1, - lift_list_to_pos_empty/1 + lift_list_to_pos_empty/1, + is_erl_type/1 ]). %%-define(DO_ERL_TYPES_TEST, true). +-compile({no_auto_import,[min/2,max/2]}). -ifdef(DO_ERL_TYPES_TEST). -export([test/0]). @@ -221,6 +224,8 @@ -export([t_is_identifier/1]). -endif. +-export_type([erl_type/0]). + %%============================================================================= %% %% Definition of the type structure @@ -299,7 +304,7 @@ %% Auxiliary types and convenient macros %% --type parse_form() :: {atom(), _, _} | {atom(), _, _, _}. %% XXX: Temporarily +-type parse_form() :: {atom(), _, _} | {atom(), _, _, _} | {'op', _, _, _, _}. %% XXX: Temporarily -type rng_elem() :: 'pos_inf' | 'neg_inf' | integer(). -record(int_set, {set :: [integer()]}). @@ -322,7 +327,7 @@ -define(nil, #c{tag=?nil_tag}). -define(nonempty_list(Types, Term),?list(Types, Term, ?nonempty_qual)). -define(number(Set, Qualifier), #c{tag=?number_tag, elements=Set, - qualifier=Qualifier}. + qualifier=Qualifier}). -define(opaque(Optypes), #c{tag=?opaque_tag, elements=Optypes}). -define(product(Types), #c{tag=?product_tag, elements=Types}). -define(remote(RemTypes), #c{tag=?remote_tag, elements=RemTypes}). @@ -398,7 +403,8 @@ t_is_none(_) -> false. -spec t_opaque(module(), atom(), [_], erl_type()) -> erl_type(). t_opaque(Mod, Name, Args, Struct) -> - ?opaque(set_singleton(#opaque{mod=Mod, name=Name, args=Args, struct=Struct})). + O = #opaque{mod = Mod, name = Name, args = Args, struct = Struct}, + ?opaque(set_singleton(O)). -spec t_is_opaque(erl_type()) -> boolean(). @@ -427,7 +433,7 @@ t_opaque_structure(?opaque(Elements)) -> t_opaque_module(?opaque(Elements)) -> case ordsets:size(Elements) of 1 -> - [#opaque{mod=Module}] = ordsets:to_list(Elements), + [#opaque{mod = Module}] = ordsets:to_list(Elements), Module; _ -> throw({error, "Unexpected multiple opaque types"}) end. @@ -631,7 +637,7 @@ t_unopaque_on_mismatch(GenType, Type, Opaques) -> case t_inf(GenType, Type) of ?none -> Unopaqued = t_unopaque(Type, Opaques), - %% Unions might be a problem, must investigate. + %% XXX: Unions might be a problem, must investigate. case t_inf(GenType, Unopaqued) of ?none -> Type; _ -> Unopaqued @@ -643,12 +649,12 @@ t_unopaque_on_mismatch(GenType, Type, Opaques) -> module_builtin_opaques(Module) -> [O || O <- all_opaque_builtins(), t_opaque_module(O) =:= Module]. - + %%----------------------------------------------------------------------------- -%% Remote types -%% These types are used for preprocessing they should never reach the analysis stage +%% Remote types: these types are used for preprocessing; +%% they should never reach the analysis stage. --spec t_remote(module(), atom(), [_]) -> erl_type(). +-spec t_remote(atom(), atom(), [erl_type()]) -> erl_type(). t_remote(Mod, Name, Args) -> ?remote(set_singleton(#remote{mod = Mod, name = Name, args = Args})). @@ -658,126 +664,132 @@ t_remote(Mod, Name, Args) -> t_is_remote(?remote(_)) -> true; t_is_remote(_) -> false. --spec t_solve_remote(erl_type(), dict()) -> erl_type(). +-spec t_solve_remote(erl_type(), set(), dict()) -> erl_type(). -t_solve_remote(Type , Records) -> - {RT, _RR} = t_solve_remote(Type, Records, []), +t_solve_remote(Type, ExpTypes, Records) -> + {RT, _RR} = t_solve_remote(Type, ExpTypes, Records, []), RT. -t_solve_remote(?function(Domain, Range), R, C) -> - {RT1, RR1} = t_solve_remote(Domain, R, C), - {RT2, RR2} = t_solve_remote(Range, R, C), +t_solve_remote(?function(Domain, Range), ET, R, C) -> + {RT1, RR1} = t_solve_remote(Domain, ET, R, C), + {RT2, RR2} = t_solve_remote(Range, ET, R, C), {?function(RT1, RT2), RR1 ++ RR2}; -t_solve_remote(?list(Types, Term, Size), R, C) -> - {RT, RR} = t_solve_remote(Types, R, C), +t_solve_remote(?list(Types, Term, Size), ET, R, C) -> + {RT, RR} = t_solve_remote(Types, ET, R, C), {?list(RT, Term, Size), RR}; -t_solve_remote(?product(Types), R, C) -> - {RL, RR} = list_solve_remote(Types, R, C), +t_solve_remote(?product(Types), ET, R, C) -> + {RL, RR} = list_solve_remote(Types, ET, R, C), {?product(RL), RR}; -t_solve_remote(?opaque(Set), R, C) -> +t_solve_remote(?opaque(Set), ET, R, C) -> List = ordsets:to_list(Set), - {NewList, RR} = opaques_solve_remote(List, R, C), + {NewList, RR} = opaques_solve_remote(List, ET, R, C), {?opaque(ordsets:from_list(NewList)), RR}; -t_solve_remote(?tuple(?any, _, _) = T, _R, _C) -> {T, []}; -t_solve_remote(?tuple(Types, Arity, Tag), R, C) -> - {RL, RR} = list_solve_remote(Types, R, C), +t_solve_remote(?tuple(?any, _, _) = T, _ET, _R, _C) -> {T, []}; +t_solve_remote(?tuple(Types, Arity, Tag), ET, R, C) -> + {RL, RR} = list_solve_remote(Types, ET, R, C), {?tuple(RL, Arity, Tag), RR}; -t_solve_remote(?tuple_set(Set), R, C) -> - {NewSet, RR} = tuples_solve_remote(Set, R, C), +t_solve_remote(?tuple_set(Set), ET, R, C) -> + {NewSet, RR} = tuples_solve_remote(Set, ET, R, C), {?tuple_set(NewSet), RR}; -t_solve_remote(?remote(Set), R, C) -> +t_solve_remote(?remote(Set), ET, R, C) -> RemoteList = ordsets:to_list(Set), - {RL, RR} = list_solve_remote_type(RemoteList, R, C), + {RL, RR} = list_solve_remote_type(RemoteList, ET, R, C), {t_sup(RL), RR}; -t_solve_remote(?union(List), R, C) -> - {RL, RR} = list_solve_remote(List, R, C), +t_solve_remote(?union(List), ET, R, C) -> + {RL, RR} = list_solve_remote(List, ET, R, C), {t_sup(RL), RR}; -t_solve_remote(T, _R, _C) -> {T, []}. +t_solve_remote(T, _ET, _R, _C) -> {T, []}. t_solve_remote_type(#remote{mod = RemMod, name = Name, args = Args} = RemType, - R, C) -> + ET, R, C) -> + ArgsLen = length(Args), case dict:find(RemMod, R) of error -> - Msg = io_lib:format("Cannot locate module ~w to " - "resolve the remote type: ~w:~w()~n", - [RemMod, RemMod, Name]), - throw({error, Msg}); + self() ! {self(), ext_types, {RemMod, Name, ArgsLen}}, + {t_any(), []}; {ok, RemDict} -> - case lookup_type(Name, RemDict) of - {type, {_Mod, Type, ArgNames}} when length(Args) =:= length(ArgNames) -> - {NewType, NewCycle, NewRR} = - case unfold(RemType, C) of - true -> - List = lists:zip(ArgNames, Args), - TmpVarDict = dict:from_list(List), - {t_from_form(Type, RemDict, TmpVarDict), [RemType|C], []}; - false -> {t_any(), C, [RemType]} - end, - {RT, RR} = t_solve_remote(NewType, R, NewCycle), - RetRR = NewRR ++ RR, - RT1 = - case lists:member(RemType, RetRR) of - true -> t_limit(RT, ?REC_TYPE_LIMIT); - false -> RT - end, - {RT1, RetRR}; - {opaque, {Mod, Type, ArgNames}} when length(Args) =:= length(ArgNames) -> - List = lists:zip(ArgNames, Args), - TmpVarDict = dict:from_list(List), - {Rep, NewCycle, NewRR} = - case unfold(RemType, C) of - true -> {t_from_form(Type, RemDict, TmpVarDict), [RemType|C], []}; - false -> {t_any(), C, [RemType]} - end, - {NewRep, RR} = t_solve_remote(Rep, R, NewCycle), - RetRR = NewRR ++ RR, - RT1 = - case lists:member(RemType, RetRR) of - true -> t_limit(NewRep, ?REC_TYPE_LIMIT); - false -> NewRep - end, - {t_from_form({opaque, -1, Name, {Mod, Args, RT1}}, - RemDict, TmpVarDict), - RetRR}; - {type, _} -> - Msg = io_lib:format("Unknown remote type ~w\n", [Name]), - throw({error, Msg}); - {opaque, _} -> - Msg = io_lib:format("Unknown remote opaque type ~w\n", [Name]), - throw({error, Msg}); - error -> - Msg = io_lib:format("Unable to find remote type ~w:~w()\n", - [RemMod, Name]), - throw({error, Msg}) + MFA = {RemMod, Name, ArgsLen}, + case sets:is_element(MFA, ET) of + true -> + case lookup_type(Name, RemDict) of + {type, {_Mod, Type, ArgNames}} when ArgsLen =:= length(ArgNames) -> + {NewType, NewCycle, NewRR} = + case unfold(RemType, C) of + true -> + List = lists:zip(ArgNames, Args), + TmpVarDict = dict:from_list(List), + {t_from_form(Type, RemDict, TmpVarDict), [RemType|C], []}; + false -> {t_any(), C, [RemType]} + end, + {RT, RR} = t_solve_remote(NewType, ET, R, NewCycle), + RetRR = NewRR ++ RR, + RT1 = + case lists:member(RemType, RetRR) of + true -> t_limit(RT, ?REC_TYPE_LIMIT); + false -> RT + end, + {RT1, RetRR}; + {opaque, {Mod, Type, ArgNames}} when ArgsLen =:= length(ArgNames) -> + List = lists:zip(ArgNames, Args), + TmpVarDict = dict:from_list(List), + {Rep, NewCycle, NewRR} = + case unfold(RemType, C) of + true -> {t_from_form(Type, RemDict, TmpVarDict), [RemType|C], []}; + false -> {t_any(), C, [RemType]} + end, + {NewRep, RR} = t_solve_remote(Rep, ET, R, NewCycle), + RetRR = NewRR ++ RR, + RT1 = + case lists:member(RemType, RetRR) of + true -> t_limit(NewRep, ?REC_TYPE_LIMIT); + false -> NewRep + end, + {t_from_form({opaque, -1, Name, {Mod, Args, RT1}}, + RemDict, TmpVarDict), + RetRR}; + {type, _} -> + Msg = io_lib:format("Unknown remote type ~w\n", [Name]), + throw({error, Msg}); + {opaque, _} -> + Msg = io_lib:format("Unknown remote opaque type ~w\n", [Name]), + throw({error, Msg}); + error -> + Msg = io_lib:format("Unable to find remote type ~w:~w()\n", + [RemMod, Name]), + throw({error, Msg}) + end; + false -> + self() ! {self(), ext_types, {RemMod, Name, ArgsLen}}, + {t_any(), []} end end. -list_solve_remote([], _R, _C) -> +list_solve_remote([], _ET, _R, _C) -> {[], []}; -list_solve_remote([Type|Types], R, C) -> - {RT, RR1} = t_solve_remote(Type, R, C), - {RL, RR2} = list_solve_remote(Types, R, C), +list_solve_remote([Type|Types], ET, R, C) -> + {RT, RR1} = t_solve_remote(Type, ET, R, C), + {RL, RR2} = list_solve_remote(Types, ET, R, C), {[RT|RL], RR1 ++ RR2}. -list_solve_remote_type([], _R, _C) -> +list_solve_remote_type([], _ET, _R, _C) -> {[], []}; -list_solve_remote_type([Type|Types], R, C) -> - {RT, RR1} = t_solve_remote_type(Type, R, C), - {RL, RR2} = list_solve_remote_type(Types, R, C), +list_solve_remote_type([Type|Types], ET, R, C) -> + {RT, RR1} = t_solve_remote_type(Type, ET, R, C), + {RL, RR2} = list_solve_remote_type(Types, ET, R, C), {[RT|RL], RR1 ++ RR2}. -opaques_solve_remote([], _R, _C) -> +opaques_solve_remote([], _ET, _R, _C) -> {[], []}; -opaques_solve_remote([#opaque{struct = Struct} = Remote|Tail], R, C) -> - {RT, RR1} = t_solve_remote(Struct, R, C), - {LOp, RR2} = opaques_solve_remote(Tail, R, C), +opaques_solve_remote([#opaque{struct = Struct} = Remote|Tail], ET, R, C) -> + {RT, RR1} = t_solve_remote(Struct, ET, R, C), + {LOp, RR2} = opaques_solve_remote(Tail, ET, R, C), {[Remote#opaque{struct = RT}|LOp], RR1 ++ RR2}. -tuples_solve_remote([], _R, _C) -> +tuples_solve_remote([], _ET, _R, _C) -> {[], []}; -tuples_solve_remote([{Sz, Tuples}|Tail], R, C) -> - {RL, RR1} = list_solve_remote(Tuples, R, C), - {LSzTpls, RR2} = tuples_solve_remote(Tail, R, C), +tuples_solve_remote([{Sz, Tuples}|Tail], ET, R, C) -> + {RL, RR1} = list_solve_remote(Tuples, ET, R, C), + {LSzTpls, RR2} = tuples_solve_remote(Tail, ET, R, C), {[{Sz, RL}|LSzTpls], RR1 ++ RR2}. %%----------------------------------------------------------------------------- @@ -801,7 +813,7 @@ t_is_none_or_unit(?unit) -> true; t_is_none_or_unit(_) -> false. %%----------------------------------------------------------------------------- -%% Atoms and the derived type bool +%% Atoms and the derived type boolean %% -spec t_atom() -> erl_type(). @@ -1596,7 +1608,7 @@ t_set() -> t_tid() -> t_opaque(ets, tid, [], t_integer()). --spec all_opaque_builtins() -> [erl_type()]. +-spec all_opaque_builtins() -> [erl_type(),...]. all_opaque_builtins() -> [t_array(), t_dict(), t_digraph(), t_gb_set(), @@ -2523,12 +2535,14 @@ t_subst(T, _Dict, _Fun) -> %% Unification %% --spec t_unify(erl_type(), erl_type()) -> {erl_type(), [{_, erl_type()}]}. +-type t_unify_ret() :: {erl_type(), [{_, erl_type()}]}. + +-spec t_unify(erl_type(), erl_type()) -> t_unify_ret(). t_unify(T1, T2) -> t_unify(T1, T2, []). --spec t_unify(erl_type(), erl_type(), [erl_type()]) -> {erl_type(), [{_, erl_type()}]}. +-spec t_unify(erl_type(), erl_type(), [erl_type()]) -> t_unify_ret(). t_unify(T1, T2, Opaques) -> {T, Dict} = t_unify(T1, T2, dict:new(), Opaques), @@ -2541,7 +2555,7 @@ t_unify(?var(Id1) = T, ?var(Id2), Dict, Opaques) -> error -> case dict:find(Id2, Dict) of error -> {T, dict:store(Id2, T, Dict)}; - {ok, Type} -> {Type, t_unify(T, Type, Dict, Opaques)} + {ok, Type} -> t_unify(T, Type, Dict, Opaques) end; {ok, Type1} -> case dict:find(Id2, Dict) of @@ -3298,28 +3312,44 @@ record_to_string(Tag, [_|Fields], FieldNames, RecDict) -> FieldStrings = record_fields_to_string(Fields, FieldNames, RecDict, []), "#" ++ atom_to_list(Tag) ++ "{" ++ sequence(FieldStrings, [], ",") ++ "}". -record_fields_to_string([Field|Left1], [{FieldName, DeclaredType}|Left2], - RecDict, Acc) -> - PrintType = - case t_is_equal(Field, DeclaredType) of - true -> false; +record_fields_to_string([F|Fs], [{FName, _DefType}|FDefs], RecDict, Acc) -> + NewAcc = + case t_is_any(F) orelse t_is_atom('undefined', F) of + true -> Acc; false -> - case t_is_any(DeclaredType) andalso t_is_atom(undefined, Field) of - true -> false; - false -> - TmpType = t_subtract(DeclaredType, t_atom(undefined)), - not t_is_equal(Field, TmpType) - end + StrFV = atom_to_list(FName) ++ "::" ++ t_to_string(F, RecDict), + %% ActualDefType = t_subtract(DefType, t_atom('undefined')), + %% Str = case t_is_any(ActualDefType) of + %% true -> StrFV; + %% false -> StrFV ++ "::" ++ t_to_string(ActualDefType, RecDict) + %% end, + [StrFV|Acc] end, - case PrintType of - false -> record_fields_to_string(Left1, Left2, RecDict, Acc); - true -> - String = atom_to_list(FieldName) ++ "::" ++ t_to_string(Field, RecDict), - record_fields_to_string(Left1, Left2, RecDict, [String|Acc]) - end; + record_fields_to_string(Fs, FDefs, RecDict, NewAcc); record_fields_to_string([], [], _RecDict, Acc) -> lists:reverse(Acc). +-spec record_field_diffs_to_string(erl_type(), dict()) -> string(). + +record_field_diffs_to_string(?tuple([_|Fs], Arity, Tag), RecDict) -> + [TagAtom] = t_atom_vals(Tag), + {ok, FieldNames} = lookup_record(TagAtom, Arity-1, RecDict), + %% io:format("RecCElems = ~p\nRecTypes = ~p\n", [Fs, FieldNames]), + FieldDiffs = field_diffs(Fs, FieldNames, RecDict, []), + sequence(FieldDiffs, [], " and "). + +field_diffs([F|Fs], [{FName, DefType}|FDefs], RecDict, Acc) -> + NewAcc = + case t_is_subtype(F, DefType) of + true -> Acc; + false -> + Str = atom_to_list(FName) ++ "::" ++ t_to_string(DefType, RecDict), + [Str|Acc] + end, + field_diffs(Fs, FDefs, RecDict, NewAcc); +field_diffs([], [], _, Acc) -> + lists:reverse(Acc). + comma_sequence(Types, RecDict) -> List = [case T =:= ?any of true -> "_"; @@ -3338,8 +3368,8 @@ sequence([], [], _Delimiter) -> []; sequence([T], Acc, _Delimiter) -> lists:flatten(lists:reverse([T|Acc])); -sequence([T|Left], Acc, Delimiter) -> - sequence(Left, [T ++ Delimiter|Acc], Delimiter). +sequence([T|Ts], Acc, Delimiter) -> + sequence(Ts, [T ++ Delimiter|Acc], Delimiter). %%============================================================================= %% @@ -3386,6 +3416,18 @@ t_from_form({atom, _L, Atom}, _TypeNames, _RecDict, _VarDict) -> {t_atom(Atom), []}; t_from_form({integer, _L, Int}, _TypeNames, _RecDict, _VarDict) -> {t_integer(Int), []}; +t_from_form({op, _L, _Op, _Arg} = Op, _TypeNames, _RecDict, _VarDict) -> + case erl_eval:partial_eval(Op) of + {integer, _, Val} -> + {t_integer(Val), []}; + _ -> throw({error, io_lib:format("Unable evaluate type ~w\n", [Op])}) + end; +t_from_form({op, _L, _Op, _Arg1, _Arg2} = Op, _TypeNames, _RecDict, _VarDict) -> + case erl_eval:partial_eval(Op) of + {integer, _, Val} -> + {t_integer(Val), []}; + _ -> throw({error, io_lib:format("Unable evaluate type ~w\n", [Op])}) + end; t_from_form({type, _L, any, []}, _TypeNames, _RecDict, _VarDict) -> {t_any(), []}; t_from_form({type, _L, arity, []}, _TypeNames, _RecDict, _VarDict) -> @@ -3396,9 +3438,15 @@ t_from_form({type, _L, atom, []}, _TypeNames, _RecDict, _VarDict) -> {t_atom(), []}; t_from_form({type, _L, binary, []}, _TypeNames, _RecDict, _VarDict) -> {t_binary(), []}; -t_from_form({type, _L, binary, [{integer, _, Base}, {integer, _, Unit}]}, +t_from_form({type, _L, binary, [Base, Unit]} = Type, _TypeNames, _RecDict, _VarDict) -> - {t_bitstr(Unit, Base), []}; + case {erl_eval:partial_eval(Base), erl_eval:partial_eval(Unit)} of + {{integer, _, BaseVal}, + {integer, _, UnitVal}} + when BaseVal >= 0, UnitVal >= 0 -> + {t_bitstr(UnitVal, BaseVal), []}; + _ -> throw({error, io_lib:format("Unable evaluate type ~w\n", [Type])}) + end; t_from_form({type, _L, bitstring, []}, _TypeNames, _RecDict, _VarDict) -> {t_bitstr(), []}; t_from_form({type, _L, bool, []}, _TypeNames, _RecDict, _VarDict) -> @@ -3502,9 +3550,14 @@ t_from_form({type, _L, product, Elements}, TypeNames, RecDict, VarDict) -> {t_product(L), R}; t_from_form({type, _L, queue, []}, _TypeNames, _RecDict, _VarDict) -> {t_queue(), []}; -t_from_form({type, _L, range, [{integer, _, From}, {integer, _, To}]}, +t_from_form({type, _L, range, [From, To]} = Type, _TypeNames, _RecDict, _VarDict) -> - {t_from_range(From, To), []}; + case {erl_eval:partial_eval(From), erl_eval:partial_eval(To)} of + {{integer, _, FromVal}, + {integer, _, ToVal}} -> + {t_from_range(FromVal, ToVal), []}; + _ -> throw({error, io_lib:format("Unable evaluate type ~w\n", [Type])}) + end; t_from_form({type, _L, record, [Name|Fields]}, TypeNames, RecDict, VarDict) -> record_from_form(Name, Fields, TypeNames, RecDict, VarDict); t_from_form({type, _L, reference, []}, _TypeNames, _RecDict, _VarDict) -> @@ -3679,6 +3732,16 @@ t_form_to_string({var, _L, Name}) -> atom_to_list(Name); t_form_to_string({atom, _L, Atom}) -> io_lib:write_string(atom_to_list(Atom), $'); % To quote or not to quote... ' t_form_to_string({integer, _L, Int}) -> integer_to_list(Int); +t_form_to_string({op, _L, _Op, _Arg} = Op) -> + case erl_eval:partial_eval(Op) of + {integer, _, _} = Int -> t_form_to_string(Int); + _ -> io_lib:format("Bad formed type ~w",[Op]) + end; +t_form_to_string({op, _L, _Op, _Arg1, _Arg2} = Op) -> + case erl_eval:partial_eval(Op) of + {integer, _, _} = Int -> t_form_to_string(Int); + _ -> io_lib:format("Bad formed type ~w",[Op]) + end; t_form_to_string({ann_type, _L, [Var, Type]}) -> t_form_to_string(Var) ++ "::" ++ t_form_to_string(Type); t_form_to_string({paren_type, _L, [Type]}) -> @@ -3705,8 +3768,12 @@ t_form_to_string({type, _L, nonempty_list, [Type]}) -> t_form_to_string({type, _L, nonempty_string, []}) -> "nonempty_string()"; t_form_to_string({type, _L, product, Elements}) -> "<" ++ sequence(t_form_to_string_list(Elements), ",") ++ ">"; -t_form_to_string({type, _L, range, [{integer, _, From}, {integer, _, To}]}) -> - io_lib:format("~w..~w", [From, To]); +t_form_to_string({type, _L, range, [From, To]} = Type) -> + case {erl_eval:partial_eval(From), erl_eval:partial_eval(To)} of + {{integer, _, FromVal}, {integer, _, ToVal}} -> + io_lib:format("~w..~w", [FromVal, ToVal]); + _ -> io_lib:format("Bad formed type ~w",[Type]) + end; t_form_to_string({type, _L, record, [{atom, _, Name}]}) -> io_lib:format("#~w{}", [Name]); t_form_to_string({type, _L, record, [{atom, _, Name}|Fields]}) -> @@ -3725,13 +3792,17 @@ t_form_to_string({type, _L, Name, []} = T) -> try t_to_string(t_from_form(T)) catch throw:{error, _} -> atom_to_list(Name) ++ "()" end; -t_form_to_string({type, _L, binary, [{integer, _, X}, {integer, _, Y}]}) -> - case Y of - 0 -> - case X of - 0 -> "<<>>"; - _ -> io_lib:format("<<_:~w>>", [X]) - end +t_form_to_string({type, _L, binary, [X,Y]} = Type) -> + case {erl_eval:partial_eval(X), erl_eval:partial_eval(Y)} of + {{integer, _, XVal}, {integer, _, YVal}} -> + case YVal of + 0 -> + case XVal of + 0 -> "<<>>"; + _ -> io_lib:format("<<_:~w>>", [XVal]) + end + end; + _ -> io_lib:format("Bad formed type ~w",[Type]) end; t_form_to_string({type, _L, Name, List}) -> io_lib:format("~w(~s)", [Name, sequence(t_form_to_string_list(List), ",")]). @@ -3763,6 +3834,8 @@ any_none_or_unit([?unit|_]) -> true; any_none_or_unit([_|Left]) -> any_none_or_unit(Left); any_none_or_unit([]) -> false. +-spec is_erl_type(any()) -> boolean(). + is_erl_type(?any) -> true; is_erl_type(?none) -> true; is_erl_type(?unit) -> true; diff --git a/lib/hipe/doc/src/notes.xml b/lib/hipe/doc/src/notes.xml index 2c78558190..cf30db0482 100644 --- a/lib/hipe/doc/src/notes.xml +++ b/lib/hipe/doc/src/notes.xml @@ -30,6 +30,91 @@ </header> <p>This document describes the changes made to HiPE.</p> +<section><title>Hipe 3.7.7</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>The HiPE compiler could crash when compiling certain + modules (the bug has been latent, and been exposed by new + optimizations introduced in the BEAM compiler in R14A). + (Thanks to Mikael Pettersson.)</p> + <p> + Own Id: OTP-8800</p> + </item> + <item> + <p> + hipe:load/1 was broken. (Thanks to Paul Guyot.)</p> + <p> + Own Id: OTP-8802</p> + </item> + </list> + </section> + +</section> + +<section><title>Hipe 3.7.6</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p><c>receive</c> statements that can only read out a + newly created reference are now specially optimized so + that it will execute in constant time regardless of the + number of messages in the receive queue for the process. + That optimization will benefit calls to + <c>gen_server:call()</c>. (See <c>gen:do_call/4</c> for + an example of a receive statement that will be + optimized.)</p> + <p> + Own Id: OTP-8623</p> + </item> + <item> + <p> + Various changes to dialyzer-related files for R14.</p> + <p> + - Dialyzer properly supports the new attribute + -export_type and checks that remote types only refer to + exported types. A warning is produced if some + files/applications refer to types defined in modules + which are neither in the PLT nor in the analyzed + applications.</p> + <p> + - Support for detecting data races involving whereis/1 + and unregister/1.</p> + <p> + - More precise identification of the reason(s) why a + record construction violates the types declared for its + fields.</p> + <p> + - Fixed bug in the handling of the 'or' guard.</p> + <p> + - Better handling of the erlang:element/2 BIF.</p> + <p> + - Complete handling of Erlang BIFs.</p> + <p> + Own Id: OTP-8699</p> + </item> + <item> + <p><c>eprof</c> has been reimplemented with support in + the Erlang virtual machine and is now both faster (i.e. + slows down the code being measured less) and scales much + better. In measurements we saw speed-ups compared to the + old eprof ranging from 6 times (for sequential code that + only uses one scheduler/core) up to 84 times (for + parallel code that uses 8 cores).</p> + <p>Note: The API for the <c>eprof</c> has been cleaned up + and extended. See the documentation.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-8706</p> + </item> + </list> + </section> + +</section> + <section><title>Hipe 3.7.5</title> <section><title>Improvements and New Features</title> diff --git a/lib/hipe/flow/hipe_dominators.erl b/lib/hipe/flow/hipe_dominators.erl index 3bfa6d43c4..17357461a5 100644 --- a/lib/hipe/flow/hipe_dominators.erl +++ b/lib/hipe/flow/hipe_dominators.erl @@ -1,20 +1,20 @@ %% -*- erlang-indent-level: 2 -*- %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% 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% %% %%------------------------------------------------------------------------ @@ -37,6 +37,8 @@ domFrontier_create/2, domFrontier_get/2]). +-export_type([domTree/0]). + -include("cfg.hrl"). %%======================================================================== diff --git a/lib/hipe/icode/hipe_beam_to_icode.erl b/lib/hipe/icode/hipe_beam_to_icode.erl index 3923e98673..1f8be4040e 100644 --- a/lib/hipe/icode/hipe_beam_to_icode.erl +++ b/lib/hipe/icode/hipe_beam_to_icode.erl @@ -1,20 +1,20 @@ %% -*- erlang-indent-level: 2 -*- %% %% %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 %% 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,8 +22,6 @@ %% Author : Kostis Sagonas %% Description : Translates symbolic BEAM code to Icode %%======================================================================= -%% $Id$ -%%======================================================================= %% @doc %% This file translates symbolic BEAM code to Icode which is HiPE's %% intermediate code representation. Either the code of an entire @@ -431,6 +429,11 @@ trans_fun([{wait_timeout,{_,Lbl},Reg}|Instructions], Env) -> SuspTmout = hipe_icode:mk_if(suspend_msg_timeout,[], map_label(Lbl),hipe_icode:label_name(DoneLbl)), Movs ++ [SetTmout, SuspTmout, DoneLbl | trans_fun(Instructions,Env1)]; +%%--- recv_mark/1 & recv_set/1 --- XXX: Handle better?? +trans_fun([{recv_mark,{f,_}}|Instructions], Env) -> + trans_fun(Instructions,Env); +trans_fun([{recv_set,{f,_}}|Instructions], Env) -> + trans_fun(Instructions,Env); %%-------------------------------------------------------------------- %%--- Translation of arithmetics {bif,ArithOp, ...} --- %%-------------------------------------------------------------------- @@ -892,11 +895,6 @@ trans_fun([{bs_init_bits,{f,Lbl},Size,_Words,_LiveRegs,{field_flags,Flags0},X}| end, trans_bin_call({hipe_bs_primop,Name}, Lbl, Args, [Dst, Base, Offset], Base, Offset, Env, Instructions); -trans_fun([{bs_bits_to_bytes2, Bits, Bytes}|Instructions], Env) -> - Src = trans_arg(Bits), - Dst = mk_var(Bytes), - [hipe_icode:mk_primop([Dst], 'bsl', [Src, hipe_icode:mk_const(3)])| - trans_fun(Instructions,Env)]; trans_fun([{bs_add, {f,Lbl}, [Old,New,Unit], Res}|Instructions], Env) -> Dst = mk_var(Res), Temp = mk_var(new), @@ -1126,13 +1124,6 @@ trans_fun([{gc_bif,Name,Fail,_Live,SrcRs,DstR}|Instructions], Env) -> trans_fun([{bif,Name,Fail,SrcRs,DstR}|Instructions], Env) end; %%-------------------------------------------------------------------- -%% Instruction for constant pool added in February 2007 for R11B-4. -%%-------------------------------------------------------------------- -trans_fun([{put_literal,{literal,Literal},DstR}|Instructions], Env) -> - DstV = mk_var(DstR), - Move = hipe_icode:mk_move(DstV, hipe_icode:mk_const(Literal)), - [Move | trans_fun(Instructions, Env)]; -%%-------------------------------------------------------------------- %% New test instruction added in July 2007 for R12. %%-------------------------------------------------------------------- %%--- is_bitstr --- diff --git a/lib/hipe/icode/hipe_icode.erl b/lib/hipe/icode/hipe_icode.erl index a4614d7237..3e211bf385 100644 --- a/lib/hipe/icode/hipe_icode.erl +++ b/lib/hipe/icode/hipe_icode.erl @@ -1,20 +1,20 @@ %% -*- erlang-indent-level: 2 -*- %% %% %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 %% 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% %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1578,27 +1578,19 @@ redirect_jmp(Jmp, ToOld, ToNew) -> _ -> Jmp end end, - simplify_branch(NewI). - -%% -%% @doc Turns a branch into a goto if it has only one successor and it -%% is safe to do so. -%% - --spec simplify_branch(icode_instr()) -> icode_instr(). - -simplify_branch(I) -> - case ordsets:from_list(successors(I)) of + %% Turn a branch into a goto if it has only one successor and it is + %% safe to do so. + case ordsets:from_list(successors(NewI)) of [Label] -> Goto = mk_goto(Label), - case I of - #icode_type{} -> Goto; + case NewI of #icode_if{} -> Goto; #icode_switch_tuple_arity{} -> Goto; #icode_switch_val{} -> Goto; - _ -> I + #icode_type{} -> Goto; + _ -> NewI end; - _ -> I + _ -> NewI end. %% 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/hipe/rtl/hipe_rtl_primops.erl b/lib/hipe/rtl/hipe_rtl_primops.erl index 560e0259f8..0361053676 100644 --- a/lib/hipe/rtl/hipe_rtl_primops.erl +++ b/lib/hipe/rtl/hipe_rtl_primops.erl @@ -701,9 +701,9 @@ gen_cons(Dst, [Arg1, Arg2]) -> %% Increase refcount %% fe->refc++; %% -%% Link to the process off_heap.funs list -%% funp->next = p->off_heap.funs; -%% p->off_heap.funs = funp; +%% Link to the process off_heap list +%% funp->next = p->off_heap.first; +%% p->off_heap.first = funp; %% %% Tag the thing %% return make_fun(funp); @@ -729,9 +729,9 @@ gen_mkfun([Dst], {_Mod, _FunId, _Arity} = MFidA, MagicNr, Index, FreeVars) -> %% fe->refc++; SkeletonCode = gen_fun_thing_skeleton(HP, MFidA, NumFree, MagicNr, Index), - %% Link to the process off_heap.funs list - %% funp->next = p->off_heap.funs; - %% p->off_heap.funs = funp; + %% Link to the process off_heap list + %% funp->next = p->off_heap.first; + %% p->off_heap.first = funp; LinkCode = gen_link_closure(HP), %% Tag the thing and increase the heap_pointer. @@ -797,14 +797,14 @@ gen_link_closure(FUNP) -> end. gen_link_closure_private(FUNP) -> - %% Link to the process off_heap.funs list - %% funp->next = p->off_heap.funs; - %% p->off_heap.funs = funp; + %% Link fun to the process off_heap list + %% funp->next = p->off_heap.first; + %% p->off_heap.first = funp; FunsVar = hipe_rtl:mk_new_reg(), - [load_p_field(FunsVar,?P_OFF_HEAP_FUNS), + [load_p_field(FunsVar,?P_OFF_HEAP_FIRST), hipe_rtl:mk_store(FUNP, hipe_rtl:mk_imm(?EFT_NEXT), FunsVar), - store_p_field(FUNP,?P_OFF_HEAP_FUNS)]. + store_p_field(FUNP,?P_OFF_HEAP_FIRST)]. gen_link_closure_non_private(_FUNP) -> []. diff --git a/lib/hipe/rtl/hipe_tagscheme.erl b/lib/hipe/rtl/hipe_tagscheme.erl index dc44b803a1..c0b6dfad8a 100644 --- a/lib/hipe/rtl/hipe_tagscheme.erl +++ b/lib/hipe/rtl/hipe_tagscheme.erl @@ -849,9 +849,9 @@ create_refc_binary(Base, Size, Flags, Dst) -> heap_arch_spec(HP) -> Tmp1 = hipe_rtl:mk_new_reg(), % MSO state - [hipe_rtl_arch:pcb_load(Tmp1, ?P_OFF_HEAP_MSO), + [hipe_rtl_arch:pcb_load(Tmp1, ?P_OFF_HEAP_FIRST), set_field_from_pointer({proc_bin, next}, HP, Tmp1), - hipe_rtl_arch:pcb_store(?P_OFF_HEAP_MSO, HP)]. + hipe_rtl_arch:pcb_store(?P_OFF_HEAP_FIRST, HP)]. test_heap_binary(Binary, TrueLblName, FalseLblName) -> Tmp1 = hipe_rtl:mk_new_reg_gcsafe(), diff --git a/lib/hipe/util/hipe_digraph.erl b/lib/hipe/util/hipe_digraph.erl index a62e913fe5..fcfaa64684 100644 --- a/lib/hipe/util/hipe_digraph.erl +++ b/lib/hipe/util/hipe_digraph.erl @@ -1,20 +1,20 @@ %% -*- erlang-indent-level: 2 -*- %% %% %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 %% 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% %% %%----------------------------------------------------------------------- @@ -30,6 +30,8 @@ from_list/1, to_list/1, get_parents/2, get_children/2]). -export([reverse_preorder_sccs/1]). +-export_type([hdg/0]). + %%------------------------------------------------------------------------ -type ordset(T) :: [T]. % XXX: temporarily diff --git a/lib/hipe/vsn.mk b/lib/hipe/vsn.mk index 129718a305..8e421ce9b2 100644 --- a/lib/hipe/vsn.mk +++ b/lib/hipe/vsn.mk @@ -1 +1 @@ -HIPE_VSN = 3.7.5 +HIPE_VSN = 3.7.7 diff --git a/lib/ic/doc/src/Makefile b/lib/ic/doc/src/Makefile index 26d0932a95..8eda436a24 100644 --- a/lib/ic/doc/src/Makefile +++ b/lib/ic/doc/src/Makefile @@ -1,19 +1,19 @@ # # %CopyrightBegin% -# -# Copyright Ericsson AB 1998-2009. All Rights Reserved. -# +# +# Copyright Ericsson AB 1998-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% # # @@ -211,7 +211,11 @@ $(HTMLDIR)/%.gif: %.gif ifdef DOCSUPPORT +ifneq (,$(JAVA)) docs: pdf html man $(JAVADOC_GENERATED_FILES) +else +docs: pdf html man +endif $(TOP_PDF_FILE): $(XML_FILES) @@ -301,6 +305,7 @@ release_docs_spec: docs $(INSTALL_DATA) $(GIF_FILES) $(EXTRA_FILES) $(HTML_FILES) \ $(RELSYSDIR)/doc/html $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) +ifneq (,$(JAVA)) $(INSTALL_DIR) $(RELSYSDIR)/doc/html/java $(INSTALL_DIR) $(RELSYSDIR)/doc/html/java/resources $(INSTALL_DIR) $(RELSYSDIR)/doc/html/java/com @@ -313,6 +318,7 @@ release_docs_spec: docs $(RELSYSDIR)/doc/html/java/resources $(INSTALL_DATA) $(JAVADOC_PACK_HTML_FILES) \ $(RELSYSDIR)/doc/html/java/com/ericsson/otp/ic +endif $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 $(INSTALL_DATA) $(MAN3_FILES) $(RELEASE_PATH)/man/man3 diff --git a/lib/ic/doc/src/ch_c_mapping.xml b/lib/ic/doc/src/ch_c_mapping.xml index f5a921bfd2..23a9361c2c 100644 --- a/lib/ic/doc/src/ch_c_mapping.xml +++ b/lib/ic/doc/src/ch_c_mapping.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>1998</year><year>2009</year> + <year>1998</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>IDL to C mapping</title> @@ -804,7 +804,7 @@ CORBA_Environment* oe_env) octets</p> </item> </list> - <p>The erlang binary IDL type is defined in <c>erlang.idl</c>, while it's + <p>The erlang binary IDL type is defined in <c>erlang.idl</c>, while its C definition is located in the <c>ic.h</c> header file, both in the <c><![CDATA[IC-< vsn >/include]]></c> directory. The user will have to include the file <c>erlang.idl</c> in order to use the diff --git a/lib/ic/doc/src/notes.xml b/lib/ic/doc/src/notes.xml index dbafde7b4b..6684547572 100644 --- a/lib/ic/doc/src/notes.xml +++ b/lib/ic/doc/src/notes.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>1998</year><year>2009</year> + <year>1998</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>IDL Compiler Release Notes</title> @@ -31,6 +31,22 @@ </header> <section> + <title>IC 4.2.25</title> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p> + The documentation can now be built and installed without Java.</p> + <p> + Own Id: OTP-8639 Aux Id:</p> + </item> + </list> + </section> + </section> + + <section> <title>IC 4.2.24</title> <section> diff --git a/lib/ic/vsn.mk b/lib/ic/vsn.mk index e0fccf4889..074d0b3d39 100644 --- a/lib/ic/vsn.mk +++ b/lib/ic/vsn.mk @@ -1,18 +1 @@ -IC_VSN = 4.2.24 - -TICKETS = 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 +IC_VSN = 4.2.25 diff --git a/lib/inets/doc/src/httpc.xml b/lib/inets/doc/src/httpc.xml index 7430a62b1b..9c8df28fec 100644 --- a/lib/inets/doc/src/httpc.xml +++ b/lib/inets/doc/src/httpc.xml @@ -167,6 +167,8 @@ ssl_options() = {verify, code()} | <v>http_option() = {timeout, timeout()} | {connect_timeout, timeout()} | {ssl, ssl_options()} | + {ossl, ssl_options()} | + {essl, ssl_options()} | {autoredirect, boolean()} | {proxy_auth, {userstring(), passwordstring()}} | {version, http_version()} | @@ -222,7 +224,22 @@ ssl_options() = {verify, code()} | <tag><c><![CDATA[ssl]]></c></tag> <item> - <p>If using SSL, these SSL-specific options are used. </p> + <p>This is the default ssl config option, currently defaults to + <c>ossl</c>, see below. </p> + <p>Defaults to <c>[]</c>. </p> + </item> + + <tag><c><![CDATA[ossl]]></c></tag> + <item> + <p>If using the OpenSSL based (old) implementation of SSL, + these SSL-specific options are used. </p> + <p>Defaults to <c>[]</c>. </p> + </item> + + <tag><c><![CDATA[essl]]></c></tag> + <item> + <p>If using the Erlang based (new) implementation of SSL, + these SSL-specific options are used. </p> <p>Defaults to <c>[]</c>. </p> </item> diff --git a/lib/inets/doc/src/httpd.xml b/lib/inets/doc/src/httpd.xml index 7dabeb33e9..847605fe93 100644 --- a/lib/inets/doc/src/httpd.xml +++ b/lib/inets/doc/src/httpd.xml @@ -148,8 +148,13 @@ in the apache like configuration file. </item> - <tag>{socket_type, ip_comm | ssl}</tag> + <tag>{socket_type, ip_comm | ssl | ossl | essl}</tag> <item> + <p>When using ssl, there are several alternatives. + <c>ossl</c> specifically uses the OpenSSL based (old) SSL. + <c>essl</c> specifically uses the Erlang based (new) SSL. + When using <c>ssl</c> it <em>currently</em> defaults to + <c>ossl</c>. </p> <p>Defaults to <c>ip_comm</c>. </p> </item> @@ -267,18 +272,22 @@ text/plain asc txt The <c>common</c> format is one line that looks like this: <c>remotehost rfc931 authuser [date] "request" status bytes</c></p> - <pre>remotehost + <pre> +remotehost Remote rfc931 The client's remote username (RFC 931). authuser - The username with which the user authenticated himself. + The username with which the user authenticated + himself. [date] Date and time of the request (RFC 1123). "request" - The request line exactly as it came from the client(RFC 1945). + The request line exactly as it came from the client + (RFC 1945). status - The HTTP status code returned to the client (RFC 1945). + The HTTP status code returned to the client + (RFC 1945). bytes The content-length of the document transferred. </pre> @@ -286,10 +295,11 @@ bytes <p>The <c>combined</c> format is on line that look like this: <c>remotehost rfc931 authuser [date] "request" status bytes "referer" "user_agent" </c></p> - <pre>"referer" + <pre> +"referer" The url the client was on before - requesting your url. (If it could not be determined a minus - sign will be placed in this field) + requesting your url. (If it could not be determined + a minus sign will be placed in this field) "user_agent" The software the client claims to be using. (If it could not be determined a minus sign will be placed in @@ -389,6 +399,31 @@ bytes and an access to http://your.server.org/image/foo.gif would refer to the file /ftp/pub/image/foo.gif.</item> + <tag>{re_write, {Re, Replacement}}</tag> + + <item> Where Re = string() and Replacement = string(). + The ReWrite property allows documents to be stored in the local file + system instead of the document_root location. URLs are rewritten + by re:replace/3 to produce a path in the local filesystem. + For example: + + <code>{re_write, {"^/[~]([^/]+)(.*)$", "/home/\\1/public\\2"}</code> + + and an access to http://your.server.org/~bob/foo.gif would refer to + the file /home/bob/public/foo.gif. + + In an Apache like configuration file the Re is separated + from Replacement with one single space, and as expected + backslashes do not need to be backslash escaped so the + same example would become: + + <code>ReWrite ^/[~]([^/]+)(.*)$ /home/\1/public\2</code> + + Beware of trailing space in Replacement that will be used. + If you must have a space in Re use e.g the character encoding + <code>\040</code> see <seealso marker="re">re(3)</seealso>. + </item> + <tag>{directory_index, [string()]}</tag> <item> @@ -408,7 +443,7 @@ bytes </taglist> <marker id="cgi_prop"></marker> - <p><em>CGI properties - requires mod_cgi</em></p> + <p><em>CGI properties - requires mod_cgi</em></p> <taglist> <tag>{script_alias, {Alias, RealName}}</tag> <item> Where Alias = string() and RealName = string(). @@ -423,6 +458,19 @@ bytes the server to run the script /web/cgi-bin/foo. </item> + <tag>{script_re_write, {Re, Replacement}}</tag> + <item> Where Re = string() and Replacement = string(). + Has the same behavior as the ReWrite property, except that + it also marks the target directory as containing CGI + scripts. URLs with a path beginning with url-path are mapped to + scripts beginning with directory-filename, for example: + + <code> {script_re_write, {"^/cgi-bin/(\\d+)/", "/web/\\1/cgi-bin/"}</code> + + and an access to http://your.server.org/cgi-bin/17/foo would cause + the server to run the script /web/17/cgi-bin/foo. + </item> + <tag>{script_nocache, boolean()}</tag> <item> diff --git a/lib/inets/doc/src/mod_esi.xml b/lib/inets/doc/src/mod_esi.xml index 6bad77dc0a..3c473d3f94 100644 --- a/lib/inets/doc/src/mod_esi.xml +++ b/lib/inets/doc/src/mod_esi.xml @@ -73,7 +73,8 @@ <v>SessionID = term()</v> <v>Env = [EnvironmentDirectives] ++ ParsedHeader</v> <v>EnvironmentDirectives = {Key,Value}</v> - <v>Key = query_string | content_length | server_software | gateway_interface | server_protocol | server_port | request_method | remote_addr | script_name. <v>Input = string()</v> + <v>Key = query_string | content_length | server_software | gateway_interface | server_protocol | server_port | request_method | remote_addr | script_name</v> + <v>Input = string()</v> </type> <desc> <p>The <c>Module</c> must be found in the code path and export diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml index 9ab35ff38b..7b16189860 100644 --- a/lib/inets/doc/src/notes.xml +++ b/lib/inets/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>Inets Release Notes</title> @@ -32,63 +32,112 @@ <file>notes.xml</file> </header> - <section><title>Inets 5.3.4</title> + <section><title>Inets 5.5</title> - <section><title>Improvements and New Features</title> - <p>-</p> - -<!-- + <section><title>Fixed Bugs and Malfunctions</title> <list> <item> - <p>[httpc] - Allow users to pass socket options to the transport - module when making requests. </p> - <p>See the <c>socket_opts</c> option in the - <seealso marker="httpc#request2">request/4</seealso> or - <seealso marker="httpc#set_options">set_options/1,2</seealso> - for more info, </p> - <p>Own Id: OTP-8352</p> + <p> + [httpc] If a request times out (not connect timeout), the + handler process exited (normal) but neglected to inform + the manager process. For this reason, the manager did not + clean up the request table., resulting in a memory leak. + Also the manager did not create a monitor for the + handler, so in an unforseen handler crash, this could + also create a memory leak.</p> + <p> + Own Id: OTP-8739</p> + </item> + <item> + <p> + The service tftp was spelled wrong in documentation and + in some parts of the code. It should be tftp.</p> + <p> + Own Id: OTP-8741 Aux Id: seq11635 </p> </item> + <item> + <p> + [httpc] Replaced the old http client api module (http) + with the new, httpc in the users guide.</p> + <p> + Own Id: OTP-8742</p> + </item> + </list> + </section> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Eliminated warnings for auto-imported BIF clashes.</p> + <p> + Own Id: OTP-8840</p> + </item> </list> ---> </section> - <section><title>Fixed Bugs and Malfunctions</title> +</section> + +<section><title>Inets 5.4</title> + <section><title>Improvements and New Features</title> <!-- <p>-</p> --> <list> <item> - <p>[httpc] - If a request times out (not during connect), the - handler process exited (normal) but neglected to inform - the manager process. For this reason, the manager - did not clean up the request table, resulting in a - memory leak. Also the manager did not create a monitor - for the handler, so in an unforseen handler crash, this - could also create a memory leak. </p> - <p>Own Id: OTP-8739</p> + <p>[httpc|httpd] - Now allow the use of the "new" ssl, by using + the <c>essl</c> tag instead. </p> + <p>See the <c>http_option</c> option in the + <seealso marker="httpc#request2">request/4,5</seealso> or + the <seealso marker="httpd#comm_prop">socket-type</seealso> + section of the Communication properties chapter for more info, </p> + <p>Own Id: OTP-7907</p> </item> <item> - <p>[tftp] - Was spelled wrong in documentation and in some - parts of the code. It should be tftp. </p> - <p>Own Id: OTP-8741</p> + <p>Deprecated functions designated to be removed in R14 has been + removed. Also, some new functions has been marked as deprecated + (the old http client api module). </p> + <p>Own Id: OTP-8564</p> + <p>*** POTENTIAL INCOMPATIBILITY ***</p> </item> <item> - <p>[htpc] - Replaced the old http client api module (http) - with the new, http client in the - <seealso marker="http_client">Users Guide</seealso>. </p> - <p>Own Id: OTP-8742</p> - <p>Ryan Zezeski</p> + <p>[httpd] - Improved mod_alias. + Now able to do better URL rewrites. </p> + <p>See + <seealso marker="httpd#alias_prop">URL aliasing properties</seealso> + and the + <seealso marker="httpd#cgi_prop">CGI properties</seealso> + section(s) for more info, </p> + <p>Own Id: OTP-8573</p> + </item> + + </list> + </section> + + <section><title>Fixed Bugs and Malfunctions</title> + + <p>-</p> + +<!-- + <list> + <item> + <p>[httpd] The server did not fully support the documented module + callback api. Specifically, the load function should be able to + return the atom <c>ok</c>, but this was not accepted. </p> + <p>Own Id: OTP-8359</p> </item> </list> +--> + </section> - </section> <!-- 5.3.4 --> + </section> <!-- 5.4 --> <section><title>Inets 5.3.3</title> @@ -363,6 +412,7 @@ <p>Own Id: OTP-8016</p> <p>*** POTENTIAL INCOMPATIBILITY ***</p> </item> + </list> </section> diff --git a/lib/inets/examples/Makefile b/lib/inets/examples/Makefile index a42b0e38b6..775c449062 100644 --- a/lib/inets/examples/Makefile +++ b/lib/inets/examples/Makefile @@ -1,19 +1,19 @@ # # %CopyrightBegin% -# -# Copyright Ericsson AB 1997-2009. All Rights Reserved. -# +# +# Copyright Ericsson AB 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% # # @@ -21,189 +21,15 @@ include $(ERL_TOP)/make/target.mk include $(ERL_TOP)/make/$(TARGET)/otp.mk # ---------------------------------------------------- -# Application version -# ---------------------------------------------------- -include ../vsn.mk -VSN=$(INETS_VSN) - -# ---------------------------------------------------- -# Release directory specification -# ---------------------------------------------------- -RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN) - -# ---------------------------------------------------- -# Target Specs +# Common Macros # ---------------------------------------------------- -MODULE= -AUTH_FILES = server_root/auth/group \ - server_root/auth/passwd -CGI_FILES = server_root/cgi-bin/printenv.sh -CONF_FILES = server_root/conf/8080.conf \ - server_root/conf/8888.conf \ - server_root/conf/httpd.conf \ - server_root/conf/ssl.conf \ - server_root/conf/mime.types -OPEN_FILES = server_root/htdocs/open/dummy.html -MNESIA_OPEN_FILES = server_root/htdocs/mnesia_open/dummy.html -MISC_FILES = server_root/htdocs/misc/friedrich.html \ - server_root/htdocs/misc/oech.html -SECRET_FILES = server_root/htdocs/secret/dummy.html -MNESIA_SECRET_FILES = server_root/htdocs/mnesia_secret/dummy.html -HTDOCS_FILES = server_root/htdocs/index.html \ - server_root/htdocs/config.shtml \ - server_root/htdocs/echo.shtml \ - server_root/htdocs/exec.shtml \ - server_root/htdocs/flastmod.shtml \ - server_root/htdocs/fsize.shtml \ - server_root/htdocs/include.shtml -ICON_FILES = server_root/icons/README \ - server_root/icons/a.gif \ - server_root/icons/alert.black.gif \ - server_root/icons/alert.red.gif \ - server_root/icons/apache_pb.gif \ - server_root/icons/back.gif \ - server_root/icons/ball.gray.gif \ - server_root/icons/ball.red.gif \ - server_root/icons/binary.gif \ - server_root/icons/binhex.gif \ - server_root/icons/blank.gif \ - server_root/icons/bomb.gif \ - server_root/icons/box1.gif \ - server_root/icons/box2.gif \ - server_root/icons/broken.gif \ - server_root/icons/burst.gif \ - server_root/icons/button1.gif \ - server_root/icons/button10.gif \ - server_root/icons/button2.gif \ - server_root/icons/button3.gif \ - server_root/icons/button4.gif \ - server_root/icons/button5.gif \ - server_root/icons/button6.gif \ - server_root/icons/button7.gif \ - server_root/icons/button8.gif \ - server_root/icons/button9.gif \ - server_root/icons/buttonl.gif \ - server_root/icons/buttonr.gif \ - server_root/icons/c.gif \ - server_root/icons/comp.blue.gif \ - server_root/icons/comp.gray.gif \ - server_root/icons/compressed.gif \ - server_root/icons/continued.gif \ - server_root/icons/dir.gif \ - server_root/icons/down.gif \ - server_root/icons/dvi.gif \ - server_root/icons/f.gif \ - server_root/icons/folder.gif \ - server_root/icons/folder.open.gif \ - server_root/icons/folder.sec.gif \ - server_root/icons/forward.gif \ - server_root/icons/generic.gif \ - server_root/icons/generic.red.gif \ - server_root/icons/generic.sec.gif \ - server_root/icons/hand.right.gif \ - server_root/icons/hand.up.gif \ - server_root/icons/htdig.gif \ - server_root/icons/icon.sheet.gif \ - server_root/icons/image1.gif \ - server_root/icons/image2.gif \ - server_root/icons/image3.gif \ - server_root/icons/index.gif \ - server_root/icons/layout.gif \ - server_root/icons/left.gif \ - server_root/icons/link.gif \ - server_root/icons/movie.gif \ - server_root/icons/p.gif \ - server_root/icons/patch.gif \ - server_root/icons/pdf.gif \ - server_root/icons/pie0.gif \ - server_root/icons/pie1.gif \ - server_root/icons/pie2.gif \ - server_root/icons/pie3.gif \ - server_root/icons/pie4.gif \ - server_root/icons/pie5.gif \ - server_root/icons/pie6.gif \ - server_root/icons/pie7.gif \ - server_root/icons/pie8.gif \ - server_root/icons/portal.gif \ - server_root/icons/poweredby.gif \ - server_root/icons/ps.gif \ - server_root/icons/quill.gif \ - server_root/icons/right.gif \ - server_root/icons/screw1.gif \ - server_root/icons/screw2.gif \ - server_root/icons/script.gif \ - server_root/icons/sound1.gif \ - server_root/icons/sound2.gif \ - server_root/icons/sphere1.gif \ - server_root/icons/sphere2.gif \ - server_root/icons/star.gif \ - server_root/icons/star_blank.gif \ - server_root/icons/tar.gif \ - server_root/icons/tex.gif \ - server_root/icons/text.gif \ - server_root/icons/transfer.gif \ - server_root/icons/unknown.gif \ - server_root/icons/up.gif \ - server_root/icons/uu.gif \ - server_root/icons/uuencoded.gif \ - server_root/icons/world1.gif \ - server_root/icons/world2.gif +include subdirs.mk -SSL_FILES = server_root/ssl/ssl_client.pem \ - server_root/ssl/ssl_server.pem +SPECIAL_TARGETS = # ---------------------------------------------------- -# FLAGS +# Default Subdir Targets # ---------------------------------------------------- -ERL_COMPILE_FLAGS += - -# ---------------------------------------------------- -# Targets -# ---------------------------------------------------- - -debug opt: - -clean: - -docs: - -# ---------------------------------------------------- -# Release Target -# ---------------------------------------------------- -include $(ERL_TOP)/make/otp_release_targets.mk - -release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/auth - $(INSTALL_DATA) $(AUTH_FILES) $(RELSYSDIR)/examples/server_root/auth - $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/cgi-bin - $(INSTALL_SCRIPT) $(CGI_FILES) $(RELSYSDIR)/examples/server_root/cgi-bin - $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/conf - $(INSTALL_DATA) $(CONF_FILES) $(RELSYSDIR)/examples/server_root/conf - $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/htdocs/open - $(INSTALL_DATA) $(OPEN_FILES) \ - $(RELSYSDIR)/examples/server_root/htdocs/open - $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/htdocs/mnesia_open - $(INSTALL_DATA) $(MNESIA_OPEN_FILES) \ - $(RELSYSDIR)/examples/server_root/htdocs/mnesia_open - $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/htdocs/misc - $(INSTALL_DATA) $(MISC_FILES) \ - $(RELSYSDIR)/examples/server_root/htdocs/misc - $(INSTALL_DIR) \ - $(RELSYSDIR)/examples/server_root/htdocs/secret/top_secret - $(INSTALL_DIR) \ - $(RELSYSDIR)/examples/server_root/htdocs/mnesia_secret/top_secret - $(INSTALL_DATA) $(SECRET_FILES) \ - $(RELSYSDIR)/examples/server_root/htdocs/secret - $(INSTALL_DATA) $(MNESIA_SECRET_FILES) \ - $(RELSYSDIR)/examples/server_root/htdocs/mnesia_secret - $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/htdocs - $(INSTALL_DATA) $(HTDOCS_FILES) $(RELSYSDIR)/examples/server_root/htdocs - $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/icons - $(INSTALL_DATA) $(ICON_FILES) $(RELSYSDIR)/examples/server_root/icons - $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/ssl - $(INSTALL_DATA) $(SSL_FILES) $(RELSYSDIR)/examples/server_root/ssl - $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/logs - -release_docs_spec: +include $(ERL_TOP)/make/otp_subdir.mk diff --git a/lib/inets/examples/httpd_load_test/Makefile b/lib/inets/examples/httpd_load_test/Makefile new file mode 100644 index 0000000000..1cc61ad8ae --- /dev/null +++ b/lib/inets/examples/httpd_load_test/Makefile @@ -0,0 +1,123 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 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 + +EBIN = . + +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Application version +# ---------------------------------------------------- +include ../../vsn.mk + +VSN=$(INETS_VSN) + + +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN) +EXAMPLE_RELSYSDIR = $(RELSYSDIR)/examples +HDLT_RELSYSDIR = $(EXAMPLE_RELSYSDIR)/httpd_load_test + + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- + +include modules.mk + +ERL_FILES = $(MODULES:%=%.erl) + +SOURCE = $(ERL_FILES) $(INTERNAL_HRL_FILES) + +TARGET_FILES = \ + $(ERL_FILES:%.erl=$(EBIN)/%.$(EMULATOR)) + +ifeq ($(TYPE),debug) +ERL_COMPILE_FLAGS += -Ddebug -W +endif + + +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- + +include ../../src/inets_app/inets.mk + +ERL_COMPILE_FLAGS += \ + $(INETS_FLAGS) \ + $(INETS_ERL_COMPILE_FLAGS) \ + -I../../include + + +# ---------------------------------------------------- +# Special Build Targets +# ---------------------------------------------------- + + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- +debug: + @${MAKE} TYPE=debug opt + +opt: $(TARGET_FILES) + +clean: + rm -f $(TARGET_FILES) + rm -f errs core *~ + +docs: + + +# ---------------------------------------------------- +# Release Target +# ---------------------------------------------------- +include $(ERL_TOP)/make/otp_release_targets.mk + + +release_spec: opt + $(INSTALL_DIR) $(EXAMPLE_RELSYSDIR) + $(INSTALL_DIR) $(HDLT_RELSYSDIR) + $(INSTALL_DATA) $(SCRIPT_SKELETONS) $(HDLT_RELSYSDIR) + $(INSTALL_DATA) $(CONF_SKELETONS) $(HDLT_RELSYSDIR) + $(INSTALL_DATA) $(CERT_FILES) $(HDLT_RELSYSDIR) + $(INSTALL_DATA) $(TARGET_FILES) $(HDLT_RELSYSDIR) + $(INSTALL_DATA) $(ERL_FILES) $(HDLT_RELSYSDIR) + + +release_docs_spec: + + +# ---------------------------------------------------- +# Include dependencies +# ---------------------------------------------------- + +megaco_codec_transform.$(EMULATOR): megaco_codec_transform.erl + +megaco_codec_meas.$(EMULATOR): megaco_codec_meas.erl + +megaco_codec_mstone1.$(EMULATOR): megaco_codec_mstone1.erl + +megaco_codec_mstone2.$(EMULATOR): megaco_codec_mstone2.erl + +megaco_codec_mstone_lib.$(EMULATOR): megaco_codec_mstone_lib.erl + diff --git a/lib/inets/examples/httpd_load_test/hdlt.config.skel b/lib/inets/examples/httpd_load_test/hdlt.config.skel new file mode 100644 index 0000000000..640867ebac --- /dev/null +++ b/lib/inets/examples/httpd_load_test/hdlt.config.skel @@ -0,0 +1,20 @@ +%% Debug: silence | info | log | debug +{debug, [{ctrl, info}, {proxy, silence}, {slave, silence}, {client, silence}]}. +{server, {"/usr/local/bin", "fooserver"}}. +%% {port, 8888}. % integer() > 0 +{server_dir, "/tmp/hdlt"}. % Absolute path +{work_dir, "/tmp/hdlt"}. % Absolute path +{clients, + [ + {"/opt/local/bin", "foo"}, + {"/usr/local/bin", "bar"} + ] +}. +%% {send_rate, 80}. % Max number of outstanding requests, integer() > 0 +%% {test_time, 120}. % Number of seconds, +%% {max_nof_schedulers, 8}. % integer() >= 0 +%% {work_simulator, 10000}. % integer() > 0 +%% {data_size, {100, 500, 2}}. % {integer() > 0, integer() > 0, integer() > 0} +%% {socket_type, ip_comm}. % ip_comm | ssl | essl | ossl +%% {server_cert_file, "hdlt_ssl_server_cert.pem"}. +%% {client_cert_file, "hdlt_ssl_client_cert.pem"}.
\ No newline at end of file diff --git a/lib/inets/examples/httpd_load_test/hdlt.erl b/lib/inets/examples/httpd_load_test/hdlt.erl new file mode 100644 index 0000000000..18d8c34ccf --- /dev/null +++ b/lib/inets/examples/httpd_load_test/hdlt.erl @@ -0,0 +1,74 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% +%% +%% +%%---------------------------------------------------------------------- +%% Purpose: Main API module for the httpd load test utility +%%---------------------------------------------------------------------- + +-module(hdlt). + + +%%----------------------------------------------------------------- +%% Public interface +%%----------------------------------------------------------------- + +-export([start/0, start/1, stop/0, help/0]). + + +%%----------------------------------------------------------------- +%% Start the HDLT utility +%%----------------------------------------------------------------- + +start() -> + ConfigFile = "hdlt.config", + case file:consult(ConfigFile) of + {ok, Config} when is_list(Config) -> + start(Config); + Error -> + Error + end. + +start(Config) -> + Flag = process_flag(trap_exit, true), + Result = + case hdlt_ctrl:start(Config) of + {ok, Pid} -> + receive + {'EXIT', Pid, normal} -> + ok; + {'EXIT', Pid, Reason} -> + io:format("HDLT failed: " + "~n ~p" + "~n", [Reason]), + {error, Reason} + end; + Error -> + Error + end, + process_flag(trap_exit, Flag), + Result. + + + +stop() -> + hdlt_ctrl:stop(). + + +help() -> + hdlt_ctrl:help(). diff --git a/lib/inets/examples/httpd_load_test/hdlt.sh.skel b/lib/inets/examples/httpd_load_test/hdlt.sh.skel new file mode 100644 index 0000000000..a250bad9c5 --- /dev/null +++ b/lib/inets/examples/httpd_load_test/hdlt.sh.skel @@ -0,0 +1,44 @@ +#!/bin/sh + +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 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% + +# Skeleton for a script intended to run the hdlt(N) +# performance test. +# +# This test can be used for several things depending on the +# configuration: SMP or SocketType performance tests +# + +ERL_HOME=<path to otp top dir> +INETS_HOME=$ERL_HOME/lib/erlang/lib/<inets dir> +HDLT_HOME=$INETS_HOME/examples/httpd_load_test +PATH=$ERL_HOME/bin:$PATH + +HDLT="-s hdlt start" +STOP="-s init stop" + +ERL="erl \ + -noshell \ + -pa $HDLT_HOME \ + $HDLT \ + $STOP" + +echo $ERL +$ERL | tee hdlt.log + diff --git a/lib/inets/examples/httpd_load_test/hdlt_client.erl b/lib/inets/examples/httpd_load_test/hdlt_client.erl new file mode 100644 index 0000000000..d65ac5a885 --- /dev/null +++ b/lib/inets/examples/httpd_load_test/hdlt_client.erl @@ -0,0 +1,370 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% +%% +%% +%%---------------------------------------------------------------------- +%% Purpose: The HDLT client module. +%% This is the traffic generator +%%---------------------------------------------------------------------- + +-module(hdlt_client). + +-export([ + start/1, + stop/0, + start_inets/0, + start_service/1, + release/0, + node_info/0 + ]). + +-export([ + proxy/1 + ]). + +-include("hdlt_logger.hrl"). + +-define(CTRL, hdlt_ctrl). +-define(PROXY, hdlt_proxy). + +-record(state, + { + mode = initial, + send_rate, + time, + stop_time, + url, + nof_reqs = 0, + nof_reps = 0, + last_req, + sizes, + socket_type, + cert_file + }). + + + +start(Debug) -> + proc_lib:start_link(?MODULE, proxy, [Debug]). + +stop() -> + (catch erlang:send(?PROXY, stop)), + ok. + +start_inets() -> + ?PROXY ! start_inets. + +start_service(Args) -> + ?PROXY ! {start_client, Args, self()}, + receive + client_started -> + %% ?LOG("client service started"), + ok + end. + +release() -> + ?PROXY ! release. + +node_info() -> + ?PROXY ! {node_info, self()}, + receive + {node_info, NodeInfo} -> + NodeInfo + end. + + +%% --------------------------------------------------------------------- +%% +%% The proxy process +%% + +proxy(Debug) -> + process_flag(trap_exit, true), + erlang:register(?PROXY, self()), + SName = lists:flatten( + io_lib:format("HDLT PROXY[~p,~p]", [self(), node()])), + ?SET_NAME(SName), + ?SET_LEVEL(Debug), + ?LOG("starting", []), + Ref = await_for_controller(10), + CtrlNode = node(Ref), + erlang:monitor_node(CtrlNode, true), + proc_lib:init_ack({ok, self()}), + ?DEBUG("started", []), + proxy_loop(Ref, CtrlNode, undefined). + +await_for_controller(N) when N > 0 -> + case global:whereis_name(hdlt_ctrl) of + Pid when is_pid(Pid) -> + erlang:monitor(process, Pid); + _ -> + timer:sleep(1000), + await_for_controller(N-1) + end; +await_for_controller(_) -> + proc_lib:init_ack({error, controller_not_found, nodes()}), + timer:sleep(500), + init:stop(). + + +proxy_loop(Ref, CtrlNode, Client) -> + ?DEBUG("await command", []), + receive + stop -> + ?LOG("stop", []), + timer:sleep(1000), + halt(); + + start_inets -> + ?LOG("start the inets service framework", []), + %% inets:enable_trace(max, "/tmp/inets-httpc-trace.log", all), + case (catch inets:start()) of + ok -> + ?LOG("framework started", []), + proxy_loop(Ref, CtrlNode, Client); + Error -> + ?LOG("failed starting inets service framework: " + "~n Error: ~p", [Error]), + timer:sleep(1000), + halt() + end; + + {start_client, Args, From} -> + ?LOG("start client with" + "~n Args: ~p", [Args]), + Client2 = spawn_link(fun() -> client(Args) end), + From ! client_started, + proxy_loop(Ref, CtrlNode, Client2); + + release -> + ?LOG("release", []), + Client ! go, + proxy_loop(Ref, CtrlNode, Client); + + {node_info, Pid} -> + ?LOG("received requets for node info", []), + NodeInfo = get_node_info(), + Pid ! {node_info, NodeInfo}, + proxy_loop(Ref, CtrlNode, Client); + + {'EXIT', Client, normal} -> + ?LOG("received normal exit message from client (~p)", + [Client]), + exit(normal); + + {'EXIT', Client, Reason} -> + ?INFO("received exit message from client (~p)" + "~n Reason: ~p", [Client, Reason]), + %% Unexpected client termination, inform the controller and die + global:send(hdlt_ctrl, {client_exit, Client, node(), Reason}), + exit({client_exit, Reason}); + + {nodedown, CtrlNode} -> + ?LOG("received nodedown for controller node - terminate", []), + halt(); + + {'DOWN', Ref, process, _, _} -> + ?INFO("received DOWN message for controller - terminate", []), + %% The controller has terminated, dont care why, time to die + halt() + + end. + + + +%% --------------------------------------------------------------------- +%% +%% The client process +%% + +client([SocketType, CertFile, URLBase, Sizes, Time, SendRate, Debug]) -> + SName = lists:flatten( + io_lib:format("HDLT CLIENT[~p,~p]", [self(), node()])), + ?SET_NAME(SName), + ?SET_LEVEL(Debug), + ?LOG("starting with" + "~n SocketType: ~p" + "~n Time: ~p" + "~n SendRate: ~p", [SocketType, Time, SendRate]), + httpc:set_options([{max_pipeline_length, 0}]), + if + (SocketType =:= ssl) orelse + (SocketType =:= ossl) orelse + (SocketType =:= essl) -> + %% Ensure crypto and ssl started: + crypto:start(), + ssl:start(); + true -> + ok + end, + State = #state{mode = idle, + url = URLBase, + time = Time, + send_rate = SendRate, + sizes = Sizes, + socket_type = SocketType, + cert_file = CertFile}, + ?DEBUG("started", []), + client_loop(State). + +%% The point is to first start all client nodes and then this +%% process. Then, when they are all started, the go-ahead, go, +%% message is sent to let them lose at the same time. +client_loop(#state{mode = idle, + time = Time, + send_rate = SendRate} = State) -> + ?DEBUG("[idle] awaiting the go command", []), + receive + go -> + ?LOG("[idle] received go", []), + erlang:send_after(Time, self(), stop), + NewState = send_requests(State, SendRate), + client_loop(NewState#state{mode = generating, + nof_reqs = SendRate}) + end; + +%% In this mode the client is generating traffic. +%% It will continue to do so until the stop message +%% is received. +client_loop(#state{mode = generating} = State) -> + receive + stop -> + ?LOG("[generating] received stop", []), + StopTime = timestamp(), + req_reply(State), + client_loop(State#state{mode = stopping, stop_time = StopTime}); + + {http, {_, {{_, 200, _}, _, _}}} -> + %% ?DEBUG("[generating] received reply - send another request", []), + NewState = send_requests(State, 1), + client_loop(NewState#state{nof_reps = NewState#state.nof_reps + 1, + nof_reqs = NewState#state.nof_reqs + 1}); + + {http, {ReqId, {error, Reason}}} -> + ?INFO("[generating] request ~p failed: " + "~n Reason: ~p" + "~n NofReqs: ~p" + "~n NofReps: ~p", + [ReqId, Reason, State#state.nof_reqs, State#state.nof_reps]), + exit({Reason, generating, State#state.nof_reqs, State#state.nof_reps}); + + Else -> + ?LOG("[generating] received unexpected message: " + "~n~p", [Else]), + unexpected_data(Else), + client_loop(State) + end; + +%% The client no longer issues any new requests, instead it +%% waits for replies for all the oustanding requests to +%% arrive. +client_loop(#state{mode = stopping, + time = Time, + last_req = LastReqId} = State) -> + receive + {http, {LastReqId, {{_, 200, _}, _, _}}} -> + ?DEBUG("[stopping] received reply for last request (~p)", [LastReqId]), + time_to_complete(State), + ok; + + {http, {ReqId, {{_, 200, _}, _, _}}} -> + ?DEBUG("[stopping] received reply ~p", [ReqId]), + client_loop(State); + + {http, {ReqId, {error, Reason}}} -> + ?INFO("[stopping] request ~p failed: " + "~n Reason: ~p" + "~n NofReqs: ~p" + "~n NofReps: ~p", + [ReqId, Reason, State#state.nof_reqs, State#state.nof_reps]), + exit({Reason, stopping, State#state.nof_reqs, State#state.nof_reps}); + + Else -> + ?LOG("[stopping] received unexpected message: " + "~n~p", [Else]), + unexpected_data(Else), + client_loop(State) + + after Time -> + ?INFO("timeout when" + "~n Number of requests: ~p" + "~n Number of replies: ~p", + [State#state.nof_reqs, State#state.nof_reps]), + exit({timeout, State#state.nof_reqs, State#state.nof_reps}) + end. + +req_reply(#state{nof_reqs = NofReqs, nof_reps = NofReps}) -> + load_data({req_reply, node(), NofReqs, NofReps}). + +time_to_complete(#state{stop_time = StopTime}) -> + StoppedTime = os:timestamp(), + load_data({time_to_complete, node(), StopTime, StoppedTime}). + +load_data(Data) -> + global:send(?CTRL, {load_data, Data}). + +unexpected_data(Else) -> + global:send(?CTRL, {unexpected_data, Else}). + + +send_requests(#state{sizes = Sizes} = State, N) -> + send_requests(State, N, Sizes). + +send_requests(State, 0, Sizes) -> + State#state{sizes = Sizes}; +send_requests(#state{socket_type = SocketType, + cert_file = CertFile} = State, N, [Sz | Sizes]) -> + URL = lists:flatten(io_lib:format("~s~w", [State#state.url, Sz])), + Method = get, + Request = {URL, []}, + HTTPOptions = + case SocketType of + ip_comm -> + []; + _ -> + SslOpts = [{verify, 0}, + {certfile, CertFile}, + {keyfile, CertFile}], + case SocketType of + ssl -> + [{ssl, SslOpts}]; + ossl -> + [{ssl, {ossl, SslOpts}}]; + essl -> + [{ssl, {essl, SslOpts}}] + end + end, + Options = [{sync, false}], + {ok, Ref} = httpc:request(Method, Request, HTTPOptions, Options), + send_requests(State#state{last_req = Ref}, N-1, lists:append(Sizes, [Sz])). + + +timestamp() -> + os:timestamp(). + + +get_node_info() -> + [{cpu_topology, erlang:system_info(cpu_topology)}, + {heap_type, erlang:system_info(heap_type)}, + {nof_schedulers, erlang:system_info(schedulers)}, + {otp_release, erlang:system_info(otp_release)}, + {version, erlang:system_info(version)}, + {system_version, erlang:system_info(system_version)}, + {system_architecture, erlang:system_info(system_architecture)}]. + + diff --git a/lib/inets/examples/httpd_load_test/hdlt_ctrl.erl b/lib/inets/examples/httpd_load_test/hdlt_ctrl.erl new file mode 100644 index 0000000000..950d2632f7 --- /dev/null +++ b/lib/inets/examples/httpd_load_test/hdlt_ctrl.erl @@ -0,0 +1,1530 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% +%% +%% +%%---------------------------------------------------------------------- +%% Purpose: The httpd load test (hdlt) controller/collector module, +%% This module contains all the code of the httpd load test +%% controller/collector. It sets up the test, starts all +%% server and client nodes and applications and finally +%% collects test data. +%%---------------------------------------------------------------------- + +-module(hdlt_ctrl). + +-export([start/1, stop/0, help/0]). + +-export([init/1, proxy/7]). + +-include_lib("kernel/include/file.hrl"). +-include("hdlt_logger.hrl"). + +-define(DEFAULT_SENDRATE, 89). +-define(DEFAULT_TEST_TIME, 120). % 2 minutes +-define(DEFAULT_PORT, 8889). +-define(TIMEOUT, 60000). +-define(DEFAULT_MAX_NOF_SCHEDULERS, 8). +-define(DEFAULT_SERVER_DIR, "/tmp/hdlt"). +-define(DEFAULT_WORK_DIR, "/tmp/hdlt"). +-define(SSH_PORT, 22). +-define(DEFAULT_SOCKET_TYPE, ip_comm). +-define(DEFAULT_SERVER_CERT, "hdlt_ssl_server_cert.pem"). +-define(DEFAULT_CLIENT_CERT, "hdlt_ssl_client_cert.pem"). +-define(SSH_CONNECT_TIMEOUT, 5000). +-define(NODE_START_TIMEOUT, 5000). +-define(LOCAL_PROXY_START_TIMEOUT, ?NODE_START_TIMEOUT * 4). +-define(DEFAULT_DEBUGS, + [{ctrl, info}, {slave, silence}, {proxy, silence}, {client, silence}]). +-define(DEFAULT_WORK_SIM, 10000). +-define(DEFAULT_DATA_SIZE_START, 500). +-define(DEFAULT_DATA_SIZE_END, 1500). +-define(DEFAULT_DATA_SIZE_INCR, 1). +-define(DEFAULT_DATA_SIZE, {?DEFAULT_DATA_SIZE_START, + ?DEFAULT_DATA_SIZE_END, + ?DEFAULT_DATA_SIZE_INCR}). + + +%% hdlt = httpd load test + +-define(COLLECTOR, hdlt_ctrl). +-define(RESULTS_TAB, hdlt_results). + +-define(CLIENT_MOD, hdlt_client). +-define(CLIENT_NODE_NAME, ?CLIENT_MOD). + +-define(SERVER_MOD, hdlt_server). +-define(SERVER_NODE_NAME, ?SERVER_MOD). + +-define(LOGGER, hdlt_logger). + + +-record(state, + { + url, + test_time, + send_rate, + http_server, + http_port, + results = ?RESULTS_TAB, + nodes, + server_root, + doc_root, + server_dir, + work_dir, + server_conn, + client_conns = [], + client_mod = ?CLIENT_MOD, + clients, + nof_schedulers = 0, + max_nof_schedulers, + socket_type, + server_cert_file, + client_cert_file, + debugs, + client_sz_from, + client_sz_to, + client_sz_incr + } + ). + +-record(proxy, + { + mode, + mod, + connection, + channel, + host, + cmd, + node_name, + node, + ref, + erl_path, + paths, + args + }). + +-record(connection, + { + proxy, + node, + node_name, + host + }). + + +-record(client, {host, path, version}). +-record(server, {host, path, version}). + + +start(Config) when is_list(Config) -> + proc_lib:start_link(?MODULE, init, [Config]). + +stop() -> + global:send(?COLLECTOR, stop). + +init(Config) -> + %% io:format("Config: ~n~p~n", [Config]), + case (catch do_init(Config)) of + {ok, State} -> + proc_lib:init_ack({ok, self()}), + loop(State); + {error, _Reason} = Error -> + proc_lib:init_ack(Error), + ok; + {'EXIT', Reason} -> + proc_lib:init_ack({error, Reason}), + ok + end. + +do_init(Config) -> + %% Do not trap exit, but register ourself + global:register_name(?COLLECTOR, self()), + + State = #state{}, + ets:new(State#state.results, [bag, named_table]), + + hdlt_logger:start(), + global:sync(), + + %% Maybe enable debug + Debugs = get_debugs(Config), + ?SET_NAME("HDLT CTRL"), + set_debug_level(Debugs), + + ?DEBUG("network info: " + "~n Global names: ~p" + "~n Nodes: ~p", [global:registered_names(), nodes()]), + + %% Read config + ?LOG("read config", []), + SendRate = get_send_rate(Config), + Clients = get_clients(Config), + TestTime = get_test_time(Config), + Server = get_server(Config), + Port = get_port(Config), + ServerDir = get_server_dir(Config), + WorkingDir = get_work_dir(Config), + MaxNofSchedulers = get_max_nof_schedulers(Config), + SocketType = get_socket_type(Config), + ServerCertFile = get_server_cert_file(Config), + ClientCertFile = get_client_cert_file(Config), + WorkSim = get_work_sim(Config), + {From, To, Incr} = get_data_size(Config), + + URL = url(Server, Port, SocketType, WorkSim), + ServerRoot = filename:join(ServerDir, "server_root"), + DocRoot = ServerRoot, %% Not really used in this test + + ?DEBUG("randomize setup", []), + randomized_sizes_init(), + + %% Start used applications + ?DEBUG("ensure crypto started", []), + crypto:start(), + ?DEBUG("ensure ssh started", []), + ssh:start(), + + State2 = State#state{server_root = ServerRoot, + doc_root = DocRoot, + server_dir = ServerDir, + work_dir = WorkingDir, + max_nof_schedulers = MaxNofSchedulers, + socket_type = SocketType, + server_cert_file = ServerCertFile, + client_cert_file = ClientCertFile, + http_server = Server, + http_port = Port, + url = URL, + test_time = TestTime, + send_rate = SendRate, + clients = Clients, + debugs = Debugs, + client_sz_from = From, + client_sz_to = To, + client_sz_incr = Incr}, + + ?LOG("prepare server host", []), + prepare_server_host(State2), + + ?LOG("prepare client hosts", []), + State3 = prepare_client_hosts(State2), + + ?LOG("basic init done", []), + {ok, State3}. + + +loop(#state{nof_schedulers = N, max_nof_schedulers = M} = State) when N > M -> + + ?INFO("Starting to analyse data", []), + + AnalysedTab = analyse_data(State), + + Files = save_results_to_file(AnalysedTab, State), + io:format("~n******************************************************" + "~n~nResult(s) saved to: ~n~p~n", [Files]), + clean_up(State); + +loop(#state{url = URL, + test_time = TestTime, + send_rate = SendRate, + nof_schedulers = NofSchedulers} = State) -> + + {StartH, StartM, StartS} = erlang:time(), + + ?INFO("Performing test with ~p smp-scheduler(s): ~n" + " It will take a minimum of: ~p seconds. ~n" + " Start time: ~.2.0w:~.2.0w:~.2.0w", + [NofSchedulers, round(TestTime/1000), StartH, StartM, StartS]), + + %% Start the server node + %% (The local proxy, the node, the remote proxy, and the inets framework) + State1 = start_server_node(State), + ?DEBUG("nodes after server start: ~p", [nodes() -- [node()]]), + + %% Start the client node(s) + %% (The local proxy, the node, the remote proxy, and the inets framework) + ?LOG("start client node(s)", []), + State2 = start_client_nodes(State1), + ?DEBUG("nodes after client(s) start: ~p", [nodes() -- [node()]]), + + ?LOG("start server", []), + start_server(State2), + + ?LOG("start clients", []), + start_clients(State2, URL, TestTime, SendRate), + + ?LOG("release clients", []), + release_clients(State2), + + ?LOG("collect data", []), + collect_data(State2), + + ?LOG("stop all nodes", []), + State3 = stop_nodes(State2), + + ?INFO("Test with ~p smp-scheduler(s) complete" + "~n~n" + "****************************************************************" + "~n", + [NofSchedulers]), + loop(State3#state{nof_schedulers = NofSchedulers + 1}). + + +prepare_server_host(#state{server_root = ServerRoot, + http_server = #server{host = Host}, + socket_type = SocketType, + server_cert_file = CertFile}) -> + ?INFO("prepare server host ~s", [Host]), + Opts = [{user_interaction, false}, + {silently_accept_hosts, true}, + {timeout, 2*?SSH_CONNECT_TIMEOUT}, + {connect_timeout, ?SSH_CONNECT_TIMEOUT}], + case ssh_sftp:start_channel(Host, Opts) of + {ok, Sftp, ConnectionRef} -> + ?DEBUG("sftp connection established - now transer server content", + []), + create_server_content(Sftp, ServerRoot, SocketType, CertFile), + ?DEBUG("server content transfered - now close ssh connection ", + []), + ssh:close(ConnectionRef), + ?DEBUG("server preparation complete ", []), + ok; + Error -> + ?INFO("FAILED creating sftp channel to server host ~s: " + "~n ~p", [Host, Error]), + exit({failed_establishing_sftp_connection, Error}) + end. + +create_server_content(Sftp, ServerRoot, SocketType, CertFile) -> + %% Create server root + ?DEBUG("ensure existence of ~p", [ServerRoot]), + ensure_remote_dir_exist(Sftp, ServerRoot), + + %% Create the server ebin dir (for the starter module) + EBIN = filename:join(ServerRoot, "ebin"), + ?DEBUG("make ebin dir: ~p", [EBIN]), + maybe_create_remote_dir(Sftp, EBIN), + + %% Create the server ebin dir (for the starter module) + LOG = filename:join(ServerRoot, "log"), + ?DEBUG("make log dir: ~p", [LOG]), + maybe_create_remote_dir(Sftp, LOG), + + LocalServerMod = local_server_module(), + ?DEBUG("copy server stub/proxy module ~s", [LocalServerMod]), + RemoteServerMod = remote_server_module(EBIN), + {ok, ServerModBin} = file:read_file(LocalServerMod), + ok = ssh_sftp:write_file(Sftp, RemoteServerMod, ServerModBin), + + LocalSlaveMod = local_slave_module(), + ?DEBUG("copy slave module ~s", [LocalSlaveMod]), + RemoteSlaveMod = remote_slave_module(EBIN), + {ok, SlaveModBin} = file:read_file(LocalSlaveMod), + ok = ssh_sftp:write_file(Sftp, RemoteSlaveMod, SlaveModBin), + + LocalLoggerMod = local_logger_module(), + ?DEBUG("copy logger module ~s", [LocalLoggerMod]), + RemoteLoggerMod = remote_logger_module(EBIN), + {ok, LoggerModBin} = file:read_file(LocalLoggerMod), + ok = ssh_sftp:write_file(Sftp, RemoteLoggerMod, LoggerModBin), + + %% Create the inets server data dir + CGI = filename:join(ServerRoot, "cgi-bin"), + ?DEBUG("make cgi dir: ~p", [CGI]), + maybe_create_remote_dir(Sftp, CGI), + + LocalRandomMod = local_random_html_module(), + ?DEBUG("copy random-html module ~s", [LocalRandomMod]), + RemoteRandomMod = remote_random_html_module(EBIN), + {ok, RandomModBin} = file:read_file(LocalRandomMod), + ok = ssh_sftp:write_file(Sftp, RemoteRandomMod, RandomModBin), + + case SocketType of + ip_comm -> + ok; + _ -> + SSLDir = filename:join(ServerRoot, "ssl"), + ?DEBUG("make conf dir: ~p", [SSLDir]), + maybe_create_remote_dir(Sftp, SSLDir), + ?DEBUG("copy ssl cert file ~s", [CertFile]), + {ok, CertBin} = file:read_file(CertFile), + RemoteCertFile = filename:join(SSLDir, + filename:basename(CertFile)), + ok = ssh_sftp:write_file(Sftp, RemoteCertFile, CertBin), + ok + end, + + ?DEBUG("done", []), + ok. + +remote_server_module(Path) -> + Mod = server_module(), + filename:join(Path, Mod). + +local_server_module() -> + Mod = server_module(), + case code:where_is_file(Mod) of + Path when is_list(Path) -> + Path; + _ -> + exit({server_module_not_found, Mod}) + end. + +server_module() -> + module(?SERVER_MOD). + + +prepare_client_hosts(#state{work_dir = WorkDir, + clients = Clients, + socket_type = SocketType, + client_cert_file = CertFile} = State) -> + Clients2 = + prepare_client_hosts(WorkDir, SocketType, CertFile, Clients, []), + State#state{clients = Clients2}. + +prepare_client_hosts(_WorkDir, _SocketType, _CertFile, [], Acc) -> + lists:reverse(Acc); +prepare_client_hosts(WorkDir, SocketType, CertFile, [Client|Clients], Acc) -> + case prepare_client_host(WorkDir, SocketType, CertFile, Client) of + ok -> + prepare_client_hosts(WorkDir, SocketType, CertFile, Clients, + [Client|Acc]); + _ -> + prepare_client_hosts(WorkDir, SocketType, CertFile, Clients, Acc) + end. + +prepare_client_host(WorkDir, SocketType, CertFile, #client{host = Host}) -> + ?INFO("prepare client host ~s", [Host]), + Opts = [{user_interaction, false}, + {silently_accept_hosts, true}, + {timeout, 2*?SSH_CONNECT_TIMEOUT}, + {connect_timeout, ?SSH_CONNECT_TIMEOUT}], + case ssh_sftp:start_channel(Host, Opts) of + {ok, Sftp, ConnectionRef} -> + ?DEBUG("sftp connection established - now transer client content", + []), + create_client_content(Sftp, WorkDir, SocketType, CertFile), + ?DEBUG("client content transered - now close ssh connection ", []), + ssh:close(ConnectionRef), + ?DEBUG("client preparation complete ", []), + ok; + Error -> + ?INFO("FAILED creating sftp channel to client host ~s: skipping" + "~n ~p", [Host, Error]), + Error + end. + +create_client_content(Sftp, WorkDir, SocketType, CertFile) -> + %% Create work dir + ?DEBUG("ensure existence of ~p", [WorkDir]), + ensure_remote_dir_exist(Sftp, WorkDir), + + %% Create the client ebin dir + EBIN = filename:join(WorkDir, "ebin"), + RemoteClientMod = remote_client_module(EBIN), + ?DEBUG("make ebin dir: ~p", [EBIN]), + maybe_create_remote_dir(Sftp, EBIN), + + LocalClientMod = local_client_module(), + ?DEBUG("copy client stub/proxy module ~s", [LocalClientMod]), + {ok, ClientModBin} = file:read_file(LocalClientMod), + ok = ssh_sftp:write_file(Sftp, RemoteClientMod, ClientModBin), + + LocalSlaveMod = local_slave_module(), + ?DEBUG("copy slave module ~s", [LocalSlaveMod]), + RemoteSlaveMod = remote_slave_module(EBIN), + {ok, SlaveModBin} = file:read_file(LocalSlaveMod), + ok = ssh_sftp:write_file(Sftp, RemoteSlaveMod, SlaveModBin), + + LocalLoggerMod = local_logger_module(), + ?DEBUG("copy logger module ~s", [LocalLoggerMod]), + RemoteLoggerMod = remote_logger_module(EBIN), + {ok, LoggerModBin} = file:read_file(LocalLoggerMod), + ok = ssh_sftp:write_file(Sftp, RemoteLoggerMod, LoggerModBin), + + case SocketType of + ip_comm -> + ok; + _ -> + %% We should really store the remote path somewhere as + %% we use it when starting the client service... + SSLDir = filename:join(WorkDir, "ssl"), + ?DEBUG("make ssl dir: ~p", [SSLDir]), + maybe_create_remote_dir(Sftp, SSLDir), + ?DEBUG("copy ssl cert file ~s", [CertFile]), + {ok, CertBin} = file:read_file(CertFile), + RemoteCertFile = filename:join(SSLDir, + filename:basename(CertFile)), + ok = ssh_sftp:write_file(Sftp, RemoteCertFile, CertBin), + ok + end, + + ?DEBUG("done", []), + ok. + +remote_client_module(Path) -> + Mod = client_module(), + filename:join(Path, Mod). + +local_client_module() -> + Mod = client_module(), + case code:where_is_file(Mod) of + Path when is_list(Path) -> + Path; + _ -> + exit({client_module_not_found, Mod}) + end. + +client_module() -> + module(?CLIENT_MOD). + + +remote_slave_module(Path) -> + Mod = slave_module(), + filename:join(Path, Mod). + +local_slave_module() -> + Mod = slave_module(), + case code:where_is_file(Mod) of + Path when is_list(Path) -> + Path; + _ -> + exit({slave_module_not_found, Mod}) + end. + +slave_module() -> + module(hdlt_slave). + + +remote_logger_module(Path) -> + Mod = logger_module(), + filename:join(Path, Mod). + +local_logger_module() -> + Mod = logger_module(), + case code:where_is_file(Mod) of + Path when is_list(Path) -> + Path; + _ -> + exit({logger_module_not_found, Mod}) + end. + +logger_module() -> + module(hdlt_logger). + + +remote_random_html_module(Path) -> + Mod = random_html_module(), + filename:join(Path, Mod). + +local_random_html_module() -> + Mod = random_html_module(), + case code:where_is_file(Mod) of + Path when is_list(Path) -> + Path; + _ -> + exit({random_module_not_found, Mod}) + end. + +random_html_module() -> + module(hdlt_random_html). + + +module(Mod) -> + Ext = string:to_lower(erlang:system_info(machine)), + lists:flatten(io_lib:format("~w.~s", [Mod, Ext])). + + +%% ----------------------------------------------------------------------- +%% - For every node created (server and client both) there is both +%% a local and remote proxy. +%% - The local proxy is running on the local (controller/collector) node. +%% - The remote proxy is running on the client or server node(s). +%% - The local (ctrl) proxy monitor the remote (server/client) proxy. +%% - The remote (server/client) proxy monitor the local (ctrl) proxy. +%% + +start_client_nodes(#state{clients = Clients, + work_dir = WorkDir, + debugs = Debugs} = State) -> + Connections = + [start_client_node(Client, WorkDir, Debugs) || Client <- Clients], + State#state{client_conns = Connections}. + +start_client_node(#client{path = ErlPath, host = Host}, WorkDir, Debugs) -> + ?INFO("start client on host ~p", [Host]), + EbinDir = filename:join(WorkDir, "ebin"), + start_client_node(Host, ErlPath, [EbinDir], Debugs). + +start_client_node(Host, ErlPath, Paths, Debugs) -> + start_node(Host, ?CLIENT_NODE_NAME, + ErlPath, Paths, [], ?CLIENT_MOD, Debugs). + + +start_server_node(#state{http_server = #server{path = ErlPath, host = Host}, + server_root = ServerRoot, + nof_schedulers = NofScheds, + debugs = Debugs} = State) -> + ?INFO("start server on host ~p", [Host]), + CgiBinDir = filename:join(ServerRoot, "cgi-bin"), + EbinDir = filename:join(ServerRoot, "ebin"), + Connection = + start_server_node(Host, ErlPath, [CgiBinDir, EbinDir], + Debugs, NofScheds), + State#state{server_conn = Connection}. + +start_server_node(Host, ErlPath, Paths, Debugs, NofScheds) -> + Args = + if + NofScheds =:= 0 -> + "-smp disable"; + true -> + lists:flatten(io_lib:format("-smp +S ~w", [NofScheds])) + end, + start_node(Host, ?SERVER_NODE_NAME, + ErlPath, Paths, Args, ?SERVER_MOD, Debugs). + + +%% ----------------------------------------------------------------------- +%% - For every node created (server and client both) there is both +%% a local and remote proxy. +%% - The local proxy is running on the local (controller/collector) node. +%% - The remote proxy is running on the client or server node(s). +%% - The local (ctrl) proxy monitor the remote (server/client) proxy. +%% - The remote (server/client) proxy monitor the local (ctrl) proxy. +%% + +start_node(Host, NodeName, ErlPath, Paths, Args, Module, Debugs) -> + %% Start the (local) proxy + ?DEBUG("start_node -> start local proxy and remote node", []), + ProxyDebug = proplists:get_value(proxy, Debugs, silence), + Proxy = proxy_start(Host, NodeName, ErlPath, Paths, Args, Module, + ProxyDebug), + + ?DEBUG("start_node -> local proxy started - now start node", []), + SlaveDebug = proplists:get_value(slave, Debugs, silence), + Node = proxy_start_node(Proxy, SlaveDebug), + + ?DEBUG("start_node -> sync global", []), + global:sync(), + + ?DEBUG("start_node -> start remote proxy", []), + proxy_start_remote(Proxy), + + ?DEBUG("start_node -> start (remote) inets framework", []), + proxy_start_inets(Proxy), + + ?DEBUG("start_node -> done", []), + #connection{proxy = Proxy, node = Node, node_name = NodeName, host = Host}. + + +proxy_start(Host, NodeName, ErlPath, Paths, Args, Module, Debug) -> + ?LOG("try starting local proxy for ~p@~s", [NodeName, Host]), + ProxyArgs = [Host, NodeName, ErlPath, Paths, Args, Module, Debug], + case proc_lib:start_link(?MODULE, proxy, + ProxyArgs, ?LOCAL_PROXY_START_TIMEOUT) of + {ok, Proxy} -> + Proxy; + Error -> + exit({failed_starting_proxy, Error}) + end. + +proxy_start_node(Proxy, Debug) -> + {ok, Node} = proxy_request(Proxy, {start_node, Debug}), + Node. + +proxy_start_remote(Proxy) -> + proxy_request(Proxy, start_remote_proxy). + +proxy_start_inets(Proxy) -> + proxy_request(Proxy, start_inets). + +proxy_start_service(Proxy, Args) -> + proxy_request(Proxy, {start_service, Args}). + +proxy_release(Proxy) -> + proxy_request(Proxy, release). + +proxy_stop(Proxy) -> + StopResult = proxy_request(Proxy, stop), + ?DEBUG("proxy stop result: ~p", [StopResult]), + StopResult. + +proxy_request(Proxy, Req) -> + Ref = make_ref(), + Proxy ! {proxy_request, Ref, self(), Req}, + receive + {proxy_reply, Ref, Proxy, Rep} -> + Rep + end. + +proxy_reply(From, Ref, Rep) -> + From ! {proxy_reply, Ref, self(), Rep}. + +proxy(Host, NodeName, ErlPath, Paths, Args, Module, Debug) -> + process_flag(trap_exit, true), + SName = lists:flatten( + io_lib:format("HDLT CTRL PROXY[~p,~s,~w]", + [self(), Host, NodeName])), + ?SET_NAME(SName), + ?SET_LEVEL(Debug), + ?LOG("starting with" + "~n Host: ~p" + "~n NodeName: ~p" + "~n ErlPath: ~p" + "~n Paths: ~p" + "~n Args: ~p" + "~n Module: ~p", [Host, NodeName, ErlPath, Paths, Args, Module]), + State = #proxy{mode = started, + mod = Module, + host = Host, + node_name = NodeName, + erl_path = ErlPath, + paths = Paths, + args = Args}, + proc_lib:init_ack({ok, self()}), + ?DEBUG("started", []), + proxy_loop(State). + + +proxy_loop(#proxy{mode = stopping}) -> + receive + {proxy_request, Ref, From, stop} -> + ?LOG("[stopping] received stop order", []), + proxy_reply(From, Ref, ok), + exit(normal); + + {'EXIT', Pid, Reason} -> + ?INFO("[stopping] received exit message from ~p: " + "~n Reason: ~p", [Pid, Reason]), + exit(Reason) + + end; + +proxy_loop(#proxy{mode = started, + host = Host, + node_name = NodeName, + erl_path = ErlPath, + paths = Paths, + args = Args} = State) -> + receive + {proxy_request, Ref, From, {start_node, Debug}} -> + ?LOG("[starting] received start_node order", []), + case hdlt_slave:start_link(Host, NodeName, + ErlPath, Paths, Args, + Debug) of + {ok, Node} -> + ?DEBUG("[starting] node ~p started - now monitor", [Node]), + erlang:monitor_node(Node, true), + State2 = State#proxy{mode = operational, + node = Node}, + proxy_reply(From, Ref, {ok, Node}), + proxy_loop(State2); + {error, Reason} -> + ?INFO("[starting] failed starting node: " + "~n Reason: ~p", [Reason]), + exit({failed_starting_node, {Host, NodeName, Reason}}) + end; + + {'EXIT', Pid, Reason} -> + ?INFO("[stopping] received exit message from ~p: " + "~n Reason: ~p", [Pid, Reason]), + exit(Reason) + + end; + +proxy_loop(#proxy{mode = operational, + mod = Mod, + node = Node} = State) -> + ?DEBUG("[operational] await command", []), + receive + {proxy_request, Ref, From, start_remote_proxy} -> + ?LOG("[operational] start remote proxy", []), + case rpc:call(Node, Mod, start, [?GET_LEVEL()]) of + {ok, Pid} -> + ?DEBUG("[operational] remote proxy started (~p) - " + "create monitor", [Pid]), + ProxyRef = erlang:monitor(process, Pid), + ?DEBUG("[operational] monitor: ~p", [Ref]), + proxy_reply(From, Ref, ok), + proxy_loop(State#proxy{ref = ProxyRef}); + Error -> + ?INFO("[operational] failed starting remote proxy" + "~n Error: ~p", [Error]), + ReplyReason = {failed_starting_remote_proxy, + {Node, Error}}, + Reply = {error, ReplyReason}, + proxy_reply(From, Ref, Reply), + exit({failed_starting_remote_proxy, {Node, Error}}) + end; + + {proxy_request, Ref, From, start_inets} -> + ?INFO("[operational] start inets framework", []), + rpc:cast(Node, Mod, start_inets, []), + proxy_reply(From, Ref, ok), + proxy_loop(State); + + {proxy_request, Ref, From, {start_service, Args}} -> + ?INFO("[operational] start service with" + "~n ~p", [Args]), + case rpc:call(Node, Mod, start_service, Args) of + ok -> + ?DEBUG("[operational] service started", []), + proxy_reply(From, Ref, ok), + proxy_loop(State); + Error -> + ?INFO("[operational] failed starting service: " + "~n Args. ~p" + "~n Error: ~p", [Args, Error]), + erlang:demonitor(State#proxy.ref, [flush]), + Reply = {error, {failed_starting_service, Node, Error}}, + proxy_reply(From, Ref, Reply), + exit({failed_starting_service, Node, Error}) + end; + + {proxy_request, Ref, From, release} -> + ?INFO("[operational] release", []), + rpc:call(Node, Mod, release, []), + proxy_reply(From, Ref, ok), + proxy_loop(State); + + {proxy_request, Ref, From, stop} -> + ?INFO("[operational] received stop order", []), + erlang:demonitor(State#proxy.ref, [flush]), + ?DEBUG("[operational] rpc cast stop order", []), + rpc:cast(Node, Mod, stop, []), + %% And wait for the node death to be reported + Reason = + receive + {nodedown, Node} when State#proxy.node =:= Node -> + ok + after 10000 -> + ?INFO("Node did not die within expected time frame", + []), + {node_death_timeout, Node} + end, + ?DEBUG("[operational] ack stop", []), + proxy_reply(From, Ref, Reason), + exit(normal); + + {nodedown, Node} when State#proxy.node =:= Node -> + ?INFO("[operational] received unexpected nodedoen message", []), + exit({node_died, Node}); + + {'DOWN', Ref, process, _, normal} when State#proxy.ref =:= Ref -> + ?INFO("[operational] remote proxy terminated normally", []), + proxy_loop(State#proxy{ref = undefined, + connection = undefined, + mode = stopping}); + + {'DOWN', Ref, process, _, noconnection} when State#proxy.ref =:= Ref -> + ?INFO("[operational] remote proxy terminated - no node", []), + proxy_loop(State#proxy{ref = undefined, + connection = undefined, + mode = stopping}); + + {'DOWN', Ref, process, _, Reason} when State#proxy.ref =:= Ref -> + ?INFO("[operational] remote proxy terminated: " + "~n Reason: ~p", [Reason]), + exit({remote_proxy_crash, Reason}); + + {'EXIT', Pid, Reason} -> + ?INFO("[operational] received unexpected exit message from ~p: " + "~n Reason: ~p", [Pid, Reason]), + proxy_loop(State) + + end. + + +stop_nodes(#state{server_conn = ServerConn, + client_conns = ClientConns} = State) -> + lists:foreach( + fun(#connection{proxy = Proxy, node_name = NodeName, host = Host}) -> + ?DEBUG("stop_erlang_nodes -> send stop order to local proxy ~p" + "~n for node ~p on ~s", [Proxy, NodeName, Host]), + proxy_stop(Proxy) + end, + ClientConns ++ [ServerConn]), + ?DEBUG("stop_erlang_nodes -> sleep some to give the nodes time to die", + []), + timer:sleep(1000), + ?DEBUG("stop_erlang_nodes -> and a final cleanup round", []), + lists:foreach(fun(Node) -> + ?INFO("try brutal stop node ~p", [Node]), + rpc:cast(Node, erlang, halt, []) + end, + nodes() -- [node()]), + ?DEBUG("stop_erlang_nodes -> done", []), + State#state{server_conn = undefined, client_conns = []}. + + +%% The nodes on which the HDLT clients run have been started previously +start_clients(#state{client_conns = Connections, + debugs = Debugs, + work_dir = WorkDir, + socket_type = SocketType, + client_cert_file = CertFile, + client_sz_from = From, + client_sz_to = To, + client_sz_incr = Incr}, + URL, TestTime, SendRate) -> + Debug = proplists:get_value(client, Debugs, silence), + StartClient = + fun(#connection{host = Host} = Connection) -> + ?DEBUG("start client on ~p", [Host]), + start_client(Connection, + WorkDir, SocketType, CertFile, + URL, From, To, Incr, + TestTime, SendRate, Debug); + (_) -> + ok + end, + lists:foreach(StartClient, Connections). + +start_client(#connection{proxy = Proxy}, + WorkDir, SocketType, LocalCertFile, + URL, From, To, Incr, + TestTime, SendRate, Debug) -> + SSLDir = filename:join(WorkDir, "ssl"), + CertFile = filename:join(SSLDir, filename:basename(LocalCertFile)), + Sizes = randomized_sizes(From, To, Incr), + Args = [SocketType, CertFile, URL, Sizes, TestTime, SendRate, Debug], + proxy_start_service(Proxy, [Args]). + +release_clients(#state{client_conns = Connections}) -> + ReleaseClient = + fun(#connection{proxy = Proxy, + host = Host}) -> + ?DEBUG("release client on ~p", [Host]), + proxy_release(Proxy); + (_) -> + ok + end, + lists:foreach(ReleaseClient, Connections). + + +start_server(#state{server_conn = #connection{proxy = Proxy}, + http_port = Port, + server_root = ServerRoot, + doc_root = DocRoot, + socket_type = SocketType, + server_cert_file = CertFile}) -> + + HttpdConfig = + httpd_config(Port, "hdlt", ServerRoot, DocRoot, SocketType, CertFile), + ?LOG("start the httpd inets service with config: " + "~n ~p", [HttpdConfig]), + proxy_start_service(Proxy, [HttpdConfig]), + ?DEBUG("start_server -> done", []), + ok. + + +httpd_config(Port, ServerName, ServerRoot, DocRoot, + SocketType, LocalCertFile) -> + LogDir = filename:join(ServerRoot, "log"), + ErrorLog = filename:join(LogDir, "error_log"), + TransferLog = filename:join(LogDir, "access_log"), + + SSL = + case SocketType of + ip_comm -> + []; + _ -> % ssl + SSLDir = filename:join(ServerRoot, "ssl"), + CertFile = + filename:join(SSLDir, filename:basename(LocalCertFile)), + [ + {ssl_certificate_file, CertFile}, + {ssl_certificate_key_file, CertFile}, + {ssl_verify_client, 0} + ] + end, + [{port, Port}, + {server_name, ServerName}, + {server_root, ServerRoot}, + {document_root, DocRoot}, + {error_log, ErrorLog}, + {error_log_format, pretty}, + {transfer_log, TransferLog}, + {socket_type, SocketType}, + {max_clients, 10000}, + {modules, [mod_alias, mod_auth, mod_esi, mod_actions, mod_cgi, + mod_dir, mod_get, mod_head, mod_log, mod_disk_log]}, + {script_alias, {"/cgi-bin", filename:join(ServerRoot, "cgi-bin")}}, + {erl_script_alias, {"/cgi-bin", [hdlt_random_html]}}, + {erl_script_timeout, 120000} | SSL]. + + +clean_up(#state{server_root = ServerRoot, + work_dir = WorkDir, + http_server = #server{host = Host}, + clients = Clients}) -> + ?DEBUG("begin server cleanup", []), + server_clean_up(ServerRoot, WorkDir, Host), + ?DEBUG("begin lient cleanup", []), + clients_clean_up(WorkDir, Clients), + ?DEBUG("cleanup done", []), + ok. + +server_clean_up(ServerRoot, WorkDir, Host) -> + ?DEBUG("server cleanup - create sftp channel", []), + {ok, Sftp, ConnectionRef} = + ssh_sftp:start_channel(Host, [{user_interaction, false}, + {silently_accept_hosts, true}]), + ?DEBUG("server cleanup - delete ~p dirs", [ServerRoot]), + del_dirs(Sftp, ServerRoot), + ?DEBUG("server cleanup - delete ~p dirs", [WorkDir]), + del_dirs(Sftp, WorkDir), + ?DEBUG("server cleanup - close sftp channel", []), + ssh:close(ConnectionRef). + +clients_clean_up(_WorkDir, []) -> + ok; +clients_clean_up(WorkDir, [Client|Clients]) -> + client_clean_up(WorkDir, Client), + clients_clean_up(WorkDir, Clients). + +client_clean_up(WorkDir, #client{host = Host}) -> + ?DEBUG("client cleanup - create sftp channel to ~p", [Host]), + {ok, Sftp, ConnectionRef} = + ssh_sftp:start_channel(Host, [{user_interaction, false}, + {silently_accept_hosts, true}]), + ?DEBUG("client cleanup - delete ~p dirs", [WorkDir]), + del_dirs(Sftp, WorkDir), + ?DEBUG("client cleanup - close sftp channel", []), + ssh:close(ConnectionRef). + + +del_dirs(Sftp, Dir) -> + case ssh_sftp:list_dir(Sftp, Dir) of + {ok, []} -> + ssh_sftp:del_dir(Sftp, Dir); + {ok, Files} -> + Files2 = [F || F <- Files, (F =/= "..") andalso (F =/= ".")], + lists:foreach(fun(File) when ((File =/= "..") andalso + (File =/= ".")) -> + FullPath = filename:join(Dir, File), + case ssh_sftp:read_file_info(Sftp, + FullPath) of + {ok, #file_info{type = directory}} -> + del_dirs(Sftp, FullPath), + ssh_sftp:del_dir(Sftp, FullPath); + {ok, _} -> + ssh_sftp:delete(Sftp, FullPath) + end + end, Files2); + _ -> + ok + end. + +collect_data(#state{clients = Clients} = State) -> + N = length(Clients), + collect_req_reply(N, State), + collect_time(N, State). + +collect_req_reply(0, _State) -> + ?DEBUG("all reply data collected", []), + ok; +collect_req_reply(N, #state{nof_schedulers = NofScheduler, + results = Db, + client_conns = Conns} = State) -> + ?DEBUG("await reply data from ~p client(s)", [N]), + receive + {load_data, + {req_reply, Client, NoRequests, NoReplys}} -> + ?DEBUG("received req_reply load-data from client ~p: " + "~n Number of requests: ~p" + "~n Number of replies: ~p", + [Client, NoRequests, NoReplys]), + ets:insert(Db, {{NofScheduler, Client}, + {req_reply, NoRequests, NoReplys}}); + stop -> + ?INFO("received stop", []), + exit(self(), stop); + + {client_exit, Client, Node, Reason} -> + ?INFO("Received unexpected client exit from ~p on node ~p " + "while collecting replies: " + "~n ~p", [Client, Node, Reason]), + case lists:keysearch(Node, #connection.node, Conns) of + {value, Conn} -> + ?LOG("Found problem connection: " + "~n ~p", [Conn]), + exit({unexpected_client_exit, Reason}); + false -> + collect_req_reply(N, State) + end + end, + collect_req_reply(N-1, State). + +collect_time(0, _State) -> + ?DEBUG("all time data collected", []), + ok; +collect_time(N, #state{nof_schedulers = NofScheduler, + results = Db, + client_conns = Conns} = State) -> + ?DEBUG("await time data from ~p clients", [N]), + receive + {load_data, + {time_to_complete, Client, StopTime, LastResponseTime}} -> + ?LOG("received time load-data from client ~p: " + "~n Time of stop: ~p" + "~n Time of last response: ~p", + [Client, StopTime, LastResponseTime]), + ets:insert(Db, {{NofScheduler, Client}, + {time, StopTime, LastResponseTime}}); + stop -> + ?INFO("received stop while collecting data, when N = ~p", [N]), + exit(self(), stop); + + {client_exit, Client, Node, Reason} -> + ?INFO("Received unexpected exit from client ~p on node ~p " + "while collecting time data: " + "~n ~p", [Client, Node, Reason]), + case lists:keysearch(Node, #connection.node, Conns) of + {value, Conn} -> + ?LOG("Found problem connection: " + "~n ~p", [Conn]), + exit({unexpected_client_exit, Reason}); + false -> + collect_req_reply(N, State) + end; + + Else -> %%% Something is wrong! + ?INFO("RECEIVED UNEXPECTED MESSAGE WHILE COLLECTING TIME DATA: " + "~n ~p", [Else]), + collect_time(N, State) + end, + collect_time(N-1, State). + +analyse_data(#state{results = Db, + max_nof_schedulers = MaxNofSchedulers, + test_time = MicroSec}) -> + Tab = ets:new(analysed_results, [set]), + lists:foreach(fun(NofSchedulers) -> + Result = analyse(NofSchedulers, Db, MicroSec), + ets:insert(Tab, Result) + end, [N || N <- lists:seq(0, MaxNofSchedulers)]), + Tab. + + +no_requests_replys(NoSchedulers, Tab) -> + NoRequests = + ets:select(Tab, [{{{NoSchedulers,'_'},{req_reply, '$1', '_'}}, + [],['$$']}]), + NoReplys = + ets:select(Tab, [{{{NoSchedulers, '_'}, {req_reply, '_', '$1'}}, + [], ['$$']}]), + + {lists:sum(lists:append(NoRequests)), + lists:sum(lists:append(NoReplys))}. + +max_time_to_final_response(NofSchedulers, Tab) -> + Candidates = + ets:select(Tab, [{{{NofSchedulers, '_'}, {time, '$1', '$2'}}, + [], ['$$']}]), + + NewCandidates = lists:map( + fun([StopTime, LastTime]) -> + round( + timer:now_diff(LastTime, StopTime) / 100000)/10 + end, Candidates), + + lists:max(NewCandidates). + + +analyse(NofSchedulers, Db, TestTime) -> + Sec = TestTime / 1000, + {NoRequests, NoReplys} = no_requests_replys(NofSchedulers, Db), + {NofSchedulers, round(NoReplys / Sec), NoRequests, + max_time_to_final_response(NofSchedulers, Db)}. + + +save_results_to_file(AnalysedTab, + #state{socket_type = SocketType, + http_server = #server{host = Server}, + max_nof_schedulers = MaxNofSchedulers}) -> + FileName = fun(Post) -> + File = + lists:flatten( + io_lib:format("~s_~w_~s", + [Server, SocketType, Post])), + filename:join("./", File) + end, + Reps = FileName("replys_per_sec.txt"), + Reqs = FileName("total_requests.txt"), + Decay = FileName("decay_time.txt"), + + [FdReps, FdReqs, FdDecay] = + lists:map(fun(File) -> + {ok, Fd} = file:open(File, [write]), + Fd + end, [Reps, Reqs, Decay]), + lists:foreach(fun(NofSchedulers) -> + save_result_to_file(NofSchedulers, + FdReps, FdReqs, + FdDecay, AnalysedTab) + end, [N || N <- lists:seq(0, MaxNofSchedulers)]), + [Reps, Reqs, Decay]. + +save_result_to_file(NofSchedulers, + FdReps, FdReqs, FdDecay, AnalysedTab) -> + + [{NofSchedulers, NofRepsPerSec, NofReqs, MaxFinalResponseTime}] = + ets:lookup(AnalysedTab, NofSchedulers), + + file:write(FdReps, io_lib:format("~p,~p~n", + [NofRepsPerSec, NofSchedulers])), + file:write(FdReqs, io_lib:format("~p,~p~n", + [NofReqs, NofSchedulers])), + file:write(FdDecay, io_lib:format("~p,~p~n", [MaxFinalResponseTime, + NofSchedulers])). + + +help() -> + io:format("hdlt:start(Options). Where options:~n " + " ~n~p~n~n hdlt:start([]). -> hdlt:start(~p)~n~n", + [[{send_rate, "integer()", + "Numer of outstanding requests that a client " + "should have during the test to create a load situation."}, + {clients, "[{path(), host()}]", "Paths to erlang and names of hosts to run clients on."}, + {test_time, "{hours(), mins(), sec()}", + "How long the test should be run."}, + {server, "{path(), host()}", "Path to erl and name of host to run the HTTP-server on."}, + {port, "port()", "The port that the HTTP-server should use."}, + {server_dir, "dir()", "The directory where the HTTP server " + " stores its contents and configuration."}, + {work_dir, "dir()", "Path on the computer, where the test " + "is run, to a directory where the results can be saved."}, + {max_no_schedulers, "integer()", + "Max number of schedulers to run."}, + {socket_type, "Httpd configuration option socket_type"}], + defaults()]). + + +defaults() -> + [{send_rate, ?DEFAULT_SENDRATE}, + %% {clients, []}, + {test_time, ?DEFAULT_TEST_TIME}, + %% {server, ?DEFAULT_SERVER}, + {port, ?DEFAULT_PORT}, + {server_dir, ?DEFAULT_SERVER_DIR}, + {work_dir, ?DEFAULT_WORK_DIR}, + {max_nof_schedulers, ?DEFAULT_MAX_NOF_SCHEDULERS}, + {socket_type, ?DEFAULT_SOCKET_TYPE}]. + + +get_debugs(Config) -> + ?DEBUG("get debugs", []), + Debugs = proplists:get_value(debug, Config, ?DEFAULT_DEBUGS), + verify_debugs(Debugs), + Debugs. + +verify_debugs([]) -> + ok; +verify_debugs([{Tag, Debug}|Debugs]) -> + verify_debug(Tag, Debug), + verify_debugs(Debugs). + +verify_debug(Tag, Debug) -> + case lists:member(Tag, [ctrl, proxy, slave, client]) of + true -> + ok; + false -> + exit({bad_debug_tag, Tag}) + end, + case lists:member(Debug, [silence, info, log, debug]) of + true -> + ok; + false -> + exit({bad_debug_level, Debug}) + end. + +get_send_rate(Config) -> + ?DEBUG("get send_rate", []), + case proplists:get_value(send_rate, Config, ?DEFAULT_SENDRATE) of + SendRate when is_integer(SendRate) andalso (SendRate > 0) -> + SendRate; + BadSendRate -> + exit({bad_sendrate, BadSendRate}) + end. + + +get_clients(Config) -> + ?DEBUG("get clients", []), + case proplists:get_value(clients, Config, undefined) of + undefined -> + missing_mandatory_config(clients); + Clients when is_list(Clients) andalso (length(Clients) > 0) -> + case [#client{path = Path, host = Host} || + {Path, Host} <- Clients] of + Clients2 when (length(Clients2) > 0) -> + Clients2; + _ -> + exit({bad_clients, Clients}) + end; + + BadClients -> + exit({bad_clients, BadClients}) + + end. + +get_server(Config) -> + ?DEBUG("get server", []), + case proplists:get_value(server, Config) of + {Path, Host} when is_list(Path) andalso is_list(Host) -> + #server{path = Path, host = Host}; + undefined -> + missing_mandatory_config(server) + end. + +get_server_dir(Config) -> + ?DEBUG("get server_dir", []), + get_dir(server_dir, Config, ?DEFAULT_SERVER_DIR). + +get_work_dir(Config) -> + ?DEBUG("get work_dir", []), + get_dir(work_dir, Config, ?DEFAULT_WORK_DIR). + +get_dir(Key, Config, Default) -> + Dir = proplists:get_value(Key, Config, Default), + ensure_absolute(Dir), + Dir. + +ensure_absolute(Path) -> + case filename:pathtype(Path) of + absolute -> + ok; + PathType -> + exit({bad_pathtype, Path, PathType}) + end. + +get_port(Config) -> + ?DEBUG("get port", []), + case proplists:get_value(port, Config, ?DEFAULT_PORT) of + Port when is_integer(Port) andalso (Port > 0) -> + Port; + BadPort -> + exit({bad_port, BadPort}) + end. + +get_socket_type(Config) -> + ?DEBUG("get socket_type", []), + case proplists:get_value(socket_type, Config, ?DEFAULT_SOCKET_TYPE) of + SocketType when ((SocketType =:= ip_comm) orelse + (SocketType =:= ssl) orelse + (SocketType =:= essl) orelse + (SocketType =:= ossl)) -> + SocketType; + BadSocketType -> + exit({bad_socket_type, BadSocketType}) + end. + +get_test_time(Config) -> + ?DEBUG("get test_time", []), + case proplists:get_value(test_time, Config, ?DEFAULT_TEST_TIME) of + Seconds when is_integer(Seconds) andalso (Seconds > 0) -> + timer:seconds(Seconds); + BadTestTime -> + exit({bad_test_time, BadTestTime}) + end. + +get_max_nof_schedulers(Config) -> + ?DEBUG("get max_nof_schedulers", []), + case proplists:get_value(max_nof_schedulers, + Config, + ?DEFAULT_MAX_NOF_SCHEDULERS) of + MaxNofScheds when (is_integer(MaxNofScheds) andalso + (MaxNofScheds >= 0)) -> + MaxNofScheds; + BadMaxNofScheds -> + exit({bad_max_nof_schedulers, BadMaxNofScheds}) + end. + + +get_server_cert_file(Config) -> + ?DEBUG("get server cert file", []), + get_cert_file(server_cert_file, ?DEFAULT_SERVER_CERT, Config). + +get_client_cert_file(Config) -> + ?DEBUG("get client cert file", []), + get_cert_file(client_cert_file, ?DEFAULT_CLIENT_CERT, Config). + +get_cert_file(Tag, DefaultCertFileName, Config) -> + LibDir = code:lib_dir(inets), + HdltDir = filename:join(LibDir, "examples/httpd_load_test"), + DefaultCertFile = filename:join(HdltDir, DefaultCertFileName), + case proplists:get_value(Tag, Config, DefaultCertFile) of + F when is_list(F) -> + case file:read_file_info(F) of + {ok, #file_info{type = regular}} -> + F; + {ok, #file_info{type = Type}} -> + exit({wrong_file_type, Tag, F, Type}); + {error, Reason} -> + exit({failed_readin_file_info, Tag, F, Reason}) + end; + BadFile -> + exit({bad_cert_file, Tag, BadFile}) + end. + + +get_work_sim(Config) -> + ?DEBUG("get work_sim", []), + case proplists:get_value(work_simulator, Config, ?DEFAULT_WORK_SIM) of + WS when is_integer(WS) andalso (WS > 0) -> + WS; + BadWS -> + exit({bad_work_simulator, BadWS}) + end. + + +get_data_size(Config) -> + ?DEBUG("get data_size", []), + case proplists:get_value(data_size, Config, ?DEFAULT_DATA_SIZE) of + {From, To, Incr} = DS when (is_integer(From) andalso + is_integer(To) andalso + is_integer(Incr) andalso + (To > From) andalso + (From > 0) andalso + (Incr > 0)) -> + DS; + {From, To} when (is_integer(From) andalso + is_integer(To) andalso + (To > From) andalso + (From > 0)) -> + {From, To, ?DEFAULT_DATA_SIZE_INCR}; + BadDS -> + exit({bad_data_size, BadDS}) + end. + + +url(#server{host = Host}, Port, SocketType, WorkSim) -> + Scheme = + case SocketType of + ip_comm -> + "http"; + _ -> %% SSL + "https" + end, + lists:flatten( + io_lib:format("~s://~s:~w/cgi-bin/hdlt_random_html:page?~w:", + [Scheme, Host, Port, WorkSim])). + + +missing_mandatory_config(Missing) -> + exit({missing_mandatory_config, Missing}). + + +ensure_remote_dir_exist(Sftp, Path0) -> + case filename:split(Path0) of + [Root, Dir | Rest] -> + %% We never accept creating the root directory, + %% or the next level, so these *must* exist: + Path = filename:join(Root, Dir), + case ssh_sftp:read_file_info(Sftp, Path) of + {ok, #file_info{type = directory}} -> + ensure_remote_dir_exist(Sftp, Path, Rest); + {ok, #file_info{type = Type}} -> + ?INFO("Not a dir: ~p (~p)", [Path, Type]), + exit({not_a_dir, Path, Type}); + {error, Reason} -> + ?INFO("Failed reading file info for ~p: ~p", + [Path, Reason]), + exit({failed_reading_file_info, Path, Reason}) + end; + BadSplit -> + ?INFO("Bad remote dir path: ~p -> ~p", [Path0, BadSplit]), + exit({bad_dir, Path0}) + end. + +ensure_remote_dir_exist(_Sftp, _Dir, []) -> + ok; +ensure_remote_dir_exist(Sftp, Path, [Dir|Rest]) -> + NewPath = filename:join(Path, Dir), + case ssh_sftp:read_file_info(Sftp, NewPath) of + {ok, #file_info{type = directory}} -> + ensure_remote_dir_exist(Sftp, NewPath, Rest); + {ok, #file_info{type = Type}} -> + %% Exist, but is not a dir + ?INFO("Not a dir: ~p (~p)", [NewPath, Type]), + exit({not_a_dir, NewPath, Type}); + {error, Reason} -> + %% This *could* be because the dir does not exist, + %% but it could also be some other error. + %% As usual, the error reason of the sftp is + %% a pease of crap, so we cannot use the + %% error reason. + %% The simplest way to test this is to simply + %% try to create the directory, since we should + %% ensure its existence anyway.. + case ssh_sftp:make_dir(Sftp, NewPath) of + ok -> + ensure_remote_dir_exist(Sftp, NewPath, Rest); + _ -> + ?INFO("Failed reading file info for ~p: ~p", + [Dir, Reason]), + exit({failed_reading_file_info, NewPath, Reason}) + end + end. + +maybe_create_remote_dir(Sftp, Dir) -> + case ssh_sftp:read_file_info(Sftp, Dir) of + {ok, #file_info{type = directory}} -> + ok; + {ok, #file_info{type = Type}} -> + %% Exist, but is not a dir + ?INFO("Not a dir: ~p (~p)", [Dir, Type]), + exit({not_a_dir, Dir, Type}); + {error, Reason} -> + %% Assume dir noes not exist... + case ssh_sftp:make_dir(Sftp, Dir) of + ok -> + ok; + _ -> + ?INFO("Failed reading file info for ~p: ~p", + [Dir, Reason]), + exit({failed_reading_file_info, Dir, Reason}) + end + end. + + +set_debug_level(Debugs) -> + Debug = proplists:get_value(ctrl, Debugs, silence), + ?SET_LEVEL(Debug). + + +%% Generates a list of numbers between A and B, such that +%% there is exact one number between A and B and then +%% randomizes that list. + +randomized_sizes_init() -> + {A, B, C} = os:timestamp(), + random:seed(A, B, C). + +randomized_sizes(From, To, Incr) -> + L = lists:seq(From, To, Incr), + Len = length(L), + randomized_sizes2(L, 0, Len-1). + +randomized_sizes2(L, N, Len) when N >= Len -> + L; +randomized_sizes2(L, N, Len) -> + SplitWhere = random:uniform(Len), + {A, B} = lists:split(SplitWhere, L), + randomized_sizes2(B ++ A, N+1, Len). diff --git a/lib/inets/examples/httpd_load_test/hdlt_logger.erl b/lib/inets/examples/httpd_load_test/hdlt_logger.erl new file mode 100644 index 0000000000..b0c7eab2d1 --- /dev/null +++ b/lib/inets/examples/httpd_load_test/hdlt_logger.erl @@ -0,0 +1,138 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% +%% +%%---------------------------------------------------------------------- +%% Purpose: This is a simple logger utility for the HDLT toolkit. +%% It assumesd that the debug level and the "name" of the +%% logging entity has been put in process environment +%% (using the set_level and set_name functions respectively). +%%---------------------------------------------------------------------- + +%% + +-module(hdlt_logger). + +-export([ + start/0, + set_level/1, get_level/0, set_name/1, + info/2, log/2, debug/2 + ]). + +-export([logger/1]). + +-define(LOGGER, ?MODULE). +-define(MSG, hdlt_logger_msg). +-define(LEVEL, hdlt_logger_level). +-define(NAME, hdlt_logger_name). +-define(INFO_STR, "INFO"). +-define(LOG_STR, "LOG "). +-define(DEBUG_STR, "DBG "). + + +start() -> + Self = self(), + proc_lib:start(?MODULE, logger, [Self]). + +set_name(Name) when is_list(Name) -> + put(?NAME, Name), + ok. + +get_level() -> + get(?LEVEL). + +set_level(Level) -> + case lists:member(Level, [silence, info, log, debug]) of + true -> + put(?LEVEL, Level), + ok; + false -> + erlang:error({bad_debug_level, Level}) + end. + + +info(F, A) -> +%% io:format("info -> " ++ F ++ "~n", A), + do_log(info, get(?LEVEL), F, A). + +log(F, A) -> +%% io:format("log -> " ++ F ++ "~n", A), + do_log(log, get(?LEVEL), F, A). + +debug(F, A) -> +%% io:format("debug -> " ++ F ++ "~n", A), + do_log(debug, get(?LEVEL), F, A). + + +logger(Parent) -> + global:register_name(?LOGGER, self()), + Ref = erlang:monitor(process, Parent), + proc_lib:init_ack(self()), + logger_loop(Ref). + +logger_loop(Ref) -> + receive + {?MSG, F, A} -> + io:format(F, A), + logger_loop(Ref); + {'DOWN', Ref, process, _Object, _Info} -> + %% start the stop timer + erlang:send_after(timer:seconds(5), self(), stop), + logger_loop(undefined); + stop -> + global:unregister_name(?LOGGER), + ok + end. + + +formated_timestamp() -> + {Date, Time} = erlang:localtime(), + {YYYY,MM,DD} = Date, + {Hour,Min,Sec} = Time, + FormatDate = + io_lib:format("~.4w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w", + [YYYY,MM,DD,Hour,Min,Sec]), + lists:flatten(FormatDate). + +do_log(_, silence, _, _) -> + ok; +do_log(info, info, F, A) -> + do_log(?INFO_STR, F, A); +do_log(info, log, F, A) -> + do_log(?INFO_STR, F, A); +do_log(log, log, F, A) -> + do_log(?LOG_STR, F, A); +do_log(info, debug, F, A) -> + do_log(?INFO_STR, F, A); +do_log(log, debug, F, A) -> + do_log(?LOG_STR, F, A); +do_log(debug, debug, F, A) -> + do_log(?DEBUG_STR, F, A); +do_log(_, _, _F, _A) -> + ok. + +do_log(SEV, F, A) -> + Name = + case get(?NAME) of + L when is_list(L) -> + L; + _ -> + "UNDEFINED" + end, + Msg = {?MSG, "~s ~s [~s] " ++ F ++ "~n", + [SEV, Name, formated_timestamp() | A]}, + (catch global:send(?LOGGER, Msg)). diff --git a/lib/inets/examples/httpd_load_test/hdlt_logger.hrl b/lib/inets/examples/httpd_load_test/hdlt_logger.hrl new file mode 100644 index 0000000000..aa94babc48 --- /dev/null +++ b/lib/inets/examples/httpd_load_test/hdlt_logger.hrl @@ -0,0 +1,33 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% +%% +%% + +-ifndef(hdlt_logger_hrl). +-define(hdlt_logger_hrl, true). + +%% Various log macros +-define(SET_LEVEL(N), hdlt_logger:set_level(N)). +-define(GET_LEVEL(), hdlt_logger:get_level()). +-define(SET_NAME(N), hdlt_logger:set_name(N)). + +-define(INFO(F, A), hdlt_logger:info(F, A)). +-define(LOG(F, A), hdlt_logger:log(F, A)). +-define(DEBUG(F, A), hdlt_logger:debug(F, A)). + +-endif. % -ifdef(hdlt_logger_hrl). diff --git a/lib/inets/examples/httpd_load_test/hdlt_random_html.erl b/lib/inets/examples/httpd_load_test/hdlt_random_html.erl new file mode 100644 index 0000000000..e3a572c61f --- /dev/null +++ b/lib/inets/examples/httpd_load_test/hdlt_random_html.erl @@ -0,0 +1,59 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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(hdlt_random_html). +-export([page/3]). + +page(SessionID, _Env, Input) -> +%% log("page(~p) -> deliver content-type when" +%% "~n SessionID: ~p" +%% "~n Env: ~p" +%% "~n Input: ~p", [self(), SessionID, Env, Input]), + [WorkSimStr, SzSimStr] = string:tokens(Input, [$:]), + WorkSim = list_to_integer(WorkSimStr), + SzSim = list_to_integer(SzSimStr), + mod_esi:deliver(SessionID, "Content-Type:text/html\r\n\r\n"), + mod_esi:deliver(SessionID, start("Random test page")), + mod_esi:deliver(SessionID, content(WorkSim, SzSim)), + mod_esi:deliver(SessionID, stop()), + ok. + +start(Title) -> + "<HTML> +<HEAD> +<TITLE>" ++ Title ++ "</TITLE> + </HEAD> +<BODY>\n". + +stop() -> + "</BODY> +</HTML> +". + +content(WorkSim, SzSim) -> + {A, B, C} = now(), + random:seed(A, B, C), + lists:sort([random:uniform(X) || X <- lists:seq(1, WorkSim)]), + lists:flatten(lists:duplicate(SzSim, "Dummy data ")). + +%% log(F, A) -> +%% hdlt_logger:set_name("HDLT RANDOM-HTML"), +%% hdlt_logger:set_level(debug), +%% hdlt_logger:log(F, A). diff --git a/lib/inets/examples/httpd_load_test/hdlt_server.erl b/lib/inets/examples/httpd_load_test/hdlt_server.erl new file mode 100644 index 0000000000..3e5a849d5b --- /dev/null +++ b/lib/inets/examples/httpd_load_test/hdlt_server.erl @@ -0,0 +1,163 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% +%% +%% +%%---------------------------------------------------------------------- +%% Purpose: The HDLT server module. +%% This is just a stub, making future expansion easy. +%% All code in this module is executed in the local node! +%%---------------------------------------------------------------------- + +-module(hdlt_server). + +-export([start/1, stop/0, start_inets/0, start_service/1]). + +-export([proxy/1]). + +-include_lib("kernel/include/file.hrl"). +-include("hdlt_logger.hrl"). + + +-define(PROXY, hdlt_proxy). + + +%% This function is used to start the proxy process +%% This function is called *after* the nodes has been +%% "connected" with the controller/collector node. + +start(Debug) -> + proc_lib:start(?MODULE, proxy, [Debug]). + +stop() -> + ?PROXY ! stop. + +start_inets() -> + ?PROXY ! start_inets. + +start_service(Config) -> + ?PROXY ! {server_start, Config, self()}, + receive + {server_start_result, Result} -> + Result + after 15000 -> + {error, timeout} + end. + + +proxy(Debug) -> + process_flag(trap_exit, true), + erlang:register(?PROXY, self()), + ?SET_NAME("HDLT PROXY"), + ?SET_LEVEL(Debug), + ?LOG("starting", []), + Ref = await_for_controller(10), + CtrlNode = node(Ref), + erlang:monitor_node(CtrlNode, true), + proc_lib:init_ack({ok, self()}), + ?DEBUG("started", []), + proxy_loop(Ref, CtrlNode). + +await_for_controller(N) when N > 0 -> + case global:whereis_name(hdlt_ctrl) of + Pid when is_pid(Pid) -> + erlang:monitor(process, Pid); + _ -> + timer:sleep(1000), + await_for_controller(N-1) + end; +await_for_controller(_) -> + proc_lib:init_ack({error, controller_not_found, nodes()}), + timer:sleep(500), + halt(). + + +proxy_loop(Ref, CtrlNode) -> + ?DEBUG("await command", []), + receive + stop -> + ?LOG("received stop", []), + halt(); + + start_inets -> + ?LOG("start the inets service framework", []), + case (catch inets:start()) of + ok -> + ?LOG("framework started", []), + proxy_loop(Ref, CtrlNode); + Error -> + ?LOG("failed starting inets service framework: " + "~n Error: ~p", [Error]), + halt() + end; + + {server_start, Config, From} -> + ?LOG("start-server", []), + maybe_start_crypto_and_ssl(Config), + %% inets:enable_trace(max, "/tmp/inets-httpd-trace.log", httpd), + %% inets:enable_trace(max, "/tmp/inets-httpd-trace.log", all), + case (catch inets:start(httpd, Config)) of + {ok, _} -> + ?LOG("server started when" + "~n which(inets): ~p" + "~n RootDir: ~p" + "~n System info: ~p", [code:which(inets), + code:root_dir(), + get_node_info()]), + From ! {server_start_result, ok}, + proxy_loop(Ref, CtrlNode); + Error -> + ?INFO("server start failed" + "~n Error: ~p", [Error]), + From ! {server_start_result, Error}, + halt() + end; + + {nodedown, CtrlNode} -> + ?LOG("received nodedown for controller node - terminate", []), + halt(); + + {'DOWN', Ref, process, _, _} -> + ?LOG("received DOWN message for controller - terminate", []), + %% The controller has terminated, time to die + halt() + + end. + + +maybe_start_crypto_and_ssl(Config) -> + case lists:keysearch(socket_type, 1, Config) of + {value, {socket_type, SocketType}} when ((SocketType =:= ssl) orelse + (SocketType =:= ossl) orelse + (SocketType =:= essl)) -> + ?LOG("maybe start crypto and ssl", []), + (catch crypto:start()), + ssl:start(); + _ -> + ok + end. + + +get_node_info() -> + [{cpu_topology, erlang:system_info(cpu_topology)}, + {heap_type, erlang:system_info(heap_type)}, + {nof_schedulers, erlang:system_info(schedulers)}, + {otp_release, erlang:system_info(otp_release)}, + {version, erlang:system_info(version)}, + {system_version, erlang:system_info(system_version)}, + {system_architecture, erlang:system_info(system_architecture)}]. + diff --git a/lib/inets/examples/httpd_load_test/hdlt_slave.erl b/lib/inets/examples/httpd_load_test/hdlt_slave.erl new file mode 100644 index 0000000000..52af9b5b90 --- /dev/null +++ b/lib/inets/examples/httpd_load_test/hdlt_slave.erl @@ -0,0 +1,291 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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(hdlt_slave). + + +-export([start_link/4, start_link/5, start_link/6, stop/1]). + +%% Internal exports +-export([wait_for_slave/9, slave_start/1, wait_for_master_to_die/3]). + +-include("hdlt_logger.hrl"). + +-define(SSH_PORT, 22). +-define(TIMEOUT, 60000). +-define(LOGGER, hdlt_logger). + + +%% *********************************************************************** +%% start_link/4,5 -- +%% +%% The start/4,5 functions are used to start a slave Erlang node. +%% The node on which the start/N functions are used is called the +%% master in the description below. +%% +%% If hostname is the same for the master and the slave, +%% the Erlang node will simply be spawned. The only requirment for +%% this to work is that the 'erl' program can be found in PATH. +%% +%% If the master and slave are on different hosts, start/N uses +%% the 'rsh' program to spawn an Erlang node on the other host. +%% Alternative, if the master was started as +%% 'erl -sname xxx -rsh my_rsh...', then 'my_rsh' will be used instead +%% of 'rsh' (this is useful for systems where the rsh program is named +%% 'remsh'). +%% +%% For this to work, the following conditions must be fulfilled: +%% +%% 1. There must be an Rsh program on computer; if not an error +%% is returned. +%% +%% 2. The hosts must be configured to allowed 'rsh' access without +%% prompts for password. +%% +%% The slave node will have its filer and user server redirected +%% to the master. When the master node dies, the slave node will +%% terminate. For the start_link functions, the slave node will +%% terminate also if the process which called start_link terminates. +%% +%% Returns: {ok, Name@Host} | +%% {error, timeout} | +%% {error, no_rsh} | +%% {error, {already_running, Name@Host}} + +start_link(Host, Name, ErlPath, Paths) -> + start_link(Host, Name, ErlPath, Paths, [], silence). + +start_link(Host, Name, ErlPath, Paths, DebugLevel) when is_atom(DebugLevel) -> + start_link(Host, Name, ErlPath, Paths, [], DebugLevel); +start_link(Host, Name, ErlPath, Paths, Args) when is_list(Args) -> + start_link(Host, Name, ErlPath, Paths, Args, silence). + +start_link(Host, Name, ErlPath, Paths, Args, DebugLevel) -> + Node = list_to_atom(lists:concat([Name, "@", Host])), + case net_adm:ping(Node) of + pang -> + start_it(Host, Name, Node, ErlPath, Paths, Args, DebugLevel); + pong -> + {error, {already_running, Node}} + end. + +%% Stops a running node. + +stop(Node) -> + rpc:call(Node, erlang, halt, []), + ok. + + +%% Starts a new slave node. + +start_it(Host, Name, Node, ErlPath, Paths, Args, DebugLevel) -> + Prog = filename:join([ErlPath, "erl"]), + spawn(?MODULE, wait_for_slave, [self(), Host, Name, Node, Paths, Args, self(), Prog, DebugLevel]), + receive + {result, Result} -> Result + end. + +%% Waits for the slave to start. + +wait_for_slave(Parent, Host, Name, Node, Paths, Args, + LinkTo, Prog, DebugLevel) -> + ?SET_NAME("HDLT SLAVE STARTER"), + ?SET_LEVEL(DebugLevel), + ?DEBUG("begin", []), + Waiter = register_unique_name(0), + case mk_cmd(Host, Name, Paths, Args, Waiter, Prog) of + {ok, Cmd} -> + ?DEBUG("command generated: ~n~s", [Cmd]), + case (catch ssh_slave_start(Host, Cmd)) of + {ok, Conn, _Chan} -> + ?DEBUG("ssh channel created", []), + receive + {SlavePid, slave_started} -> + ?DEBUG("slave started: ~p", [SlavePid]), + unregister(Waiter), + slave_started(Parent, LinkTo, SlavePid, Conn, + DebugLevel) + after 32000 -> + ?INFO("slave node failed to report in on time", + []), + %% If it seems that the node was partially started, + %% try to kill it. + case net_adm:ping(Node) of + pong -> + spawn(Node, erlang, halt, []), + ok; + _ -> + ok + end, + Parent ! {result, {error, timeout}} + end; + {error, Reason} = Error -> + ?INFO("FAILED starting node: " + "~n ~p" + "~n ~p", [Reason, Cmd]), + Parent ! {result, Error} + end; + Other -> + ?INFO("FAILED creating node command string: " + "~n ~p", [Other]), + Parent ! {result, Other} + end. + + +ssh_slave_start(Host, ErlCmd) -> + ?DEBUG("ssh_slave_start -> try connect to ~p", [Host]), + Connection = + case (catch ssh:connect(Host, ?SSH_PORT, + [{silently_accept_hosts, true}])) of + {ok, Conn} -> + ?DEBUG("ssh_exec_erl -> connected: ~p", [Conn]), + Conn; + Error1 -> + ?LOG("failed connecting to ~p: ~p", [Host, Error1]), + throw({error, {ssh_connect_failed, Error1}}) + end, + + ?DEBUG("ssh_exec_erl -> connected - now create channel", []), + Channel = + case (catch ssh_connection:session_channel(Connection, ?TIMEOUT)) of + {ok, Chan} -> + ?DEBUG("ssh_exec_erl -> channel ~p created", [Chan]), + Chan; + Error2 -> + ?LOG("failed creating channel: ~p", [Error2]), + throw({error, {ssh_channel_create_failed, Error2}}) + end, + + ?DEBUG("ssh_exec_erl -> channel created - now exec command: " + "~n ~p", [ErlCmd]), + case (catch ssh_connection:exec(Connection, Channel, ErlCmd, infinity)) of + success -> + ?DEBUG("ssh_exec_erl -> command exec'ed - clean ssh msg", []), + clean_ssh_msg(), + ?DEBUG("ssh_exec_erl -> done", []), + {ok, Connection, Channel}; + Error3 -> + ?LOG("failed exec comand: ~p", [Error3]), + throw({error, {ssh_exec_failed, Error3}}) + end. + +clean_ssh_msg() -> + receive + {ssh_cm, _X, _Y} -> + clean_ssh_msg() + after 1000 -> + ok + end. + + +slave_started(ReplyTo, Master, Slave, Conn, Level) + when is_pid(Master) andalso is_pid(Slave) -> + process_flag(trap_exit, true), + SName = lists:flatten( + io_lib:format("HDLT SLAVE CTRL[~p,~p]", + [self(), node(Slave)])), + ?SET_NAME(SName), + ?SET_LEVEL(Level), + ?LOG("initiating", []), + MasterRef = erlang:monitor(process, Master), + SlaveRef = erlang:monitor(process, Slave), + ReplyTo ! {result, {ok, node(Slave)}}, + slave_running(Master, MasterRef, Slave, SlaveRef, Conn). + + +%% The slave node will be killed if the master process terminates, +%% The master process will not be killed if the slave node terminates. + +slave_running(Master, MasterRef, Slave, SlaveRef, Conn) -> + ?DEBUG("await message", []), + receive + {'DOWN', MasterRef, process, _Object, _Info} -> + ?LOG("received DOWN from master", []), + erlang:demonitor(SlaveRef, [flush]), + Slave ! {nodedown, node()}, + ssh:close(Conn); + + {'DOWN', SlaveRef, process, Object, _Info} -> + ?LOG("received DOWN from slave (~p)", [Object]), + erlang:demonitor(MasterRef, [flush]), + ssh:close(Conn); + + Other -> + ?DEBUG("received unknown: ~n~p", [Other]), + slave_running(Master, MasterRef, Slave, SlaveRef, Conn) + + end. + +register_unique_name(Number) -> + Name = list_to_atom(lists:concat([?MODULE, "_waiter_", Number])), + case catch register(Name, self()) of + true -> + Name; + {'EXIT', {badarg, _}} -> + register_unique_name(Number+1) + end. + + +%% Makes up the command to start the nodes. +%% If the node should run on the local host, there is +%% no need to use rsh. + +mk_cmd(Host, Name, Paths, Args, Waiter, Prog) -> + PaPaths = [[" -pa ", Path] || Path <- Paths], + {ok, lists:flatten( + lists:concat([Prog, + " -detached -nopinput ", + Args, " ", + " -sname ", Name, "@", Host, + " -s ", ?MODULE, " slave_start ", node(), + " ", Waiter, + " ", PaPaths]))}. + + +%% This function will be invoked on the slave, using the -s option of erl. +%% It will wait for the master node to terminate. + +slave_start([Master, Waiter]) -> + spawn(?MODULE, wait_for_master_to_die, [Master, Waiter, silence]); +slave_start([Master, Waiter, Level]) -> + spawn(?MODULE, wait_for_master_to_die, [Master, Waiter, Level]). + + +wait_for_master_to_die(Master, Waiter, Level) -> + process_flag(trap_exit, true), + SName = lists:flatten( + io_lib:format("HDLT-SLAVE MASTER MONITOR[~p,~p,~p]", + [self(), node(), Master])), + ?SET_NAME(SName), + ?SET_LEVEL(Level), + erlang:monitor_node(Master, true), + {Waiter, Master} ! {self(), slave_started}, + wloop(Master). + +wloop(Master) -> + ?DEBUG("await message", []), + receive + {nodedown, Master} -> + ?INFO("received master nodedown", []), + halt(); + _Other -> + wloop(Master) + end. + + + diff --git a/lib/inets/examples/httpd_load_test/hdlt_ssl_client_cert.pem b/lib/inets/examples/httpd_load_test/hdlt_ssl_client_cert.pem new file mode 120000 index 0000000000..41644a1098 --- /dev/null +++ b/lib/inets/examples/httpd_load_test/hdlt_ssl_client_cert.pem @@ -0,0 +1 @@ +../../test/httpc_SUITE_data/ssl_client_cert.pem
\ No newline at end of file diff --git a/lib/inets/examples/httpd_load_test/hdlt_ssl_server_cert.pem b/lib/inets/examples/httpd_load_test/hdlt_ssl_server_cert.pem new file mode 120000 index 0000000000..41644a1098 --- /dev/null +++ b/lib/inets/examples/httpd_load_test/hdlt_ssl_server_cert.pem @@ -0,0 +1 @@ +../../test/httpc_SUITE_data/ssl_client_cert.pem
\ No newline at end of file diff --git a/lib/inets/examples/httpd_load_test/modules.mk b/lib/inets/examples/httpd_load_test/modules.mk new file mode 100644 index 0000000000..9d0d7103d5 --- /dev/null +++ b/lib/inets/examples/httpd_load_test/modules.mk @@ -0,0 +1,44 @@ +#-*-makefile-*- ; force emacs to enter makefile-mode + +# %CopyrightBegin% +# +# Copyright Ericsson AB 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% + +SCRIPT_SKELETONS = \ + hdlt.sh.skel + +CONF_SKELETONS = \ + hdlt.config.skel + +CERT_FILES = \ + hdlt_ssl_client_cert.pem \ + hdlt_ssl_server_cert.pem + +README = HDLT_README + +MODULES = \ + hdlt \ + hdlt_ctrl \ + hdlt_client \ + hdlt_logger \ + hdlt_random_html \ + hdlt_server \ + hdlt_slave + +INTERNAL_HRL_FILES = \ + hdlt_logger.hrl + + diff --git a/lib/inets/examples/server_root/Makefile b/lib/inets/examples/server_root/Makefile new file mode 100644 index 0000000000..d7a3231068 --- /dev/null +++ b/lib/inets/examples/server_root/Makefile @@ -0,0 +1,209 @@ +# +# %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% +# +# +include $(ERL_TOP)/make/target.mk +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Application version +# ---------------------------------------------------- +include ../../vsn.mk +VSN=$(INETS_VSN) + +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN) + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- +MODULE= + +AUTH_FILES = auth/group \ + auth/passwd +CGI_FILES = cgi-bin/printenv.sh +CONF_FILES = conf/8080.conf \ + conf/8888.conf \ + conf/httpd.conf \ + conf/ssl.conf \ + conf/mime.types +OPEN_FILES = htdocs/open/dummy.html +MNESIA_OPEN_FILES = htdocs/mnesia_open/dummy.html +MISC_FILES = htdocs/misc/friedrich.html \ + htdocs/misc/oech.html +SECRET_FILES = htdocs/secret/dummy.html +MNESIA_SECRET_FILES = htdocs/mnesia_secret/dummy.html +HTDOCS_FILES = htdocs/index.html \ + htdocs/config.shtml \ + htdocs/echo.shtml \ + htdocs/exec.shtml \ + htdocs/flastmod.shtml \ + htdocs/fsize.shtml \ + htdocs/include.shtml +ICON_FILES = icons/README \ + icons/a.gif \ + icons/alert.black.gif \ + icons/alert.red.gif \ + icons/apache_pb.gif \ + icons/back.gif \ + icons/ball.gray.gif \ + icons/ball.red.gif \ + icons/binary.gif \ + icons/binhex.gif \ + icons/blank.gif \ + icons/bomb.gif \ + icons/box1.gif \ + icons/box2.gif \ + icons/broken.gif \ + icons/burst.gif \ + icons/button1.gif \ + icons/button10.gif \ + icons/button2.gif \ + icons/button3.gif \ + icons/button4.gif \ + icons/button5.gif \ + icons/button6.gif \ + icons/button7.gif \ + icons/button8.gif \ + icons/button9.gif \ + icons/buttonl.gif \ + icons/buttonr.gif \ + icons/c.gif \ + icons/comp.blue.gif \ + icons/comp.gray.gif \ + icons/compressed.gif \ + icons/continued.gif \ + icons/dir.gif \ + icons/down.gif \ + icons/dvi.gif \ + icons/f.gif \ + icons/folder.gif \ + icons/folder.open.gif \ + icons/folder.sec.gif \ + icons/forward.gif \ + icons/generic.gif \ + icons/generic.red.gif \ + icons/generic.sec.gif \ + icons/hand.right.gif \ + icons/hand.up.gif \ + icons/htdig.gif \ + icons/icon.sheet.gif \ + icons/image1.gif \ + icons/image2.gif \ + icons/image3.gif \ + icons/index.gif \ + icons/layout.gif \ + icons/left.gif \ + icons/link.gif \ + icons/movie.gif \ + icons/p.gif \ + icons/patch.gif \ + icons/pdf.gif \ + icons/pie0.gif \ + icons/pie1.gif \ + icons/pie2.gif \ + icons/pie3.gif \ + icons/pie4.gif \ + icons/pie5.gif \ + icons/pie6.gif \ + icons/pie7.gif \ + icons/pie8.gif \ + icons/portal.gif \ + icons/poweredby.gif \ + icons/ps.gif \ + icons/quill.gif \ + icons/right.gif \ + icons/screw1.gif \ + icons/screw2.gif \ + icons/script.gif \ + icons/sound1.gif \ + icons/sound2.gif \ + icons/sphere1.gif \ + icons/sphere2.gif \ + icons/star.gif \ + icons/star_blank.gif \ + icons/tar.gif \ + icons/tex.gif \ + icons/text.gif \ + icons/transfer.gif \ + icons/unknown.gif \ + icons/up.gif \ + icons/uu.gif \ + icons/uuencoded.gif \ + icons/world1.gif \ + icons/world2.gif + +SSL_FILES = ssl/ssl_client.pem \ + ssl/ssl_server.pem + +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +ERL_COMPILE_FLAGS += + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- + +debug opt: + +clean: + +docs: + +# ---------------------------------------------------- +# Release Target +# ---------------------------------------------------- +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: opt + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/auth + $(INSTALL_DATA) $(AUTH_FILES) $(RELSYSDIR)/examples/server_root/auth + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/cgi-bin + $(INSTALL_SCRIPT) $(CGI_FILES) $(RELSYSDIR)/examples/server_root/cgi-bin + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/conf + $(INSTALL_DATA) $(CONF_FILES) $(RELSYSDIR)/examples/server_root/conf + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/htdocs/open + $(INSTALL_DATA) $(OPEN_FILES) \ + $(RELSYSDIR)/examples/server_root/htdocs/open + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/htdocs/mnesia_open + $(INSTALL_DATA) $(MNESIA_OPEN_FILES) \ + $(RELSYSDIR)/examples/server_root/htdocs/mnesia_open + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/htdocs/misc + $(INSTALL_DATA) $(MISC_FILES) \ + $(RELSYSDIR)/examples/server_root/htdocs/misc + $(INSTALL_DIR) \ + $(RELSYSDIR)/examples/server_root/htdocs/secret/top_secret + $(INSTALL_DIR) \ + $(RELSYSDIR)/examples/server_root/htdocs/mnesia_secret/top_secret + $(INSTALL_DATA) $(SECRET_FILES) \ + $(RELSYSDIR)/examples/server_root/htdocs/secret + $(INSTALL_DATA) $(MNESIA_SECRET_FILES) \ + $(RELSYSDIR)/examples/server_root/htdocs/mnesia_secret + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/htdocs + $(INSTALL_DATA) $(HTDOCS_FILES) $(RELSYSDIR)/examples/server_root/htdocs + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/icons + $(INSTALL_DATA) $(ICON_FILES) $(RELSYSDIR)/examples/server_root/icons + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/ssl + $(INSTALL_DATA) $(SSL_FILES) $(RELSYSDIR)/examples/server_root/ssl + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/logs + +release_docs_spec: + diff --git a/lib/inets/examples/subdirs.mk b/lib/inets/examples/subdirs.mk new file mode 100644 index 0000000000..10a331fc26 --- /dev/null +++ b/lib/inets/examples/subdirs.mk @@ -0,0 +1,3 @@ +#-*-makefile-*- ; force emacs to enter makefile-mode + +SUB_DIRECTORIES = server_root httpd_load_test
\ No newline at end of file diff --git a/lib/inets/src/ftp/Makefile b/lib/inets/src/ftp/Makefile index 0c15277a18..19b93870df 100644 --- a/lib/inets/src/ftp/Makefile +++ b/lib/inets/src/ftp/Makefile @@ -22,6 +22,7 @@ include $(ERL_TOP)/make/target.mk EBIN = ../../ebin include $(ERL_TOP)/make/$(TARGET)/otp.mk + # ---------------------------------------------------- # Application version # ---------------------------------------------------- @@ -29,6 +30,7 @@ include ../../vsn.mk VSN = $(INETS_VSN) + # ---------------------------------------------------- # Release directory specification # ---------------------------------------------------- @@ -52,24 +54,21 @@ TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) # ---------------------------------------------------- -# INETS FLAGS +# FLAGS # ---------------------------------------------------- -INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"' + +include ../inets_app/inets.mk ifeq ($(FTP_DEBUG),true) INETS_FLAGS += -Dftp_debug endif +ERL_COMPILE_FLAGS += \ + $(INETS_FLAGS) \ + $(INETS_ERL_COMPILE_FLAGS) \ + -I../../include \ + -I../inets_app -# ---------------------------------------------------- -# FLAGS -# ---------------------------------------------------- -INETS_ERL_FLAGS += -I ../inets_app -pa ../../ebin - -ERL_COMPILE_FLAGS += $(INETS_ERL_FLAGS) \ - $(INETS_FLAGS) \ - +'{parse_transform,sys_pre_attributes}' \ - +'{attribute,insert,app_vsn,$(APP_VSN)}' # ---------------------------------------------------- # Targets @@ -89,9 +88,10 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin + $(INSTALL_DIR) $(RELSYSDIR)/src + $(INSTALL_DIR) $(RELSYSDIR)/src/ftp + $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src/ftp + $(INSTALL_DIR) $(RELSYSDIR)/ebin $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin release_docs_spec: diff --git a/lib/inets/src/ftp/ftp.erl b/lib/inets/src/ftp/ftp.erl index 534fcae675..5ad74851c8 100644 --- a/lib/inets/src/ftp/ftp.erl +++ b/lib/inets/src/ftp/ftp.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% %% %% @@ -25,14 +25,12 @@ -behaviour(gen_server). -behaviour(inets_service). --deprecated({open, 3, next_major_release}). --deprecated({force_active, 1, next_major_release}). %% API - Client interface -export([cd/2, close/1, delete/2, formaterror/1, lcd/2, lpwd/1, ls/1, ls/2, mkdir/2, nlist/1, nlist/2, - open/1, open/2, open/3, force_active/1, + open/1, open/2, pwd/1, quote/2, recv/2, recv/3, recv_bin/2, recv_chunk_start/2, recv_chunk/1, @@ -133,11 +131,6 @@ open(Host, Port) when is_integer(Port) -> open(Host, [{port, Port}]); %% </BACKWARD-COMPATIBILLITY> -%% <BACKWARD-COMPATIBILLITY> -open(Host, [H|_] = Flags) when is_atom(H) -> - open(Host, ?FTP_PORT, Flags); -%% </BACKWARD-COMPATIBILLITY> - open(Host, Opts) when is_list(Opts) -> ?fcrt("open", [{host, Host}, {opts, Opts}]), try @@ -160,32 +153,6 @@ open(Host, Opts) when is_list(Opts) -> end. -%% <BACKWARD-COMPATIBILLITY> -open(Host, Port, Flags) when is_integer(Port) andalso is_list(Flags) -> - ?fcrt("open", [{host, Host}, {port, Port}, {flags, Flags}]), - try - {ok, StartOptions} = start_options([{flags, Flags}]), - ?fcrt("open", [{start_options, StartOptions}]), - {ok, OpenOptions} = open_options([{host, Host}, {port, Port}|Flags]), - ?fcrt("open", [{open_options, OpenOptions}]), - case ftp_sup:start_child([[{client, self()} | StartOptions], []]) of - {ok, Pid} -> - ?fcrt("open - ok", [{pid, Pid}]), - call(Pid, {open, ip_comm, OpenOptions}, plain); - Error1 -> - ?fcrt("open - error", [{error1, Error1}]), - Error1 - end - catch - throw:Error2 -> - Error2 - end. -%% </BACKWARD-COMPATIBILLITY> - - - - - %%-------------------------------------------------------------------------- %% user(Pid, User, Pass, <Acc>) -> ok | {error, euser} | {error, econn} %% | {error, eacct} @@ -528,16 +495,6 @@ close(Pid) -> cast(Pid, close), ok. -%%-------------------------------------------------------------------------- -%% force_active(Pid) -> ok -%% Pid = pid() -%% -%% Description: Force connection to use active mode. -%%-------------------------------------------------------------------------- -force_active(Pid) -> - error_logger:info_report("This function is deprecated use the mode flag " - "instead"), - call(Pid, force_active, atom). %%-------------------------------------------------------------------------- %% formaterror(Tag) -> string() @@ -886,9 +843,6 @@ handle_call({_, {open, ip_comm, Host, Opts}}, From, State) -> {stop, normal, State2#state{client = undefined}} end; -handle_call({_, force_active}, _, State) -> - {reply, ok, State#state{mode = active}}; - handle_call({_, {user, User, Password}}, From, #state{csock = CSock} = State) when (CSock =/= undefined) -> handle_user(User, Password, "", State#state{client = From}); diff --git a/lib/inets/src/ftp/ftp_internal.hrl b/lib/inets/src/ftp/ftp_internal.hrl index c3fa1e611d..148f8217ba 100644 --- a/lib/inets/src/ftp/ftp_internal.hrl +++ b/lib/inets/src/ftp/ftp_internal.hrl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% @@ -21,7 +21,8 @@ -ifndef(ftp_internal_hrl). -define(ftp_internal_hrl, true). --include("inets_internal.hrl"). +-include_lib("inets/src/inets_app/inets_internal.hrl"). + -define(SERVICE, ftpc). -define(fcri(Label, Content), ?report_important(Label, ?SERVICE, Content)). -define(fcrv(Label, Content), ?report_verbose(Label, ?SERVICE, Content)). diff --git a/lib/inets/src/http_client/Makefile b/lib/inets/src/http_client/Makefile index 628c91421f..575c6efaec 100644 --- a/lib/inets/src/http_client/Makefile +++ b/lib/inets/src/http_client/Makefile @@ -61,20 +61,17 @@ TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) # ---------------------------------------------------- -# INETS FLAGS -# ---------------------------------------------------- -INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"' - - -# ---------------------------------------------------- # FLAGS # ---------------------------------------------------- -INETS_ERL_FLAGS += -I ../http_lib -I ../inets_app -pa ../../ebin -ERL_COMPILE_FLAGS += $(INETS_ERL_FLAGS) \ - $(INETS_FLAGS) \ - +'{parse_transform,sys_pre_attributes}' \ - +'{attribute,insert,app_vsn,$(APP_VSN)}' +include ../inets_app/inets.mk + +ERL_COMPILE_FLAGS += \ + $(INETS_FLAGS) \ + $(INETS_ERL_COMPILE_FLAGS) \ + -I../../include \ + -I../inets_app \ + -I../http_lib # ---------------------------------------------------- @@ -94,9 +91,10 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin + $(INSTALL_DIR) $(RELSYSDIR)/src + $(INSTALL_DIR) $(RELSYSDIR)/src/http_client + $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src/http_client + $(INSTALL_DIR) $(RELSYSDIR)/ebin $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin release_docs_spec: diff --git a/lib/inets/src/http_client/http.erl b/lib/inets/src/http_client/http.erl index 7e1e90b50e..bbe2fec267 100644 --- a/lib/inets/src/http_client/http.erl +++ b/lib/inets/src/http_client/http.erl @@ -18,21 +18,38 @@ %% %% -%% Description: -%%% This version of the HTTP/1.1 client supports: -%%% - RFC 2616 HTTP 1.1 client part -%%% - RFC 2818 HTTP Over TLS +%%% Description: OLD API MODULE - USE httpc INSTEAD -module(http). -%% API --export([request/1, request/2, request/4, request/5, +-deprecated({request, 1, next_major_release}). +-deprecated({request, 2, next_major_release}). +-deprecated({request, 4, next_major_release}). +-deprecated({request, 5, next_major_release}). +-deprecated({cancel_request, 1, next_major_release}). +-deprecated({cancel_request, 2, next_major_release}). +-deprecated({set_option, 2, next_major_release}). +-deprecated({set_option, 3, next_major_release}). +-deprecated({set_options, 1, next_major_release}). +-deprecated({set_options, 2, next_major_release}). +-deprecated({verify_cookies, 2, next_major_release}). +-deprecated({verify_cookies, 3, next_major_release}). +-deprecated({cookie_header, 1, next_major_release}). +-deprecated({cookie_header, 2, next_major_release}). +-deprecated({stream_next, 1, next_major_release}). +-deprecated({default_profile, 0, next_major_release}). + +%% Deprecated +-export([ + request/1, request/2, request/4, request/5, cancel_request/1, cancel_request/2, set_option/2, set_option/3, set_options/1, set_options/2, - verify_cookies/2, verify_cookies/3, cookie_header/1, - cookie_header/2, stream_next/1, - default_profile/0]). + verify_cookies/2, verify_cookies/3, + cookie_header/1, cookie_header/2, + stream_next/1, + default_profile/0 + ]). %%%========================================================================= diff --git a/lib/inets/src/http_client/httpc.erl b/lib/inets/src/http_client/httpc.erl index 6deeab6948..851364001c 100644 --- a/lib/inets/src/http_client/httpc.erl +++ b/lib/inets/src/http_client/httpc.erl @@ -48,7 +48,7 @@ stop_service/1, services/0, service_info/1]). --include("http_internal.hrl"). +-include_lib("inets/src/http_lib/http_internal.hrl"). -include("httpc_internal.hrl"). -define(DEFAULT_PROFILE, default). @@ -104,8 +104,14 @@ request(Url, Profile) -> %% HTTPOptions - [HttpOption] %% HTTPOption - {timeout, Time} | {connect_timeout, Time} | %% {ssl, SSLOptions} | {proxy_auth, {User, Password}} -%% Ssloptions = [SSLOption] -%% SSLOption = {verify, code()} | {depth, depth()} | {certfile, path()} | +%% Ssloptions = ssl_options() | +%% {ssl, ssl_options()} | +%% {ossl, ssl_options()} | +%% {essl, ssl_options()} +%% ssl_options() = [ssl_option()] +%% ssl_option() = {verify, code()} | +%% {depth, depth()} | +%% {certfile, path()} | %% {keyfile, path()} | {password, string()} | {cacertfile, path()} | %% {ciphers, string()} %% Options - [Option] @@ -579,7 +585,13 @@ http_options_default() -> error end, SslPost = fun(Value) when is_list(Value) -> - {ok, Value}; + {ok, {?HTTP_DEFAULT_SSL_KIND, Value}}; + ({ssl, SslOptions}) when is_list(SslOptions) -> + {ok, {?HTTP_DEFAULT_SSL_KIND, SslOptions}}; + ({ossl, SslOptions}) when is_list(SslOptions) -> + {ok, {ossl, SslOptions}}; + ({essl, SslOptions}) when is_list(SslOptions) -> + {ok, {essl, SslOptions}}; (_) -> error end, @@ -604,14 +616,14 @@ http_options_default() -> error end, [ - {version, {value, "HTTP/1.1"}, #http_options.version, VersionPost}, - {timeout, {value, ?HTTP_REQUEST_TIMEOUT}, #http_options.timeout, TimeoutPost}, - {autoredirect, {value, true}, #http_options.autoredirect, AutoRedirectPost}, - {ssl, {value, []}, #http_options.ssl, SslPost}, - {proxy_auth, {value, undefined}, #http_options.proxy_auth, ProxyAuthPost}, - {relaxed, {value, false}, #http_options.relaxed, RelaxedPost}, - %% this field has to be *after* the timeout field (as that field is used for the default value) - {connect_timeout, {field, #http_options.timeout}, #http_options.connect_timeout, ConnTimeoutPost} + {version, {value, "HTTP/1.1"}, #http_options.version, VersionPost}, + {timeout, {value, ?HTTP_REQUEST_TIMEOUT}, #http_options.timeout, TimeoutPost}, + {autoredirect, {value, true}, #http_options.autoredirect, AutoRedirectPost}, + {ssl, {value, {?HTTP_DEFAULT_SSL_KIND, []}}, #http_options.ssl, SslPost}, + {proxy_auth, {value, undefined}, #http_options.proxy_auth, ProxyAuthPost}, + {relaxed, {value, false}, #http_options.relaxed, RelaxedPost}, + %% this field has to be *after* the timeout option (as that field is used for the default value) + {connect_timeout, {field, #http_options.timeout}, #http_options.connect_timeout, ConnTimeoutPost} ]. diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl index db5ff3036a..8af6613fa2 100644 --- a/lib/inets/src/http_client/httpc_handler.erl +++ b/lib/inets/src/http_client/httpc_handler.erl @@ -22,8 +22,8 @@ -behaviour(gen_server). +-include_lib("inets/src/http_lib/http_internal.hrl"). -include("httpc_internal.hrl"). --include("http_internal.hrl"). %%-------------------------------------------------------------------- @@ -177,8 +177,8 @@ stream(BodyPart, Request = #request{stream = Self}, Code) stream(BodyPart, Request = #request{stream = Self}, 404) when (Self =:= self) orelse (Self =:= {self, once}) -> ?hcrt("stream - self with 404", [{stream, Self}]), - httpc_response:send(Request#request.from, - {Request#request.id, stream, BodyPart}), + httpc_response:send(Request#request.from, + {Request#request.id, stream, BodyPart}), {<<>>, Request}; %% Stream to file @@ -286,8 +286,7 @@ handle_call({connect_and_send, #request{address = Address0, handle_call(#request{address = Addr} = Request, _, #state{status = Status, - session = #tcp_session{socket = Socket, - type = pipeline} = Session, + session = #session{type = pipeline} = Session, timers = Timers, options = #options{proxy = Proxy} = _Options, profile_name = ProfileName} = State) @@ -301,7 +300,7 @@ handle_call(#request{address = Addr} = Request, _, Address = handle_proxy(Addr, Proxy), - case httpc_request:send(Address, Request, Socket) of + case httpc_request:send(Address, Session, Request) of ok -> ?hcrd("request sent", []), @@ -320,10 +319,10 @@ handle_call(#request{address = Addr} = Request, _, NewTimers = NewState#state.timers, NewPipeline = queue:in(Request, State#state.pipeline), NewSession = - Session#tcp_session{queue_length = - %% Queue + current - queue:len(NewPipeline) + 1, - client_close = ClientClose}, + Session#session{queue_length = + %% Queue + current + queue:len(NewPipeline) + 1, + client_close = ClientClose}, httpc_manager:insert_session(NewSession, ProfileName), ?hcrd("session updated", []), {reply, ok, State#state{pipeline = NewPipeline, @@ -336,8 +335,8 @@ handle_call(#request{address = Addr} = Request, _, cancel_timer(Timers#timers.queue_timer, timeout_queue), NewSession = - Session#tcp_session{queue_length = 1, - client_close = ClientClose}, + Session#session{queue_length = 1, + client_close = ClientClose}, httpc_manager:insert_session(NewSession, ProfileName), Relaxed = (Request#request.settings)#http_options.relaxed, @@ -357,8 +356,7 @@ handle_call(#request{address = Addr} = Request, _, handle_call(#request{address = Addr} = Request, _, #state{status = Status, - session = #tcp_session{socket = Socket, - type = keep_alive} = Session, + session = #session{type = keep_alive} = Session, timers = Timers, options = #options{proxy = Proxy} = _Options, profile_name = ProfileName} = State) @@ -370,7 +368,7 @@ handle_call(#request{address = Addr} = Request, _, {status, Status}]), Address = handle_proxy(Addr, Proxy), - case httpc_request:send(Address, Request, Socket) of + case httpc_request:send(Address, Session, Request) of ok -> ?hcrd("request sent", []), @@ -389,10 +387,10 @@ handle_call(#request{address = Addr} = Request, _, NewTimers = NewState#state.timers, NewKeepAlive = queue:in(Request, State#state.keep_alive), NewSession = - Session#tcp_session{queue_length = - %% Queue + current - queue:len(NewKeepAlive) + 1, - client_close = ClientClose}, + Session#session{queue_length = + %% Queue + current + queue:len(NewKeepAlive) + 1, + client_close = ClientClose}, httpc_manager:insert_session(NewSession, ProfileName), ?hcrd("session updated", []), {reply, ok, State#state{keep_alive = NewKeepAlive, @@ -405,8 +403,8 @@ handle_call(#request{address = Addr} = Request, _, cancel_timer(Timers#timers.queue_timer, timeout_queue), NewSession = - Session#tcp_session{queue_length = 1, - client_close = ClientClose}, + Session#session{queue_length = 1, + client_close = ClientClose}, httpc_manager:insert_session(NewSession, ProfileName), Relaxed = (Request#request.settings)#http_options.relaxed, @@ -589,13 +587,13 @@ handle_info({ssl_closed, _}, State = #state{request = undefined}) -> %%% Error cases handle_info({tcp_closed, _}, #state{session = Session0} = State) -> - Socket = Session0#tcp_session.socket, - Session = Session0#tcp_session{socket = {remote_close, Socket}}, + Socket = Session0#session.socket, + Session = Session0#session{socket = {remote_close, Socket}}, %% {stop, session_remotly_closed, State}; {stop, normal, State#state{session = Session}}; handle_info({ssl_closed, _}, #state{session = Session0} = State) -> - Socket = Session0#tcp_session.socket, - Session = Session0#tcp_session{socket = {remote_close, Socket}}, + Socket = Session0#session.socket, + Session = Session0#session{socket = {remote_close, Socket}}, %% {stop, session_remotly_closed, State}; {stop, normal, State#state{session = Session}}; handle_info({tcp_error, _, _} = Reason, State) -> @@ -704,19 +702,18 @@ terminate(normal, #state{session = undefined}) -> %% Init error sending, no session information has been setup but %% there is a socket that needs closing. terminate(normal, - #state{request = Request, - session = #tcp_session{id = undefined, - socket = Socket}}) -> - http_transport:close(socket_type(Request), Socket); + #state{session = #session{id = undefined} = Session}) -> + close_socket(Session); %% Socket closed remotely terminate(normal, - #state{session = #tcp_session{socket = {remote_close, Socket}, - id = Id}, + #state{session = #session{socket = {remote_close, Socket}, + socket_type = SocketType, + id = Id}, profile_name = ProfileName, - request = Request, - timers = Timers, - pipeline = Pipeline}) -> + request = Request, + timers = Timers, + pipeline = Pipeline}) -> ?hcrt("terminate(normal) - remote close", [{id, Id}, {profile, ProfileName}]), @@ -733,11 +730,11 @@ terminate(normal, deliver_answers([Request | queue:to_list(Pipeline)]), %% And, just in case, close our side (**really** overkill) - http_transport:close(socket_type(Request), Socket); + http_transport:close(SocketType, Socket); -terminate(_, #state{session = #tcp_session{id = Id, - socket = Socket, - scheme = Scheme}, +terminate(_, #state{session = #session{id = Id, + socket = Socket, + socket_type = SocketType}, request = undefined, profile_name = ProfileName, timers = Timers, @@ -749,7 +746,7 @@ terminate(_, #state{session = #tcp_session{id = Id, maybe_retry_queue(KeepAlive, State), cancel_timer(Timers#timers.queue_timer, timeout_queue), - http_transport:close(socket_type(Scheme), Socket); + http_transport:close(SocketType, Socket); terminate(Reason, #state{request = undefined}) -> ?hcrt("terminate", [{reason, Reason}]), @@ -883,22 +880,23 @@ connect_and_send_first_request(Address, ConnTimeout = Settings#http_options.connect_timeout, case connect(SocketType, Address, Options, ConnTimeout) of {ok, Socket} -> + Session = #session{id = {OrigAddress, self()}, + scheme = Scheme, + socket = Socket, + socket_type = SocketType}, ?hcrd("connected - now send first request", [{socket, Socket}]), - case httpc_request:send(Address, Request, Socket) of + case httpc_request:send(Address, Session, Request) of ok -> ?hcrd("first request sent", []), ClientClose = httpc_request:is_client_closing(Headers), SessionType = httpc_manager:session_type(Options), - Session = - #tcp_session{id = {OrigAddress, self()}, - scheme = Scheme, - socket = Socket, - client_close = ClientClose, - type = SessionType}, + Session2 = + Session#session{client_close = ClientClose, + type = SessionType}, TmpState = State#state{request = Request, - session = Session, + session = Session2, mfa = init_mfa(Request, State), status_line = init_status_line(Request), headers = undefined, @@ -952,21 +950,20 @@ handler_info(#state{request = Request, ?hcrt("handler info", [{request_info, RequestInfo}]), %% Info about the current session/socket - SessionType = Session#tcp_session.type, - QueueLen = case Session#tcp_session.type of + SessionType = Session#session.type, + QueueLen = case SessionType of pipeline -> queue:len(Pipeline); keep_alive -> queue:len(KeepAlive) end, - Socket = Session#tcp_session.socket, - Scheme = Session#tcp_session.scheme, - SocketType = socket_type(Scheme), + Scheme = Session#session.scheme, + Socket = Session#session.socket, + SocketType = Session#session.socket_type, ?hcrt("handler info", [{session_type, SessionType}, {queue_length, QueueLen}, {scheme, Scheme}, - {socket_type, SocketType}, {socket, Socket}]), SocketOpts = http_transport:getopts(SocketType, Socket), @@ -1123,9 +1120,7 @@ handle_response(#state{request = Request, ?hcrd("handle response - continue", []), %% Send request body {_, RequestBody} = Request#request.content, - http_transport:send(socket_type(Session#tcp_session.scheme), - Session#tcp_session.socket, - RequestBody), + send_raw(Session, RequestBody), %% Wait for next response activate_once(Session), Relaxed = (Request#request.settings)#http_options.relaxed, @@ -1222,7 +1217,7 @@ handle_pipeline(#state{status = pipeline, %% If a pipeline that has been idle for some time is not %% closed by the server, the client may want to close it. NewState = activate_queue_timeout(TimeOut, State), - NewSession = Session#tcp_session{queue_length = 0}, + NewSession = Session#session{queue_length = 0}, httpc_manager:insert_session(NewSession, ProfileName), %% Note mfa will be initilized when a new request %% arrives. @@ -1244,9 +1239,9 @@ handle_pipeline(#state{status = pipeline, false -> ?hcrv("next request", [{request, NextRequest}]), NewSession = - Session#tcp_session{queue_length = - %% Queue + current - queue:len(Pipeline) + 1}, + Session#session{queue_length = + %% Queue + current + queue:len(Pipeline) + 1}, httpc_manager:insert_session(NewSession, ProfileName), Relaxed = (NextRequest#request.settings)#http_options.relaxed, @@ -1295,16 +1290,16 @@ handle_keep_alive_queue( %% If a keep_alive session has been idle for some time is not %% closed by the server, the client may want to close it. NewState = activate_queue_timeout(TimeOut, State), - NewSession = Session#tcp_session{queue_length = 0}, + NewSession = Session#session{queue_length = 0}, httpc_manager:insert_session(NewSession, ProfileName), %% Note mfa will be initilized when a new request %% arrives. {noreply, - NewState#state{request = undefined, - mfa = undefined, + NewState#state{request = undefined, + mfa = undefined, status_line = undefined, - headers = undefined, - body = undefined + headers = undefined, + body = undefined } }; {{value, NextRequest}, KeepAlive} -> @@ -1347,10 +1342,12 @@ case_insensitive_header(Str) when is_list(Str) -> case_insensitive_header(Str) -> Str. -activate_once(#tcp_session{scheme = Scheme, socket = Socket}) -> - SocketType = socket_type(Scheme), +activate_once(#session{socket = Socket, socket_type = SocketType}) -> http_transport:setopts(SocketType, Socket, [{active, once}]). +close_socket(#session{socket = Socket, socket_type = SocketType}) -> + http_transport:close(SocketType, Socket). + activate_request_timeout( #state{request = #request{timer = undefined} = Request} = State) -> Timeout = (Request#request.settings)#http_options.timeout, @@ -1383,7 +1380,7 @@ activate_queue_timeout(Time, State) -> State#state{timers = #timers{queue_timer = Ref}}. -is_pipeline_enabled_client(#tcp_session{type = pipeline}) -> +is_pipeline_enabled_client(#session{type = pipeline}) -> true; is_pipeline_enabled_client(_) -> false. @@ -1396,7 +1393,7 @@ is_keep_alive_enabled_server("HTTP/1.0", is_keep_alive_enabled_server(_,_) -> false. -is_keep_alive_connection(Headers, #tcp_session{client_close = ClientClose}) -> +is_keep_alive_connection(Headers, #session{client_close = ClientClose}) -> (not ((ClientClose) orelse httpc_response:is_server_closing(Headers))). try_to_enable_pipeline_or_keep_alive( @@ -1421,7 +1418,7 @@ try_to_enable_pipeline_or_keep_alive( httpc_manager:insert_session(Session, ProfileName), %% Make sure type is keep_alive in session %% as it in this case might be pipeline - NewSession = Session#tcp_session{type = keep_alive}, + NewSession = Session#session{type = keep_alive}, State#state{status = keep_alive, session = NewSession} end; @@ -1556,11 +1553,11 @@ init_status_line(#request{settings = Settings}) -> socket_type(#request{scheme = http}) -> ip_comm; socket_type(#request{scheme = https, settings = Settings}) -> - {ssl, Settings#http_options.ssl}; -socket_type(http) -> - ip_comm; -socket_type(https) -> - {ssl, []}. %% Dummy value ok for ex setopts that does not use this value + Settings#http_options.ssl. +%% socket_type(http) -> +%% ip_comm; +%% socket_type(https) -> +%% {ssl1, []}. %% Dummy value ok for ex setopts that does not use this value start_stream({_Version, _Code, _ReasonPhrase}, _Headers, #request{stream = none} = Request) -> @@ -1629,18 +1626,15 @@ end_stream(SL, R) -> next_body_chunk(#state{request = #request{stream = {self, once}}, - once = once, session = Session} = State) -> - http_transport:setopts(socket_type(Session#tcp_session.scheme), - Session#tcp_session.socket, - [{active, once}]), + once = once, + session = Session} = State) -> + activate_once(Session), State#state{once = inactive}; next_body_chunk(#state{request = #request{stream = {self, once}}, once = inactive} = State) -> State; %% Wait for user to call stream_next next_body_chunk(#state{session = Session} = State) -> - http_transport:setopts(socket_type(Session#tcp_session.scheme), - Session#tcp_session.socket, - [{active, once}]), + activate_once(Session), State. handle_verbose(verbose) -> @@ -1717,6 +1711,11 @@ handle_verbose(_) -> %% ok. +send_raw(#session{socket = Socket, socket_type = SocketType}, Body) -> + http_transport:send(SocketType, Socket, Body). + + + call(Msg, Pid) -> Timeout = infinity, call(Msg, Pid, Timeout). diff --git a/lib/inets/src/http_client/httpc_internal.hrl b/lib/inets/src/http_client/httpc_internal.hrl index 4d76c4beb3..3cdd95a02b 100644 --- a/lib/inets/src/http_client/httpc_internal.hrl +++ b/lib/inets/src/http_client/httpc_internal.hrl @@ -18,7 +18,11 @@ %% %% --include("inets_internal.hrl"). +-ifndef(httpc_internal_hrl). +-define(httpc_internal_hrl, true). + +-include_lib("inets/src/inets_app/inets_internal.hrl"). + -define(SERVICE, httpc). -define(hcri(Label, Data), ?report_important(Label, ?SERVICE, Data)). -define(hcrv(Label, Data), ?report_verbose(Label, ?SERVICE, Data)). @@ -104,13 +108,14 @@ } ). --record(tcp_session, +-record(session, { id, % {{Host, Port}, HandlerPid} client_close, % true | false scheme, % http (HTTP/TCP) | https (HTTP/SSL/TCP) socket, % Open socket, used by connection - queue_length = 1, % Current length of pipeline or keep alive queue + socket_type, % socket-type, used by connection + queue_length = 1, % Current length of pipeline or keep-alive queue type % pipeline | keep_alive (wait for response before sending new request) }). @@ -138,3 +143,6 @@ %% path, % string() %% q % query: string() %% }). + + +-endif. % -ifdef(httpc_internal_hrl). diff --git a/lib/inets/src/http_client/httpc_manager.erl b/lib/inets/src/http_client/httpc_manager.erl index 4738517210..1e1bde220b 100644 --- a/lib/inets/src/http_client/httpc_manager.erl +++ b/lib/inets/src/http_client/httpc_manager.erl @@ -21,8 +21,8 @@ -behaviour(gen_server). +-include_lib("inets/src/http_lib/http_internal.hrl"). -include("httpc_internal.hrl"). --include("http_internal.hrl"). %% Internal Application API -export([ @@ -324,7 +324,7 @@ do_init(ProfileName, CookiesDir) -> ?hcrt("create session db", []), SessionDbName = session_db_name(ProfileName), ets:new(SessionDbName, - [public, set, named_table, {keypos, #tcp_session.id}]), + [public, set, named_table, {keypos, #session.id}]), %% Create handler db ?hcrt("create handler/request db", []), @@ -882,12 +882,12 @@ select_session(Method, HostPort, Scheme, SessionType, %% client_close, scheme and type specified. %% The fields id (part of: HandlerPid) and queue_length %% specified. - Pattern = #tcp_session{id = {HostPort, '$1'}, - client_close = false, - scheme = Scheme, - socket = '_', - queue_length = '$2', - type = SessionType}, + Pattern = #session{id = {HostPort, '$1'}, + client_close = false, + scheme = Scheme, + queue_length = '$2', + type = SessionType, + _ = '_'}, %% {'_', {HostPort, '$1'}, false, Scheme, '_', '$2', SessionTyp}, Candidates = ets:match(SessionDb, Pattern), ?hcrd("select session", [{host_port, HostPort}, diff --git a/lib/inets/src/http_client/httpc_request.erl b/lib/inets/src/http_client/httpc_request.erl index 55e0af4b42..d4df97ad40 100644 --- a/lib/inets/src/http_client/httpc_request.erl +++ b/lib/inets/src/http_client/httpc_request.erl @@ -19,12 +19,13 @@ -module(httpc_request). --include("http_internal.hrl"). +-include_lib("inets/src/http_lib/http_internal.hrl"). -include("httpc_internal.hrl"). %%% Internal API -export([send/3, is_idempotent/1, is_client_closing/1]). + %%%========================================================================= %%% Internal application API %%%========================================================================= @@ -39,10 +40,9 @@ %% %% Description: Composes and sends a HTTP-request. %%------------------------------------------------------------------------- -send(SendAddr, #request{scheme = Scheme, socket_opts = SocketOpts} = Request, - Socket) +send(SendAddr, #session{socket = Socket, socket_type = SocketType}, + #request{socket_opts = SocketOpts} = Request) when is_list(SocketOpts) -> - SocketType = socket_type(Scheme), case http_transport:setopts(SocketType, Socket, SocketOpts) of ok -> send(SendAddr, Socket, SocketType, @@ -50,8 +50,7 @@ send(SendAddr, #request{scheme = Scheme, socket_opts = SocketOpts} = Request, {error, Reason} -> {error, {setopts_failed, Reason}} end; -send(SendAddr, #request{scheme = Scheme} = Request, Socket) -> - SocketType = socket_type(Scheme), +send(SendAddr, #session{socket = Socket, socket_type = SocketType}, Request) -> send(SendAddr, Socket, SocketType, Request). send(SendAddr, Socket, SocketType, @@ -209,10 +208,6 @@ headers(_, "HTTP/0.9") -> headers(Headers, _) -> Headers. -socket_type(http) -> - ip_comm; -socket_type(https) -> - {ssl, []}. http_headers([], Headers) -> lists:flatten(Headers); diff --git a/lib/inets/src/http_client/httpc_response.erl b/lib/inets/src/http_client/httpc_response.erl index df7d40a33e..207b96271c 100644 --- a/lib/inets/src/http_client/httpc_response.erl +++ b/lib/inets/src/http_client/httpc_response.erl @@ -19,10 +19,12 @@ -module(httpc_response). --include("http_internal.hrl"). +-include_lib("inets/src/http_lib/http_internal.hrl"). -include("httpc_internal.hrl"). %% API +%% Avoid warning for local function error/2 clashing with autoimported BIF. +-compile({no_auto_import,[error/2]}). -export([parse/1, result/2, send/2, error/2, is_server_closing/1, stream_start/3]). diff --git a/lib/inets/src/http_lib/Makefile b/lib/inets/src/http_lib/Makefile index 7f4c92861c..5dac3b0c00 100644 --- a/lib/inets/src/http_lib/Makefile +++ b/lib/inets/src/http_lib/Makefile @@ -55,24 +55,16 @@ TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) # ---------------------------------------------------- -# INETS FLAGS -# ---------------------------------------------------- -INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"' - - -# ---------------------------------------------------- # FLAGS # ---------------------------------------------------- -INETS_ERL_FLAGS += -I ../inets_app -ifeq ($(WARN_UNUSED_WARS),true) -ERL_COMPILE_FLAGS += +warn_unused_vars -endif +include ../inets_app/inets.mk -ERL_COMPILE_FLAGS += $(INETS_ERL_FLAGS) \ - $(INETS_FLAGS) \ - +'{parse_transform,sys_pre_attributes}' \ - +'{attribute,insert,app_vsn,$(APP_VSN)}' +ERL_COMPILE_FLAGS += \ + $(INETS_FLAGS) \ + $(INETS_ERL_COMPILE_FLAGS) \ + -I../../include \ + -I../inets_app # ---------------------------------------------------- @@ -94,9 +86,10 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin + $(INSTALL_DIR) $(RELSYSDIR)/src + $(INSTALL_DIR) $(RELSYSDIR)/src/http_lib + $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src/http_lib + $(INSTALL_DIR) $(RELSYSDIR)/ebin $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin release_docs_spec: diff --git a/lib/inets/src/http_lib/http_internal.hrl b/lib/inets/src/http_lib/http_internal.hrl index bb2e831727..5440f214b5 100644 --- a/lib/inets/src/http_lib/http_internal.hrl +++ b/lib/inets/src/http_lib/http_internal.hrl @@ -1,28 +1,37 @@ %% %% %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 %% 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("inets_internal.hrl"). +-ifndef(http_internal_hrl). +-define(http_internal_hrl, true). --define(HTTP_MAX_BODY_SIZE, nolimit). +-include_lib("inets/src/inets_app/inets_internal.hrl"). + +-define(HTTP_MAX_BODY_SIZE, nolimit). -define(HTTP_MAX_HEADER_SIZE, 10240). --define(HTTP_MAX_URI_SIZE, nolimit). +-define(HTTP_MAX_URI_SIZE, nolimit). + +-ifndef(HTTP_DEFAULT_SSL_KIND). +-define(HTTP_DEFAULT_SSL_KIND, ossl). +%% -define(HTTP_DEFAULT_SSL_KIND, essl). +-endif. % -ifdef(HTTP_DEFAULT_SSL_KIND). + %%% Response headers -record(http_response_h,{ @@ -106,3 +115,5 @@ 'last-modified', other=[] % list() - Key/Value list with other headers }). + +-endif. % -ifdef(http_internal_hrl). diff --git a/lib/inets/src/http_lib/http_transport.erl b/lib/inets/src/http_lib/http_transport.erl index 7c2ac626e6..b8121852b8 100644 --- a/lib/inets/src/http_lib/http_transport.erl +++ b/lib/inets/src/http_lib/http_transport.erl @@ -36,7 +36,9 @@ -export([negotiate/3]). --include("inets_internal.hrl"). +-include_lib("inets/src/inets_app/inets_internal.hrl"). +-include("http_internal.hrl"). + -define(SERVICE, httpl). -define(hlri(Label, Content), ?report_important(Label, ?SERVICE, Content)). -define(hlrv(Label, Content), ?report_verbose(Label, ?SERVICE, Content)). @@ -55,6 +57,18 @@ %% Description: Makes sure inet_db or ssl is started. %%------------------------------------------------------------------------- start(ip_comm) -> + do_start_ip_comm(); + +%% This is just for backward compatibillity +start({ssl, _}) -> + do_start_ssl(); +start({ossl, _}) -> + do_start_ssl(); +start({essl, _}) -> + do_start_ssl(). + + +do_start_ip_comm() -> case inet_db:start() of {ok, _} -> ok; @@ -62,8 +76,9 @@ start(ip_comm) -> ok; Error -> Error - end; -start({ssl, _}) -> + end. + +do_start_ssl() -> case ssl:start() of ok -> ok; @@ -97,18 +112,26 @@ connect(ip_comm = _SocketType, {Host, Port}, Opts0, Timeout) [{host, Host}, {port, Port}, {opts, Opts}, {timeout, Timeout}]), gen_tcp:connect(Host, Port, Opts, Timeout); -connect({ssl, SslConfig}, {Host, Port}, _, Timeout) -> - Opts = [binary, {active, false}] ++ SslConfig, - ?hlrt("connect using ssl", - [{host, Host}, {port, Port}, {ssl_config, SslConfig}, - {timeout, Timeout}]), +%% Wrapper for backaward compatibillity +connect({ssl, SslConfig}, Address, Opts, Timeout) -> + connect({?HTTP_DEFAULT_SSL_KIND, SslConfig}, Address, Opts, Timeout); + +connect({ossl, SslConfig}, {Host, Port}, _, Timeout) -> + Opts = [binary, {active, false}, {ssl_imp, old}] ++ SslConfig, + ?hlrt("connect using ossl", + [{host, Host}, + {port, Port}, + {ssl_config, SslConfig}, + {timeout, Timeout}]), ssl:connect(Host, Port, Opts, Timeout); -connect({erl_ssl, SslConfig}, {Host, Port}, _, Timeout) -> +connect({essl, SslConfig}, {Host, Port}, _, Timeout) -> Opts = [binary, {active, false}, {ssl_imp, new}] ++ SslConfig, - ?hlrt("connect using erl_ssl", - [{host, Host}, {port, Port}, {ssl_config, SslConfig}, - {timeout, Timeout}]), + ?hlrt("connect using essl", + [{host, Host}, + {port, Port}, + {ssl_config, SslConfig}, + {timeout, Timeout}]), ssl:connect(Host, Port, Opts, Timeout). @@ -136,13 +159,32 @@ listen(ip_comm, Addr, Port) -> Else end; -listen({ssl, SSLConfig} = Ssl, Addr, Port) -> +%% Wrapper for backaward compatibillity +listen({ssl, SSLConfig}, Addr, Port) -> + ?hlrt("listen (wrapper)", + [{addr, Addr}, + {port, Port}, + {ssl_config, SSLConfig}]), + listen({?HTTP_DEFAULT_SSL_KIND, SSLConfig}, Addr, Port); + +listen({ossl, SSLConfig} = Ssl, Addr, Port) -> + ?hlrt("listen (ossl)", + [{addr, Addr}, + {port, Port}, + {ssl_config, SSLConfig}]), Opt = sock_opt(Ssl, Addr, SSLConfig), - ssl:listen(Port, Opt); - -listen({erl_ssl, SSLConfig} = Ssl, Addr, Port) -> + ?hlrt("listen options", [{opt, Opt}]), + ssl:listen(Port, [{ssl_imp, old} | Opt]); + +listen({essl, SSLConfig} = Ssl, Addr, Port) -> + ?hlrt("listen (essl)", + [{addr, Addr}, + {port, Port}, + {ssl_config, SSLConfig}]), Opt = sock_opt(Ssl, Addr, SSLConfig), - ssl:listen(Port, [{ssl_imp, new} | Opt]). + ?hlrt("listen options", [{opt, Opt}]), + Opt2 = [{ssl_imp, new}, {reuseaddr, true} | Opt], + ssl:listen(Port, Opt2). listen_ip_comm(Addr, Port) -> @@ -228,9 +270,17 @@ ip_family_of(IpFamilyStr) -> %%------------------------------------------------------------------------- accept(SocketType, ListenSocket) -> accept(SocketType, ListenSocket, infinity). + accept(ip_comm, ListenSocket, Timeout) -> gen_tcp:accept(ListenSocket, Timeout); -accept({ssl,_SSLConfig}, ListenSocket, Timeout) -> + +%% Wrapper for backaward compatibillity +accept({ssl, SSLConfig}, ListenSocket, Timeout) -> + accept({?HTTP_DEFAULT_SSL_KIND, SSLConfig}, ListenSocket, Timeout); + +accept({ossl, _SSLConfig}, ListenSocket, Timeout) -> + ssl:transport_accept(ListenSocket, Timeout); +accept({essl, _SSLConfig}, ListenSocket, Timeout) -> ssl:transport_accept(ListenSocket, Timeout). @@ -244,7 +294,15 @@ accept({ssl,_SSLConfig}, ListenSocket, Timeout) -> %%------------------------------------------------------------------------- controlling_process(ip_comm, Socket, NewOwner) -> gen_tcp:controlling_process(Socket, NewOwner); -controlling_process({ssl, _}, Socket, NewOwner) -> + +%% Wrapper for backaward compatibillity +controlling_process({ssl, SSLConfig}, Socket, NewOwner) -> + controlling_process({?HTTP_DEFAULT_SSL_KIND, SSLConfig}, Socket, NewOwner); + +controlling_process({ossl, _}, Socket, NewOwner) -> + ssl:controlling_process(Socket, NewOwner); + +controlling_process({essl, _}, Socket, NewOwner) -> ssl:controlling_process(Socket, NewOwner). @@ -259,9 +317,23 @@ controlling_process({ssl, _}, Socket, NewOwner) -> setopts(ip_comm, Socket, Options) -> ?hlrt("ip_comm setopts", [{socket, Socket}, {options, Options}]), inet:setopts(Socket, Options); -setopts({ssl, _}, Socket, Options) -> - ?hlrt("ssl setopts", [{socket, Socket}, {options, Options}]), - ssl:setopts(Socket, Options). + +%% Wrapper for backaward compatibillity +setopts({ssl, SSLConfig}, Socket, Options) -> + setopts({?HTTP_DEFAULT_SSL_KIND, SSLConfig}, Socket, Options); + +setopts({ossl, _}, Socket, Options) -> + ?hlrt("[o]ssl setopts", [{socket, Socket}, {options, Options}]), + Reason = (catch ssl:setopts(Socket, Options)), + ?hlrt("[o]ssl setopts result", [{reason, Reason}]), + Reason; + + +setopts({essl, _}, Socket, Options) -> + ?hlrt("[e]ssl setopts", [{socket, Socket}, {options, Options}]), + Reason = (catch ssl:setopts(Socket, Options)), + ?hlrt("[e]ssl setopts result", [{reason, Reason}]), + Reason. %%------------------------------------------------------------------------- @@ -283,15 +355,27 @@ getopts(ip_comm, Socket, Options) -> {error, _} -> [] end; -getopts({ssl, _}, Socket, Options) -> + +%% Wrapper for backaward compatibillity +getopts({ssl, SSLConfig}, Socket, Options) -> + getopts({?HTTP_DEFAULT_SSL_KIND, SSLConfig}, Socket, Options); + +getopts({ossl, _}, Socket, Options) -> ?hlrt("ssl getopts", [{socket, Socket}, {options, Options}]), + getopts_ssl(Socket, Options); + +getopts({essl, _}, Socket, Options) -> + ?hlrt("essl getopts", [{socket, Socket}, {options, Options}]), + getopts_ssl(Socket, Options). + +getopts_ssl(Socket, Options) -> case ssl:getopts(Socket, Options) of {ok, SocketOpts} -> SocketOpts; {error, _} -> [] end. - + %%------------------------------------------------------------------------- %% getstat(SocketType, Socket) -> socket_stats() @@ -308,8 +392,15 @@ getstat(ip_comm = _SocketType, Socket) -> {error, _} -> [] end; -getstat({ssl, _} = _SocketType, _Socket) -> - %% ?hlrt("ssl getstat", [{socket, Socket}]), + +%% Wrapper for backaward compatibillity +getstat({ssl, SSLConfig}, Socket) -> + getstat({?HTTP_DEFAULT_SSL_KIND, SSLConfig}, Socket); + +getstat({ossl, _} = _SocketType, _Socket) -> + []; + +getstat({essl, _} = _SocketType, _Socket) -> []. @@ -322,7 +413,15 @@ getstat({ssl, _} = _SocketType, _Socket) -> %%------------------------------------------------------------------------- send(ip_comm, Socket, Message) -> gen_tcp:send(Socket, Message); -send({ssl, _}, Socket, Message) -> + +%% Wrapper for backaward compatibillity +send({ssl, SSLConfig}, Socket, Message) -> + send({?HTTP_DEFAULT_SSL_KIND, SSLConfig}, Socket, Message); + +send({ossl, _}, Socket, Message) -> + ssl:send(Socket, Message); + +send({essl, _}, Socket, Message) -> ssl:send(Socket, Message). @@ -335,9 +434,18 @@ send({ssl, _}, Socket, Message) -> %%------------------------------------------------------------------------- close(ip_comm, Socket) -> gen_tcp:close(Socket); -close({ssl, _}, Socket) -> + +%% Wrapper for backaward compatibillity +close({ssl, SSLConfig}, Socket) -> + close({?HTTP_DEFAULT_SSL_KIND, SSLConfig}, Socket); + +close({ossl, _}, Socket) -> + ssl:close(Socket); + +close({essl, _}, Socket) -> ssl:close(Socket). + %%------------------------------------------------------------------------- %% peername(SocketType, Socket) -> {Port, SockName} %% SocketType = ip_comm | {ssl, _} @@ -368,7 +476,17 @@ peername(ip_comm, Socket) -> {-1, "unknown"} end; -peername({ssl, _}, Socket) -> +%% Wrapper for backaward compatibillity +peername({ssl, SSLConfig}, Socket) -> + peername({?HTTP_DEFAULT_SSL_KIND, SSLConfig}, Socket); + +peername({ossl, _}, Socket) -> + peername_ssl(Socket); + +peername({essl, _}, Socket) -> + peername_ssl(Socket). + +peername_ssl(Socket) -> case ssl:peername(Socket) of {ok,{{A, B, C, D}, Port}} -> PeerName = integer_to_list(A)++"."++integer_to_list(B)++"."++ @@ -409,7 +527,17 @@ sockname(ip_comm, Socket) -> {-1, "unknown"} end; -sockname({ssl, _}, Socket) -> +%% Wrapper for backaward compatibillity +sockname({ssl, SSLConfig}, Socket) -> + sockname({?HTTP_DEFAULT_SSL_KIND, SSLConfig}, Socket); + +sockname({ossl, _}, Socket) -> + sockname_ssl(Socket); + +sockname({essl, _}, Socket) -> + sockname_ssl(Socket). + +sockname_ssl(Socket) -> case ssl:sockname(Socket) of {ok,{{A, B, C, D}, Port}} -> SockName = integer_to_list(A)++"."++integer_to_list(B)++"."++ @@ -455,22 +583,31 @@ sock_opt2(Opts) -> [{packet, 0}, {active, false} | Opts]. negotiate(ip_comm,_,_) -> + ?hlrt("negotiate(ip_comm)", []), ok; -negotiate({ssl,_},Socket,Timeout) -> - negotiate(Socket, Timeout); -negotiate({erl_ssl, _}, Socket, Timeout) -> - negotiate(Socket, Timeout). - -negotiate(Socket, Timeout) -> +negotiate({ssl, SSLConfig}, Socket, Timeout) -> + ?hlrt("negotiate(ssl)", []), + negotiate({?HTTP_DEFAULT_SSL_KIND, SSLConfig}, Socket, Timeout); +negotiate({ossl, _}, Socket, Timeout) -> + ?hlrt("negotiate(ossl)", []), + negotiate_ssl(Socket, Timeout); +negotiate({essl, _}, Socket, Timeout) -> + ?hlrt("negotiate(essl)", []), + negotiate_ssl(Socket, Timeout). + +negotiate_ssl(Socket, Timeout) -> + ?hlrt("negotiate_ssl", [{socket, Socket}, {timeout, Timeout}]), case ssl:ssl_accept(Socket, Timeout) of ok -> ok; - {error, Error} -> - case lists:member(Error, - [timeout,econnreset,esslaccept,esslerrssl]) of + {error, Reason} -> + ?hlrd("negotiate_ssl - accept failed", [{reason, Reason}]), + %% Look for "valid" error reasons + ValidReasons = [timeout, econnreset, esslaccept, esslerrssl], + case lists:member(Reason, ValidReasons) of true -> - {error,normal}; + {error, normal}; false -> - {error, Error} + {error, Reason} end end. diff --git a/lib/inets/src/http_server/Makefile b/lib/inets/src/http_server/Makefile index ce1405011e..879e605217 100644 --- a/lib/inets/src/http_server/Makefile +++ b/lib/inets/src/http_server/Makefile @@ -90,20 +90,17 @@ TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) # ---------------------------------------------------- -# INETS FLAGS -# ---------------------------------------------------- -INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"' - - -# ---------------------------------------------------- # FLAGS # ---------------------------------------------------- -INETS_ERL_FLAGS += -I ../http_lib -I ../inets_app -pa ../../ebin -ERL_COMPILE_FLAGS += $(INETS_ERL_FLAGS) \ - $(INETS_FLAGS) \ - +'{parse_transform,sys_pre_attributes}' \ - +'{attribute,insert,app_vsn,$(APP_VSN)}' +include ../inets_app/inets.mk + +ERL_COMPILE_FLAGS += \ + $(INETS_FLAGS) \ + $(INETS_ERL_COMPILE_FLAGS) \ + -I../../include \ + -I../inets_app \ + -I../http_lib # ---------------------------------------------------- @@ -125,9 +122,10 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin + $(INSTALL_DIR) $(RELSYSDIR)/src + $(INSTALL_DIR) $(RELSYSDIR)/src/http_server + $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src/http_server + $(INSTALL_DIR) $(RELSYSDIR)/ebin $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin release_docs_spec: diff --git a/lib/inets/src/http_server/httpd.erl b/lib/inets/src/http_server/httpd.erl index 8fe54ccef6..fb5fa1c758 100644 --- a/lib/inets/src/http_server/httpd.erl +++ b/lib/inets/src/http_server/httpd.erl @@ -24,54 +24,25 @@ -include("httpd.hrl"). --deprecated({start, 0, next_major_release}). --deprecated({start, 1, next_major_release}). --deprecated({start_link, 1, next_major_release}). --deprecated({start_child, 0, next_major_release}). --deprecated({start_child, 1, next_major_release}). --deprecated({stop, 0, next_major_release}). --deprecated({stop, 1, next_major_release}). --deprecated({stop, 2, next_major_release}). --deprecated({stop_child, 0, next_major_release}). --deprecated({stop_child, 1, next_major_release}). --deprecated({stop_child, 2, next_major_release}). --deprecated({restart, 0, next_major_release}). --deprecated({restart, 1, next_major_release}). --deprecated({restart, 2, next_major_release}). --deprecated({block, 0, next_major_release}). --deprecated({block, 1, next_major_release}). --deprecated({block, 2, next_major_release}). --deprecated({block, 3, next_major_release}). --deprecated({block, 4, next_major_release}). --deprecated({unblock, 0, next_major_release}). --deprecated({unblock, 1, next_major_release}). --deprecated({unblock, 2, next_major_release}). %% Behavior callbacks --export([start_standalone/1, start_service/1, stop_service/1, services/0, - service_info/1]). +-export([ + start_standalone/1, + start_service/1, + stop_service/1, + services/0, + service_info/1 + ]). %% API -export([parse_query/1, reload_config/2, info/1, info/2, info/3]). -%% Deprecated --export([start/0, start/1, - start_link/0, start_link/1, - start_child/0,start_child/1, - stop/0,stop/1,stop/2, - stop_child/0,stop_child/1,stop_child/2, - restart/0,restart/1,restart/2]). - -%% Management stuff should be internal functions -%% Will be from r13 --export([block/0,block/1,block/2,block/3,block/4, - unblock/0,unblock/1,unblock/2]). - -%% Internal Debugging and status info stuff... -%% Keep for now should probably be moved to test catalog --export([get_status/1,get_status/2,get_status/3, - get_admin_state/0,get_admin_state/1,get_admin_state/2, - get_usage_state/0,get_usage_state/1,get_usage_state/2]). +%% Internal debugging and status info stuff... +-export([ + get_status/1, get_status/2, get_status/3, + get_admin_state/0, get_admin_state/1, get_admin_state/2, + get_usage_state/0, get_usage_state/1, get_usage_state/2 + ]). %%%======================================================================== %%% API @@ -111,6 +82,7 @@ info(Address, Port, Properties) when is_integer(Port) andalso is_list(Properties) -> httpd_conf:get_config(Address, Port, Properties). + %%%======================================================================== %%% Behavior callbacks %%%======================================================================== @@ -149,6 +121,8 @@ service_info(Pid) -> exit:{noproc, _} -> {error, service_not_available} end. + + %%%-------------------------------------------------------------- %%% Internal functions %%%-------------------------------------------------------------------- @@ -176,6 +150,7 @@ child_name2info({httpd_instance_sup, Address, Port}) -> {ok, [{bind_address, Address}, {port, Port} | Info]} end. + reload(Config, Address, Port) -> Name = make_name(Address,Port), case whereis(Name) of @@ -185,26 +160,12 @@ reload(Config, Address, Port) -> {error,not_started} end. -reload(Addr, Port) when is_integer(Port) -> - Name = make_name(Addr,Port), - case whereis(Name) of - Pid when is_pid(Pid) -> - httpd_manager:reload(Pid, undefined); - _ -> - {error,not_started} - end. %%% ========================================================= -%%% Function: block/0, block/1, block/2, block/3, block/4 -%%% block() -%%% block(Port) -%%% block(ConfigFile) -%%% block(Addr,Port) -%%% block(Port,Mode) -%%% block(ConfigFile,Mode) -%%% block(Addr,Port,Mode) -%%% block(ConfigFile,Mode,Timeout) -%%% block(Addr,Port,Mode,Timeout) +%%% Function: block/3, block/4 +%%% block(Addr, Port, Mode) +%%% block(ConfigFile, Mode, Timeout) +%%% block(Addr, Port, Mode, Timeout) %%% %%% Returns: ok | {error,Reason} %%% @@ -237,58 +198,32 @@ reload(Addr, Port) when is_integer(Port) -> %%% Mode -> disturbing | non_disturbing %%% Timeout -> integer() %%% -block() -> block(undefined,8888,disturbing). - -block(Port) when is_integer(Port) -> - block(undefined,Port,disturbing); - -block(ConfigFile) when is_list(ConfigFile) -> - case get_addr_and_port(ConfigFile) of - {ok,Addr,Port} -> - block(Addr,Port,disturbing); - Error -> - Error - end. - -block(Addr,Port) when is_integer(Port) -> - block(Addr,Port,disturbing); - -block(Port,Mode) when is_integer(Port) andalso is_atom(Mode) -> - block(undefined,Port,Mode); - -block(ConfigFile,Mode) when is_list(ConfigFile) andalso is_atom(Mode) -> - case get_addr_and_port(ConfigFile) of - {ok,Addr,Port} -> - block(Addr,Port,Mode); - Error -> - Error - end. - -block(Addr,Port,disturbing) when is_integer(Port) -> - do_block(Addr,Port,disturbing); -block(Addr,Port,non_disturbing) when is_integer(Port) -> - do_block(Addr,Port,non_disturbing); +block(Addr, Port, disturbing) when is_integer(Port) -> + do_block(Addr, Port, disturbing); +block(Addr, Port, non_disturbing) when is_integer(Port) -> + do_block(Addr, Port, non_disturbing); -block(ConfigFile,Mode,Timeout) when is_list(ConfigFile) andalso - is_atom(Mode) andalso - is_integer(Timeout) -> +block(ConfigFile, Mode, Timeout) + when is_list(ConfigFile) andalso + is_atom(Mode) andalso + is_integer(Timeout) -> case get_addr_and_port(ConfigFile) of - {ok,Addr,Port} -> - block(Addr,Port,Mode,Timeout); + {ok, Addr, Port} -> + block(Addr, Port, Mode, Timeout); Error -> Error end. -block(Addr,Port,non_disturbing,Timeout) +block(Addr, Port, non_disturbing, Timeout) + when is_integer(Port) andalso is_integer(Timeout) -> + do_block(Addr, Port, non_disturbing, Timeout); +block(Addr,Port,disturbing,Timeout) when is_integer(Port) andalso is_integer(Timeout) -> - do_block(Addr,Port,non_disturbing,Timeout); -block(Addr,Port,disturbing,Timeout) when is_integer(Port) andalso - is_integer(Timeout) -> - do_block(Addr,Port,disturbing,Timeout). + do_block(Addr, Port, disturbing, Timeout). -do_block(Addr,Port,Mode) when is_integer(Port) andalso is_atom(Mode) -> +do_block(Addr, Port, Mode) when is_integer(Port) andalso is_atom(Mode) -> Name = make_name(Addr,Port), case whereis(Name) of Pid when is_pid(Pid) -> @@ -298,7 +233,7 @@ do_block(Addr,Port,Mode) when is_integer(Port) andalso is_atom(Mode) -> end. -do_block(Addr,Port,Mode,Timeout) +do_block(Addr, Port, Mode, Timeout) when is_integer(Port) andalso is_atom(Mode) -> Name = make_name(Addr,Port), case whereis(Name) of @@ -310,11 +245,8 @@ do_block(Addr,Port,Mode,Timeout) %%% ========================================================= -%%% Function: unblock/0, unblock/1, unblock/2 -%%% unblock() -%%% unblock(Port) -%%% unblock(ConfigFile) -%%% unblock(Addr,Port) +%%% Function: unblock/2 +%%% unblock(Addr, Port) %%% %%% Description: This function is used to reverse a previous block %%% operation on the HTTP server. @@ -323,16 +255,6 @@ do_block(Addr,Port,Mode,Timeout) %%% Addr -> {A,B,C,D} | string() | undefined %%% ConfigFile -> string() %%% -unblock() -> unblock(undefined,8888). -unblock(Port) when is_integer(Port) -> unblock(undefined,Port); - -unblock(ConfigFile) when is_list(ConfigFile) -> - case get_addr_and_port(ConfigFile) of - {ok,Addr,Port} -> - unblock(Addr,Port); - Error -> - Error - end. unblock(Addr, Port) when is_integer(Port) -> Name = make_name(Addr,Port), @@ -521,80 +443,81 @@ do_reload_config(ConfigList, Mode) -> %%%-------------------------------------------------------------- %%% Deprecated %%%-------------------------------------------------------------- -start() -> - start("/var/tmp/server_root/conf/8888.conf"). -start(ConfigFile) -> - {ok, Pid} = inets:start(httpd, ConfigFile, stand_alone), - unlink(Pid), - {ok, Pid}. +%% start() -> +%% start("/var/tmp/server_root/conf/8888.conf"). -start_link() -> - start("/var/tmp/server_root/conf/8888.conf"). +%% start(ConfigFile) -> +%% {ok, Pid} = inets:start(httpd, ConfigFile, stand_alone), +%% unlink(Pid), +%% {ok, Pid}. -start_link(ConfigFile) when is_list(ConfigFile) -> - inets:start(httpd, ConfigFile, stand_alone). +%% start_link() -> +%% start("/var/tmp/server_root/conf/8888.conf"). -stop() -> - stop(8888). +%% start_link(ConfigFile) when is_list(ConfigFile) -> +%% inets:start(httpd, ConfigFile, stand_alone). -stop(Port) when is_integer(Port) -> - stop(undefined, Port); -stop(Pid) when is_pid(Pid) -> - old_stop(Pid); -stop(ConfigFile) when is_list(ConfigFile) -> - old_stop(ConfigFile). +%% stop() -> +%% stop(8888). -stop(Addr, Port) when is_integer(Port) -> - old_stop(Addr, Port). +%% stop(Port) when is_integer(Port) -> +%% stop(undefined, Port); +%% stop(Pid) when is_pid(Pid) -> +%% old_stop(Pid); +%% stop(ConfigFile) when is_list(ConfigFile) -> +%% old_stop(ConfigFile). -start_child() -> - start_child("/var/tmp/server_root/conf/8888.conf"). +%% stop(Addr, Port) when is_integer(Port) -> +%% old_stop(Addr, Port). -start_child(ConfigFile) -> - httpd_sup:start_child(ConfigFile). +%% start_child() -> +%% start_child("/var/tmp/server_root/conf/8888.conf"). -stop_child() -> - stop_child(8888). +%% start_child(ConfigFile) -> +%% httpd_sup:start_child(ConfigFile). -stop_child(Port) -> - stop_child(undefined, Port). +%% stop_child() -> +%% stop_child(8888). -stop_child(Addr, Port) when is_integer(Port) -> - httpd_sup:stop_child(Addr, Port). +%% stop_child(Port) -> +%% stop_child(undefined, Port). -restart() -> reload(undefined, 8888). +%% stop_child(Addr, Port) when is_integer(Port) -> +%% httpd_sup:stop_child(Addr, Port). -restart(Port) when is_integer(Port) -> - reload(undefined, Port). -restart(Addr, Port) -> - reload(Addr, Port). +%% restart() -> reload(undefined, 8888). -old_stop(Pid) when is_pid(Pid) -> - do_stop(Pid); -old_stop(ConfigFile) when is_list(ConfigFile) -> - case get_addr_and_port(ConfigFile) of - {ok, Addr, Port} -> - old_stop(Addr, Port); - - Error -> - Error - end; -old_stop(_StartArgs) -> - ok. +%% restart(Port) when is_integer(Port) -> +%% reload(undefined, Port). +%% restart(Addr, Port) -> +%% reload(Addr, Port). -old_stop(Addr, Port) when is_integer(Port) -> - Name = old_make_name(Addr, Port), - case whereis(Name) of - Pid when is_pid(Pid) -> - do_stop(Pid), - ok; - _ -> - not_started - end. +%% old_stop(Pid) when is_pid(Pid) -> +%% do_stop(Pid); +%% old_stop(ConfigFile) when is_list(ConfigFile) -> +%% case get_addr_and_port(ConfigFile) of +%% {ok, Addr, Port} -> +%% old_stop(Addr, Port); + +%% Error -> +%% Error +%% end; +%% old_stop(_StartArgs) -> +%% ok. + +%% old_stop(Addr, Port) when is_integer(Port) -> +%% Name = old_make_name(Addr, Port), +%% case whereis(Name) of +%% Pid when is_pid(Pid) -> +%% do_stop(Pid), +%% ok; +%% _ -> +%% not_started +%% end. -do_stop(Pid) -> - exit(Pid, shutdown). +%% do_stop(Pid) -> +%% exit(Pid, shutdown). -old_make_name(Addr,Port) -> - httpd_util:make_name("httpd_instance_sup",Addr,Port). +%% old_make_name(Addr,Port) -> +%% httpd_util:make_name("httpd_instance_sup",Addr,Port). diff --git a/lib/inets/src/http_server/httpd_acceptor.erl b/lib/inets/src/http_server/httpd_acceptor.erl index 568fd3c610..c261eff6b2 100644 --- a/lib/inets/src/http_server/httpd_acceptor.erl +++ b/lib/inets/src/http_server/httpd_acceptor.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% @@ -138,9 +138,9 @@ acceptor_loop(Manager, SocketType, ListenSocket, ConfigDb, AcceptTimeout) -> handle_error(Reason, ConfigDb), ?MODULE:acceptor_loop(Manager, SocketType, ListenSocket, ConfigDb, AcceptTimeout); - {'EXIT', Reason} -> - ?hdri("accept exited", [{reason, Reason}]), - handle_error({'EXIT', Reason}, ConfigDb), + {'EXIT', _Reason} = EXIT -> + ?hdri("accept exited", [{reason, _Reason}]), + handle_error(EXIT, ConfigDb), ?MODULE:acceptor_loop(Manager, SocketType, ListenSocket, ConfigDb, AcceptTimeout) end. diff --git a/lib/inets/src/http_server/httpd_cgi.erl b/lib/inets/src/http_server/httpd_cgi.erl index 0532d7d100..c06a06aad3 100644 --- a/lib/inets/src/http_server/httpd_cgi.erl +++ b/lib/inets/src/http_server/httpd_cgi.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% @@ -21,7 +21,8 @@ -export([parse_headers/1, handle_headers/1]). --include("inets_internal.hrl"). +-include_lib("inets/src/inets_app/inets_internal.hrl"). + %%%========================================================================= %%% Internal application API diff --git a/lib/inets/src/http_server/httpd_conf.erl b/lib/inets/src/http_server/httpd_conf.erl index 5ca2e47eb5..8438c4037e 100644 --- a/lib/inets/src/http_server/httpd_conf.erl +++ b/lib/inets/src/http_server/httpd_conf.erl @@ -25,13 +25,15 @@ %% Application internal API -export([load/1, load/2, load_mime_types/1, store/1, store/2, - remove/1, remove_all/1, config/1, get_config/2, get_config/3, - lookup/2, lookup/3, lookup/4, - validate_properties/1]). + remove/1, remove_all/1, get_config/2, get_config/3, + lookup_socket_type/1, + lookup/2, lookup/3, lookup/4, + validate_properties/1]). -define(VMODULE,"CONF"). -include("httpd.hrl"). -include("httpd_internal.hrl"). +-include_lib("inets/src/http_lib/http_internal.hrl"). %%%========================================================================= @@ -216,9 +218,12 @@ load("ServerName " ++ ServerName, []) -> {ok,[],{server_name,clean(ServerName)}}; load("SocketType " ++ SocketType, []) -> - case check_enum(clean(SocketType),["ssl","ip_comm"]) of + %% ssl is the same as HTTP_DEFAULT_SSL_KIND + %% ossl is ssl based on OpenSSL (the "old" ssl) + %% essl is the pure Erlang-based ssl (the "new" ssl) + case check_enum(clean(SocketType), ["ssl", "ossl", "essl", "ip_comm"]) of {ok, ValidSocketType} -> - {ok, [], {socket_type,ValidSocketType}}; + {ok, [], {socket_type, ValidSocketType}}; {error,_} -> {error, ?NICE(clean(SocketType) ++ " is an invalid SocketType")} end; @@ -226,7 +231,7 @@ load("SocketType " ++ SocketType, []) -> load("Port " ++ Port, []) -> case make_integer(Port) of {ok, Integer} -> - {ok, [], {port,Integer}}; + {ok, [], {port, Integer}}; {error, _} -> {error, ?NICE(clean(Port)++" is an invalid Port")} end; @@ -534,7 +539,10 @@ validate_config_params([{server_name, Value} | _]) -> throw({server_name, Value}); validate_config_params([{socket_type, Value} | Rest]) - when (Value =:= ip_comm) orelse (Value =:= ssl) -> + when (Value =:= ip_comm) orelse + (Value =:= ssl) orelse + (Value =:= ossl) orelse + (Value =:= essl) -> validate_config_params(Rest); validate_config_params([{socket_type, Value} | _]) -> throw({socket_type, Value}); @@ -695,6 +703,8 @@ store(ConfigList0) -> ConfigList) catch throw:Error -> + ?hdri("store - config parameter validation failed", + [{error, Error}]), {error, {invalid_option, Error}} end. @@ -741,27 +751,27 @@ remove(ConfigDB) -> ets:delete(ConfigDB), ok. -config(ConfigDB) -> - case httpd_util:lookup(ConfigDB, socket_type,ip_comm) of - ssl -> - case ssl_certificate_file(ConfigDB) of - undefined -> - {error, - "Directive SSLCertificateFile " - "not found in the config file"}; - SSLCertificateFile -> - {ssl, - SSLCertificateFile++ - ssl_certificate_key_file(ConfigDB)++ - ssl_verify_client(ConfigDB)++ - ssl_ciphers(ConfigDB)++ - ssl_password(ConfigDB)++ - ssl_verify_depth(ConfigDB)++ - ssl_ca_certificate_file(ConfigDB)} - end; - ip_comm -> - ip_comm - end. +%% config(ConfigDB) -> +%% case httpd_util:lookup(ConfigDB, socket_type, ip_comm) of +%% ssl -> +%% case ssl_certificate_file(ConfigDB) of +%% undefined -> +%% {error, +%% "Directive SSLCertificateFile " +%% "not found in the config file"}; +%% SSLCertificateFile -> +%% {ssl, +%% SSLCertificateFile++ +%% ssl_certificate_key_file(ConfigDB)++ +%% ssl_verify_client(ConfigDB)++ +%% ssl_ciphers(ConfigDB)++ +%% ssl_password(ConfigDB)++ +%% ssl_verify_depth(ConfigDB)++ +%% ssl_ca_certificate_file(ConfigDB)} +%% end; +%% ip_comm -> +%% ip_comm +%% end. get_config(Address, Port) -> @@ -797,6 +807,38 @@ table(Address, Port) -> httpd_util:make_name("httpd_conf", Address, Port). +lookup_socket_type(ConfigDB) -> + case httpd_util:lookup(ConfigDB, socket_type, ip_comm) of + ip_comm -> + ip_comm; + SSL when (SSL =:= ssl) orelse (SSL =:= ossl) orelse (SSL =:= essl) -> + SSLTag = + if + (SSL =:= ssl) -> + ?HTTP_DEFAULT_SSL_KIND; + true -> + SSL + end, + case ssl_certificate_file(ConfigDB) of + undefined -> + Reason = "Directive SSLCertificateFile " + "not found in the config file", + throw({error, Reason}); + SSLCertificateFile -> + {SSLTag, SSLCertificateFile ++ ssl_config(ConfigDB)} + end + end. + +ssl_config(ConfigDB) -> + ssl_certificate_key_file(ConfigDB) ++ + ssl_verify_client(ConfigDB) ++ + ssl_ciphers(ConfigDB) ++ + ssl_password(ConfigDB) ++ + ssl_verify_depth(ConfigDB) ++ + ssl_ca_certificate_file(ConfigDB). + + + %%%======================================================================== %%% Internal functions %%%======================================================================== diff --git a/lib/inets/src/http_server/httpd_esi.erl b/lib/inets/src/http_server/httpd_esi.erl index b1a75fda52..026ec9a5fe 100644 --- a/lib/inets/src/http_server/httpd_esi.erl +++ b/lib/inets/src/http_server/httpd_esi.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% @@ -21,7 +21,8 @@ -export([parse_headers/1, handle_headers/1]). --include("inets_internal.hrl"). +-include_lib("inets/src/inets_app/inets_internal.hrl"). + %%%========================================================================= %%% Internal application API diff --git a/lib/inets/src/http_server/httpd_internal.hrl b/lib/inets/src/http_server/httpd_internal.hrl index 7795ab6c18..38b0ddefd3 100644 --- a/lib/inets/src/http_server/httpd_internal.hrl +++ b/lib/inets/src/http_server/httpd_internal.hrl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009. All Rights Reserved. -%% +%% +%% 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% %% %% @@ -21,7 +21,8 @@ -ifndef(httpd_internal_hrl). -define(httpd_internal_hrl, true). --include("inets_internal.hrl"). +-include_lib("inets/src/inets_app/inets_internal.hrl"). + -define(SERVICE, httpd). -define(hdri(Label, Content), ?report_important(Label, ?SERVICE, Content)). -define(hdrv(Label, Content), ?report_verbose(Label, ?SERVICE, Content)). diff --git a/lib/inets/src/http_server/httpd_manager.erl b/lib/inets/src/http_server/httpd_manager.erl index f2e8763907..b44bc77c41 100644 --- a/lib/inets/src/http_server/httpd_manager.erl +++ b/lib/inets/src/http_server/httpd_manager.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% @@ -238,24 +238,25 @@ init([ConfigFile, ConfigList, AcceptTimeout, Addr, Port]) -> case (catch do_init(ConfigFile, ConfigList, AcceptTimeout, Addr, Port)) of {error, Reason} -> String = lists:flatten( - io_lib:format("Failed initiating " - "web server: ~n~p~n~p~n", - [ConfigFile,Reason])), + io_lib:format("Failed initiating web server: " + "~n~p" + "~n~p" + "~n", [ConfigFile, Reason])), error_logger:error_report(String), {stop, {error, Reason}}; {ok, State} -> {ok, State} end; -init([ConfigFile, ConfigList, AcceptTimeout, Addr, Port, - ListenInfo]) -> +init([ConfigFile, ConfigList, AcceptTimeout, Addr, Port, ListenInfo]) -> process_flag(trap_exit, true), case (catch do_init(ConfigFile, ConfigList, AcceptTimeout, Addr, Port, ListenInfo)) of {error, Reason} -> String = lists:flatten( - io_lib:format("Failed initiating " - "web server: ~n~p~n~p~n", - [ConfigFile,Reason])), + io_lib:format("Failed initiating web server: " + "~n~p" + "~n~p" + "~n", [ConfigFile, Reason])), error_logger:error_report(String), {stop, {error, Reason}}; {ok, State} -> @@ -264,13 +265,14 @@ init([ConfigFile, ConfigList, AcceptTimeout, Addr, Port, do_init(ConfigFile, ConfigList, AcceptTimeout, Addr, Port) -> NewConfigFile = proplists:get_value(file, ConfigList, ConfigFile), - ConfigDB = do_initial_store(ConfigList), - SocketType = httpd_conf:config(ConfigDB), + ConfigDB = do_initial_store(ConfigList), + SocketType = httpd_conf:lookup_socket_type(ConfigDB), case httpd_acceptor_sup:start_acceptor(SocketType, Addr, Port, ConfigDB, AcceptTimeout) of {ok, _Pid} -> - Status = [{max_conn,0}, {last_heavy_load,never}, - {last_connection,never}], + Status = [{max_conn, 0}, + {last_heavy_load, never}, + {last_connection, never}], State = #state{socket_type = SocketType, config_file = NewConfigFile, config_db = ConfigDB, @@ -284,7 +286,7 @@ do_init(ConfigFile, ConfigList, AcceptTimeout, Addr, Port) -> do_init(ConfigFile, ConfigList, AcceptTimeout, Addr, Port, ListenInfo) -> NewConfigFile = proplists:get_value(file, ConfigList, ConfigFile), ConfigDB = do_initial_store(ConfigList), - SocketType = httpd_conf:config(ConfigDB), + SocketType = httpd_conf:lookup_socket_type(ConfigDB), case httpd_acceptor_sup:start_acceptor(SocketType, Addr, Port, ConfigDB, AcceptTimeout, ListenInfo) of diff --git a/lib/inets/src/http_server/httpd_request.erl b/lib/inets/src/http_server/httpd_request.erl index 8eee08e766..883acbf585 100644 --- a/lib/inets/src/http_server/httpd_request.erl +++ b/lib/inets/src/http_server/httpd_request.erl @@ -19,22 +19,35 @@ -module(httpd_request). --include("http_internal.hrl"). +-include_lib("inets/src/http_lib/http_internal.hrl"). -include("httpd.hrl"). +-include("httpd_internal.hrl"). --export([parse/1, whole_body/2, validate/3, update_mod_data/5, - body_data/2]). +-export([ + parse/1, + whole_body/2, + validate/3, + update_mod_data/5, + body_data/2 + ]). %% Callback API - used for example if the header/body is received a %% little at a time on a socket. --export([parse_method/1, parse_uri/1, parse_version/1, parse_headers/1, - whole_body/1]). +-export([ + parse_method/1, parse_uri/1, parse_version/1, parse_headers/1, + whole_body/1 + ]). + %%%========================================================================= %%% Internal application API %%%========================================================================= parse([Bin, MaxSizes]) -> - parse_method(Bin, [], MaxSizes, []). + ?hdrt("parse", [{bin, Bin}, {max_sizes, MaxSizes}]), + parse_method(Bin, [], MaxSizes, []); +parse(Unknown) -> + ?hdrt("parse", [{unknown, Unknown}]), + exit({bad_args, Unknown}). %% Functions that may be returned during the decoding process %% if the input data is incompleate. @@ -119,30 +132,65 @@ update_mod_data(ModData, Method, RequestURI, HTTPVersion, Headers)-> %%% Internal functions %%%======================================================================== parse_method(<<>>, Method, MaxSizes, Result) -> + ?hdrt("parse_method - empty bin", + [{method, Method}, {max_sizes, MaxSizes}, {result, Result}]), {?MODULE, parse_method, [Method, MaxSizes, Result]}; parse_method(<<?SP, Rest/binary>>, Method, MaxSizes, Result) -> + ?hdrt("parse_method - SP begin", + [{rest, Rest}, + {method, Method}, + {max_sizes, MaxSizes}, + {result, Result}]), parse_uri(Rest, [], 0, MaxSizes, [string:strip(lists:reverse(Method)) | Result]); parse_method(<<Octet, Rest/binary>>, Method, MaxSizes, Result) -> + ?hdrt("parse_method", + [{octet, Octet}, + {rest, Rest}, + {method, Method}, + {max_sizes, MaxSizes}, + {result, Result}]), parse_method(Rest, [Octet | Method], MaxSizes, Result). -parse_uri(_, _, CurrSize, {MaxURI, _}, _) when CurrSize > MaxURI, - MaxURI =/= nolimit -> +parse_uri(_, _, CurrSize, {MaxURI, _}, _) + when (CurrSize > MaxURI) andalso (MaxURI =/= nolimit) -> + ?hdrt("parse_uri", + [{current_size, CurrSize}, + {max_uri, MaxURI}]), %% We do not know the version of the client as it comes after the %% uri send the lowest version in the response so that the client %% will be able to handle it. HttpVersion = "HTTP/0.9", {error, {uri_too_long, MaxURI}, HttpVersion}; parse_uri(<<>>, URI, CurrSize, MaxSizes, Result) -> + ?hdrt("parse_uri - empty bin", + [{uri, URI}, + {current_size, CurrSize}, + {max_sz, MaxSizes}, + {result, Result}]), {?MODULE, parse_uri, [URI, CurrSize, MaxSizes, Result]}; parse_uri(<<?SP, Rest/binary>>, URI, _, MaxSizes, Result) -> + ?hdrt("parse_uri - SP begin", + [{uri, URI}, + {max_sz, MaxSizes}, + {result, Result}]), parse_version(Rest, [], MaxSizes, [string:strip(lists:reverse(URI)) | Result]); %% Can happen if it is a simple HTTP/0.9 request e.i "GET /\r\n\r\n" -parse_uri(<<?CR, _Rest/binary>> = Data, URI, _,MaxSizes, Result) -> +parse_uri(<<?CR, _Rest/binary>> = Data, URI, _, MaxSizes, Result) -> + ?hdrt("parse_uri - CR begin", + [{uri, URI}, + {max_sz, MaxSizes}, + {result, Result}]), parse_version(Data, [], MaxSizes, [string:strip(lists:reverse(URI)) | Result]); parse_uri(<<Octet, Rest/binary>>, URI, CurrSize, MaxSizes, Result) -> + ?hdrt("parse_uri", + [{octet, Octet}, + {uri, URI}, + {curr_sz, CurrSize}, + {max_sz, MaxSizes}, + {result, Result}]), parse_uri(Rest, [Octet | URI], CurrSize + 1, MaxSizes, Result). parse_version(<<>>, Version, MaxSizes, Result) -> diff --git a/lib/inets/src/http_server/httpd_request_handler.erl b/lib/inets/src/http_server/httpd_request_handler.erl index fa832cba3f..a9db6e2058 100644 --- a/lib/inets/src/http_server/httpd_request_handler.erl +++ b/lib/inets/src/http_server/httpd_request_handler.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% %% %% @@ -101,11 +101,13 @@ init([Manager, ConfigDB, AcceptTimeout]) -> Then = erlang:now(), + ?hdrd("negotiate", []), case http_transport:negotiate(SocketType, Socket, TimeOut) of {error, Error} -> + ?hdrd("negotiation failed", [{error, Error}]), exit(Error); %% Can be 'normal'. ok -> - ?hdrt("negotiated", []), + ?hdrt("negotiation successfull", []), NewTimeout = TimeOut - timer:now_diff(now(),Then) div 1000, continue_init(Manager, ConfigDB, SocketType, Socket, NewTimeout) end. @@ -121,12 +123,9 @@ continue_init(Manager, ConfigDB, SocketType, Socket, TimeOut) -> socket = Socket, init_data = InitData}, - MaxHeaderSize = httpd_util:lookup(ConfigDB, max_header_size, - ?HTTP_MAX_HEADER_SIZE), - MaxURISize = httpd_util:lookup(ConfigDB, max_uri_size, - ?HTTP_MAX_URI_SIZE), - NrOfRequest = httpd_util:lookup(ConfigDB, - max_keep_alive_request, infinity), + MaxHeaderSize = max_header_size(ConfigDB), + MaxURISize = max_uri_size(ConfigDB), + NrOfRequest = max_keep_alive_request(ConfigDB), {_, Status} = httpd_manager:new_connection(Manager), @@ -142,9 +141,10 @@ continue_init(Manager, ConfigDB, SocketType, Socket, TimeOut) -> ?hdrt("activate request timeout", []), NewState = activate_request_timeout(State), - ?hdrt("update socket options", []), - http_transport:setopts(SocketType, Socket, [binary,{packet, 0}, - {active, once}]), + ?hdrt("set socket options (binary, packet & active)", []), + http_transport:setopts(SocketType, Socket, + [binary, {packet, 0}, {active, once}]), + ?hdrt("init done", []), gen_server:enter_loop(?MODULE, [], NewState). @@ -180,21 +180,29 @@ handle_cast(Msg, State) -> %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- -handle_info({Proto, Socket, Data}, State = +handle_info({Proto, Socket, Data}, #state{mfa = {Module, Function, Args} = MFA, mod = #mod{socket_type = SockType, socket = Socket} = ModData} = State) when (((Proto =:= tcp) orelse (Proto =:= ssl) orelse (Proto =:= dummy)) andalso is_binary(Data)) -> + ?hdrd("received data", [{data, Data}, {proto, Proto}, {socket, Socket}, {socket_type, SockType}, {mfa, MFA}]), - case Module:Function([Data | Args]) of + +%% case (catch Module:Function([Data | Args])) of + PROCESSED = (catch Module:Function([Data | Args])), + + ?hdrt("data processed", [{processing_result, PROCESSED}]), + + case PROCESSED of {ok, Result} -> ?hdrd("data processed", [{result, Result}]), NewState = cancel_request_timeout(State), handle_http_msg(Result, NewState); + {error, {uri_too_long, MaxSize}, Version} -> ?hdrv("uri too long", [{max_size, MaxSize}, {version, Version}]), NewModData = ModData#mod{http_version = Version}, @@ -205,7 +213,8 @@ handle_info({Proto, Socket, Data}, State = {stop, normal, State#state{response_sent = true, mod = NewModData}}; {error, {header_too_long, MaxSize}, Version} -> - ?hdrv("header too long", [{max_size, MaxSize}, {version, Version}]), + ?hdrv("header too long", + [{max_size, MaxSize}, {version, Version}]), NewModData = ModData#mod{http_version = Version}, httpd_response:send_status(NewModData, 413, "Header too long"), Reason = io_lib:format("Header too long, max size is ~p~n", @@ -263,14 +272,16 @@ terminate(Reason, #state{response_sent = false, mod = ModData} = State) -> httpd_response:send_status(ModData, 500, none), error_log(httpd_util:reason_phrase(500), ModData), terminate(Reason, State#state{response_sent = true, mod = ModData}); -terminate(_, State) -> +terminate(_Reason, State) -> do_terminate(State). do_terminate(#state{mod = ModData, manager = Manager} = State) -> catch httpd_manager:done_connection(Manager), cancel_request_timeout(State), + %% receive after 5000 -> ok end, httpd_socket:close(ModData#mod.socket_type, ModData#mod.socket). + %%-------------------------------------------------------------------- %% code_change(OldVsn, State, Extra) -> {ok, NewState} %% @@ -279,6 +290,7 @@ do_terminate(#state{mod = ModData, manager = Manager} = State) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. + %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- @@ -383,9 +395,8 @@ is_host_specified_if_required(_, _, _) -> handle_body(#state{mod = #mod{config_db = ConfigDB}} = State) -> ?hdrt("handle body", []), - MaxHeaderSize = - httpd_util:lookup(ConfigDB, max_header_size, ?HTTP_MAX_HEADER_SIZE), - MaxBodySize = httpd_util:lookup(ConfigDB, max_body_size, nolimit), + MaxHeaderSize = max_header_size(ConfigDB), + MaxBodySize = max_body_size(ConfigDB), case handle_expect(State, MaxBodySize) of ok -> @@ -538,24 +549,23 @@ handle_response(#state{body = Body, {stop, normal, State#state{response_sent = true}}. handle_next_request(#state{mod = #mod{connection = true} = ModData, - max_keep_alive_request = Max} = State, Data) -> + max_keep_alive_request = Max} = State, Data) -> ?hdrt("handle next request", [{max, Max}]), + NewModData = #mod{socket_type = ModData#mod.socket_type, - socket = ModData#mod.socket, - config_db = ModData#mod.config_db, - init_data = ModData#mod.init_data}, - MaxHeaderSize = - httpd_util:lookup(ModData#mod.config_db, - max_header_size, ?HTTP_MAX_HEADER_SIZE), - MaxURISize = httpd_util:lookup(ModData#mod.config_db, max_uri_size, - ?HTTP_MAX_URI_SIZE), - TmpState = State#state{mod = NewModData, - mfa = {httpd_request, parse, [{MaxURISize, - MaxHeaderSize}]}, + socket = ModData#mod.socket, + config_db = ModData#mod.config_db, + init_data = ModData#mod.init_data}, + MaxHeaderSize = max_header_size(ModData#mod.config_db), + MaxURISize = max_uri_size(ModData#mod.config_db), + + MFA = {httpd_request, parse, [{MaxURISize, MaxHeaderSize}]}, + TmpState = State#state{mod = NewModData, + mfa = MFA, max_keep_alive_request = decrease(Max), - headers = undefined, - body = undefined, - response_sent = false}, + headers = undefined, + body = undefined, + response_sent = false}, NewState = activate_request_timeout(TmpState), @@ -596,7 +606,7 @@ decrease(N) -> error_log(ReasonString, Info) -> Error = lists:flatten( - io_lib:format("Error reading request:~s",[ReasonString])), + io_lib:format("Error reading request: ~s", [ReasonString])), error_log(mod_log, Info, Error), error_log(mod_disk_log, Info, Error). @@ -609,3 +619,21 @@ error_log(Mod, #mod{config_db = ConfigDB} = Info, String) -> _ -> ok end. + + +%%-------------------------------------------------------------------- +%% Config access wrapper functions +%%-------------------------------------------------------------------- + +max_header_size(ConfigDB) -> + httpd_util:lookup(ConfigDB, max_header_size, ?HTTP_MAX_HEADER_SIZE). + +max_uri_size(ConfigDB) -> + httpd_util:lookup(ConfigDB, max_uri_size, ?HTTP_MAX_URI_SIZE). + +max_body_size(ConfigDB) -> + httpd_util:lookup(ConfigDB, max_body_size, nolimit). + +max_keep_alive_request(ConfigDB) -> + httpd_util:lookup(ConfigDB, max_keep_alive_request, infinity). + diff --git a/lib/inets/src/http_server/mod_alias.erl b/lib/inets/src/http_server/mod_alias.erl index ec0a12242f..9c5a8cc1c6 100644 --- a/lib/inets/src/http_server/mod_alias.erl +++ b/lib/inets/src/http_server/mod_alias.erl @@ -103,6 +103,19 @@ real_name(ConfigDB, RequestURI, []) -> httpd_util:split_path(default_index(ConfigDB, RealName)), {ShortPath, Path, AfterPath}; +real_name(ConfigDB, RequestURI, [{MP,Replacement}|Rest]) + when element(1, MP) =:= re_pattern -> + case re:run(RequestURI, MP, [{capture,[]}]) of + match -> + NewURI = re:replace(RequestURI, MP, Replacement, [{return,list}]), + {ShortPath,_} = httpd_util:split_path(NewURI), + {Path,AfterPath} = + httpd_util:split_path(default_index(ConfigDB, NewURI)), + {ShortPath, Path, AfterPath}; + nomatch -> + real_name(ConfigDB, RequestURI, Rest) + end; + real_name(ConfigDB, RequestURI, [{FakeName,RealName}|Rest]) -> case inets_regexp:match(RequestURI, "^" ++ FakeName) of {match, _, _} -> @@ -120,6 +133,18 @@ real_name(ConfigDB, RequestURI, [{FakeName,RealName}|Rest]) -> real_script_name(_ConfigDB, _RequestURI, []) -> not_a_script; + +real_script_name(ConfigDB, RequestURI, [{MP,Replacement} | Rest]) + when element(1, MP) =:= re_pattern -> + case re:run(RequestURI, MP, [{capture,[]}]) of + match -> + ActualName = + re:replace(RequestURI, MP, Replacement, [{return,list}]), + httpd_util:split_script_path(default_index(ConfigDB, ActualName)); + nomatch -> + real_script_name(ConfigDB, RequestURI, Rest) + end; + real_script_name(ConfigDB, RequestURI, [{FakeName,RealName} | Rest]) -> case inets_regexp:match(RequestURI, "^" ++ FakeName) of {match,_,_} -> @@ -180,6 +205,8 @@ load("Alias " ++ Alias, []) -> {ok, _} -> {error,?NICE(httpd_conf:clean(Alias)++" is an invalid Alias")} end; +load("ReWrite " ++ Rule, Acc) -> + load_re_write(Rule, Acc, "ReWrite", re_write); load("ScriptAlias " ++ ScriptAlias, []) -> case inets_regexp:split(ScriptAlias, " ") of {ok, [FakeName, RealName]} -> @@ -189,6 +216,24 @@ load("ScriptAlias " ++ ScriptAlias, []) -> {ok, _} -> {error, ?NICE(httpd_conf:clean(ScriptAlias)++ " is an invalid ScriptAlias")} + end; +load("ScriptReWrite " ++ Rule, Acc) -> + load_re_write(Rule, Acc, "ScriptReWrite", script_re_write). + +load_re_write(Rule0, Acc, Type, Tag) -> + case lists:dropwhile( + fun ($\s) -> true; ($\t) -> true; (_) -> false end, + Rule0) of + "" -> + {error, ?NICE(httpd_conf:clean(Rule0)++" is an invalid "++Type)}; + Rule -> + case string:chr(Rule, $\s) of + 0 -> + {ok, Acc, {Tag, {Rule, ""}}}; + N -> + {Re, [_|Replacement]} = lists:split(N-1, Rule), + {ok, Acc, {Tag, {Re, Replacement}}} + end end. store({directory_index, Value} = Conf, _) when is_list(Value) -> @@ -200,16 +245,36 @@ store({directory_index, Value} = Conf, _) when is_list(Value) -> end; store({directory_index, Value}, _) -> {error, {wrong_type, {directory_index, Value}}}; -store({alias, {Fake, Real}} = Conf, _) - when is_list(Fake) andalso is_list(Real) -> +store({alias, {Fake, Real}} = Conf, _) + when is_list(Fake), is_list(Real) -> {ok, Conf}; store({alias, Value}, _) -> {error, {wrong_type, {alias, Value}}}; +store({re_write, {Re, Replacement}} = Conf, _) + when is_list(Re), is_list(Replacement) -> + case re:compile(Re) of + {ok, MP} -> + {ok, {alias, {MP, Replacement}}}; + {error,_} -> + {error, {re_compile, Conf}} + end; +store({re_write, _} = Conf, _) -> + {error, {wrong_type, Conf}}; store({script_alias, {Fake, Real}} = Conf, _) - when is_list(Fake) andalso is_list(Real) -> + when is_list(Fake), is_list(Real) -> {ok, Conf}; store({script_alias, Value}, _) -> - {error, {wrong_type, {script_alias, Value}}}. + {error, {wrong_type, {script_alias, Value}}}; +store({script_re_write, {Re, Replacement}} = Conf, _) + when is_list(Re), is_list(Replacement) -> + case re:compile(Re) of + {ok, MP} -> + {ok, {script_alias, {MP, Replacement}}}; + {error,_} -> + {error, {re_compile, Conf}} + end; +store({script_re_write, _} = Conf, _) -> + {error, {wrong_type, Conf}}. is_directory_index_list([]) -> true; diff --git a/lib/inets/src/http_server/mod_esi.erl b/lib/inets/src/http_server/mod_esi.erl index cb33544540..f7877aa9e2 100644 --- a/lib/inets/src/http_server/mod_esi.erl +++ b/lib/inets/src/http_server/mod_esi.erl @@ -29,6 +29,7 @@ -export([do/1, load/2, store/2]). -include("httpd.hrl"). +-include("httpd_internal.hrl"). -define(VMODULE,"ESI"). -define(DEFAULT_ERL_TIMEOUT,15000). @@ -37,6 +38,7 @@ %%%========================================================================= %%% API %%%========================================================================= + %%-------------------------------------------------------------------------- %% deliver(SessionID, Data) -> ok | {error, bad_sessionID} %% SessionID = pid() @@ -48,7 +50,7 @@ %% request handling process so it can forward it to the client. %%------------------------------------------------------------------------- deliver(SessionID, Data) when is_pid(SessionID) -> - SessionID ! {ok, Data}, + SessionID ! {esi_data, Data}, ok; deliver(_SessionID, _Data) -> {error, bad_sessionID}. @@ -65,6 +67,7 @@ deliver(_SessionID, _Data) -> %% Description: See httpd(3) ESWAPI CALLBACK FUNCTIONS %%------------------------------------------------------------------------- do(ModData) -> + ?hdrt("do", []), case proplists:get_value(status, ModData#mod.data) of {_StatusCode, _PhraseArgs, _Reason} -> {proceed, ModData#mod.data}; @@ -184,6 +187,7 @@ store({erl_script_nocache, Value}, _) -> %%% Internal functions %%%======================================================================== generate_response(ModData) -> + ?hdrt("generate response", []), case scheme(ModData#mod.request_uri, ModData#mod.config_db) of {eval, ESIBody, Modules} -> eval(ModData, ESIBody, Modules); @@ -235,6 +239,7 @@ alias_match_str(Alias, eval_script_alias) -> erl(#mod{method = Method} = ModData, ESIBody, Modules) when (Method =:= "GET") orelse (Method =:= "HEAD") -> + ?hdrt("erl", [{method, Method}]), case httpd_util:split(ESIBody,":|%3A|/",2) of {ok, [ModuleName, FuncAndInput]} -> case httpd_util:split(FuncAndInput,"[\?/]",2) of @@ -260,6 +265,7 @@ erl(#mod{request_uri = ReqUri, method = "PUT", http_version = Version, data = Data}, _ESIBody, _Modules) -> + ?hdrt("erl", [{method, put}]), {proceed, [{status,{501,{"PUT", ReqUri, Version}, ?NICE("Erl mechanism doesn't support method PUT")}}| Data]}; @@ -268,12 +274,14 @@ erl(#mod{request_uri = ReqUri, method = "DELETE", http_version = Version, data = Data}, _ESIBody, _Modules) -> + ?hdrt("erl", [{method, delete}]), {proceed,[{status,{501,{"DELETE", ReqUri, Version}, ?NICE("Erl mechanism doesn't support method DELETE")}}| Data]}; erl(#mod{method = "POST", entity_body = Body} = ModData, ESIBody, Modules) -> + ?hdrt("erl", [{method, post}]), case httpd_util:split(ESIBody,":|%3A|/",2) of {ok,[ModuleName, Function]} -> generate_webpage(ModData, ESIBody, Modules, @@ -289,6 +297,7 @@ generate_webpage(ModData, ESIBody, [all], Module, FunctionName, FunctionName, Input, ScriptElements); generate_webpage(ModData, ESIBody, Modules, Module, FunctionName, Input, ScriptElements) -> + ?hdrt("generate webpage", []), Function = list_to_atom(FunctionName), case lists:member(Module, Modules) of true -> @@ -309,8 +318,9 @@ generate_webpage(ModData, ESIBody, Modules, Module, FunctionName, %% Old API that waits for the dymnamic webpage to be totally generated %% before anythig is sent back to the client. -erl_scheme_webpage_whole(Module, Function, Env, Input, ModData) -> - case (catch Module:Function(Env, Input)) of +erl_scheme_webpage_whole(Mod, Func, Env, Input, ModData) -> + ?hdrt("erl_scheme_webpage_whole", [{module, Mod}, {function, Func}]), + case (catch Mod:Func(Env, Input)) of {'EXIT',{undef, _}} -> {proceed, [{status, {404, ModData#mod.request_uri, "Not found"}} | ModData#mod.data]}; @@ -347,6 +357,7 @@ erl_scheme_webpage_whole(Module, Function, Env, Input, ModData) -> %% in small chunks at the time during generation. erl_scheme_webpage_chunk(Mod, Func, Env, Input, ModData) -> process_flag(trap_exit, true), + ?hdrt("erl_scheme_webpage_chunk", [{module, Mod}, {function, Func}]), Self = self(), %% Spawn worker that generates the webpage. %% It would be nicer to use erlang:function_exported/3 but if the @@ -372,9 +383,12 @@ deliver_webpage_chunk(#mod{config_db = Db} = ModData, Pid) -> deliver_webpage_chunk(ModData, Pid, Timeout). deliver_webpage_chunk(#mod{config_db = Db} = ModData, Pid, Timeout) -> + ?hdrt("deliver_webpage_chunk", [{timeout, Timeout}]), case receive_headers(Timeout) of {error, Reason} -> %% Happens when webpage generator callback/3 is undefined + ?hdrv("deliver_webpage_chunk - failed receiving headers", + [{reason, Reason}]), {error, Reason}; {Headers, Body} -> case httpd_esi:handle_headers(Headers) of @@ -399,6 +413,7 @@ deliver_webpage_chunk(#mod{config_db = Db} = ModData, Pid, Timeout) -> IsDisableChunkedSend) end; timeout -> + ?hdrv("deliver_webpage_chunk - timeout", []), send_headers(ModData, {504, "Timeout"},[{"connection", "close"}]), httpd_socket:close(ModData#mod.socket_type, ModData#mod.socket), process_flag(trap_exit,false), @@ -407,11 +422,17 @@ deliver_webpage_chunk(#mod{config_db = Db} = ModData, Pid, Timeout) -> receive_headers(Timeout) -> receive + {esi_data, Chunk} -> + ?hdrt("receive_headers - received esi data (esi)", []), + httpd_esi:parse_headers(lists:flatten(Chunk)); {ok, Chunk} -> + ?hdrt("receive_headers - received esi data (ok)", []), httpd_esi:parse_headers(lists:flatten(Chunk)); {'EXIT', Pid, erl_scheme_webpage_chunk_undefined} when is_pid(Pid) -> + ?hdrd("receive_headers - exit:chunk-undef", []), {error, erl_scheme_webpage_chunk_undefined}; {'EXIT', Pid, Reason} when is_pid(Pid) -> + ?hdrv("receive_headers - exit", [{reason, Reason}]), exit({mod_esi_linked_process_died, Pid, Reason}) after Timeout -> timeout @@ -427,19 +448,29 @@ handle_body(_, #mod{method = "HEAD"} = ModData, _, _, Size, _) -> {proceed, [{response, {already_sent, 200, Size}} | ModData#mod.data]}; handle_body(Pid, ModData, Body, Timeout, Size, IsDisableChunkedSend) -> + ?hdrt("handle_body - send chunk", [{timeout, Timeout}, {size, Size}]), httpd_response:send_chunk(ModData, Body, IsDisableChunkedSend), receive + {esi_data, Data} -> + ?hdrt("handle_body - received data (esi)", []), + handle_body(Pid, ModData, Data, Timeout, Size + length(Data), + IsDisableChunkedSend); {ok, Data} -> + ?hdrt("handle_body - received data (ok)", []), handle_body(Pid, ModData, Data, Timeout, Size + length(Data), IsDisableChunkedSend); {'EXIT', Pid, normal} when is_pid(Pid) -> + ?hdrt("handle_body - exit:normal", []), httpd_response:send_final_chunk(ModData, IsDisableChunkedSend), {proceed, [{response, {already_sent, 200, Size}} | ModData#mod.data]}; {'EXIT', Pid, Reason} when is_pid(Pid) -> + ?hdrv("handle_body - exit", [{reason, Reason}]), httpd_response:send_final_chunk(ModData, IsDisableChunkedSend), exit({mod_esi_linked_process_died, Pid, Reason}) + after Timeout -> + ?hdrv("handle_body - timeout", []), process_flag(trap_exit,false), httpd_response:send_final_chunk(ModData, IsDisableChunkedSend), exit({mod_esi_linked_process_timeout, Pid}) @@ -473,6 +504,7 @@ eval(#mod{request_uri = ReqUri, method = "PUT", http_version = Version, data = Data}, _ESIBody, _Modules) -> + ?hdrt("eval", [{method, put}]), {proceed,[{status,{501,{"PUT", ReqUri, Version}, ?NICE("Eval mechanism doesn't support method PUT")}}| Data]}; @@ -481,6 +513,7 @@ eval(#mod{request_uri = ReqUri, method = "DELETE", http_version = Version, data = Data}, _ESIBody, _Modules) -> + ?hdrt("eval", [{method, delete}]), {proceed,[{status,{501,{"DELETE", ReqUri, Version}, ?NICE("Eval mechanism doesn't support method DELETE")}}| Data]}; @@ -489,12 +522,14 @@ eval(#mod{request_uri = ReqUri, method = "POST", http_version = Version, data = Data}, _ESIBody, _Modules) -> + ?hdrt("eval", [{method, post}]), {proceed,[{status,{501,{"POST", ReqUri, Version}, ?NICE("Eval mechanism doesn't support method POST")}}| Data]}; eval(#mod{method = Method} = ModData, ESIBody, Modules) - when Method == "GET"; Method == "HEAD" -> + when (Method =:= "GET") orelse (Method =:= "HEAD") -> + ?hdrt("eval", [{method, Method}]), case is_authorized(ESIBody, Modules) of true -> case generate_webpage(ESIBody) of diff --git a/lib/inets/src/inets_app/Makefile b/lib/inets/src/inets_app/Makefile index 33c9e34a3a..4632ff3b68 100644 --- a/lib/inets/src/inets_app/Makefile +++ b/lib/inets/src/inets_app/Makefile @@ -67,18 +67,15 @@ APPUP_TARGET = $(EBIN)/$(APPUP_FILE) # ---------------------------------------------------- -# INETS FLAGS -# ---------------------------------------------------- -INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"' - - -# ---------------------------------------------------- # FLAGS # ---------------------------------------------------- -ERL_COMPILE_FLAGS += $(INETS_FLAGS) \ - +'{parse_transform,sys_pre_attributes}' \ - +'{attribute,insert,app_vsn,$(APP_VSN)}' +include inets.mk + +ERL_COMPILE_FLAGS += \ + $(INETS_FLAGS) \ + $(INETS_ERL_COMPILE_FLAGS) \ + -I../../include # ---------------------------------------------------- @@ -112,7 +109,8 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src + $(INSTALL_DIR) $(RELSYSDIR)/src/inets_app + $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src/inets_app $(INSTALL_DIR) $(RELSYSDIR)/ebin $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin diff --git a/lib/inets/src/inets_app/inets.app.src b/lib/inets/src/inets_app/inets.app.src index 04f6365b98..cb036157a5 100644 --- a/lib/inets/src/inets_app/inets.app.src +++ b/lib/inets/src/inets_app/inets.app.src @@ -107,5 +107,6 @@ tftp_sup ]}, {registered,[inets_sup, httpc_manager]}, + %% If the "new" ssl is used then 'crypto' must be started before inets. {applications,[kernel,stdlib]}, {mod,{inets_app,[]}}]}. diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src index d86e998f01..84d8c9278d 100644 --- a/lib/inets/src/inets_app/inets.appup.src +++ b/lib/inets/src/inets_app/inets.appup.src @@ -1,125 +1,31 @@ %% This is an -*- erlang -*- file. %% %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% {"%VSN%", [ - {"5.3.3", - [ - {load_module, inets, soft_purge, soft_purge, []}, - {update, httpc_handler, soft, soft_purge, soft_purge, []}, - {update, httpc_manager, soft, soft_purge, soft_purge, []} - ] - }, - {"5.3.2", - [ - {load_module, inets, soft_purge, soft_purge, []}, - {load_module, http_util, soft_purge, soft_purge, []}, - {load_module, httpc_cookie, soft_purge, soft_purge, []}, - {update, httpc_handler, soft, soft_purge, soft_purge, []}, - {update, httpc_manager, soft, soft_purge, soft_purge, []} - ] - }, - {"5.3.1", - [ - {load_module, inets, soft_purge, soft_purge, []}, - {load_module, http_util, soft_purge, soft_purge, []}, - {load_module, httpc, soft_purge, soft_purge, []}, - {load_module, httpc_cookie, soft_purge, soft_purge, []}, - {update, httpc_handler, soft, soft_purge, soft_purge, [httpc_manager]}, - {update, httpc_manager, soft, soft_purge, soft_purge, []} - ] - }, - {"5.3", - [ - {load_module, inets, soft_purge, soft_purge, []}, - {load_module, http_util, soft_purge, soft_purge, []}, - {load_module, httpc, soft_purge, soft_purge, []}, - {load_module, httpc_cookie, soft_purge, soft_purge, []}, - {update, httpc_handler, soft, soft_purge, soft_purge, [httpc_manager]}, - {update, httpc_manager, soft, soft_purge, soft_purge, []}, - {load_module, mod_esi, soft_purge, soft_purge, []} - ] - }, - {"5.2", + {"5.4", [ {restart_application, inets} ] - }, - {"5.1.3", - [ - {restart_application, inets} - ] - }, - {"5.1.2", - [ - {restart_application, inets} - ] - } + } ], [ - {"5.3.3", - [ - {load_module, inets, soft_purge, soft_purge, []}, - {update, httpc_handler, soft, soft_purge, soft_purge, []}, - {update, httpc_manager, soft, soft_purge, soft_purge, []} - ] - }, - {"5.3.2", - [ - {load_module, inets, soft_purge, soft_purge, []}, - {load_module, http_util, soft_purge, soft_purge, []}, - {load_module, httpc_cookie, soft_purge, soft_purge, []}, - {update, httpc_handler, soft, soft_purge, soft_purge, []}, - {update, httpc_manager, soft, soft_purge, soft_purge, []} - ] - }, - {"5.3.1", - [ - {load_module, inets, soft_purge, soft_purge, []}, - {load_module, http_util, soft_purge, soft_purge, []}, - {load_module, httpc, soft_purge, soft_purge, []}, - {load_module, httpc_cookie, soft_purge, soft_purge, []}, - {update, httpc_handler, soft, soft_purge, soft_purge, [httpc_manager]}, - {update, httpc_manager, soft, soft_purge, soft_purge, []} - ] - }, - {"5.3", - [ - {load_module, inets, soft_purge, soft_purge, []}, - {load_module, http_util, soft_purge, soft_purge, []}, - {load_module, httpc, soft_purge, soft_purge, []}, - {load_module, httpc_cookie, soft_purge, soft_purge, []}, - {update, httpc_handler, soft, soft_purge, soft_purge, [httpc_manager]}, - {update, httpc_manager, soft, soft_purge, soft_purge, []}, - {load_module, mod_esi, soft_purge, soft_purge, []} - ] - }, - {"5.2", - [ - {restart_application, inets} - ] - }, - {"5.1.3", - [ - {restart_application, inets} - ] - }, - {"5.1.2", + {"5.4", [ {restart_application, inets} ] diff --git a/lib/inets/src/inets_app/inets.mk b/lib/inets/src/inets_app/inets.mk new file mode 100644 index 0000000000..b6e9fe1d96 --- /dev/null +++ b/lib/inets/src/inets_app/inets.mk @@ -0,0 +1,45 @@ +#-*-makefile-*- ; force emacs to enter makefile-mode + +# %CopyrightBegin% +# +# Copyright Ericsson AB 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% + +ifeq ($(INETS_TRACE), io) +ERL_COMPILE_FLAGS += -Dinets_trace_io +endif + +ifeq ($(INETS_DEBUG), true) +ERL_COMPILE_FLAGS += -Dinets_debug +endif + +ifeq ($(USE_INETS_HIPE), true) +ERL_COMPILE_FLAGS += +native +endif + +ifeq ($(WARN_UNUSED_WARS), true) +ERL_COMPILE_FLAGS += +warn_unused_vars +endif + +INETS_APP_VSN_COMPILE_FLAGS = \ + +'{parse_transform,sys_pre_attributes}' \ + +'{attribute,insert,app_vsn,$(APP_VSN)}' + +INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"' + +INETS_ERL_COMPILE_FLAGS += \ + -pa $(ERL_TOP)/lib/inets/ebin \ + $(INETS_APP_VSN_COMPILE_FLAGS) + diff --git a/lib/inets/src/inets_app/inets_service.erl b/lib/inets/src/inets_app/inets_service.erl index 3499314d54..e9eb9892f2 100644 --- a/lib/inets/src/inets_app/inets_service.erl +++ b/lib/inets/src/inets_app/inets_service.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% @@ -61,5 +61,5 @@ behaviour_info(_) -> %% service_info() -> [{Property, Value}] | {error, Reason} -%% ex: http:service_info() -> [{profile, ProfileName}] +%% ex: httpc:service_info() -> [{profile, ProfileName}] %% httpd:service_info() -> [{host, Host}, {port, Port}] diff --git a/lib/inets/src/tftp/Makefile b/lib/inets/src/tftp/Makefile index b4339da1e2..759b70c8e4 100644 --- a/lib/inets/src/tftp/Makefile +++ b/lib/inets/src/tftp/Makefile @@ -56,17 +56,16 @@ TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) # ---------------------------------------------------- -# INETS FLAGS +# FLAGS # ---------------------------------------------------- -INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"' +include ../inets_app/inets.mk -# ---------------------------------------------------- -# FLAGS -# ---------------------------------------------------- -ERL_COMPILE_FLAGS += $(INETS_FLAGS) \ - +'{parse_transform,sys_pre_attributes}' \ - +'{attribute,insert,app_vsn,$(APP_VSN)}' +ERL_COMPILE_FLAGS += \ + $(INETS_FLAGS) \ + $(INETS_ERL_COMPILE_FLAGS) \ + -I../../include \ + -I../inets_app # ---------------------------------------------------- @@ -87,9 +86,10 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin + $(INSTALL_DIR) $(RELSYSDIR)/src + $(INSTALL_DIR) $(RELSYSDIR)/src/tftp + $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src/tftp + $(INSTALL_DIR) $(RELSYSDIR)/ebin $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin release_docs_spec: diff --git a/lib/inets/test/Makefile b/lib/inets/test/Makefile index 668752da9e..bb7f2186af 100644 --- a/lib/inets/test/Makefile +++ b/lib/inets/test/Makefile @@ -143,6 +143,8 @@ else INETS_FLAGS += -Dhttpd_security_verbosity=log endif +INETS_FLAGS += -pa ../../inets/ebin + INETS_ROOT = ../../inets MODULES = \ @@ -241,8 +243,11 @@ RELTESTSYSBINDIR = $(RELTESTSYSALLDATADIR)/bin # The path to the test_server ebin dir is needed when # running the target "targets". # ---------------------------------------------------- -ERL_COMPILE_FLAGS += -pa ../../../internal_tools/test_server/ebin \ - $(INCLUDES) $(FTP_FLAGS) $(INETS_FLAGS) +ERL_COMPILE_FLAGS += \ + -pa ../../../internal_tools/test_server/ebin \ + $(INCLUDES) \ + $(FTP_FLAGS) \ + $(INETS_FLAGS) # ---------------------------------------------------- # Targets diff --git a/lib/inets/test/ftp_suite_lib.erl b/lib/inets/test/ftp_suite_lib.erl index b3c4ff2657..c539b7c17c 100644 --- a/lib/inets/test/ftp_suite_lib.erl +++ b/lib/inets/test/ftp_suite_lib.erl @@ -48,14 +48,17 @@ -ifdef(ftp_debug_client). -define(ftp_open(Host, Flags), - do_ftp_open(Host, [debug, {timeout, timer:seconds(15)}] ++ Flags)). + do_ftp_open(Host, [{debug, debug}, + {timeout, timer:seconds(15)} | Flags])). -else. -ifdef(ftp_trace_client). -define(ftp_open(Host, Flags), - do_ftp_open(Host, [trace, {timeout, timer:seconds(15)}] ++ Flags)). + do_ftp_open(Host, [{debug, trace}, + {timeout, timer:seconds(15)} | Flags])). -else. -define(ftp_open(Host, Flags), - do_ftp_open(Host, [verbose, {timeout, timer:seconds(15)}] ++ Flags)). + do_ftp_open(Host, [{verbose, true}, + {timeout, timer:seconds(15)} | Flags])). -endif. -endif. @@ -113,9 +116,7 @@ get_ftpd_host([Host|Hosts]) -> p("get_ftpd_host -> entry with" "~n Host: ~p" "~n", [Host]), - case (catch ftp:open({option_list, - [{host, Host}, {port, ?FTP_PORT}, - {timeout, 20000}]})) of + case (catch ftp:open(Host, [{port, ?FTP_PORT}, {timeout, 20000}])) of {ok, Pid} -> (catch ftp:close(Pid)), {ok, Host}; @@ -212,7 +213,7 @@ do_init_per_testcase(Case, Config) inets:start(), NewConfig = close_connection(watch_dog(Config)), Host = ftp_host(Config), - case (catch ?ftp_open(Host, [])) of + case (catch ?ftp_open(Host, [{mode, passive}])) of {ok, Pid} -> [{ftp, Pid} | data_dir(NewConfig)]; {skip, _} = SKIP -> @@ -225,9 +226,8 @@ do_init_per_testcase(Case, Config) inets:start(), NewConfig = close_connection(watch_dog(Config)), Host = ftp_host(Config), - case (catch ?ftp_open(Host, [])) of + case (catch ?ftp_open(Host, [{mode, active}])) of {ok, Pid} -> - ok = ftp:force_active(Pid), [{ftp, Pid} | data_dir(NewConfig)]; {skip, _} = SKIP -> SKIP @@ -240,11 +240,10 @@ do_init_per_testcase(Case, Config) io:format(user, "~n~n*** INIT ~w:~w ***~n~n", [?MODULE, Case]), NewConfig = close_connection(watch_dog(Config)), Host = ftp_host(Config), - Opts = [{host, Host}, - {port, ?FTP_PORT}, - {flags, [verbose]}, + Opts = [{port, ?FTP_PORT}, + {verbose, true}, {progress, {?MODULE, progress, #progress{}}}], - case ftp:open({option_list, Opts}) of + case ftp:open(Host, Opts) of {ok, Pid} -> ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS), [{ftp, Pid} | data_dir(NewConfig)]; @@ -257,22 +256,23 @@ do_init_per_testcase(Case, Config) -> inets:start(), NewConfig = close_connection(watch_dog(Config)), Host = ftp_host(Config), - Flags = + Opts1 = if ((Case =:= passive_ip_v6_disabled) orelse (Case =:= active_ip_v6_disabled)) -> - [ip_v6_disabled]; + [{ipfamily, inet}]; true -> [] end, - case (catch ?ftp_open(Host, Flags)) of + Opts2 = + case string:tokens(atom_to_list(Case), [$_]) of + [_, "active" | _] -> + [{mode, active} | Opts1]; + _ -> + [{mode, passive} | Opts1] + end, + case (catch ?ftp_open(Host, Opts2)) of {ok, Pid} -> - case string:tokens(atom_to_list(Case), [$_]) of - [_, "active"|_] -> - ok = ftp:force_active(Pid); - _ -> - ok - end, ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS), [{ftp, Pid} | data_dir(NewConfig)]; {skip, _} = SKIP -> @@ -365,6 +365,7 @@ open(Config) when is_list(Config) -> Host = ftp_host(Config), (catch tc_open(Host)). + tc_open(Host) -> {ok, Pid} = ?ftp_open(Host, []), ok = ftp:close(Pid), @@ -374,8 +375,9 @@ tc_open(Host) -> {flags, [verbose]}, {timeout, 30000}]}), ok = ftp:close(Pid1), - {error, ehost} = ftp:open({option_list, [{port, ?FTP_PORT}, - {flags, [verbose]}]}), + + {error, ehost} = + ftp:open({option_list, [{port, ?FTP_PORT}, {flags, [verbose]}]}), {ok, Pid2} = ftp:open(Host), ok = ftp:close(Pid2), @@ -408,6 +410,15 @@ tc_open(Host) -> {mode, cool}]}), test_server:sleep(100), ok = ftp:close(Pid6), + + {ok, Pid7} = + ftp:open(Host, [{port, ?FTP_PORT}, {verbose, true}, {timeout, 30000}]), + ok = ftp:close(Pid7), + + {ok, Pid8} = + ftp:open(Host, ?FTP_PORT), + ok = ftp:close(Pid8), + ok. @@ -420,7 +431,7 @@ open_port(suite) -> []; open_port(Config) when is_list(Config) -> Host = ftp_host(Config), - {ok, Pid} = ftp:open(Host, ?FTP_PORT), + {ok, Pid} = ftp:open(Host, [{port, ?FTP_PORT}]), ok = ftp:close(Pid), {error, ehost} = ftp:open(?BAD_HOST, []), ok. @@ -956,26 +967,39 @@ api_missuse(doc)-> ["Test that behaviour of the ftp process if the api is abused"]; api_missuse(suite) -> []; api_missuse(Config) when is_list(Config) -> + io:format("api_missuse -> entry~n", []), + Flag = process_flag(trap_exit, true), Pid = ?config(ftp, Config), Host = ftp_host(Config), - + %% Serious programming fault, connetion will be shut down - {error, {connection_terminated, 'API_violation'}} = - gen_server:call(Pid, {self(), foobar, 10}, infinity), + io:format("api_missuse -> verify bad call termination (~p)~n", [Pid]), + case (catch gen_server:call(Pid, {self(), foobar, 10}, infinity)) of + {error, {connection_terminated, 'API_violation'}} -> + ok; + Unexpected1 -> + exit({unexpected_result, Unexpected1}) + end, test_server:sleep(500), undefined = process_info(Pid, status), + io:format("api_missuse -> start new client~n", []), {ok, Pid2} = ?ftp_open(Host, []), %% Serious programming fault, connetion will be shut down + io:format("api_missuse -> verify bad cast termination~n", []), gen_server:cast(Pid2, {self(), foobar, 10}), test_server:sleep(500), undefined = process_info(Pid2, status), + io:format("api_missuse -> start new client~n", []), {ok, Pid3} = ?ftp_open(Host, []), %% Could be an innocent misstake the connection lives. + io:format("api_missuse -> verify bad bang~n", []), Pid3 ! foobar, test_server:sleep(500), {status, _} = process_info(Pid3, status), + process_flag(trap_exit, Flag), + io:format("api_missuse -> done~n", []), ok. @@ -1531,11 +1555,11 @@ split([C| Cs], I, Is) -> split([], I, Is) -> lists:reverse([lists:reverse(I)| Is]). -do_ftp_open(Host, Flags) -> +do_ftp_open(Host, Opts) -> io:format("do_ftp_open -> entry with" - "~n Host: ~p" - "~n Flags: ~p", [Host, Flags]), - case ftp:open(Host, Flags) of + "~n Host: ~p" + "~n Opts: ~p", [Host, Opts]), + case ftp:open(Host, Opts) of {ok, _} = OK -> OK; {error, Reason} -> diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl index f2e8bebe07..902e440c80 100644 --- a/lib/inets/test/httpc_SUITE.erl +++ b/lib/inets/test/httpc_SUITE.erl @@ -87,8 +87,14 @@ all(suite) -> http_headers_dummy, http_bad_response, ssl_head, + ossl_head, + essl_head, ssl_get, + ossl_get, + essl_get, ssl_trace, + ossl_trace, + essl_trace, http_redirect, http_redirect_loop, http_internal_server_error, @@ -179,49 +185,66 @@ init_per_testcase(otp_8154_1 = Case, Config) -> init_per_testcase(Case, Config) -> init_per_testcase(Case, 2, Config). +init_per_testcase_ssl(Tag, PrivDir, SslConfFile, Config) -> + tsp("init_per_testcase_ssl -> stop ssl"), + application:stop(ssl), + Config2 = lists:keydelete(local_ssl_server, 1, Config), + %% Will start inets + tsp("init_per_testcase_ssl -> try start http server (including inets)"), + Server = inets_test_lib:start_http_server( + filename:join(PrivDir, SslConfFile), Tag), + tsp("init_per_testcase -> Server: ~p", [Server]), + [{local_ssl_server, Server} | Config2]. + init_per_testcase(Case, Timeout, Config) -> - io:format(user, "~n~n*** INIT ~w:~w[~w] ***~n~n", + io:format(user, "~n~n*** INIT ~w:[~w][~w] ***~n~n", [?MODULE, Timeout, Case]), - PrivDir = ?config(priv_dir, Config), + PrivDir = ?config(priv_dir, Config), + tsp("init_per_testcase -> stop inets"), application:stop(inets), - Dog = test_server:timetrap(inets_test_lib:minutes(Timeout)), - TmpConfig = lists:keydelete(watchdog, 1, Config), - IpConfFile = integer_to_list(?IP_PORT) ++ ".conf", + Dog = test_server:timetrap(inets_test_lib:minutes(Timeout)), + TmpConfig = lists:keydelete(watchdog, 1, Config), + IpConfFile = integer_to_list(?IP_PORT) ++ ".conf", SslConfFile = integer_to_list(?SSL_PORT) ++ ".conf", + %% inets:enable_trace(max, io, httpd), + %% inets:enable_trace(max, io, httpc), + inets:enable_trace(max, io, all), + NewConfig = case atom_to_list(Case) of - "ssl" ++ _ -> - application:stop(ssl), - TmpConfig2 = - lists:keydelete(local_ssl_server, 1, TmpConfig), - %% Will start inets - Server = - inets_test_lib:start_http_server( - filename:join(PrivDir, SslConfFile)), - [{watchdog, Dog}, {local_ssl_server, Server} | TmpConfig2]; + [$s, $s, $l | _] -> + init_per_testcase_ssl(ssl, PrivDir, SslConfFile, [{watchdog, Dog} | TmpConfig]); + + [$o, $s, $s, $l | _] -> + init_per_testcase_ssl(ossl, PrivDir, SslConfFile, [{watchdog, Dog} | TmpConfig]); + + [$e, $s, $s, $l | _] -> + init_per_testcase_ssl(essl, PrivDir, SslConfFile, [{watchdog, Dog} | TmpConfig]); + "proxy" ++ Rest -> - case Rest of - "_https_not_supported" -> - inets:start(), - case (catch application:start(ssl)) of - ok -> - [{watchdog, Dog} | TmpConfig]; - _ -> - [{skip, - "SSL does not seem to be supported"} - | TmpConfig] - end; - _ -> - case is_proxy_available(?PROXY, ?PROXY_PORT) of - true -> - inets:start(), - [{watchdog, Dog} | TmpConfig]; - false -> - [{skip, "Failed to contact proxy"} | - TmpConfig] - end - end; + case Rest of + "_https_not_supported" -> + tsp("init_per_testcase -> [proxy case] start inets"), + inets:start(), + tsp("init_per_testcase -> [proxy case] start ssl"), + case (catch application:start(ssl)) of + ok -> + [{watchdog, Dog} | TmpConfig]; + _ -> + [{skip, "SSL does not seem to be supported"} + | TmpConfig] + end; + _ -> + case is_proxy_available(?PROXY, ?PROXY_PORT) of + true -> + inets:start(), + [{watchdog, Dog} | TmpConfig]; + false -> + [{skip, "Failed to contact proxy"} | + TmpConfig] + end + end; _ -> TmpConfig2 = lists:keydelete(local_server, 1, TmpConfig), Server = @@ -231,13 +254,12 @@ init_per_testcase(Case, Timeout, Config) -> [{watchdog, Dog}, {local_server, Server} | TmpConfig2] end, - http:set_options([{proxy, {{?PROXY, ?PROXY_PORT}, - ["localhost", ?IPV6_LOCAL_HOST]}}]), - inets:enable_trace(max, io, httpc), - %% inets:enable_trace(max, io, all), + httpc:set_options([{proxy, {{?PROXY, ?PROXY_PORT}, + ["localhost", ?IPV6_LOCAL_HOST]}}]), %% snmp:set_trace([gen_tcp, inet_tcp, prim_inet]), NewConfig. + %%-------------------------------------------------------------------- %% Function: end_per_testcase(Case, Config) -> _ %% Case - atom() @@ -307,7 +329,7 @@ http_head(Config) when is_list(Config) -> ok -> Port = ?config(local_port, Config), URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html", - case http:request(head, {URL, []}, [], []) of + case httpc:request(head, {URL, []}, [], []) of {ok, {{_,200,_}, [_ | _], []}} -> ok; {ok, WrongReply} -> @@ -338,7 +360,7 @@ http_get(Config) when is_list(Config) -> HttpOptions1 = [{timeout, Timeout}, {connect_timeout, ConnTimeout}], Options1 = [], Body = - case http:request(Method, Request, HttpOptions1, Options1) of + case httpc:request(Method, Request, HttpOptions1, Options1) of {ok, {{_,200,_}, [_ | _], ReplyBody = [_ | _]}} -> ReplyBody; {ok, UnexpectedReply1} -> @@ -347,12 +369,12 @@ http_get(Config) when is_list(Config) -> tsf({bad_reply, Error1}) end, - %% eqvivivalent to http:request(get, {URL, []}, [], []), + %% eqvivivalent to httpc:request(get, {URL, []}, [], []), inets_test_lib:check_body(Body), HttpOptions2 = [], Options2 = [{body_format, binary}], - case http:request(Method, Request, HttpOptions2, Options2) of + case httpc:request(Method, Request, HttpOptions2, Options2) of {ok, {{_,200,_}, [_ | _], Bin}} when is_binary(Bin) -> ok; {ok, {{_,200,_}, [_ | _], BadBin}} -> @@ -391,11 +413,11 @@ http_post(Config) when is_list(Config) -> Body = lists:duplicate(100, "1"), {ok, {{_,200,_}, [_ | _], [_ | _]}} = - http:request(post, {URL, [{"expect","100-continue"}], + httpc:request(post, {URL, [{"expect","100-continue"}], "text/plain", Body}, [], []), {ok, {{_,504,_}, [_ | _], []}} = - http:request(post, {URL, [{"expect","100-continue"}], + httpc:request(post, {URL, [{"expect","100-continue"}], "text/plain", "foobar"}, [], []); _ -> {skip, "Failed to start local http-server"} @@ -412,13 +434,13 @@ http_emulate_lower_versions(Config) when is_list(Config) -> Port = ?config(local_port, Config), URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html", {ok, Body0} = - http:request(get, {URL, []}, [{version, "HTTP/0.9"}], []), + httpc:request(get, {URL, []}, [{version, "HTTP/0.9"}], []), inets_test_lib:check_body(Body0), {ok, {{"HTTP/1.0", 200, _}, [_ | _], Body1 = [_ | _]}} = - http:request(get, {URL, []}, [{version, "HTTP/1.0"}], []), + httpc:request(get, {URL, []}, [{version, "HTTP/1.0"}], []), inets_test_lib:check_body(Body1), {ok, {{"HTTP/1.1", 200, _}, [_ | _], Body2 = [_ | _]}} = - http:request(get, {URL, []}, [{version, "HTTP/1.1"}], []), + httpc:request(get, {URL, []}, [{version, "HTTP/1.1"}], []), inets_test_lib:check_body(Body2); _-> {skip, "Failed to start local http-server"} @@ -432,24 +454,24 @@ http_relaxed(doc) -> http_relaxed(suite) -> []; http_relaxed(Config) when is_list(Config) -> - ok = http:set_options([{ipv6, disabled}]), % also test the old option - %% ok = http:set_options([{ipfamily, inet}]), + ok = httpc:set_options([{ipv6, disabled}]), % also test the old option + %% ok = httpc:set_options([{ipfamily, inet}]), {DummyServerPid, Port} = dummy_server(self(), ipv4), URL = ?URL_START ++ integer_to_list(Port) ++ "/missing_reason_phrase.html", {error, Reason} = - http:request(get, {URL, []}, [{relaxed, false}], []), + httpc:request(get, {URL, []}, [{relaxed, false}], []), test_server:format("Not relaxed: ~p~n", [Reason]), {ok, {{_, 200, _}, [_ | _], [_ | _]}} = - http:request(get, {URL, []}, [{relaxed, true}], []), + httpc:request(get, {URL, []}, [{relaxed, true}], []), DummyServerPid ! stop, - ok = http:set_options([{ipv6, enabled}]), - %% ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipv6, enabled}]), + %% ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* ok. @@ -459,7 +481,7 @@ http_dummy_pipe(doc) -> http_dummy_pipe(suite) -> []; http_dummy_pipe(Config) when is_list(Config) -> - ok = http:set_options([{ipfamily, inet}]), + ok = httpc:set_options([{ipfamily, inet}]), {DummyServerPid, Port} = dummy_server(self(), ipv4), URL = ?URL_START ++ integer_to_list(Port) ++ "/foobar.html", @@ -467,7 +489,7 @@ http_dummy_pipe(Config) when is_list(Config) -> test_pipeline(URL), DummyServerPid ! stop, - ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* ok. http_inets_pipe(doc) -> @@ -489,11 +511,11 @@ test_pipeline(URL) -> p("test_pipeline -> entry with" "~n URL: ~p", [URL]), - http:set_options([{pipeline_timeout, 50000}]), + httpc:set_options([{pipeline_timeout, 50000}]), p("test_pipeline -> issue (async) request 1"), {ok, RequestId1} = - http:request(get, {URL, []}, [], [{sync, false}]), + httpc:request(get, {URL, []}, [], [{sync, false}]), test_server:format("RequestId1: ~p~n", [RequestId1]), p("test_pipeline -> RequestId1: ~p", [RequestId1]), @@ -503,13 +525,13 @@ test_pipeline(URL) -> p("test_pipeline -> issue (async) request 2"), {ok, RequestId2} = - http:request(get, {URL, []}, [], [{sync, false}]), + httpc:request(get, {URL, []}, [], [{sync, false}]), tsp("RequestId2: ~p", [RequestId2]), p("test_pipeline -> RequestId2: ~p", [RequestId2]), p("test_pipeline -> issue (sync) request 3"), {ok, {{_,200,_}, [_ | _], [_ | _]}} = - http:request(get, {URL, []}, [], []), + httpc:request(get, {URL, []}, [], []), p("test_pipeline -> expect reply for (async) request 1 or 2"), receive @@ -545,18 +567,18 @@ test_pipeline(URL) -> p("test_pipeline -> issue (async) request 4"), {ok, RequestId3} = - http:request(get, {URL, []}, [], [{sync, false}]), + httpc:request(get, {URL, []}, [], [{sync, false}]), tsp("RequestId3: ~p", [RequestId3]), p("test_pipeline -> RequestId3: ~p", [RequestId3]), p("test_pipeline -> issue (async) request 5"), {ok, RequestId4} = - http:request(get, {URL, []}, [], [{sync, false}]), + httpc:request(get, {URL, []}, [], [{sync, false}]), tsp("RequestId4: ~p~n", [RequestId4]), p("test_pipeline -> RequestId4: ~p", [RequestId4]), p("test_pipeline -> cancel (async) request 4"), - ok = http:cancel_request(RequestId3), + ok = httpc:cancel_request(RequestId3), p("test_pipeline -> expect *no* reply for cancelled (async) request 4 (for 3 secs)"), receive @@ -608,7 +630,7 @@ http_trace(Config) when is_list(Config) -> ok -> Port = ?config(local_port, Config), URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html", - case http:request(trace, {URL, []}, [], []) of + case httpc:request(trace, {URL, []}, [], []) of {ok, {{_,200,_}, [_ | _], "TRACE /dummy.html" ++ _}} -> ok; {ok, {{_,200,_}, [_ | _], WrongBody}} -> @@ -632,7 +654,7 @@ http_async(Config) when is_list(Config) -> Port = ?config(local_port, Config), URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html", {ok, RequestId} = - http:request(get, {URL, []}, [], [{sync, false}]), + httpc:request(get, {URL, []}, [], [{sync, false}]), Body = receive @@ -645,8 +667,8 @@ http_async(Config) when is_list(Config) -> inets_test_lib:check_body(binary_to_list(Body)), {ok, NewRequestId} = - http:request(get, {URL, []}, [], [{sync, false}]), - ok = http:cancel_request(NewRequestId), + httpc:request(get, {URL, []}, [], [{sync, false}]), + ok = httpc:cancel_request(NewRequestId), receive {http, {NewRequestId, _NewResult}} -> test_server:fail(http_cancel_request_failed) @@ -670,9 +692,9 @@ http_save_to_file(Config) when is_list(Config) -> Port = ?config(local_port, Config), URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html", {ok, saved_to_file} - = http:request(get, {URL, []}, [], [{stream, FilePath}]), + = httpc:request(get, {URL, []}, [], [{stream, FilePath}]), {ok, Bin} = file:read_file(FilePath), - {ok, {{_,200,_}, [_ | _], Body}} = http:request(URL), + {ok, {{_,200,_}, [_ | _], Body}} = httpc:request(URL), Bin == Body; _ -> {skip, "Failed to start local http-server"} @@ -691,7 +713,7 @@ http_save_to_file_async(Config) when is_list(Config) -> FilePath = filename:join(PrivDir, "dummy.html"), Port = ?config(local_port, Config), URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html", - {ok, RequestId} = http:request(get, {URL, []}, [], + {ok, RequestId} = httpc:request(get, {URL, []}, [], [{stream, FilePath}, {sync, false}]), receive @@ -702,7 +724,7 @@ http_save_to_file_async(Config) when is_list(Config) -> end, {ok, Bin} = file:read_file(FilePath), - {ok, {{_,200,_}, [_ | _], Body}} = http:request(URL), + {ok, {{_,200,_}, [_ | _], Body}} = httpc:request(URL), Bin == Body; _ -> {skip, "Failed to start local http-server"} @@ -732,7 +754,7 @@ http_headers(Config) when is_list(Config) -> Date = httpd_util:rfc1123_date({date(), time()}), {ok, {{_,200,_}, [_ | _], [_ | _]}} = - http:request(get, {URL, [{"If-Modified-Since", + httpc:request(get, {URL, [{"If-Modified-Since", Mod}, {"From","[email protected]"}, {"Date", Date} @@ -743,7 +765,7 @@ http_headers(Config) when is_list(Config) -> CreatedSec+1)), {ok, {{_,200,_}, [_ | _], [_ | _]}} = - http:request(get, {URL, [{"If-UnModified-Since", + httpc:request(get, {URL, [{"If-UnModified-Since", Mod1} ]}, [], []), @@ -751,12 +773,12 @@ http_headers(Config) when is_list(Config) -> {ok, {{_,200,_}, [_ | _], [_ | _]}} = - http:request(get, {URL, [{"If-Match", + httpc:request(get, {URL, [{"If-Match", Tag} ]}, [], []), {ok, {{_,200,_}, [_ | _], _}} = - http:request(get, {URL, [{"If-None-Match", + httpc:request(get, {URL, [{"If-None-Match", "NotEtag,NeihterEtag"}, {"Connection", "Close"} ]}, [], []), @@ -774,7 +796,7 @@ http_headers_dummy(doc) -> http_headers_dummy(suite) -> []; http_headers_dummy(Config) when is_list(Config) -> - ok = http:set_options([{ipfamily, inet}]), + ok = httpc:set_options([{ipfamily, inet}]), {DummyServerPid, Port} = dummy_server(self(), ipv4), URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy_headers.html", @@ -790,7 +812,7 @@ http_headers_dummy(Config) when is_list(Config) -> %% that the client header-handling code. This would not %% be a vaild http-request! {ok, {{_,200,_}, [_ | _], [_|_]}} = - http:request(post, + httpc:request(post, {URL, [{"Via", "1.0 fred, 1.1 nowhere.com (Apache/1.1)"}, @@ -829,7 +851,7 @@ http_headers_dummy(Config) when is_list(Config) -> ], "text/plain", FooBar}, [], []), DummyServerPid ! stop, - ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* ok. @@ -839,21 +861,21 @@ http_bad_response(doc) -> http_bad_response(suite) -> []; http_bad_response(Config) when is_list(Config) -> - ok = http:set_options([{ipfamily, inet}]), + ok = httpc:set_options([{ipfamily, inet}]), {DummyServerPid, Port} = dummy_server(self(), ipv4), URL = ?URL_START ++ integer_to_list(Port) ++ "/missing_crlf.html", URL1 = ?URL_START ++ integer_to_list(Port) ++ "/wrong_statusline.html", - {error, timeout} = http:request(get, {URL, []}, [{timeout, 400}], []), + {error, timeout} = httpc:request(get, {URL, []}, [{timeout, 400}], []), - {error, Reason} = http:request(URL1), + {error, Reason} = httpc:request(URL1), test_server:format("Wrong Statusline: ~p~n", [Reason]), DummyServerPid ! stop, - ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* ok. @@ -863,69 +885,168 @@ ssl_head(doc) -> ssl_head(suite) -> []; ssl_head(Config) when is_list(Config) -> + ssl_head(ssl, Config). + +ossl_head(doc) -> + ["Same as http_head/1 but over ssl sockets."]; +ossl_head(suite) -> + []; +ossl_head(Config) when is_list(Config) -> + ssl_head(ossl, Config). + +essl_head(doc) -> + ["Same as http_head/1 but over ssl sockets."]; +essl_head(suite) -> + []; +essl_head(Config) when is_list(Config) -> + ssl_head(essl, Config). + +ssl_head(SslTag, Config) -> + tsp("ssl_head -> entry with" + "~n SslTag: ~p" + "~n Config: ~p", [SslTag, Config]), case ?config(local_ssl_server, Config) of ok -> - DataDir = ?config(data_dir, Config), - Port = ?config(local_ssl_port, Config), - URL = ?SSL_URL_START ++ integer_to_list(Port) ++ "/dummy.html", - CertFile = filename:join(DataDir, "ssl_client_cert.pem"), + DataDir = ?config(data_dir, Config), + Port = ?config(local_ssl_port, Config), + URL = ?SSL_URL_START ++ integer_to_list(Port) ++ "/dummy.html", + CertFile = filename:join(DataDir, "ssl_client_cert.pem"), SSLOptions = [{certfile, CertFile}, {keyfile, CertFile}], + SSLConfig = + case SslTag of + ssl -> + SSLOptions; + ossl -> + {ossl, SSLOptions}; + essl -> + {essl, SSLOptions} + end, + tsp("ssl_head -> make request using: " + "~n URL: ~p" + "~n SslTag: ~p" + "~n SSLOptions: ~p", [URL, SslTag, SSLOptions]), {ok, {{_,200, _}, [_ | _], []}} = - http:request(head, {URL, []}, [{ssl, SSLOptions}], []); + httpc:request(head, {URL, []}, [{ssl, SSLConfig}], []); {ok, _} -> - {skip, "Failed to start local http-server"}; + {skip, "local http-server not started"}; _ -> - {skip, "Failed to start SSL"} + {skip, "SSL not started"} end. + + %%------------------------------------------------------------------------- ssl_get(doc) -> ["Same as http_get/1 but over ssl sockets."]; ssl_get(suite) -> []; ssl_get(Config) when is_list(Config) -> + ssl_get(ssl, Config). + +ossl_get(doc) -> + ["Same as http_get/1 but over ssl sockets."]; +ossl_get(suite) -> + []; +ossl_get(Config) when is_list(Config) -> + ssl_get(ossl, Config). + +essl_get(doc) -> + ["Same as http_get/1 but over ssl sockets."]; +essl_get(suite) -> + []; +essl_get(Config) when is_list(Config) -> + ssl_get(essl, Config). + +ssl_get(SslTag, Config) when is_list(Config) -> case ?config(local_ssl_server, Config) of ok -> - DataDir = ?config(data_dir, Config), - Port = ?config(local_ssl_port, Config), - URL = ?SSL_URL_START ++ integer_to_list(Port) ++ "/dummy.html", - CertFile = filename:join(DataDir, "ssl_client_cert.pem"), + DataDir = ?config(data_dir, Config), + Port = ?config(local_ssl_port, Config), + URL = ?SSL_URL_START ++ integer_to_list(Port) ++ "/dummy.html", + CertFile = filename:join(DataDir, "ssl_client_cert.pem"), SSLOptions = [{certfile, CertFile}, {keyfile, CertFile}], - {ok, {{_,200, _}, [_ | _], Body = [_ | _]}} = - http:request(get, {URL, []}, [{ssl, SSLOptions}], []), - inets_test_lib:check_body(Body); + SSLConfig = + case SslTag of + ssl -> + SSLOptions; + ossl -> + {ossl, SSLOptions}; + essl -> + {essl, SSLOptions} + end, + tsp("ssl_get -> make request using: " + "~n URL: ~p" + "~n SslTag: ~p" + "~n SSLOptions: ~p", [URL, SslTag, SSLOptions]), + {ok, {{_,200, _}, [_ | _], Body = [_ | _]}} = + httpc:request(get, {URL, []}, [{ssl, SSLConfig}], []), + inets_test_lib:check_body(Body); {ok, _} -> {skip, "Failed to start local http-server"}; _ -> {skip, "Failed to start SSL"} end. + + %%------------------------------------------------------------------------- ssl_trace(doc) -> ["Same as http_trace/1 but over ssl sockets."]; ssl_trace(suite) -> []; ssl_trace(Config) when is_list(Config) -> + ssl_trace(ssl, Config). + +ossl_trace(doc) -> + ["Same as http_trace/1 but over ssl sockets."]; +ossl_trace(suite) -> + []; +ossl_trace(Config) when is_list(Config) -> + ssl_trace(ossl, Config). + +essl_trace(doc) -> + ["Same as http_trace/1 but over ssl sockets."]; +essl_trace(suite) -> + []; +essl_trace(Config) when is_list(Config) -> + ssl_trace(essl, Config). + +ssl_trace(SslTag, Config) when is_list(Config) -> case ?config(local_ssl_server, Config) of ok -> - DataDir = ?config(data_dir, Config), - Port = ?config(local_ssl_port, Config), - URL = ?SSL_URL_START ++ integer_to_list(Port) ++ "/dummy.html", - CertFile = filename:join(DataDir, "ssl_client_cert.pem"), + DataDir = ?config(data_dir, Config), + Port = ?config(local_ssl_port, Config), + URL = ?SSL_URL_START ++ integer_to_list(Port) ++ "/dummy.html", + CertFile = filename:join(DataDir, "ssl_client_cert.pem"), SSLOptions = [{certfile, CertFile}, {keyfile, CertFile}], - case http:request(trace, {URL, []}, [{ssl, SSLOptions}], []) of + SSLConfig = + case SslTag of + ssl -> + SSLOptions; + ossl -> + {ossl, SSLOptions}; + essl -> + {essl, SSLOptions} + end, + tsp("ssl_trace -> make request using: " + "~n URL: ~p" + "~n SslTag: ~p" + "~n SSLOptions: ~p", [URL, SslTag, SSLOptions]), + case httpc:request(trace, {URL, []}, [{ssl, SSLConfig}], []) of {ok, {{_,200, _}, [_ | _], "TRACE /dummy.html" ++ _}} -> ok; {ok, {{_,200,_}, [_ | _], WrongBody}} -> - test_server:fail({wrong_body, WrongBody}); + tsf({wrong_body, WrongBody}); {ok, WrongReply} -> - test_server:fail({wrong_reply, WrongReply}); + tsf({wrong_reply, WrongReply}); Error -> - test_server:fail({failed, Error}) + tsf({failed, Error}) end; {ok, _} -> {skip, "Failed to start local http-server"}; _ -> {skip, "Failed to start SSL"} end. + + %%------------------------------------------------------------------------- http_redirect(doc) -> ["Test redirect with dummy server as httpd does not implement" @@ -938,7 +1059,7 @@ http_redirect(Config) when is_list(Config) -> case ?config(local_server, Config) of ok -> tsp("http_redirect -> set ipfamily option to inet"), - ok = http:set_options([{ipfamily, inet}]), + ok = httpc:set_options([{ipfamily, inet}]), tsp("http_redirect -> start dummy server inet"), {DummyServerPid, Port} = dummy_server(self(), ipv4), @@ -949,29 +1070,29 @@ http_redirect(Config) when is_list(Config) -> tsp("http_redirect -> issue request 1: " "~n ~p", [URL300]), {ok, {{_,200,_}, [_ | _], [_|_]}} - = http:request(get, {URL300, []}, [], []), + = httpc:request(get, {URL300, []}, [], []), tsp("http_redirect -> issue request 2: " "~n ~p", [URL300]), {ok, {{_,300,_}, [_ | _], _}} = - http:request(get, {URL300, []}, [{autoredirect, false}], []), + httpc:request(get, {URL300, []}, [{autoredirect, false}], []), URL301 = ?URL_START ++ integer_to_list(Port) ++ "/301.html", tsp("http_redirect -> issue request 3: " "~n ~p", [URL301]), {ok, {{_,200,_}, [_ | _], [_|_]}} - = http:request(get, {URL301, []}, [], []), + = httpc:request(get, {URL301, []}, [], []), tsp("http_redirect -> issue request 4: " "~n ~p", [URL301]), {ok, {{_,200,_}, [_ | _], []}} - = http:request(head, {URL301, []}, [], []), + = httpc:request(head, {URL301, []}, [], []), tsp("http_redirect -> issue request 5: " "~n ~p", [URL301]), {ok, {{_,301,_}, [_ | _], [_|_]}} - = http:request(post, {URL301, [],"text/plain", "foobar"}, + = httpc:request(post, {URL301, [],"text/plain", "foobar"}, [], []), URL302 = ?URL_START ++ integer_to_list(Port) ++ "/302.html", @@ -979,8 +1100,8 @@ http_redirect(Config) when is_list(Config) -> tsp("http_redirect -> issue request 6: " "~n ~p", [URL302]), {ok, {{_,200,_}, [_ | _], [_|_]}} - = http:request(get, {URL302, []}, [], []), - case http:request(get, {URL302, []}, [], []) of + = httpc:request(get, {URL302, []}, [], []), + case httpc:request(get, {URL302, []}, [], []) of {ok, Reply7} -> case Reply7 of {{_,200,_}, [_ | _], [_|_]} -> @@ -1007,12 +1128,12 @@ http_redirect(Config) when is_list(Config) -> tsp("http_redirect -> issue request 7: " "~n ~p", [URL302]), {ok, {{_,200,_}, [_ | _], []}} - = http:request(head, {URL302, []}, [], []), + = httpc:request(head, {URL302, []}, [], []), tsp("http_redirect -> issue request 8: " "~n ~p", [URL302]), {ok, {{_,302,_}, [_ | _], [_|_]}} - = http:request(post, {URL302, [],"text/plain", "foobar"}, + = httpc:request(post, {URL302, [],"text/plain", "foobar"}, [], []), URL307 = ?URL_START ++ integer_to_list(Port) ++ "/307.html", @@ -1020,23 +1141,23 @@ http_redirect(Config) when is_list(Config) -> tsp("http_redirect -> issue request 9: " "~n ~p", [URL307]), {ok, {{_,200,_}, [_ | _], [_|_]}} - = http:request(get, {URL307, []}, [], []), + = httpc:request(get, {URL307, []}, [], []), tsp("http_redirect -> issue request 10: " "~n ~p", [URL307]), {ok, {{_,200,_}, [_ | _], []}} - = http:request(head, {URL307, []}, [], []), + = httpc:request(head, {URL307, []}, [], []), tsp("http_redirect -> issue request 11: " "~n ~p", [URL307]), {ok, {{_,307,_}, [_ | _], [_|_]}} - = http:request(post, {URL307, [],"text/plain", "foobar"}, + = httpc:request(post, {URL307, [],"text/plain", "foobar"}, [], []), tsp("http_redirect -> stop dummy server"), DummyServerPid ! stop, tsp("http_redirect -> reset ipfamily option (to inet6fb4)"), - ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* tsp("http_redirect -> done"), ok; @@ -1052,15 +1173,15 @@ http_redirect_loop(doc) -> http_redirect_loop(suite) -> []; http_redirect_loop(Config) when is_list(Config) -> - ok = http:set_options([{ipfamily, inet}]), + ok = httpc:set_options([{ipfamily, inet}]), {DummyServerPid, Port} = dummy_server(self(), ipv4), URL = ?URL_START ++ integer_to_list(Port) ++ "/redirectloop.html", {ok, {{_,300,_}, [_ | _], _}} - = http:request(get, {URL, []}, [], []), + = httpc:request(get, {URL, []}, [], []), DummyServerPid ! stop, - ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* ok. %%------------------------------------------------------------------------- @@ -1069,13 +1190,13 @@ http_internal_server_error(doc) -> http_internal_server_error(suite) -> []; http_internal_server_error(Config) when is_list(Config) -> - ok = http:set_options([{ipfamily, inet}]), + ok = httpc:set_options([{ipfamily, inet}]), {DummyServerPid, Port} = dummy_server(self(), ipv4), URL500 = ?URL_START ++ integer_to_list(Port) ++ "/500.html", {ok, {{_,500,_}, [_ | _], _}} - = http:request(get, {URL500, []}, [], []), + = httpc:request(get, {URL500, []}, [], []), URL503 = ?URL_START ++ integer_to_list(Port) ++ "/503.html", @@ -1085,16 +1206,16 @@ http_internal_server_error(Config) when is_list(Config) -> ets:insert(unavailable, {503, unavailable}), {ok, {{_,200, _}, [_ | _], [_|_]}} = - http:request(get, {URL503, []}, [], []), + httpc:request(get, {URL503, []}, [], []), ets:insert(unavailable, {503, long_unavailable}), {ok, {{_,503, _}, [_ | _], [_|_]}} = - http:request(get, {URL503, []}, [], []), + httpc:request(get, {URL503, []}, [], []), ets:delete(unavailable), DummyServerPid ! stop, - ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* ok. @@ -1104,7 +1225,7 @@ http_userinfo(doc) -> http_userinfo(suite) -> []; http_userinfo(Config) when is_list(Config) -> - ok = http:set_options([{ipfamily, inet}]), + ok = httpc:set_options([{ipfamily, inet}]), {DummyServerPid, Port} = dummy_server(self(), ipv4), @@ -1112,16 +1233,16 @@ http_userinfo(Config) when is_list(Config) -> ++ integer_to_list(Port) ++ "/userinfo.html", {ok, {{_,200,_}, [_ | _], _}} - = http:request(get, {URLAuth, []}, [], []), + = httpc:request(get, {URLAuth, []}, [], []), URLUnAuth = "http://alladin:foobar@localhost:" ++ integer_to_list(Port) ++ "/userinfo.html", {ok, {{_,401, _}, [_ | _], _}} = - http:request(get, {URLUnAuth, []}, [], []), + httpc:request(get, {URLUnAuth, []}, [], []), DummyServerPid ! stop, - ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* ok. @@ -1131,7 +1252,7 @@ http_cookie(doc) -> http_cookie(suite) -> []; http_cookie(Config) when is_list(Config) -> - ok = http:set_options([{cookies, enabled}, {ipfamily, inet}]), + ok = httpc:set_options([{cookies, enabled}, {ipfamily, inet}]), {DummyServerPid, Port} = dummy_server(self(), ipv4), URLStart = ?URL_START @@ -1140,19 +1261,19 @@ http_cookie(Config) when is_list(Config) -> URLCookie = URLStart ++ "/cookie.html", {ok, {{_,200,_}, [_ | _], [_|_]}} - = http:request(get, {URLCookie, []}, [], []), + = httpc:request(get, {URLCookie, []}, [], []), ets:new(cookie, [named_table, public, set]), ets:insert(cookie, {cookies, true}), {ok, {{_,200,_}, [_ | _], [_|_]}} - = http:request(get, {URLStart ++ "/", []}, [], []), + = httpc:request(get, {URLStart ++ "/", []}, [], []), ets:delete(cookie), - ok = http:set_options([{cookies, disabled}, {ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{cookies, disabled}, {ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* DummyServerPid ! stop, - ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6************ + ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6************ ok. %%------------------------------------------------------------------------- @@ -1163,7 +1284,7 @@ proxy_options(suite) -> proxy_options(Config) when is_list(Config) -> case ?config(skip, Config) of undefined -> - case http:request(options, {?PROXY_URL, []}, [], []) of + case httpc:request(options, {?PROXY_URL, []}, [], []) of {ok, {{_,200,_}, Headers, _}} -> case lists:keysearch("allow", 1, Headers) of {value, {"allow", _}} -> @@ -1187,7 +1308,7 @@ proxy_head(suite) -> proxy_head(Config) when is_list(Config) -> case ?config(skip, Config) of undefined -> - case http:request(head, {?PROXY_URL, []}, [], []) of + case httpc:request(head, {?PROXY_URL, []}, [], []) of {ok, {{_,200, _}, [_ | _], []}} -> ok; Unexpected -> @@ -1206,7 +1327,7 @@ proxy_get(suite) -> proxy_get(Config) when is_list(Config) -> case ?config(skip, Config) of undefined -> - case http:request(get, {?PROXY_URL, []}, [], []) of + case httpc:request(get, {?PROXY_URL, []}, [], []) of {ok, {{_,200,_}, [_ | _], Body = [_ | _]}} -> inets_test_lib:check_body(Body); Unexpected -> @@ -1258,7 +1379,7 @@ proxy_emulate_lower_versions(Config) when is_list(Config) -> end. pelv_get(Version) -> - http:request(get, {?PROXY_URL, []}, [{version, Version}], []). + httpc:request(get, {?PROXY_URL, []}, [{version, Version}], []). %%------------------------------------------------------------------------- proxy_trace(doc) -> @@ -1267,7 +1388,7 @@ proxy_trace(suite) -> []; proxy_trace(Config) when is_list(Config) -> %%{ok, {{_,200,_}, [_ | _], "TRACE " ++ _}} = - %% http:request(trace, {?PROXY_URL, []}, [], []), + %% httpc:request(trace, {?PROXY_URL, []}, [], []), {skip, "HTTP TRACE is no longer allowed on the ?PROXY_URL server due " "to security reasons"}. @@ -1282,7 +1403,7 @@ proxy_post(suite) -> proxy_post(Config) when is_list(Config) -> case ?config(skip, Config) of undefined -> - case http:request(post, {?PROXY_URL, [], + case httpc:request(post, {?PROXY_URL, [], "text/plain", "foobar"}, [],[]) of {ok, {{_,405,_}, [_ | _], [_ | _]}} -> ok; @@ -1304,7 +1425,7 @@ proxy_put(suite) -> proxy_put(Config) when is_list(Config) -> case ?config(skip, Config) of undefined -> - case http:request(put, {"http://www.erlang.org/foobar.html", [], + case httpc:request(put, {"http://www.erlang.org/foobar.html", [], "html", "<html> <body><h1> foo </h1>" "<p>bar</p> </body></html>"}, [], []) of {ok, {{_,405,_}, [_ | _], [_ | _]}} -> @@ -1329,7 +1450,7 @@ proxy_delete(Config) when is_list(Config) -> case ?config(skip, Config) of undefined -> URL = ?PROXY_URL ++ "/foobar.html", - case http:request(delete, {URL, []}, [], []) of + case httpc:request(delete, {URL, []}, [], []) of {ok, {{_,404,_}, [_ | _], [_ | _]}} -> ok; Unexpected -> @@ -1349,7 +1470,7 @@ proxy_headers(Config) when is_list(Config) -> case ?config(skip, Config) of undefined -> {ok, {{_,200,_}, [_ | _], [_ | _]}} - = http:request(get, {?PROXY_URL, + = httpc:request(get, {?PROXY_URL, [ {"Accept", "text/*, text/html," @@ -1384,7 +1505,7 @@ proxy_auth(Config) when is_list(Config) -> %% atleast the code for sending the header does not crash! case ?config(skip, Config) of undefined -> - case http:request(get, {?PROXY_URL, []}, + case httpc:request(get, {?PROXY_URL, []}, [{proxy_auth, {"foo", "bar"}}], []) of {ok, {{_,200, _}, [_ | _], [_|_]}} -> ok; @@ -1404,7 +1525,7 @@ http_server_does_not_exist(suite) -> []; http_server_does_not_exist(Config) when is_list(Config) -> {error, _} = - http:request(get, {"http://localhost:" ++ + httpc:request(get, {"http://localhost:" ++ integer_to_list(?NOT_IN_USE_PORT) ++ "/", []},[], []), ok. @@ -1419,7 +1540,7 @@ page_does_not_exist(Config) when is_list(Config) -> Port = ?config(local_port, Config), URL = ?URL_START ++ integer_to_list(Port) ++ "/doesnotexist.html", {ok, {{_,404,_}, [_ | _], [_ | _]}} - = http:request(get, {URL, []}, [], []), + = httpc:request(get, {URL, []}, [], []), ok. @@ -1433,7 +1554,7 @@ proxy_page_does_not_exist(Config) when is_list(Config) -> undefined -> URL = ?PROXY_URL ++ "/doesnotexist.html", {ok, {{_,404,_}, [_ | _], [_ | _]}} = - http:request(get, {URL, []}, [], []), + httpc:request(get, {URL, []}, [], []), ok; Reason -> {skip, Reason} @@ -1447,7 +1568,7 @@ proxy_https_not_supported(doc) -> proxy_https_not_supported(suite) -> []; proxy_https_not_supported(Config) when is_list(Config) -> - Result = http:request(get, {"https://login.yahoo.com", []}, [], []), + Result = httpc:request(get, {"https://login.yahoo.com", []}, [], []), case Result of {error, Reason} -> %% ok so far @@ -1479,10 +1600,10 @@ http_stream(Config) when is_list(Config) -> Port = ?config(local_port, Config), URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html", {ok, {{_,200,_}, [_ | _], Body}} = - http:request(get, {URL, []}, [], []), + httpc:request(get, {URL, []}, [], []), {ok, RequestId} = - http:request(get, {URL, []}, [], [{sync, false}, + httpc:request(get, {URL, []}, [], [{sync, false}, {stream, self}]), receive @@ -1507,7 +1628,7 @@ http_stream_once(Config) when is_list(Config) -> "~n Config: ~p", [Config]), p("http_stream_once -> set ipfamily to inet", []), - ok = http:set_options([{ipfamily, inet}]), + ok = httpc:set_options([{ipfamily, inet}]), p("http_stream_once -> start dummy server", []), {DummyServerPid, Port} = dummy_server(self(), ipv4), @@ -1522,18 +1643,18 @@ http_stream_once(Config) when is_list(Config) -> p("http_stream_once -> stop dummy server", []), DummyServerPid ! stop, p("http_stream_once -> set ipfamily to inet6fb4", []), - ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* p("http_stream_once -> done", []), ok. once(URL) -> p("once -> issue sync request for ~p", [URL]), {ok, {{_,200,_}, [_ | _], Body}} = - http:request(get, {URL, []}, [], []), + httpc:request(get, {URL, []}, [], []), p("once -> issue async (self stream) request for ~p", [URL]), {ok, RequestId} = - http:request(get, {URL, []}, [], [{sync, false}, + httpc:request(get, {URL, []}, [], [{sync, false}, {stream, {self, once}}]), p("once -> await stream_start reply for (async) request ~p", [RequestId]), @@ -1577,10 +1698,10 @@ proxy_stream(Config) when is_list(Config) -> case ?config(skip, Config) of undefined -> {ok, {{_,200,_}, [_ | _], Body}} = - http:request(get, {?PROXY_URL, []}, [], []), + httpc:request(get, {?PROXY_URL, []}, [], []), {ok, RequestId} = - http:request(get, {?PROXY_URL, []}, [], + httpc:request(get, {?PROXY_URL, []}, [], [{sync, false}, {stream, self}]), receive @@ -1660,7 +1781,7 @@ ipv6(Config) when is_list(Config) -> URL = "http://[" ++ ?IPV6_LOCAL_HOST ++ "]:" ++ integer_to_list(Port) ++ "/foobar.html", {ok, {{_,200,_}, [_ | _], [_|_]}} = - http:request(get, {URL, []}, [], []), + httpc:request(get, {URL, []}, [], []), DummyServerPid ! stop, ok; @@ -1678,11 +1799,11 @@ headers_as_is(Config) when is_list(Config) -> Port = ?config(local_port, Config), URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html", {ok, {{_,200,_}, [_|_], [_|_]}} = - http:request(get, {URL, [{"Host", "localhost"},{"Te", ""}]}, + httpc:request(get, {URL, [{"Host", "localhost"},{"Te", ""}]}, [], [{headers_as_is, true}]), {ok, {{_,400,_}, [_|_], [_|_]}} = - http:request(get, {URL, [{"Te", ""}]},[], [{headers_as_is, true}]), + httpc:request(get, {URL, [{"Te", ""}]},[], [{headers_as_is, true}]), ok. @@ -1697,13 +1818,13 @@ options(Config) when is_list(Config) -> Port = ?config(local_port, Config), URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html", {ok, {{_,200,_}, [_ | _], Bin}} - = http:request(get, {URL, []}, [{foo, bar}], + = httpc:request(get, {URL, []}, [{foo, bar}], %% Ignore unknown options [{body_format, binary}, {foo, bar}]), true = is_binary(Bin), {ok, {200, [_|_]}} - = http:request(get, {URL, []}, [{timeout, infinity}], + = httpc:request(get, {URL, []}, [{timeout, infinity}], [{full_result, false}]); _ -> {skip, "Failed to start local http-server"} @@ -1716,17 +1837,17 @@ http_invalid_http(doc) -> http_invalid_http(suite) -> []; http_invalid_http(Config) when is_list(Config) -> - ok = http:set_options([{ipfamily, inet}]), + ok = httpc:set_options([{ipfamily, inet}]), {DummyServerPid, Port} = dummy_server(self(), ipv4), URL = ?URL_START ++ integer_to_list(Port) ++ "/invalid_http.html", {error, {could_not_parse_as_http, _} = Reason} = - http:request(get, {URL, []}, [], []), + httpc:request(get, {URL, []}, [], []), test_server:format("Parse error: ~p ~n", [Reason]), DummyServerPid ! stop, - ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* ok. @@ -1763,7 +1884,7 @@ empty_body_otp_6243(Config) when is_list(Config) -> Port = ?config(local_port, Config), URL = ?URL_START ++ integer_to_list(Port) ++ "/empty.html", {ok, {{_,200,_}, [_ | _], []}} = - http:request(get, {URL, []}, [{timeout, 500}], []). + httpc:request(get, {URL, []}, [{timeout, 500}], []). %%------------------------------------------------------------------------- @@ -1773,14 +1894,14 @@ transfer_encoding_otp_6807(doc) -> transfer_encoding_otp_6807(suite) -> []; transfer_encoding_otp_6807(Config) when is_list(Config) -> - ok = http:set_options([{ipfamily, inet}]), + ok = httpc:set_options([{ipfamily, inet}]), {DummyServerPid, Port} = dummy_server(self(), ipv4), URL = ?URL_START ++ integer_to_list(Port) ++ "/capital_transfer_encoding.html", - {ok, {{_,200,_}, [_|_], [_ | _]}} = http:request(URL), + {ok, {{_,200,_}, [_|_], [_ | _]}} = httpc:request(URL), DummyServerPid ! stop, - ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* ok. @@ -1806,13 +1927,13 @@ empty_response_header_otp_6830(doc) -> empty_response_header_otp_6830(suite) -> []; empty_response_header_otp_6830(Config) when is_list(Config) -> - ok = http:set_options([{ipfamily, inet}]), + ok = httpc:set_options([{ipfamily, inet}]), {DummyServerPid, Port} = dummy_server(self(), ipv4), URL = ?URL_START ++ integer_to_list(Port) ++ "/no_headers.html", - {ok, {{_,200,_}, [], [_ | _]}} = http:request(URL), + {ok, {{_,200,_}, [], [_ | _]}} = httpc:request(URL), DummyServerPid ! stop, - ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* ok. @@ -1823,13 +1944,13 @@ no_content_204_otp_6982(doc) -> no_content_204_otp_6982(suite) -> []; no_content_204_otp_6982(Config) when is_list(Config) -> - ok = http:set_options([{ipfamily, inet}]), + ok = httpc:set_options([{ipfamily, inet}]), {DummyServerPid, Port} = dummy_server(self(), ipv4), URL = ?URL_START ++ integer_to_list(Port) ++ "/no_content.html", - {ok, {{_,204,_}, [], []}} = http:request(URL), + {ok, {{_,204,_}, [], []}} = httpc:request(URL), DummyServerPid ! stop, - ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* ok. @@ -1841,13 +1962,13 @@ missing_CR_otp_7304(doc) -> missing_CR_otp_7304(suite) -> []; missing_CR_otp_7304(Config) when is_list(Config) -> - ok = http:set_options([{ipfamily, inet}]), + ok = httpc:set_options([{ipfamily, inet}]), {DummyServerPid, Port} = dummy_server(self(), ipv4), URL = ?URL_START ++ integer_to_list(Port) ++ "/missing_CR.html", - {ok, {{_,200,_}, _, [_ | _]}} = http:request(URL), + {ok, {{_,200,_}, _, [_ | _]}} = httpc:request(URL), DummyServerPid ! stop, - ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* ok. @@ -1861,15 +1982,15 @@ otp_7883_1(doc) -> otp_7883_1(suite) -> []; otp_7883_1(Config) when is_list(Config) -> - ok = http:set_options([{ipfamily, inet}]), + ok = httpc:set_options([{ipfamily, inet}]), {DummyServerPid, Port} = dummy_server(self(), ipv4), URL = ?URL_START ++ integer_to_list(Port) ++ "/just_close.html", - {error, socket_closed_remotely} = http:request(URL), + {error, socket_closed_remotely} = httpc:request(URL), DummyServerPid ! stop, - ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* ok. otp_7883_2(doc) -> @@ -1877,7 +1998,7 @@ otp_7883_2(doc) -> otp_7883_2(suite) -> []; otp_7883_2(Config) when is_list(Config) -> - ok = http:set_options([{ipfamily, inet}]), + ok = httpc:set_options([{ipfamily, inet}]), {DummyServerPid, Port} = dummy_server(self(), ipv4), @@ -1886,9 +2007,9 @@ otp_7883_2(Config) when is_list(Config) -> Request = {URL, []}, HttpOptions = [], Options = [{sync, false}], - Profile = http:default_profile(), + Profile = httpc:default_profile(), {ok, RequestId} = - http:request(Method, Request, HttpOptions, Options, Profile), + httpc:request(Method, Request, HttpOptions, Options, Profile), ok = receive {http, {RequestId, {error, socket_closed_remotely}}} -> @@ -1896,7 +2017,7 @@ otp_7883_2(Config) when is_list(Config) -> end, DummyServerPid ! stop, - ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* ok. @@ -1967,7 +2088,7 @@ run_clients(NumClients, ServerPort, SeqNumServer) -> fun() -> io:format("[~w] client started - " "issue request~n", [Id]), - case http:request(Url) of + case httpc:request(Url) of {ok, {{_,200,_}, _, Resp}} -> io:format("[~w] 200 response: " "~p~n", [Id, Resp]), @@ -2355,7 +2476,7 @@ otp_8352(Config) when is_list(Config) -> ConnOptions = [{max_sessions, MaxSessions}, {max_keep_alive_length, MaxKeepAlive}, {keep_alive_timeout, KeepAliveTimeout}], - http:set_options(ConnOptions), + httpc:set_options(ConnOptions), Method = get, Port = ?config(local_port, Config), @@ -2367,9 +2488,9 @@ otp_8352(Config) when is_list(Config) -> Options1 = [{socket_opts, [{tos, 87}, {recbuf, 16#FFFF}, {sndbuf, 16#FFFF}]}], - case http:request(Method, Request, HttpOptions1, Options1) of + case httpc:request(Method, Request, HttpOptions1, Options1) of {ok, {{_,200,_}, [_ | _], ReplyBody1 = [_ | _]}} -> - %% equivaliant to http:request(get, {URL, []}, [], []), + %% equivaliant to httpc:request(get, {URL, []}, [], []), inets_test_lib:check_body(ReplyBody1); {ok, UnexpectedReply1} -> tsf({unexpected_reply, UnexpectedReply1}); @@ -2383,9 +2504,9 @@ otp_8352(Config) when is_list(Config) -> Options2 = [{socket_opts, [{tos, 84}, {recbuf, 32#1FFFF}, {sndbuf, 32#1FFFF}]}], - case http:request(Method, Request, HttpOptions2, Options2) of + case httpc:request(Method, Request, HttpOptions2, Options2) of {ok, {{_,200,_}, [_ | _], ReplyBody2 = [_ | _]}} -> - %% equivaliant to http:request(get, {URL, []}, [], []), + %% equivaliant to httpc:request(get, {URL, []}, [], []), inets_test_lib:check_body(ReplyBody2); {ok, UnexpectedReply2} -> tsf({unexpected_reply, UnexpectedReply2}); @@ -2407,13 +2528,13 @@ otp_8371(doc) -> otp_8371(suite) -> []; otp_8371(Config) when is_list(Config) -> - ok = http:set_options([{ipv6, disabled}]), % also test the old option + ok = httpc:set_options([{ipv6, disabled}]), % also test the old option {DummyServerPid, Port} = dummy_server(self(), ipv4), URL = ?URL_START ++ integer_to_list(Port) ++ "/ensure_host_header_with_port.html", - case http:request(get, {URL, []}, [], []) of + case httpc:request(get, {URL, []}, [], []) of {ok, Result} -> case Result of {{_, 200, _}, _Headers, Body} -> @@ -2437,7 +2558,7 @@ otp_8371(Config) when is_list(Config) -> end, DummyServerPid ! stop, - ok = http:set_options([{ipv6, enabled}]), + ok = httpc:set_options([{ipv6, enabled}]), ok. @@ -2609,7 +2730,7 @@ receive_streamed_body(RequestId, Body) -> end. receive_streamed_body(RequestId, Body, Pid) -> - http:stream_next(Pid), + httpc:stream_next(Pid), test_server:format("~p:receive_streamed_body -> requested next stream ~n", [?MODULE]), receive {http, {RequestId, stream, BinBodyPart}} -> @@ -2993,11 +3114,11 @@ provocate_not_modified_bug(Url) -> Timeout = 15000, %% 15s should be plenty {ok, {{_, 200, _}, ReplyHeaders, _Body}} = - http:request(get, {Url, []}, [{timeout, Timeout}], []), + httpc:request(get, {Url, []}, [{timeout, Timeout}], []), Etag = pick_header(ReplyHeaders, "ETag"), Last = pick_header(ReplyHeaders, "last-modified"), - case http:request(get, {Url, [{"If-None-Match", Etag}, + case httpc:request(get, {Url, [{"If-None-Match", Etag}, {"If-Modified-Since", Last}]}, [{timeout, 15000}], []) of diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl index 7403d4a643..3255cbec06 100644 --- a/lib/inets/test/httpd_SUITE.erl +++ b/lib/inets/test/httpd_SUITE.erl @@ -32,44 +32,176 @@ init_per_suite/1, end_per_suite/1]). %% Test cases must be exported. --export([ip/1, ssl/1, http_1_1_ip/1, http_1_0_ip/1, http_0_9_ip/1, - ipv6/1, tickets/1]). +-export([ + ip/1, + ssl/1, pssl/1, ossl/1, essl/1, + http_1_1_ip/1, + http_1_0_ip/1, + http_0_9_ip/1, + ipv6/1, + tickets/1 + ]). %% Core Server tests --export([ip_mod_alias/1, ip_mod_actions/1, ip_mod_security/1, ip_mod_auth/1, - ip_mod_auth_api/1, ip_mod_auth_mnesia_api/1, - ip_mod_htaccess/1, ip_mod_cgi/1, ip_mod_esi/1, - ip_mod_get/1, ip_mod_head/1, ip_mod_all/1, ip_load_light/1, - ip_load_medium/1, ip_load_heavy/1, ip_dos_hostname/1, - ip_time_test/1, ip_block_disturbing_idle/1, - ip_block_non_disturbing_idle/1, ip_block_503/1, - ip_block_disturbing_active/1, ip_block_non_disturbing_active/1, +-export([ + ip_mod_alias/1, + ip_mod_actions/1, + ip_mod_security/1, + ip_mod_auth/1, + ip_mod_auth_api/1, + ip_mod_auth_mnesia_api/1, + ip_mod_htaccess/1, + ip_mod_cgi/1, + ip_mod_esi/1, + ip_mod_get/1, + ip_mod_head/1, + ip_mod_all/1, + ip_load_light/1, + ip_load_medium/1, + ip_load_heavy/1, + ip_dos_hostname/1, + ip_time_test/1, + ip_block_disturbing_idle/1, + ip_block_non_disturbing_idle/1, + ip_block_503/1, + ip_block_disturbing_active/1, + ip_block_non_disturbing_active/1, ip_block_disturbing_active_timeout_not_released/1, ip_block_disturbing_active_timeout_released/1, ip_block_non_disturbing_active_timeout_not_released/1, ip_block_non_disturbing_active_timeout_released/1, ip_block_disturbing_blocker_dies/1, ip_block_non_disturbing_blocker_dies/1, - ip_restart_no_block/1, ip_restart_disturbing_block/1, + ip_restart_no_block/1, + ip_restart_disturbing_block/1, ip_restart_non_disturbing_block/1 ]). --export([ssl_mod_alias/1, ssl_mod_actions/1, ssl_mod_security/1, - ssl_mod_auth/1, ssl_mod_auth_api/1, - ssl_mod_auth_mnesia_api/1, ssl_mod_htaccess/1, - ssl_mod_cgi/1, ssl_mod_esi/1, ssl_mod_get/1, ssl_mod_head/1, - ssl_mod_all/1, ssl_load_light/1, ssl_load_medium/1, - ssl_load_heavy/1, ssl_dos_hostname/1, ssl_time_test/1, - ssl_restart_no_block/1, ssl_restart_disturbing_block/1, - ssl_restart_non_disturbing_block/1, ssl_block_disturbing_idle/1, - ssl_block_non_disturbing_idle/1, ssl_block_503/1, - ssl_block_disturbing_active/1, ssl_block_non_disturbing_active/1, - ssl_block_disturbing_active_timeout_not_released/1, - ssl_block_disturbing_active_timeout_released/1, - ssl_block_non_disturbing_active_timeout_not_released/1, - ssl_block_non_disturbing_active_timeout_released/1, - ssl_block_disturbing_blocker_dies/1, - ssl_block_non_disturbing_blocker_dies/1]). +-export([ + pssl_mod_alias/1, + ossl_mod_alias/1, + essl_mod_alias/1, + + pssl_mod_actions/1, + ossl_mod_actions/1, + essl_mod_actions/1, + + pssl_mod_security/1, + ossl_mod_security/1, + essl_mod_security/1, + + pssl_mod_auth/1, + ossl_mod_auth/1, + essl_mod_auth/1, + + pssl_mod_auth_api/1, + ossl_mod_auth_api/1, + essl_mod_auth_api/1, + + pssl_mod_auth_mnesia_api/1, + ossl_mod_auth_mnesia_api/1, + essl_mod_auth_mnesia_api/1, + + pssl_mod_htaccess/1, + ossl_mod_htaccess/1, + essl_mod_htaccess/1, + + pssl_mod_cgi/1, + ossl_mod_cgi/1, + essl_mod_cgi/1, + + pssl_mod_esi/1, + ossl_mod_esi/1, + essl_mod_esi/1, + + pssl_mod_get/1, + ossl_mod_get/1, + essl_mod_get/1, + + pssl_mod_head/1, + ossl_mod_head/1, + essl_mod_head/1, + + pssl_mod_all/1, + ossl_mod_all/1, + essl_mod_all/1, + + pssl_load_light/1, + ossl_load_light/1, + essl_load_light/1, + + pssl_load_medium/1, + ossl_load_medium/1, + essl_load_medium/1, + + pssl_load_heavy/1, + ossl_load_heavy/1, + essl_load_heavy/1, + + pssl_dos_hostname/1, + ossl_dos_hostname/1, + essl_dos_hostname/1, + + pssl_time_test/1, + ossl_time_test/1, + essl_time_test/1, + + pssl_restart_no_block/1, + ossl_restart_no_block/1, + essl_restart_no_block/1, + + pssl_restart_disturbing_block/1, + ossl_restart_disturbing_block/1, + essl_restart_disturbing_block/1, + + pssl_restart_non_disturbing_block/1, + ossl_restart_non_disturbing_block/1, + essl_restart_non_disturbing_block/1, + + pssl_block_disturbing_idle/1, + ossl_block_disturbing_idle/1, + essl_block_disturbing_idle/1, + + pssl_block_non_disturbing_idle/1, + ossl_block_non_disturbing_idle/1, + essl_block_non_disturbing_idle/1, + + pssl_block_503/1, + ossl_block_503/1, + essl_block_503/1, + + pssl_block_disturbing_active/1, + ossl_block_disturbing_active/1, + essl_block_disturbing_active/1, + + pssl_block_non_disturbing_active/1, + ossl_block_non_disturbing_active/1, + essl_block_non_disturbing_active/1, + + pssl_block_disturbing_active_timeout_not_released/1, + ossl_block_disturbing_active_timeout_not_released/1, + essl_block_disturbing_active_timeout_not_released/1, + + pssl_block_disturbing_active_timeout_released/1, + ossl_block_disturbing_active_timeout_released/1, + essl_block_disturbing_active_timeout_released/1, + + pssl_block_non_disturbing_active_timeout_not_released/1, + ossl_block_non_disturbing_active_timeout_not_released/1, + essl_block_non_disturbing_active_timeout_not_released/1, + + pssl_block_non_disturbing_active_timeout_released/1, + ossl_block_non_disturbing_active_timeout_released/1, + essl_block_non_disturbing_active_timeout_released/1, + + pssl_block_disturbing_blocker_dies/1, + ossl_block_disturbing_blocker_dies/1, + essl_block_disturbing_blocker_dies/1, + + pssl_block_non_disturbing_blocker_dies/1, + ossl_block_non_disturbing_blocker_dies/1, + essl_block_non_disturbing_blocker_dies/1 + ]). %%% HTTP 1.1 tests -export([ip_host/1, ip_chunked/1, ip_expect/1, ip_range/1, @@ -103,8 +235,8 @@ %% Seconds before successful auths timeout. -define(AUTH_TIMEOUT,5). --record(httpd_user, {user_name, password, user_data}). --record(httpd_group,{group_name, userlist}). +-record(httpd_user, {user_name, password, user_data}). +-record(httpd_group, {group_name, userlist}). %%-------------------------------------------------------------------- @@ -197,9 +329,9 @@ init_per_testcase2(Case, Config) -> "~n Config: ~p" "~n", [?MODULE, Case, Config]), - IpNormal = integer_to_list(?IP_PORT) ++ ".conf", - IpHtacess = integer_to_list(?IP_PORT) ++ "htacess.conf", - SslNormal = integer_to_list(?SSL_PORT) ++ ".conf", + IpNormal = integer_to_list(?IP_PORT) ++ ".conf", + IpHtacess = integer_to_list(?IP_PORT) ++ "htacess.conf", + SslNormal = integer_to_list(?SSL_PORT) ++ ".conf", SslHtacess = integer_to_list(?SSL_PORT) ++ "htacess.conf", DataDir = ?config(data_dir, Config), @@ -210,8 +342,8 @@ init_per_testcase2(Case, Config) -> "~n DataDir: ~p" "~n", [?MODULE, Case, SuiteTopDir, DataDir]), - TcTopDir = filename:join(SuiteTopDir, Case), - ?line ok = file:make_dir(TcTopDir), + TcTopDir = filename:join(SuiteTopDir, Case), + ?line ok = file:make_dir(TcTopDir), io:format(user, "~w:init_per_testcase2(~w) -> " "~n TcTopDir: ~p" @@ -267,9 +399,21 @@ init_per_testcase2(Case, Config) -> %% To be used by SSL test cases io:format(user, "~w:init_per_testcase2(~w) -> ssl testcase setups~n", [?MODULE, Case]), - create_config([{port, ?SSL_PORT}, {sock_type, ssl} | NewConfig], + SocketType = + case atom_to_list(Case) of + [X, $s, $s, $l | _] -> + case X of + $p -> ssl; + $o -> ossl; + $e -> essl + end; + _ -> + ssl + end, + + create_config([{port, ?SSL_PORT}, {sock_type, SocketType} | NewConfig], normal_acess, SslNormal), - create_config([{port, ?SSL_PORT}, {sock_type, ssl} | NewConfig], + create_config([{port, ?SSL_PORT}, {sock_type, SocketType} | NewConfig], mod_htaccess, SslHtacess), %% To be used by IPv6 test cases. Case-clause is so that @@ -300,8 +444,14 @@ init_per_testcase3(Case, Config) -> io:format(user, "~w:init_per_testcase3(~w) -> entry with" "~n Config: ~p", [?MODULE, Case, Config]), + +%% %% Create a new fresh node to be used by the server in this test-case + +%% NodeName = list_to_atom(atom_to_list(Case) ++ "_httpd"), +%% Node = inets_test_lib:start_node(NodeName), + %% Clean up (we do not want this clean up in end_per_testcase - %% if init_per_testcase crases for some testcase it will + %% if init_per_testcase crashes for some testcase it will %% have contaminated the environment and there will be no clean up.) %% This init can take a few different paths so that one crashes %% does not mean that all invocations will. @@ -310,15 +460,26 @@ init_per_testcase3(Case, Config) -> application:stop(inets), application:stop(ssl), cleanup_mnesia(), - - %% TraceLevel = max, - TraceLevel = 70, - TraceDest = io, - inets:enable_trace(TraceLevel, TraceDest), + %% Set trace + case lists:reverse(atom_to_list(Case)) of + "tset_emit" ++ _Rest -> % test-cases ending with time_test + io:format(user, "~w:init_per_testcase3(~w) -> disabling trace", + [?MODULE, Case]), + inets:disable_trace(); + _ -> + %% TraceLevel = max, + io:format(user, "~w:init_per_testcase3(~w) -> enabling trace", + [?MODULE, Case]), + TraceLevel = 70, + TraceDest = io, + inets:enable_trace(TraceLevel, TraceDest, httpd) + end, + %% Start initialization io:format(user, "~w:init_per_testcase3(~w) -> start init", [?MODULE, Case]), + Dog = test_server:timetrap(inets_test_lib:minutes(10)), NewConfig = lists:keydelete(watchdog, 1, Config), @@ -351,22 +512,35 @@ init_per_testcase3(Case, Config) -> filename:join(TcTopDir, integer_to_list(?IP_PORT) ++ ".conf")}]), Rest; - "ssl_mod_htaccess" -> + + [X, $s, $s, $l, $_, $m, $o, $d, $_, $h, $t, $a, $c, $c, $e, $s, $s] -> + SslTag = + case X of + $p -> ssl; % plain + $o -> ossl; % OpenSSL based ssl + $e -> essl % Erlang based ssl + end, case inets_test_lib:start_http_server_ssl( filename:join(TcTopDir, integer_to_list(?SSL_PORT) ++ - "htacess.conf")) of + "htacess.conf"), SslTag) of ok -> "mod_htaccess"; Other -> error_logger:info_report("Other: ~p~n", [Other]), {skip, "SSL does not seem to be supported"} end; - "ssl_" ++ Rest -> + [X, $s, $s, $l, $_ | Rest] -> + SslTag = + case X of + $p -> ssl; + $o -> ossl; + $e -> essl + end, case inets_test_lib:start_http_server_ssl( filename:join(TcTopDir, integer_to_list(?SSL_PORT) ++ - ".conf")) of + ".conf"), SslTag) of ok -> Rest; Other -> @@ -431,6 +605,7 @@ end_per_testcase2(Case, Config) -> application:unset_env(inets, services), application:stop(inets), application:stop(ssl), + application:stop(crypto), % used by the new ssl (essl test cases) cleanup_mnesia(), io:format(user, "~w:end_per_testcase2(~w) -> done~n", [?MODULE, Case]), @@ -461,6 +636,9 @@ ip(suite) -> ip_load_heavy, ip_dos_hostname, ip_time_test, + ip_restart_no_block, + ip_restart_disturbing_block, + ip_restart_non_disturbing_block, ip_block_disturbing_idle, ip_block_non_disturbing_idle, ip_block_503, @@ -471,10 +649,7 @@ ip(suite) -> ip_block_non_disturbing_active_timeout_not_released, ip_block_non_disturbing_active_timeout_released, ip_block_disturbing_blocker_dies, - ip_block_non_disturbing_blocker_dies, - ip_restart_no_block, - ip_restart_disturbing_block, - ip_restart_non_disturbing_block + ip_block_non_disturbing_blocker_dies ]. %%------------------------------------------------------------------------- @@ -482,39 +657,124 @@ ssl(doc) -> ["HTTP test using SSL"]; ssl(suite) -> [ - ssl_mod_alias, - ssl_mod_actions, - ssl_mod_security, - ssl_mod_auth, - ssl_mod_auth_api, - ssl_mod_auth_mnesia_api, - ssl_mod_htaccess, - ssl_mod_cgi, - ssl_mod_esi, - ssl_mod_get, - ssl_mod_head, - ssl_mod_all, - ssl_load_light, - ssl_load_medium, - ssl_load_heavy, - ssl_dos_hostname, - ssl_time_test, - ssl_restart_no_block, - ssl_restart_disturbing_block, - ssl_restart_non_disturbing_block, - ssl_block_disturbing_idle, - ssl_block_non_disturbing_idle, - ssl_block_503, - ssl_block_disturbing_active, - ssl_block_non_disturbing_active, - ssl_block_disturbing_active_timeout_not_released, - ssl_block_disturbing_active_timeout_released, - ssl_block_non_disturbing_active_timeout_not_released, - ssl_block_non_disturbing_active_timeout_released, - ssl_block_disturbing_blocker_dies, - ssl_block_non_disturbing_blocker_dies + pssl, + ossl, + essl ]. + +pssl(doc) -> + ["HTTP test using SSL - using old way of configuring SSL"]; +pssl(suite) -> + [ + pssl_mod_alias, + pssl_mod_actions, + pssl_mod_security, + pssl_mod_auth, + pssl_mod_auth_api, + pssl_mod_auth_mnesia_api, + pssl_mod_htaccess, + pssl_mod_cgi, + pssl_mod_esi, + pssl_mod_get, + pssl_mod_head, + pssl_mod_all, + pssl_load_light, + pssl_load_medium, + pssl_load_heavy, + pssl_dos_hostname, + pssl_time_test, + pssl_restart_no_block, + pssl_restart_disturbing_block, + pssl_restart_non_disturbing_block, + pssl_block_disturbing_idle, + pssl_block_non_disturbing_idle, + pssl_block_503, + pssl_block_disturbing_active, + pssl_block_non_disturbing_active, + pssl_block_disturbing_active_timeout_not_released, + pssl_block_disturbing_active_timeout_released, + pssl_block_non_disturbing_active_timeout_not_released, + pssl_block_non_disturbing_active_timeout_released, + pssl_block_disturbing_blocker_dies, + pssl_block_non_disturbing_blocker_dies + ]. + +ossl(doc) -> + ["HTTP test using SSL - using new way of configuring usage of old SSL"]; +ossl(suite) -> + [ + ossl_mod_alias, + ossl_mod_actions, + ossl_mod_security, + ossl_mod_auth, + ossl_mod_auth_api, + ossl_mod_auth_mnesia_api, + ossl_mod_htaccess, + ossl_mod_cgi, + ossl_mod_esi, + ossl_mod_get, + ossl_mod_head, + ossl_mod_all, + ossl_load_light, + ossl_load_medium, + ossl_load_heavy, + ossl_dos_hostname, + ossl_time_test, + ossl_restart_no_block, + ossl_restart_disturbing_block, + ossl_restart_non_disturbing_block, + ossl_block_disturbing_idle, + ossl_block_non_disturbing_idle, + ossl_block_503, + ossl_block_disturbing_active, + ossl_block_non_disturbing_active, + ossl_block_disturbing_active_timeout_not_released, + ossl_block_disturbing_active_timeout_released, + ossl_block_non_disturbing_active_timeout_not_released, + ossl_block_non_disturbing_active_timeout_released, + ossl_block_disturbing_blocker_dies, + ossl_block_non_disturbing_blocker_dies + ]. + +essl(doc) -> + ["HTTP test using SSL - using new way of configuring usage of new SSL"]; +essl(suite) -> + [ + essl_mod_alias, + essl_mod_actions, + essl_mod_security, + essl_mod_auth, + essl_mod_auth_api, + essl_mod_auth_mnesia_api, + essl_mod_htaccess, + essl_mod_cgi, + essl_mod_esi, + essl_mod_get, + essl_mod_head, + essl_mod_all, + essl_load_light, + essl_load_medium, + essl_load_heavy, + essl_dos_hostname, + essl_time_test, + essl_restart_no_block, + essl_restart_disturbing_block, + essl_restart_non_disturbing_block, + essl_block_disturbing_idle, + essl_block_non_disturbing_idle, + essl_block_503, + essl_block_disturbing_active, + essl_block_non_disturbing_active, + essl_block_disturbing_active_timeout_not_released, + essl_block_disturbing_active_timeout_released, + essl_block_non_disturbing_active_timeout_not_released, + essl_block_non_disturbing_active_timeout_released, + essl_block_disturbing_blocker_dies, + essl_block_non_disturbing_blocker_dies + ]. + + %%------------------------------------------------------------------------- http_1_1_ip(doc) -> ["HTTP/1.1"]; @@ -721,6 +981,8 @@ ip_load_heavy(Config) when is_list(Config) -> ?config(node, Config), get_nof_clients(ip_comm, heavy)), ok. + + %%------------------------------------------------------------------------- ip_dos_hostname(doc) -> ["Denial Of Service (DOS) attack test case"]; @@ -730,6 +992,8 @@ ip_dos_hostname(Config) when is_list(Config) -> dos_hostname(ip_comm, ?IP_PORT, ?config(host, Config), ?config(node, Config), ?MAX_HEADER_SIZE), ok. + + %%------------------------------------------------------------------------- ip_time_test(doc) -> [""]; @@ -966,363 +1230,1072 @@ ip_restart_non_disturbing_block(Config) when is_list(Config) -> ok. %%------------------------------------------------------------------------- -ssl_mod_alias(doc) -> - ["Module test: mod_alias"]; -ssl_mod_alias(suite) -> + +pssl_mod_alias(doc) -> + ["Module test: mod_alias - old SSL config"]; +pssl_mod_alias(suite) -> + []; +pssl_mod_alias(Config) when is_list(Config) -> + ssl_mod_alias(ssl, Config). + +ossl_mod_alias(doc) -> + ["Module test: mod_alias - using new of configure old SSL"]; +ossl_mod_alias(suite) -> + []; +ossl_mod_alias(Config) when is_list(Config) -> + ssl_mod_alias(ossl, Config). + +essl_mod_alias(doc) -> + ["Module test: mod_alias - using new of configure new SSL"]; +essl_mod_alias(suite) -> []; -ssl_mod_alias(Config) when is_list(Config) -> - httpd_mod:alias(ssl, ?SSL_PORT, +essl_mod_alias(Config) when is_list(Config) -> + ssl_mod_alias(essl, Config). + + +ssl_mod_alias(Tag, Config) -> + httpd_mod:alias(Tag, ?SSL_PORT, ?config(host, Config), ?config(node, Config)), ok. + + %%------------------------------------------------------------------------- -ssl_mod_actions(doc) -> - ["Module test: mod_actions"]; -ssl_mod_actions(suite) -> + +pssl_mod_actions(doc) -> + ["Module test: mod_actions - old SSL config"]; +pssl_mod_actions(suite) -> []; -ssl_mod_actions(Config) when is_list(Config) -> - httpd_mod:actions(ssl, ?SSL_PORT, - ?config(host, Config), ?config(node, Config)), +pssl_mod_actions(Config) when is_list(Config) -> + ssl_mod_actions(ssl, Config). + +ossl_mod_actions(doc) -> + ["Module test: mod_actions - using new of configure old SSL"]; +ossl_mod_actions(suite) -> + []; +ossl_mod_actions(Config) when is_list(Config) -> + ssl_mod_actions(ossl, Config). + +essl_mod_actions(doc) -> + ["Module test: mod_actions - using new of configure new SSL"]; +essl_mod_actions(suite) -> + []; +essl_mod_actions(Config) when is_list(Config) -> + ssl_mod_actions(essl, Config). + + +ssl_mod_actions(Tag, Config) -> + httpd_mod:actions(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), ok. + + %%------------------------------------------------------------------------- -ssl_mod_security(doc) -> - ["Module test: mod_security"]; -ssl_mod_security(suite) -> + +pssl_mod_security(doc) -> + ["Module test: mod_security - old SSL config"]; +pssl_mod_security(suite) -> []; -ssl_mod_security(Config) when is_list(Config) -> +pssl_mod_security(Config) when is_list(Config) -> + ssl_mod_security(ssl, Config). + +ossl_mod_security(doc) -> + ["Module test: mod_security - using new of configure old SSL"]; +ossl_mod_security(suite) -> + []; +ossl_mod_security(Config) when is_list(Config) -> + ssl_mod_security(ossl, Config). + +essl_mod_security(doc) -> + ["Module test: mod_security - using new of configure new SSL"]; +essl_mod_security(suite) -> + []; +essl_mod_security(Config) when is_list(Config) -> + ssl_mod_security(essl, Config). + +ssl_mod_security(Tag, Config) -> ServerRoot = ?config(server_root, Config), - httpd_mod:security(ServerRoot, ssl, ?SSL_PORT, - ?config(host, Config), ?config(node, Config)), + httpd_mod:security(ServerRoot, + Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), ok. + + %%------------------------------------------------------------------------- -ssl_mod_auth(doc) -> - ["Module test: mod_auth"]; -ssl_mod_auth(suite) -> + +pssl_mod_auth(doc) -> + ["Module test: mod_auth - old SSL config"]; +pssl_mod_auth(suite) -> []; -ssl_mod_auth(Config) when is_list(Config) -> - httpd_mod:auth(ssl, ?SSL_PORT, - ?config(host, Config), ?config(node, Config)), +pssl_mod_auth(Config) when is_list(Config) -> + ssl_mod_auth(ssl, Config). + +ossl_mod_auth(doc) -> + ["Module test: mod_auth - using new of configure old SSL"]; +ossl_mod_auth(suite) -> + []; +ossl_mod_auth(Config) when is_list(Config) -> + ssl_mod_auth(ossl, Config). + +essl_mod_auth(doc) -> + ["Module test: mod_auth - using new of configure new SSL"]; +essl_mod_auth(suite) -> + []; +essl_mod_auth(Config) when is_list(Config) -> + ssl_mod_auth(essl, Config). + +ssl_mod_auth(Tag, Config) -> + httpd_mod:auth(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), ok. + + %%------------------------------------------------------------------------- -ssl_mod_auth_api(doc) -> - ["Module test: mod_auth"]; -ssl_mod_auth_api(suite) -> + +pssl_mod_auth_api(doc) -> + ["Module test: mod_auth - old SSL config"]; +pssl_mod_auth_api(suite) -> + []; +pssl_mod_auth_api(Config) when is_list(Config) -> + ssl_mod_auth_api(ssl, Config). + +ossl_mod_auth_api(doc) -> + ["Module test: mod_auth - using new of configure old SSL"]; +ossl_mod_auth_api(suite) -> + []; +ossl_mod_auth_api(Config) when is_list(Config) -> + ssl_mod_auth_api(ossl, Config). + +essl_mod_auth_api(doc) -> + ["Module test: mod_auth - using new of configure new SSL"]; +essl_mod_auth_api(suite) -> []; -ssl_mod_auth_api(Config) when is_list(Config) -> +essl_mod_auth_api(Config) when is_list(Config) -> + ssl_mod_auth_api(essl, Config). + +ssl_mod_auth_api(Tag, Config) -> ServerRoot = ?config(server_root, Config), - Host = ?config(host, Config), - Node = ?config(node, Config), - httpd_mod:auth_api(ServerRoot, "", ssl, ?SSL_PORT, Host, Node), - httpd_mod:auth_api(ServerRoot, "dets_", ssl, ?SSL_PORT, Host, Node), - httpd_mod:auth_api(ServerRoot, "mnesia_", ssl, ?SSL_PORT, Host, Node), + Host = ?config(host, Config), + Node = ?config(node, Config), + httpd_mod:auth_api(ServerRoot, "", Tag, ?SSL_PORT, Host, Node), + httpd_mod:auth_api(ServerRoot, "dets_", Tag, ?SSL_PORT, Host, Node), + httpd_mod:auth_api(ServerRoot, "mnesia_", Tag, ?SSL_PORT, Host, Node), ok. + %%------------------------------------------------------------------------- -ssl_mod_auth_mnesia_api(doc) -> - ["Module test: mod_auth_mnesia_api"]; -ssl_mod_auth_mnesia_api(suite) -> + +pssl_mod_auth_mnesia_api(doc) -> + ["Module test: mod_auth_mnesia_api - old SSL config"]; +pssl_mod_auth_mnesia_api(suite) -> []; -ssl_mod_auth_mnesia_api(Config) when is_list(Config) -> - httpd_mod:auth_mnesia_api(ssl, ?SSL_PORT, - ?config(host, Config), ?config(node, Config)), +pssl_mod_auth_mnesia_api(Config) when is_list(Config) -> + ssl_mod_auth_mnesia_api(ssl, Config). + +ossl_mod_auth_mnesia_api(doc) -> + ["Module test: mod_auth_mnesia_api - using new of configure old SSL"]; +ossl_mod_auth_mnesia_api(suite) -> + []; +ossl_mod_auth_mnesia_api(Config) when is_list(Config) -> + ssl_mod_auth_mnesia_api(ossl, Config). + +essl_mod_auth_mnesia_api(doc) -> + ["Module test: mod_auth_mnesia_api - using new of configure new SSL"]; +essl_mod_auth_mnesia_api(suite) -> + []; +essl_mod_auth_mnesia_api(Config) when is_list(Config) -> + ssl_mod_auth_mnesia_api(essl, Config). + +ssl_mod_auth_mnesia_api(Tag, Config) -> + httpd_mod:auth_mnesia_api(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), ok. + + %%------------------------------------------------------------------------- -ssl_mod_htaccess(doc) -> - ["Module test: mod_htaccess"]; -ssl_mod_htaccess(suite) -> + +pssl_mod_htaccess(doc) -> + ["Module test: mod_htaccess - old SSL config"]; +pssl_mod_htaccess(suite) -> []; -ssl_mod_htaccess(Config) when is_list(Config) -> - httpd_mod:htaccess(ssl, ?SSL_PORT, - ?config(host, Config), ?config(node, Config)), +pssl_mod_htaccess(Config) when is_list(Config) -> + ssl_mod_htaccess(ssl, Config). + +ossl_mod_htaccess(doc) -> + ["Module test: mod_htaccess - using new of configure old SSL"]; +ossl_mod_htaccess(suite) -> + []; +ossl_mod_htaccess(Config) when is_list(Config) -> + ssl_mod_htaccess(ossl, Config). + +essl_mod_htaccess(doc) -> + ["Module test: mod_htaccess - using new of configure new SSL"]; +essl_mod_htaccess(suite) -> + []; +essl_mod_htaccess(Config) when is_list(Config) -> + ssl_mod_htaccess(essl, Config). + +ssl_mod_htaccess(Tag, Config) -> + httpd_mod:htaccess(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), ok. + + %%------------------------------------------------------------------------- -ssl_mod_cgi(doc) -> - ["Module test: mod_cgi"]; -ssl_mod_cgi(suite) -> + +pssl_mod_cgi(doc) -> + ["Module test: mod_cgi - old SSL config"]; +pssl_mod_cgi(suite) -> + []; +pssl_mod_cgi(Config) when is_list(Config) -> + ssl_mod_cgi(ssl, Config). + +ossl_mod_cgi(doc) -> + ["Module test: mod_cgi - using new of configure old SSL"]; +ossl_mod_cgi(suite) -> + []; +ossl_mod_cgi(Config) when is_list(Config) -> + ssl_mod_cgi(ossl, Config). + +essl_mod_cgi(doc) -> + ["Module test: mod_cgi - using new of configure new SSL"]; +essl_mod_cgi(suite) -> []; -ssl_mod_cgi(Config) when is_list(Config) -> +essl_mod_cgi(Config) when is_list(Config) -> + ssl_mod_cgi(essl, Config). + +ssl_mod_cgi(Tag, Config) -> case test_server:os_type() of vxworks -> {skip, cgi_not_supported_on_vxwoks}; _ -> - httpd_mod:cgi(ssl, ?SSL_PORT, - ?config(host, Config), ?config(node, Config)), + httpd_mod:cgi(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), ok end. + + %%------------------------------------------------------------------------- -ssl_mod_esi(doc) -> - ["Module test: mod_esi"]; -ssl_mod_esi(suite) -> + +pssl_mod_esi(doc) -> + ["Module test: mod_esi - old SSL config"]; +pssl_mod_esi(suite) -> []; -ssl_mod_esi(Config) when is_list(Config) -> - httpd_mod:esi(ssl, ?SSL_PORT, - ?config(host, Config), ?config(node, Config)), +pssl_mod_esi(Config) when is_list(Config) -> + ssl_mod_esi(ssl, Config). + +ossl_mod_esi(doc) -> + ["Module test: mod_esi - using new of configure old SSL"]; +ossl_mod_esi(suite) -> + []; +ossl_mod_esi(Config) when is_list(Config) -> + ssl_mod_esi(ossl, Config). + +essl_mod_esi(doc) -> + ["Module test: mod_esi - using new of configure new SSL"]; +essl_mod_esi(suite) -> + []; +essl_mod_esi(Config) when is_list(Config) -> + ssl_mod_esi(essl, Config). + +ssl_mod_esi(Tag, Config) -> + httpd_mod:esi(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), ok. + %%------------------------------------------------------------------------- -ssl_mod_get(doc) -> - ["Module test: mod_get"]; -ssl_mod_get(suite) -> + +pssl_mod_get(doc) -> + ["Module test: mod_get - old SSL config"]; +pssl_mod_get(suite) -> []; -ssl_mod_get(Config) when is_list(Config) -> - httpd_mod:get(ssl, ?SSL_PORT, - ?config(host, Config), ?config(node, Config)), +pssl_mod_get(Config) when is_list(Config) -> + ssl_mod_get(ssl, Config). + +ossl_mod_get(doc) -> + ["Module test: mod_get - using new of configure old SSL"]; +ossl_mod_get(suite) -> + []; +ossl_mod_get(Config) when is_list(Config) -> + ssl_mod_get(ossl, Config). + +essl_mod_get(doc) -> + ["Module test: mod_get - using new of configure new SSL"]; +essl_mod_get(suite) -> + []; +essl_mod_get(Config) when is_list(Config) -> + ssl_mod_get(essl, Config). + +ssl_mod_get(Tag, Config) -> + httpd_mod:get(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), ok. + + %%------------------------------------------------------------------------- -ssl_mod_head(doc) -> - ["Module test: mod_head"]; -ssl_mod_head(suite) -> + +pssl_mod_head(doc) -> + ["Module test: mod_head - old SSL config"]; +pssl_mod_head(suite) -> []; -ssl_mod_head(Config) when is_list(Config) -> - httpd_mod:head(ssl, ?SSL_PORT, - ?config(host, Config), ?config(node, Config)), +pssl_mod_head(Config) when is_list(Config) -> + ssl_mod_head(ssl, Config). + +ossl_mod_head(doc) -> + ["Module test: mod_head - using new of configure old SSL"]; +ossl_mod_head(suite) -> + []; +ossl_mod_head(Config) when is_list(Config) -> + ssl_mod_head(ossl, Config). + +essl_mod_head(doc) -> + ["Module test: mod_head - using new of configure new SSL"]; +essl_mod_head(suite) -> + []; +essl_mod_head(Config) when is_list(Config) -> + ssl_mod_head(essl, Config). + +ssl_mod_head(Tag, Config) -> + httpd_mod:head(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), ok. + + %%------------------------------------------------------------------------- -ssl_mod_all(doc) -> - ["All modules test"]; -ssl_mod_all(suite) -> + +pssl_mod_all(doc) -> + ["All modules test - old SSL config"]; +pssl_mod_all(suite) -> []; -ssl_mod_all(Config) when is_list(Config) -> - httpd_mod:all(ssl, ?SSL_PORT, - ?config(host, Config), ?config(node, Config)), +pssl_mod_all(Config) when is_list(Config) -> + ssl_mod_all(ssl, Config). + +ossl_mod_all(doc) -> + ["All modules test - using new of configure old SSL"]; +ossl_mod_all(suite) -> + []; +ossl_mod_all(Config) when is_list(Config) -> + ssl_mod_all(ossl, Config). + +essl_mod_all(doc) -> + ["All modules test - using new of configure new SSL"]; +essl_mod_all(suite) -> + []; +essl_mod_all(Config) when is_list(Config) -> + ssl_mod_all(essl, Config). + +ssl_mod_all(Tag, Config) -> + httpd_mod:all(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), ok. + %%------------------------------------------------------------------------- -ssl_load_light(doc) -> - ["Test light load"]; -ssl_load_light(suite) -> + +pssl_load_light(doc) -> + ["Test light load - old SSL config"]; +pssl_load_light(suite) -> + []; +pssl_load_light(Config) when is_list(Config) -> + ssl_load_light(ssl, Config). + +ossl_load_light(doc) -> + ["Test light load - using new of configure old SSL"]; +ossl_load_light(suite) -> + []; +ossl_load_light(Config) when is_list(Config) -> + ssl_load_light(ossl, Config). + +essl_load_light(doc) -> + ["Test light load - using new of configure new SSL"]; +essl_load_light(suite) -> []; -ssl_load_light(Config) when is_list(Config) -> - httpd_load:load_test(ssl, ?SSL_PORT, ?config(host, Config), +essl_load_light(Config) when is_list(Config) -> + ssl_load_light(essl, Config). + +ssl_load_light(Tag, Config) -> + httpd_load:load_test(Tag, + ?SSL_PORT, + ?config(host, Config), ?config(node, Config), get_nof_clients(ssl, light)), ok. + %%------------------------------------------------------------------------- -ssl_load_medium(doc) -> - ["Test medium load"]; -ssl_load_medium(suite) -> + +pssl_load_medium(doc) -> + ["Test medium load - old SSL config"]; +pssl_load_medium(suite) -> + []; +pssl_load_medium(Config) when is_list(Config) -> + ssl_load_medium(ssl, Config). + +ossl_load_medium(doc) -> + ["Test medium load - using new of configure old SSL"]; +ossl_load_medium(suite) -> []; -ssl_load_medium(Config) when is_list(Config) -> +ossl_load_medium(Config) when is_list(Config) -> + ssl_load_medium(ossl, Config). + +essl_load_medium(doc) -> + ["Test medium load - using new of configure new SSL"]; +essl_load_medium(suite) -> + []; +essl_load_medium(Config) when is_list(Config) -> + ssl_load_medium(essl, Config). + +ssl_load_medium(Tag, Config) -> %% <CONDITIONAL-SKIP> Skippable = [win32], Condition = fun() -> ?OS_BASED_SKIP(Skippable) end, ?NON_PC_TC_MAYBE_SKIP(Config, Condition), %% </CONDITIONAL-SKIP> - httpd_load:load_test(ssl, ?SSL_PORT, ?config(host, Config), + httpd_load:load_test(Tag, + ?SSL_PORT, + ?config(host, Config), ?config(node, Config), get_nof_clients(ssl, medium)), ok. + %%------------------------------------------------------------------------- -ssl_load_heavy(doc) -> - ["Test heavy load"]; -ssl_load_heavy(suite) -> + +pssl_load_heavy(doc) -> + ["Test heavy load - old SSL config"]; +pssl_load_heavy(suite) -> []; -ssl_load_heavy(Config) when is_list(Config) -> +pssl_load_heavy(Config) when is_list(Config) -> + ssl_load_heavy(ssl, Config). + +ossl_load_heavy(doc) -> + ["Test heavy load - using new of configure old SSL"]; +ossl_load_heavy(suite) -> + []; +ossl_load_heavy(Config) when is_list(Config) -> + ssl_load_heavy(ossl, Config). + +essl_load_heavy(doc) -> + ["Test heavy load - using new of configure new SSL"]; +essl_load_heavy(suite) -> + []; +essl_load_heavy(Config) when is_list(Config) -> + ssl_load_heavy(essl, Config). + +ssl_load_heavy(Tag, Config) -> %% <CONDITIONAL-SKIP> Skippable = [win32], Condition = fun() -> ?OS_BASED_SKIP(Skippable) end, ?NON_PC_TC_MAYBE_SKIP(Config, Condition), %% </CONDITIONAL-SKIP> - httpd_load:load_test(ssl, ?SSL_PORT, ?config(host, Config), + httpd_load:load_test(Tag, + ?SSL_PORT, + ?config(host, Config), ?config(node, Config), get_nof_clients(ssl, heavy)), ok. + %%------------------------------------------------------------------------- -ssl_dos_hostname(doc) -> - ["Denial Of Service (DOS) attack test case"]; -ssl_dos_hostname(suite) -> + +pssl_dos_hostname(doc) -> + ["Denial Of Service (DOS) attack test case - old SSL config"]; +pssl_dos_hostname(suite) -> []; -ssl_dos_hostname(Config) when is_list(Config) -> - dos_hostname(ssl, ?SSL_PORT, ?config(host, Config), - ?config(node, Config), ?MAX_HEADER_SIZE), +pssl_dos_hostname(Config) when is_list(Config) -> + ssl_dos_hostname(ssl, Config). + +ossl_dos_hostname(doc) -> + ["Denial Of Service (DOS) attack test case - using new of configure old SSL"]; +ossl_dos_hostname(suite) -> + []; +ossl_dos_hostname(Config) when is_list(Config) -> + ssl_dos_hostname(ossl, Config). + +essl_dos_hostname(doc) -> + ["Denial Of Service (DOS) attack test case - using new of configure new SSL"]; +essl_dos_hostname(suite) -> + []; +essl_dos_hostname(Config) when is_list(Config) -> + ssl_dos_hostname(essl, Config). + +ssl_dos_hostname(Tag, Config) -> + dos_hostname(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config), + ?MAX_HEADER_SIZE), ok. + + %%------------------------------------------------------------------------- -ssl_time_test(doc) -> - [""]; -ssl_time_test(suite) -> + +pssl_time_test(doc) -> + ["old SSL config"]; +pssl_time_test(suite) -> []; -ssl_time_test(Config) when is_list(Config) -> +pssl_time_test(Config) when is_list(Config) -> + ssl_time_test(ssl, Config). + +ossl_time_test(doc) -> + ["using new of configure old SSL"]; +ossl_time_test(suite) -> + []; +ossl_time_test(Config) when is_list(Config) -> + ssl_time_test(ossl, Config). + +essl_time_test(doc) -> + ["using new of configure new SSL"]; +essl_time_test(suite) -> + []; +essl_time_test(Config) when is_list(Config) -> + ssl_time_test(essl, Config). + +ssl_time_test(Tag, Config) when is_list(Config) -> %% <CONDITIONAL-SKIP> - Condition = fun() -> true end, + FreeBSDVersionVerify = + fun() -> + case os:version() of + {7, 1, _} -> % We only have one such machine, so... + true; + _ -> + false + end + end, + Skippable = [win32, {unix, [{freebsd, FreeBSDVersionVerify}]}], + Condition = fun() -> ?OS_BASED_SKIP(Skippable) end, ?NON_PC_TC_MAYBE_SKIP(Config, Condition), %% </CONDITIONAL-SKIP> - httpd_time_test:t(ssl, ?config(host, Config), ?SSL_PORT), + httpd_time_test:t(Tag, + ?config(host, Config), + ?SSL_PORT), ok. + %%------------------------------------------------------------------------- -ssl_block_503(doc) -> + +pssl_block_503(doc) -> ["Check that you will receive status code 503 when the server" - " is blocked and 200 when its not blocked."]; -ssl_block_503(suite) -> + " is blocked and 200 when its not blocked - old SSL config."]; +pssl_block_503(suite) -> []; -ssl_block_503(Config) when is_list(Config) -> - httpd_block:block_503(ssl, ?SSL_PORT, ?config(host, Config), +pssl_block_503(Config) when is_list(Config) -> + ssl_block_503(ssl, Config). + +ossl_block_503(doc) -> + ["Check that you will receive status code 503 when the server" + " is blocked and 200 when its not blocked - using new of configure old SSL."]; +ossl_block_503(suite) -> + []; +ossl_block_503(Config) when is_list(Config) -> + ssl_block_503(ossl, Config). + +essl_block_503(doc) -> + ["Check that you will receive status code 503 when the server" + " is blocked and 200 when its not blocked - using new of configure new SSL."]; +essl_block_503(suite) -> + []; +essl_block_503(Config) when is_list(Config) -> + ssl_block_503(essl, Config). + +ssl_block_503(Tag, Config) -> + httpd_block:block_503(Tag, + ?SSL_PORT, + ?config(host, Config), ?config(node, Config)), ok. + + %%------------------------------------------------------------------------- -ssl_block_disturbing_idle(doc) -> + +pssl_block_disturbing_idle(doc) -> ["Check that you can block/unblock an idle server. The strategy " - "distribing does not really make a difference in this case."]; -ssl_block_disturbing_idle(suite) -> + "distribing does not really make a difference in this case." + "Old SSL config"]; +pssl_block_disturbing_idle(suite) -> []; -ssl_block_disturbing_idle(Config) when is_list(Config) -> - httpd_block:block_disturbing_idle(ssl, ?SSL_PORT, +pssl_block_disturbing_idle(Config) when is_list(Config) -> + ssl_block_disturbing_idle(ssl, Config). + +ossl_block_disturbing_idle(doc) -> + ["Check that you can block/unblock an idle server. The strategy " + "distribing does not really make a difference in this case." + "Using new of configure old SSL"]; +ossl_block_disturbing_idle(suite) -> + []; +ossl_block_disturbing_idle(Config) when is_list(Config) -> + ssl_block_disturbing_idle(ossl, Config). + +essl_block_disturbing_idle(doc) -> + ["Check that you can block/unblock an idle server. The strategy " + "distribing does not really make a difference in this case." + "Using new of configure new SSL"]; +essl_block_disturbing_idle(suite) -> + []; +essl_block_disturbing_idle(Config) when is_list(Config) -> + ssl_block_disturbing_idle(essl, Config). + +ssl_block_disturbing_idle(Tag, Config) -> + httpd_block:block_disturbing_idle(Tag, + ?SSL_PORT, ?config(host, Config), ?config(node, Config)), ok. + + %%------------------------------------------------------------------------- -ssl_block_non_disturbing_idle(doc) -> + +pssl_block_non_disturbing_idle(doc) -> ["Check that you can block/unblock an idle server. The strategy " - "non distribing does not really make a difference in this case."]; -ssl_block_non_disturbing_idle(suite) -> + "non distribing does not really make a difference in this case." + "Old SSL config"]; +pssl_block_non_disturbing_idle(suite) -> + []; +pssl_block_non_disturbing_idle(Config) when is_list(Config) -> + ssl_block_non_disturbing_idle(ssl, Config). + +ossl_block_non_disturbing_idle(doc) -> + ["Check that you can block/unblock an idle server. The strategy " + "non distribing does not really make a difference in this case." + "Using new of configure old SSL"]; +ossl_block_non_disturbing_idle(suite) -> + []; +ossl_block_non_disturbing_idle(Config) when is_list(Config) -> + ssl_block_non_disturbing_idle(ossl, Config). + +essl_block_non_disturbing_idle(doc) -> + ["Check that you can block/unblock an idle server. The strategy " + "non distribing does not really make a difference in this case." + "Using new of configure new SSL"]; +essl_block_non_disturbing_idle(suite) -> []; -ssl_block_non_disturbing_idle(Config) when is_list(Config) -> - httpd_block:block_non_disturbing_idle(ssl, ?SSL_PORT, +essl_block_non_disturbing_idle(Config) when is_list(Config) -> + ssl_block_non_disturbing_idle(essl, Config). + +ssl_block_non_disturbing_idle(Tag, Config) -> + httpd_block:block_non_disturbing_idle(Tag, + ?SSL_PORT, ?config(host, Config), ?config(node, Config)), ok. + + %%------------------------------------------------------------------------- -ssl_block_disturbing_active(doc) -> + +pssl_block_disturbing_active(doc) -> ["Check that you can block/unblock an active server. The strategy " - "distribing means ongoing requests should be terminated."]; -ssl_block_disturbing_active(suite) -> + "distribing means ongoing requests should be terminated." + "Old SSL config"]; +pssl_block_disturbing_active(suite) -> + []; +pssl_block_disturbing_active(Config) when is_list(Config) -> + ssl_block_disturbing_active(ssl, Config). + +ossl_block_disturbing_active(doc) -> + ["Check that you can block/unblock an active server. The strategy " + "distribing means ongoing requests should be terminated." + "Using new of configure old SSL"]; +ossl_block_disturbing_active(suite) -> []; -ssl_block_disturbing_active(Config) when is_list(Config) -> - httpd_block:block_disturbing_active(ssl, ?SSL_PORT, +ossl_block_disturbing_active(Config) when is_list(Config) -> + ssl_block_disturbing_active(ossl, Config). + +essl_block_disturbing_active(doc) -> + ["Check that you can block/unblock an active server. The strategy " + "distribing means ongoing requests should be terminated." + "Using new of configure new SSL"]; +essl_block_disturbing_active(suite) -> + []; +essl_block_disturbing_active(Config) when is_list(Config) -> + ssl_block_disturbing_active(essl, Config). + +ssl_block_disturbing_active(Tag, Config) -> + httpd_block:block_disturbing_active(Tag, + ?SSL_PORT, ?config(host, Config), ?config(node, Config)), ok. + + %%------------------------------------------------------------------------- -ssl_block_non_disturbing_active(doc) -> + +pssl_block_non_disturbing_active(doc) -> ["Check that you can block/unblock an idle server. The strategy " - "non distribing means the ongoing requests should be compleated."]; -ssl_block_non_disturbing_active(suite) -> + "non distribing means the ongoing requests should be compleated." + "Old SSL config"]; +pssl_block_non_disturbing_active(suite) -> + []; +pssl_block_non_disturbing_active(Config) when is_list(Config) -> + ssl_block_non_disturbing_active(ssl, Config). + +ossl_block_non_disturbing_active(doc) -> + ["Check that you can block/unblock an idle server. The strategy " + "non distribing means the ongoing requests should be compleated." + "Using new of configure old SSL"]; +ossl_block_non_disturbing_active(suite) -> []; -ssl_block_non_disturbing_active(Config) when is_list(Config) -> - httpd_block:block_non_disturbing_idle(ssl, ?SSL_PORT, +ossl_block_non_disturbing_active(Config) when is_list(Config) -> + ssl_block_non_disturbing_active(ossl, Config). + +essl_block_non_disturbing_active(doc) -> + ["Check that you can block/unblock an idle server. The strategy " + "non distribing means the ongoing requests should be compleated." + "Using new of configure new SSL"]; +essl_block_non_disturbing_active(suite) -> + []; +essl_block_non_disturbing_active(Config) when is_list(Config) -> + ssl_block_non_disturbing_active(essl, Config). + +ssl_block_non_disturbing_active(Tag, Config) -> + httpd_block:block_non_disturbing_idle(Tag, + ?SSL_PORT, ?config(host, Config), ?config(node, Config)), ok. + %%------------------------------------------------------------------------- -ssl_block_disturbing_active_timeout_not_released(doc) -> + +pssl_block_disturbing_active_timeout_not_released(doc) -> ["Check that you can block an active server. The strategy " "distribing means ongoing requests should be compleated" - "if the timeout does not occur."]; -ssl_block_disturbing_active_timeout_not_released(suite) -> + "if the timeout does not occur." + "Old SSL config"]; +pssl_block_disturbing_active_timeout_not_released(suite) -> []; -ssl_block_disturbing_active_timeout_not_released(Config) +pssl_block_disturbing_active_timeout_not_released(Config) when is_list(Config) -> - httpd_block: - block_disturbing_active_timeout_not_released(ssl, - ?SSL_PORT, - ?config(host, - Config), - ?config(node, - Config)), + ssl_block_disturbing_active_timeout_not_released(ssl, Config). + +ossl_block_disturbing_active_timeout_not_released(doc) -> + ["Check that you can block an active server. The strategy " + "distribing means ongoing requests should be compleated" + "if the timeout does not occur." + "Using new of configure old SSL"]; +ossl_block_disturbing_active_timeout_not_released(suite) -> + []; +ossl_block_disturbing_active_timeout_not_released(Config) + when is_list(Config) -> + ssl_block_disturbing_active_timeout_not_released(ossl, Config). + +essl_block_disturbing_active_timeout_not_released(doc) -> + ["Check that you can block an active server. The strategy " + "distribing means ongoing requests should be compleated" + "if the timeout does not occur." + "Using new of configure new SSL"]; +essl_block_disturbing_active_timeout_not_released(suite) -> + []; +essl_block_disturbing_active_timeout_not_released(Config) + when is_list(Config) -> + ssl_block_disturbing_active_timeout_not_released(essl, Config). + +ssl_block_disturbing_active_timeout_not_released(Tag, Config) -> + Port = ?SSL_PORT, + Host = ?config(host, Config), + Node = ?config(node, Config), + httpd_block:block_disturbing_active_timeout_not_released(Tag, + Port, Host, Node), ok. + + %%------------------------------------------------------------------------- -ssl_block_disturbing_active_timeout_released(doc) -> + +pssl_block_disturbing_active_timeout_released(doc) -> ["Check that you can block an active server. The strategy " "distribing means ongoing requests should be terminated when" - "the timeout occurs."]; -ssl_block_disturbing_active_timeout_released(suite) -> + "the timeout occurs." + "Old SSL config"]; +pssl_block_disturbing_active_timeout_released(suite) -> []; -ssl_block_disturbing_active_timeout_released(Config) +pssl_block_disturbing_active_timeout_released(Config) when is_list(Config) -> - httpd_block:block_disturbing_active_timeout_released(ssl, - ?SSL_PORT, - ?config(host, - Config), - ?config(node, - Config)), + ssl_block_disturbing_active_timeout_released(ssl, Config). + +ossl_block_disturbing_active_timeout_released(doc) -> + ["Check that you can block an active server. The strategy " + "distribing means ongoing requests should be terminated when" + "the timeout occurs." + "Using new of configure old SSL"]; +ossl_block_disturbing_active_timeout_released(suite) -> + []; +ossl_block_disturbing_active_timeout_released(Config) + when is_list(Config) -> + ssl_block_disturbing_active_timeout_released(ossl, Config). + +essl_block_disturbing_active_timeout_released(doc) -> + ["Check that you can block an active server. The strategy " + "distribing means ongoing requests should be terminated when" + "the timeout occurs." + "Using new of configure new SSL"]; +essl_block_disturbing_active_timeout_released(suite) -> + []; +essl_block_disturbing_active_timeout_released(Config) + when is_list(Config) -> + ssl_block_disturbing_active_timeout_released(essl, Config). + +ssl_block_disturbing_active_timeout_released(Tag, Config) -> + Port = ?SSL_PORT, + Host = ?config(host, Config), + Node = ?config(node, Config), + httpd_block:block_disturbing_active_timeout_released(Tag, + Port, + Host, + Node), ok. + %%------------------------------------------------------------------------- -ssl_block_non_disturbing_active_timeout_not_released(doc) -> + +pssl_block_non_disturbing_active_timeout_not_released(doc) -> ["Check that you can block an active server. The strategy " - "non non distribing means ongoing requests should be completed."]; -ssl_block_non_disturbing_active_timeout_not_released(suite) -> + "non non distribing means ongoing requests should be completed." + "Old SSL config"]; +pssl_block_non_disturbing_active_timeout_not_released(suite) -> []; -ssl_block_non_disturbing_active_timeout_not_released(Config) +pssl_block_non_disturbing_active_timeout_not_released(Config) when is_list(Config) -> - httpd_block: - block_non_disturbing_active_timeout_not_released(ssl, - ?SSL_PORT, - ?config(host, - Config), - ?config(node, - Config)), + ssl_block_non_disturbing_active_timeout_not_released(ssl, Config). + +ossl_block_non_disturbing_active_timeout_not_released(doc) -> + ["Check that you can block an active server. The strategy " + "non non distribing means ongoing requests should be completed." + "Using new of configure old SSL"]; +ossl_block_non_disturbing_active_timeout_not_released(suite) -> + []; +ossl_block_non_disturbing_active_timeout_not_released(Config) + when is_list(Config) -> + ssl_block_non_disturbing_active_timeout_not_released(ossl, Config). + +essl_block_non_disturbing_active_timeout_not_released(doc) -> + ["Check that you can block an active server. The strategy " + "non non distribing means ongoing requests should be completed." + "Using new of configure new SSL"]; +essl_block_non_disturbing_active_timeout_not_released(suite) -> + []; +essl_block_non_disturbing_active_timeout_not_released(Config) + when is_list(Config) -> + ssl_block_non_disturbing_active_timeout_not_released(essl, Config). + +ssl_block_non_disturbing_active_timeout_not_released(Tag, Config) -> + Port = ?SSL_PORT, + Host = ?config(host, Config), + Node = ?config(node, Config), + httpd_block:block_non_disturbing_active_timeout_not_released(Tag, + Port, + Host, + Node), ok. + + %%------------------------------------------------------------------------- -ssl_block_non_disturbing_active_timeout_released(doc) -> + +pssl_block_non_disturbing_active_timeout_released(doc) -> ["Check that you can block an active server. The strategy " - "non non distribing means ongoing requests should be completed. " - "When the timeout occurs the block operation sohould be canceled." ]; -ssl_block_non_disturbing_active_timeout_released(suite) -> + "non distribing means ongoing requests should be completed. " + "When the timeout occurs the block operation sohould be canceled." + "Old SSL config"]; +pssl_block_non_disturbing_active_timeout_released(suite) -> []; -ssl_block_non_disturbing_active_timeout_released(Config) +pssl_block_non_disturbing_active_timeout_released(Config) when is_list(Config) -> - httpd_block: - block_non_disturbing_active_timeout_released(ssl, - ?SSL_PORT, - ?config(host, - Config), - ?config(node, - Config)), + ssl_block_non_disturbing_active_timeout_released(ssl, Config). + +ossl_block_non_disturbing_active_timeout_released(doc) -> + ["Check that you can block an active server. The strategy " + "non distribing means ongoing requests should be completed. " + "When the timeout occurs the block operation sohould be canceled." + "Using new of configure old SSL"]; +ossl_block_non_disturbing_active_timeout_released(suite) -> + []; +ossl_block_non_disturbing_active_timeout_released(Config) + when is_list(Config) -> + ssl_block_non_disturbing_active_timeout_released(ossl, Config). + +essl_block_non_disturbing_active_timeout_released(doc) -> + ["Check that you can block an active server. The strategy " + "non distribing means ongoing requests should be completed. " + "When the timeout occurs the block operation sohould be canceled." + "Using new of configure new SSL"]; +essl_block_non_disturbing_active_timeout_released(suite) -> + []; +essl_block_non_disturbing_active_timeout_released(Config) + when is_list(Config) -> + ssl_block_non_disturbing_active_timeout_released(essl, Config). + +ssl_block_non_disturbing_active_timeout_released(Tag, Config) + when is_list(Config) -> + Port = ?SSL_PORT, + Host = ?config(host, Config), + Node = ?config(node, Config), + httpd_block:block_non_disturbing_active_timeout_released(Tag, + Port, + Host, + Node), + ok. + %%------------------------------------------------------------------------- -ssl_block_disturbing_blocker_dies(doc) -> + +pssl_block_disturbing_blocker_dies(doc) -> + ["old SSL config"]; +pssl_block_disturbing_blocker_dies(suite) -> []; -ssl_block_disturbing_blocker_dies(suite) -> +pssl_block_disturbing_blocker_dies(Config) when is_list(Config) -> + ssl_block_disturbing_blocker_dies(ssl, Config). + +ossl_block_disturbing_blocker_dies(doc) -> + ["using new of configure old SSL"]; +ossl_block_disturbing_blocker_dies(suite) -> + []; +ossl_block_disturbing_blocker_dies(Config) when is_list(Config) -> + ssl_block_disturbing_blocker_dies(ossl, Config). + +essl_block_disturbing_blocker_dies(doc) -> + ["using new of configure new SSL"]; +essl_block_disturbing_blocker_dies(suite) -> []; -ssl_block_disturbing_blocker_dies(Config) when is_list(Config) -> - httpd_block:disturbing_blocker_dies(ssl, ?SSL_PORT, +essl_block_disturbing_blocker_dies(Config) when is_list(Config) -> + ssl_block_disturbing_blocker_dies(essl, Config). + +ssl_block_disturbing_blocker_dies(Tag, Config) -> + httpd_block:disturbing_blocker_dies(Tag, + ?SSL_PORT, ?config(host, Config), ?config(node, Config)), ok. + + %%------------------------------------------------------------------------- -ssl_block_non_disturbing_blocker_dies(doc) -> + +pssl_block_non_disturbing_blocker_dies(doc) -> + ["old SSL config"]; +pssl_block_non_disturbing_blocker_dies(suite) -> + []; +pssl_block_non_disturbing_blocker_dies(Config) when is_list(Config) -> + ssl_block_non_disturbing_blocker_dies(ssl, Config). + +ossl_block_non_disturbing_blocker_dies(doc) -> + ["using new of configure old SSL"]; +ossl_block_non_disturbing_blocker_dies(suite) -> []; -ssl_block_non_disturbing_blocker_dies(suite) -> +ossl_block_non_disturbing_blocker_dies(Config) when is_list(Config) -> + ssl_block_non_disturbing_blocker_dies(ossl, Config). + +essl_block_non_disturbing_blocker_dies(doc) -> + ["using new of configure new SSL"]; +essl_block_non_disturbing_blocker_dies(suite) -> []; -ssl_block_non_disturbing_blocker_dies(Config) when is_list(Config) -> - httpd_block:non_disturbing_blocker_dies(ssl, ?SSL_PORT, +essl_block_non_disturbing_blocker_dies(Config) when is_list(Config) -> + ssl_block_non_disturbing_blocker_dies(essl, Config). + +ssl_block_non_disturbing_blocker_dies(Tag, Config) -> + httpd_block:non_disturbing_blocker_dies(Tag, + ?SSL_PORT, ?config(host, Config), ?config(node, Config)), ok. + + %%------------------------------------------------------------------------- -ssl_restart_no_block(doc) -> - [""]; -ssl_restart_no_block(suite) -> + +pssl_restart_no_block(doc) -> + ["old SSL config"]; +pssl_restart_no_block(suite) -> + []; +pssl_restart_no_block(Config) when is_list(Config) -> + ssl_restart_no_block(ssl, Config). + +ossl_restart_no_block(doc) -> + ["using new of configure old SSL"]; +ossl_restart_no_block(suite) -> + []; +ossl_restart_no_block(Config) when is_list(Config) -> + ssl_restart_no_block(ossl, Config). + +essl_restart_no_block(doc) -> + ["using new of configure new SSL"]; +essl_restart_no_block(suite) -> []; -ssl_restart_no_block(Config) when is_list(Config) -> - httpd_block:restart_no_block(ssl, ?SSL_PORT, ?config(host, Config), +essl_restart_no_block(Config) when is_list(Config) -> + ssl_restart_no_block(essl, Config). + +ssl_restart_no_block(Tag, Config) -> + httpd_block:restart_no_block(Tag, + ?SSL_PORT, + ?config(host, Config), ?config(node, Config)), ok. + + %%------------------------------------------------------------------------- -ssl_restart_disturbing_block(doc) -> - [""]; -ssl_restart_disturbing_block(suite) -> + +pssl_restart_disturbing_block(doc) -> + ["old SSL config"]; +pssl_restart_disturbing_block(suite) -> + []; +pssl_restart_disturbing_block(Config) when is_list(Config) -> + ssl_restart_disturbing_block(ssl, Config). + +ossl_restart_disturbing_block(doc) -> + ["using new of configure old SSL"]; +ossl_restart_disturbing_block(suite) -> + []; +ossl_restart_disturbing_block(Config) when is_list(Config) -> + ssl_restart_disturbing_block(ossl, Config). + +essl_restart_disturbing_block(doc) -> + ["using new of configure new SSL"]; +essl_restart_disturbing_block(suite) -> []; -ssl_restart_disturbing_block(Config) when is_list(Config) -> +essl_restart_disturbing_block(Config) when is_list(Config) -> + ssl_restart_disturbing_block(essl, Config). + +ssl_restart_disturbing_block(Tag, Config) -> %% <CONDITIONAL-SKIP> Condition = fun() -> case os:type() of {unix, linux} -> - HW = string:strip(os:cmd("uname -m"), right, $\n), - case HW of + case ?OSCMD("uname -m") of "ppc" -> - case inet:gethostname() of - {ok, "peach"} -> - true; + case file:read_file_info("/etc/fedora-release") of + {ok, _} -> + case ?OSCMD("awk '{print $2}' /etc/fedora-release") of + "release" -> + %% Fedora 7 and later + case ?OSCMD("awk '{print $3}' /etc/fedora-release") of + "7" -> + true; + _ -> + false + end; + _ -> + false + end; _ -> false end; @@ -1336,17 +2309,36 @@ ssl_restart_disturbing_block(Config) when is_list(Config) -> ?NON_PC_TC_MAYBE_SKIP(Config, Condition), %% </CONDITIONAL-SKIP> - httpd_block:restart_disturbing_block(ssl, ?SSL_PORT, + httpd_block:restart_disturbing_block(Tag, ?SSL_PORT, ?config(host, Config), ?config(node, Config)), ok. + %%------------------------------------------------------------------------- -ssl_restart_non_disturbing_block(doc) -> - [""]; -ssl_restart_non_disturbing_block(suite) -> + +pssl_restart_non_disturbing_block(doc) -> + ["old SSL config"]; +pssl_restart_non_disturbing_block(suite) -> []; -ssl_restart_non_disturbing_block(Config) when is_list(Config) -> +pssl_restart_non_disturbing_block(Config) when is_list(Config) -> + ssl_restart_non_disturbing_block(ssl, Config). + +ossl_restart_non_disturbing_block(doc) -> + ["using new of configure old SSL"]; +ossl_restart_non_disturbing_block(suite) -> + []; +ossl_restart_non_disturbing_block(Config) when is_list(Config) -> + ssl_restart_non_disturbing_block(ossl, Config). + +essl_restart_non_disturbing_block(doc) -> + ["using new of configure new SSL"]; +essl_restart_non_disturbing_block(suite) -> + []; +essl_restart_non_disturbing_block(Config) when is_list(Config) -> + ssl_restart_non_disturbing_block(essl, Config). + +ssl_restart_non_disturbing_block(Tag, Config) -> %% <CONDITIONAL-SKIP> Condition = fun() -> @@ -1371,11 +2363,13 @@ ssl_restart_non_disturbing_block(Config) when is_list(Config) -> ?NON_PC_TC_MAYBE_SKIP(Config, Condition), %% </CONDITIONAL-SKIP> - httpd_block:restart_non_disturbing_block(ssl, ?SSL_PORT, - ?config(host, Config), - ?config(node, Config)), + httpd_block:restart_non_disturbing_block(Tag, + ?SSL_PORT, + ?config(host, Config), + ?config(node, Config)), ok. + %%------------------------------------------------------------------------- ip_host(doc) -> ["Control that the server accepts/rejects requests with/ without host"]; @@ -1665,17 +2659,29 @@ dos_hostname(Type, Port, Host, Node, Max) -> %% Other help functions create_config(Config, Access, FileName) -> ServerRoot = ?config(server_root, Config), - TcTopDir = ?config(tc_top_dir, Config), - Port = ?config(port, Config), - Type = ?config(sock_type, Config), - Host = ?config(host, Config), - Mods = io_lib:format("~p", [httpd_mod]), - Funcs = io_lib:format("~p", [ssl_password_cb]), - MaxHdrSz = io_lib:format("~p", [256]), - MaxHdrAct = io_lib:format("~p", [close]), + TcTopDir = ?config(tc_top_dir, Config), + Port = ?config(port, Config), + Type = ?config(sock_type, Config), + Host = ?config(host, Config), + Mods = io_lib:format("~p", [httpd_mod]), + Funcs = io_lib:format("~p", [ssl_password_cb]), + MaxHdrSz = io_lib:format("~p", [256]), + MaxHdrAct = io_lib:format("~p", [close]), + + io:format(user, + "create_config -> " + "~n ServerRoot: ~p" + "~n TcTopDir: ~p" + "~n Type: ~p" + "~n Port: ~p" + "~n Host: ~p" + "~n", [ServerRoot, TcTopDir, Port, Type, Host]), + SSL = - case Type of - ssl -> + if + (Type =:= ssl) orelse + (Type =:= ossl) orelse + (Type =:= essl) -> [cline(["SSLCertificateFile ", filename:join(ServerRoot, "ssl/ssl_server.pem")]), cline(["SSLCertificateKeyFile ", @@ -1686,25 +2692,25 @@ create_config(Config, Access, FileName) -> cline(["SSLPasswordCallbackFunction ", Funcs]), cline(["SSLVerifyClient 0"]), cline(["SSLVerifyDepth 1"])]; - _ -> + true -> [] end, - Mod_order = case Access of - mod_htaccess -> - "Modules mod_alias mod_htaccess mod_auth " - "mod_security " - "mod_responsecontrol mod_trace mod_esi " - "mod_actions mod_cgi mod_include mod_dir " - "mod_range mod_get " - "mod_head mod_log mod_disk_log"; - _ -> - "Modules mod_alias mod_auth mod_security " - "mod_responsecontrol mod_trace mod_esi " - "mod_actions mod_cgi mod_include mod_dir " - "mod_range mod_get " - "mod_head mod_log mod_disk_log" - end, - + ModOrder = case Access of + mod_htaccess -> + "Modules mod_alias mod_htaccess mod_auth " + "mod_security " + "mod_responsecontrol mod_trace mod_esi " + "mod_actions mod_cgi mod_include mod_dir " + "mod_range mod_get " + "mod_head mod_log mod_disk_log"; + _ -> + "Modules mod_alias mod_auth mod_security " + "mod_responsecontrol mod_trace mod_esi " + "mod_actions mod_cgi mod_include mod_dir " + "mod_range mod_get " + "mod_head mod_log mod_disk_log" + end, + %% The test suite currently does not handle an explicit BindAddress. %% They assume any has been used, that is Addr is always set to undefined! @@ -1720,7 +2726,7 @@ create_config(Config, Access, FileName) -> cline(["Port ", integer_to_list(Port)]), cline(["ServerName ", Host]), cline(["SocketType ", atom_to_list(Type)]), - cline([Mod_order]), + cline([ModOrder]), %% cline(["LogFormat ", "erlang"]), cline(["ServerAdmin [email protected]"]), cline(["BindAddress ", BindAddress]), @@ -1882,18 +2888,18 @@ start_mnesia(Node) -> ok -> ok; Other -> - test_server:fail({failed_to_cleanup_mnesia, Other}) + tsf({failed_to_cleanup_mnesia, Other}) end, - case rpc:call(Node, ?MODULE, setup_mnesia, []) of + case rpc:call(Node, ?MODULE, setup_mnesia, []) of {atomic, ok} -> ok; Other2 -> - test_server:fail({failed_to_setup_mnesia, Other2}) + tsf({failed_to_setup_mnesia, Other2}) end, ok. setup_mnesia() -> - setup_mnesia([node()]). + setup_mnesia([node()]). setup_mnesia(Nodes) -> ok = mnesia:create_schema(Nodes), @@ -2029,20 +3035,20 @@ dos_hostname_request(Host) -> get_nof_clients(Mode, Load) -> get_nof_clients(test_server:os_type(), Mode, Load). -get_nof_clients(vxworks, _, light) -> 1; +get_nof_clients(vxworks, _, light) -> 1; get_nof_clients(vxworks, ip_comm, medium) -> 3; -get_nof_clients(vxworks, ssl, medium) -> 3; +get_nof_clients(vxworks, ssl, medium) -> 3; get_nof_clients(vxworks, ip_comm, heavy) -> 5; -get_nof_clients(vxworks, ssl, heavy) -> 5; -get_nof_clients(_, ip_comm, light) -> 5; -get_nof_clients(_, ssl, light) -> 2; -get_nof_clients(_, ip_comm, medium) -> 10; -get_nof_clients(_, ssl, medium) -> 4; -get_nof_clients(_, ip_comm, heavy) -> 20; -get_nof_clients(_, ssl, heavy) -> 6. +get_nof_clients(vxworks, ssl, heavy) -> 5; +get_nof_clients(_, ip_comm, light) -> 5; +get_nof_clients(_, ssl, light) -> 2; +get_nof_clients(_, ip_comm, medium) -> 10; +get_nof_clients(_, ssl, medium) -> 4; +get_nof_clients(_, ip_comm, heavy) -> 20; +get_nof_clients(_, ssl, heavy) -> 6. %% Make a file 100 bytes long containing 012...9*10 -create_range_data(Path)-> +create_range_data(Path) -> PathAndFileName=filename:join([Path,"range.txt"]), file:write_file(PathAndFileName,list_to_binary(["12345678901234567890", "12345678901234567890", @@ -2079,3 +3085,6 @@ create_range_data(Path)-> %% {ok, Fd} = file:open(ConfigFile, [write]), %% ok = file:write(Fd, lists:flatten(HttpConfig)), %% ok = file:close(Fd). + +tsf(Reason) -> + test_server:fail(Reason). diff --git a/lib/inets/test/httpd_SUITE_data/server_root/Makefile b/lib/inets/test/httpd_SUITE_data/server_root/Makefile new file mode 100644 index 0000000000..d7a3231068 --- /dev/null +++ b/lib/inets/test/httpd_SUITE_data/server_root/Makefile @@ -0,0 +1,209 @@ +# +# %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% +# +# +include $(ERL_TOP)/make/target.mk +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Application version +# ---------------------------------------------------- +include ../../vsn.mk +VSN=$(INETS_VSN) + +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN) + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- +MODULE= + +AUTH_FILES = auth/group \ + auth/passwd +CGI_FILES = cgi-bin/printenv.sh +CONF_FILES = conf/8080.conf \ + conf/8888.conf \ + conf/httpd.conf \ + conf/ssl.conf \ + conf/mime.types +OPEN_FILES = htdocs/open/dummy.html +MNESIA_OPEN_FILES = htdocs/mnesia_open/dummy.html +MISC_FILES = htdocs/misc/friedrich.html \ + htdocs/misc/oech.html +SECRET_FILES = htdocs/secret/dummy.html +MNESIA_SECRET_FILES = htdocs/mnesia_secret/dummy.html +HTDOCS_FILES = htdocs/index.html \ + htdocs/config.shtml \ + htdocs/echo.shtml \ + htdocs/exec.shtml \ + htdocs/flastmod.shtml \ + htdocs/fsize.shtml \ + htdocs/include.shtml +ICON_FILES = icons/README \ + icons/a.gif \ + icons/alert.black.gif \ + icons/alert.red.gif \ + icons/apache_pb.gif \ + icons/back.gif \ + icons/ball.gray.gif \ + icons/ball.red.gif \ + icons/binary.gif \ + icons/binhex.gif \ + icons/blank.gif \ + icons/bomb.gif \ + icons/box1.gif \ + icons/box2.gif \ + icons/broken.gif \ + icons/burst.gif \ + icons/button1.gif \ + icons/button10.gif \ + icons/button2.gif \ + icons/button3.gif \ + icons/button4.gif \ + icons/button5.gif \ + icons/button6.gif \ + icons/button7.gif \ + icons/button8.gif \ + icons/button9.gif \ + icons/buttonl.gif \ + icons/buttonr.gif \ + icons/c.gif \ + icons/comp.blue.gif \ + icons/comp.gray.gif \ + icons/compressed.gif \ + icons/continued.gif \ + icons/dir.gif \ + icons/down.gif \ + icons/dvi.gif \ + icons/f.gif \ + icons/folder.gif \ + icons/folder.open.gif \ + icons/folder.sec.gif \ + icons/forward.gif \ + icons/generic.gif \ + icons/generic.red.gif \ + icons/generic.sec.gif \ + icons/hand.right.gif \ + icons/hand.up.gif \ + icons/htdig.gif \ + icons/icon.sheet.gif \ + icons/image1.gif \ + icons/image2.gif \ + icons/image3.gif \ + icons/index.gif \ + icons/layout.gif \ + icons/left.gif \ + icons/link.gif \ + icons/movie.gif \ + icons/p.gif \ + icons/patch.gif \ + icons/pdf.gif \ + icons/pie0.gif \ + icons/pie1.gif \ + icons/pie2.gif \ + icons/pie3.gif \ + icons/pie4.gif \ + icons/pie5.gif \ + icons/pie6.gif \ + icons/pie7.gif \ + icons/pie8.gif \ + icons/portal.gif \ + icons/poweredby.gif \ + icons/ps.gif \ + icons/quill.gif \ + icons/right.gif \ + icons/screw1.gif \ + icons/screw2.gif \ + icons/script.gif \ + icons/sound1.gif \ + icons/sound2.gif \ + icons/sphere1.gif \ + icons/sphere2.gif \ + icons/star.gif \ + icons/star_blank.gif \ + icons/tar.gif \ + icons/tex.gif \ + icons/text.gif \ + icons/transfer.gif \ + icons/unknown.gif \ + icons/up.gif \ + icons/uu.gif \ + icons/uuencoded.gif \ + icons/world1.gif \ + icons/world2.gif + +SSL_FILES = ssl/ssl_client.pem \ + ssl/ssl_server.pem + +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +ERL_COMPILE_FLAGS += + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- + +debug opt: + +clean: + +docs: + +# ---------------------------------------------------- +# Release Target +# ---------------------------------------------------- +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: opt + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/auth + $(INSTALL_DATA) $(AUTH_FILES) $(RELSYSDIR)/examples/server_root/auth + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/cgi-bin + $(INSTALL_SCRIPT) $(CGI_FILES) $(RELSYSDIR)/examples/server_root/cgi-bin + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/conf + $(INSTALL_DATA) $(CONF_FILES) $(RELSYSDIR)/examples/server_root/conf + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/htdocs/open + $(INSTALL_DATA) $(OPEN_FILES) \ + $(RELSYSDIR)/examples/server_root/htdocs/open + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/htdocs/mnesia_open + $(INSTALL_DATA) $(MNESIA_OPEN_FILES) \ + $(RELSYSDIR)/examples/server_root/htdocs/mnesia_open + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/htdocs/misc + $(INSTALL_DATA) $(MISC_FILES) \ + $(RELSYSDIR)/examples/server_root/htdocs/misc + $(INSTALL_DIR) \ + $(RELSYSDIR)/examples/server_root/htdocs/secret/top_secret + $(INSTALL_DIR) \ + $(RELSYSDIR)/examples/server_root/htdocs/mnesia_secret/top_secret + $(INSTALL_DATA) $(SECRET_FILES) \ + $(RELSYSDIR)/examples/server_root/htdocs/secret + $(INSTALL_DATA) $(MNESIA_SECRET_FILES) \ + $(RELSYSDIR)/examples/server_root/htdocs/mnesia_secret + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/htdocs + $(INSTALL_DATA) $(HTDOCS_FILES) $(RELSYSDIR)/examples/server_root/htdocs + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/icons + $(INSTALL_DATA) $(ICON_FILES) $(RELSYSDIR)/examples/server_root/icons + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/ssl + $(INSTALL_DATA) $(SSL_FILES) $(RELSYSDIR)/examples/server_root/ssl + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/logs + +release_docs_spec: + diff --git a/lib/inets/test/httpd_block.erl b/lib/inets/test/httpd_block.erl index f967d8172a..ac1bf43ff5 100644 --- a/lib/inets/test/httpd_block.erl +++ b/lib/inets/test/httpd_block.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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,6 +36,7 @@ ]). %% Help functions +-export([httpd_block/3, httpd_block/4, httpd_unblock/2, httpd_restart/2]). -export([do_block_server/4, do_block_nd_server/5, do_long_poll/6]). -define(report(Label, Content), @@ -47,18 +48,24 @@ %% Test cases starts here. %%------------------------------------------------------------------------- block_disturbing_idle(_Type, Port, Host, Node) -> - unblocked = get_admin_state(Node, Host, Port), + io:format("block_disturbing_idle -> entry~n", []), + validate_admin_state(Node, Host, Port, unblocked), block_server(Node, Host, Port), - blocked = get_admin_state(Node, Host, Port), + validate_admin_state(Node, Host, Port, blocked), unblock_server(Node, Host, Port), - unblocked = get_admin_state(Node, Host, Port). + validate_admin_state(Node, Host, Port, unblocked), + io:format("block_disturbing_idle -> done~n", []), + ok. + %%-------------------------------------------------------------------- block_non_disturbing_idle(_Type, Port, Host, Node) -> unblocked = get_admin_state(Node, Host, Port), block_nd_server(Node, Host, Port), blocked = get_admin_state(Node, Host, Port), unblock_server(Node, Host, Port), - unblocked = get_admin_state(Node, Host, Port). + unblocked = get_admin_state(Node, Host, Port), + ok. + %%-------------------------------------------------------------------- block_503(Type, Port, Host, Node) -> Req = "GET / HTTP/1.0\r\ndummy-host.ericsson.se:\r\n\r\n", @@ -76,6 +83,7 @@ block_503(Type, Port, Host, Node) -> ok = httpd_test_lib:verify_request(Type, Host, Port, Node, Req, [{statuscode, 200}, {version, "HTTP/1.0"}]). + %%-------------------------------------------------------------------- block_disturbing_active(Type, Port, Host, Node) -> process_flag(trap_exit, true), @@ -87,6 +95,7 @@ block_disturbing_active(Type, Port, Host, Node) -> blocked = get_admin_state(Node, Host, Port), process_flag(trap_exit, false), ok. + %%-------------------------------------------------------------------- block_non_disturbing_active(Type, Port, Host, Node) -> process_flag(trap_exit, true), @@ -219,32 +228,91 @@ do_block_nd_server(Node, Host, Port, Timeout, Reply) -> restart_server(Node, _Host, Port) -> Addr = undefined, - rpc:call(Node, httpd, restart, [Addr, Port]). + rpc:call(Node, ?MODULE, httpd_restart, [Addr, Port]). + block_server(Node, _Host, Port) -> + io:format("block_server -> entry~n", []), Addr = undefined, - rpc:call(Node, httpd, block, [Addr, Port]). + rpc:call(Node, ?MODULE, httpd_block, [Addr, Port, disturbing]). + block_server(Node, _Host, Port, Timeout) -> Addr = undefined, - rpc:call(Node, httpd, block, [Addr, Port, disturbing, Timeout]). + rpc:call(Node, ?MODULE, httpd_block, [Addr, Port, disturbing, Timeout]). + block_nd_server(Node, _Host, Port) -> Addr = undefined, - rpc:call(Node, httpd, block, [Addr, Port, non_disturbing]). + rpc:call(Node, ?MODULE, httpd_block, [Addr, Port, non_disturbing]). block_nd_server(Node, _Host, Port, Timeout) -> Addr = undefined, - rpc:call(Node, httpd, block, [Addr, Port, non_disturbing, Timeout]). + rpc:call(Node, ?MODULE, httpd_block, [Addr, Port, non_disturbing, Timeout]). unblock_server(Node, _Host, Port) -> + io:format("~p:~p:block_server -> entry~n", [node(),self()]), Addr = undefined, - rpc:call(Node, httpd, unblock, [Addr, Port]). + rpc:call(Node, ?MODULE, httpd_unblock, [Addr, Port]). + + +httpd_block(Addr, Port, Mode) -> + io:format("~p:~p:httpd_block -> entry~n", [node(),self()]), + Name = make_name(Addr, Port), + case whereis(Name) of + Pid when is_pid(Pid) -> + httpd_manager:block(Pid, Mode); + _ -> + {error, not_started} + end. + +httpd_block(Addr, Port, Mode, Timeout) -> + Name = make_name(Addr, Port), + case whereis(Name) of + Pid when is_pid(Pid) -> + httpd_manager:block(Pid, Mode, Timeout); + _ -> + {error, not_started} + end. + +httpd_unblock(Addr, Port) -> + io:format("~p:~p:httpd_unblock -> entry~n", [node(),self()]), + Name = make_name(Addr, Port), + case whereis(Name) of + Pid when is_pid(Pid) -> + httpd_manager:unblock(Pid); + _ -> + {error, not_started} + end. + +httpd_restart(Addr, Port) -> + Name = make_name(Addr, Port), + case whereis(Name) of + Pid when is_pid(Pid) -> + httpd_manager:reload(Pid, undefined); + _ -> + {error, not_started} + end. + +make_name(Addr, Port) -> + httpd_util:make_name("httpd", Addr, Port). -get_admin_state(Node,_Host,Port) -> +get_admin_state(Node, _Host, Port) -> Addr = undefined, rpc:call(Node, httpd, get_admin_state, [Addr, Port]). +validate_admin_state(Node, Host, Port, Expect) -> + io:format("try validating server admin state: ~p~n", [Expect]), + case get_admin_state(Node, Host, Port) of + Expect -> + ok; + Unexpected -> + io:format("failed validating server admin state: ~p~n", + [Unexpected]), + exit({unexpected_admin_state, Unexpected, Expect}) + end. + + await_normal_process_exit(Pid, Name, Timeout) -> receive {'EXIT', Pid, normal} -> @@ -260,6 +328,7 @@ await_normal_process_exit(Pid, Name, Timeout) -> test_server:fail("timeout while waiting for " ++ Name) end. + await_suite_failed_process_exit(Pid, Name, Timeout, Why) -> receive {'EXIT', Pid, {suite_failed, Why}} -> diff --git a/lib/inets/test/httpd_mod.erl b/lib/inets/test/httpd_mod.erl index b03f842e7c..f2c1fd6a65 100644 --- a/lib/inets/test/httpd_mod.erl +++ b/lib/inets/test/httpd_mod.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% @@ -40,6 +40,13 @@ %% Test cases starts here. %%------------------------------------------------------------------------- alias(Type, Port, Host, Node) -> +%% io:format(user, "~w:alias -> entry with" +%% "~n Type: ~p" +%% "~n Port: ~p" +%% "~n Host: ~p" +%% "~n Node: ~p" +%% "~n", [?MODULE, Type, Port, Host, Node]), + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, "GET /pics/icon.sheet.gif " "HTTP/1.0\r\n\r\n", @@ -82,14 +89,15 @@ actions(Type, Port, Host, Node) -> %%------------------------------------------------------------------------- security(ServerRoot, Type, Port, Host, Node) -> - io:format(user, "~w:security -> entry with" - "~n ServerRoot: ~p" - "~n Type: ~p" - "~n Port: ~p" - "~n Host: ~p" - "~n Node: ~p" - "~n", [?MODULE, ServerRoot, Type, Port, Host, Node]), +%% io:format(user, "~w:security -> entry with" +%% "~n ServerRoot: ~p" +%% "~n Type: ~p" +%% "~n Port: ~p" +%% "~n Host: ~p" +%% "~n Node: ~p" +%% "~n", [?MODULE, ServerRoot, Type, Port, Host, Node]), +%% io:format(user, "~w:security -> register~n", [?MODULE]), global:register_name(mod_security_test, self()), % Receive events test_server:sleep(5000), @@ -99,54 +107,71 @@ security(ServerRoot, Type, Port, Host, Node) -> %% Test blocking / unblocking of users. %% /open, require user one Aladdin +%% io:format(user, "~w:security -> remove user~n", [?MODULE]), remove_users(Node, ServerRoot, Host, Port, "open"), +%% io:format(user, "~w:security -> auth request~n", [?MODULE]), auth_request(Type, Host, Port, Node, "/open/", "one", "onePassword", [{statuscode, 401}]), +%% io:format(user, "~w:security -> await fail security event~n", [?MODULE]), receive_security_event({event, auth_fail, Port, OpenDir, [{user, "one"}, {password, "onePassword"}]}, Node, Port), +%% io:format(user, "~w:security -> auth request~n", [?MODULE]), auth_request(Type,Host,Port,Node,"/open/", "two", "twoPassword", [{statuscode, 401}]), +%% io:format(user, "~w:security -> await fail security event~n", [?MODULE]), receive_security_event({event, auth_fail, Port, OpenDir, [{user, "two"}, {password, "twoPassword"}]}, Node, Port), +%% io:format(user, "~w:security -> auth request~n", [?MODULE]), auth_request(Type, Host, Port, Node,"/open/", "Aladdin", "AladdinPassword", [{statuscode, 401}]), +%% io:format(user, "~w:security -> await fail security event~n", [?MODULE]), receive_security_event({event, auth_fail, Port, OpenDir, [{user, "Aladdin"}, {password, "AladdinPassword"}]}, Node, Port), +%% io:format(user, "~w:security -> add users~n", [?MODULE]), add_user(Node, ServerRoot, Port, "open", "one", "onePassword", []), add_user(Node, ServerRoot, Port, "open", "two", "twoPassword", []), +%% io:format(user, "~w:security -> auth request~n", [?MODULE]), auth_request(Type, Host, Port, Node,"/open/", "one", "WrongPassword", [{statuscode, 401}]), +%% io:format(user, "~w:security -> await fail security event~n", [?MODULE]), receive_security_event({event, auth_fail, Port, OpenDir, [{user, "one"}, {password, "WrongPassword"}]}, Node, Port), +%% io:format(user, "~w:security -> auth request~n", [?MODULE]), auth_request(Type, Host, Port, Node,"/open/", "one", "WrongPassword", [{statuscode, 401}]), +%% io:format(user, "~w:security -> await fail security event~n", [?MODULE]), receive_security_event({event, auth_fail, Port, OpenDir, [{user, "one"}, {password, "WrongPassword"}]}, Node, Port), +%% io:format(user, "~w:security -> await block security event~n", [?MODULE]), receive_security_event({event, user_block, Port, OpenDir, [{user, "one"}]}, Node, Port), +%% io:format(user, "~w:security -> unregister~n", [?MODULE]), global:unregister_name(mod_security_test), % No more events. +%% io:format(user, "~w:security -> auth request~n", [?MODULE]), auth_request(Type, Host, Port, Node,"/open/", "one", "WrongPassword", [{statuscode, 401}]), +%% io:format(user, "~w:security -> auth request~n", [?MODULE]), auth_request(Type, Host, Port, Node,"/open/", "one", "onePassword", [{statuscode, 403}]), %% User "one" should be blocked now.. %% [{"one",_, Port, OpenDir,_}] = list_blocked_users(Node,Port), +%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), case list_blocked_users(Node, Port) of [{"one",_, Port, OpenDir,_}] -> ok; @@ -156,35 +181,54 @@ security(ServerRoot, Type, Port, Host, Node) -> exit({unexpected_blocked, Blocked}) end, +%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), [{"one",_, Port, OpenDir,_}] = list_blocked_users(Node,Port,OpenDir), +%% io:format(user, "~w:security -> unblock user~n", [?MODULE]), true = unblock_user(Node, "one", Port, OpenDir), %% User "one" should not be blocked any more.. +%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), [] = list_blocked_users(Node, Port), +%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), [] = list_blocked_users(Node, Port, OpenDir), +%% io:format(user, "~w:security -> auth request~n", [?MODULE]), auth_request(Type, Host, Port, Node,"/open/", "one", "onePassword", [{statuscode, 200}]), %% Test list_auth_users & auth_timeout +%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), ["one"] = list_auth_users(Node, Port), +%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), ["one"] = list_auth_users(Node, Port, OpenDir), +%% io:format(user, "~w:security -> auth request~n", [?MODULE]), auth_request(Type, Host, Port, Node,"/open/", "two", "onePassword", [{statuscode, 401}]), +%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), ["one"] = list_auth_users(Node, Port), +%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), ["one"] = list_auth_users(Node, Port, OpenDir), +%% io:format(user, "~w:security -> auth request~n", [?MODULE]), auth_request(Type, Host, Port, Node,"/open/", "two", "twoPassword", [{statuscode, 401}]), +%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), ["one"] = list_auth_users(Node, Port), +%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), ["one"] = list_auth_users(Node, Port, OpenDir), %% Wait for successful auth to timeout. test_server:sleep(?AUTH_TIMEOUT*1001), +%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), [] = list_auth_users(Node, Port), +%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), [] = list_auth_users(Node, Port, OpenDir), %% "two" is blocked. +%% io:format(user, "~w:security -> unblock user~n", [?MODULE]), true = unblock_user(Node, "two", Port, OpenDir), %% Test explicit blocking. Block user 'two'. +%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), [] = list_blocked_users(Node,Port,OpenDir), +%% io:format(user, "~w:security -> block user~n", [?MODULE]), true = block_user(Node, "two", Port, OpenDir, 10), +%% io:format(user, "~w:security -> auth request~n", [?MODULE]), auth_request(Type, Host, Port, Node,"/open/", "two", "twoPassword", [{statuscode, 401}]). @@ -600,6 +644,11 @@ htaccess(Type, Port, Host, Node) -> {header, "WWW-Authenticate"}]). %%-------------------------------------------------------------------- cgi(Type, Port, Host, Node) -> +%% tsp("cgi -> entry with" +%% "~n Type: ~p" +%% "~n Port: ~p" +%% "~n Host: ~p" +%% "~n Node: ~p", []), {Script, Script2, Script3} = case test_server:os_type() of {win32, _} -> @@ -609,6 +658,7 @@ cgi(Type, Port, Host, Node) -> end, %% The length (> 100) is intentional +%% tsp("cgi -> request 01 with length > 100"), ok = httpd_test_lib: verify_request(Type, Host, Port, Node, "POST /cgi-bin/" ++ Script3 ++ @@ -636,46 +686,55 @@ cgi(Type, Port, Host, Node) -> {version, "HTTP/1.0"}, {header, "content-type", "text/plain"}]), +%% tsp("cgi -> request 02"), ok = httpd_test_lib:verify_request(Type, Host, Port, Node, "GET /cgi-bin/"++ Script ++ " HTTP/1.0\r\n\r\n", [{statuscode, 200}, {version, "HTTP/1.0"}]), +%% tsp("cgi -> request 03"), ok = httpd_test_lib:verify_request(Type, Host, Port, Node, "GET /cgi-bin/not_there " "HTTP/1.0\r\n\r\n", [{statuscode, 404},{statuscode, 500}, {version, "HTTP/1.0"}]), +%% tsp("cgi -> request 04"), ok = httpd_test_lib:verify_request(Type, Host, Port, Node, "GET /cgi-bin/"++ Script ++ "?Nisse:kkk?sss/lll HTTP/1.0\r\n\r\n", [{statuscode, 200}, {version, "HTTP/1.0"}]), +%% tsp("cgi -> request 04"), ok = httpd_test_lib:verify_request(Type, Host, Port, Node, "POST /cgi-bin/"++ Script ++ " HTTP/1.0\r\n\r\n", [{statuscode, 200}, {version, "HTTP/1.0"}]), +%% tsp("cgi -> request 05"), ok = httpd_test_lib:verify_request(Type, Host, Port, Node, "GET /htbin/"++ Script ++ " HTTP/1.0\r\n\r\n", [{statuscode, 200}, {version, "HTTP/1.0"}]), +%% tsp("cgi -> request 06"), ok = httpd_test_lib:verify_request(Type, Host, Port, Node, "GET /htbin/not_there " "HTTP/1.0\r\n\r\n", [{statuscode, 404},{statuscode, 500}, {version, "HTTP/1.0"}]), +%% tsp("cgi -> request 07"), ok = httpd_test_lib:verify_request(Type, Host, Port, Node, "GET /htbin/"++ Script ++ "?Nisse:kkk?sss/lll HTTP/1.0\r\n\r\n", [{statuscode, 200}, {version, "HTTP/1.0"}]), +%% tsp("cgi -> request 08"), ok = httpd_test_lib:verify_request(Type, Host, Port, Node, "POST /htbin/"++ Script ++ " HTTP/1.0\r\n\r\n", [{statuscode, 200}, {version, "HTTP/1.0"}]), +%% tsp("cgi -> request 09"), ok = httpd_test_lib:verify_request(Type, Host, Port, Node, "POST /htbin/"++ Script ++ " HTTP/1.0\r\n\r\n", @@ -683,19 +742,24 @@ cgi(Type, Port, Host, Node) -> {version, "HTTP/1.0"}]), %% Execute an existing, but bad CGI script.. +%% tsp("cgi -> request 10 - bad script"), ok = httpd_test_lib:verify_request(Type, Host, Port, Node, "POST /htbin/"++ Script2 ++ " HTTP/1.0\r\n\r\n", [{statuscode, 404}, {version, "HTTP/1.0"}]), +%% tsp("cgi -> request 11 - bad script"), ok = httpd_test_lib:verify_request(Type, Host, Port, Node, "POST /cgi-bin/"++ Script2 ++ " HTTP/1.0\r\n\r\n", [{statuscode, 404}, {version, "HTTP/1.0"}]), + +%% tsp("cgi -> done"), ok. + %%-------------------------------------------------------------------- esi(Type, Port, Host, Node) -> %% Check "ErlScriptAlias" and "EvalScriptAlias" directives @@ -850,25 +914,44 @@ list_users(Node, Root, _Host, Port, Dir) -> Directory = filename:join([Root, "htdocs", Dir]), rpc:call(Node, mod_auth, list_users, [Addr, Port, Directory]). + receive_security_event(Event, Node, Port) -> - io:format(user, "~w:receive_security_event -> entry with" - "~n Event: ~p" - "~n Node: ~p" - "~n Port: ~p" - "~n", [?MODULE, Event, Node, Port]), +%% io:format(user, "~w:receive_security_event -> entry with" +%% "~n Event: ~p" +%% "~n Node: ~p" +%% "~n Port: ~p" +%% "~n", [?MODULE, Event, Node, Port]), receive Event -> ok; {'EXIT', _, _} -> - receive_security_event(Event, Node, Port); - Other -> - test_server:fail({unexpected_event, - {expected, Event}, {received, Other}}) + receive_security_event(Event, Node, Port) after 5000 -> - test_server:fail(no_event_recived) + %% Flush the message queue, to see if we got something... + Msgs = inets_test_lib:flush(), + tsf({expected_event_not_received, Msgs}) end. +%% receive_security_event(Event, Node, Port) -> +%% io:format(user, "~w:receive_security_event -> entry with" +%% "~n Event: ~p" +%% "~n Node: ~p" +%% "~n Port: ~p" +%% "~n", [?MODULE, Event, Node, Port]), +%% receive +%% Event -> +%% ok; +%% {'EXIT', _, _} -> +%% receive_security_event(Event, Node, Port); +%% Other -> +%% test_server:fail({unexpected_event, +%% {expected, Event}, {received, Other}}) +%% after 5000 -> +%% test_server:fail(no_event_recived) + +%% end. + list_blocked_users(Node,Port) -> Addr = undefined, % Assumed to be on the same host rpc:call(Node, mod_security, list_blocked_users, [Addr,Port]). @@ -945,3 +1028,12 @@ check_lists_members1(L,L) -> ok; check_lists_members1(L1,L2) -> {error,{lists_not_equal,L1,L2}}. + + +%% tsp(F) -> +%% tsp(F, []). +%% tsp(F, A) -> +%% test_server:format("~p ~p:" ++ F ++ "~n", [self(), ?MODULE | A]). + +tsf(Reason) -> + test_server:fail(Reason). diff --git a/lib/inets/test/httpd_poll.erl b/lib/inets/test/httpd_poll.erl index 1cc10365a7..32335cabcf 100644 --- a/lib/inets/test/httpd_poll.erl +++ b/lib/inets/test/httpd_poll.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% @@ -27,7 +27,8 @@ %% gen_server exports -export([init/1, - handle_call/3, handle_cast/2, handle_info/2, terminate/2]). + handle_call/3, handle_cast/2, handle_info/2, terminate/2, + code_change/3]). -define(default_verbosity,error). @@ -86,8 +87,8 @@ options(Options) -> options([], Defaults, Options) -> Options ++ Defaults; -options([{Key,Val} = Opt|Opts], Defaults, Options) -> - options(Opts, lists:keydelete(Key, 1, Defaults), [Opt|Options]). +options([{Key, _Val} = Opt|Opts], Defaults, Options) -> + options(Opts, lists:keydelete(Key, 1, Defaults), [Opt | Options]). verbosity(silence) -> @@ -134,10 +135,9 @@ uris(otp) -> uri_top_index(), uri_internal_product1(), uri_internal_product2(), - uri_p7a_test_results(), + uri_r13b03_test_results(), uri_bjorn1(), - uri_bjorn2(), - uri_top_ronja() + uri_bjorn2() ]. uri_top_index() -> @@ -149,9 +149,9 @@ uri_internal_product1() -> uri_internal_product2() -> {"product internal page (2)","/product/internal"}. -uri_p7a_test_results() -> - {"test summery index page", - "/product/internal/test/test_results/progress_P7A/index.html"}. +uri_r13b03_test_results() -> + {"daily build index page", + "/product/internal/test/daily/logs.html"}. uri_bjorn1() -> {"bjorns home page (1)","/~bjorn/"}. @@ -159,9 +159,6 @@ uri_bjorn1() -> uri_bjorn2() -> {"bjorns home page (2)","/~bjorn"}. -uri_top_ronja() -> - {"ronja top page","/ronja/"}. - handle_call(stop, _From, State) -> vlog("stop request"), @@ -199,7 +196,11 @@ handle_info(Info, State) -> {noreply, State}. -terminate(Reason,State) -> +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + + +terminate(_Reason, State) -> tcancel(State#state.tref), log_close(get(log_file)), ok. @@ -287,16 +288,16 @@ trash_the_rest(Socket,N) -> end. -add(N1,N2) when integer(N1),integer(N2) -> +add(N1, N2) when is_integer(N1) andalso is_integer(N2) -> N1 + N2; -add(N1,N2) when integer(N1) -> +add(N1, _N2) when is_integer(N1) -> N1; -add(N1,N2) when integer(N2) -> +add(_N1, N2) when is_integer(N2) -> N2. -sz(L) when list(L) -> +sz(L) when is_list(L) -> length(lists:flatten(L)); -sz(B) when binary(B) -> +sz(B) when is_binary(B) -> size(B); sz(O) -> {unknown_size,O}. @@ -307,9 +308,9 @@ sz(O) -> %% Status code to printable string %% -status_to_message(L) when list(L) -> +status_to_message(L) when is_list(L) -> case (catch list_to_integer(L)) of - I when integer(I) -> + I when is_integer(I) -> status_to_message(I); _ -> io_lib:format("UNKNOWN STATUS CODE: '~p'",[L]) @@ -470,12 +471,12 @@ vlog(F,A) -> vprint(get(verbosity),log,F,A). verror(F) -> vprint(get(verbosity),error,F,[]). verror(F,A) -> vprint(get(verbosity),error,F,A). -vprint(trace,Severity,F,A) -> vprint(Severity,F,A); -vprint(debug,trace,F,A) -> ok; -vprint(debug,Severity,F,A) -> vprint(Severity,F,A); -vprint(log,log,F,A) -> vprint(log,F,A); -vprint(log,error,F,A) -> vprint(log,F,A); -vprint(error,error,F,A) -> vprint(error,F,A); +vprint(trace, Severity, F, A) -> vprint(Severity,F,A); +vprint(debug, trace, _F, _A) -> ok; +vprint(debug, Severity, F, A) -> vprint(Severity,F,A); +vprint(log, log, F, A) -> vprint(log,F,A); +vprint(log, error, F, A) -> vprint(log,F,A); +vprint(error, error, F, A) -> vprint(error,F,A); vprint(_Verbosity,_Severity,_F,_A) -> ok. vprint(Severity,F,A) -> @@ -491,6 +492,3 @@ image_of(trace) -> "TRC: ". local_time() -> calendar:local_time(). - - - diff --git a/lib/inets/test/httpd_test_data/server_root/Makefile b/lib/inets/test/httpd_test_data/server_root/Makefile new file mode 100644 index 0000000000..d7a3231068 --- /dev/null +++ b/lib/inets/test/httpd_test_data/server_root/Makefile @@ -0,0 +1,209 @@ +# +# %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% +# +# +include $(ERL_TOP)/make/target.mk +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Application version +# ---------------------------------------------------- +include ../../vsn.mk +VSN=$(INETS_VSN) + +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN) + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- +MODULE= + +AUTH_FILES = auth/group \ + auth/passwd +CGI_FILES = cgi-bin/printenv.sh +CONF_FILES = conf/8080.conf \ + conf/8888.conf \ + conf/httpd.conf \ + conf/ssl.conf \ + conf/mime.types +OPEN_FILES = htdocs/open/dummy.html +MNESIA_OPEN_FILES = htdocs/mnesia_open/dummy.html +MISC_FILES = htdocs/misc/friedrich.html \ + htdocs/misc/oech.html +SECRET_FILES = htdocs/secret/dummy.html +MNESIA_SECRET_FILES = htdocs/mnesia_secret/dummy.html +HTDOCS_FILES = htdocs/index.html \ + htdocs/config.shtml \ + htdocs/echo.shtml \ + htdocs/exec.shtml \ + htdocs/flastmod.shtml \ + htdocs/fsize.shtml \ + htdocs/include.shtml +ICON_FILES = icons/README \ + icons/a.gif \ + icons/alert.black.gif \ + icons/alert.red.gif \ + icons/apache_pb.gif \ + icons/back.gif \ + icons/ball.gray.gif \ + icons/ball.red.gif \ + icons/binary.gif \ + icons/binhex.gif \ + icons/blank.gif \ + icons/bomb.gif \ + icons/box1.gif \ + icons/box2.gif \ + icons/broken.gif \ + icons/burst.gif \ + icons/button1.gif \ + icons/button10.gif \ + icons/button2.gif \ + icons/button3.gif \ + icons/button4.gif \ + icons/button5.gif \ + icons/button6.gif \ + icons/button7.gif \ + icons/button8.gif \ + icons/button9.gif \ + icons/buttonl.gif \ + icons/buttonr.gif \ + icons/c.gif \ + icons/comp.blue.gif \ + icons/comp.gray.gif \ + icons/compressed.gif \ + icons/continued.gif \ + icons/dir.gif \ + icons/down.gif \ + icons/dvi.gif \ + icons/f.gif \ + icons/folder.gif \ + icons/folder.open.gif \ + icons/folder.sec.gif \ + icons/forward.gif \ + icons/generic.gif \ + icons/generic.red.gif \ + icons/generic.sec.gif \ + icons/hand.right.gif \ + icons/hand.up.gif \ + icons/htdig.gif \ + icons/icon.sheet.gif \ + icons/image1.gif \ + icons/image2.gif \ + icons/image3.gif \ + icons/index.gif \ + icons/layout.gif \ + icons/left.gif \ + icons/link.gif \ + icons/movie.gif \ + icons/p.gif \ + icons/patch.gif \ + icons/pdf.gif \ + icons/pie0.gif \ + icons/pie1.gif \ + icons/pie2.gif \ + icons/pie3.gif \ + icons/pie4.gif \ + icons/pie5.gif \ + icons/pie6.gif \ + icons/pie7.gif \ + icons/pie8.gif \ + icons/portal.gif \ + icons/poweredby.gif \ + icons/ps.gif \ + icons/quill.gif \ + icons/right.gif \ + icons/screw1.gif \ + icons/screw2.gif \ + icons/script.gif \ + icons/sound1.gif \ + icons/sound2.gif \ + icons/sphere1.gif \ + icons/sphere2.gif \ + icons/star.gif \ + icons/star_blank.gif \ + icons/tar.gif \ + icons/tex.gif \ + icons/text.gif \ + icons/transfer.gif \ + icons/unknown.gif \ + icons/up.gif \ + icons/uu.gif \ + icons/uuencoded.gif \ + icons/world1.gif \ + icons/world2.gif + +SSL_FILES = ssl/ssl_client.pem \ + ssl/ssl_server.pem + +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +ERL_COMPILE_FLAGS += + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- + +debug opt: + +clean: + +docs: + +# ---------------------------------------------------- +# Release Target +# ---------------------------------------------------- +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: opt + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/auth + $(INSTALL_DATA) $(AUTH_FILES) $(RELSYSDIR)/examples/server_root/auth + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/cgi-bin + $(INSTALL_SCRIPT) $(CGI_FILES) $(RELSYSDIR)/examples/server_root/cgi-bin + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/conf + $(INSTALL_DATA) $(CONF_FILES) $(RELSYSDIR)/examples/server_root/conf + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/htdocs/open + $(INSTALL_DATA) $(OPEN_FILES) \ + $(RELSYSDIR)/examples/server_root/htdocs/open + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/htdocs/mnesia_open + $(INSTALL_DATA) $(MNESIA_OPEN_FILES) \ + $(RELSYSDIR)/examples/server_root/htdocs/mnesia_open + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/htdocs/misc + $(INSTALL_DATA) $(MISC_FILES) \ + $(RELSYSDIR)/examples/server_root/htdocs/misc + $(INSTALL_DIR) \ + $(RELSYSDIR)/examples/server_root/htdocs/secret/top_secret + $(INSTALL_DIR) \ + $(RELSYSDIR)/examples/server_root/htdocs/mnesia_secret/top_secret + $(INSTALL_DATA) $(SECRET_FILES) \ + $(RELSYSDIR)/examples/server_root/htdocs/secret + $(INSTALL_DATA) $(MNESIA_SECRET_FILES) \ + $(RELSYSDIR)/examples/server_root/htdocs/mnesia_secret + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/htdocs + $(INSTALL_DATA) $(HTDOCS_FILES) $(RELSYSDIR)/examples/server_root/htdocs + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/icons + $(INSTALL_DATA) $(ICON_FILES) $(RELSYSDIR)/examples/server_root/icons + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/ssl + $(INSTALL_DATA) $(SSL_FILES) $(RELSYSDIR)/examples/server_root/ssl + $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/logs + +release_docs_spec: + diff --git a/lib/inets/test/httpd_test_lib.erl b/lib/inets/test/httpd_test_lib.erl index 6abee5be2c..3189a758a5 100644 --- a/lib/inets/test/httpd_test_lib.erl +++ b/lib/inets/test/httpd_test_lib.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% @@ -72,6 +72,8 @@ 'last-modified', other=[] % list() - Key/Value list with other headers }). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%-------------------------------------------------------------------- @@ -81,7 +83,8 @@ verify_request(SocketType, Host, Port, Node, RequestStr, Options) -> verify_request(SocketType, Host, Port, Node, RequestStr, Options, 30000). verify_request(SocketType, Host, Port, Node, RequestStr, Options, TimeOut) -> {ok, Socket} = inets_test_lib:connect_bin(SocketType, Host, Port), - inets_test_lib:send(SocketType, Socket, RequestStr), + + _SendRes = inets_test_lib:send(SocketType, Socket, RequestStr), State = case inets_regexp:match(RequestStr, "printenv") of nomatch -> @@ -90,18 +93,26 @@ verify_request(SocketType, Host, Port, Node, RequestStr, Options, TimeOut) -> #state{print = true} end, - case request(State#state{request = RequestStr, socket = Socket}, TimeOut) of - {error, Reson} -> - {error, Reson}; + case request(State#state{request = RequestStr, + socket = Socket}, TimeOut) of + {error, Reason} -> + tsp("request failed: " + "~n Reason: ~p", [Reason]), + {error, Reason}; NewState -> + tsp("validate reply: " + "~n NewState: ~p", [NewState]), ValidateResult = validate(RequestStr, NewState, Options, Node, Port), + tsp("validation result: " + "~n ~p", [ValidateResult]), inets_test_lib:close(SocketType, Socket), ValidateResult end. request(#state{mfa = {Module, Function, Args}, request = RequestStr, socket = Socket} = State, TimeOut) -> + HeadRequest = lists:sublist(RequestStr, 1, 4), receive {tcp, Socket, Data} -> @@ -109,12 +120,12 @@ request(#state{mfa = {Module, Function, Args}, case Module:Function([Data | Args]) of {ok, Parsed} -> handle_http_msg(Parsed, State); - {_, whole_body, _} when HeadRequest == "HEAD" -> + {_, whole_body, _} when HeadRequest =:= "HEAD" -> State#state{body = <<>>}; NewMFA -> request(State#state{mfa = NewMFA}, TimeOut) end; - {tcp_closed, Socket} when Function == whole_body -> + {tcp_closed, Socket} when Function =:= whole_body -> print(tcp, "closed", State), State#state{body = hd(Args)}; {tcp_closed, Socket} -> @@ -126,12 +137,12 @@ request(#state{mfa = {Module, Function, Args}, case Module:Function([Data | Args]) of {ok, Parsed} -> handle_http_msg(Parsed, State); - {_, whole_body, _} when HeadRequest == "HEAD" -> + {_, whole_body, _} when HeadRequest =:= "HEAD" -> State#state{body = <<>>}; NewMFA -> request(State#state{mfa = NewMFA}, TimeOut) end; - {ssl_closed, Socket} when Function == whole_body -> + {ssl_closed, Socket} when Function =:= whole_body -> print(ssl, "closed", State), State#state{body = hd(Args)}; {ssl_closed, Socket} -> @@ -330,3 +341,9 @@ print(Proto, Data, #state{print = true}) -> print(_, _, #state{print = false}) -> ok. + +%% tsp(F) -> +%% tsp(F, []). +tsp(F, A) -> + test_server:format("~p ~p:" ++ F ++ "~n", [self(), ?MODULE | A]). + diff --git a/lib/inets/test/httpd_time_test.erl b/lib/inets/test/httpd_time_test.erl index 7d6aa08542..f39f9faff0 100644 --- a/lib/inets/test/httpd_time_test.erl +++ b/lib/inets/test/httpd_time_test.erl @@ -1,25 +1,25 @@ %% %% %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 %% 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(httpd_time_test). --export([t/3, t1/2, t2/2]). +-export([t/3, t1/2, t2/2, t3/2, t4/2]). -export([do/1, do/2, do/3, do/4, do/5]). @@ -29,6 +29,9 @@ -record(stat, {pid, time = undefined, count = undefined, res}). +%% -define(NUM_POLLERS, 10). +-define(NUM_POLLERS, 1). + %%% ----------------------------------------------------------------- %%% Test suite interface @@ -42,9 +45,17 @@ t2(Host, Port) -> t(ssl, Host, Port). +t3(Host, Port) -> + t(ossl, Host, Port). + + +t4(Host, Port) -> + t(essl, Host, Port). + + t(SocketType, Host, Port) -> %% put(dbg,true), - main(1, SocketType, Host, Port, 60000). + main(?NUM_POLLERS, SocketType, Host, Port, 60000). @@ -111,28 +122,40 @@ loop(Pollers, Timeout) -> "~n Timeout: ~p", [Timeout]), Start = t(), receive - {'EXIT', Pid, {poller_stat_failure, Time, Reason}} -> + {'EXIT', Pid, {poller_stat_failure, SocketType, Host, Port, Time, Reason}} -> case is_poller(Pid, Pollers) of true -> error_msg("received unexpected exit from poller ~p~n" "befor completion of test " - "(after ~p micro sec):~n" - "~p~n", [Pid,Time,Reason]), - exit({fail, {poller_exit, Pid, Reason}}); + "after ~p micro sec" + "~n SocketType: ~p" + "~n Host: ~p" + "~n Port: ~p" + "~n~p~n", + [Pid, SocketType, Host, Port, Time, Reason]), + exit({fail, {poller_exit, Pid, Time, Reason}}); false -> error_msg("received unexpected ~p from ~p" "befor completion of test", [Reason, Pid]), loop(Pollers, to(Timeout, Start)) end; - {poller_stat_failure, Pid, {Time, Reason}} -> + {poller_stat_failure, Pid, {SocketType, Host, Port, Time, Reason}} -> error_msg("received stat failure ~p from poller ~p after ~p " - "befor completion of test", [Reason, Pid, Time]), - exit({fail, {poller_failure, Pid, Reason}}); - - {poller_stat_failure, Pid, Reason} -> + "befor completion of test" + "~n SocketType: ~p" + "~n Host: ~p" + "~n Port: ~p", + [Reason, Pid, Time, SocketType, Host, Port]), + exit({fail, {poller_failure, Pid, Time, Reason}}); + + {poller_stat_failure, Pid, SocketType, Host, Port, Reason} -> error_msg("received stat failure ~p from poller ~p " - "befor completion of test", [Reason, Pid]), + "befor completion of test" + "~n SocketType: ~p" + "~n Host: ~p" + "~n Port: ~p", + [Reason, Pid, SocketType, Host, Port]), exit({fail, {poller_failure, Pid, Reason}}); Any -> @@ -250,16 +273,16 @@ is_poller(Pid, [_|Rest]) -> poller_main(Parent, SocketType, Host, Port) -> process_flag(trap_exit,true), - put(sname,poller), + put(sname, poller), case timer:tc(?MODULE, poller_loop, [SocketType, Host, Port, uris()]) of {Time, Count} when is_integer(Time) andalso is_integer(Count) -> Parent ! {poller_statistics, self(), {Time, Count}}; {Time, {'EXIT', Reason}} when is_integer(Time) -> - exit({poller_stat_failure, Time, Reason}); + exit({poller_stat_failure, SocketType, Host, Port, Time, Reason}); {Time, Other} when is_integer(Time) -> - Parent ! {poller_stat_failure, self(), {Time, Other}}; + Parent ! {poller_stat_failure, self(), {SocketType, Host, Port, Time, Other}}; Else -> - Parent ! {poller_stat_failure, self(), Else} + Parent ! {poller_stat_failure, self(), SocketType, Host, Port, Else} end. diff --git a/lib/inets/test/inets_sup_SUITE.erl b/lib/inets/test/inets_sup_SUITE.erl index ba41e0960c..1e701bc074 100644 --- a/lib/inets/test/inets_sup_SUITE.erl +++ b/lib/inets/test/inets_sup_SUITE.erl @@ -372,11 +372,11 @@ httpc_subtree(Config) when is_list(Config) -> "~n Config: ~p", [Config]), tsp("httpc_subtree -> start inets service httpc with profile foo"), - {ok, Foo} = inets:start(httpc, [{profile, foo}]), + {ok, _Foo} = inets:start(httpc, [{profile, foo}]), tsp("httpc_subtree -> " "start stand-alone inets service httpc with profile bar"), - {ok, Bar} = inets:start(httpc, [{profile, bar}], stand_alone), + {ok, _Bar} = inets:start(httpc, [{profile, bar}], stand_alone), tsp("httpc_subtree -> retreive list of httpc instances"), HttpcChildren = supervisor:which_children(httpc_profile_sup), diff --git a/lib/inets/test/inets_test_lib.erl b/lib/inets/test/inets_test_lib.erl index 6af2ad32f7..86fc2d1a32 100644 --- a/lib/inets/test/inets_test_lib.erl +++ b/lib/inets/test/inets_test_lib.erl @@ -1,44 +1,136 @@ %% %% %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 %% 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(inets_test_lib). -include("inets_test_lib.hrl"). +-include_lib("inets/src/http_lib/http_internal.hrl"). %% Various small utility functions --export([start_http_server/1, start_http_server_ssl/1]). +-export([start_http_server/1, start_http_server/2]). +-export([start_http_server_ssl/1, start_http_server_ssl/2]). -export([hostname/0]). -export([connect_bin/3, connect_byte/3, send/3, close/2]). -export([copy_file/3, copy_files/2, copy_dirs/2, del_dirs/1]). -export([info/4, log/4, debug/4, print/4]). -export([check_body/1]). -export([millis/0, millis_diff/2, hours/1, minutes/1, seconds/1, sleep/1]). +-export([oscmd/1]). -export([non_pc_tc_maybe_skip/4, os_based_skip/1]). +-export([flush/0]). +-export([start_node/1, stop_node/1]). + +%% -- Misc os command and stuff + +oscmd(Cmd) -> + string:strip(os:cmd(Cmd), right, $\n). + +%% -- Misc node operation wrapper functions -- + +start_node(Name) -> + Pa = filename:dirname(code:which(?MODULE)), + Args = case init:get_argument('CC_TEST') of + {ok, [[]]} -> + " -pa /clearcase/otp/libraries/snmp/ebin "; + {ok, [[Path]]} -> + " -pa " ++ Path; + error -> + "" + end, + A = Args ++ " -pa " ++ Pa, + Opts = [{cleanup,false}, {args, A}], + case (catch test_server:start_node(Name, slave, Opts)) of + {ok, Node} -> + Node; + Else -> + exit({failed_starting_node, Name, Else}) + end. + +stop_node(Node) -> + rpc:cast(Node, erlang, halt, []), + await_stopped(Node, 5). + +await_stopped(_, 0) -> + ok; +await_stopped(Node, N) -> + Nodes = erlang:nodes(), + case lists:member(Node, Nodes) of + true -> + sleep(1000), + await_stopped(Node, N-1); + false -> + ok + end. + + +%% ---------------------------------------------------------------- +%% HTTPD starter functions +%% start_http_server(Conf) -> + start_http_server(Conf, ?HTTP_DEFAULT_SSL_KIND). + +start_http_server(Conf, essl = _SslTag) -> + application:start(crypto), + do_start_http_server(Conf); +start_http_server(Conf, _SslTag) -> + do_start_http_server(Conf). + +do_start_http_server(Conf) -> + tsp("start http server with " + "~n Conf: ~p" + "~n", [Conf]), application:load(inets), - ok = application:set_env(inets, services, [{httpd, Conf}]), - ok = application:start(inets). - + case application:set_env(inets, services, [{httpd, Conf}]) of + ok -> + case application:start(inets) of + ok -> + ok; + Error1 -> + test_server:format("<ERROR> Failed starting application: " + "~n Error: ~p" + "~n", [Error1]), + Error1 + end; + Error2 -> + test_server:format("<ERROR> Failed set application env: " + "~n Error: ~p" + "~n", [Error2]), + Error2 + end. + start_http_server_ssl(FileName) -> + start_http_server_ssl(FileName, ?HTTP_DEFAULT_SSL_KIND). + +start_http_server_ssl(FileName, essl = _SslTag) -> + application:start(crypto), + do_start_http_server_ssl(FileName); +start_http_server_ssl(FileName, _SslTag) -> + do_start_http_server_ssl(FileName). + +do_start_http_server_ssl(FileName) -> + tsp("start (ssl) http server with " + "~n FileName: ~p" + "~n", [FileName]), application:start(ssl), - catch start_http_server(FileName). + catch do_start_http_server(FileName). + %% ---------------------------------------------------------------------- %% print functions @@ -84,27 +176,17 @@ copy_files(FromDir, ToDir) -> copy_dirs(FromDirRoot, ToDirRoot) -> -%% io:format("~w:copy_dirs -> entry with" -%% "~n FromDirRoot: ~p" -%% "~n ToDirRoot: ~p" -%% "~n", [?MODULE, FromDirRoot, ToDirRoot]), {ok, Files} = file:list_dir(FromDirRoot), lists:foreach( fun(FileOrDir) -> %% Check if it's a directory or a file -%% io:format("~w:copy_dirs -> check ~p" -%% "~n", [?MODULE, FileOrDir]), case filelib:is_dir(filename:join(FromDirRoot, FileOrDir)) of true -> -%% io:format("~w:copy_dirs -> ~p is a directory" -%% "~n", [?MODULE, FileOrDir]), FromDir = filename:join([FromDirRoot, FileOrDir]), ToDir = filename:join([ToDirRoot, FileOrDir]), ok = file:make_dir(ToDir), copy_dirs(FromDir, ToDir); false -> -%% io:format("~w:copy_dirs -> ~p is a file" -%% "~n", [?MODULE, FileOrDir]), copy_file(FileOrDir, FromDirRoot, ToDirRoot) end end, Files). @@ -133,8 +215,8 @@ check_body(Body) -> 0 -> case string:rstr(Body, "</HTML>") of 0 -> - test_server:format("Body ~p~n", [Body]), - test_server:fail(did_not_receive_whole_body); + tsp("Body ~p", [Body]), + tsf(did_not_receive_whole_body); _ -> ok end; @@ -204,9 +286,31 @@ os_based_skip(_) -> %% Port -> integer() connect_bin(ssl, Host, Port) -> + connect(ssl, Host, Port, [binary, {packet,0}]); +connect_bin(ossl, Host, Port) -> + connect(ssl, Host, Port, [{ssl_imp, old}, binary, {packet,0}]); +connect_bin(essl, Host, Port) -> + connect(ssl, Host, Port, [{ssl_imp, new}, binary, {packet,0}, {reuseaddr, true}]); +connect_bin(ip_comm, Host, Port) -> + Opts = [inet6, binary, {packet,0}], + connect(ip_comm, Host, Port, Opts). + + +connect_byte(ssl, Host, Port) -> + connect(ssl, Host, Port, [{packet,0}]); +connect_byte(ossl, Host, Port) -> + connect(ssl, Host, Port, [{ssl_imp, old}, {packet,0}]); +connect_byte(essl, Host, Port) -> + connect(ssl, Host, Port, [{ssl_imp, new}, {packet,0}]); +connect_byte(ip_comm, Host, Port) -> + Opts = [inet6, {packet,0}], + connect(ip_comm, Host, Port, Opts). + + +connect(ssl, Host, Port, Opts) -> ssl:start(), %% Does not support ipv6 in old ssl - case ssl:connect(Host, Port, [binary, {packet,0}]) of + case ssl:connect(Host, Port, Opts) of {ok, Socket} -> {ok, Socket}; {error, Reason} -> @@ -214,61 +318,48 @@ connect_bin(ssl, Host, Port) -> Error -> Error end; -connect_bin(ip_comm, Host, Port) -> - Opts = [inet6, binary, {packet,0}], - connect(ip_comm, Host, Port, Opts). - - connect(ip_comm, Host, Port, Opts) -> - test_server:format("gen_tcp:connect(~p, ~p, ~p) ~n", [Host, Port, Opts]), case gen_tcp:connect(Host,Port, Opts) of {ok, Socket} -> - test_server:format("connect success~n", []), + %% tsp("connect success"), {ok, Socket}; {error, nxdomain} -> - test_server:format("nxdomain opts: ~p~n", [Opts]), + tsp("nxdomain opts: ~p", [Opts]), connect(ip_comm, Host, Port, lists:delete(inet6, Opts)); {error, eafnosupport} -> - test_server:format("eafnosupport opts: ~p~n", [Opts]), + tsp("eafnosupport opts: ~p", [Opts]), connect(ip_comm, Host, Port, lists:delete(inet6, Opts)); {error, {enfile,_}} -> - test_server:format("Error enfile~n", []), + tsp("Error enfile"), {error, enfile}; Error -> - test_server:format("Unexpected error: " - "~n Error: ~p" - "~nwhen" - "~n Host: ~p" - "~n Port: ~p" - "~n Opts: ~p" - "~n", [Error, Host, Port, Opts]), + tsp("Unexpected error: " + "~n Error: ~p" + "~nwhen" + "~n Host: ~p" + "~n Port: ~p" + "~n Opts: ~p" + "~n", [Error, Host, Port, Opts]), Error end. -connect_byte(ip_comm, Host, Port) -> - Opts = [inet6, {packet,0}], - connect(ip_comm, Host, Port, Opts); - -connect_byte(ssl, Host, Port) -> - ssl:start(), - %% Does not support ipv6 in old ssl - case ssl:connect(Host,Port,[{packet,0}]) of - {ok,Socket} -> - {ok,Socket}; - {error,{enfile,_}} -> - {error, enfile}; - Error -> - Error - end. send(ssl, Socket, Data) -> ssl:send(Socket, Data); +send(ossl, Socket, Data) -> + ssl:send(Socket, Data); +send(essl, Socket, Data) -> + ssl:send(Socket, Data); send(ip_comm,Socket,Data) -> gen_tcp:send(Socket,Data). close(ssl,Socket) -> catch ssl:close(Socket); +close(ossl,Socket) -> + catch ssl:close(Socket); +close(essl,Socket) -> + catch ssl:close(Socket); close(ip_comm,Socket) -> catch gen_tcp:close(Socket). @@ -300,3 +391,20 @@ sleep(MSecs) -> skip(Reason, File, Line) -> exit({skipped, {Reason, File, Line}}). + +flush() -> + receive + Msg -> + [Msg | flush()] + after 1000 -> + [] + end. + + +tsp(F) -> + tsp(F, []). +tsp(F, A) -> + test_server:format("~p ~p:" ++ F ++ "~n", [self(), ?MODULE | A]). + +tsf(Reason) -> + test_server:fail(Reason). diff --git a/lib/inets/test/inets_test_lib.hrl b/lib/inets/test/inets_test_lib.hrl index 12a43fa136..0cdb04139c 100644 --- a/lib/inets/test/inets_test_lib.hrl +++ b/lib/inets/test/inets_test_lib.hrl @@ -1,19 +1,19 @@ %% %% %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 %% 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,6 +46,11 @@ -endif. +%% - OS Command and stuff + +-define(OSCMD(Cmd), inets_test_lib:oscmd(Cmd)). + + %% - Test case macros - -define(EXPANDABLE(I, C, F), inets_test_lib:expandable(I, C, F)). diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk index 408f49c19f..5eff9e4e3f 100644 --- a/lib/inets/vsn.mk +++ b/lib/inets/vsn.mk @@ -1,77 +1,5 @@ APPLICATION = inets -INETS_VSN = 5.3.4 +INETS_VSN = 5.5 PRE_VSN = APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)" -TICKETS = OTP-8739 OTP-8741 OTP-8742 - -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 - diff --git a/lib/inviso/doc/src/notes.xml b/lib/inviso/doc/src/notes.xml index 443aaf523b..48a71e314c 100644 --- a/lib/inviso/doc/src/notes.xml +++ b/lib/inviso/doc/src/notes.xml @@ -31,7 +31,23 @@ <p>This document describes the changes made to the Inviso application.</p> - <section><title>Inviso 0.6.1</title> + <section><title>Inviso 0.6.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + The obsolete guards has now been changed to the new guard + interface.</p> + <p> + Own Id: OTP-8747</p> + </item> + </list> + </section> + +</section> + +<section><title>Inviso 0.6.1</title> <section><title>Improvements and New Features</title> <list> diff --git a/lib/inviso/src/inviso.erl b/lib/inviso/src/inviso.erl index de42926ffe..0eda06a5c2 100644 --- a/lib/inviso/src/inviso.erl +++ b/lib/inviso/src/inviso.erl @@ -129,7 +129,7 @@ start(Options) -> add_node(Reference) ->
gen_server:call(?CONTROLLER,{add_nodes,[node()],[],Reference,any_ref},?CALL_TIMEOUT).
-add_node(Reference,Options) when list(Options) ->
+add_node(Reference,Options) when is_list(Options) -> gen_server:call(?CONTROLLER,{add_nodes,[node()],Options,Reference,any_ref},?CALL_TIMEOUT).
%% -----------------------------------------------------------------------------
@@ -142,7 +142,7 @@ add_node(Reference,Options) when list(Options) -> add_node_if_ref(Reference) ->
gen_server:call(?CONTROLLER,{add_nodes,[node()],[],Reference,if_ref},?CALL_TIMEOUT).
-add_node_if_ref(Reference,Options) when list(Options) ->
+add_node_if_ref(Reference,Options) when is_list(Options) -> gen_server:call(?CONTROLLER,{add_nodes,[node()],Options,Reference,if_ref},?CALL_TIMEOUT).
%% -----------------------------------------------------------------------------
@@ -156,10 +156,10 @@ add_node_if_ref(Reference,Options) when list(Options) -> %% system. By speicifying node() as the node where the runtime component shall
%% be started. The return value will then follow the rules of non distributed
%% returnvalues and not have a node indicator.
-add_nodes(Nodes,Reference) when list(Nodes) ->
+add_nodes(Nodes,Reference) when is_list(Nodes) -> gen_server:call(?CONTROLLER,{add_nodes,Nodes,[],Reference,any_ref},?CALL_TIMEOUT).
-add_nodes(Nodes,Reference,Options) when list(Nodes),list(Options) ->
+add_nodes(Nodes,Reference,Options) when is_list(Nodes),is_list(Options) -> gen_server:call(?CONTROLLER,{add_nodes,Nodes,Options,Reference,any_ref},?CALL_TIMEOUT).
%% -----------------------------------------------------------------------------
@@ -168,10 +168,10 @@ add_nodes(Nodes,Reference,Options) when list(Nodes),list(Options) -> %%
%% As add_nodes/2,/3 but will only connect to an already existing runtime component
%% if its reference is the same as the one given as argument.
-add_nodes_if_ref(Nodes,Reference) when list(Nodes) ->
+add_nodes_if_ref(Nodes,Reference) when is_list(Nodes) -> gen_server:call(?CONTROLLER,{add_nodes,Nodes,[],Reference,if_ref},?CALL_TIMEOUT).
-add_nodes_if_ref(Nodes,Reference,Options) when list(Nodes),list(Options) ->
+add_nodes_if_ref(Nodes,Reference,Options) when is_list(Nodes),is_list(Options) -> gen_server:call(?CONTROLLER,{add_nodes,Nodes,Options,Reference,if_ref},?CALL_TIMEOUT).
%% -----------------------------------------------------------------------------
@@ -182,9 +182,9 @@ add_nodes_if_ref(Nodes,Reference,Options) when list(Nodes),list(Options) -> %%
%% Change options on all or specified Nodes. This may result in for instance
%% reinitialization of overloadcheck.
-change_options(Options) when list(Options) ->
+change_options(Options) when is_list(Options) -> gen_server:call(?CONTROLLER,{change_options,all,Options},?CALL_TIMEOUT).
-change_options(Nodes,Options) when list(Nodes),list(Options) ->
+change_options(Nodes,Options) when is_list(Nodes),is_list(Options) -> gen_server:call(?CONTROLLER,{change_options,Nodes,Options},?CALL_TIMEOUT).
%% -----------------------------------------------------------------------------
@@ -234,7 +234,7 @@ change_options(Nodes,Options) when list(Nodes),list(Options) -> init_tracing(TracerDataList) ->
gen_server:call(?CONTROLLER,{init_tracing,TracerDataList},?CALL_TIMEOUT).
-init_tracing(Nodes,TracerData) when list(Nodes) ->
+init_tracing(Nodes,TracerData) when is_list(Nodes) -> gen_server:call(?CONTROLLER,{init_tracing,Nodes,TracerData},?CALL_TIMEOUT).
%% -----------------------------------------------------------------------------
@@ -270,10 +270,10 @@ stop_tracing(Nodes) when is_list(Nodes) -> clear() ->
gen_server:call(?CONTROLLER,{clear,all,[]},?CALL_TIMEOUT).
-clear(Nodes) when list(Nodes) ->
+clear(Nodes) when is_list(Nodes) -> gen_server:call(?CONTROLLER,{clear,Nodes,[]},?CALL_TIMEOUT).
-clear(Nodes,Options) when list(Nodes),list(Options) ->
+clear(Nodes,Options) when is_list(Nodes),is_list(Options) -> gen_server:call(?CONTROLLER,{clear,Nodes,Options},?CALL_TIMEOUT).
%% -----------------------------------------------------------------------------
@@ -355,9 +355,9 @@ stop_all() -> tp(Nodes,Module,Function,Arity,MatchSpec,Opts) ->
trace_pattern(Nodes,[{Module,Function,Arity,MatchSpec,Opts}],[global]).
-tp(Nodes,Module,Function,Arity,MatchSpec) when list(Nodes) ->
+tp(Nodes,Module,Function,Arity,MatchSpec) when is_list(Nodes) -> trace_pattern(Nodes,[{Module,Function,Arity,MatchSpec,[]}],[global]);
-tp(Module,Function,Arity,MatchSpec,Opts) when atom(Module) ->
+tp(Module,Function,Arity,MatchSpec,Opts) when is_atom(Module) -> trace_pattern(all,[{Module,Function,Arity,MatchSpec,Opts}],[global]).
tp(Module,Function,Arity,MatchSpec) ->
@@ -384,9 +384,9 @@ tp(PatternList) -> tpl(Nodes,Module,Function,Arity,MatchSpec,Opts) ->
trace_pattern(Nodes,[{Module,Function,Arity,MatchSpec,Opts}],[local]).
-tpl(Nodes,Module,Function,Arity,MatchSpec) when list(Nodes) ->
+tpl(Nodes,Module,Function,Arity,MatchSpec) when is_list(Nodes) -> trace_pattern(Nodes,[{Module,Function,Arity,MatchSpec,[]}],[local]);
-tpl(Module,Function,Arity,MatchSpec,Opts) when atom(Module) ->
+tpl(Module,Function,Arity,MatchSpec,Opts) when is_atom(Module) -> trace_pattern(all,[{Module,Function,Arity,MatchSpec,Opts}],[local]).
tpl(Module,Function,Arity,MatchSpec) ->
@@ -417,12 +417,12 @@ ctp(Nodes,Module,Function,Arity) -> ctp(Module,Function,Arity) ->
trace_pattern(all,[{Module,Function,Arity,false,[only_loaded]}],[global]).
-ctp(Nodes,PatternList) when list(PatternList) ->
+ctp(Nodes,PatternList) when is_list(PatternList) -> trace_pattern(Nodes,
lists:map(fun({M,F,A})->{M,F,A,false,[only_loaded]} end,PatternList),
[global]).
-ctp(PatternList) when list(PatternList) ->
+ctp(PatternList) when is_list(PatternList) -> trace_pattern(all,
lists:map(fun({M,F,A})->{M,F,A,false,[only_loaded]} end,PatternList),
[global]).
@@ -445,12 +445,12 @@ ctpl(Nodes,Module,Function,Arity) -> ctpl(Module,Function,Arity) ->
trace_pattern(all,[{Module,Function,Arity,false,[only_loaded]}],[local]).
-ctpl(Nodes,PatternList) when list(PatternList) ->
+ctpl(Nodes,PatternList) when is_list(PatternList) -> trace_pattern(Nodes,
lists:map(fun({M,F,A})->{M,F,A,false,[only_loaded]} end,PatternList),
[local]).
-ctpl(PatternList) when list(PatternList) ->
+ctpl(PatternList) when is_list(PatternList) -> trace_pattern(all,
lists:map(fun({M,F,A})->{M,F,A,false,[only_loaded]} end,PatternList),
[local]).
@@ -485,19 +485,19 @@ trace_pattern(Nodes,Patterns,FlagList) -> %% specifying a certain pid at all nodes. Or an empty TraceConfList for all
%% nodes.
%% When calling several nodes, the nodes are called in parallel.
-tf(Nodes,PidSpec,FlagList) when list(Nodes),list(FlagList) ->
+tf(Nodes,PidSpec,FlagList) when is_list(Nodes),is_list(FlagList) -> trace_flags(Nodes,[{PidSpec, FlagList}],true).
-tf(Nodes,TraceConfList) when list(Nodes),list(TraceConfList) ->
+tf(Nodes,TraceConfList) when is_list(Nodes),is_list(TraceConfList) -> trace_flags(Nodes,TraceConfList,true);
-tf(PidSpec,FlagList) when list(FlagList) ->
+tf(PidSpec,FlagList) when is_list(FlagList) -> trace_flags(all,[{PidSpec,FlagList}],true).
-tf(ArgList) when list(ArgList) -> % This one has triple functionality!
+tf(ArgList) when is_list(ArgList) -> % This one has triple functionality! case ArgList of
- [{_Process,Flags}|_] when list(Flags),atom(hd(Flags))-> % A call to all nodes.
+ [{_Process,Flags}|_] when is_list(Flags),is_atom(hd(Flags))-> % A call to all nodes. trace_flags(all,ArgList,true);
- [{_Node,TraceConfList}|_] when list(TraceConfList),tuple(hd(TraceConfList)) ->
+ [{_Node,TraceConfList}|_] when is_list(TraceConfList),is_tuple(hd(TraceConfList)) -> trace_flags(ArgList,true);
[{_Node,_TraceConfList,_How}|_] ->
trace_flags(ArgList);
@@ -517,15 +517,15 @@ tf(ArgList) when list(ArgList) -> % This one has triple functionality %% The functions without a Nodes argument means all nodes, in a non-distributed
%% environment it means the local node.
%% When calling several nodes, the nodes are called in parallel.
-ctf(Nodes,PidSpec,FlagList) when list(Nodes),list(FlagList) ->
+ctf(Nodes,PidSpec,FlagList) when is_list(Nodes),is_list(FlagList) -> trace_flags(Nodes,[{PidSpec,FlagList}],false).
-ctf(Nodes,TraceConfList) when list(Nodes),list(TraceConfList) ->
+ctf(Nodes,TraceConfList) when is_list(Nodes),is_list(TraceConfList) -> trace_flags(Nodes,TraceConfList,false);
-ctf(PidSpec,FlagList) when list(FlagList) ->
+ctf(PidSpec,FlagList) when is_list(FlagList) -> trace_flags(all,[{PidSpec,FlagList}],false).
-ctf(TraceConfList) when list(TraceConfList) ->
+ctf(TraceConfList) when is_list(TraceConfList) -> trace_flags(all,TraceConfList,false).
%% -----------------------------------------------------------------------------
@@ -668,10 +668,10 @@ init_tpm(Nodes,Mod,Func,Arity,InitFunc,CallFunc,ReturnFunc,RemoveFunc) -> tpm(Mod,Func,Arity,MS) ->
tpm(all,Mod,Func,Arity,MS).
-tpm(Nodes,Mod,Func,Arity,MS) when integer(Arity) ->
+tpm(Nodes,Mod,Func,Arity,MS) when is_integer(Arity) -> gen_server:call(?CONTROLLER,
{meta_pattern,Nodes,{tpm,[Mod,Func,Arity,MS]}});
-tpm(Mod,Func,Arity,MS,CallFunc) when integer(Arity) ->
+tpm(Mod,Func,Arity,MS,CallFunc) when is_integer(Arity) -> tpm(all,Mod,Func,Arity,MS,CallFunc).
tpm(Nodes,Mod,Func,Arity,MS,CallFunc) ->
@@ -695,11 +695,11 @@ tpm(Nodes,Mod,Func,Arity,MS,InitFunc,CallFunc,ReturnFunc,RemoveFunc) -> tpm_tracer(Mod,Func,Arity,MS) ->
tpm_tracer(all,Mod,Func,Arity,MS).
-tpm_tracer(Nodes,Mod,Func,Arity,MS) when integer(Arity) ->
+tpm_tracer(Nodes,Mod,Func,Arity,MS) when is_integer(Arity) -> gen_server:call(?CONTROLLER,
{meta_pattern,Nodes,{tpm_tracer,[Mod,Func,Arity,MS]}},
?CALL_TIMEOUT);
-tpm_tracer(Mod,Func,Arity,MS,CallFunc) when integer(Arity) ->
+tpm_tracer(Mod,Func,Arity,MS,CallFunc) when is_integer(Arity) -> tpm_tracer(all,Mod,Func,Arity,MS,CallFunc).
tpm_tracer(Nodes,Mod,Func,Arity,MS,CallFunc) ->
@@ -878,7 +878,7 @@ cancel_suspension() -> %% Status=running|{suspended,SReason}
%%
%% Get Status form all or specified runtime components.
-get_status(Nodes) when list(Nodes) ->
+get_status(Nodes) when is_list(Nodes) -> gen_server:call(?CONTROLLER,{get_status,Nodes},?CALL_TIMEOUT).
get_status() ->
@@ -918,7 +918,7 @@ get_tracerdata(Nodes) when is_list(Nodes) -> list_logs() ->
gen_server:call(?CONTROLLER,list_logs,?CALL_TIMEOUT).
-list_logs(TracerDataOrNodesList) when list(TracerDataOrNodesList) ->
+list_logs(TracerDataOrNodesList) when is_list(TracerDataOrNodesList) -> gen_server:call(?CONTROLLER,{list_logs,TracerDataOrNodesList},?CALL_TIMEOUT).
%% ------------------------------------------------------------------------------
@@ -960,17 +960,17 @@ list_logs(TracerDataOrNodesList) when list(TracerDataOrNodesList) -> %% Note that the client process using this function will wait until all files
%% are moved. The job can be cancelled, causing any already copied files to be
%% removed, by simply terminating the waiting client process.
-fetch_log(DestDir,Prefix) when list(DestDir),list(Prefix) ->
+fetch_log(DestDir,Prefix) when is_list(DestDir),is_list(Prefix) -> gen_server:call(?CONTROLLER,{fetch_log,node(),all,DestDir,Prefix},infinity).
-fetch_log(ToNode,DestDir,Prefix) when atom(ToNode),list(DestDir),list(Prefix) ->
+fetch_log(ToNode,DestDir,Prefix) when is_atom(ToNode),is_list(DestDir),is_list(Prefix) -> gen_server:call(?CONTROLLER,{fetch_log,ToNode,all,DestDir,Prefix},infinity);
-fetch_log(LogSpecList,DestDir,Prefix) when list(LogSpecList),list(DestDir),list(Prefix) ->
+fetch_log(LogSpecList,DestDir,Prefix) when is_list(LogSpecList),is_list(DestDir),is_list(Prefix) -> gen_server:call(?CONTROLLER,{fetch_log,node(),LogSpecList,DestDir,Prefix},infinity).
fetch_log(ToNode,LogSpecList,DestDir,Prefix)
- when atom(ToNode),list(LogSpecList),list(DestDir),list(Prefix) ->
+ when is_atom(ToNode),is_list(LogSpecList),is_list(DestDir),is_list(Prefix) -> gen_server:call(?CONTROLLER,{fetch_log,ToNode,LogSpecList,DestDir,Prefix},infinity).
%% ------------------------------------------------------------------------------
diff --git a/lib/inviso/src/inviso_c.erl b/lib/inviso/src/inviso_c.erl index ecbd5b0778..b1597a7f35 100644 --- a/lib/inviso/src/inviso_c.erl +++ b/lib/inviso/src/inviso_c.erl @@ -100,7 +100,7 @@ init({_Parent,Options}) -> end. %% ------------------------------------------------------------------------------ -handle_call({subscribe,Pid},_From,LD) when pid(Pid) -> +handle_call({subscribe,Pid},_From,LD) when is_pid(Pid) -> MRef=erlang:monitor(process,Pid), {reply,ok,LD#state{subscribers=[{Pid,MRef}|LD#state.subscribers]}}; handle_call({subscribe,Faulty},_From,LD) -> @@ -131,7 +131,7 @@ handle_call({change_options,Nodes,Opts},_From,LD) -> end; handle_call({init_tracing,TracerDataList},_From,LD) -> {reply,adapt_reply(LD,do_init_tracing(TracerDataList,LD)),LD}; -handle_call({init_tracing,Nodes,TracerData},_From,LD) when list(Nodes) -> +handle_call({init_tracing,Nodes,TracerData},_From,LD) when is_list(Nodes) -> TracerDataList= lists:map(fun(N)->{N,TracerData} end,started_trace_nodes(Nodes,LD)), {reply,adapt_reply(LD,do_init_tracing(TracerDataList,LD)),LD}; @@ -173,7 +173,7 @@ handle_call({fetch_log,ToNode,Spec,Dest,Prefix},From,LD) -> end; handle_call({delete_log,NodesOrNodeSpecs},_From,LD) -> {reply,adapt_reply(LD,do_delete_log(NodesOrNodeSpecs,LD)),LD}; -handle_call({delete_log,Nodes,Specs},_From,LD) when list(Nodes) -> +handle_call({delete_log,Nodes,Specs},_From,LD) when is_list(Nodes) -> Reply=do_delete_log(lists:map(fun(N)->{N,Specs} end,Nodes),LD), {reply,adapt_reply(LD,Reply),LD}; handle_call({delete_log,FaultyNodes,_Specs},_From,LD) -> @@ -283,7 +283,7 @@ do_change_option(Nodes,Options,LD) -> do_change_option_2([Node|Tail],Options,LD,Replies) -> case get_node_rec(Node,LD) of - Rec when record(Rec,node) -> + Rec when is_record(Rec,node) -> Answer=?RUNTIME:change_options(Rec#node.pid,Options), do_change_option_2(Tail,Options,LD,[{Node,Answer}|Replies]); Error -> @@ -333,7 +333,7 @@ do_init_tracing_2(What,_LD,_) -> %% Returns {ok,Reply} or {error,Reason}. distribute_tp(all,Patterns,FlagList,LD) -> distribute_tp(started_trace_nodes(all,LD),Patterns,FlagList,LD); -distribute_tp(Nodes,Patterns,FlagList,LD) when list(Nodes) -> +distribute_tp(Nodes,Patterns,FlagList,LD) when is_list(Nodes) -> RTpids=lists:map(fun(N)->case get_node_rec(N,LD) of #node{pid=Pid} -> {Pid,N}; @@ -354,7 +354,7 @@ distribute_tp(Faulty,_,_,_) -> %% Returns {ok,Reply} or {error,Reason}. distribute_tf(all,Args,How,LD) -> distribute_tf(started_trace_nodes(all,LD),Args,How,LD); -distribute_tf(Nodes,Args,How,LD) when list(Nodes) -> +distribute_tf(Nodes,Args,How,LD) when is_list(Nodes) -> RTpids=lists:map(fun(Node)-> case get_node_rec(Node,LD) of #node{pid=Pid} -> @@ -369,7 +369,7 @@ distribute_tf(Faulty,_,_,_) -> {error,{badarg,Faulty}}. %% As above but specific args for each node. -distribute_tf(NodeArgs,How,LD) when list(NodeArgs) -> +distribute_tf(NodeArgs,How,LD) when is_list(NodeArgs) -> RTpidArgs=lists:map(fun({Node,Args})-> case get_node_rec(Node,LD) of #node{pid=Pid} -> @@ -384,7 +384,7 @@ distribute_tf(Faulty,_,_) -> {error,{badarg,Faulty}}. %% As above but both specific args for each node and How (set or remove flag). -distribute_tf(NodeArgHows,LD) when list(NodeArgHows) -> +distribute_tf(NodeArgHows,LD) when is_list(NodeArgHows) -> RTpidArgHows= lists:map(fun({Node,Args,How}) -> case get_node_rec(Node,LD) of @@ -405,7 +405,7 @@ distribute_tf(Faulty,_) -> %% Returns {ok,Reply} or {error,Reason}. distribute_metapattern(all,Args,LD) -> distribute_metapattern(started_trace_nodes(all,LD),Args,LD); -distribute_metapattern(Nodes,Args,LD) when list(Nodes) -> +distribute_metapattern(Nodes,Args,LD) when is_list(Nodes) -> RTpids=lists:map(fun(N)->case get_node_rec(N,LD) of #node{pid=Pid} -> {Pid,N}; @@ -480,7 +480,7 @@ do_cancel_suspension_2(Faulty,_,_) -> %% Return {ok,Reply} or {error,Reason}. do_stop_tracing(all,LD) -> do_stop_tracing(started_trace_nodes(all,LD),LD); -do_stop_tracing(Nodes,LD) when list(Nodes) -> +do_stop_tracing(Nodes,LD) when is_list(Nodes) -> RTpids=lists:map(fun(N)->case get_node_rec(N,LD) of #node{pid=Pid} -> {Pid,N}; @@ -580,7 +580,7 @@ do_list_logs_2(Other,_LD,_Replies) -> %% proper strings. do_fetch_log(ToNode,all,Dest,Prefix,From,LD) -> do_fetch_log(ToNode,started_trace_nodes(all,LD),Dest,Prefix,From,LD); -do_fetch_log(ToNode,Specs,Dest,Prefix,From,LD) when list(Dest),list(Prefix) -> +do_fetch_log(ToNode,Specs,Dest,Prefix,From,LD) when is_list(Dest),is_list(Prefix) -> CollectPid=spawn_link(ToNode,?MODULE,log_rec_init,[self(),Dest,Prefix,From]), do_fetch_log_2(Specs,LD,CollectPid,[],[]); do_fetch_log(_ToNode,_Specs,Dest,Prefix,From,_LD) -> @@ -639,7 +639,7 @@ do_delete_log(NodeSpecs,LD) -> LD,[]); false -> if - list(NodeSpecs),list(hd(NodeSpecs)) -> % A list of files. + is_list(NodeSpecs),is_list(hd(NodeSpecs)) -> % A list of files. do_delete_log_2(lists:map(fun(N)->{N,NodeSpecs} end, started_trace_nodes(all,LD)), LD,[]); @@ -785,9 +785,9 @@ check_options(Options, Context) -> check_options_2([],_Context,Result) -> {ok,Result}; -check_options_2([{subscribe,Pid}|OptionsTail],start,Result) when pid(Pid) -> +check_options_2([{subscribe,Pid}|OptionsTail],start,Result) when is_pid(Pid) -> check_options_2(OptionsTail,start,[{subscribe,Pid}|Result]); -check_options_2([{unsubscribe,Pid}|OptionsTail],start,Result) when pid(Pid) -> +check_options_2([{unsubscribe,Pid}|OptionsTail],start,Result) when is_pid(Pid) -> check_options_2(OptionsTail,start,[{unsubscribe,Pid}|Result]); check_options_2([{dependency,How}|OptionsTail],Context,Result) -> check_options_2(OptionsTail,Context,[{dependency,How}|Result]); @@ -819,12 +819,12 @@ initiate_state(Options) -> LD1#state{distributed=true} end. -initiate_state_2([{subscribe,Proc}|Tail],LD) when pid(Proc);atom(Proc)-> +initiate_state_2([{subscribe,Proc}|Tail],LD) when is_pid(Proc);is_atom(Proc)-> MRef=erlang:monitor(process,Proc), initiate_state_2(Tail,LD#state{subscribers=[{Proc,MRef}|LD#state.subscribers]}); -initiate_state_2([Opt|Tail],LD) when tuple(Opt),size(Opt)>=1 -> +initiate_state_2([Opt|Tail],LD) when is_tuple(Opt),size(Opt)>=1 -> initiate_state_2(Tail,initiate_state_3(element(1,Opt),Opt,LD)); -initiate_state_2([Opt|Tail],LD) when atom(Opt) -> +initiate_state_2([Opt|Tail],LD) when is_atom(Opt) -> initiate_state_2(Tail,initiate_state_3(Opt,Opt,LD)); initiate_state_2([_|Tail],LD) -> initiate_state_2(Tail,LD); @@ -853,9 +853,9 @@ initiate_state_is_rt_option(_) -> false. %% or more values associated with the Parameter, or just an atom. merge_options([], Options) -> Options; -merge_options([T|DefaultTail],Options) when tuple(T),size(T)>=1 -> +merge_options([T|DefaultTail],Options) when is_tuple(T),size(T)>=1 -> merge_options(DefaultTail,merge_options_2(element(1,T),T,Options)); -merge_options([Param|DefaultTail],Options) when atom(Param) -> +merge_options([Param|DefaultTail],Options) when is_atom(Param) -> merge_options(DefaultTail,merge_options_2(Param,Param,Options)); merge_options([_|DefaultTail],Options) -> % Strange, bad default option! merge_options(DefaultTail,Options). @@ -868,7 +868,7 @@ merge_options_2(Param,Opt,Options) -> [Opt|Options] end. -merge_options_find(Param,[T|_]) when tuple(T),element(1,T)==Param -> +merge_options_find(Param,[T|_]) when is_tuple(T),element(1,T)==Param -> true; merge_options_find(Param,[Param|_]) -> true; @@ -883,7 +883,7 @@ merge_options_find(_,[]) -> %% It also checks the formatting of the tracerdata since runtime components %% does not accept too badly formatted tracerdata. %% Returns {ok,NewTraceData} or {error,Reason}. -check_modify_tracerdata(TracerData,LoopData) when list(TracerData) -> +check_modify_tracerdata(TracerData,LoopData) when is_list(TracerData) -> case lists:keysearch(trace,1,TracerData) of {value,{_,TraceTD}} -> % Examine the trace part. case check_modify_tracerdata(TraceTD,LoopData) of @@ -908,7 +908,7 @@ check_modify_tracerdata({relayer,Collector},LoopData) when is_atom(Collector) -> end; check_modify_tracerdata({Type,Data},_LoopData) when Type==ip;Type==file -> {ok,{Type,Data}}; -check_modify_tracerdata({Handler,Data},_LoopData) when function(Handler) -> +check_modify_tracerdata({Handler,Data},_LoopData) when is_function(Handler) -> {ok,{Handler,Data}}; check_modify_tracerdata(Data,_LoopData) -> {error,{bad_tracerdata,Data}}. @@ -999,7 +999,7 @@ set_node_rec_2(Rec,[NodeRec|Tail]) -> %% Help function finding a node record for Node in a list of #node or in loopdata. %% Returns the #node in question or {error,not_an_added_node}. -get_node_rec(Node,NodeList) when list(NodeList) -> +get_node_rec(Node,NodeList) when is_list(NodeList) -> get_node_rec_2(Node,NodeList); get_node_rec(Node,#state{nodes=NodeList}) -> get_node_rec_2(Node,NodeList). @@ -1016,7 +1016,7 @@ get_node_rec_2(Node,[_NodeRec|Tail]) -> %% structure. Returns a new list of #node or a new loopdata structure. delete_node_rec(Node,LD=#state{nodes=NodeList}) -> LD#state{nodes=delete_node_rec_2(Node,NodeList)}; -delete_node_rec(Node,NodeList) when list(NodeList) -> +delete_node_rec(Node,NodeList) when is_list(NodeList) -> delete_node_rec_2(Node,NodeList). delete_node_rec_2(_,[]) -> @@ -1059,7 +1059,7 @@ log_rec_init(Parent,Dest,Prefix,From={ClientPid,_}) -> Fetchers), CMRef=erlang:monitor(process,ClientPid), % Monitor the client. case log_rec_loop(Dest,Prefix,RTs,InitialReplies,CMRef) of - Reply when list(Reply) -> % It is an ok value. + Reply when is_list(Reply) -> % It is an ok value. gen_server:reply(From,{ok,Reply}); {error,Reason} -> gen_server:reply(From,{error,Reason}); diff --git a/lib/inviso/src/inviso_lfm.erl b/lib/inviso/src/inviso_lfm.erl index 362176c776..085048518c 100644 --- a/lib/inviso/src/inviso_lfm.erl +++ b/lib/inviso/src/inviso_lfm.erl @@ -87,13 +87,13 @@ %% close the outfile.
%%
%% Using merge/2 assumes you want to use default handlers writing to a file.
-merge(Files,OutputFile) when list(OutputFile) ->
+merge(Files,OutputFile) when is_list(OutputFile) -> merge(Files,fun outfile_opener/1,fun outfile_writer/4,fun outfile_closer/1,OutputFile,off).
-merge(Files,WorkHandlerFun,HandlerData) when function(WorkHandlerFun) ->
+merge(Files,WorkHandlerFun,HandlerData) when is_function(WorkHandlerFun) -> merge(Files,void,WorkHandlerFun,void,HandlerData,off);
-merge(Files,OutputFile,Dbg) when list(OutputFile) ->
+merge(Files,OutputFile,Dbg) when is_list(OutputFile) -> merge(Files,fun outfile_opener/1,fun outfile_writer/4,fun outfile_closer/1,OutputFile,Dbg).
-merge(Files,WorkHandlerFun,HandlerData,Dbg) when function(WorkHandlerFun) ->
+merge(Files,WorkHandlerFun,HandlerData,Dbg) when is_function(WorkHandlerFun) -> merge(Files,void,WorkHandlerFun,void,HandlerData,Dbg).
merge(Files,BeginHandlerFun,WorkHandlerFun,EndHandlerFun,HandlerData) ->
merge(Files,BeginHandlerFun,WorkHandlerFun,EndHandlerFun,HandlerData,off).
@@ -123,7 +123,7 @@ init_receiver(From,Files,BeginHandlerFun,WorkHandlerFun,EndHandlerFun,HandlerDat {ok,Readers} ->
process_flag(trap_exit,true),
if
- function(BeginHandlerFun) ->
+ is_function(BeginHandlerFun) -> case catch BeginHandlerFun(HandlerData) of
{ok,NewHandlerData} ->
init_receiver_2(From,WorkHandlerFun,EndHandlerFun,
@@ -145,7 +145,7 @@ init_receiver_2(From,WorkHandlerFun,EndHandlerFun,HandlerData,Dbg,Readers) -> {Reply,NewHandlerData}=
loop(From,WorkHandlerFun,HandlerData,NewReaders,EntryStruct,Dbg,0),
if
- function(EndHandlerFun) ->
+ is_function(EndHandlerFun) -> case EndHandlerFun(NewHandlerData) of
ok ->
From ! {reply,self(),Reply};
@@ -207,7 +207,7 @@ find_oldest_entry(EntryStruct) -> case list_all_entries(EntryStruct) of
[] -> % The we are done!
done;
- EntryList when list(EntryList) -> % Find smallest timestamp in here then.
+ EntryList when is_list(EntryList) -> % Find smallest timestamp in here then. {Pid,Node,PidMappings,_TS,Term}=
lists:foldl(fun({P,N,PMap,TS1,T},{_P,_N,_PMap,TS0,_T}) when TS1<TS0 ->
{P,N,PMap,TS1,T};
diff --git a/lib/inviso/src/inviso_lfm_tpfreader.erl b/lib/inviso/src/inviso_lfm_tpfreader.erl index d0db4b6d02..6de4d11fe0 100644 --- a/lib/inviso/src/inviso_lfm_tpfreader.erl +++ b/lib/inviso/src/inviso_lfm_tpfreader.erl @@ -60,9 +60,9 @@ %% File=string()
%% Spawn on this function to start a reader process for trace-port generated
%% logfiles, possibly with inviso-generated ti-files.
-init(RecPid,LogFiles=[Tuple|_]) when tuple(Tuple) -> % Only one LogFiles.
+init(RecPid,LogFiles=[Tuple|_]) when is_tuple(Tuple) -> % Only one LogFiles. init(RecPid,[LogFiles]);
-init(RecPid,FileStruct) when list(FileStruct) ->
+init(RecPid,FileStruct) when is_list(FileStruct) -> logfiles_loop(RecPid,FileStruct).
%% -----------------------------------------------------------------------------
@@ -135,7 +135,7 @@ read_traceport_file(FileName,FD) -> case file:read(FD,5) of % Trace-port file entries start with 5 bytes.
{ok,<<0,Size:32>>} -> % Each entry in a traceport file begins.
case file:read(FD,Size) of
- {ok,Bin} when binary(Bin),size(Bin)=:=Size ->
+ {ok,Bin} when is_binary(Bin),size(Bin)=:=Size -> try binary_to_term(Bin) of
Term -> % Bin was a properly formatted term!
{ok,Term}
@@ -244,7 +244,7 @@ find_timestamp_in_term(_) -> % Don't know if there is a timestamp %% (1) plain straight raw binary files.
handle_ti_file(FileStruct) ->
case lists:keysearch(ti_log,1,FileStruct) of
- {value,{_,[FileName]}} when list(FileName) -> % There is one ti-file in this set.
+ {value,{_,[FileName]}} when is_list(FileName) -> % There is one ti-file in this set. case file:open(FileName,[read,raw,binary]) of
{ok,FD} ->
TIdAlias=ets:new(list_to_atom("inviso_ti_atab_"++pid_to_list(self())),
@@ -308,9 +308,9 @@ handle_ti_file_2(FD,TIdAlias,TIdUnalias) -> handle_logfiles(FileStruct) ->
handle_logfiles_2(lists:keysearch(trace_log,1,FileStruct)).
-handle_logfiles_2({value,{_,[FileName]}}) when list(FileName)-> % One single plain file.
+handle_logfiles_2({value,{_,[FileName]}}) when is_list(FileName)-> % One single plain file. [FileName];
-handle_logfiles_2({value,{_,Files}}) when list(Files) -> % A wrap-set.
+handle_logfiles_2({value,{_,Files}}) when is_list(Files) -> % A wrap-set. handle_logfile_sort_wrapset(Files);
handle_logfiles_2(_) ->
[]. % Pretend there were no files otherwise.
diff --git a/lib/inviso/src/inviso_tool.erl b/lib/inviso/src/inviso_tool.erl index 7126ba4387..05158f58fe 100644 --- a/lib/inviso/src/inviso_tool.erl +++ b/lib/inviso/src/inviso_tool.erl @@ -267,9 +267,9 @@ stop(UntouchedNodes) -> %% tracing.
reconnect_nodes() ->
gen_server:call(?MODULE,{reconnect_nodes,local_runtime},?CALL_TIMEOUT).
-reconnect_nodes(Node) when atom(Node) ->
+reconnect_nodes(Node) when is_atom(Node) -> reconnect_nodes([Node]);
-reconnect_nodes(Nodes) when list(Nodes) ->
+reconnect_nodes(Nodes) when is_list(Nodes) -> gen_server:call(?MODULE,{reconnect_nodes,Nodes},?CALL_TIMEOUT).
%% -----------------------------------------------------------------------------
@@ -572,7 +572,7 @@ reactivator_reply(TPid,Counter) -> init(Config) ->
case fetch_configuration(Config) of % From conf-file and Config.
- {ok,LD} when record(LD,ld) ->
+ {ok,LD} when is_record(LD,ld) -> case start_inviso_at_c_node(LD) of
{ok,CPid} ->
LD2=start_runtime_components(LD),
@@ -650,7 +650,7 @@ start_runtime_components_2([],_,LD) -> start_runtime_components_mk_opts(Node,{M,F,Args}) ->
case catch apply(M,F,[Node|Args]) of
- {ok,Opts} when list(Opts) ->
+ {ok,Opts} when is_list(Opts) -> start_runtime_component_mk_opts_add_dependency(Opts);
_ ->
[?DEFAULT_DEPENDENCY]
@@ -698,7 +698,7 @@ handle_call({reconnect_nodes,Nodes},_From,LD) -> {reply,
build_reconnect_nodes_reply(Nodes,Nodes2,NodesErr,NewLD#ld.nodes),
NewLD};
- list(Nodes) ->
+ is_list(Nodes) -> {reply,
{ok,build_reconnect_nodes_reply(Nodes,Nodes2,NodesErr,NewLD#ld.nodes)},
NewLD}
@@ -711,7 +711,7 @@ handle_call({start_session,MoreTDGargs},_From,LD=#ld{session_state=SState}) -> case is_tracing(SState) of
false -> % No session running.
if
- list(MoreTDGargs) ->
+ is_list(MoreTDGargs) -> DateTime=calendar:universal_time(),
{M,F,Args}=LD#ld.tdg,
TDGargs=inviso_tool_lib:mk_tdg_args(DateTime,MoreTDGargs++Args),
@@ -757,15 +757,15 @@ handle_call({reinitiate_session,Nodes},_From,LD=#ld{session_state=SState}) -> end;
handle_call({restore_session,{FileName,MoreTDGargs}},_From,LD=#ld{chl=OldCHL})
- when list(MoreTDGargs) ->
+ when is_list(MoreTDGargs) -> case is_tracing(LD#ld.session_state) of
false ->
case catch make_absolute_path(FileName,LD#ld.dir) of
- AbsFileName when list(AbsFileName) ->
+ AbsFileName when is_list(AbsFileName) -> case file:read_file(AbsFileName) of
{ok,Bin} ->
if
- list(MoreTDGargs) ->
+ is_list(MoreTDGargs) -> case catch replace_history_chl(OldCHL,
binary_to_term(Bin)) of
{ok,CHL} -> % The file was well formatted.
@@ -803,7 +803,7 @@ handle_call({restore_session,MoreTDGargs},_From,LD=#ld{chl=CHL}) -> case history_exists_chl(CHL) of
true -> % There is a history to redo.
if
- list(MoreTDGargs) ->
+ is_list(MoreTDGargs) -> case h_restore_session(MoreTDGargs,LD) of
{ok,{SessionNr,ReturnVal,NewLD}} ->
{reply,
@@ -879,7 +879,7 @@ handle_call({sync_atc,{TC,Id,Vars,TimeOut}},_From,LD=#ld{session_state=SState}) case is_tracing(SState) of
true ->
if
- integer(TimeOut);TimeOut==infinity ->
+ is_integer(TimeOut);TimeOut==infinity -> case h_sync_atc(TC,Id,Vars,TimeOut,LD) of
{ok,NewLD,Result} ->
{reply,Result,NewLD};
@@ -897,7 +897,7 @@ handle_call({sync_rtc,{TC,Vars,TimeOut}},_From,LD=#ld{session_state=SState}) -> case is_tracing(SState) of
true ->
if
- integer(TimeOut);TimeOut==infinity ->
+ is_integer(TimeOut);TimeOut==infinity -> case h_sync_rtc(TC,Vars,TimeOut,LD) of
{ok,NewLD,Result} ->
{reply,Result,NewLD};
@@ -929,7 +929,7 @@ handle_call({sync_dtc,{TC,Id,TimeOut}},_From,LD=#ld{session_state=SState}) -> case is_tracing(SState) of % Check that we are tracing now.
true ->
if
- integer(TimeOut);TimeOut==infinity ->
+ is_integer(TimeOut);TimeOut==infinity -> case h_sync_dtc(TC,Id,TimeOut,LD) of
{ok,NewLD,Result} ->
{reply,Result,NewLD};
@@ -947,7 +947,7 @@ handle_call({inviso,{Cmd,Args}},_From,LD=#ld{session_state=SState}) -> case is_tracing(SState) of
true ->
if
- list(Args) ->
+ is_list(Args) -> case h_inviso(Cmd,Args,LD) of
{ok,{Reply,NewLD}} ->
{reply,Reply,NewLD};
@@ -1156,7 +1156,7 @@ h_reconnect_nodes(local_runtime,LD=#ld{nodes=NodesD}) -> % Non-distributed. _ -> % Allready connected!
{ok,{[],{error,already_connected},LD}}
end;
-h_reconnect_nodes(Nodes,LD=#ld{nodes=NodesD}) when list(Nodes) ->
+h_reconnect_nodes(Nodes,LD=#ld{nodes=NodesD}) when is_list(Nodes) -> {Nodes2,NodesErr}=
lists:foldl(fun(N,{Nodes2,NodesErr})->
case get_state_nodes(N,NodesD) of
@@ -1246,7 +1246,7 @@ h_start_session_ctp_all_2([],Errors,Nodes) -> %% Help function doing the actual init_tracing.
h_start_session_2(undefined,TracerData,_Errors) -> % Non distributed case.
case inviso:init_tracing(TracerData) of
- {ok,LogResult} when list(LogResult) ->
+ {ok,LogResult} when is_list(LogResult) -> {ok,{ok,LogResult}};
{error,already_initated} -> % Perhaps adopted!?
{ok,{error,already_initiated}}; % Not necessarily wrong.
@@ -1360,7 +1360,7 @@ h_reinitiate_session_2(local_runtime,NodesD,undefined) -> % Non distributed case _ ->
{ok,{[],{error,already_in_session}}}
end;
-h_reinitiate_session_2(Nodes,NodesD,CNode) when list(Nodes) ->
+h_reinitiate_session_2(Nodes,NodesD,CNode) when is_list(Nodes) -> {ok,lists:foldl(fun(N,{Nodes2,NodesErr})->
case get_state_nodes(N,NodesD) of
{inactive,running} -> % Only ok case.
@@ -1515,7 +1515,7 @@ h_atc(TC,Id,Vars,LD=#ld{c_node=CNode,tc_dict=TCdict,chl=CHL},Nodes) -> case check_bindings(Vars,TraceCase) of
{ok,Bindings} -> % Necessary vars exists in Vars.
if
- list(Nodes) -> % Nodes predefined.
+ is_list(Nodes) -> % Nodes predefined. h_atc_2(TC,Id,CNode,CHL,LD,TraceCase,Bindings,Nodes);
true -> % Use all tracing and running nodes.
Nodes1=get_nodenames_running_nodes(LD#ld.nodes),
@@ -1769,13 +1769,13 @@ h_reactivate(Node,CNode) -> h_save_history(HDir,Dir,FileName,SortedLog) ->
Dir0=
if
- list(HDir) -> % There is a history dir specified.
+ is_list(HDir) -> % There is a history dir specified. HDir; % Use it then.
true ->
Dir % Else use the tool dir.
end,
case catch make_absolute_path(FileName,Dir0) of
- AbsFileName when list(AbsFileName) ->
+ AbsFileName when is_list(AbsFileName) -> Log2=build_saved_history_data(SortedLog), % Remove stopped tracecases.
case file:write_file(AbsFileName,term_to_binary(Log2)) of
ok ->
@@ -1801,7 +1801,7 @@ h_get_autostart_data(local_runtime,_,Dependency,ASD,M,F,TDGargs,OptsG) -> Opts=[Dependency|lists:keydelete(dependency,1,Opts0)],
{ok,{ASD,{ok,{Opts,{tdg,{M,F,CompleteTDGargs}}}}}};
-h_get_autostart_data(Nodes,CNode,Dependency,ASD,M,F,TDGargs,OptsG) when list(Nodes) ->
+h_get_autostart_data(Nodes,CNode,Dependency,ASD,M,F,TDGargs,OptsG) when is_list(Nodes) -> {ok,{ASD,h_get_autostart_data_2(Nodes,CNode,Dependency,M,F,TDGargs,OptsG)}};
h_get_autostart_data(Nodes,_CNode,_Dependency,_ASD,_M,_F,_TDGargs,_OptsG) ->
{error,{badarg,Nodes}}.
@@ -2144,14 +2144,14 @@ expand_module_regexps(Args,_RegExpNode,_Nodes,false) -> {ok,Args};
expand_module_regexps([PatternList],RegExpNode,Nodes,{tp,1,1}) ->
case catch expand_module_regexps_tp(PatternList,RegExpNode,Nodes) of
- NewPatternList when list(NewPatternList) ->
+ NewPatternList when is_list(NewPatternList) -> {ok,[NewPatternList]};
{error,Reason} ->
{error,Reason}
end;
expand_module_regexps([PatternList],RegExpNode,Nodes,{ctp,1,1}) ->
case catch expand_module_regexps_ctp(PatternList,RegExpNode,Nodes) of
- NewPatternList when list(NewPatternList) ->
+ NewPatternList when is_list(NewPatternList) -> {ok,[NewPatternList]};
{error,Reason} ->
{error,Reason}
@@ -2164,9 +2164,9 @@ expand_module_regexps([M,F,Arity],RegExpNode,Nodes,{ctp,3,1}) -> expand_module_regexps([[{M,F,Arity}]],RegExpNode,Nodes,{ctp,1,1}).
-expand_module_regexps_tp([E={M,_,_,_,_}|Rest],RegExpNode,Nodes) when atom(M) ->
+expand_module_regexps_tp([E={M,_,_,_,_}|Rest],RegExpNode,Nodes) when is_atom(M) -> [E|expand_module_regexps_tp(Rest,RegExpNode,Nodes)];
-expand_module_regexps_tp([{M,F,Arity,MS,Opts}|Rest],RegExpNode,Nodes) when list(M);tuple(M) ->
+expand_module_regexps_tp([{M,F,Arity,MS,Opts}|Rest],RegExpNode,Nodes) when is_list(M);is_tuple(M) -> case inviso_tool_lib:expand_module_names([RegExpNode],
M,
[{expand_only_at,RegExpNode}]) of
@@ -2193,9 +2193,9 @@ expand_module_regexps_tp_2([M|MRest],F,Arity,MS,Opts,Rest,RegExpNode,Nodes) -> expand_module_regexps_tp_2([],_,_,_,_,Rest,RegExpNode,Nodes) ->
expand_module_regexps_tp(Rest,RegExpNode,Nodes).
-expand_module_regexps_ctp([E={M,_,_}|Rest],RegExpNode,Nodes) when atom(M) ->
+expand_module_regexps_ctp([E={M,_,_}|Rest],RegExpNode,Nodes) when is_atom(M) -> [E|expand_module_regexps_ctp(Rest,RegExpNode,Nodes)];
-expand_module_regexps_ctp([{M,F,Arity}|Rest],RegExpNode,Nodes) when list(M);tuple(M) ->
+expand_module_regexps_ctp([{M,F,Arity}|Rest],RegExpNode,Nodes) when is_list(M);is_tuple(M) -> case inviso_tool_lib:expand_module_names([RegExpNode],
M,
[{expand_only_at,RegExpNode}]) of
@@ -2450,7 +2450,7 @@ fetch_configuration(Config) -> %% Returns {ok,FileName} or 'false'. The latter if no name could be determined.
fetch_config_filename(Config) ->
case catch lists:keysearch(config_file,1,Config) of
- {value,{_,FName}} when list(FName) ->
+ {value,{_,FName}} when is_list(FName) -> {ok,FName};
_ -> % No filename in the start argument.
fetch_config_filename_2()
@@ -2458,7 +2458,7 @@ fetch_config_filename(Config) -> fetch_config_filename_2() ->
case application:get_env(inviso_tool_config_file) of
- {ok,FName} when list(FName) ->
+ {ok,FName} when is_list(FName) -> {ok,FName};
_ -> % Application parameter not specified.
false % Means no config file will be used.
@@ -2499,14 +2499,14 @@ read_config_list_2(LD,Terms,Tag) -> %% Function updating a named field in a record. Returns a new record. Note that
%% this function must be maintained due the fact that field names are removed
%% at compile time.
-update_ld_record(LD,nodes,Value) when record(LD,ld) ->
+update_ld_record(LD,nodes,Value) when is_record(LD,ld) -> case mk_nodes(Value) of
{ok,NodesD} ->
LD#ld{nodes=NodesD};
error ->
LD
end;
-update_ld_record(LD,Tag,Value) when record(LD,ld) ->
+update_ld_record(LD,Tag,Value) when is_record(LD,ld) -> Index=
case Tag of
c_node -> % atom()
@@ -2546,7 +2546,7 @@ update_ld_record(LD,Tag,Value) when record(LD,ld) -> %% ActivationFileName=DeactivationFileName=string()
read_trace_case_definitions(LD) ->
case LD#ld.tc_def_file of
- TCfileName when list(TCfileName) ->
+ TCfileName when is_list(TCfileName) -> case catch file:consult(TCfileName) of
{ok,Terms} ->
Dir=LD#ld.dir, % The working directory of the tool.
@@ -2636,8 +2636,8 @@ get_status(CNode,Nodes) -> %% We can end up here if a session is stopped with this node suspended.
%% Returns a nodes database structure filled with the nodes Nodes.
-mk_nodes(Nodes) when list(Nodes) ->
- {ok,lists:map(fun(N) when atom(N)->{N,down} end,Nodes)};
+mk_nodes(Nodes) when is_list(Nodes) -> + {ok,lists:map(fun(N) when is_atom(N)->{N,down} end,Nodes)}; mk_nodes(local_runtime) -> % The non-distributed case.
down;
mk_nodes(_Nodes) ->
@@ -2783,7 +2783,7 @@ set_suspended_nodes(_,{up,{State,_}}) -> %% This function is called when reactivation is completed. Hence it moves the
%% node to no longer suspended. Note this can mean that the node is either
%% tracing or inactive. Reactivation is not allowed for a node have trace_failure.
-set_running_nodes(Node,NodesD) when list(NodesD) ->
+set_running_nodes(Node,NodesD) when is_list(NodesD) -> case lists:keysearch(Node,1,NodesD) of
{value,{_,AvailableStatus}} ->
lists:keyreplace(Node,1,NodesD,{Node,set_running_nodes_2(AvailableStatus)});
@@ -2902,7 +2902,7 @@ get_available_nodes([]) -> %% suspended or not.
%% Returns {State,Status} | reactivating | down
%% where
-get_state_nodes(Node,NodesD) when list(NodesD) ->
+get_state_nodes(Node,NodesD) when is_list(NodesD) -> case lists:keysearch(Node,1,NodesD) of
{value,{_,AvailableStatus}} ->
get_state_nodes_2(AvailableStatus);
diff --git a/lib/inviso/src/inviso_tool_lib.erl b/lib/inviso/src/inviso_tool_lib.erl index 20a8b509ae..7953acedd6 100644 --- a/lib/inviso/src/inviso_tool_lib.erl +++ b/lib/inviso/src/inviso_tool_lib.erl @@ -83,7 +83,7 @@ inviso_cmd(NodeName,Func,Args) -> %% In the non-distributed case the singlenode_expansion will be returned.
expand_module_names(_Nodes,Mod={_,'_'},_) ->
{error,{faulty_regexp_combination,Mod}};
-expand_module_names(Nodes,{DirStr,ModStr},Opts) when list(DirStr), list(ModStr) ->
+expand_module_names(Nodes,{DirStr,ModStr},Opts) when is_list(DirStr), is_list(ModStr) -> case expand_module_names_special_regexp(DirStr) of
{ok,NewDirStr} ->
case expand_module_names_special_regexp(ModStr) of
@@ -97,11 +97,11 @@ expand_module_names(Nodes,{DirStr,ModStr},Opts) when list(DirStr), list(ModStr) end;
expand_module_names(_,'_',_Opts) -> % If we want to trace all modules
wildcard; % we shall not expand it.
-expand_module_names(_Nodes,Mod,_Opts) when atom(Mod) ->
+expand_module_names(_Nodes,Mod,_Opts) when is_atom(Mod) -> module; % If it is an atom, no expansion.
expand_module_names(Nodes,"*",Opts) -> % Treat this as a reg.exp.
expand_module_names(Nodes,".*",Opts);
-expand_module_names(Nodes,ModStr,Opts) when list(ModStr) ->
+expand_module_names(Nodes,ModStr,Opts) when is_list(ModStr) -> case expand_module_names_special_regexp(ModStr) of
{ok,NewModStr} ->
expand_module_names_2(Nodes,NewModStr,Opts);
@@ -115,7 +115,7 @@ expand_module_names_2(Nodes,ModStr,Opts) -> case get_expand_regexp_at_opts(Opts) of
{ok,Node} -> % Expansion only at this node.
case inviso_rt_lib:expand_regexp([Node],ModStr,Opts) of
- [{Node,Modules}] when list(Modules) ->
+ [{Node,Modules}] when is_list(Modules) -> {singlenode_expansion,Modules};
[{Node,_}] -> % Most likely badrpc.
{error,{faulty_node,Node}}
@@ -130,7 +130,7 @@ expand_module_names_2(Nodes,DirStr,ModStr,Opts) -> case get_expand_regexp_at_opts(Opts) of
{ok,Node} -> % Expansion only at this node.
case inviso_rt_lib:expand_regexp([Node],DirStr,ModStr,Opts) of
- [{Node,Modules}] when list(Modules) ->
+ [{Node,Modules}] when is_list(Modules) -> {singlenode_expansion,Modules};
[{Node,_}] -> % Most likely badrpc.
{error,{faulty_node,Node}}
@@ -186,12 +186,12 @@ make_patterns(Catches,Opts,Dbg,NodeModsOrMods,F,A,MS) -> make_patterns_2(Catches,OwnArg,Dbg,NodeModsOrMods,F,A,MS)
end.
-make_patterns_2(Catches,OwnArg,Dbg,[{Node,Mods}|Rest],F,A,MS) when list(Mods) ->
+make_patterns_2(Catches,OwnArg,Dbg,[{Node,Mods}|Rest],F,A,MS) when is_list(Mods) -> TPs=make_patterns_3(Catches,OwnArg,Dbg,Mods,F,A,MS,[]),
[{Node,join_patterns(TPs)}|make_patterns_2(Catches,OwnArg,Dbg,Rest,F,A,MS)];
make_patterns_2(Catches,OwnArg,Dbg,[{_Node,_}|Rest],F,A,MS) -> % badrpc!?
make_patterns_2(Catches,OwnArg,Dbg,Rest,F,A,MS);
-make_patterns_2(Catches,OwnArg,Dbg,Modules,F,A,MS) when list(Modules) ->
+make_patterns_2(Catches,OwnArg,Dbg,Modules,F,A,MS) when is_list(Modules) -> TPs=make_patterns_3(Catches,OwnArg,Dbg,Modules,F,A,MS,[]),
join_patterns(TPs);
make_patterns_2(_,_,_,[],_,_,_) ->
@@ -330,7 +330,7 @@ get_datetime_from_tdg_args([DateTime|_]) -> %% Returns a list.
get_ownarg_opts(Opts) ->
case lists:keysearch(arg,1,Opts) of
- {value,{_,OwnArg}} when list(OwnArg) ->
+ {value,{_,OwnArg}} when is_list(OwnArg) -> OwnArg;
{value,{_,OwnArg}} ->
[OwnArg];
@@ -350,7 +350,7 @@ get_disable_safety_opts(Opts) -> get_expand_regexp_at_opts(Opts) ->
case lists:keysearch(expand_only_at,1,Opts) of
- {value,{_,Node}} when atom(Node) ->
+ {value,{_,Node}} when is_atom(Node) -> {ok,Node};
_ ->
false
diff --git a/lib/inviso/vsn.mk b/lib/inviso/vsn.mk index cab3bc0ff3..79093597fe 100644 --- a/lib/inviso/vsn.mk +++ b/lib/inviso/vsn.mk @@ -1 +1 @@ -INVISO_VSN = 0.6.1 +INVISO_VSN = 0.6.2 diff --git a/lib/jinterface/doc/src/notes.xml b/lib/jinterface/doc/src/notes.xml index 977a7a7f98..a571de6916 100644 --- a/lib/jinterface/doc/src/notes.xml +++ b/lib/jinterface/doc/src/notes.xml @@ -30,6 +30,22 @@ </header> <p>This document describes the changes made to the Jinterface application.</p> +<section><title>Jinterface 1.5.3.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + An pom.xml file is now generated. (Thanks to Gabor + Liptak.)</p> + <p> + Own Id: OTP-8841</p> + </item> + </list> + </section> + +</section> + <section><title>Jinterface 1.5.3</title> <section><title>Improvements and New Features</title> diff --git a/lib/jinterface/java_src/Makefile b/lib/jinterface/java_src/Makefile index 37a57352ad..22c55328b8 100644 --- a/lib/jinterface/java_src/Makefile +++ b/lib/jinterface/java_src/Makefile @@ -35,7 +35,21 @@ VSN=$(JINTERFACE_VSN) SPECIAL_TARGETS = +TARGET_FILES= $(POM_TARGET) +SPECIAL_TARGETS = + +POM_FILE= pom.xml + +POM_TARGET= ../$(POM_FILE) +POM_SRC= $(POM_FILE).src + +# ---------------------------------------------------- +# Special Build Targets +# ---------------------------------------------------- + +$(POM_TARGET): $(POM_SRC) ../vsn.mk + sed -e 's;%VSN%;$(VSN);' $< > $@ # ---------------------------------------------------- # Default Subdir Targets @@ -43,7 +57,7 @@ SPECIAL_TARGETS = .PHONY: debug opt instr release docs release_docs tests release_tests clean depend -debug opt instr release docs release_docs tests release_tests clean depend: +debug opt instr release docs release_docs tests release_tests clean depend: $(TARGET_FILES) set -e; set -x; \ case "$(MAKE)" in *clearmake*) tflag="-T";; *) tflag="";; esac; \ if test -f com/ericsson/otp/erlang/ignore_config_record.inf; then xflag=$$tflag; fi; \ diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpEpmd.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpEpmd.java index 3bb678c2cc..deac528133 100644 --- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpEpmd.java +++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpEpmd.java @@ -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 @@ -71,11 +71,6 @@ public class OtpEpmd { // common values private static final byte stopReq = (byte) 115; - // version specific value - private static final byte port3req = (byte) 112; - private static final byte publish3req = (byte) 97; - private static final byte publish3ok = (byte) 89; - private static final byte port4req = (byte) 122; private static final byte port4resp = (byte) 119; private static final byte publish4req = (byte) 120; @@ -123,11 +118,7 @@ public class OtpEpmd { * if there was no response from the name server. */ public static int lookupPort(final AbstractNode node) throws IOException { - try { return r4_lookupPort(node); - } catch (final IOException e) { - return r3_lookupPort(node); - } } /** @@ -147,11 +138,7 @@ public class OtpEpmd { throws IOException { Socket s = null; - try { - s = r4_publish(node); - } catch (final IOException e) { - s = r3_publish(node); - } + s = r4_publish(node); node.setEpmd(s); @@ -196,67 +183,6 @@ public class OtpEpmd { } } - private static int r3_lookupPort(final AbstractNode node) - throws IOException { - int port = 0; - Socket s = null; - - try { - final OtpOutputStream obuf = new OtpOutputStream(); - s = new Socket(node.host(), EpmdPort.get()); - - // build and send epmd request - // length[2], tag[1], alivename[n] (length = n+1) - obuf.write2BE(node.alive().length() + 1); - obuf.write1(port3req); - obuf.writeN(node.alive().getBytes()); - - // send request - obuf.writeTo(s.getOutputStream()); - - if (traceLevel >= traceThreshold) { - System.out.println("-> LOOKUP (r3) " + node); - } - - // receive and decode reply - final byte[] tmpbuf = new byte[100]; - - s.getInputStream().read(tmpbuf); - final OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0); - - port = ibuf.read2BE(); - } catch (final IOException e) { - if (traceLevel >= traceThreshold) { - System.out.println("<- (no response)"); - } - throw new IOException("Nameserver not responding on " + node.host() - + " when looking up " + node.alive()); - } catch (final OtpErlangDecodeException e) { - if (traceLevel >= traceThreshold) { - System.out.println("<- (invalid response)"); - } - throw new IOException("Nameserver not responding on " + node.host() - + " when looking up " + node.alive()); - } finally { - try { - if (s != null) { - s.close(); - } - } catch (final IOException e) { /* ignore close errors */ - } - s = null; - } - - if (traceLevel >= traceThreshold) { - if (port == 0) { - System.out.println("<- NOT FOUND"); - } else { - System.out.println("<- PORT " + port); - } - } - return port; - } - private static int r4_lookupPort(final AbstractNode node) throws IOException { int port = 0; @@ -288,8 +214,6 @@ public class OtpEpmd { final int n = s.getInputStream().read(tmpbuf); if (n < 0) { - // this was an r3 node => not a failure (yet) - s.close(); throw new IOException("Nameserver not responding on " + node.host() + " when looking up " + node.alive()); @@ -342,81 +266,13 @@ public class OtpEpmd { return port; } - private static Socket r3_publish(final OtpLocalNode node) - throws IOException { - Socket s = null; - - try { - final OtpOutputStream obuf = new OtpOutputStream(); - s = new Socket((String) null, EpmdPort.get()); - - obuf.write2BE(node.alive().length() + 3); - - obuf.write1(publish3req); - obuf.write2BE(node.port()); - obuf.writeN(node.alive().getBytes()); - - // send request - obuf.writeTo(s.getOutputStream()); - if (traceLevel >= traceThreshold) { - System.out.println("-> PUBLISH (r3) " + node + " port=" - + node.port()); - } - - final byte[] tmpbuf = new byte[100]; - - final int n = s.getInputStream().read(tmpbuf); - - if (n < 0) { - s.close(); - if (traceLevel >= traceThreshold) { - System.out.println("<- (no response)"); - } - return null; - } - - final OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0); - - if (ibuf.read1() == publish3ok) { - node.creation = ibuf.read2BE(); - if (traceLevel >= traceThreshold) { - System.out.println("<- OK"); - } - return s; // success - don't close socket - } - } catch (final IOException e) { - // epmd closed the connection = fail - if (s != null) { - s.close(); - } - if (traceLevel >= traceThreshold) { - System.out.println("<- (no response)"); - } - throw new IOException("Nameserver not responding on " + node.host() - + " when publishing " + node.alive()); - } catch (final OtpErlangDecodeException e) { - if (s != null) { - s.close(); - } - if (traceLevel >= traceThreshold) { - System.out.println("<- (invalid response)"); - } - throw new IOException("Nameserver not responding on " + node.host() - + " when publishing " + node.alive()); - } - - if (s != null) { - s.close(); - } - return null; // failure - } - /* - * this function will get an exception if it tries to talk to an r3 epmd, or - * if something else happens that it cannot forsee. In both cases we return - * an exception (and the caller should try again, using the r3 protocol). If - * we manage to successfully communicate with an r4 epmd, we return either - * the socket, or null, depending on the result. + * this function will get an exception if it tries to talk to a + * very old epmd, or if something else happens that it cannot + * forsee. In both cases we return an exception. We no longer + * support r3, so the exception is fatal. If we manage to + * successfully communicate with an r4 epmd, we return either the + * socket, or null, depending on the result. */ private static Socket r4_publish(final OtpLocalNode node) throws IOException { @@ -454,7 +310,6 @@ public class OtpEpmd { final int n = s.getInputStream().read(tmpbuf); if (n < 0) { - // this was an r3 node => not a failure (yet) if (s != null) { s.close(); } diff --git a/lib/jinterface/java_src/pom.xml.src b/lib/jinterface/java_src/pom.xml.src new file mode 100644 index 0000000000..cef49b735a --- /dev/null +++ b/lib/jinterface/java_src/pom.xml.src @@ -0,0 +1,106 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>org.erlang.otp</groupId> + <artifactId>jinterface</artifactId> + <packaging>jar</packaging> + <version>%VSN%</version> + <name>jinterface</name> + <description> + Jinterface Java package contains java classes, which help you integrate programs written in Java with Erlang. + Erlang is a programming language designed at the Ericsson Computer Science Laboratory. + </description> + <url>http://erlang.org/</url> + <licenses> + <license> + <name>ERLANG PUBLIC LICENSE 1.1</name> + <url>http://www.erlang.org/EPLICENSE</url> + <distribution>repo</distribution> + </license> + </licenses> + <scm> + <connection>git://github.com/erlang/otp.git</connection> + <developerConnection>git://github.com/erlang/otp.git</developerConnection> + <url>http://github.com/erlang/otp</url> + </scm> + <developers> + <developer> + <email>[email protected]</email> + </developer> + </developers> + <organization> + <name>Open Source Erlang</name> + <url>http://www.erlang.org/</url> + </organization> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.5</source> + <target>1.5</target> + </configuration> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <phase>generate-sources</phase> + <goals> + <goal>add-source</goal> + </goals> + <configuration> + <sources> + <source>java_src</source> + </sources> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + <distributionManagement> + <repository> + <id>ossrh</id> + <url>http://oss.sonatype.org/service/local/staging/deploy/maven2</url> + </repository> + <snapshotRepository> + <id>ossrh</id> + <url>http://oss.sonatype.org/content/repositories/snapshots</url> + </snapshotRepository> + </distributionManagement> + <profiles> + <profile> + <id>release-sign-artifacts</id> + <activation> + <property> + <name>performRelease</name> + <value>true</value> + </property> + </activation> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-gpg-plugin</artifactId> + <version>1.0-alpha-4</version> + <executions> + <execution> + <id>sign-artifacts</id> + <phase>verify</phase> + <goals> + <goal>sign</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + </profiles> + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> +</project> diff --git a/lib/jinterface/vsn.mk b/lib/jinterface/vsn.mk index 26613febbf..ed085b5d4d 100644 --- a/lib/jinterface/vsn.mk +++ b/lib/jinterface/vsn.mk @@ -1 +1 @@ -JINTERFACE_VSN = 1.5.3 +JINTERFACE_VSN = 1.5.3.1 diff --git a/lib/kernel/doc/src/application.xml b/lib/kernel/doc/src/application.xml index 08ef0b1e52..47d578a339 100644 --- a/lib/kernel/doc/src/application.xml +++ b/lib/kernel/doc/src/application.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2009</year> + <year>1996</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>application</title> @@ -503,7 +503,7 @@ Nodes = [cp1@cave, {cp2@cave, cp3@cave}]</code> the tree.</p> <p><c>StartType</c> defines the type of start:</p> <list type="bulleted"> - <item><c>normal</c> if its a normal startup.</item> + <item><c>normal</c> if it's a normal startup.</item> <item><c>normal</c> also if the application is distributed and started at the current node due to a failover from another node, and the application specification key <c>start_phases == undefined</c>.</item> diff --git a/lib/kernel/doc/src/code.xml b/lib/kernel/doc/src/code.xml index 19e1d3221c..b8db509fa8 100644 --- a/lib/kernel/doc/src/code.xml +++ b/lib/kernel/doc/src/code.xml @@ -54,7 +54,7 @@ for and tries to load the module.</p> </item> </list> - <p>To prevent accidentaly reloading modules affecting the Erlang + <p>To prevent accidentally reloading modules affecting the Erlang runtime system itself, the <c>kernel</c>, <c>stdlib</c> and <c>compiler</c> directories are considered <em>sticky</em>. This means that the system issues a warning and rejects the request if diff --git a/lib/kernel/doc/src/erl_ddll.xml b/lib/kernel/doc/src/erl_ddll.xml index 75dca8a85d..9a62b45d63 100644 --- a/lib/kernel/doc/src/erl_ddll.xml +++ b/lib/kernel/doc/src/erl_ddll.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1997</year><year>2009</year> + <year>1997</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>erl_ddll</title> @@ -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> @@ -730,7 +730,7 @@ extension suffix, i.e. <c>.so</c>). The name by which the driver identifies itself must also be consistent with this <c>Name</c> parameter, much as a beam-file's - module name much correspond to it's filename.</p> + module name much correspond to its filename.</p> </item> <tag><em>OptionList</em></tag> <item> @@ -742,8 +742,8 @@ <tag><em>{driver_options, DriverOptionsList}</em></tag> <item> <p>This option is to provide options that will change - it's general behavior and will "stick" to the driver - throughout it's lifespan.</p> + its general behavior and will "stick" to the driver + throughout its lifespan.</p> <p>The driver options for a given driver name need always to be consistent, <em>even when the driver is reloaded</em>, meaning that they are as much a part of the driver as the actual name.</p> @@ -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/doc/src/file.xml b/lib/kernel/doc/src/file.xml index f9f5443f68..2044b074ee 100644 --- a/lib/kernel/doc/src/file.xml +++ b/lib/kernel/doc/src/file.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2009</year> + <year>1996</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>file</title> @@ -62,6 +62,25 @@ time() = {{Year, Month, Day}, {Hour, Minute, Second}} </section> <funcs> <func> + <name>advise(IoDevice, Offset, Length, Advise) -> ok | {error, Reason}</name> + <fsummary>Predeclare an access pattern for file data</fsummary> + <type> + <v>IoDevice = io_device()</v> + <v>Offset = int()</v> + <v>Length = int()</v> + <v>Advise = posix_file_advise()</v> + <v>posix_file_advise() = normal | sequential | random | no_reuse + | will_need | dont_need</v> + <v>Reason = ext_posix()</v> + </type> + <desc> + <p><c>advise/4</c> can be used to announce an intention to access file + data in a specific pattern in the future, thus allowing the + operating system to perform appropriate optimizations.</p> + <p>On some platforms, this function might have no effect.</p> + </desc> + </func> + <func> <name>change_group(Filename, Gid) -> ok | {error, Reason}</name> <fsummary>Change group of a file</fsummary> <type> @@ -75,6 +94,19 @@ time() = {{Year, Month, Day}, {Hour, Minute, Second}} </desc> </func> <func> + <name>change_mode(Filename, Mode) -> ok | {error, Reason}</name> + <fsummary>Change permissions of a file</fsummary> + <type> + <v>Filename = name()</v> + <v>Mode = int()</v> + <v>Reason = ext_posix()</v> + </type> + <desc> + <p>Changes permissions of a file. See + <seealso marker="#write_file_info/2">write_file_info/2</seealso>.</p> + </desc> + </func> + <func> <name>change_owner(Filename, Uid) -> ok | {error, Reason}</name> <fsummary>Change owner of a file</fsummary> <type> @@ -571,7 +603,7 @@ f.txt: {person, "kalle", 25}. <type> <v>Filename = name()</v> <v>Modes = [Mode]</v> - <v> Mode = read | write | append | raw | binary | {delayed_write, Size, Delay} | delayed_write | {read_ahead, Size} | read_ahead | compressed</v> + <v> Mode = read | write | append | exclusive | raw | binary | {delayed_write, Size, Delay} | delayed_write | {read_ahead, Size} | read_ahead | compressed</v> <v> Size = Delay = int()</v> <v>IoDevice = io_device()</v> <v>Reason = ext_posix() | system_limit</v> @@ -598,6 +630,17 @@ f.txt: {person, "kalle", 25}. file opened with <c>append</c> will take place at the end of the file.</p> </item> + <tag><c>exclusive</c></tag> + <item> + <p>The file, when opened for writing, is created if it + does not exist. If the file exists, open will return + <c>{error, eexist}</c>.</p> + <warning><p>This option does not guarantee exclusiveness on + file systems that do not support O_EXCL properly, + such as NFS. Do not depend on this option unless you + know that the file system supports it (in general, local + file systems should be safe).</p></warning> + </item> <tag><c>raw</c></tag> <item> <p>The <c>raw</c> option allows faster access to a file, @@ -1186,7 +1229,7 @@ f.txt: {person, "kalle", 25}. </item> <tag><c>{no_translation, unicode, latin1}</c></tag> <item> - <p>The file is was opened with another <c>encoding</c> than <c>latin1</c> and the data on the file can not be translated to the byte-oriented data that this function returns.</p> + <p>The file was opened with another <c>encoding</c> than <c>latin1</c> and the data in the file can not be translated to the byte-oriented data that this function returns.</p> </item> </taglist> </desc> @@ -1628,6 +1671,33 @@ f.txt: {person, "kalle", 25}. </desc> </func> <func> + <name>datasync(IoDevice) -> ok | {error, Reason}</name> + <fsummary>Synchronizes the in-memory data of a file, ignoring most of its metadata, with that on the physical medium</fsummary> + <type> + <v>IoDevice = io_device()</v> + <v>Reason = ext_posix() | terminated</v> + </type> + <desc> + <p>Makes sure that any buffers kept by the operating system + (not by the Erlang runtime system) are written to disk. In + many ways it's resembles fsync but it not requires to update + some of file's metadata such as the access time. On + some platforms, this function might have no effect.</p> + <p>Applications that access databases or log files often write + a tiny data fragment (e.g., one line in a log file) and then + call fsync() immediately in order to ensure that the written + data is physically stored on the harddisk. Unfortunately, fsync() + will always initiate two write operations: one for the newly + written data and another one in order to update the modification + time stored in the inode. If the modification time is not a part + of the transaction concept fdatasync() can be used to avoid + unnecessary inode disk write operations.</p> + <p>Available only in some POSIX systems. This call results in a + call to fsync(), or has no effect, in systems not implementing + the fdatasync syscall.</p> + </desc> + </func> + <func> <name>truncate(IoDevice) -> ok | {error, Reason}</name> <fsummary>Truncate a file</fsummary> <type> diff --git a/lib/kernel/doc/src/gen_sctp.xml b/lib/kernel/doc/src/gen_sctp.xml index 3a8011e28b..fb09092f1c 100644 --- a/lib/kernel/doc/src/gen_sctp.xml +++ b/lib/kernel/doc/src/gen_sctp.xml @@ -1173,7 +1173,7 @@ client_loop(S, Peer1, Port1, AssocId1, Peer2, Port2, AssocId2) -> <title>SEE ALSO</title> <p><seealso marker="inet">inet(3)</seealso>, <seealso marker="gen_tcp">gen_tcp(3)</seealso>, - <seealso marker="gen_udp">gen_upd(3)</seealso>, + <seealso marker="gen_udp">gen_udp(3)</seealso>, <url href="http://www.rfc-archive.org/getrfc.php?rfc=2960">RFC2960</url> (Stream Control Transmission Protocol), <url href="http://tools.ietf.org/html/draft-ietf-tsvwg-sctpsocket-13">Sockets API Extensions for SCTP.</url></p> <marker id="authors"></marker> diff --git a/lib/kernel/doc/src/gen_tcp.xml b/lib/kernel/doc/src/gen_tcp.xml index 032dcc5251..8e7192a496 100644 --- a/lib/kernel/doc/src/gen_tcp.xml +++ b/lib/kernel/doc/src/gen_tcp.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1997</year><year>2009</year> + <year>1997</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -284,9 +284,10 @@ socket() <type> <v>Socket = socket()</v> <v>Length = int()</v> - <v>Packet = [char()] | binary()</v> + <v>Packet = [char()] | binary() | HttpPacket</v> <v>Timeout = int() | infinity</v> <v>Reason = closed | posix()</v> + <v>HttpPacket = see the description of <c>HttpPacket</c> in <seealso marker="erts:erlang#decode_packet/3">erlang:decode_packet/3</seealso></v> </type> <desc> <p>This function receives a packet from a socket in passive diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml index f502b30c8d..2ae230152c 100644 --- a/lib/kernel/doc/src/inet.xml +++ b/lib/kernel/doc/src/inet.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1997</year><year>2009</year> + <year>1997</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>inet</title> @@ -221,7 +221,7 @@ fe80::204:acff:fe17:bf38 </desc> </func> <func> - <name>getopts(Socket, Options) -> OptionValues | {error, posix()}</name> + <name>getopts(Socket, Options) -> {ok, OptionValues} | {error, posix()}</name> <fsummary>Get one or more options for a socket</fsummary> <type> <v>Socket = term()</v> diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml index 5467cd8cde..9859183390 100644 --- a/lib/kernel/doc/src/notes.xml +++ b/lib/kernel/doc/src/notes.xml @@ -30,11 +30,32 @@ </header> <p>This document describes the changes made to the Kernel application.</p> -<section><title>Kernel 2.13.5.4</title> +<section><title>Kernel 2.14.1</title> <section><title>Fixed Bugs and Malfunctions</title> <list> <item> + <p> + Fixed: inet:setopts(S, [{linger,{true,2}}]) returned + {error,einval} for SCTP sockets. The inet_drv had a bug + when checking the option size.</p> + <p> + Own Id: OTP-8726 Aux Id: seq11617 </p> + </item> + <item> + <p> + gen_udp:connect/3 was broken for SCTP enabled builds. It + did not detect remote end errors as it should.</p> + <p> + Own Id: OTP-8729</p> + </item> + <item> + <p>reference() has been substituted for ref() in the + documentation.</p> + <p> + Own Id: OTP-8733</p> + </item> + <item> <p>A bug introduced in kernel-2.13.5.3 has been fixed. If running <c>net_kernel:set_net_ticktime/1</c> twice within the <c>TransitionPerod</c> the second call caused the @@ -42,6 +63,150 @@ <p> Own Id: OTP-8787 Aux Id: seq11657, OTP-8643 </p> </item> + <item> + <p> + inet:getsockopt for SCTP sctp_default_send_param had a + bug to not initialize required feilds causing random + answers. It is now corrected.</p> + <p> + Own Id: OTP-8795 Aux Id: seq11655 </p> + </item> + <item> + <p>For a socket in the HTTP packet mode, the return value + from <c>gen_tcp:recv/2,3</c> if there is an error in the + header will be <c>{ok,{http_error,String}}</c> instead of + <c>{error,{http_error,String}}</c> to be consistent with + <c>ssl:recv/2,3</c>.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-8831</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Even when configuring erlang with --enable-native-libs, + the native code for modules loaded very early (such as + lists) would not get loaded. This has been corrected. + (Thanks to Paul Guyot.)</p> + <p> + Own Id: OTP-8750</p> + </item> + <item> + <p> + The undocumented function inet:ifget/2 has been improved + to return interface hardware address (MAC) on platforms + supporting getaddrinfo() (such as BSD unixes). Note it + still does not work on all platforms for example not + Windows nor Solaris, so the function is still + undocumented.</p> + <p> + Buffer overflow and field init bugs for inet:ifget/2 and + inet:getservbyname/2 has also been fixed.</p> + <p> + Thanks to Michael Santos.</p> + <p> + Own Id: OTP-8816</p> + </item> + <item> + <p> + As a usability improvement the 'inet6' option to + functions gen_tcp:listen/2, gen_tcp:connect/3-4, + gen_udp:open/2 and gen_sctp:open/1-2 is now implicit if + the address argument or the 'ip' option contain an IPv6 + address (8-tuple).</p> + <p> + Own Id: OTP-8822</p> + </item> + </list> + </section> + +</section> + +<section><title>Kernel 2.14</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + os:find_executable can now be fed with the complete name + of the executable on Windows and still find it. I.e + os:find_executable("werl.exe") will work as + os:find_executable("werl").</p> + <p> + Own Id: OTP-3626</p> + </item> + <item> + <p> + The shell's line editing has been improved to more + resemble the behaviour of readline and other shells. + (Thanks to Dave Peticolas)</p> + <p> + Own Id: OTP-8635</p> + </item> + <item> + <p>Under certain circumstances the net kernel could hang. + (Thanks to Scott Lystig Fritchie.)</p> + <p> + Own Id: OTP-8643 Aux Id: seq11584 </p> + </item> + <item> + <p> + The kernel DNS resolver was leaking one or two ports if + the DNS reply could not be parsed or if the resolver(s) + caused noconnection type errors. Bug now fixed. A DNS + specification borderline truncated reply triggering the + port leakage bug has also been fixed.</p> + <p> + Own Id: OTP-8652</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>As of this version, the global name server no longer + supports nodes running Erlang/OTP R11B.</p> + <p> + Own Id: OTP-8527</p> + </item> + <item> + <p> + The file module's functions write,read and read_line now + handles named io_servers like 'standard_io' and + 'standard_error' correctly.</p> + <p> + Own Id: OTP-8611</p> + </item> + <item> + <p> + The functions file:advise/4 and file:datasync/1 have been + added. (Thanks to Filipe David Manana.)</p> + <p> + Own Id: OTP-8637</p> + </item> + <item> + <p>When exchanging groups between nodes <c>pg2</c> did + not remove duplicated members. This bug was introduced in + R13B03 (kernel-2.13.4).</p> + <p> + Own Id: OTP-8653</p> + </item> + <item> + <p> + There is a new option 'exclusive' to file:open/2 that + uses the OS O_EXCL flag where supported to open the file + in exclusive mode.</p> + <p> + Own Id: OTP-8670</p> + </item> </list> </section> diff --git a/lib/kernel/include/file.hrl b/lib/kernel/include/file.hrl index c1de4d764d..3889bce393 100644 --- a/lib/kernel/include/file.hrl +++ b/lib/kernel/include/file.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% %% @@ -21,29 +21,18 @@ -define(FILE_HRL_, 1). %%-------------------------------------------------------------------------- -%%-type namelist() :: [char() | atom() | namelist()]. --type namelist() :: [_]. %% XXX: GROSS OVERAPPROXIMATION -- FIX ME --type name() :: string() | atom() | namelist(). --type posix() :: atom(). - --type date() :: {pos_integer(), pos_integer(), pos_integer()}. --type time() :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}. --type date_time() :: {date(), time()}. - -%%-------------------------------------------------------------------------- - -record(file_info, {size :: non_neg_integer(), % Size of file in bytes. type :: 'device' | 'directory' | 'other' | 'regular' | 'symlink', access :: 'read' | 'write' | 'read_write' | 'none', - atime :: date_time(), % The local time the file was last read: - % {{Year, Mon, Day}, {Hour, Min, Sec}}. - mtime :: date_time(), % The local time the file was last written. - ctime :: date_time(), % The interpretation of this time field - % is dependent on operating system. - % On Unix it is the last time the file or - % or the inode was changed. On Windows, - % it is the creation time. + atime :: file:date_time(), % The local time the file was last read: + % {{Year, Mon, Day}, {Hour, Min, Sec}}. + mtime :: file:date_time(), % The local time the file was last written. + ctime :: file:date_time(), % The interpretation of this time field + % is dependent on operating system. + % On Unix it is the last time the file + % or the inode was changed. On Windows, + % it is the creation time. mode :: integer(), % File permissions. On Windows, % the owner permissions will be % duplicated for group and user. @@ -61,10 +50,8 @@ -record(file_descriptor, - {module :: module(), % Module that handles this kind of file + {module :: module(), % Module that handles this kind of file data :: term()}). % Module dependent data --type fd() :: pid() | #file_descriptor{}. - %%-------------------------------------------------------------------------- -endif. diff --git a/lib/kernel/internal_doc/distribution_handshake.txt b/lib/kernel/internal_doc/distribution_handshake.txt index f64ebe0302..6a3ee22ed3 100644 --- a/lib/kernel/internal_doc/distribution_handshake.txt +++ b/lib/kernel/internal_doc/distribution_handshake.txt @@ -11,7 +11,7 @@ The TCP/IP distribution uses a handshake which expects a connection based protocol, i.e. the protocol does not include any authentication after the handshake procedure. -This is not entirelly safe, as it is vulnerable against takeover +This is not entirely safe, as it is vulnerable against takeover attacks, but it is a tradeoff between fair safety and performance. The cookies are never sent in cleartext and the handshake procedure @@ -23,7 +23,7 @@ random numbers. DEFINITIONS ----------- -A challenge is a 32 bit integer number in big endian. Below the function +A challenge is a 32 bit integer number in big endian order. Below the function gen_challenge() returns a random 32 bit integer used as a challenge. A digest is a (16 bytes) MD5 hash of [the Challenge (as text) concatenated @@ -46,19 +46,19 @@ The cookies are text strings that can be viewed as passwords. Every message in the handshake starts with a 16 bit big endian integer which contains the length of the message (not counting the two initial bytes). In erlang this corresponds to the gen_tcp option {packet, 2}. Note that after -the handshake, the distribution switches to 4 byte backet headers. +the handshake, the distribution switches to 4 byte packet headers. THE HANDSHAKE IN DETAIL ----------------------- -Imagine two nodes, node A, which initiates the handshake and node B, whitch +Imagine two nodes, node A, which initiates the handshake and node B, which accepts the connection. 1) connect/accept: A connects to B via TCP/IP and B accepts the connection. 2) send_name/receive_name: A sends an initial identification to B. B receives the message. The message looks -like this (every "square" beeing one byte and the packet header removed): +like this (every "square" being one byte and the packet header removed): +---+--------+--------+-----+-----+-----+-----+-----+-----+-...-+-----+ |'n'|Version0|Version1|Flag0|Flag1|Flag2|Flag3|Name0|Name1| ... |NameN| @@ -67,7 +67,7 @@ like this (every "square" beeing one byte and the packet header removed): The 'n' is just a message tag, Version0 & Version1 is the distribution version selected by node A, based on information from EPMD. (16 bit big endian) -Flag0 ... Flag3 is capability flags, the capabilities defined in dist.hrl. +Flag0 ... Flag3 are capability flags, the capabilities defined in dist.hrl. (32 bit big endian) Name0 ... NameN is the full nodename of A, as a string of bytes (the packet length denotes how long it is). @@ -91,9 +91,9 @@ alive: A connection to the node is already active, which either means This is the format of the status message: -+---+-------+-------+ ... +-------+ ++---+-------+-------+-...-+-------+ |'s'|Status0|Status1| ... |StatusN| -+---+-------+-------+ ... +-------+ ++---+-------+-------+-...-+-------+ 's' is the message tag Status0 ... StatusN is the status as a string (not terminated) @@ -111,35 +111,35 @@ initially sent from A to B, with the addition of a 32 bit challenge: +---+--------+--------+-----+-----+-----+-----+-----+-----+-----+-----+--- |'n'|Version0|Version1|Flag0|Flag1|Flag2|Flag3|Chal0|Chal1|Chal2|Chal3| -+---+--------+--------+-----+-----+-----+-----+-----+-----+---- +-----+--- ++---+--------+--------+-----+-----+-----+-----+-----+-----+-----+-----+--- ------+-----+-...-+-----+ Name0|Name1| ... |NameN| ------+-----+-... +-----+ -Where Chal0 ... Chal3 is the challenge as a 32 bit biog endian integer +Where Chal0 ... Chal3 is the challenge as a 32 bit big endian integer and the other fields are B's version, flags and full nodename. 5) send_challenge_reply/recv_challenge_reply: Now A has generated -a digest and it's own challenge. Those are sent together in a package +a digest and its own challenge. Those are sent together in a package to B: -+---+-----+-----+-----+-----+-----+-----+-----+-----+ -|'r'|Chal0|Chal1|Chal2|Chal3|Dige0|Dige1|Dige2|Dige3| -+---+-----+-----+-----+-----+-----+-----+---- +-----+ ++---+-----+-----+-----+-----+-----+-----+-----+-----+-...-+------+ +|'r'|Chal0|Chal1|Chal2|Chal3|Dige0|Dige1|Dige2|Dige3| ... |Dige15| ++---+-----+-----+-----+-----+-----+-----+-----+-----+-...-+------+ Where 'r' is the tag, Chal0 ... Chal3 is A's challenge for B to handle and -Dige0 ... Dige3 is the digest that A constructed from the challenge B sent +Dige0 ... Dige15 is the digest that A constructed from the challenge B sent in the previous step. 6) recv_challenge_ack/send_challenge_ack: B checks that the digest received from A is correct and generates a digest from the challenge received from A. The digest is then sent to A. The message looks like this: -+---+-----+-----+-----+-----+ -|'a'|Dige0|Dige1|Dige2|Dige3| -+---+-----+-----+---- +-----+ ++---+-----+-----+-----+-----+-...-+------+ +|'a'|Dige0|Dige1|Dige2|Dige3| ... |Dige15| ++---+-----+-----+-----+-----+-...-+------+ -Where 'a' is the tag and Dige0 ... Dige3 is the digest calculated by B +Where 'a' is the tag and Dige0 ... Dige15 is the digest calculated by B for A's challenge. 7) A checks the digest from B and the connection is up. @@ -206,7 +206,7 @@ Currently the following capability flags are defined: %% The node implements distributed process monitoring. -define(DFLAG_DIST_MONITOR,8). -%% The node uses separate tag for fun's (labmdas) in the distribution protocol. +%% The node uses separate tag for fun's (lambdas) in the distribution protocol. -define(DFLAG_FUN_TAGS,16). An R6 erlang node implements all of the above, while a C or Java node only diff --git a/lib/kernel/src/application_controller.erl b/lib/kernel/src/application_controller.erl index 7c1f059875..42f527f400 100644 --- a/lib/kernel/src/application_controller.erl +++ b/lib/kernel/src/application_controller.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(application_controller). @@ -40,7 +40,7 @@ -export([test_change_apps/2]). -import(lists, [zf/2, map/2, foreach/2, foldl/3, - keysearch/3, keydelete/3, keyreplace/4]). + keyfind/3, keydelete/3, keyreplace/4]). -include("application_master.hrl"). @@ -128,8 +128,13 @@ %% AppName = atom() %% Application = App | AppName %%----------------------------------------------------------------- + +-type appname() :: atom(). + -record(state, {loading = [], starting = [], start_p_false = [], running = [], control = [], started = [], start_req = [], conf_data}). +-type state() :: #state{}. + %%----------------------------------------------------------------- %% loading = [{AppName, From}] - Load not yet finished %% starting = [{AppName, RestartType, Type, From}] - Start not @@ -519,7 +524,9 @@ init(Init, Kernel) -> end. -%% Check the syntax of the .config file [{ApplicationName, [{Parameter, Value}]}]. +%% Check the syntax of the .config file +%% [{ApplicationName, [{Parameter, Value}]}]. + check_conf_data([]) -> ok; check_conf_data(ConfData) when is_list(ConfData) -> @@ -563,8 +570,8 @@ check_para_kernel([]) -> ok; check_para_kernel([{distributed, Apps} | ParaList]) when is_list(Apps) -> case check_distributed(Apps) of - {error, ErrorMsg} -> - {error, ErrorMsg}; + {error, _ErrorMsg} = Error -> + Error; _ -> check_para_kernel(ParaList) end; @@ -604,6 +611,19 @@ check_para([Else | _ParaList], AppName) -> lists:flatten(io_lib:format("~p",[Else]))}. +-type calls() :: 'info' | 'prep_config_change' | 'which_applications' + | {'config_change' | 'control_application' | + 'load_application' | 'start_type' | 'stop_application' | + 'unload_application', term()} + | {'change_application_data', _, _} + | {'permit_application', atom() | {'application',atom(),_},_} + | {'start_application', _, _} + | {'unset_env', _, _} + | {'set_env', _, _, _}. + +-spec handle_call(calls(), {pid(), term()}, state()) -> + {'noreply', state()} | {'reply', term(), state()}. + handle_call({load_application, Application}, From, S) -> case catch do_load_application(Application, S) of {ok, NewS} -> @@ -615,9 +635,9 @@ handle_call({load_application, Application}, From, S) -> false -> {reply, ok, NewS} end; - {error, Error} -> - {reply, {error, Error}, S}; - {'EXIT',R} -> + {error, _} = Error -> + {reply, Error, S}; + {'EXIT', R} -> {reply, {error, R}, S} end; @@ -642,7 +662,7 @@ handle_call({start_application, AppName, RestartType}, From, S) -> %% Incase of erroneous variables do not start the application, %% if the application is permanent crash the node. %% Check if the application is already starting. - case lists:keysearch(AppName, 1, Start_req) of + case lists:keyfind(AppName, 1, Start_req) of false -> case catch check_start_cond(AppName, RestartType, Started, Running) of {ok, Appl} -> @@ -671,13 +691,12 @@ handle_call({start_application, AppName, RestartType}, From, S) -> {reply, ok, SS} end end; - {error, R} -> - {reply, {error, R}, S} + {error, _R} = Error -> + {reply, Error, S} end; - {value, {AppName, _FromX}} -> + {AppName, _FromX} -> SS = S#state{start_req = [{AppName, From} | Start_req]}, {noreply, SS} - end; handle_call({permit_application, AppName, Bool}, From, S) -> @@ -751,11 +770,11 @@ handle_call({permit_application, AppName, Bool}, From, S) -> {noreply, SS}; %%========================== - %% unpermit the applicaition + %% unpermit the application %%========================== %% running {false, _, _, _, _, {value, {_AppName, Id}}} -> - {value, {_AppName2, Type}} = keysearch(AppName, 1, Started), + {_AppName2, Type} = lists:keyfind(AppName, 1, Started), stop_appl(AppName, Id, Type), NRunning = keydelete(AppName, 1, Running), {reply, ok, S#state{running = NRunning}}; @@ -785,9 +804,9 @@ handle_call({permit_application, AppName, Bool}, From, S) -> handle_call({stop_application, AppName}, _From, S) -> #state{running = Running, started = Started} = S, - case keysearch(AppName, 1, Running) of - {value, {_AppName, Id}} -> - {value, {_AppName2, Type}} = keysearch(AppName, 1, Started), + case lists:keyfind(AppName, 1, Running) of + {_AppName, Id} -> + {_AppName2, Type} = lists:keyfind(AppName, 1, Started), stop_appl(AppName, Id, Type), NRunning = keydelete(AppName, 1, Running), NStarted = keydelete(AppName, 1, Started), @@ -813,8 +832,8 @@ handle_call({change_application_data, Applications, Config}, _From, S) -> end, []), case catch do_change_apps(Applications, Config, OldAppls) of - {error, R} -> - {reply, {error, R}, S}; + {error, _} = Error -> + {reply, Error, S}; {'EXIT', R} -> {reply, {error, R}, S}; NewAppls -> @@ -868,10 +887,10 @@ handle_call({control_application, AppName}, {Pid, _Tag}, S) -> handle_call({start_type, AppName}, _From, S) -> Starting = S#state.starting, - StartType = case keysearch(AppName, 1, Starting) of + StartType = case lists:keyfind(AppName, 1, Starting) of false -> local; - {value, {_AppName, _RestartType, Type, _F}} -> + {_AppName, _RestartType, Type, _F} -> Type end, {reply, StartType, S}; @@ -885,6 +904,9 @@ handle_call(info, _From, S) -> {starting, S#state.starting}], {reply, Reply, S}. +-spec handle_cast({'application_started', appname(), _}, state()) -> + {'noreply', state()} | {'stop', string(), state()}. + handle_cast({application_started, AppName, Res}, S) -> handle_application_started(AppName, Res, S). @@ -892,7 +914,7 @@ handle_application_started(AppName, Res, S) -> #state{starting = Starting, running = Running, started = Started, start_req = Start_req} = S, Start_reqN = reply_to_requester(AppName, Start_req, Res), - {value, {_AppName, RestartType, _Type, _From}} = keysearch(AppName, 1, Starting), + {_AppName, RestartType, _Type, _From} = lists:keyfind(AppName, 1, Starting), case Res of {ok, Id} -> case AppName of @@ -907,7 +929,6 @@ handle_application_started(AppName, Res, S) -> running = NRunning, started = NStarted, start_req = Start_reqN}, - %% The permission may have been changed during start Perm = application:get_env(kernel, permissions), case {Perm, Id} of @@ -918,10 +939,10 @@ handle_application_started(AppName, Res, S) -> case lists:member({AppName, false}, Perms) of true -> #state{running = StopRunning, started = StopStarted} = NewS, - case keysearch(AppName, 1, StopRunning) of - {value, {_AppName, Id}} -> - {value, {_AppName2, Type}} = - keysearch(AppName, 1, StopStarted), + case lists:keyfind(AppName, 1, StopRunning) of + {_AppName, Id} -> + {_AppName2, Type} = + lists:keyfind(AppName, 1, StopStarted), stop_appl(AppName, Id, Type), NStopRunning = keydelete(AppName, 1, StopRunning), cntrl(AppName, NewS, {ac_application_stopped, AppName}), @@ -936,12 +957,8 @@ handle_application_started(AppName, Res, S) -> _ -> {noreply, NewS} end; - - - - - {error, R} when RestartType =:= temporary -> - notify_cntrl_started(AppName, undefined, S, {error, R}), + {error, R} = Error when RestartType =:= temporary -> + notify_cntrl_started(AppName, undefined, S, Error), info_exited(AppName, R, RestartType), {noreply, S#state{starting = keydelete(AppName, 1, Starting), start_req = Start_reqN}}; @@ -966,8 +983,8 @@ handle_application_started(AppName, Res, S) -> Reason = {application_start_failure, AppName, R}, {stop, to_string(Reason), S} end; - {error, R} -> %% permanent - notify_cntrl_started(AppName, undefined, S, {error, R}), + {error, R} = Error -> %% permanent + notify_cntrl_started(AppName, undefined, S, Error), info_exited(AppName, R, RestartType), Reason = {application_start_failure, AppName, R}, {stop, to_string(Reason), S}; @@ -977,6 +994,9 @@ handle_application_started(AppName, Res, S) -> {stop, to_string(Reason), S} end. +-spec handle_info(term(), state()) -> + {'noreply', state()} | {'stop', string(), state()}. + handle_info({ac_load_application_reply, AppName, Res}, S) -> case keysearchdelete(AppName, 1, S#state.loading) of {value, {_AppName, From}, Loading} -> @@ -994,12 +1014,12 @@ handle_info({ac_load_application_reply, AppName, Res}, S) -> handle_info({ac_start_application_reply, AppName, Res}, S) -> Start_req = S#state.start_req, - case keysearch(AppName, 1, Starting = S#state.starting) of - {value, {_AppName, RestartType, Type, From}} -> + case lists:keyfind(AppName, 1, Starting = S#state.starting) of + {_AppName, RestartType, Type, From} -> case Res of start_it -> {true, Appl} = get_loaded(AppName), - spawn_starter(From, Appl, S, Type), + spawn_starter(From, Appl, S, Type), {noreply, S}; {started, Node} -> handle_application_started(AppName, @@ -1013,23 +1033,19 @@ handle_info({ac_start_application_reply, AppName, Res}, S) -> S#state{starting = keydelete(AppName, 1, Starting), started = [{AppName, RestartType} | Started], start_req = Start_reqN}}; - {takeover, Node} -> + {takeover, _Node} = Takeover -> {true, Appl} = get_loaded(AppName), - spawn_starter(From, Appl, S, {takeover, Node}), + spawn_starter(From, Appl, S, Takeover), NewStarting1 = keydelete(AppName, 1, Starting), - NewStarting = [{AppName, RestartType, {takeover, Node}, From} | NewStarting1], + NewStarting = [{AppName, RestartType, Takeover, From} | NewStarting1], {noreply, S#state{starting = NewStarting}}; - {error, Reason} when RestartType =:= permanent -> - Start_reqN = - reply_to_requester(AppName, Start_req, - {error, Reason}), + {error, Reason} = Error when RestartType =:= permanent -> + Start_reqN = reply_to_requester(AppName, Start_req, Error), {stop, to_string(Reason), S#state{start_req = Start_reqN}}; - {error, Reason} -> - Start_reqN = - reply_to_requester(AppName, Start_req, - {error, Reason}), + {error, _Reason} = Error -> + Start_reqN = reply_to_requester(AppName, Start_req, Error), {noreply, S#state{starting = - keydelete(AppName, 1, Starting), + keydelete(AppName, 1, Starting), start_req = Start_reqN}} end; false -> @@ -1040,8 +1056,8 @@ handle_info({ac_change_application_req, AppName, Msg}, S) -> Running = S#state.running, Started = S#state.started, Starting = S#state.starting, - case {keysearch(AppName, 1, Running), keysearch(AppName, 1, Started)} of - {{value, {AppName, Id}}, {value, {_AppName2, Type}}} -> + case {keyfind(AppName, 1, Running), keyfind(AppName, 1, Started)} of + {{AppName, Id}, {_AppName2, Type}} -> case Msg of {started, Node} -> stop_appl(AppName, Id, Type), @@ -1134,17 +1150,17 @@ handle_info({'EXIT', Pid, Reason}, S) -> ets:match_delete(ac_tab, {{application_master, '_'}, Pid}), NRunning = keydelete(Pid, 2, S#state.running), NewS = S#state{running = NRunning}, - case keysearch(Pid, 2, S#state.running) of - {value, {AppName, _AmPid}} -> + case lists:keyfind(Pid, 2, S#state.running) of + {AppName, _AmPid} -> cntrl(AppName, S, {ac_application_stopped, AppName}), - case keysearch(AppName, 1, S#state.started) of - {value, {_AppName, temporary}} -> + case lists:keyfind(AppName, 1, S#state.started) of + {_AppName, temporary} -> info_exited(AppName, Reason, temporary), {noreply, NewS}; - {value, {_AppName, transient}} when Reason =:= normal -> + {_AppName, transient} when Reason =:= normal -> info_exited(AppName, Reason, transient), {noreply, NewS}; - {value, {_AppName, Type}} -> + {_AppName, Type} -> info_exited(AppName, Reason, Type), {stop, to_string({application_terminated, AppName, Reason}), NewS} end; @@ -1155,6 +1171,8 @@ handle_info({'EXIT', Pid, Reason}, S) -> handle_info(_, S) -> {noreply, S}. +-spec terminate(term(), state()) -> 'ok'. + terminate(Reason, S) -> case application:get_env(kernel, shutdown_func) of {ok, {M, F}} -> @@ -1170,8 +1188,10 @@ terminate(Reason, S) -> (_) -> ok end, S#state.running), - ets:delete(ac_tab). + true = ets:delete(ac_tab), + ok. +-spec code_change(term(), state(), term()) -> {'ok', state()}. code_change(_OldVsn, State, _Extra) -> {ok, State}. @@ -1181,8 +1201,8 @@ code_change(_OldVsn, State, _Extra) -> %%% Internal functions %%%----------------------------------------------------------------- cntrl(AppName, #state{control = Control}, Msg) -> - case keysearch(AppName, 1, Control) of - {value, {_AppName, Pid}} -> + case lists:keyfind(AppName, 1, Control) of + {_AppName, Pid} -> Pid ! Msg, true; false -> @@ -1282,8 +1302,8 @@ check_start_cond(AppName, RestartType, Started, Running) -> end. do_start(AppName, RT, Type, From, S) -> - RestartType = case keysearch(AppName, 1, S#state.started) of - {value, {_AppName2, OldRT}} -> + RestartType = case lists:keyfind(AppName, 1, S#state.started) of + {_AppName2, OldRT} -> get_restart_type(RT, OldRT); false -> RT @@ -1295,12 +1315,12 @@ do_start(AppName, RT, Type, From, S) -> {true, Appl} = get_loaded(AppName), Start_req = S#state.start_req, spawn_starter(undefined, Appl, S, Type), - Starting = case keysearch(AppName, 1, S#state.starting) of + Starting = case lists:keymember(AppName, 1, S#state.starting) of false -> %% UW: don't know if this is necessary [{AppName, RestartType, Type, From} | S#state.starting]; - _ -> + true -> S#state.starting end, S#state{starting = Starting, @@ -1340,10 +1360,10 @@ start_appl(Appl, S, Type) -> end end, Appl#appl.apps), case application_master:start_link(ApplData, Type) of - {ok, Pid} -> - {ok, Pid}; - {error, Reason} -> - throw({error, Reason}) + {ok, _Pid} = Ok -> + Ok; + {error, _Reason} = Error -> + throw(Error) end end. @@ -1435,15 +1455,15 @@ prim_parse(Tokens, Acc) -> case erl_parse:parse_term(Tokens2 ++ [Dot]) of {ok, Term} -> prim_parse(Rest, [Term | Acc]); - {error, Reason} -> - {error, Reason} + {error, _R} = Error -> + Error end; {Tokens2, []} -> case erl_parse:parse_term(Tokens2) of {ok, Term} -> {ok, lists:reverse([Term | Acc])}; - {error, Reason} -> - {error, Reason} + {error, _R} = Error -> + Error end end. @@ -1456,7 +1476,7 @@ make_appl_i({application, Name, Opts}) when is_atom(Name), is_list(Opts) -> Apps = get_opt(applications, Opts, []), Mod = case get_opt(mod, Opts, []) of - {M,A} when is_atom(M) -> {M,A}; + {M,_A}=MA when is_atom(M) -> MA; [] -> []; Other -> throw({error, {badstartspec, Other}}) end, @@ -1465,8 +1485,8 @@ make_appl_i({application, Name, Opts}) when is_atom(Name), is_list(Opts) -> MaxP = get_opt(maxP, Opts, infinity), MaxT = get_opt(maxT, Opts, infinity), IncApps = get_opt(included_applications, Opts, []), - {#appl_data{name = Name, regs = Regs, mod = Mod, phases = Phases, mods = Mods, - inc_apps = IncApps, maxP = MaxP, maxT = MaxT}, + {#appl_data{name = Name, regs = Regs, mod = Mod, phases = Phases, + mods = Mods, inc_apps = IncApps, maxP = MaxP, maxT = MaxT}, Env, IncApps, Descr, Id, Vsn, Apps}; make_appl_i({application, Name, Opts}) when is_list(Opts) -> throw({error,{invalid_name,Name}}); @@ -1545,12 +1565,12 @@ do_change_appl({ok, {ApplData, Env, IncApps, Descr, Id, Vsn, Apps}}, vsn=Vsn, inc_apps=IncApps, apps=Apps}; -do_change_appl({error, R}, _Appl, _ConfData) -> - throw({error, R}). +do_change_appl({error, _R} = Error, _Appl, _ConfData) -> + throw(Error). get_opt(Key, List, Default) -> - case keysearch(Key, 1, List) of - {value, {_Key, Val}} -> Val; + case lists:keyfind(Key, 1, List) of + {_Key, Val} -> Val; _ -> Default end. @@ -1584,8 +1604,8 @@ make_term(Str) -> end. get_env_i(Name, #state{conf_data = ConfData}) when is_list(ConfData) -> - case keysearch(Name, 1, ConfData) of - {value, {_Name, Env}} -> Env; + case lists:keyfind(Name, 1, ConfData) of + {_Name, Env} -> Env; _ -> [] end; get_env_i(_Name, _) -> []. @@ -1605,9 +1625,6 @@ merge_env([{App, AppEnv1} | T], Env2, Res) -> merge_env([], Env2, Res) -> Env2 ++ Res. - - - %% Merges envs for an application. Env2 overrides Env1 merge_app_env(Env1, Env2) -> merge_app_env(Env1, Env2, []). @@ -1671,13 +1688,12 @@ do_config_change([], _EnvBefore, Errors) -> {error, Errors}; do_config_change([{App, _Id} | Apps], EnvBefore, Errors) -> AppEnvNow = lists:sort(application:get_all_env(App)), - AppEnvBefore = case lists:keysearch(App, 1, EnvBefore) of + AppEnvBefore = case lists:keyfind(App, 1, EnvBefore) of false -> []; - {value, {App, AppEnvBeforeT}} -> + {App, AppEnvBeforeT} -> lists:sort(AppEnvBeforeT) end, - Res = case AppEnvNow of AppEnvBefore -> @@ -1697,12 +1713,12 @@ do_config_change([{App, _Id} | Apps], EnvBefore, Errors) -> %% if the cb-function is not defined {'EXIT', {undef, _}} -> ok; - {error, Error} -> - {error, Error}; + {error, _} = Error -> + Error; Else -> {error, Else} end; - {ok,[]} -> + {ok, []} -> {error, {module_not_defined, App}}; undefined -> {error, {application_not_found, App}} @@ -1716,9 +1732,7 @@ do_config_change([{App, _Id} | Apps], EnvBefore, Errors) -> {error, NewError} -> do_config_change(Apps, EnvBefore,[NewError | Errors]) end. - - - + %%----------------------------------------------------------------- %% Check if the configuration is changed in anyway. @@ -1732,21 +1746,17 @@ do_config_diff([], AppEnvBefore, {Changed, New}) -> do_config_diff(AppEnvNow, [], {Changed, New}) -> {Changed, AppEnvNow++New, []}; do_config_diff([{Env, Value} | AppEnvNow], AppEnvBefore, {Changed, New}) -> - case lists:keysearch(Env, 1, AppEnvBefore) of - {value, {Env, Value}} -> + case lists:keyfind(Env, 1, AppEnvBefore) of + {Env, Value} -> do_config_diff(AppEnvNow, lists:keydelete(Env,1,AppEnvBefore), {Changed, New}); - {value, {Env, _OtherValue}} -> + {Env, _OtherValue} -> do_config_diff(AppEnvNow, lists:keydelete(Env,1,AppEnvBefore), {[{Env, Value} | Changed], New}); false -> do_config_diff(AppEnvNow, AppEnvBefore, {Changed, [{Env, Value}|New]}) end. - - - - %%----------------------------------------------------------------- %% Read the .config files. %%----------------------------------------------------------------- @@ -1901,14 +1911,13 @@ reply_to_requester(AppName, Start_req, Res) -> %% Update the environment variable permission for an application. %%----------------------------------------------------------------- update_permissions(AppName, Bool) -> - case ets:lookup(ac_tab, {env, kernel, permissions}) of + T = {env, kernel, permissions}, + case ets:lookup(ac_tab, T) of [] -> - ets:insert(ac_tab, {{env, kernel, permissions}, - [{AppName, Bool}]}); + ets:insert(ac_tab, {T, [{AppName, Bool}]}); [{_, Perm}] -> Perm2 = lists:keydelete(AppName, 1, Perm), - ets:insert(ac_tab, {{env, kernel, permissions}, - [{AppName, Bool}| Perm2]}) + ets:insert(ac_tab, {T, [{AppName, Bool}|Perm2]}) end. %%----------------------------------------------------------------- @@ -1937,6 +1946,9 @@ test_make_apps([A|Apps], Res) -> %% Exit reason needs to be a printable string %% (and of length <200, but init now does the chopping). %%----------------------------------------------------------------- + +-spec to_string(term()) -> string(). + to_string(Term) -> case io_lib:printable_list(Term) of true -> diff --git a/lib/kernel/src/application_starter.erl b/lib/kernel/src/application_starter.erl index 8d839e4662..564366f304 100644 --- a/lib/kernel/src/application_starter.erl +++ b/lib/kernel/src/application_starter.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1998-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% %% %% ---------------------------------------------------------------------- @@ -42,8 +42,8 @@ start([], _Type, _Apps) -> ok; start([{Phase,_PhaseArgs}|Phases], Type, Apps) -> case start_apps(Phase, Type, Apps) of - {error, Error} -> - {error, Error}; + {error, _} = Error -> + Error; _ -> start(Phases, Type, Apps) end. @@ -56,8 +56,8 @@ start_apps(_Phase, _Type, []) -> ok; start_apps(Phase, Type, [App | Apps]) -> case catch run_start_phase(Phase, Type, App) of - {error, Error} -> - {error, Error}; + {error, _} = Error -> + Error; _ -> start_apps(Phase, Type, Apps) end. @@ -91,10 +91,10 @@ run_the_phase(Phase, Type, App, Mod) -> {ok, Sp} -> Sp end, - case lists:keysearch(Phase, 1, Start_phases) of + case lists:keyfind(Phase, 1, Start_phases) of false -> ok; - {value, {Phase, PhaseArgs}} -> + {Phase, PhaseArgs} -> case catch Mod:start_phase(Phase, Type, PhaseArgs) of ok -> ok; diff --git a/lib/kernel/src/auth.erl b/lib/kernel/src/auth.erl index 62c0bef0cc..5c7fe2421d 100644 --- a/lib/kernel/src/auth.erl +++ b/lib/kernel/src/auth.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(auth). @@ -37,10 +37,12 @@ -define(COOKIE_ETS_PROTECTION, protected). +-type cookie() :: atom(). -record(state, { - our_cookie, %% Our own cookie - other_cookies %% The send-cookies of other nodes + our_cookie :: cookie(), %% Our own cookie + other_cookies :: ets:tab() %% The send-cookies of other nodes }). +-type state() :: #state{}. -include("../include/file.hrl"). @@ -48,6 +50,8 @@ %% Exported functions %%---------------------------------------------------------------------- +-spec start_link() -> {'ok',pid()} | {'error', term()} | 'ignore'. + start_link() -> gen_server:start_link({local, auth}, auth, [], []). @@ -61,24 +65,24 @@ is_auth(Node) -> pang -> no end. --spec cookie() -> atom(). +-spec cookie() -> cookie(). cookie() -> get_cookie(). --spec cookie(Cookies :: [atom(),...] | atom()) -> 'true'. +-spec cookie(Cookies :: [cookie(),...] | cookie()) -> 'true'. cookie([Cookie]) -> set_cookie(Cookie); cookie(Cookie) -> set_cookie(Cookie). --spec node_cookie(Cookies :: [atom(),...]) -> 'yes' | 'no'. +-spec node_cookie(Cookies :: [node() | cookie(),...]) -> 'yes' | 'no'. node_cookie([Node, Cookie]) -> node_cookie(Node, Cookie). --spec node_cookie(Node :: node(), Cookie :: atom()) -> 'yes' | 'no'. +-spec node_cookie(Node :: node(), Cookie :: cookie()) -> 'yes' | 'no'. node_cookie(Node, Cookie) -> set_cookie(Node, Cookie), @@ -86,24 +90,24 @@ node_cookie(Node, Cookie) -> %%--"New" interface----------------------------------------------------- --spec get_cookie() -> atom(). +-spec get_cookie() -> 'nocookie' | cookie(). get_cookie() -> get_cookie(node()). --spec get_cookie(Node :: node()) -> atom(). +-spec get_cookie(Node :: node()) -> 'nocookie' | cookie(). get_cookie(_Node) when node() =:= nonode@nohost -> nocookie; get_cookie(Node) -> gen_server:call(auth, {get_cookie, Node}). --spec set_cookie(Cookie :: atom()) -> 'true'. +-spec set_cookie(Cookie :: cookie()) -> 'true'. set_cookie(Cookie) -> set_cookie(node(), Cookie). --spec set_cookie(Node :: node(), Cookie :: atom()) -> 'true'. +-spec set_cookie(Node :: node(), Cookie :: cookie()) -> 'true'. set_cookie(_Node, _Cookie) when node() =:= nonode@nohost -> erlang:error(distribution_not_started); @@ -117,11 +121,13 @@ sync_cookie() -> -spec print(Node :: node(), Format :: string(), Args :: [_]) -> 'ok'. -print(Node,Format,Args) -> - (catch gen_server:cast({auth,Node},{print,Format,Args})). +print(Node, Format, Args) -> + (catch gen_server:cast({auth, Node}, {print, Format, Args})). %%--gen_server callbacks------------------------------------------------ +-spec init([]) -> {'ok', state()}. + init([]) -> process_flag(trap_exit, true), {ok, init_cookie()}. @@ -130,6 +136,13 @@ init([]) -> %% The net kernel will let all message to the auth server %% through as is +-type calls() :: 'echo' | 'sync_cookie' + | {'get_cookie', node()} + | {'set_cookie', node(), term()}. + +-spec handle_call(calls(), {pid(), term()}, state()) -> + {'reply', 'hello' | 'true' | 'nocookie' | cookie(), state()}. + handle_call({get_cookie, Node}, {_From,_Tag}, State) when Node =:= node() -> {reply, State#state.our_cookie, State}; handle_call({get_cookie, Node}, {_From,_Tag}, State) -> @@ -145,7 +158,7 @@ handle_call({set_cookie, Node, Cookie}, {_From,_Tag}, State) %% %% Happens when the distribution is brought up and -%% Someone wight have set up the cookie for our new nodename. +%% someone might have set up the cookie for our new node name. %% handle_call({set_cookie, Node, Cookie}, {_From,_Tag}, State) -> @@ -153,9 +166,9 @@ handle_call({set_cookie, Node, Cookie}, {_From,_Tag}, State) -> {reply, true, State}; handle_call(sync_cookie, _From, State) -> - case ets:lookup(State#state.other_cookies,node()) of + case ets:lookup(State#state.other_cookies, node()) of [{_N,C}] -> - ets:delete(State#state.other_cookies,node()), + ets:delete(State#state.other_cookies, node()), {reply, true, State#state{our_cookie = C}}; [] -> {reply, true, State} @@ -164,13 +177,22 @@ handle_call(sync_cookie, _From, State) -> handle_call(echo, _From, O) -> {reply, hello, O}. +%% +%% handle_cast/2 +%% + +-spec handle_cast({'print', string(), [term()]}, state()) -> + {'noreply', state()}. + handle_cast({print,What,Args}, O) -> %% always allow print outs - error_logger:error_msg(What,Args), + error_logger:error_msg(What, Args), {noreply, O}. %% A series of bad messages that may come (from older distribution versions). +-spec handle_info(term(), state()) -> {'noreply', state()}. + handle_info({From,badcookie,net_kernel,{From,spawn,_M,_F,_A,_Gleader}}, O) -> auth:print(node(From) ,"~n** Unauthorized spawn attempt to ~w **~n", [node()]), @@ -188,10 +210,10 @@ handle_info({_From,badcookie,ddd_server,_Mess}, O) -> {noreply, O}; handle_info({From,badcookie,rex,_Msg}, O) -> auth:print(getnode(From), - "~n** Unauthorized rpc attempt to ~w **~n",[node()]), + "~n** Unauthorized rpc attempt to ~w **~n", [node()]), disconnect_node(node(From)), {noreply, O}; -%% These two messages has to do with the old auth:is_auth() call (net_adm:ping) +%% These two messages have to do with the old auth:is_auth() call (net_adm:ping) handle_info({From,badcookie,net_kernel,{'$gen_call',{From,Tag},{is_auth,_Node}}}, O) -> %% ho ho From ! {Tag, no}, {noreply, O}; @@ -215,12 +237,16 @@ handle_info({From,badcookie,Name,Mess}, Opened) -> end end, {noreply, Opened}; -handle_info(_, O)-> % Ignore anything else especially EXIT signals +handle_info(_, O) -> % Ignore anything else especially EXIT signals {noreply, O}. +-spec code_change(term(), state(), term()) -> {'ok', state()}. + code_change(_OldVsn, State, _Extra) -> {ok, State}. +-spec terminate(term(), state()) -> 'ok'. + terminate(_Reason, _State) -> ok. @@ -260,7 +286,7 @@ init_cookie() -> end; _Other -> #state{our_cookie = nocookie, - other_cookies = ets:new(cookies,[?COOKIE_ETS_PROTECTION])} + other_cookies = ets:new(cookies, [?COOKIE_ETS_PROTECTION])} end. read_cookie() -> diff --git a/lib/kernel/src/code.erl b/lib/kernel/src/code.erl index ffe58ae7a9..ec256d5806 100644 --- a/lib/kernel/src/code.erl +++ b/lib/kernel/src/code.erl @@ -66,6 +66,8 @@ set_primary_archive/3, clash/0]). +-export_type([load_error_rsn/0, load_ret/0]). + -include_lib("kernel/include/file.hrl"). %% User interface. @@ -302,6 +304,8 @@ do_start(Flags) -> true -> ok end, + % Quietly load the native code for all modules loaded so far. + catch load_native_code_for_all_loaded(), Ok2; Other -> Other @@ -425,8 +429,8 @@ where_is_file(Path, File) when is_list(Path), is_list(File) -> FileInfo :: #file_info{}) -> 'ok' | {'error', atom()}. -set_primary_archive(ArchiveFile0, ArchiveBin, FileInfo) - when is_list(ArchiveFile0), is_binary(ArchiveBin), is_record(FileInfo, file_info) -> +set_primary_archive(ArchiveFile0, ArchiveBin, #file_info{} = FileInfo) + when is_list(ArchiveFile0), is_binary(ArchiveBin) -> ArchiveFile = filename:absname(ArchiveFile0), case call({set_primary_archive, ArchiveFile, ArchiveBin, FileInfo}) of {ok, []} -> @@ -473,7 +477,7 @@ decorate([], _) -> []; decorate([File|Tail], Dir) -> [{Dir, File} | decorate(Tail, Dir)]. -filter(_Ext, Dir, {error,_}) -> +filter(_Ext, Dir, error) -> io:format("** Bad path can't read ~s~n", [Dir]), []; filter(Ext, _, {ok,Files}) -> filter2(Ext, length(Ext), Files). @@ -494,3 +498,19 @@ has_ext(Ext, Extlen,File) -> to_path(X) -> filename:join(packages:split(X)). + +-spec load_native_code_for_all_loaded() -> ok. +load_native_code_for_all_loaded() -> + Architecture = erlang:system_info(hipe_architecture), + ChunkName = hipe_unified_loader:chunk_name(Architecture), + lists:foreach(fun({Module, BeamFilename}) -> + case code:is_module_native(Module) of + false -> + case beam_lib:chunks(BeamFilename, [ChunkName]) of + {ok,{_,[{_,Bin}]}} when is_binary(Bin) -> + load_native_partial(Module, Bin); + {error, beam_lib, _} -> ok + end; + true -> ok + end + end, all_loaded()). diff --git a/lib/kernel/src/code_server.erl b/lib/kernel/src/code_server.erl index 7aeddb73d1..4a1fc7df34 100644 --- a/lib/kernel/src/code_server.erl +++ b/lib/kernel/src/code_server.erl @@ -32,14 +32,15 @@ -import(lists, [foreach/2]). --record(state,{supervisor, - root, - path, - moddb, - namedb, - cache = no_cache, - mode=interactive, - on_load = []}). +-record(state, {supervisor, + root, + path, + moddb, + namedb, + cache = no_cache, + mode = interactive, + on_load = []}). +-type state() :: #state{}. start_link(Args) -> Ref = make_ref(), @@ -65,8 +66,8 @@ init(Ref, Parent, [Root,Mode0]) -> Mode = case Mode0 of - minimal -> interactive; - _ -> Mode0 + minimal -> interactive; + _ -> Mode0 end, IPath = @@ -74,7 +75,7 @@ init(Ref, Parent, [Root,Mode0]) -> interactive -> LibDir = filename:append(Root, "lib"), {ok,Dirs} = erl_prim_loader:list_dir(LibDir), - {Paths,_Libs} = make_path(LibDir,Dirs), + {Paths,_Libs} = make_path(LibDir, Dirs), UserLibPaths = get_user_lib_dirs(), ["."] ++ UserLibPaths ++ Paths; _ -> @@ -97,7 +98,7 @@ init(Ref, Parent, [Root,Mode0]) -> end, Parent ! {Ref,{ok,self()}}, - loop(State#state{supervisor=Parent}). + loop(State#state{supervisor = Parent}). get_user_lib_dirs() -> case os:getenv("ERL_LIBS") of @@ -169,8 +170,8 @@ loop(#state{supervisor=Supervisor}=State0) -> %%%%%%%%%%%%%%%%%%%%%%%%%%% %% System upgrade -handle_system_msg(SysState,Msg,From,Parent,Misc) -> - case do_sys_cmd(SysState,Msg,Parent, Misc) of +handle_system_msg(SysState, Msg, From, Parent, Misc) -> + case do_sys_cmd(SysState, Msg, Parent, Misc) of {suspended, Reply, NMisc} -> gen_reply(From, Reply), suspend_loop(suspended, Parent, NMisc); @@ -207,7 +208,7 @@ do_sys_cmd(SysState, {debug, _What}, _Parent, Misc) -> do_sys_cmd(suspended, {change_code, Module, Vsn, Extra}, _Parent, Misc0) -> {Res, Misc} = case catch ?MODULE:system_code_change(Misc0, Module, Vsn, Extra) of - {ok, Misc1} -> {ok, Misc1}; + {ok, _} = Ok -> Ok; Else -> {{error, Else}, Misc0} end, {suspended, Res, Misc}; @@ -218,9 +219,10 @@ system_continue(_Parent, _Debug, State) -> loop(State). system_terminate(_Reason, _Parent, _Debug, _State) -> -% error_msg("~p terminating: ~p~n ",[?MODULE,Reason]), + %% error_msg("~p terminating: ~p~n ", [?MODULE, Reason]), exit(shutdown). +-spec system_code_change(state(), module(), term(), term()) -> {'ok', state()}. system_code_change(State, _Module, _OldVsn, _Extra) -> {ok, State}. @@ -240,7 +242,7 @@ handle_call({stick_mod,Mod}, {_From,_Tag}, S) -> handle_call({unstick_mod,Mod}, {_From,_Tag}, S) -> {reply,stick_mod(Mod, false, S),S}; -handle_call({dir,Dir},{_From,_Tag}, S) -> +handle_call({dir,Dir}, {_From,_Tag}, S) -> Root = S#state.root, Resp = do_dir(Root,Dir,S#state.namedb), {reply,Resp,S}; @@ -253,43 +255,47 @@ handle_call({load_file,Mod}, Caller, St) -> load_file(Mod, Caller, St) end; -handle_call({add_path,Where,Dir0}, {_From,_Tag}, S=#state{cache=Cache0}) -> +handle_call({add_path,Where,Dir0}, {_From,_Tag}, + #state{cache=Cache0,namedb=Namedb,path=Path0}=S) -> case Cache0 of no_cache -> - {Resp,Path} = add_path(Where, Dir0, S#state.path, S#state.namedb), + {Resp,Path} = add_path(Where, Dir0, Path0, Namedb), {reply,Resp,S#state{path=Path}}; _ -> Dir = absname(Dir0), %% Cache always expands the path - {Resp,Path} = add_path(Where, Dir, S#state.path, S#state.namedb), - Cache=update_cache([Dir],Where,Cache0), + {Resp,Path} = add_path(Where, Dir, Path0, Namedb), + Cache = update_cache([Dir], Where, Cache0), {reply,Resp,S#state{path=Path,cache=Cache}} end; -handle_call({add_paths,Where,Dirs0}, {_From,_Tag}, S=#state{cache=Cache0}) -> +handle_call({add_paths,Where,Dirs0}, {_From,_Tag}, + #state{cache=Cache0,namedb=Namedb,path=Path0}=S) -> case Cache0 of no_cache -> - {Resp,Path} = add_paths(Where,Dirs0,S#state.path,S#state.namedb), - {reply,Resp, S#state{path=Path}}; + {Resp,Path} = add_paths(Where, Dirs0, Path0, Namedb), + {reply,Resp,S#state{path=Path}}; _ -> %% Cache always expands the path Dirs = [absname(Dir) || Dir <- Dirs0], - {Resp,Path} = add_paths(Where, Dirs, S#state.path, S#state.namedb), + {Resp,Path} = add_paths(Where, Dirs, Path0, Namedb), Cache=update_cache(Dirs,Where,Cache0), {reply,Resp,S#state{cache=Cache,path=Path}} end; -handle_call({set_path,PathList}, {_From,_Tag}, S) -> - Path = S#state.path, - {Resp, NewPath,NewDb} = set_path(PathList, Path, S#state.namedb), - {reply,Resp,rehash_cache(S#state{path = NewPath, namedb=NewDb})}; +handle_call({set_path,PathList}, {_From,_Tag}, + #state{path=Path0,namedb=Namedb}=S) -> + {Resp,Path,NewDb} = set_path(PathList, Path0, Namedb), + {reply,Resp,rehash_cache(S#state{path=Path,namedb=NewDb})}; -handle_call({del_path,Name}, {_From,_Tag}, S) -> - {Resp,Path} = del_path(Name,S#state.path,S#state.namedb), - {reply,Resp,rehash_cache(S#state{path = Path})}; +handle_call({del_path,Name}, {_From,_Tag}, + #state{path=Path0,namedb=Namedb}=S) -> + {Resp,Path} = del_path(Name, Path0, Namedb), + {reply,Resp,rehash_cache(S#state{path=Path})}; -handle_call({replace_path,Name,Dir}, {_From,_Tag}, S) -> - {Resp,Path} = replace_path(Name,Dir,S#state.path,S#state.namedb), - {reply,Resp,rehash_cache(S#state{path = Path})}; +handle_call({replace_path,Name,Dir}, {_From,_Tag}, + #state{path=Path0,namedb=Namedb}=S) -> + {Resp,Path} = replace_path(Name, Dir, Path0, Namedb), + {reply,Resp,rehash_cache(S#state{path=Path})}; handle_call(rehash, {_From,_Tag}, S0) -> S = create_cache(S0), @@ -311,12 +317,12 @@ handle_call({load_binary,Mod,File,Bin}, Caller, S) -> do_load_binary(Mod, File, Bin, Caller, S); handle_call({load_native_partial,Mod,Bin}, {_From,_Tag}, S) -> - Result = (catch hipe_unified_loader:load(Mod,Bin)), + Result = (catch hipe_unified_loader:load(Mod, Bin)), Status = hipe_result_to_status(Result), {reply,Status,S}; handle_call({load_native_sticky,Mod,Bin,WholeModule}, {_From,_Tag}, S) -> - Result = (catch hipe_unified_loader:load_module(Mod,Bin,WholeModule)), + Result = (catch hipe_unified_loader:load_module(Mod, Bin, WholeModule)), Status = hipe_result_to_status(Result), {reply,Status,S}; @@ -388,8 +394,8 @@ handle_call({set_primary_archive, File, ArchiveBin, FileInfo}, {_From,_Tag}, S=# case erl_prim_loader:set_primary_archive(File, ArchiveBin, FileInfo) of {ok, Files} -> {reply, {ok, Mode, Files}, S}; - {error, Reason} -> - {reply, {error, Reason}, S} + {error, _Reason} = Error -> + {reply, Error, S} end; handle_call({is_cached,File}, {_From,_Tag}, S=#state{cache=Cache}) -> @@ -469,8 +475,8 @@ locate_mods([], _, _, Cache, Path) -> filter_mods([File|Rest], Where, Exts, Dir, Cache) -> Ext = filename:extension(File), Root = list_to_atom(filename:rootname(File, Ext)), - case lists:keysearch(Ext, 2, Exts) of - {value,{Type,_}} -> + case lists:keyfind(Ext, 2, Exts) of + {Type, _} -> Key = {Type,Root}, case Where of first -> @@ -487,7 +493,6 @@ filter_mods([File|Rest], Where, Exts, Dir, Cache) -> ok end, filter_mods(Rest, Where, Exts, Dir, Cache); - filter_mods([], _, _, _, Cache) -> Cache. @@ -498,27 +503,27 @@ filter_mods([], _, _, _, Cache) -> %% %% Create the initial path. %% -make_path(BundleDir,Bundles0) -> +make_path(BundleDir, Bundles0) -> Bundles = choose_bundles(Bundles0), - make_path(BundleDir,Bundles,[],[]). + make_path(BundleDir, Bundles, [], []). choose_bundles(Bundles) -> ArchiveExt = archive_extension(), - Bs = lists:sort([create_bundle(B,ArchiveExt) || B <- Bundles]), + Bs = lists:sort([create_bundle(B, ArchiveExt) || B <- Bundles]), [FullName || {_Name,_NumVsn,FullName} <- choose(lists:reverse(Bs), [], ArchiveExt)]. -create_bundle(FullName,ArchiveExt) -> - BaseName = filename:basename(FullName,ArchiveExt), +create_bundle(FullName, ArchiveExt) -> + BaseName = filename:basename(FullName, ArchiveExt), case split(BaseName, "-") of - Toks when length(Toks) > 1 -> + [_, _|_] = Toks -> VsnStr = lists:last(Toks), case vsn_to_num(VsnStr) of {ok, VsnNum} -> - Name = join(lists:sublist(Toks,length(Toks)-1),"-"), + Name = join(lists:sublist(Toks, length(Toks)-1),"-"), {Name,VsnNum,FullName}; false -> - {FullName, [0], FullName} + {FullName,[0],FullName} end; _ -> {FullName,[0],FullName} @@ -569,8 +574,8 @@ join([], _) -> []. choose([{Name,NumVsn,NewFullName}=New|Bs], Acc, ArchiveExt) -> - case lists:keysearch(Name,1,Acc) of - {value, {_, NV, OldFullName}} when NV =:= NumVsn -> + case lists:keyfind(Name, 1, Acc) of + {_, NV, OldFullName} when NV =:= NumVsn -> case filename:extension(OldFullName) =:= ArchiveExt of false -> choose(Bs,Acc, ArchiveExt); @@ -578,7 +583,7 @@ choose([{Name,NumVsn,NewFullName}=New|Bs], Acc, ArchiveExt) -> Acc2 = lists:keystore(Name, 1, Acc, New), choose(Bs,Acc2, ArchiveExt) end; - {value, {_, _, _}} -> + {_, _, _} -> choose(Bs,Acc, ArchiveExt); false -> choose(Bs,[{Name,NumVsn,NewFullName}|Acc], ArchiveExt) @@ -602,8 +607,8 @@ make_path(BundleDir,[Bundle|Tail],Res,Bs) -> Ebin2 = filename:join([filename:dirname(Dir), Base ++ Ext, Base, "ebin"]), Ebins = case split(Base, "-") of - Toks when length(Toks) > 1 -> - AppName = join(lists:sublist(Toks,length(Toks)-1),"-"), + [_, _|_] = Toks -> + AppName = join(lists:sublist(Toks, length(Toks)-1),"-"), Ebin3 = filename:join([filename:dirname(Dir), Base ++ Ext, AppName, "ebin"]), [Ebin3, Ebin2, Dir]; _ -> @@ -835,30 +840,25 @@ add_path(_,_,Path,_) -> %% then the table is created :-) %% do_add(first,Dir,Path,NameDb) -> - update(Dir,NameDb), + update(Dir, NameDb), [Dir|lists:delete(Dir,Path)]; do_add(last,Dir,Path,NameDb) -> case lists:member(Dir,Path) of true -> Path; false -> - maybe_update(Dir,NameDb), + maybe_update(Dir, NameDb), Path ++ [Dir] end. %% Do not update if the same name already exists ! -maybe_update(Dir,NameDb) -> - case lookup_name(get_name(Dir),NameDb) of - false -> update(Dir,NameDb); - _ -> false - end. +maybe_update(Dir, NameDb) -> + (lookup_name(get_name(Dir), NameDb) =:= false) andalso update(Dir, NameDb). update(_Dir, false) -> - ok; -update(Dir,NameDb) -> - replace_name(Dir,NameDb). - - + true; +update(Dir, NameDb) -> + replace_name(Dir, NameDb). %% %% Set a completely new path. @@ -946,8 +946,8 @@ all_archive_subdirs(AppDir) -> Base = filename:basename(AppDir), Dirs = case split(Base, "-") of - Toks when length(Toks) > 1 -> - Base2 = join(lists:sublist(Toks,length(Toks)-1),"-"), + [_, _|_] = Toks -> + Base2 = join(lists:sublist(Toks, length(Toks)-1), "-"), [Base2, Base]; _ -> [Base] @@ -1060,7 +1060,6 @@ check_pars(Name,Dir) -> {error,bad_name} end. - del_ebin(Dir) -> case filename:basename(Dir) of "ebin" -> @@ -1079,8 +1078,6 @@ del_ebin(Dir) -> Dir end. - - replace_name(Dir, Db) -> case get_name(Dir) of Dir -> @@ -1187,15 +1184,7 @@ get_mods([File|Tail], Extension) -> get_mods([], _) -> []. is_sticky(Mod, Db) -> - case erlang:module_loaded(Mod) of - true -> - case ets:lookup(Db, {sticky,Mod}) of - [] -> false; - _ -> true - end; - false -> - false - end. + erlang:module_loaded(Mod) andalso (ets:lookup(Db, {sticky, Mod}) =/= []). add_paths(Where,[Dir|Tail],Path,NameDb) -> {_,NPath} = add_path(Where,Dir,Path,NameDb), @@ -1203,7 +1192,6 @@ add_paths(Where,[Dir|Tail],Path,NameDb) -> add_paths(_,_,Path,_) -> {ok,Path}. - do_load_binary(Module, File, Binary, Caller, St) -> case modp(Module) andalso modp(File) andalso is_binary(Binary) of true -> @@ -1220,7 +1208,6 @@ modp(Atom) when is_atom(Atom) -> true; modp(List) when is_list(List) -> int_list(List); modp(_) -> false. - load_abs(File, Mod0, Caller, St) -> Ext = objfile_extension(), FileName0 = lists:concat([File, Ext]), @@ -1263,20 +1250,20 @@ try_load_module_1(File, Mod, Bin, Caller, #state{moddb=Db}=St) -> {reply,{error,sticky_directory},St}; false -> case catch load_native_code(Mod, Bin) of - {module,Mod} -> + {module,Mod} = Module -> ets:insert(Db, {Mod,File}), - {reply,{module,Mod},St}; + {reply,Module,St}; no_native -> case erlang:load_module(Mod, Bin) of - {module,Mod} -> + {module,Mod} = Module -> ets:insert(Db, {Mod,File}), post_beam_load(Mod), - {reply,{module,Mod},St}; + {reply,Module,St}; {error,on_load} -> handle_on_load(Mod, File, Caller, St); - {error,What} -> + {error,What} = Error -> error_msg("Loading of ~s failed: ~p\n", [File, What]), - {reply,{error,What},St} + {reply,Error,St} end; Error -> error_msg("Native loading of ~s failed: ~p\n", diff --git a/lib/kernel/src/disk_log.hrl b/lib/kernel/src/disk_log.hrl index b0849145ca..9a94d4d3b9 100644 --- a/lib/kernel/src/disk_log.hrl +++ b/lib/kernel/src/disk_log.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% %% @@ -44,17 +44,11 @@ -define(OPENED, <<6,7,8,9>>). -define(CLOSED, <<99,88,77,11>>). -%% Needed for the definition of fd() +%% Needed for the definition of #file_info{} %% Must use include_lib() so that we always can be sure to find %% file.hrl. A relative path will not work in an installed system. -include_lib("kernel/include/file.hrl"). -%% Ugly workaround. If we are building the bootstrap compiler, -%% file.hrl does not define the fd() type. --ifndef(FILE_HRL_). --type fd() :: pid() | #file_descriptor{}. --endif. - %%------------------------------------------------------------------------ %% Types -- alphabetically %%------------------------------------------------------------------------ @@ -94,7 +88,7 @@ options = [] :: dlog_options()}). -record(cache, %% Cache for logged terms (per file descriptor). - {fd :: fd(), %% File descriptor. + {fd :: file:fd(), %% File descriptor. sz = 0 :: non_neg_integer(), %% Number of bytes in the cache. c = [] :: iodata()} %% The cache. ). diff --git a/lib/kernel/src/disk_log_1.erl b/lib/kernel/src/disk_log_1.erl index 7103417149..8ccdb88d12 100644 --- a/lib/kernel/src/disk_log_1.erl +++ b/lib/kernel/src/disk_log_1.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% %% -module(disk_log_1). @@ -1529,7 +1529,7 @@ write_cache(Fd, FileName, C) -> Error -> {catch file_error(FileName, Error), #cache{fd = Fd}} end. --spec write_cache_close(fd(), file:filename(), iodata()) -> #cache{}. % | throw(Error) +-spec write_cache_close(file:fd(), file:filename(), iodata()) -> #cache{}. % | throw(Error) write_cache_close(Fd, _FileName, []) -> #cache{fd = Fd}; @@ -1539,12 +1539,12 @@ write_cache_close(Fd, FileName, C) -> Error -> file_error_close(Fd, FileName, Error) end. --spec file_error(file:filename(), {'error', atom()}) -> no_return(). +-spec file_error(file:filename(), {'error', file:posix()}) -> no_return(). file_error(FileName, {error, Error}) -> throw({error, {file_error, FileName, Error}}). --spec file_error_close(fd(), file:filename(), {'error', atom()}) -> no_return(). +-spec file_error_close(file:fd(), file:filename(), {'error', file:posix()}) -> no_return(). file_error_close(Fd, FileName, {error, Error}) -> file:close(Fd), diff --git a/lib/kernel/src/dist_util.erl b/lib/kernel/src/dist_util.erl index a2937d60b8..f0d54a2f3e 100644 --- a/lib/kernel/src/dist_util.erl +++ b/lib/kernel/src/dist_util.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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% %% %%%---------------------------------------------------------------------- @@ -564,7 +564,7 @@ recv_challenge(#hs_data{socket=Socket,other_node=Node, case Recv(Socket, 0, infinity) of {ok,[$n,V1,V0,Fl1,Fl2,Fl3,Fl4,CA3,CA2,CA1,CA0 | Ns]} -> Flags = ?u32(Fl1,Fl2,Fl3,Fl4), - case {list_to_existing_atom(Ns),?u16(V1,V0)} of + try {list_to_existing_atom(Ns),?u16(V1,V0)} of {Node,Version} -> Challenge = ?u32(CA3,CA2,CA1,CA0), ?trace("recv: node=~w, challenge=~w version=~w\n", @@ -572,6 +572,9 @@ recv_challenge(#hs_data{socket=Socket,other_node=Node, {Flags,Challenge}; _ -> ?shutdown(no_node) + catch + error:badarg -> + ?shutdown(no_node) end; _ -> ?shutdown(no_node) diff --git a/lib/kernel/src/erl_boot_server.erl b/lib/kernel/src/erl_boot_server.erl index 702b2feac9..b4c5f5e27c 100644 --- a/lib/kernel/src/erl_boot_server.erl +++ b/lib/kernel/src/erl_boot_server.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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% %% %% A simple boot_server at a CP. @@ -53,6 +53,7 @@ bootp :: pid(), %% boot process prim_state %% state for efile code loader }). +-type state() :: #state{}. -define(single_addr_mask, {255, 255, 255, 255}). @@ -165,6 +166,8 @@ member_address(_, []) -> %% call-back functions. %% ------------------------------------------------------------ +-spec init([atom()]) -> {'ok', state()}. + init(Slaves) -> {ok, U} = gen_udp:open(?EBOOT_PORT, []), {ok, L} = gen_tcp:listen(0, [binary,{packet,4}]), @@ -176,15 +179,18 @@ init(Slaves) -> Pid ! {Ref, L}, %% We trap exit inorder to restart boot_init and udp_port process_flag(trap_exit, true), - {ok, #state {priority = 0, - version = erlang:system_info(version), - udp_sock = U, - udp_port = UPort, - listen_sock = L, - listen_port = Port, - slaves = ordsets:from_list(Slaves), - bootp = Pid - }}. + {ok, #state{priority = 0, + version = erlang:system_info(version), + udp_sock = U, + udp_port = UPort, + listen_sock = L, + listen_port = Port, + slaves = ordsets:from_list(Slaves), + bootp = Pid + }}. + +-spec handle_call('which' | {'add',atom()} | {'delete',atom()}, _, state()) -> + {'reply', 'ok' | [atom()], state()}. handle_call({add,Address}, _, S0) -> Slaves = ordsets:add_element(Address, S0#state.slaves), @@ -197,9 +203,13 @@ handle_call({delete,Address}, _, S0) -> handle_call(which, _, S0) -> {reply, ordsets:to_list(S0#state.slaves), S0}. +-spec handle_cast(term(), [atom()]) -> {'noreply', [atom()]}. + handle_cast(_, Slaves) -> {noreply, Slaves}. +-spec handle_info(term(), state()) -> {'noreply', state()}. + handle_info({udp, U, IP, Port, Data}, S0) -> Token = ?EBOOT_REQUEST ++ S0#state.version, Valid = member_address(IP, ordsets:to_list(S0#state.slaves)), @@ -230,9 +240,13 @@ handle_info({udp, U, IP, Port, Data}, S0) -> handle_info(_Info, S0) -> {noreply,S0}. +-spec terminate(term(), state()) -> 'ok'. + terminate(_Reason, _S0) -> ok. +-spec code_change(term(), state(), term()) -> {'ok', state()}. + code_change(_Vsn, State, _Extra) -> {ok, State}. @@ -242,6 +256,8 @@ code_change(_Vsn, State, _Extra) -> %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec boot_init(reference()) -> no_return(). + boot_init(Tag) -> receive {Tag, Listen} -> diff --git a/lib/kernel/src/erl_epmd.erl b/lib/kernel/src/erl_epmd.erl index e4b371836b..91af49f303 100644 --- a/lib/kernel/src/erl_epmd.erl +++ b/lib/kernel/src/erl_epmd.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1998-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(erl_epmd). @@ -40,6 +40,7 @@ -import(lists, [reverse/1]). -record(state, {socket, port_no = -1, name = ""}). +-type state() :: #state{}. -include("inet_int.hrl"). -include("erl_epmd.hrl"). @@ -111,11 +112,18 @@ register_node(Name, PortNo) -> %%% Callback functions from gen_server %%%---------------------------------------------------------------------- +-spec init(_) -> {'ok', state()}. + init(_) -> {ok, #state{socket = -1}}. %%---------------------------------------------------------------------- +-type calls() :: 'client_info_req' | 'stop' | {'register', term(), term()}. + +-spec handle_call(calls(), term(), state()) -> + {'reply', term(), state()} | {'stop', 'shutdown', 'ok', state()}. + handle_call({register, Name, PortNo}, _From, State) -> case State#state.socket of P when P < 0 -> @@ -133,19 +141,23 @@ handle_call({register, Name, PortNo}, _From, State) -> end; handle_call(client_info_req, _From, State) -> - Reply = {ok,{r4,State#state.name,State#state.port_no}}, - {reply,Reply,State}; + Reply = {ok,{r4,State#state.name,State#state.port_no}}, + {reply, Reply, State}; handle_call(stop, _From, State) -> {stop, shutdown, ok, State}. %%---------------------------------------------------------------------- +-spec handle_cast(term(), state()) -> {'noreply', state()}. + handle_cast(_, State) -> {noreply, State}. %%---------------------------------------------------------------------- +-spec handle_info(term(), state()) -> {'noreply', state()}. + handle_info({tcp_closed, Socket}, State) when State#state.socket =:= Socket -> {noreply, State#state{socket = -1}}; handle_info(_, State) -> @@ -153,6 +165,8 @@ handle_info(_, State) -> %%---------------------------------------------------------------------- +-spec terminate(term(), state()) -> 'ok'. + terminate(_, #state{socket = Socket}) when Socket > 0 -> close(Socket), ok; @@ -161,6 +175,8 @@ terminate(_, _) -> %%---------------------------------------------------------------------- +-spec code_change(term(), state(), term()) -> {'ok', state()}. + code_change(_OldVsn, State, _Extra) -> {ok, State}. @@ -194,19 +210,6 @@ open({A,B,C,D,E,F,G,H}=EpmdAddr, Timeout) when ?ip6(A,B,C,D,E,F,G,H) -> close(Socket) -> gen_tcp:close(Socket). - -do_register_node_v0(NodeName, TcpPort) -> - case open() of - {ok, Socket} -> - Name = cstring(NodeName), - Len = 1+2+length(Name), - gen_tcp:send(Socket, [?int16(Len), ?EPMD_ALIVE, - ?int16(TcpPort), Name]), - wait_for_reg_reply_v0(Socket, []); - Error -> - Error - end. - do_register_node(NodeName, TcpPort) -> case open() of {ok, Socket} -> @@ -224,14 +227,7 @@ do_register_node(NodeName, TcpPort) -> Name, ?int16(Elen), Extra]), - case wait_for_reg_reply(Socket, []) of - {error, epmd_close} -> - %% could be old epmd; try old protocol -% erlang:display('trying old'), - do_register_node_v0(NodeName, TcpPort); - Other -> - Other - end; + wait_for_reg_reply(Socket, []); Error -> Error end. @@ -289,41 +285,9 @@ wait_for_reg_reply(Socket, SoFar) -> {error, no_reg_reply_from_epmd} end. -wait_for_reg_reply_v0(Socket, SoFar) -> - receive - {tcp, Socket, Data0} -> - case SoFar ++ Data0 of - [$Y, A, B] -> - {alive, Socket, ?u16(A, B)}; - Data when length(Data) < 3 -> - wait_for_reg_reply(Socket, Data); - Garbage -> - {error, {garbage_from_epmd, Garbage}} - end; - {tcp_closed, Socket} -> - {error, duplicate_name} % A guess -- the most likely reason. - after 10000 -> - gen_tcp:close(Socket), - {error, no_reg_reply_from_epmd} - end. %% %% Lookup a node "Name" at Host %% -get_port_v0(Node, EpmdAddress) -> - case open(EpmdAddress) of - {ok, Socket} -> - Name = cstring(Node), - Len = 1+length(Name), - gen_tcp:send(Socket, [?int16(Len),?EPMD_PORT_PLEASE, Name]), - wait_for_port_reply_v0(Socket, []); - _Error -> - ?port_please_failure(), - noport - end. - -%%% Not used anymore -%%% get_port(Node, EpmdAddress) -> -%%% get_port(Node, EpmdAddress, infinity). get_port(Node, EpmdAddress, Timeout) -> case open(EpmdAddress, Timeout) of @@ -331,40 +295,12 @@ get_port(Node, EpmdAddress, Timeout) -> Name = to_string(Node), Len = 1+length(Name), gen_tcp:send(Socket, [?int16(Len),?EPMD_PORT_PLEASE2_REQ, Name]), - Reply = wait_for_port_reply(Socket, []), - case Reply of - closed -> - get_port_v0(Node, EpmdAddress); - Other -> - Other - end; + wait_for_port_reply(Socket, []); _Error -> ?port_please_failure2(_Error), noport end. -wait_for_port_reply_v0(Socket, SoFar) -> - receive - {tcp, Socket, Data0} -> -% io:format("got ~p~n", [Data0]), - case SoFar ++ Data0 of - [A, B] -> - wait_for_close(Socket, {port, ?u16(A, B), 0}); -% wait_for_close(Socket, {port, ?u16(A, B)}); - Data when length(Data) < 2 -> - wait_for_port_reply_v0(Socket, Data); - Garbage -> - ?port_please_failure(), - {error, {garbage_from_epmd, Garbage}} - end; - {tcp_closed, Socket} -> - ?port_please_failure(), - noport - after 10000 -> - ?port_please_failure(), - gen_tcp:close(Socket), - noport - end. wait_for_port_reply(Socket, SoFar) -> receive @@ -471,8 +407,6 @@ wait_for_close(Socket, Reply) -> %% %% Creates a (flat) null terminated string from atom or list. %% -cstring(S) when is_atom(S) -> cstring(atom_to_list(S)); -cstring(S) when is_list(S) -> S ++ [0]. to_string(S) when is_atom(S) -> atom_to_list(S); to_string(S) when is_list(S) -> S. diff --git a/lib/kernel/src/erl_epmd.hrl b/lib/kernel/src/erl_epmd.hrl index 47ab6195d8..5a50fda508 100644 --- a/lib/kernel/src/erl_epmd.hrl +++ b/lib/kernel/src/erl_epmd.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% Copyright Ericsson AB 1998-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 @@ -17,16 +17,13 @@ %% %CopyrightEnd% %% --define(EPMD_ALIVE, $a). --define(EPMD_PORT_PLEASE, $p). --define(EPMD_NAMES, $n). --define(EPMD_DUMP, $d). --define(EPMD_KILL, $k). --define(EPMD_STOP, $s). - --define(EPMD_ALIVE_OK, $Y). - -define(EPMD_ALIVE2_REQ, $x). -define(EPMD_PORT_PLEASE2_REQ, $z). -define(EPMD_ALIVE2_RESP, $y). -define(EPMD_PORT2_RESP, $w). +-define(EPMD_NAMES, $n). + +%% Commands used only by interactive client +-define(EPMD_DUMP, $d). +-define(EPMD_KILL, $k). +-define(EPMD_STOP, $s). diff --git a/lib/kernel/src/error_handler.erl b/lib/kernel/src/error_handler.erl index 5f2507fc08..17dd02acd4 100644 --- a/lib/kernel/src/error_handler.erl +++ b/lib/kernel/src/error_handler.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(error_handler). @@ -117,13 +117,13 @@ stub_function(Mod, Func, Args) -> check_inheritance(Module, Args) -> Attrs = erlang:get_module_info(Module, attributes), - case lists:keysearch(extends, 1, Attrs) of - {value,{extends,[Base]}} when is_atom(Base), Base =/= Module -> + case lists:keyfind(extends, 1, Attrs) of + {extends, [Base]} when is_atom(Base), Base =/= Module -> %% This is just a heuristic for detecting abstract modules %% with inheritance so they can be handled; it would be %% much better to do it in the emulator runtime - case lists:keysearch(abstract, 1, Attrs) of - {value,{abstract,[true]}} -> + case lists:keyfind(abstract, 1, Attrs) of + {abstract, [true]} -> case lists:reverse(Args) of [M|Rs] when tuple_size(M) > 1, element(1,M) =:= Module, diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl index a42771dfb6..cffe4e3db5 100644 --- a/lib/kernel/src/file.erl +++ b/lib/kernel/src/file.erl @@ -36,11 +36,11 @@ %% Specialized -export([ipread_s32bu_p32bu/3]). %% Generic file contents. --export([open/2, close/1, +-export([open/2, close/1, advise/4, read/2, write/2, pread/2, pread/3, pwrite/2, pwrite/3, read_line/1, - position/2, truncate/1, sync/1, + position/2, truncate/1, datasync/1, sync/1, copy/2, copy/3]). %% High level operations -export([consult/1, path_consult/2]). @@ -61,6 +61,9 @@ -export([ipread_s32bu_p32bu_int/3]). +%% Types that can be used from other modules -- alphabetically ordered. +-export_type([date_time/0, fd/0, file_info/0, filename/0, io_device/0, + name/0, posix/0]). %%% Includes and defines -include("file.hrl"). @@ -74,15 +77,24 @@ %% data types -type filename() :: string(). -type file_info() :: #file_info{}. --type io_device() :: pid() | #file_descriptor{}. +-type fd() :: #file_descriptor{}. +-type io_device() :: pid() | fd(). -type location() :: integer() | {'bof', integer()} | {'cur', integer()} | {'eof', integer()} | 'bof' | 'cur' | 'eof'. -type mode() :: 'read' | 'write' | 'append' | 'raw' | 'binary' | {'delayed_write', non_neg_integer(), non_neg_integer()} | 'delayed_write' | {'read_ahead', pos_integer()} | - 'read_ahead' | 'compressed'. + 'read_ahead' | 'compressed' | 'exclusive'. +-type name() :: string() | atom() | [name()]. +-type posix() :: atom(). -type bindings() :: any(). +-type date() :: {pos_integer(), pos_integer(), pos_integer()}. +-type time() :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}. +-type date_time() :: {date(), time()}. +-type posix_file_advise() :: 'normal' | 'sequential' | 'random' | 'no_reuse' | + 'will_need' | 'dont_need'. + %%%----------------------------------------------------------------- %%% General functions @@ -345,10 +357,22 @@ close(#file_descriptor{module = Module} = Handle) -> close(_) -> {error, badarg}. --spec read(File :: io_device(), Size :: non_neg_integer()) -> +-spec advise(File :: io_device(), Offset :: integer(), + Length :: integer(), Advise :: posix_file_advise()) -> + 'ok' | {'error', posix()}. + +advise(File, Offset, Length, Advise) when is_pid(File) -> + R = file_request(File, {advise, Offset, Length, Advise}), + wait_file_reply(File, R); +advise(#file_descriptor{module = Module} = Handle, Offset, Length, Advise) -> + Module:advise(Handle, Offset, Length, Advise); +advise(_, _, _, _) -> + {error, badarg}. + +-spec read(File :: io_device() | atom(), Size :: non_neg_integer()) -> 'eof' | {'ok', [char()] | binary()} | {'error', posix()}. -read(File, Sz) when is_pid(File), is_integer(Sz), Sz >= 0 -> +read(File, Sz) when (is_pid(File) orelse is_atom(File)), is_integer(Sz), Sz >= 0 -> case io:request(File, {get_chars, '', Sz}) of Data when is_list(Data); is_binary(Data) -> {ok, Data}; @@ -361,10 +385,10 @@ read(#file_descriptor{module = Module} = Handle, Sz) read(_, _) -> {error, badarg}. --spec read_line(File :: io_device()) -> +-spec read_line(File :: io_device() | atom()) -> 'eof' | {'ok', [char()] | binary()} | {'error', posix()}. -read_line(File) when is_pid(File) -> +read_line(File) when (is_pid(File) orelse is_atom(File)) -> case io:request(File, {get_line, ''}) of Data when is_list(Data); is_binary(Data) -> {ok, Data}; @@ -415,10 +439,10 @@ pread(#file_descriptor{module = Module} = Handle, Offs, Sz) pread(_, _, _) -> {error, badarg}. --spec write(File :: io_device(), Byte :: iodata()) -> +-spec write(File :: io_device() | atom(), Byte :: iodata()) -> 'ok' | {'error', posix()}. -write(File, Bytes) when is_pid(File) -> +write(File, Bytes) when (is_pid(File) orelse is_atom(File)) -> case make_binary(Bytes) of Bin when is_binary(Bin) -> io:request(File, {put_chars,Bin}); @@ -465,6 +489,16 @@ pwrite(#file_descriptor{module = Module} = Handle, Offs, Bytes) -> pwrite(_, _, _) -> {error, badarg}. +-spec datasync(File :: io_device()) -> 'ok' | {'error', posix()}. + +datasync(File) when is_pid(File) -> + R = file_request(File, datasync), + wait_file_reply(File, R); +datasync(#file_descriptor{module = Module} = Handle) -> + Module:datasync(Handle); +datasync(_) -> + {error, badarg}. + -spec sync(File :: io_device()) -> 'ok' | {'error', posix()}. sync(File) when is_pid(File) -> diff --git a/lib/kernel/src/file_io_server.erl b/lib/kernel/src/file_io_server.erl index 37e803c493..39dc32bb79 100644 --- a/lib/kernel/src/file_io_server.erl +++ b/lib/kernel/src/file_io_server.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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(file_io_server). @@ -106,21 +106,21 @@ do_start(Spawn, Owner, FileName, ModeList) -> parse_options(List) -> parse_options(expand_encoding(List), list, latin1, []). -parse_options([],list,Uni,Acc) -> +parse_options([], list, Uni, Acc) -> {list,Uni,[binary|lists:reverse(Acc)]}; -parse_options([],binary,Uni,Acc) -> +parse_options([], binary, Uni, Acc) -> {binary,Uni,lists:reverse(Acc)}; -parse_options([{encoding, Encoding}|T],RMode,_,Acc) -> +parse_options([{encoding, Encoding}|T], RMode, _, Acc) -> case valid_enc(Encoding) of {ok, ExpandedEnc} -> - parse_options(T,RMode,ExpandedEnc,Acc); - {error,Reason} -> - {error,Reason} + parse_options(T, RMode, ExpandedEnc, Acc); + {error,_Reason} = Error -> + Error end; -parse_options([binary|T],_,Uni,Acc) -> - parse_options(T,binary,Uni,[binary|Acc]); -parse_options([H|T],R,U,Acc) -> - parse_options(T,R,U,[H|Acc]). +parse_options([binary|T], _, Uni, Acc) -> + parse_options(T, binary, Uni, [binary|Acc]); +parse_options([H|T], R, U, Acc) -> + parse_options(T, R, U, [H|Acc]). expand_encoding([]) -> []; @@ -153,7 +153,6 @@ valid_enc(_Other) -> {error,badarg}. - server_loop(#state{mref = Mref} = State) -> receive {file_request, From, ReplyAs, Request} when is_pid(From) -> @@ -199,6 +198,14 @@ io_reply(From, ReplyAs, Reply) -> %%%----------------------------------------------------------------- %%% file requests +file_request({advise,Offset,Length,Advise}, + #state{handle=Handle}=State) -> + case ?PRIM_FILE:advise(Handle, Offset, Length, Advise) of + {error,_}=Reply -> + {stop,normal,Reply,State}; + Reply -> + {reply,Reply,State} + end; file_request({pread,At,Sz}, #state{handle=Handle,buf=Buf,read_mode=ReadMode}=State) -> case position(Handle, At, Buf) of @@ -220,6 +227,14 @@ file_request({pwrite,At,Data}, Reply -> std_reply(Reply, State) end; +file_request(datasync, + #state{handle=Handle}=State) -> + case ?PRIM_FILE:datasync(Handle) of + {error,_}=Reply -> + {stop,normal,Reply,State}; + Reply -> + {reply,Reply,State} + end; file_request(sync, #state{handle=Handle}=State) -> case ?PRIM_FILE:sync(Handle) of @@ -326,7 +341,6 @@ io_request(Unknown, {error,{error,Reason},State}. - %% Process a list of requests as long as the results are ok. io_request_loop([], Result) -> @@ -342,7 +356,6 @@ io_request_loop([Request|Tail], io_request_loop(Tail, io_request(Request, State)). - %% I/O request put_chars %% put_chars(Chars, latin1, #state{handle=Handle, unic=latin1}=State) -> @@ -653,20 +666,14 @@ do_setopts(Opts, State) -> end. getopts(#state{read_mode=RM, unic=Unic} = State) -> - Bin = {binary, case RM of - binary -> - true; - _ -> - false - end}, + Bin = {binary, RM =:= binary}, Uni = {encoding, Unic}, {reply,[Bin,Uni],State}. - %% Concatenate two binaries and convert the result to list or binary -cat(B1, B2, binary,latin1,latin1) -> +cat(B1, B2, binary, latin1, latin1) -> list_to_binary([B1,B2]); -cat(B1, B2, binary,InEncoding,OutEncoding) -> +cat(B1, B2, binary, InEncoding, OutEncoding) -> case unicode:characters_to_binary([B1,B2],InEncoding,OutEncoding) of Good when is_binary(Good) -> Good; diff --git a/lib/kernel/src/file_server.erl b/lib/kernel/src/file_server.erl index 74f2fb94a9..64c61ba3ac 100644 --- a/lib/kernel/src/file_server.erl +++ b/lib/kernel/src/file_server.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -62,6 +62,8 @@ stop() -> %%% Callback functions from gen_server %%%---------------------------------------------------------------------- +-type state() :: port(). % Internal type + %%---------------------------------------------------------------------- %% Func: init/1 %% Returns: {ok, State} | @@ -69,6 +71,9 @@ stop() -> %% ignore | %% {stop, Reason} %%---------------------------------------------------------------------- + +-spec init([]) -> {'ok', state()} | {'stop', term()}. + init([]) -> process_flag(trap_exit, true), case ?PRIM_FILE:start() of @@ -88,6 +93,12 @@ init([]) -> %% {stop, Reason, Reply, State} | (terminate/2 is called) %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- + +-spec handle_call(term(), term(), state()) -> + {'noreply', state()} | + {'reply', 'eof' | 'ok' | {'error', term()} | {'ok', term()}, state()} | + {'stop', 'normal', 'stopped', state()}. + handle_call({open, Name, ModeList}, {Pid, _Tag} = _From, Handle) when is_list(ModeList) -> Child = ?FILE_IO_SERVER:start_link(Pid, Name, ModeList), @@ -190,6 +201,9 @@ handle_call(Request, From, Handle) -> %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- + +-spec handle_cast(term(), state()) -> {'noreply', state()}. + handle_cast(Msg, State) -> error_logger:error_msg("handle_cast(~p, _)", [Msg]), {noreply, State}. @@ -201,6 +215,9 @@ handle_cast(Msg, State) -> %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- +-spec handle_info(term(), state()) -> + {'noreply', state()} | {'stop', 'normal', state()}. + handle_info({'EXIT', Pid, _Reason}, Handle) when is_pid(Pid) -> ets:delete(?FILE_IO_SERVER_TABLE, Pid), {noreply, Handle}; @@ -219,6 +236,9 @@ handle_info(Info, State) -> %% Purpose: Shutdown the server %% Returns: any (ignored by gen_server) %%---------------------------------------------------------------------- + +-spec terminate(term(), state()) -> 'ok'. + terminate(_Reason, Handle) -> ?PRIM_FILE:stop(Handle). @@ -227,6 +247,9 @@ terminate(_Reason, Handle) -> %% Purpose: Convert process state when code is changed %% Returns: {ok, NewState} %%---------------------------------------------------------------------- + +-spec code_change(term(), state(), term()) -> {'ok', state()}. + code_change(_OldVsn, State, _Extra) -> {ok, State}. diff --git a/lib/kernel/src/gen_sctp.erl b/lib/kernel/src/gen_sctp.erl index 5a31e3976f..cccfa75005 100644 --- a/lib/kernel/src/gen_sctp.erl +++ b/lib/kernel/src/gen_sctp.erl @@ -39,7 +39,7 @@ open() -> open([]). open(Opts) when is_list(Opts) -> - Mod = mod(Opts), + Mod = mod(Opts, undefined), case Mod:open(Opts) of {error,badarg} -> erlang:error(badarg, [Opts]); @@ -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) -> @@ -238,17 +234,27 @@ controlling_process(S, Pid) -> %% Utilites %% -%% Get the SCTP moudule -mod() -> inet_db:sctp_module(). +%% Get the SCTP module, but IPv6 address overrides default IPv4 +mod(Address) -> + case inet_db:sctp_module() of + inet_sctp when tuple_size(Address) =:= 8 -> + inet6_sctp; + Mod -> + Mod + end. %% Get the SCTP module, but option sctp_module|inet|inet6 overrides -mod([{sctp_module,Mod}|_]) -> +mod([{sctp_module,Mod}|_], _Address) -> Mod; -mod([inet|_]) -> +mod([inet|_], _Address) -> inet_sctp; -mod([inet6|_]) -> +mod([inet6|_], _Address) -> inet6_sctp; -mod([_|Opts]) -> - mod(Opts); -mod([]) -> - mod(). +mod([{ip, Address}|Opts], _) -> + mod(Opts, Address); +mod([{ifaddr, Address}|Opts], _) -> + mod(Opts, Address); +mod([_|Opts], Address) -> + mod(Opts, Address); +mod([], Address) -> + mod(Address). diff --git a/lib/kernel/src/gen_tcp.erl b/lib/kernel/src/gen_tcp.erl index 7401b06a64..16a87d71b6 100644 --- a/lib/kernel/src/gen_tcp.erl +++ b/lib/kernel/src/gen_tcp.erl @@ -1,7 +1,7 @@ %% %% %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 @@ -46,7 +46,7 @@ connect(Address, Port, Opts, Time) -> end. connect1(Address,Port,Opts,Timer) -> - Mod = mod(Opts), + Mod = mod(Opts, Address), case Mod:getaddrs(Address,Timer) of {ok,IPs} -> case Mod:getserv(Port) of @@ -73,7 +73,7 @@ try_connect([], _Port, _Opts, _Timer, _Mod, Err) -> %% Listen on a tcp port %% listen(Port, Opts) -> - Mod = mod(Opts), + Mod = mod(Opts, undefined), case Mod:getserv(Port) of {ok,TP} -> Mod:listen(TP, Opts); @@ -173,20 +173,30 @@ controlling_process(S, NewOwner) -> %% Create a port/socket from a file descriptor %% fdopen(Fd, Opts) -> - Mod = mod(Opts), + Mod = mod(Opts, undefined), Mod:fdopen(Fd, Opts). -%% Get the tcp_module -mod() -> inet_db:tcp_module(). +%% Get the tcp_module, but IPv6 address overrides default IPv4 +mod(Address) -> + case inet_db:tcp_module() of + inet_tcp when tuple_size(Address) =:= 8 -> + inet6_tcp; + Mod -> + Mod + end. %% Get the tcp_module, but option tcp_module|inet|inet6 overrides -mod([{tcp_module,Mod}|_]) -> +mod([{tcp_module,Mod}|_], _Address) -> Mod; -mod([inet|_]) -> +mod([inet|_], _Address) -> inet_tcp; -mod([inet6|_]) -> +mod([inet6|_], _Address) -> inet6_tcp; -mod([_|Opts]) -> - mod(Opts); -mod([]) -> - mod(). +mod([{ip, Address}|Opts], _) -> + mod(Opts, Address); +mod([{ifaddr, Address}|Opts], _) -> + mod(Opts, Address); +mod([_|Opts], Address) -> + mod(Opts, Address); +mod([], Address) -> + mod(Address). diff --git a/lib/kernel/src/gen_udp.erl b/lib/kernel/src/gen_udp.erl index 6bded4bda6..99020c7b6c 100644 --- a/lib/kernel/src/gen_udp.erl +++ b/lib/kernel/src/gen_udp.erl @@ -1,7 +1,7 @@ %% %% %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 @@ -29,7 +29,7 @@ open(Port) -> open(Port, []). open(Port, Opts) -> - Mod = mod(Opts), + Mod = mod(Opts, undefined), {ok,UP} = Mod:getserv(Port), Mod:open(UP, Opts). @@ -97,21 +97,31 @@ controlling_process(S, NewOwner) -> %% Create a port/socket from a file descriptor %% fdopen(Fd, Opts) -> - Mod = mod(), + Mod = mod(Opts, undefined), Mod:fdopen(Fd, Opts). -%% Get the udp_module -mod() -> inet_db:udp_module(). +%% Get the udp_module, but IPv6 address overrides default IPv4 +mod(Address) -> + case inet_db:udp_module() of + inet_udp when tuple_size(Address) =:= 8 -> + inet6_udp; + Mod -> + Mod + end. %% Get the udp_module, but option udp_module|inet|inet6 overrides -mod([{udp_module,Mod}|_]) -> +mod([{udp_module,Mod}|_], _Address) -> Mod; -mod([inet|_]) -> +mod([inet|_], _Address) -> inet_udp; -mod([inet6|_]) -> +mod([inet6|_], _Address) -> inet6_udp; -mod([_|Opts]) -> - mod(Opts); -mod([]) -> - mod(). +mod([{ip, Address}|Opts], _) -> + mod(Opts, Address); +mod([{ifaddr, Address}|Opts], _) -> + mod(Opts, Address); +mod([_|Opts], Address) -> + mod(Opts, Address); +mod([], Address) -> + mod(Address). diff --git a/lib/kernel/src/global.erl b/lib/kernel/src/global.erl index cc0402da73..081e7e2f93 100644 --- a/lib/kernel/src/global.erl +++ b/lib/kernel/src/global.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(global). @@ -112,7 +112,7 @@ resolvers = [], syncers = [] :: [pid()], node_name = node() :: node(), - the_locker, the_deleter, the_registrar, trace, + the_locker, the_registrar, trace, global_lock_down = false }). @@ -153,6 +153,8 @@ %%% It can be removed later as can the deleter process. %%% An extra process calling erlang:monitor() is sometimes created. %%% The new_nodes messages has been augmented with the global lock id. +%%% +%%% R14A (OTP-8527): The deleter process has been removed. start() -> gen_server:start({local, global_name_server}, ?MODULE, [], []). @@ -418,7 +420,6 @@ init([]) -> S = #state{the_locker = start_the_locker(DoTrace), trace = T0, - the_deleter = start_the_deleter(self()), the_registrar = start_the_registrar()}, S1 = trace_message(S, {init, node()}, []), @@ -763,13 +764,16 @@ handle_cast({in_sync, Node, _IsKnown}, S) -> %% Called when Pid on other node crashed handle_cast({async_del_name, _Name, _Pid}, S) -> - %% Sent from the_deleter at some node in the partition but node(). + %% Sent from the_deleter at some node in the partition but node() (-R13B) %% The DOWN message deletes the name. + %% R14A nodes and later do not send async_del_name messages. {noreply, S}; handle_cast({async_del_lock, _ResourceId, _Pid}, S) -> - %% Sent from global_name_server at some node in the partition but node(). + %% Sent from global_name_server at some node in the partition but + %% node(). (-R13B) %% The DOWN message deletes the lock. + %% R14A nodes and later do not send async_del_lock messages. {noreply, S}; handle_cast(Request, S) -> @@ -778,8 +782,6 @@ handle_cast(Request, S) -> "handle_cast(~p, _)\n", [Request]), {noreply, S}. -handle_info({'EXIT', Deleter, _Reason}=Exit, #state{the_deleter=Deleter}=S) -> - {stop, {deleter_died,Exit}, S#state{the_deleter=undefined}}; handle_info({'EXIT', Locker, _Reason}=Exit, #state{the_locker=Locker}=S) -> {stop, {locker_died,Exit}, S#state{the_locker=undefined}}; handle_info({'EXIT', Registrar, _}=Exit, #state{the_registrar=Registrar}=S) -> @@ -1348,30 +1350,13 @@ lock_still_set(PidOrNode, ExtraInfo, S) -> [{?GLOBAL_RID, _LockReqId, PidRefs}] when is_pid(PidOrNode) -> %% Name registration. lists:keymember(PidOrNode, 1, PidRefs); - [{?GLOBAL_RID, LockReqId, PidRefs}] when is_atom(PidOrNode) -> - case extra_info(lock, ExtraInfo) of - {?GLOBAL_RID, LockId} -> % R11B-4 or later - LockReqId =:= LockId; - undefined -> - lock_still_set_old(PidOrNode, LockReqId, PidRefs) - end; + [{?GLOBAL_RID, LockReqId, _PidRefs}] when is_atom(PidOrNode) -> + {?GLOBAL_RID, LockId} = extra_info(lock, ExtraInfo), + LockReqId =:= LockId; [] -> - %% If the global lock was not removed by a DOWN message - %% then we have a node that do not monitor locking pids - %% (pre R11B-3), or an R11B-3 node (which does not ensure - %% that {new_nodes, ...} arrives before {del_lock, ...}). not S#state.global_lock_down end. -%%% The following is probably overkill. It is possible that this node -%%% has been locked again, but it is a rare occasion. -lock_still_set_old(_Node, ReqId, _PidRefs) when is_pid(ReqId) -> - %% Cannot do better than return true. - true; -lock_still_set_old(Node, ReqId, PidRefs) when is_list(ReqId) -> - %% Connection, version > 4, but before R11B-4. - [P || {P, _RPid, _Ref} <- PidRefs, node(P) =:= Node] =/= []. - extra_info(Tag, ExtraInfo) -> %% ExtraInfo used to be a list of nodes (vsn 2). case catch lists:keyfind(Tag, 1, ExtraInfo) of @@ -1382,36 +1367,18 @@ extra_info(Tag, ExtraInfo) -> end. del_name(Ref, S) -> - NameL = [{Name, Pid} || + NameL = [Name || {_, Name} <- ets:lookup(global_pid_names, Ref), - {_, Pid, _Method, _RPid, Ref1} <- + {_, _Pid, _Method, _RPid, Ref1} <- ets:lookup(global_names, Name), Ref1 =:= Ref], - ?trace({async_del_name, self(), NameL, Ref}), case NameL of - [{Name, Pid}] -> - _ = del_names(Name, Pid, S), + [Name] -> delete_global_name2(Name, S); [] -> S end. -%% Send {async_del_name, ...} to old nodes (pre R11B-3). -del_names(Name, Pid, S) -> - Send = case ets:lookup(global_names_ext, Name) of - [{Name, Pid, RegNode}] -> - RegNode =:= node(); - [] -> - node(Pid) =:= node() - end, - if - Send -> - ?trace({del_names, {pid,Pid}, {name,Name}}), - S#state.the_deleter ! {delete_name, self(), Name, Pid}; - true -> - ok - end. - %% Keeps the entry in global_names for whereis_name/1. delete_global_name_keep_pid(Name, S) -> case ets:lookup(global_names, Name) of @@ -1986,7 +1953,6 @@ pid_is_locking(Pid, PidRefs) -> delete_lock(Ref, S0) -> Locks = pid_locks(Ref), - del_locks(Locks, Ref, S0#state.known), F = fun({ResourceId, LockRequesterId, PidRefs}, S) -> {Pid, _RPid, Ref} = lists:keyfind(Ref, 3, PidRefs), remove_lock(ResourceId, LockRequesterId, Pid, PidRefs, true,S) @@ -2003,20 +1969,6 @@ pid_locks(Ref) -> rpid_is_locking(Ref, PidRefs) -> lists:keyfind(Ref, 3, PidRefs) =/= false. -%% Send {async_del_lock, ...} to old nodes (pre R11B-3). -del_locks([{ResourceId, _LockReqId, PidRefs} | Tail], Ref, KnownNodes) -> - {Pid, _RPid, Ref} = lists:keyfind(Ref, 3, PidRefs), - case node(Pid) =:= node() of - true -> - gen_server:abcast(KnownNodes, global_name_server, - {async_del_lock, ResourceId, Pid}); - false -> - ok - end, - del_locks(Tail, Ref, KnownNodes); -del_locks([], _Ref, _KnownNodes) -> - ok. - handle_nodedown(Node, S) -> %% DOWN signals from monitors have removed locks and registered names. #state{known = Known, synced = Syncs} = S, @@ -2147,51 +2099,6 @@ get_own_nodes() -> OkTup end. -%%----------------------------------------------------------------- -%% The deleter process is a satellite process to global_name_server -%% that does background batch deleting of names when a process -%% that had globally registered names dies. It is started by and -%% linked to global_name_server. -%%----------------------------------------------------------------- - -start_the_deleter(Global) -> - spawn_link(fun() -> loop_the_deleter(Global) end). - -loop_the_deleter(Global) -> - Deletions = collect_deletions(Global, []), - ?trace({loop_the_deleter, self(), {deletions,Deletions}, - {names,get_names()}}), - %% trans_all_known is called rather than trans/3 with nodes() as - %% third argument. The reason is that known gets updated by - %% new_nodes when the lock is still set. nodes() on the other hand - %% could be updated later (if in_sync is received after the lock - %% is gone). It is not likely that in_sync would be received after - %% the lock has been taken here, but using trans_all_known makes it - %% even less likely. - trans_all_known( - fun(Known) -> - lists:map( - fun({Name,Pid}) -> - gen_server:abcast(Known, global_name_server, - {async_del_name, Name, Pid}) - end, Deletions) - end), - loop_the_deleter(Global). - -collect_deletions(Global, Deletions) -> - receive - {delete_name, Global, Name, Pid} -> - collect_deletions(Global, [{Name,Pid} | Deletions]); - Other -> - unexpected_message(Other, deleter), - collect_deletions(Global, Deletions) - after case Deletions of - [] -> infinity; - _ -> 0 - end -> - lists:reverse(Deletions) - end. - %% The registrar is a helper process that registers and unregisters %% names. Since it never dies it assures that names are registered and %% unregistered on all known nodes. It is started by and linked to diff --git a/lib/kernel/src/group.erl b/lib/kernel/src/group.erl index a45ba34eae..f92c6f7208 100644 --- a/lib/kernel/src/group.erl +++ b/lib/kernel/src/group.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(group). @@ -477,15 +477,15 @@ get_line(Chars, Pbs, Drv, Encoding) -> get_line1(edlin:edit_line(Chars, Cont), Drv, new_stack(get(line_buffer)), Encoding). -get_line1({done,Line,Rest,Rs}, Drv, _Ls, _Encoding) -> +get_line1({done,Line,Rest,Rs}, Drv, Ls, _Encoding) -> send_drv_reqs(Drv, Rs), - put(line_buffer, [Line|lists:delete(Line, get(line_buffer))]), + save_line_buffer(Line, get_lines(Ls)), {done,Line,Rest}; get_line1({undefined,{_A,Mode,Char},Cs,Cont,Rs}, Drv, Ls0, Encoding) when ((Mode =:= none) and (Char =:= $\^P)) or ((Mode =:= meta_left_sq_bracket) and (Char =:= $A)) -> send_drv_reqs(Drv, Rs), - case up_stack(Ls0) of + case up_stack(save_line(Ls0, edlin:current_line(Cont))) of {none,_Ls} -> send_drv(Drv, beep), get_line1(edlin:edit_line(Cs, Cont), Drv, Ls0, Encoding); @@ -498,14 +498,14 @@ get_line1({undefined,{_A,Mode,Char},Cs,Cont,Rs}, Drv, Ls0, Encoding) Drv, Ls, Encoding) end; -get_line1({undefined,{_A,Mode,Char},_Cs,Cont,Rs}, Drv, Ls0, Encoding) +get_line1({undefined,{_A,Mode,Char},Cs,Cont,Rs}, Drv, Ls0, Encoding) when ((Mode =:= none) and (Char =:= $\^N)) or ((Mode =:= meta_left_sq_bracket) and (Char =:= $B)) -> send_drv_reqs(Drv, Rs), - case down_stack(Ls0) of - {none,Ls} -> - send_drv_reqs(Drv, edlin:erase_line(Cont)), - get_line1(edlin:start(edlin:prompt(Cont)), Drv, Ls, Encoding); + case down_stack(save_line(Ls0, edlin:current_line(Cont))) of + {none,_Ls} -> + send_drv(Drv, beep), + get_line1(edlin:edit_line(Cs, Cont), Drv, Ls0, Encoding); {Lcs,Ls} -> send_drv_reqs(Drv, edlin:erase_line(Cont)), {more_chars,Ncont,Nrs} = edlin:start(edlin:prompt(Cont)), @@ -627,6 +627,28 @@ down_stack({stack,U,{},[]}) -> down_stack({stack,U,C,D}) -> down_stack({stack,[C|U],{},D}). +save_line({stack, U, {}, []}, Line) -> + {stack, U, {}, [Line]}; +save_line({stack, U, _L, D}, Line) -> + {stack, U, Line, D}. + +get_lines({stack, U, {}, []}) -> + U; +get_lines({stack, U, {}, D}) -> + tl(lists:reverse(D, U)); +get_lines({stack, U, L, D}) -> + get_lines({stack, U, {}, [L|D]}). + +save_line_buffer("\n", Lines) -> + save_line_buffer(Lines); +save_line_buffer(Line, [Line|_Lines]=Lines) -> + save_line_buffer(Lines); +save_line_buffer(Line, Lines) -> + save_line_buffer([Line|Lines]). + +save_line_buffer(Lines) -> + put(line_buffer, Lines). + %% This is get_line without line editing (except for backspace) and %% without echo. get_password_line(Chars, Drv) -> diff --git a/lib/kernel/src/heart.erl b/lib/kernel/src/heart.erl index bad0950fca..e78acfc7a6 100644 --- a/lib/kernel/src/heart.erl +++ b/lib/kernel/src/heart.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(heart). @@ -61,8 +61,8 @@ start() -> wait_for_init_ack(From) -> receive - {ok, From} -> - {ok, From}; + {ok, From} = Ok -> + Ok; {no_heart, From} -> ignore; {Error, From} -> @@ -119,8 +119,7 @@ wait() -> start_portprogram() -> check_start_heart(), - HeartCmd = "heart -pid " ++ os:getpid() ++ " " ++ - get_heart_timeouts(), + HeartCmd = "heart -pid " ++ os:getpid() ++ " " ++ get_heart_timeouts(), try open_port({spawn, HeartCmd}, [{packet, 2}]) of Port when is_port(Port) -> case wait_ack(Port) of @@ -175,7 +174,7 @@ wait_ack(Port) -> loop(Parent, Port, Cmd) -> send_heart_beat(Port), receive - {From, set_cmd, NewCmd} when is_list(NewCmd), length(NewCmd) < 2047 -> + {From, set_cmd, NewCmd} when length(NewCmd) < 2047 -> send_heart_cmd(Port, NewCmd), wait_ack(Port), From ! {heart, ok}, diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl index eb503235d8..93d75321ba 100644 --- a/lib/kernel/src/inet.erl +++ b/lib/kernel/src/inet.erl @@ -62,6 +62,8 @@ %% timer interface -export([start_timer/1, timeout/1, timeout/2, stop_timer/1]). +-export_type([ip_address/0, socket/0]). + %% imports -import(lists, [append/1, duplicate/2, filter/2, foldl/3]). 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/inet6_tcp_dist.erl b/lib/kernel/src/inet6_tcp_dist.erl index 34cf582af7..fab00bbb9f 100644 --- a/lib/kernel/src/inet6_tcp_dist.erl +++ b/lib/kernel/src/inet6_tcp_dist.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% %% -module(inet6_tcp_dist). @@ -87,7 +87,7 @@ accept(Listen) -> accept_loop(Kernel, Listen) -> case inet6_tcp:accept(Listen) of {ok, Socket} -> - Kernel ! {accept,self(),Socket,inet,tcp}, + Kernel ! {accept,self(),Socket,inet6,tcp}, controller(Kernel, Socket), accept_loop(Kernel, Listen); Error -> @@ -236,8 +236,8 @@ do_setup(Kernel, Node, Type, MyNode, LongOrShortNames,SetupTime) -> timer = Timer, this_flags = 0, other_version = Version, - f_send = fun inet_tcp:send/2, - f_recv = fun inet_tcp:recv/3, + f_send = fun inet6_tcp:send/2, + f_recv = fun inet6_tcp:recv/3, f_setopts_pre_nodeup = fun(S) -> inet:setopts @@ -262,7 +262,7 @@ do_setup(Kernel, Node, Type, MyNode, LongOrShortNames,SetupTime) -> address = {Ip,TcpPort}, host = Address, protocol = tcp, - family = inet} + family = inet6} end, mf_tick = fun ?MODULE:tick/1, mf_getstat = fun ?MODULE:getstat/1, @@ -302,12 +302,17 @@ splitnode(Node, LongOrShortNames) -> Host = lists:append(Tail), case split_node(Host, $., []) of [_] when LongOrShortNames =:= longnames -> - error_msg("** System running to use " - "fully qualified " - "hostnames **~n" - "** Hostname ~s is illegal **~n", - [Host]), - ?shutdown(Node); + case inet_parse:ipv6strict_address(Host) of + {ok, _} -> + [Name, Host]; + _ -> + error_msg("** System running to use " + "fully qualified " + "hostnames **~n" + "** Hostname ~s is illegal **~n", + [Host]), + ?shutdown(Node) + end; L when length(L) > 1, LongOrShortNames =:= shortnames -> error_msg("** System NOT running to use fully qualified " "hostnames **~n" diff --git a/lib/kernel/src/inet_config.erl b/lib/kernel/src/inet_config.erl index 311e6bc9f9..2458876326 100644 --- a/lib/kernel/src/inet_config.erl +++ b/lib/kernel/src/inet_config.erl @@ -23,6 +23,8 @@ -import(lists, [foreach/2, member/2, reverse/1]). +%% Avoid warning for local function error/2 clashing with autoimported BIF. +-compile({no_auto_import,[error/2]}). -export([init/0]). -export([do_load_resolv/2]). diff --git a/lib/kernel/src/inet_db.erl b/lib/kernel/src/inet_db.erl index a05b380855..d4749b9756 100644 --- a/lib/kernel/src/inet_db.erl +++ b/lib/kernel/src/inet_db.erl @@ -88,6 +88,7 @@ hosts_file_byaddr, %% hosts table from system file cache_timer %% timer reference for refresh }). +-type state() :: #state{}. -include("inet.hrl"). -include("inet_int.hrl"). @@ -101,14 +102,14 @@ start() -> case gen_server:start({local, inet_db}, inet_db, [], []) of - {ok,Pid} -> inet_config:init(), {ok,Pid}; + {ok, _Pid}=Ok -> inet_config:init(), Ok; Error -> Error end. start_link() -> case gen_server:start_link({local, inet_db}, inet_db, [], []) of - {ok,Pid} -> inet_config:init(), {ok,Pid}; + {ok, _Pid}=Ok -> inet_config:init(), Ok; Error -> Error end. @@ -139,7 +140,6 @@ add_hosts(File) -> Error -> Error end. - add_host(IP, Names) -> call({add_host, IP, Names}). del_host(IP) -> call({del_host, IP}). @@ -481,10 +481,7 @@ res_check_option_absfile(F) -> res_check_list([], _Fun) -> true; res_check_list([H|T], Fun) -> - case Fun(H) of - true -> res_check_list(T, Fun); - false -> false - end; + Fun(H) andalso res_check_list(T, Fun); res_check_list(_, _Fun) -> false. res_check_ns({{A,B,C,D,E,F,G,H}, Port}) @@ -496,12 +493,12 @@ res_check_ns(_) -> false. res_check_search("") -> true; res_check_search(Dom) -> inet_parse:visible_string(Dom). -socks_option(server) -> db_get(socks5_server); -socks_option(port) -> db_get(socks5_port); -socks_option(methods) -> db_get(socks5_methods); -socks_option(noproxy) -> db_get(socks5_noproxy). +socks_option(server) -> db_get(socks5_server); +socks_option(port) -> db_get(socks5_port); +socks_option(methods) -> db_get(socks5_methods); +socks_option(noproxy) -> db_get(socks5_noproxy). -gethostname() -> db_get(hostname). +gethostname() -> db_get(hostname). res_update_conf() -> res_update(res_resolv_conf, res_resolv_conf_tm, res_resolv_conf_info, @@ -590,15 +587,13 @@ getbyname(Name, Type) -> getbysearch(Name, Dot, [Dom | Ds], Type, _) -> case hostent_by_domain(Name ++ Dot ++ Dom, Type) of - {ok, HEnt} -> {ok, HEnt}; - Error -> - getbysearch(Name, Dot, Ds, Type, Error) + {ok, _HEnt}=Ok -> Ok; + Error -> getbysearch(Name, Dot, Ds, Type, Error) end; getbysearch(_Name, _Dot, [], _Type, Error) -> Error. - %% %% get_searchlist %% @@ -609,7 +604,6 @@ get_searchlist() -> end. - make_hostent(Name, Addrs, Aliases, ?S_A) -> #hostent { h_name = Name, @@ -844,6 +838,9 @@ lookup_socket(Socket) when is_port(Socket) -> %% node_auth Ls - Default authenication %% node_crypt Ls - Default encryption %% + +-spec init([]) -> {'ok', state()}. + init([]) -> process_flag(trap_exit, true), Db = ets:new(inet_db, [public, named_table]), @@ -897,6 +894,10 @@ reset_db(Db) -> %% {stop, Reason, Reply, State} | (terminate/2 is called) %% {stop, Reason, Reply, State} (terminate/2 is called) %%---------------------------------------------------------------------- + +-spec handle_call(term(), {pid(), term()}, state()) -> + {'reply', term(), state()} | {'stop', 'normal', 'ok', state()}. + handle_call(Request, From, #state{db=Db}=State) -> case Request of {load_hosts_file,IPNmAs} when is_list(IPNmAs) -> @@ -1138,13 +1139,15 @@ handle_call(Request, From, #state{db=Db}=State) -> {reply, error, State} end. - %%---------------------------------------------------------------------- %% Func: handle_cast/2 %% Returns: {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- + +-spec handle_cast(term(), state()) -> {'noreply', state()}. + handle_cast(_Msg, State) -> {noreply, State}. @@ -1154,6 +1157,9 @@ handle_cast(_Msg, State) -> %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- + +-spec handle_info(term(), state()) -> {'noreply', state()}. + handle_info(refresh_timeout, State) -> do_refresh_cache(State#state.cache), {noreply, State#state{cache_timer = init_timer()}}; @@ -1166,6 +1172,9 @@ handle_info(_Info, State) -> %% Purpose: Shutdown the server %% Returns: any (ignored by gen_server) %%---------------------------------------------------------------------- + +-spec terminate(term(), state()) -> 'ok'. + terminate(_Reason, State) -> stop_timer(State#state.cache_timer), ok. @@ -1342,16 +1351,15 @@ do_add_rr(RR, Db, State) -> TM = times(), case alloc_entry(Db, CacheDb, TM) of true -> - cache_rr(Db, CacheDb, RR#dns_rr { tm = TM, - cnt = TM }); + cache_rr(Db, CacheDb, RR#dns_rr{tm = TM, cnt = TM}); _ -> false end. cache_rr(_Db, Cache, RR) -> %% delete possible old entry - ets:match_delete(Cache, RR#dns_rr { cnt = '_', tm = '_', ttl = '_', - bm = '_', func = '_'}), + ets:match_delete(Cache, RR#dns_rr{cnt = '_', tm = '_', ttl = '_', + bm = '_', func = '_'}), ets:insert(Cache, RR). times() -> @@ -1361,9 +1369,9 @@ times() -> %% lookup and remove old entries do_lookup_rr(Domain, Class, Type) -> - match_rr(#dns_rr { domain = tolower(Domain), class = Class,type = Type, - cnt = '_', tm = '_', ttl = '_', - bm = '_', func = '_', data = '_'}). + match_rr(#dns_rr{domain = tolower(Domain), class = Class,type = Type, + cnt = '_', tm = '_', ttl = '_', + bm = '_', func = '_', data = '_'}). match_rr(RR) -> filter_rr(ets:match_object(inet_cache, RR), times()). @@ -1414,7 +1422,7 @@ dn_in_addr_arpa(A,B,C,D) -> integer_to_list(A) ++ ".in-addr.arpa". dnib(X) -> - [ hex(X), $., hex(X bsr 4), $., hex(X bsr 8), $., hex(X bsr 12), $.]. + [hex(X), $., hex(X bsr 4), $., hex(X bsr 8), $., hex(X bsr 12), $.]. hex(X) -> X4 = (X band 16#f), @@ -1509,12 +1517,7 @@ alloc_entry(CacheDb, OldSize, TM, N) -> delete_n_oldest(CacheDb, TM, OldestTM, N) -> DelTM = trunc((TM - OldestTM) * 0.3) + OldestTM, - case delete_older(CacheDb, DelTM, N) of - 0 -> - false; - _ -> - true - end. + delete_older(CacheDb, DelTM, N) =/= 0. %% Delete entries with latest access time older than TM. %% Delete max N number of entries. diff --git a/lib/kernel/src/inet_dns.erl b/lib/kernel/src/inet_dns.erl index 669a361c9d..1289e176c7 100644 --- a/lib/kernel/src/inet_dns.erl +++ b/lib/kernel/src/inet_dns.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% %% -module(inet_dns). @@ -129,27 +129,33 @@ do_decode(<<Id:16, RA:1,PR:1,_:2,Rcode:4, QdCount:16,AnCount:16,NsCount:16,ArCount:16, QdBuf/binary>>=Buffer) -> - {AnBuf,QdList} = decode_query_section(QdBuf,QdCount,Buffer), - {NsBuf,AnList} = decode_rr_section(AnBuf,AnCount,Buffer), - {ArBuf,NsList} = decode_rr_section(NsBuf,NsCount,Buffer), - {Rest,ArList} = decode_rr_section(ArBuf,ArCount,Buffer), + {AnBuf,QdList,QdTC} = decode_query_section(QdBuf,QdCount,Buffer), + {NsBuf,AnList,AnTC} = decode_rr_section(AnBuf,AnCount,Buffer), + {ArBuf,NsList,NsTC} = decode_rr_section(NsBuf,NsCount,Buffer), + {Rest,ArList,ArTC} = decode_rr_section(ArBuf,ArCount,Buffer), case Rest of <<>> -> + HdrTC = decode_boolean(TC), DnsHdr = #dns_header{id=Id, qr=decode_boolean(QR), opcode=decode_opcode(Opcode), aa=decode_boolean(AA), - tc=decode_boolean(TC), + tc=HdrTC, rd=decode_boolean(RD), ra=decode_boolean(RA), pr=decode_boolean(PR), rcode=Rcode}, - #dns_rec{header=DnsHdr, - qdlist=QdList, - anlist=AnList, - nslist=NsList, - arlist=ArList}; + case QdTC or AnTC or NsTC or ArTC of + true when not HdrTC -> + throw(?DECODE_ERROR); + _ -> + #dns_rec{header=DnsHdr, + qdlist=QdList, + anlist=AnList, + nslist=NsList, + arlist=ArList} + end; _ -> %% Garbage data after DNS message throw(?DECODE_ERROR) @@ -161,8 +167,10 @@ do_decode(_) -> decode_query_section(Bin, N, Buffer) -> decode_query_section(Bin, N, Buffer, []). +decode_query_section(<<>>=Rest, N, _Buffer, Qs) -> + {Rest,reverse(Qs),N =/= 0}; decode_query_section(Rest, 0, _Buffer, Qs) -> - {Rest,reverse(Qs)}; + {Rest,reverse(Qs),false}; decode_query_section(Bin, N, Buffer, Qs) -> case decode_name(Bin, Buffer) of {<<Type:16,Class:16,Rest/binary>>,Name} -> @@ -179,8 +187,10 @@ decode_query_section(Bin, N, Buffer, Qs) -> decode_rr_section(Bin, N, Buffer) -> decode_rr_section(Bin, N, Buffer, []). +decode_rr_section(<<>>=Rest, N, _Buffer, RRs) -> + {Rest,reverse(RRs),N =/= 0}; decode_rr_section(Rest, 0, _Buffer, RRs) -> - {Rest,reverse(RRs)}; + {Rest,reverse(RRs),false}; decode_rr_section(Bin, N, Buffer, RRs) -> case decode_name(Bin, Buffer) of {<<T:16/unsigned,C:16/unsigned,TTL:4/binary, diff --git a/lib/kernel/src/inet_gethost_native.erl b/lib/kernel/src/inet_gethost_native.erl index fabe9bf8b3..db3e44ce6f 100644 --- a/lib/kernel/src/inet_gethost_native.erl +++ b/lib/kernel/src/inet_gethost_native.erl @@ -106,8 +106,11 @@ pool_size = 4, % Number of C processes in pool. statistics % Statistics record (records error causes). }). +-type state() :: #state{}. %% The supervisor bridge code +-spec init([]) -> {'ok', pid(), pid()} | {'error', term()}. + init([]) -> % Called by supervisor_bridge:start_link Ref = make_ref(), SaveTE = process_flag(trap_exit,true), @@ -151,11 +154,13 @@ run_once() -> {Port, {data, <<1:32, BinReply/binary>>}} -> Pid ! {R, {ok, BinReply}} after Timeout -> - Pid ! {R,{error,timeout}} + Pid ! {R, {error, timeout}} end. -terminate(_Reason,Pid) -> - (catch exit(Pid,kill)), +-spec terminate(term(), pid()) -> 'ok'. + +terminate(_Reason, Pid) -> + (catch exit(Pid, kill)), ok. %%----------------------------------------------------------------------- @@ -337,14 +342,14 @@ pick_client(State,RID,Clid) -> {last, SoleClient}; % Note, not removed, the caller % should cleanup request data CList -> - case lists:keysearch(Clid,1,CList) of - {value, Client} -> + case lists:keyfind(Clid,1,CList) of + false -> + false; + Client -> NCList = lists:keydelete(Clid,1,CList), ets:insert(State#state.requests, R#request{clients = NCList}), - {more, Client}; - false -> - false + {more, Client} end end end. @@ -382,8 +387,7 @@ restart_port(#state{port = Port, requests = Requests}) -> end, Requests), NewPort. - - + do_open_port(Poolsize, ExtraArgs) -> try @@ -431,6 +435,7 @@ system_continue(_Parent, _, State) -> system_terminate(Reason, _Parent, _, _State) -> exit(Reason). +-spec system_code_change(state(), module(), term(), term()) -> {'ok', state()}. system_code_change(State, _Module, _OldVsn, _Extra) -> {ok, State}. %% Nothing to do in this version. diff --git a/lib/kernel/src/inet_parse.erl b/lib/kernel/src/inet_parse.erl index 3bd5fa0958..65edddcb46 100644 --- a/lib/kernel/src/inet_parse.erl +++ b/lib/kernel/src/inet_parse.erl @@ -20,6 +20,8 @@ %% Parser for all kinds of ineternet configuration files +%% Avoid warning for local function error/2 clashing with autoimported BIF. +-compile({no_auto_import,[error/2]}). -export([hosts/1, hosts/2]). -export([hosts_vxworks/1]). -export([protocols/1, protocols/2]). diff --git a/lib/kernel/src/inet_res.erl b/lib/kernel/src/inet_res.erl index 9b9e078898..de0f23bf24 100644 --- a/lib/kernel/src/inet_res.erl +++ b/lib/kernel/src/inet_res.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% %% %% RFC 1035, 2671, 2782, 2915. @@ -592,6 +592,7 @@ query_retries(_Q, _NSs, _Timer, Retry, Retry, S) -> query_retries(Q, NSs, Timer, Retry, I, S0) -> Num = length(NSs), if Num =:= 0 -> + udp_close(S0), {error,timeout}; true -> case query_nss(Q, NSs, Timer, Retry, I, S0, []) of 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/kernel_config.erl b/lib/kernel/src/kernel_config.erl index e5e9a0498d..b1daf655c9 100644 --- a/lib/kernel/src/kernel_config.erl +++ b/lib/kernel/src/kernel_config.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(kernel_config). @@ -40,6 +40,9 @@ start_link() -> gen_server:start_link(kernel_config, [], []). %%----------------------------------------------------------------- %% Callback functions from gen_server %%----------------------------------------------------------------- + +-spec init([]) -> {'ok', []} | {'stop', term()}. + init([]) -> process_flag(trap_exit, true), case sync_nodes() of @@ -59,18 +62,28 @@ init([]) -> {stop, Error} end. +-spec handle_info(term(), State) -> {'noreply', State}. + handle_info(_, State) -> {noreply, State}. +-spec terminate(term(), term()) -> 'ok'. + terminate(_Reason, _State) -> ok. +-spec handle_call(term(), term(), State) -> {'reply', 'ok', State}. + handle_call('__not_used', _From, State) -> {reply, ok, State}. +-spec handle_cast(term(), State) -> {'noreply', State}. + handle_cast('__not_used', State) -> {noreply, State}. +-spec code_change(term(), State, term()) -> {'ok', State}. + code_change(_OldVsn, State, _Extra) -> {ok, State}. @@ -79,9 +92,9 @@ code_change(_OldVsn, State, _Extra) -> %%----------------------------------------------------------------- sync_nodes() -> case catch get_sync_data() of - {error, Reason} -> + {error, Reason} = Error -> error_logger:format("~p", [Reason]), - {error, Reason}; + Error; {infinity, MandatoryNodes, OptionalNodes} -> case wait_nodes(MandatoryNodes, OptionalNodes) of ok -> diff --git a/lib/kernel/src/net_kernel.erl b/lib/kernel/src/net_kernel.erl index 9875044844..f5e2820bbe 100644 --- a/lib/kernel/src/net_kernel.erl +++ b/lib/kernel/src/net_kernel.erl @@ -72,7 +72,7 @@ -export([publish_on_node/1, update_publish_nodes/1]). -%% Internal Exports +%% Internal Exports -export([do_spawn/3, spawn_func/6, ticker/2, @@ -94,7 +94,7 @@ connecttime, %% the connection setuptime. connections, %% table of connections conn_owners = [], %% List of connection owner pids, - pend_owners = [], %% List of potential owners + pend_owners = [], %% List of potential owners listen, %% list of #listen allowed, %% list of allowed nodes in a restricted system verbose = 0, %% level of verboseness @@ -232,7 +232,7 @@ do_connect(Node, Type, WaitForBarred) -> %% Type = normal | hidden %% "connected from other end.~n",[Node]), true; {Pid, false} -> - ?connect_failure(Node,{barred_connection, + ?connect_failure(Node,{barred_connection, ets:lookup(sys_dist, Node)}), %%io:format("Net Kernel: barred connection (~p) " %% "- failure.~n",[Node]), @@ -244,12 +244,12 @@ do_connect(Node, Type, WaitForBarred) -> %% Type = normal | hidden {ok, never} -> ?connect_failure(Node,{dist_auto_connect,never}), false; - % This might happen due to connection close + % This might happen due to connection close % not beeing propagated to user space yet. - % Save the day by just not connecting... + % Save the day by just not connecting... {ok, once} when Else =/= [], (hd(Else))#connection.state =:= up -> - ?connect_failure(Node,{barred_connection, + ?connect_failure(Node,{barred_connection, ets:lookup(sys_dist, Node)}), false; _ -> @@ -276,8 +276,8 @@ passive_connect_monitor(Parent, Node) -> Parent ! {self(),true} end end. - -%% If the net_kernel isn't running we ignore all requests to the + +%% If the net_kernel isn't running we ignore all requests to the %% kernel, thus basically accepting them :-) request(Req) -> case whereis(net_kernel) of @@ -302,7 +302,7 @@ start_link([Name, LongOrShortNames]) -> start_link([Name, LongOrShortNames, 15000]); start_link([Name, LongOrShortNames, Ticktime]) -> - case gen_server:start_link({local, net_kernel}, net_kernel, + case gen_server:start_link({local, net_kernel}, net_kernel, {Name, LongOrShortNames, Ticktime}, []) of {ok, Pid} -> {ok, Pid}; @@ -313,7 +313,7 @@ start_link([Name, LongOrShortNames, Ticktime]) -> end. %% auth:get_cookie should only be able to return an atom -%% tuple cookies are unknowns +%% tuple cookies are unknowns init({Name, LongOrShortNames, TickT}) -> process_flag(trap_exit,true), @@ -390,27 +390,27 @@ handle_call({disconnect, Node}, From, State) -> {Reply, State1} = do_disconnect(Node, State), async_reply({reply, Reply, State1}, From); -%% +%% %% The spawn/4 BIF ends up here. -%% +%% handle_call({spawn,M,F,A,Gleader},{From,Tag},State) when is_pid(From) -> do_spawn([no_link,{From,Tag},M,F,A,Gleader],[],State); -%% +%% %% The spawn_link/4 BIF ends up here. -%% +%% handle_call({spawn_link,M,F,A,Gleader},{From,Tag},State) when is_pid(From) -> do_spawn([link,{From,Tag},M,F,A,Gleader],[],State); -%% +%% %% The spawn_opt/5 BIF ends up here. -%% +%% handle_call({spawn_opt,M,F,A,O,L,Gleader},{From,Tag},State) when is_pid(From) -> do_spawn([L,{From,Tag},M,F,A,Gleader],O,State); -%% +%% %% Only allow certain nodes. -%% +%% handle_call({allow, Nodes}, From, State) -> case all_atoms(Nodes) of true -> @@ -421,17 +421,17 @@ handle_call({allow, Nodes}, From, State) -> async_reply({reply,error,State}, From) end; -%% +%% %% authentication, used by auth. Simply works as this: %% if the message comes through, the other node IS authorized. -%% +%% handle_call({is_auth, _Node}, From, State) -> async_reply({reply,yes,State}, From); -%% +%% %% Not applicable any longer !? -%% -handle_call({apply,_Mod,_Fun,_Args}, {From,Tag}, State) +%% +handle_call({apply,_Mod,_Fun,_Args}, {From,Tag}, State) when is_pid(From), node(From) =:= node() -> async_gen_server_reply({From,Tag}, not_implemented), % Port = State#state.port, @@ -503,7 +503,10 @@ handle_call({new_ticktime,T,TP}, From, #state{tick = #tick{ticker = Tckr, handle_call({new_ticktime,_T,_TP}, From, #state{tick = #tick_change{time = T}} = State) -> - async_reply({reply, {ongoing_change_to, T}, State}, From). + async_reply({reply, {ongoing_change_to, T}, State}, From); + +handle_call(_Msg, _From, State) -> + {noreply, State}. %% ------------------------------------------------------------ %% handle_cast. @@ -571,7 +574,7 @@ handle_info({accept,AcceptPid,Socket,Family,Proto}, State) -> %% %% A node has successfully been connected. %% -handle_info({SetupPid, {nodeup,Node,Address,Type,Immediate}}, +handle_info({SetupPid, {nodeup,Node,Address,Type,Immediate}}, State) -> case {Immediate, ets:lookup(sys_dist, Node)} of {true, [Conn]} when Conn#connection.state =:= pending, @@ -659,7 +662,7 @@ handle_info({From,registered_send,To,Mess},State) -> send(From,To,Mess), {noreply,State}; -%% badcookies SHOULD not be sent +%% badcookies SHOULD not be sent %% (if someone does erlang:set_cookie(node(),foo) this may be) handle_info({From,badcookie,_To,_Mess}, State) -> error_logger:error_msg("~n** Got OLD cookie from ~w~n", @@ -707,7 +710,7 @@ handle_info(X, State) -> %% 4. The ticker process. %% (5. Garbage pid.) %% -%% The process type function that handled the process throws +%% The process type function that handled the process throws %% the handle_info return value ! %% ----------------------------------------------------------- @@ -997,9 +1000,9 @@ ticker(Kernel, Tick) when is_integer(Tick) -> ticker_loop(Kernel, Tick). to_integer(T) when is_integer(T) -> T; -to_integer(T) when is_atom(T) -> +to_integer(T) when is_atom(T) -> list_to_integer(atom_to_list(T)); -to_integer(T) when is_list(T) -> +to_integer(T) when is_list(T) -> list_to_integer(T). ticker_loop(Kernel, Tick) -> @@ -1007,7 +1010,7 @@ ticker_loop(Kernel, Tick) -> {new_ticktime, NewTick} -> ?tckr_dbg({ticker_changed_time, Tick, NewTick}), ?MODULE:ticker_loop(Kernel, NewTick) - after Tick -> + after Tick -> Kernel ! tick, ?MODULE:ticker_loop(Kernel, Tick) end. @@ -1055,7 +1058,7 @@ send(_From,To,Mess) -> -ifdef(UNUSED). safesend(Name,Mess) when is_atom(Name) -> - case whereis(Name) of + case whereis(Name) of undefined -> Mess; P when is_pid(P) -> @@ -1149,7 +1152,7 @@ get_proto_mod(Family,Protocol,[L|Ls]) -> true -> get_proto_mod(Family,Protocol,Ls) end; -get_proto_mod(_Family, _Protocol, []) -> +get_proto_mod(_Family, _Protocol, []) -> error. %% -------- Initialisation functions ------------------------ @@ -1160,9 +1163,9 @@ init_node(Name, LongOrShortNames) -> case create_name(Name, LongOrShortNames, 1) of {ok,Node} -> case start_protos(list_to_atom(NameWithoutHost),Node) of - {ok, Ls} -> + {ok, Ls} -> {ok, Node, Ls}; - Error -> + Error -> Error end; Error -> @@ -1171,9 +1174,9 @@ init_node(Name, LongOrShortNames) -> %% Create the node name create_name(Name, LongOrShortNames, Try) -> - put(longnames, case LongOrShortNames of - shortnames -> false; - longnames -> true + put(longnames, case LongOrShortNames of + shortnames -> false; + longnames -> true end), {Head,Host1} = create_hostpart(Name, LongOrShortNames), case Host1 of @@ -1222,7 +1225,7 @@ create_hostpart(Name, LongOrShortNames) -> {Head,Host1}. %% -%% +%% %% protocol_childspecs() -> case init:get_argument(proto_dist) of @@ -1232,7 +1235,7 @@ protocol_childspecs() -> protocol_childspecs(["inet_tcp"]) end. -protocol_childspecs([]) -> +protocol_childspecs([]) -> []; protocol_childspecs([H|T]) -> Mod = list_to_atom(H ++ "_dist"), @@ -1242,15 +1245,15 @@ protocol_childspecs([H|T]) -> _ -> protocol_childspecs(T) end. - - + + %% %% epmd_module() -> module_name of erl_epmd or similar gen_server_module. %% epmd_module() -> case init:get_argument(epmd_module) of - {ok,[[Module]]} -> + {ok,[[Module]]} -> Module; _ -> erl_epmd @@ -1297,7 +1300,7 @@ start_protos(Name, [Proto | Ps], Node, Ls) -> error_logger:info_msg("Protocol: ~p: not supported~n", [Proto]), start_protos(Name,Ps, Node, Ls); {'EXIT', Reason} -> - error_logger:info_msg("Protocol: ~p: register error: ~p~n", + error_logger:info_msg("Protocol: ~p: register error: ~p~n", [Proto, Reason]), start_protos(Name,Ps, Node, Ls); {error, duplicate_name} -> @@ -1307,7 +1310,7 @@ start_protos(Name, [Proto | Ps], Node, Ls) -> [Proto]), start_protos(Name,Ps, Node, Ls); {error, Reason} -> - error_logger:info_msg("Protocol: ~p: register/listen error: ~p~n", + error_logger:info_msg("Protocol: ~p: register/listen error: ~p~n", [Proto, Reason]), start_protos(Name,Ps, Node, Ls) end; @@ -1459,7 +1462,7 @@ display_info({Node, Info}, {I,O}) -> integer_to_list(In), integer_to_list(Out), Address), {I+In,O+Out}. -fmt_address(undefined) -> +fmt_address(undefined) -> "-"; fmt_address(A) -> case A#net_address.family of diff --git a/lib/kernel/src/os.erl b/lib/kernel/src/os.erl index d0b498edc9..75a11a8afd 100644 --- a/lib/kernel/src/os.erl +++ b/lib/kernel/src/os.erl @@ -50,7 +50,7 @@ find_executable(Name, Path) -> relative -> find_executable1(Name, split_path(Path), Extensions); _ -> - case verify_executable(Name, Extensions) of + case verify_executable(Name, Extensions, Extensions) of {ok, Complete} -> Complete; error -> @@ -60,7 +60,7 @@ find_executable(Name, Path) -> find_executable1(Name, [Base|Rest], Extensions) -> Complete0 = filename:join(Base, Name), - case verify_executable(Complete0, Extensions) of + case verify_executable(Complete0, Extensions, Extensions) of {ok, Complete} -> Complete; error -> @@ -69,7 +69,7 @@ find_executable1(Name, [Base|Rest], Extensions) -> find_executable1(_Name, [], _Extensions) -> false. -verify_executable(Name0, [Ext|Rest]) -> +verify_executable(Name0, [Ext|Rest], OrigExtensions) -> Name1 = Name0 ++ Ext, case os:type() of vxworks -> @@ -78,7 +78,7 @@ verify_executable(Name0, [Ext|Rest]) -> {ok, _} -> {ok, Name1}; _ -> - verify_executable(Name0, Rest) + verify_executable(Name0, Rest, OrigExtensions) end; _ -> case file:read_file_info(Name1) of @@ -87,12 +87,30 @@ verify_executable(Name0, [Ext|Rest]) -> %% on Unix, since we test if any execution bit is set. {ok, Name1}; _ -> - verify_executable(Name0, Rest) + verify_executable(Name0, Rest, OrigExtensions) end end; -verify_executable(_, []) -> +verify_executable(Name, [], OrigExtensions) when OrigExtensions =/= [""] -> %% Windows + %% Will only happen on windows, hence case insensitivity + case can_be_full_name(string:to_lower(Name),OrigExtensions) of + true -> + verify_executable(Name,[""],[""]); + _ -> + error + end; +verify_executable(_, [], _) -> error. +can_be_full_name(_Name,[]) -> + false; +can_be_full_name(Name,[H|T]) -> + case lists:suffix(H,Name) of %% Name is in lowercase, cause this is a windows thing + true -> + true; + _ -> + can_be_full_name(Name,T) + end. + split_path(Path) -> case type() of {win32, _} -> @@ -119,6 +137,7 @@ reverse_element(List) -> lists:reverse(List). -spec extensions() -> [string()]. +%% Extensions in lower case extensions() -> case type() of {win32, _} -> [".exe",".com",".cmd",".bat"]; diff --git a/lib/kernel/src/pg2.erl b/lib/kernel/src/pg2.erl index cb9fec2ffe..956a900adc 100644 --- a/lib/kernel/src/pg2.erl +++ b/lib/kernel/src/pg2.erl @@ -251,7 +251,9 @@ terminate(_Reason, _S) -> %%% Pid is a member of group Name. store(List) -> - _ = [assure_group(Name) andalso [join_group(Name, P) || P <- Members] || + _ = [(assure_group(Name) + andalso + [join_group(Name, P) || P <- Members -- group_members(Name)]) || [Name, Members] <- List], ok. diff --git a/lib/kernel/src/ram_file.erl b/lib/kernel/src/ram_file.erl index d996650948..48ea871433 100644 --- a/lib/kernel/src/ram_file.erl +++ b/lib/kernel/src/ram_file.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% %% -module(ram_file). @@ -24,11 +24,11 @@ -export([open/2, close/1]). -export([write/2, read/2, copy/3, pread/2, pread/3, pwrite/2, pwrite/3, - position/2, truncate/1, sync/1]). + position/2, truncate/1, datasync/1, sync/1]). %% Specialized file operations -export([get_size/1, get_file/1, set_file/2, get_file_close/1]). --export([compress/1, uncompress/1, uuencode/1, uudecode/1]). +-export([compress/1, uncompress/1, uuencode/1, uudecode/1, advise/4]). -export([open_mode/1]). %% used by ftp-file @@ -60,6 +60,7 @@ -define(RAM_FILE_TRUNCATE, 14). -define(RAM_FILE_PREAD, 17). -define(RAM_FILE_PWRITE, 18). +-define(RAM_FILE_FDATASYNC, 19). %% Other operations -define(RAM_FILE_GET, 30). @@ -70,6 +71,7 @@ -define(RAM_FILE_UUENCODE, 35). -define(RAM_FILE_UUDECODE, 36). -define(RAM_FILE_SIZE, 37). +-define(RAM_FILE_ADVISE, 38). %% Open modes for RAM_FILE_OPEN -define(RAM_FILE_MODE_READ, 1). @@ -90,6 +92,14 @@ -define(RAM_FILE_RESP_NUMBER, 3). -define(RAM_FILE_RESP_INFO, 4). +%% POSIX file advises +-define(POSIX_FADV_NORMAL, 0). +-define(POSIX_FADV_RANDOM, 1). +-define(POSIX_FADV_SEQUENTIAL, 2). +-define(POSIX_FADV_WILLNEED, 3). +-define(POSIX_FADV_DONTNEED, 4). +-define(POSIX_FADV_NOREUSE, 5). + %% -------------------------------------------------------------------------- %% Generic file contents operations. %% @@ -167,6 +177,8 @@ copy(#file_descriptor{module = ?MODULE} = Source, %% XXX Should be moved down to the driver for optimization. file:copy_opened(Source, Dest, Length). +datasync(#file_descriptor{module = ?MODULE, data = Port}) -> + call_port(Port, <<?RAM_FILE_FDATASYNC>>). sync(#file_descriptor{module = ?MODULE, data = Port}) -> call_port(Port, <<?RAM_FILE_FSYNC>>). @@ -349,6 +361,28 @@ uudecode(#file_descriptor{module = ?MODULE, data = Port}) -> uudecode(#file_descriptor{}) -> {error, enotsup}. +advise(#file_descriptor{module = ?MODULE, data = Port}, Offset, + Length, Advise) -> + Cmd0 = <<?RAM_FILE_ADVISE, Offset:64/signed, Length:64/signed>>, + case Advise of + normal -> + call_port(Port, <<Cmd0/binary, ?POSIX_FADV_NORMAL:32/signed>>); + random -> + call_port(Port, <<Cmd0/binary, ?POSIX_FADV_RANDOM:32/signed>>); + sequential -> + call_port(Port, <<Cmd0/binary, ?POSIX_FADV_SEQUENTIAL:32/signed>>); + will_need -> + call_port(Port, <<Cmd0/binary, ?POSIX_FADV_WILLNEED:32/signed>>); + dont_need -> + call_port(Port, <<Cmd0/binary, ?POSIX_FADV_DONTNEED:32/signed>>); + no_reuse -> + call_port(Port, <<Cmd0/binary, ?POSIX_FADV_NOREUSE:32/signed>>); + _ -> + {error, einval} + end; +advise(#file_descriptor{}, _Offset, _Length, _Advise) -> + {error, enotsup}. + %%%----------------------------------------------------------------- diff --git a/lib/kernel/src/rpc.erl b/lib/kernel/src/rpc.erl index d69f2a12ad..e09acb5024 100644 --- a/lib/kernel/src/rpc.erl +++ b/lib/kernel/src/rpc.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(rpc). @@ -56,7 +56,7 @@ -export([safe_multi_server_call/2,safe_multi_server_call/3]). %% gen_server exports --export([init/1,handle_call/3,handle_cast/2,handle_info/2, +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). %% Internals @@ -64,13 +64,23 @@ %%------------------------------------------------------------------------ +-type state() :: gb_tree(). + +%%------------------------------------------------------------------------ + %% Remote execution and broadcasting facility +-spec start() -> {'ok', pid()} | 'ignore' | {'error', term()}. + start() -> - gen_server:start({local,?NAME},?MODULE,[],[]). + gen_server:start({local,?NAME}, ?MODULE, [], []). + +-spec start_link() -> {'ok', pid()} | 'ignore' | {'error', term()}. start_link() -> - gen_server:start_link({local,?NAME},?MODULE,[],[]). + gen_server:start_link({local,?NAME}, ?MODULE, [], []). + +-spec stop() -> term(). stop() -> stop(?NAME). @@ -78,11 +88,17 @@ stop() -> stop(Rpc) -> gen_server:call(Rpc, stop, infinity). --spec init([]) -> {'ok', gb_tree()}. +-spec init([]) -> {'ok', state()}. + init([]) -> process_flag(trap_exit, true), {ok, gb_trees:empty()}. +-spec handle_call(term(), term(), state()) -> + {'noreply', state()} | + {'reply', term(), state()} | + {'stop', 'normal', 'stopped', state()}. + handle_call({call, Mod, Fun, Args, Gleader}, To, S) -> handle_call_call(Mod, Fun, Args, Gleader, To, S); handle_call({block_call, Mod, Fun, Args, Gleader}, _To, S) -> @@ -102,17 +118,18 @@ handle_call(stop, _To, S) -> handle_call(_, _To, S) -> {noreply, S}. % Ignore ! +-spec handle_cast(term(), state()) -> {'noreply', state()}. handle_cast({cast, Mod, Fun, Args, Gleader}, S) -> - spawn( - fun() -> - set_group_leader(Gleader), - apply(Mod, Fun, Args) - end), - {noreply, S}; + spawn(fun() -> + set_group_leader(Gleader), + apply(Mod, Fun, Args) + end), + {noreply, S}; handle_cast(_, S) -> {noreply, S}. % Ignore ! +-spec handle_info(term(), state()) -> {'noreply', state()}. handle_info({'DOWN', _, process, Caller, Reason}, S) -> case gb_trees:lookup(Caller, S) of @@ -145,7 +162,7 @@ handle_info({From, {sbcast, Name, Msg}}, S) -> _ -> From ! {?NAME, node(), node()} end, - {noreply,S}; + {noreply, S}; handle_info({From, {send, Name, Msg}}, S) -> case catch Name ! {From, Msg} of %% use catch to get the printout {'EXIT', _} -> @@ -153,16 +170,20 @@ handle_info({From, {send, Name, Msg}}, S) -> _ -> ok %% It's up to Name to respond !!!!! end, - {noreply,S}; + {noreply, S}; handle_info({From, {call,Mod,Fun,Args,Gleader}}, S) -> %% Special for hidden C node's, uugh ... handle_call_call(Mod, Fun, Args, Gleader, {From,?NAME}, S); handle_info(_, S) -> - {noreply,S}. + {noreply, S}. + +-spec terminate(term(), state()) -> 'ok'. terminate(_, _S) -> ok. +-spec code_change(term(), state(), term()) -> {'ok', state()}. + code_change(_, S, _) -> {ok, S}. @@ -209,7 +230,7 @@ proxy_user() -> case whereis(rex_proxy_user) of Pid when is_pid(Pid) -> Pid; undefined -> - Pid = spawn(fun()-> proxy_user_loop() end), + Pid = spawn(fun() -> proxy_user_loop() end), try register(rex_proxy_user,Pid) of true -> Pid catch error:_ -> % spawn race, kill and try again @@ -226,6 +247,8 @@ proxy_user_loop() -> undefined -> proxy_user_loop() end. +-spec proxy_user_flush() -> no_return(). + proxy_user_flush() -> %% Forward all received messages to 'user' receive Msg -> diff --git a/lib/kernel/src/standard_error.erl b/lib/kernel/src/standard_error.erl index 73901d9896..e41dcd01fc 100644 --- a/lib/kernel/src/standard_error.erl +++ b/lib/kernel/src/standard_error.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009. All Rights Reserved. -%% +%% +%% 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% %% -module(standard_error). @@ -24,8 +24,6 @@ -define(NAME, standard_error). -define(PROCNAME_SUP, standard_error_sup). -%% Internal exports --export([server/1, server/2]). %% Defines for control ops -define(CTRL_OP_GET_WINSIZE,100). @@ -33,13 +31,19 @@ %% %% The basic server and start-up. %% +-spec start_link() -> 'ignore' | {'error',term()} | {'ok',pid()}. + start_link() -> supervisor_bridge:start_link({local, ?PROCNAME_SUP}, ?MODULE, []). +-spec terminate(term(), pid()) -> 'ok'. + terminate(_Reason,Pid) -> (catch exit(Pid,kill)), ok. +-spec init([]) -> {'error','no_stderror'} | {'ok',pid(),pid()}. + init([]) -> case (catch start_port([out,binary])) of Pid when is_pid(Pid) -> @@ -48,18 +52,11 @@ init([]) -> {error,no_stderror} end. - start_port(PortSettings) -> - Id = spawn(?MODULE,server,[{fd,2,2},PortSettings]), - register(?NAME,Id), + Id = spawn(fun () -> server({fd,2,2}, PortSettings) end), + register(?NAME, Id), Id. - -server(Pid) when is_pid(Pid) -> - process_flag(trap_exit, true), - link(Pid), - run(Pid). - server(PortName,PortSettings) -> process_flag(trap_exit, true), Port = open_port(PortName,PortSettings), @@ -82,17 +79,15 @@ server_loop(Port) -> server_loop(Port) end. - get_fd_geometry(Port) -> case (catch port_control(Port,?CTRL_OP_GET_WINSIZE,[])) of - List when is_list(List), length(List) =:= 8 -> + List when length(List) =:= 8 -> <<W:32/native,H:32/native>> = list_to_binary(List), {W,H}; _ -> error end. - %% NewSaveBuffer = io_request(Request, FromPid, ReplyAs, Port, SaveBuffer) do_io_request(Req, From, ReplyAs, Port) -> @@ -221,12 +216,7 @@ do_setopts(Opts, _Port) -> {ok,ok}. getopts(_Port) -> - Uni = {unicode, case get(unicode) of - true -> - true; - _ -> - false - end}, + Uni = {unicode, get(unicode) =:= true}, {ok,[Uni]}. wrap_characters_to_binary(Chars,From,To) -> diff --git a/lib/kernel/src/user.erl b/lib/kernel/src/user.erl index 17dc5a56a2..88f32df20b 100644 --- a/lib/kernel/src/user.erl +++ b/lib/kernel/src/user.erl @@ -26,9 +26,6 @@ -define(NAME, user). -%% Internal exports --export([server/1, server/2]). - %% Defines for control ops -define(CTRL_OP_GET_WINSIZE,100). @@ -43,7 +40,7 @@ start([Mod,Fun|Args]) -> %% Mod,Fun,Args should return a pid. That process is supposed to act %% as the io port. Pid = apply(Mod, Fun, Args), % This better work! - Id = spawn(?MODULE, server, [Pid]), + Id = spawn(fun() -> server(Pid) end), register(?NAME, Id), Id. @@ -52,8 +49,8 @@ start_out() -> start_port([out,binary]). start_port(PortSettings) -> - Id = spawn(?MODULE,server,[{fd,0,1},PortSettings]), - register(?NAME,Id), + Id = spawn(fun() -> server({fd,0,1}, PortSettings) end), + register(?NAME, Id), Id. %% Return the pid of the shell process. @@ -72,7 +69,6 @@ interfaces(User) -> [] end. - server(Pid) when is_pid(Pid) -> process_flag(trap_exit, true), link(Pid), @@ -104,7 +100,7 @@ catch_loop(Port, Shell, Q) -> new_shell -> exit(Shell, kill), catch_loop(Port, start_new_shell()); - {unknown_exit,{Shell,Reason},_} -> % shell has exited + {unknown_exit,{Shell,Reason},_} -> % shell has exited case Reason of normal -> put_chars("*** ", Port, []); @@ -172,7 +168,7 @@ server_loop(Port, Q) -> get_fd_geometry(Port) -> case (catch port_control(Port,?CTRL_OP_GET_WINSIZE,[])) of - List when is_list(List), length(List) =:= 8 -> + List when length(List) =:= 8 -> <<W:32/native,H:32/native>> = list_to_binary(List), {W,H}; _ -> @@ -373,12 +369,7 @@ do_setopts(Opts, _Port, Q) -> end. getopts(_Port,Q) -> - Bin = {binary, case get(read_mode) of - binary -> - true; - _ -> - false - end}, + Bin = {binary, get(read_mode) =:= binary}, Uni = {encoding, case get(unicode) of true -> unicode; diff --git a/lib/kernel/src/wrap_log_reader.erl b/lib/kernel/src/wrap_log_reader.erl index 5030d3aed5..fabaa07752 100644 --- a/lib/kernel/src/wrap_log_reader.erl +++ b/lib/kernel/src/wrap_log_reader.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1998-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% %% @@ -37,7 +37,7 @@ cont :: dlog_cont(), % disk_log's continuation record file :: file:filename(), % file name without extension file_no :: non_neg_integer(), % current file number - mod_time :: date_time(), % modification time of current file + mod_time :: file:date_time(), % modification time of current file first_no :: non_neg_integer() | 'one' % first read file number }). diff --git a/lib/kernel/test/code_SUITE.erl b/lib/kernel/test/code_SUITE.erl index 37b9200942..c9437df258 100644 --- a/lib/kernel/test/code_SUITE.erl +++ b/lib/kernel/test/code_SUITE.erl @@ -31,7 +31,7 @@ where_is_file_cached/1, where_is_file_no_cache/1, purge_stacktrace/1, mult_lib_roots/1, bad_erl_libs/1, code_archive/1, code_archive2/1, on_load/1, - on_load_embedded/1, on_load_errors/1]). + on_load_embedded/1, on_load_errors/1, native_early_modules/1]). -export([init_per_testcase/2, fin_per_testcase/2, init_per_suite/1, end_per_suite/1, @@ -53,7 +53,7 @@ all(suite) -> where_is_file_no_cache, where_is_file_cached, purge_stacktrace, mult_lib_roots, bad_erl_libs, code_archive, code_archive2, on_load, on_load_embedded, - on_load_errors]. + on_load_errors, native_early_modules]. init_per_suite(Config) -> %% The compiler will no longer create a Beam file if @@ -543,8 +543,8 @@ add_del_path(Config) when is_list(Config) -> ?line code:del_path(Dir2), ?line PrivDir1 = code:priv_dir(dummy_app), ok. - - + + clash(Config) when is_list(Config) -> DDir = ?config(data_dir,Config)++"clash/", P = code:get_path(), @@ -555,11 +555,11 @@ clash(Config) when is_list(Config) -> ?line true = code:del_path("."), ?line true = code:add_path(DDir++"foobar-0.1/ebin"), ?line true = code:add_path(DDir++"zork-0.8/ebin"), - ?line test_server:capture_start(), - ?line code:clash(), - ?line test_server:capture_stop(), - ?line OKMsg = test_server:capture_get(), - ?line lists:prefix("** Found 0 name clashes in code paths", OKMsg), + test_server:capture_start(), + ?line ok = code:clash(), + test_server:capture_stop(), + ?line [OKMsg|_] = test_server:capture_get(), + ?line true = lists:prefix("** Found 0 name clashes", OKMsg), ?line true = code:set_path(P), %% test clashing entries @@ -568,13 +568,29 @@ clash(Config) when is_list(Config) -> ?line true = code:del_path("."), ?line true = code:add_path(DDir++"foobar-0.1/ebin"), ?line true = code:add_path(DDir++"foobar-0.1.ez/foobar-0.1/ebin"), - ?line test_server:capture_start(), - ?line code:clash(), - ?line test_server:capture_stop(), - ?line [ErrMsg1|_] = test_server:capture_get(), - ?line {match, [" hides "]} = re:run(ErrMsg1, "\\*\\* .*( hides ).*", + test_server:capture_start(), + ?line ok = code:clash(), + test_server:capture_stop(), + ?line [ClashMsg|_] = test_server:capture_get(), + ?line {match, [" hides "]} = re:run(ClashMsg, "\\*\\* .*( hides ).*", [{capture,all_but_first,list}]), ?line true = code:set_path(P), + + %% test "Bad path can't read" + + %% remove "." to prevent clash with test-server path + Priv = ?config(priv_dir, Config), + ?line true = code:del_path("."), + TmpEzFile = Priv++"foobar-0.tmp.ez", + ?line {ok, _} = file:copy(DDir++"foobar-0.1.ez", TmpEzFile), + ?line true = code:add_path(TmpEzFile++"/foobar-0.1/ebin"), + ?line ok = file:delete(TmpEzFile), + test_server:capture_start(), + ?line ok = code:clash(), + test_server:capture_stop(), + ?line [BadPathMsg|_] = test_server:capture_get(), + ?line true = lists:prefix("** Bad path can't read", BadPathMsg), + ?line true = code:set_path(P), ok. ext_mod_dep(suite) -> @@ -1317,6 +1333,34 @@ do_on_load_error(ReturnValue) -> ?line {undef,[{on_load_error,main,[]}|_]} = Exit end. +native_early_modules(suite) -> []; +native_early_modules(doc) -> ["Test that the native code of early loaded modules is loaded"]; +native_early_modules(Config) when is_list(Config) -> + case erlang:system_info(hipe_architecture) of + undefined -> + {skip,"Native code support is not enabled"}; + Architecture -> + native_early_modules_1(Architecture) + end. + +native_early_modules_1(Architecture) -> + ?line {lists, ListsBinary, _ListsFilename} = code:get_object_code(lists), + ?line ChunkName = hipe_unified_loader:chunk_name(Architecture), + ?line NativeChunk = beam_lib:chunks(ListsBinary, [ChunkName]), + ?line IsHipeCompiled = case NativeChunk of + {ok,{_,[{_,Bin}]}} when is_binary(Bin) -> true; + {error, beam_lib, _} -> false + end, + case IsHipeCompiled of + false -> + {skip,"OTP apparently not configured with --enable-native-libs"}; + true -> + ?line true = lists:all(fun code:is_module_native/1, + [ets,file,filename,gb_sets,gb_trees, + hipe_unified_loader,lists,os,packages]), + ok + end. + %%----------------------------------------------------------------- %% error_logger handler. %% (Copied from stdlib/test/proc_lib_SUITE.erl.) diff --git a/lib/kernel/test/disk_log_SUITE.erl b/lib/kernel/test/disk_log_SUITE.erl index ade9644c15..1bfe76f5ea 100644 --- a/lib/kernel/test/disk_log_SUITE.erl +++ b/lib/kernel/test/disk_log_SUITE.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% %% -module(disk_log_SUITE). @@ -384,7 +384,7 @@ halt_misc(Conf) when is_list(Conf) -> ?line {error, {read_only_mode, a}} = disk_log:change_header(a, {head,header}), ?line {error, {read_only_mode, a}} = - disk_log:change_size(a, inifinity), + disk_log:change_size(a, infinity), ?line ok = disk_log:close(a), ?line ok = file:delete(File). @@ -1574,7 +1574,7 @@ block_blocked(Conf) when is_list(Conf) -> ?line "The blocked disk" ++ _ = format_error(Error1), ?line {error, {blocked_log, halt}} = disk_log:sync(halt), ?line {error, {blocked_log, halt}} = disk_log:truncate(halt), - ?line {error, {blocked_log, halt}} = disk_log:change_size(halt, inifinity), + ?line {error, {blocked_log, halt}} = disk_log:change_size(halt, infinity), ?line {error, {blocked_log, halt}} = disk_log:change_notify(halt, self(), false), ?line {error, {blocked_log, halt}} = @@ -2423,6 +2423,9 @@ get_reply() -> sync_do(Pid, Req) -> Pid ! {self(), Req}, receive + Reply when Req =:= terminate -> + timer:sleep(500), + Reply; Reply -> Reply end. @@ -3165,7 +3168,7 @@ many_users(Conf) when is_list(Conf) -> ?line true = lists:duplicate(NoClients, ok) == C1, ?line true = length(T1) == N*NoClients, ?line {C2, T2} = many(Fun1, NoClients, N, halt, internal, 1000, Dir), - ?line true = lists:duplicate(NoClients, {error, {full,'log.LOG'}}) == C2, + ?line true = lists:duplicate(NoClients, {error, {full,"log.LOG"}}) == C2, ?line true = length(T2) > 0, ?line {C3, T3} = many(Fun2, NoClients, N, wrap, internal, {300*NoClients,20}, Dir), @@ -3174,7 +3177,7 @@ many_users(Conf) when is_list(Conf) -> ok. many(Fun, NoClients, N, Type, Format, Size, Dir) -> - Name = 'log.LOG', + Name = "log.LOG", File = filename:join(Dir, Name), del_files(Size, File), ?line Q = qlen(), @@ -4328,11 +4331,9 @@ dist_terminate(Conf) when is_list(Conf) -> ?line 0 = sync_do(Pid1, users), ?line 0 = sync_do(Pid2, users), ?line sync_do(Pid1, terminate), - ?line timer:sleep(500), ?line [_] = sync_do(Pid2, owners), ?line 0 = sync_do(Pid2, users), ?line sync_do(Pid2, terminate), - ?line timer:sleep(500), ?line {error, no_such_log} = disk_log:info(n), %% Users terminate (no link...). diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl index d01e1f1fcf..17c47f871d 100644 --- a/lib/kernel/test/file_SUITE.erl +++ b/lib/kernel/test/file_SUITE.erl @@ -52,8 +52,8 @@ old_modes/1, new_modes/1, path_open/1, open_errors/1]). -export([file_info/1, file_info_basic_file/1, file_info_basic_directory/1, file_info_bad/1, file_info_times/1, file_write_file_info/1]). --export([rename/1, access/1, truncate/1, sync/1, - read_write/1, pread_write/1, append/1]). +-export([rename/1, access/1, truncate/1, datasync/1, sync/1, + read_write/1, pread_write/1, append/1, exclusive/1]). -export([errors/1, e_delete/1, e_rename/1, e_make_dir/1, e_del_dir/1]). -export([otp_5814/1]). @@ -82,6 +82,10 @@ -export([read_line_1/1, read_line_2/1, read_line_3/1,read_line_4/1]). +-export([advise/1]). + +-export([standard_io/1,mini_server/1]). + %% Debug exports -export([create_file_slow/2, create_file/2, create_bin/2]). -export([verify_file/2, verify_bin/3]). @@ -101,7 +105,8 @@ all(suite) -> compression, links, copy, delayed_write, read_ahead, segment_read, segment_write, ipread, pid2name, interleaved_read_write, - otp_5814, large_file, read_line_1, read_line_2, read_line_3, read_line_4], + otp_5814, large_file, read_line_1, read_line_2, read_line_3, read_line_4, + standard_io], fini}. init(Config) when is_list(Config) -> @@ -170,6 +175,85 @@ time_dist({_D1, _T1} = DT1, {_D2, _T2} = DT2) -> - calendar:datetime_to_gregorian_seconds(DT1). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +mini_server(Parent) -> + receive + die -> + ok; + {io_request,From,To,{put_chars,Data}} -> + Parent ! {io_request,From,To,{put_chars,Data}}, + From ! {io_reply, To, ok}, + mini_server(Parent); + {io_request,From,To,{get_chars,'',N}} -> + Parent ! {io_request,From,To,{get_chars,'',N}}, + From ! {io_reply, To, {ok, lists:duplicate(N,$a)}}, + mini_server(Parent); + {io_request,From,To,{get_line,''}} -> + Parent ! {io_request,From,To,{get_line,''}}, + From ! {io_reply, To, {ok, "hej\n"}}, + mini_server(Parent) + end. + +standard_io(suite) -> + []; +standard_io(doc) -> + ["Test that standard i/o-servers work with file module"]; +standard_io(Config) when is_list(Config) -> + %% Really just a smoke test + ?line Pid = spawn(?MODULE,mini_server,[self()]), + ?line register(mini_server,Pid), + ?line ok = file:write(mini_server,<<"hej\n">>), + ?line receive + {io_request,_,_,{put_chars,<<"hej\n">>}} -> + ok + after 1000 -> + exit(noreply) + end, + ?line {ok,"aaaaa"} = file:read(mini_server,5), + ?line receive + {io_request,_,_,{get_chars,'',5}} -> + ok + after 1000 -> + exit(noreply) + end, + ?line {ok,"hej\n"} = file:read_line(mini_server), + ?line receive + {io_request,_,_,{get_line,''}} -> + ok + after 1000 -> + exit(noreply) + end, + ?line OldGL = group_leader(), + ?line group_leader(Pid,self()), + ?line ok = file:write(standard_io,<<"hej\n">>), + ?line group_leader(OldGL,self()), + ?line receive + {io_request,_,_,{put_chars,<<"hej\n">>}} -> + ok + after 1000 -> + exit(noreply) + end, + ?line group_leader(Pid,self()), + ?line {ok,"aaaaa"} = file:read(standard_io,5), + ?line group_leader(OldGL,self()), + ?line receive + {io_request,_,_,{get_chars,'',5}} -> + ok + after 1000 -> + exit(noreply) + end, + ?line group_leader(Pid,self()), + ?line {ok,"hej\n"} = file:read_line(standard_io), + ?line group_leader(OldGL,self()), + ?line receive + {io_request,_,_,{get_line,''}} -> + ok + after 1000 -> + exit(noreply) + end, + Pid ! die, + receive after 1000 -> ok end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% read_write_file(suite) -> []; read_write_file(doc) -> []; @@ -270,7 +354,10 @@ make_del_dir(Config) when is_list(Config) -> %% Try deleting some bad directories %% Deleting the parent directory to the current, sounds dangerous, huh? %% Don't worry ;-) the parent directory should never be empty, right? - ?line {error, eexist} = ?FILE_MODULE:del_dir('..'), + case ?FILE_MODULE:del_dir('..') of + {error, eexist} -> ok; + {error, einval} -> ok %FreeBSD + end, ?line {error, enoent} = ?FILE_MODULE:del_dir(""), ?line {error, badarg} = ?FILE_MODULE:del_dir([3,2,1,{}]), @@ -374,10 +461,12 @@ win_cur_dir_1(_Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -files(suite) -> [open,pos,file_info,consult,eval,script,truncate,sync]. +files(suite) -> + [open,pos,file_info,consult,eval,script,truncate, + sync,datasync,advise]. open(suite) -> [open1,old_modes,new_modes,path_open,close,access,read_write, - pread_write,append,open_errors]. + pread_write,append,open_errors,exclusive]. open1(suite) -> []; open1(doc) -> []; @@ -751,6 +840,22 @@ open_errors(Config) when is_list(Config) -> ?line test_server:timetrap_cancel(Dog), ok. +exclusive(suite) -> []; +exclusive(doc) -> "Test exclusive access to a file."; +exclusive(Config) when is_list(Config) -> + ?line Dog = test_server:timetrap(test_server:seconds(5)), + ?line RootDir = ?config(priv_dir,Config), + ?line NewDir = filename:join(RootDir, + atom_to_list(?MODULE) + ++"_exclusive"), + ?line ok = ?FILE_MODULE:make_dir(NewDir), + ?line Name = filename:join(NewDir, "ex_file.txt"), + ?line {ok, Fd} = ?FILE_MODULE:open(Name, [write, exclusive]), + ?line {error, eexist} = ?FILE_MODULE:open(Name, [write, exclusive]), + ?line ok = ?FILE_MODULE:close(Fd), + ?line test_server:timetrap_cancel(Dog), + ok. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% pos(suite) -> [pos1,pos2]. @@ -1352,6 +1457,30 @@ truncate(Config) when is_list(Config) -> ok. +datasync(suite) -> []; +datasync(doc) -> "Tests that ?FILE_MODULE:datasync/1 at least doesn't crash."; +datasync(Config) when is_list(Config) -> + ?line Dog = test_server:timetrap(test_server:seconds(5)), + ?line PrivDir = ?config(priv_dir, Config), + ?line Sync = filename:join(PrivDir, + atom_to_list(?MODULE) + ++"_sync.fil"), + + %% Raw open. + ?line {ok, Fd} = ?FILE_MODULE:open(Sync, [write, raw]), + ?line ok = ?FILE_MODULE:datasync(Fd), + ?line ok = ?FILE_MODULE:close(Fd), + + %% Ordinary open. + ?line {ok, Fd2} = ?FILE_MODULE:open(Sync, [write]), + ?line ok = ?FILE_MODULE:datasync(Fd2), + ?line ok = ?FILE_MODULE:close(Fd2), + + ?line [] = flush(), + ?line test_server:timetrap_cancel(Dog), + ok. + + sync(suite) -> []; sync(doc) -> "Tests that ?FILE_MODULE:sync/1 at least doesn't crash."; sync(Config) when is_list(Config) -> @@ -1375,6 +1504,77 @@ sync(Config) when is_list(Config) -> ?line test_server:timetrap_cancel(Dog), ok. +advise(suite) -> []; +advise(doc) -> "Tests that ?FILE_MODULE:advise/4 at least doesn't crash."; +advise(Config) when is_list(Config) -> + ?line Dog = test_server:timetrap(test_server:seconds(5)), + ?line PrivDir = ?config(priv_dir, Config), + ?line Advise = filename:join(PrivDir, + atom_to_list(?MODULE) + ++"_advise.fil"), + + Line1 = "Hello\n", + Line2 = "World!\n", + + ?line {ok, Fd} = ?FILE_MODULE:open(Advise, [write]), + ?line ok = ?FILE_MODULE:advise(Fd, 0, 0, normal), + ?line ok = io:format(Fd, "~s", [Line1]), + ?line ok = io:format(Fd, "~s", [Line2]), + ?line ok = ?FILE_MODULE:close(Fd), + + ?line {ok, Fd2} = ?FILE_MODULE:open(Advise, [write]), + ?line ok = ?FILE_MODULE:advise(Fd2, 0, 0, random), + ?line ok = io:format(Fd2, "~s", [Line1]), + ?line ok = io:format(Fd2, "~s", [Line2]), + ?line ok = ?FILE_MODULE:close(Fd2), + + ?line {ok, Fd3} = ?FILE_MODULE:open(Advise, [write]), + ?line ok = ?FILE_MODULE:advise(Fd3, 0, 0, sequential), + ?line ok = io:format(Fd3, "~s", [Line1]), + ?line ok = io:format(Fd3, "~s", [Line2]), + ?line ok = ?FILE_MODULE:close(Fd3), + + ?line {ok, Fd4} = ?FILE_MODULE:open(Advise, [write]), + ?line ok = ?FILE_MODULE:advise(Fd4, 0, 0, will_need), + ?line ok = io:format(Fd4, "~s", [Line1]), + ?line ok = io:format(Fd4, "~s", [Line2]), + ?line ok = ?FILE_MODULE:close(Fd4), + + ?line {ok, Fd5} = ?FILE_MODULE:open(Advise, [write]), + ?line ok = ?FILE_MODULE:advise(Fd5, 0, 0, dont_need), + ?line ok = io:format(Fd5, "~s", [Line1]), + ?line ok = io:format(Fd5, "~s", [Line2]), + ?line ok = ?FILE_MODULE:close(Fd5), + + ?line {ok, Fd6} = ?FILE_MODULE:open(Advise, [write]), + ?line ok = ?FILE_MODULE:advise(Fd6, 0, 0, no_reuse), + ?line ok = io:format(Fd6, "~s", [Line1]), + ?line ok = io:format(Fd6, "~s", [Line2]), + ?line ok = ?FILE_MODULE:close(Fd6), + + ?line {ok, Fd7} = ?FILE_MODULE:open(Advise, [write]), + ?line {error, einval} = ?FILE_MODULE:advise(Fd7, 0, 0, bad_advise), + ?line ok = ?FILE_MODULE:close(Fd7), + + %% test write without advise, then a read after an advise + ?line {ok, Fd8} = ?FILE_MODULE:open(Advise, [write]), + ?line ok = io:format(Fd8, "~s", [Line1]), + ?line ok = io:format(Fd8, "~s", [Line2]), + ?line ok = ?FILE_MODULE:close(Fd8), + ?line {ok, Fd9} = ?FILE_MODULE:open(Advise, [read]), + Offset = 0, + %% same as a 0 length in some implementations + Length = length(Line1) + length(Line2), + ?line ok = ?FILE_MODULE:advise(Fd9, Offset, Length, sequential), + ?line {ok, Line1} = ?FILE_MODULE:read_line(Fd9), + ?line {ok, Line2} = ?FILE_MODULE:read_line(Fd9), + ?line eof = ?FILE_MODULE:read_line(Fd9), + ?line ok = ?FILE_MODULE:close(Fd9), + + ?line [] = flush(), + ?line test_server:timetrap_cancel(Dog), + ok. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/lib/kernel/test/gen_sctp_SUITE.erl b/lib/kernel/test/gen_sctp_SUITE.erl index fad8c7398b..9aa94a0868 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,implicit_inet6/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,implicit_inet6]. 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,72 @@ 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. + +implicit_inet6(Config) when is_list(Config) -> + ?line Hostname = ok(inet:gethostname()), + ?line + case gen_sctp:open(0, [inet6]) of + {ok,S1} -> + ?line + case inet:getaddr(Hostname, inet6) of + {ok,Host} -> + ?line Loopback = {0,0,0,0,0,0,0,1}, + ?line io:format("~s ~p~n", ["Loopback",Loopback]), + ?line implicit_inet6(S1, Loopback), + ?line ok = gen_sctp:close(S1), + %% + ?line Localhost = + ok(inet:getaddr("localhost", inet6)), + ?line io:format("~s ~p~n", ["localhost",Localhost]), + ?line S2 = + ok(gen_sctp:open(0, [{ip,Localhost}])), + ?line implicit_inet6(S2, Localhost), + ?line ok = gen_sctp:close(S2), + %% + ?line io:format("~s ~p~n", [Hostname,Host]), + ?line S3 = + ok(gen_sctp:open(0, [{ifaddr,Host}])), + ?line implicit_inet6(S3, Host), + ?line ok = gen_sctp:close(S1); + {error,eafnosupport} -> + ?line ok = gen_sctp:close(S1), + {skip,"Can not look up IPv6 address"} + end; + _ -> + {skip,"IPv6 not supported"} + end. + +implicit_inet6(S1, Addr) -> + ?line ok = gen_sctp:listen(S1, true), + ?line P1 = ok(inet:port(S1)), + ?line S2 = ok(gen_sctp:open(0, [inet6])), + ?line P2 = ok(inet:port(S2)), + ?line #sctp_assoc_change{state=comm_up} = + ok(gen_sctp:connect(S2, Addr, P1, [])), + ?line case ok(gen_sctp:recv(S1)) of + {Addr,P2,[],#sctp_assoc_change{state=comm_up}} -> + ok + end, + ?line case ok(inet:sockname(S1)) of + {Addr,P1} -> ok; + {{0,0,0,0,0,0,0,0},P1} -> ok + end, + ?line case ok(inet:sockname(S2)) of + {Addr,P2} -> ok; + {{0,0,0,0,0,0,0,0},P2} -> ok + end, + ?line ok = gen_sctp:close(S2). diff --git a/lib/kernel/test/gen_tcp_api_SUITE.erl b/lib/kernel/test/gen_tcp_api_SUITE.erl index 11d19aaa82..94637290a1 100644 --- a/lib/kernel/test/gen_tcp_api_SUITE.erl +++ b/lib/kernel/test/gen_tcp_api_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% Copyright Ericsson AB 1998-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 @@ -30,10 +30,11 @@ t_connect/1, t_connect_bad/1, t_recv/1, t_recv_timeout/1, t_recv_eof/1, t_shutdown_write/1, t_shutdown_both/1, t_shutdown_error/1, - t_fdopen/1]). + t_fdopen/1, t_implicit_inet6/1]). all(suite) -> [t_accept, t_connect, t_recv, t_shutdown_write, - t_shutdown_both, t_shutdown_error, t_fdopen]. + t_shutdown_both, t_shutdown_error, t_fdopen, + t_implicit_inet6]. init_per_testcase(_Func, Config) -> Dog = test_server:timetrap(test_server:seconds(60)), @@ -156,6 +157,54 @@ t_fdopen(Config) when is_list(Config) -> ok. +%%% implicit inet6 option to api functions + +t_implicit_inet6(Config) when is_list(Config) -> + ?line Hostname = ok(inet:gethostname()), + ?line + case gen_tcp:listen(0, [inet6]) of + {ok,S1} -> + ?line + case inet:getaddr(Hostname, inet6) of + {ok,Host} -> + ?line Loopback = {0,0,0,0,0,0,0,1}, + ?line io:format("~s ~p~n", ["Loopback",Loopback]), + ?line implicit_inet6(S1, Loopback), + ?line ok = gen_tcp:close(S1), + %% + ?line Localhost = + ok(inet:getaddr("localhost", inet6)), + ?line io:format("~s ~p~n", ["localhost",Localhost]), + ?line S2 = ok(gen_tcp:listen(0, [{ip,Localhost}])), + ?line implicit_inet6(S2, Localhost), + ?line ok = gen_tcp:close(S2), + %% + ?line io:format("~s ~p~n", [Hostname,Host]), + ?line S3 = ok(gen_tcp:listen(0, [{ifaddr,Host}])), + ?line implicit_inet6(S3, Host), + ?line ok = gen_tcp:close(S1); + {error,eafnosupport} -> + ?line ok = gen_tcp:close(S1), + {skip,"Can not look up IPv6 address"} + end; + _ -> + {skip,"IPv6 not supported"} + end. + +implicit_inet6(S, Addr) -> + ?line P = ok(inet:port(S)), + ?line S2 = ok(gen_tcp:connect(Addr, P, [])), + ?line P2 = ok(inet:port(S2)), + ?line S1 = ok(gen_tcp:accept(S)), + ?line P1 = P = ok(inet:port(S1)), + ?line {Addr,P2} = ok(inet:peername(S1)), + ?line {Addr,P1} = ok(inet:peername(S2)), + ?line {Addr,P1} = ok(inet:sockname(S1)), + ?line {Addr,P2} = ok(inet:sockname(S2)), + ?line ok = gen_tcp:close(S2), + ?line ok = gen_tcp:close(S1). + + %%% Utilities @@ -217,3 +266,5 @@ unused_ip(A, B, C, D) -> {ok, _} -> unused_ip(A, B, C, D+1); {error, _} -> {ok, {A, B, C, D}} end. + +ok({ok,V}) -> V. diff --git a/lib/kernel/test/gen_tcp_misc_SUITE.erl b/lib/kernel/test/gen_tcp_misc_SUITE.erl index 5d726a3b1b..d73c5fab56 100644 --- a/lib/kernel/test/gen_tcp_misc_SUITE.erl +++ b/lib/kernel/test/gen_tcp_misc_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1998-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(gen_tcp_misc_SUITE). @@ -957,12 +957,11 @@ http_bad_packet(Config) when is_list(Config) -> http_worker(S) -> case gen_tcp:recv(S, 0, 30000) of + {ok,{http_error,Error}} -> + io:format("Http error: ~s\n", [Error]); {ok,Data} -> io:format("Data: ~p\n", [Data]), - http_worker(S); - {error,Rsn} -> - io:format("Error: ~p\n", [Rsn]), - ok + http_worker(S) end. http_bad_client(Port) -> diff --git a/lib/kernel/test/gen_udp_SUITE.erl b/lib/kernel/test/gen_udp_SUITE.erl index bd5685952e..bbdfbd3cb0 100644 --- a/lib/kernel/test/gen_udp_SUITE.erl +++ b/lib/kernel/test/gen_udp_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% Copyright Ericsson AB 1998-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,12 +34,12 @@ -export([send_to_closed/1, buffer_size/1, binary_passive_recv/1, bad_address/1, - read_packets/1, open_fd/1]). + read_packets/1, open_fd/1, connect/1, implicit_inet6/1]). all(suite) -> [send_to_closed, buffer_size, binary_passive_recv, bad_address, read_packets, - open_fd]. + open_fd, connect, implicit_inet6]. init_per_testcase(_Case, Config) -> ?line Dog=test_server:timetrap(?default_timeout), @@ -408,3 +408,74 @@ start_node(Name) -> stop_node(Node) -> ?t:stop_node(Node). + + +connect(suite) -> + []; +connect(doc) -> + ["Test that connect/3 has effect"]; +connect(Config) when is_list(Config) -> + ?line Addr = {127,0,0,1}, + ?line {ok,S1} = gen_udp:open(0), + ?line {ok,P1} = inet:port(S1), + ?line {ok,S2} = gen_udp:open(0), + ?line ok = inet:setopts(S2, [{active,false}]), + ?line ok = gen_udp:close(S1), + ?line ok = gen_udp:connect(S2, Addr, P1), + ?line ok = gen_udp:send(S2, <<16#deadbeef:32>>), + ?line {error,econnrefused} = gen_udp:recv(S2, 0, 5), + ok. + +implicit_inet6(Config) when is_list(Config) -> + ?line Hostname = ok(inet:gethostname()), + ?line Active = {active,false}, + ?line + case gen_udp:open(0, [inet6,Active]) of + {ok,S1} -> + ?line + case inet:getaddr(Hostname, inet6) of + {ok,Host} -> + ?line Loopback = {0,0,0,0,0,0,0,1}, + ?line io:format("~s ~p~n", ["Loopback",Loopback]), + ?line implicit_inet6(S1, Active, Loopback), + ?line ok = gen_udp:close(S1), + %% + ?line Localhost = + ok(inet:getaddr("localhost", inet6)), + ?line io:format("~s ~p~n", ["localhost",Localhost]), + ?line S2 = + ok(gen_udp:open(0, [{ip,Localhost},Active])), + ?line implicit_inet6(S2, Active, Localhost), + ?line ok = gen_udp:close(S2), + %% + ?line io:format("~s ~p~n", [Hostname,Host]), + ?line S3 = + ok(gen_udp:open(0, [{ifaddr,Host},Active])), + ?line implicit_inet6(S3, Active, Host), + ?line ok = gen_udp:close(S1); + {error,eafnosupport} -> + ?line ok = gen_udp:close(S1), + {skip,"Can not look up IPv6 address"} + end; + _ -> + {skip,"IPv6 not supported"} + end. + +implicit_inet6(S1, Active, Addr) -> + ?line P1 = ok(inet:port(S1)), + ?line S2 = ok(gen_udp:open(0, [inet6,Active])), + ?line P2 = ok(inet:port(S2)), + ?line ok = gen_udp:connect(S2, Addr, P1), + ?line ok = gen_udp:connect(S1, Addr, P2), + ?line {Addr,P2} = ok(inet:peername(S1)), + ?line {Addr,P1} = ok(inet:peername(S2)), + ?line {Addr,P1} = ok(inet:sockname(S1)), + ?line {Addr,P2} = ok(inet:sockname(S2)), + ?line ok = gen_udp:send(S1, Addr, P2, "ping"), + ?line {Addr,P1,"ping"} = ok(gen_udp:recv(S2, 1024, 1000)), + ?line ok = gen_udp:send(S2, Addr, P1, "pong"), + ?line {Addr,P2,"pong"} = ok(gen_udp:recv(S1, 1024)), + ?line ok = gen_udp:close(S2). + + +ok({ok,V}) -> V. diff --git a/lib/kernel/test/global_SUITE.erl b/lib/kernel/test/global_SUITE.erl index a8c68985e2..7a84ad5e75 100644 --- a/lib/kernel/test/global_SUITE.erl +++ b/lib/kernel/test/global_SUITE.erl @@ -1,25 +1,23 @@ %% %% %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% %% -module(global_SUITE). --compile(r11). % some code is run from r11-nodes - %-define(line_trace, 1). -export([all/1, @@ -2616,19 +2614,6 @@ proc(Parent) -> name_exit(suite) -> []; name_exit(doc) -> ["OTP-5563. Registered process dies."]; name_exit(Config) when is_list(Config) -> - case ?t:is_release_available("r11b") of - true -> - StartOldFun = - fun() -> - {ok, N1} = start_node_rel(n_1, r11b, Config), - {ok, N2} = start_node_rel(n_2, this, Config), - [N1, N2] - end, - ?t:format("Test of r11~n"), - do_name_exit(StartOldFun, old, Config); - false -> - ok - end, StartFun = fun() -> {ok, N1} = start_node_rel(n_1, this, Config), {ok, N2} = start_node_rel(n_2, this, Config), @@ -2855,14 +2840,7 @@ many_nodes(Config) when is_list(Config) -> N_nodes = quite_a_few_nodes(32), {node_rel(1, N_nodes, this), N_nodes}; {unix, _} -> - case ?t:is_release_available("r11b") of - true -> - This = node_rel(1, 16, this), - R11B = node_rel(17, 32, r11b), - {This ++ R11B, 32}; - false -> - {node_rel(1, 32, this), 32} - end; + {node_rel(1, 32, this), 32}; _ -> {node_rel(1, 32, this), 32} end, @@ -3864,12 +3842,7 @@ start_node_rel(Name0, Rel, Config) -> RelList -> {RelList, ""} end, - Env = case Rel of - r11b -> - [{env, [{"ERL_R11B_FLAGS", []}]}]; - _ -> - [] - end, + Env = [], Pa = filename:dirname(code:which(?MODULE)), Res = test_server:start_node(Name, peer, [{args, 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/test/inet_sockopt_SUITE_data/sockopt_helper.c b/lib/kernel/test/inet_sockopt_SUITE_data/sockopt_helper.c index fb3c622909..f24c93edf5 100644 --- a/lib/kernel/test/inet_sockopt_SUITE_data/sockopt_helper.c +++ b/lib/kernel/test/inet_sockopt_SUITE_data/sockopt_helper.c @@ -1,4 +1,4 @@ -#if defined(VXWORKS) || defined(__OSE__) +#if defined(VXWORKS) #include <stdio.h> #include <stdlib.h> #include <string.h> diff --git a/lib/kernel/test/os_SUITE.erl b/lib/kernel/test/os_SUITE.erl index 6a3534b094..ace9501d18 100644 --- a/lib/kernel/test/os_SUITE.erl +++ b/lib/kernel/test/os_SUITE.erl @@ -137,6 +137,13 @@ find_executable(Config) when is_list(Config) -> ?line find_exe(Abin, "my_ar", ".exe", Path), ?line find_exe(Abin, "my_ascii", ".com", Path), ?line find_exe(Abin, "my_adb", ".bat", Path), + %% OTP-3626 find names of executables given with extension + ?line find_exe(Abin, "my_ar.exe", "", Path), + ?line find_exe(Abin, "my_ascii.com", "", Path), + ?line find_exe(Abin, "my_adb.bat", "", Path), + ?line find_exe(Abin, "my_ar.EXE", "", Path), + ?line find_exe(Abin, "my_ascii.COM", "", Path), + ?line find_exe(Abin, "MY_ADB.BAT", "", Path), %% Search for programs in Abin (second element in PATH). ?line find_exe(Abin, "my_ar", ".exe", Path), diff --git a/lib/kernel/test/pg2_SUITE.erl b/lib/kernel/test/pg2_SUITE.erl index 8eb1a7ca19..df28dcf447 100644 --- a/lib/kernel/test/pg2_SUITE.erl +++ b/lib/kernel/test/pg2_SUITE.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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:Test Suite for the 'pg2' module. @@ -26,8 +26,8 @@ -export([all/1, init_per_testcase/2, fin_per_testcase/2]). --export([tickets/1, - otp_7277/1, otp_8259/1, +-export([tickets/1, + otp_7277/1, otp_8259/1, otp_8653/1, compat/1, basic/1]). % Default timetrap timeout (set in init_per_testcase). @@ -37,7 +37,8 @@ -define(testcase, ?config(?TESTCASE, Config)). %% Internal export. --export([mk_part_node/3, part1/5, p_init/3, start_proc/1, sane/0]). +-export([mk_part_node_and_group/3, part2/4, + mk_part_node/3, part1/5, p_init/3, start_proc/1, sane/0]). init_per_testcase(Case, Config) -> ?line Dog = ?t:timetrap(?default_timeout), @@ -48,11 +49,11 @@ fin_per_testcase(_Case, _Config) -> test_server:timetrap_cancel(Dog), ok. -all(suite) -> +all(suite) -> [tickets]. tickets(suite) -> - [otp_7277, otp_8259, compat, basic]. + [otp_7277, otp_8259, otp_8653, compat, basic]. otp_7277(doc) -> "OTP-7277. Bugfix leave()."; @@ -65,9 +66,9 @@ otp_7277(Config) when is_list(Config) -> ?line ok = pg2:leave(b, P), ?line true = exit(P, kill), case {pg2:get_members(a), pg2:get_local_members(a)} of - {[], []} -> + {[], []} -> ok; - _ -> + _ -> timer:sleep(100), ?line [] = pg2:get_members(a), ?line [] = pg2:get_local_members(a) @@ -79,6 +80,63 @@ otp_7277(Config) when is_list(Config) -> -define(UNTIL(Seq), loop_until_true(fun() -> Seq end, Config)). -define(UNTIL_LOOP, 300). +otp_8653(suite) -> []; +otp_8653(doc) -> + ["OTP-8259. Member was not removed after being killed."]; +otp_8653(Config) when is_list(Config) -> + Timeout = 15, + ?line Dog = test_server:timetrap({seconds,Timeout}), + + ?line [A, B, C] = start_nodes([a, b, c], peer, Config), + + ?line wait_for_ready_net(Config), + + % make b and c connected, partitioned from node() and a + ?line rpc_cast(B, ?MODULE, part2, [Config, node(), A, C]), + ?line ?UNTIL(is_ready_partition(Config)), + + % Connect to the other partition. + ?line pong = net_adm:ping(B), + timer:sleep(100), + ?line pong = net_adm:ping(C), + ?line _ = global:sync(), + ?line [A, B, C] = lists:sort(nodes()), + + G = pg2_otp_8653, + ?line ?UNTIL(begin + GA = lists:sort(rpc:call(A, pg2, get_members, [G])), + GB = lists:sort(rpc:call(B, pg2, get_members, [G])), + GC = lists:sort(rpc:call(C, pg2, get_members, [G])), + GT = lists:sort(pg2:get_members(G)), + GA =:= GB andalso + GB =:= GC andalso + GC =:= GT andalso + 8 =:= length(GA) + end), + ?line ok = pg2:delete(G), + ?line stop_nodes([A,B,C]), + ?line test_server:timetrap_cancel(Dog), + ok. + +part2(Config, Main, A, C) -> + Function = mk_part_node_and_group, + case catch begin + make_partition(Config, [Main, A], [node(), C], Function) + end + of + ok -> ok + end. + +mk_part_node_and_group(File, MyPart0, Config) -> + touch(File, "start"), % debug + MyPart = lists:sort(MyPart0), + ?UNTIL(is_node_in_part(File, MyPart)), + G = pg2_otp_8653, + Pid = spawn(forever()), + ok = pg2:create(G), + _ = [ok = pg2:join(G, Pid) || _ <- [1,1]], + touch(File, "done"). + otp_8259(suite) -> []; otp_8259(doc) -> ["OTP-8259. Member was not removed after being killed."]; @@ -102,7 +160,7 @@ otp_8259(Config) when is_list(Config) -> % make b and c connected, partitioned from node() and a ?line rpc_cast(B, ?MODULE, part1, [Config, node(), A, C, Name]), ?line ?UNTIL(is_ready_partition(Config)), - + % Connect to the other partition. % The resolver on node b will be called. ?line pong = net_adm:ping(B), @@ -140,9 +198,9 @@ start_proc(Name) -> p_init(Parent, Name, TestServer) -> Resolve = fun(_Name, Pid1, Pid2) -> %% The pid on node a will be chosen. - [{_,Min}, {_,Max}] = + [{_,Min}, {_,Max}] = lists:sort([{node(Pid1),Pid1}, {node(Pid2),Pid2}]), - %% b is connected to test_server. + %% b is connected to test_server. %% exit(Min, kill), % would ping a rpc:cast(TestServer, erlang, exit, [Min, kill]), Max @@ -165,7 +223,7 @@ compat(Config) when is_list(Config) -> true -> Timeout = 15, ?line Dog = test_server:timetrap({seconds,Timeout}), - Pid = spawn(forever()), + Pid = spawn(forever()), G = a, ?line ok = pg2:create(G), ?line ok = pg2:join(G, Pid), @@ -365,7 +423,7 @@ killit(N, P, Ps, Ns) -> timer:sleep(100), sane(Ns), lists:keydelete(P, 1, Ps). - + pr(Node, C) -> _ = [?t:format("~p: ", [Node]) || Node =/= node()], ?t:format("do ~p~n", [C]). @@ -412,27 +470,27 @@ sane(Ns) -> wsane(Ns) -> %% Same members on all nodes: - {[_],gs} = + {[_],gs} = {lists:usort([rpc:call(N, pg2, which_groups, []) || N <- Ns]),gs}, - _ = [{[_],ms,G} = {lists:usort([rpc:call(N, pg2, get_members, [G]) || + _ = [{[_],ms,G} = {lists:usort([rpc:call(N, pg2, get_members, [G]) || N <- Ns]),ms,G} || G <- pg2:which_groups()], %% The local members are a partitioning of the members: - [begin - LocalMembers = + [begin + LocalMembers = lists:sort(lists:append( - [rpc:call(N, pg2, get_local_members, [G]) || + [rpc:call(N, pg2, get_local_members, [G]) || N <- Ns])), {part, LocalMembers} = {part, lists:sort(pg2:get_members(G))} end || G <- pg2:which_groups()], %% The closest pid should run on the local node, if possible. [[case rpc:call(N, pg2, get_closest_pid, [G]) of Pid when is_pid(Pid), node(Pid) =:= N -> - true = + true = lists:member(Pid, rpc:call(N, pg2, get_local_members, [G])); %% FIXME. Om annan nod: member, local = []. _ -> [] = rpc:call(N, pg2, get_local_members, [G]) - end || N <- Ns] + end || N <- Ns] || G <- pg2:which_groups()]. %% Look inside the pg2_table. @@ -482,9 +540,9 @@ start_node_rel(Name, Rel, How) -> {RelList, ""} end, ?line Pa = filename:dirname(code:which(?MODULE)), - ?line Res = test_server:start_node(Name, How, + ?line Res = test_server:start_node(Name, How, [{args, - Compat ++ + Compat ++ " -kernel net_setuptime 100 " " -pa " ++ Pa}, {erl, Release}]), @@ -575,29 +633,30 @@ get_known(Node) -> case catch gen_server:call({global_name_server,Node},get_known,infinity) of {'EXIT', _} -> [list, without, nodenames]; - Known when is_list(Known) -> + Known when is_list(Known) -> lists:sort([Node | Known]) end. node_name(Name, Config) -> U = "_", {{Y,M,D}, {H,Min,S}} = calendar:now_to_local_time(now()), - Date = io_lib:format("~4w_~2..0w_~2..0w__~2..0w_~2..0w_~2..0w", + Date = io_lib:format("~4w_~2..0w_~2..0w__~2..0w_~2..0w_~2..0w", [Y,M,D, H,Min,S]), L = lists:flatten(Date), lists:concat([Name,U,?testcase,U,U,L]). -%% this one runs on one node in Part2 -%% The partition is ready when is_ready_partition(Config) returns (true). -%% this one runs on one node in Part2 +%% This one runs on one node in Part2. %% The partition is ready when is_ready_partition(Config) returns (true). make_partition(Config, Part1, Part2) -> + make_partition(Config, Part1, Part2, mk_part_node). + +make_partition(Config, Part1, Part2, Function) -> Dir = ?config(priv_dir, Config), - Ns = [begin + Ns = [begin Name = lists:concat([atom_to_list(N),"_",msec(),".part"]), File = filename:join([Dir, Name]), file:delete(File), - rpc_cast(N, ?MODULE, mk_part_node, [File, Part, Config], File), + rpc_cast(N, ?MODULE, Function, [File, Part, Config], File), {N, File} end || Part <- [Part1, Part2], N <- Part], all_nodes_files(Ns, "done", Config), @@ -614,10 +673,10 @@ mk_part_node(File, MyPart0, Config) -> %% The calls to append_to_file are for debugging. is_node_in_part(File, MyPart) -> - lists:foreach(fun(N) -> + lists:foreach(fun(N) -> _ = erlang:disconnect_node(N) end, nodes() -- MyPart), - case {(Known = get_known(node())) =:= MyPart, + case {(Known = get_known(node())) =:= MyPart, (Nodes = lists:sort([node() | nodes()])) =:= MyPart} of {true, true} -> %% Make sure the resolvers have been terminated, @@ -649,7 +708,7 @@ wait_for_ready_net(Nodes0, Config) -> ?t:format("wait_for_ready_net ~p~n", [Nodes]), ?UNTIL(begin lists:all(fun(N) -> Nodes =:= get_known(N) end, Nodes) and - lists:all(fun(N) -> + lists:all(fun(N) -> LNs = rpc:call(N, erlang, nodes, []), Nodes =:= lists:sort([N | LNs]) end, Nodes) @@ -688,11 +747,11 @@ file_contents(File, ContentsList, Config) -> file_contents(File, ContentsList, Config, no_log_file). file_contents(File, ContentsList, Config, LogFile) -> - Contents = list_to_binary(ContentsList), + Contents = list_to_binary(ContentsList), Sz = size(Contents), ?UNTIL(begin case file:read_file(File) of - {ok, FileContents}=Reply -> + {ok, FileContents}=Reply -> case catch split_binary(FileContents, Sz) of {Contents,_} -> true; diff --git a/lib/kernel/test/prim_file_SUITE.erl b/lib/kernel/test/prim_file_SUITE.erl index 860aeecbf4..1688ec45ca 100644 --- a/lib/kernel/test/prim_file_SUITE.erl +++ b/lib/kernel/test/prim_file_SUITE.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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(prim_file_SUITE). @@ -34,8 +34,8 @@ file_info_times_a/1, file_info_times_b/1, file_write_file_info_a/1, file_write_file_info_b/1]). -export([rename_a/1, rename_b/1, - access/1, truncate/1, sync/1, - read_write/1, pread_write/1, append/1]). + access/1, truncate/1, datasync/1, sync/1, + read_write/1, pread_write/1, append/1, exclusive/1]). -export([errors/1, e_delete/1, e_rename/1, e_make_dir/1, e_del_dir/1]). -export([compression/1, read_not_really_compressed/1, @@ -48,6 +48,8 @@ symlinks_a/1, symlinks_b/1, list_dir_limit/1]). +-export([advise/1]). + -include("test_server.hrl"). -include_lib("kernel/include/file.hrl"). @@ -243,7 +245,10 @@ make_del_dir(Config, Handle, Suffix) -> %% Try deleting some bad directories %% Deleting the parent directory to the current, sounds dangerous, huh? %% Don't worry ;-) the parent directory should never be empty, right? - ?line {error, eexist} = ?PRIM_FILE_call(del_dir, Handle, [".."]), + case ?PRIM_FILE_call(del_dir, Handle, [".."]) of + {error, eexist} -> ok; + {error, einval} -> ok %FreeBSD + end, ?line {error, enoent} = ?PRIM_FILE_call(del_dir, Handle, [""]), ?line {error, badarg} = ?PRIM_FILE_call(del_dir, Handle, [[3,2,1,{}]]), @@ -377,10 +382,10 @@ win_cur_dir_1(_Config, Handle) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -files(suite) -> [open,pos,file_info,truncate,sync]. +files(suite) -> [open,pos,file_info,truncate,sync,datasync,advise]. open(suite) -> [open1,modes,close,access,read_write, - pread_write,append]. + pread_write,append,exclusive]. open1(suite) -> []; open1(doc) -> []; @@ -605,6 +610,22 @@ append(Config) when is_list(Config) -> ?line test_server:timetrap_cancel(Dog), ok. +exclusive(suite) -> []; +exclusive(doc) -> "Test exclusive access to a file."; +exclusive(Config) when is_list(Config) -> + ?line Dog = test_server:timetrap(test_server:seconds(5)), + ?line RootDir = ?config(priv_dir,Config), + ?line NewDir = filename:join(RootDir, + atom_to_list(?MODULE) + ++"_exclusive"), + ?line ok = ?PRIM_FILE:make_dir(NewDir), + ?line Name = filename:join(NewDir, "ex_file.txt"), + ?line {ok,Fd} = ?PRIM_FILE:open(Name, [write, exclusive]), + ?line {error, eexist} = ?PRIM_FILE:open(Name, [write, exclusive]), + ?line ok = ?PRIM_FILE:close(Fd), + ?line test_server:timetrap_cancel(Dog), + ok. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% pos(suite) -> [pos1,pos2]. @@ -1061,6 +1082,24 @@ truncate(Config) when is_list(Config) -> ok. +datasync(suite) -> []; +datasync(doc) -> "Tests that ?PRIM_FILE:datasync/1 at least doesn't crash."; +datasync(Config) when is_list(Config) -> + ?line Dog = test_server:timetrap(test_server:seconds(5)), + ?line PrivDir = ?config(priv_dir, Config), + ?line Sync = filename:join(PrivDir, + atom_to_list(?MODULE) + ++"_sync.fil"), + + %% Raw open. + ?line {ok, Fd} = ?PRIM_FILE:open(Sync, [write]), + ?line ok = ?PRIM_FILE:datasync(Fd), + ?line ok = ?PRIM_FILE:close(Fd), + + ?line test_server:timetrap_cancel(Dog), + ok. + + sync(suite) -> []; sync(doc) -> "Tests that ?PRIM_FILE:sync/1 at least doesn't crash."; sync(Config) when is_list(Config) -> @@ -1079,6 +1118,77 @@ sync(Config) when is_list(Config) -> ok. +advise(suite) -> []; +advise(doc) -> "Tests that ?PRIM_FILE:advise/4 at least doesn't crash."; +advise(Config) when is_list(Config) -> + ?line Dog = test_server:timetrap(test_server:seconds(5)), + ?line PrivDir = ?config(priv_dir, Config), + ?line Advise = filename:join(PrivDir, + atom_to_list(?MODULE) + ++"_advise.fil"), + + Line1 = "Hello\n", + Line2 = "World!\n", + + ?line {ok, Fd} = ?PRIM_FILE:open(Advise, [write]), + ?line ok = ?PRIM_FILE:advise(Fd, 0, 0, normal), + ?line ok = ?PRIM_FILE:write(Fd, Line1), + ?line ok = ?PRIM_FILE:write(Fd, Line2), + ?line ok = ?PRIM_FILE:close(Fd), + + ?line {ok, Fd2} = ?PRIM_FILE:open(Advise, [write]), + ?line ok = ?PRIM_FILE:advise(Fd2, 0, 0, random), + ?line ok = ?PRIM_FILE:write(Fd2, Line1), + ?line ok = ?PRIM_FILE:write(Fd2, Line2), + ?line ok = ?PRIM_FILE:close(Fd2), + + ?line {ok, Fd3} = ?PRIM_FILE:open(Advise, [write]), + ?line ok = ?PRIM_FILE:advise(Fd3, 0, 0, sequential), + ?line ok = ?PRIM_FILE:write(Fd3, Line1), + ?line ok = ?PRIM_FILE:write(Fd3, Line2), + ?line ok = ?PRIM_FILE:close(Fd3), + + ?line {ok, Fd4} = ?PRIM_FILE:open(Advise, [write]), + ?line ok = ?PRIM_FILE:advise(Fd4, 0, 0, will_need), + ?line ok = ?PRIM_FILE:write(Fd4, Line1), + ?line ok = ?PRIM_FILE:write(Fd4, Line2), + ?line ok = ?PRIM_FILE:close(Fd4), + + ?line {ok, Fd5} = ?PRIM_FILE:open(Advise, [write]), + ?line ok = ?PRIM_FILE:advise(Fd5, 0, 0, dont_need), + ?line ok = ?PRIM_FILE:write(Fd5, Line1), + ?line ok = ?PRIM_FILE:write(Fd5, Line2), + ?line ok = ?PRIM_FILE:close(Fd5), + + ?line {ok, Fd6} = ?PRIM_FILE:open(Advise, [write]), + ?line ok = ?PRIM_FILE:advise(Fd6, 0, 0, no_reuse), + ?line ok = ?PRIM_FILE:write(Fd6, Line1), + ?line ok = ?PRIM_FILE:write(Fd6, Line2), + ?line ok = ?PRIM_FILE:close(Fd6), + + ?line {ok, Fd7} = ?PRIM_FILE:open(Advise, [write]), + ?line {error, einval} = ?PRIM_FILE:advise(Fd7, 0, 0, bad_advise), + ?line ok = ?PRIM_FILE:close(Fd7), + + %% test write without advise, then a read after an advise + ?line {ok, Fd8} = ?PRIM_FILE:open(Advise, [write]), + ?line ok = ?PRIM_FILE:write(Fd8, Line1), + ?line ok = ?PRIM_FILE:write(Fd8, Line2), + ?line ok = ?PRIM_FILE:close(Fd8), + ?line {ok, Fd9} = ?PRIM_FILE:open(Advise, [read]), + Offset = 0, + %% same as a 0 length in some implementations + Length = length(Line1) + length(Line2), + ?line ok = ?PRIM_FILE:advise(Fd9, Offset, Length, sequential), + ?line {ok, Line1} = ?PRIM_FILE:read_line(Fd9), + ?line {ok, Line2} = ?PRIM_FILE:read_line(Fd9), + ?line eof = ?PRIM_FILE:read_line(Fd9), + ?line ok = ?PRIM_FILE:close(Fd9), + + ?line test_server:timetrap_cancel(Dog), + ok. + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% delete_a(suite) -> []; diff --git a/lib/kernel/vsn.mk b/lib/kernel/vsn.mk index 933600b501..651d082379 100644 --- a/lib/kernel/vsn.mk +++ b/lib/kernel/vsn.mk @@ -1 +1 @@ -KERNEL_VSN = 2.13.5.4 +KERNEL_VSN = 2.14.1 diff --git a/lib/megaco/doc/src/Makefile b/lib/megaco/doc/src/Makefile index 2355a1b8b9..4b3c117b20 100644 --- a/lib/megaco/doc/src/Makefile +++ b/lib/megaco/doc/src/Makefile @@ -125,6 +125,12 @@ DVIPS_FLAGS += $(HTMLDIR)/%.gif: %.gif $(INSTALL_DATA) $< $@ +$(HTMLDIR)/%.jpg: %.jpg + $(INSTALL_DATA) $< $@ + +$(HTMLDIR)/%.png: %.png + $(INSTALL_DATA) $< $@ + ifdef DOCSUPPORT docs: pdf html man @@ -135,7 +141,7 @@ $(TOP_PDF_FILE): $(XML_FILES) pdf: $(TOP_PDF_FILE) -html: gifs $(HTML_REF_MAN_FILE) +html: imgs $(HTML_REF_MAN_FILE) clean clean_docs: clean_html clean_man rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) @@ -149,7 +155,7 @@ else ifeq ($(DOCTYPE),ps) docs: ps else -docs: html gifs man +docs: html imgs man endif endif @@ -157,7 +163,7 @@ pdf: $(TOP_PDF_FILE) ps: $(TOP_PS_FILE) -html: gifs $(HTML_FILES) $(TOP_HTML_FILES) +html: imgs $(HTML_FILES) $(TOP_HTML_FILES) mhtml: html $(HTML_REF3_FILES) $(HTML_CHAPTER_FILES) @@ -182,7 +188,7 @@ clean_man: clean_html: rm -rf $(HTMLDIR)/* -gifs: $(GIF_FILES:%=$(HTMLDIR)/%) +imgs: $(IMG_FILES:%=$(HTMLDIR)/%) man: $(MAN3_FILES) @@ -208,7 +214,7 @@ info: @echo "XML_REF3_FILES = $(XML_REF3_FILES)" @echo "XML_CHAPTER_FILES = $(XML_CHAPTER_FILES)" @echo "" - @echo "GIF_FILES = $(GIF_FILES)" + @echo "IMG_FILES = $(IMG_FILES)" @echo "" @echo "TEX_FILES_USERS_GUIDE = $(TEX_FILES_USERS_GUIDE)" @echo "TEX_FILES_REF_MAN = $(TEX_FILES_REF_MAN)" @@ -258,7 +264,7 @@ release_docs_spec: ps else release_docs_spec: docs $(INSTALL_DIR) $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(GIF_FILES) $(EXTRA_FILES) $(HTML_FILES) \ + $(INSTALL_DATA) $(IMG_FILES) $(EXTRA_FILES) $(HTML_FILES) \ $(RELSYSDIR)/doc/html $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 diff --git a/lib/megaco/doc/src/files.mk b/lib/megaco/doc/src/files.mk index debc5d278d..efacb7e422 100644 --- a/lib/megaco/doc/src/files.mk +++ b/lib/megaco/doc/src/files.mk @@ -1,20 +1,20 @@ #-*-makefile-*- ; force emacs to enter makefile-mode # %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 # 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% XML_APPLICATION_FILES = \ @@ -56,7 +56,7 @@ XML_CHAPTER_FILES = \ BOOK_FILES = book.xml -GIF_FILES = \ +IMG_FILES = \ single_node_config.gif \ distr_node_config.gif \ megaco_sys_arch.gif \ @@ -70,4 +70,4 @@ GIF_FILES = \ MG_startup_call_flow.gif \ call_flow.gif \ call_flow_cont.gif \ - mstone1.gif + mstone1.jpg diff --git a/lib/megaco/doc/src/megaco.xml b/lib/megaco/doc/src/megaco.xml index ae9e250965..b9bf414299 100644 --- a/lib/megaco/doc/src/megaco.xml +++ b/lib/megaco/doc/src/megaco.xml @@ -662,7 +662,7 @@ megaco_incr_timer() = #megaco_incr_timer{} <taglist> <tag><c><![CDATA[none]]></c></tag> <item> - <p>Do not segment outgoing reply messages. This is usefull when + <p>Do not segment outgoing reply messages. This is useful when either it is known that messages are never to large or that the transport protocol can handle such things on its own (e.g. TCP or SCTP).</p> @@ -1182,7 +1182,7 @@ megaco_incr_timer() = #megaco_incr_timer{} <taglist> <tag><c><![CDATA[none]]></c></tag> <item> - <p>Do not segment outgoing reply messages. This is usefull when + <p>Do not segment outgoing reply messages. This is useful when either it is known that messages are never to large or that the transport protocol can handle such things on its own (e.g. TCP or SCTP).</p> diff --git a/lib/megaco/doc/src/megaco_flex_scanner.xml b/lib/megaco/doc/src/megaco_flex_scanner.xml index eb206e5d13..18c40bb71a 100644 --- a/lib/megaco/doc/src/megaco_flex_scanner.xml +++ b/lib/megaco/doc/src/megaco_flex_scanner.xml @@ -128,7 +128,7 @@ megaco_version() = integer() >= 1 <v>Boolean = boolean()</v> </type> <desc> - <p>Checks if a port is a flex scanner port or not (usefull when + <p>Checks if a port is a flex scanner port or not (useful when if a port exits). </p> <marker id="scan"></marker> diff --git a/lib/megaco/doc/src/megaco_performance.xml b/lib/megaco/doc/src/megaco_performance.xml index 72b5c156ba..eb3d852a19 100644 --- a/lib/megaco/doc/src/megaco_performance.xml +++ b/lib/megaco/doc/src/megaco_performance.xml @@ -50,9 +50,15 @@ of these configurations for each codec. The figures presented are the average of all used messages.</p> - <p>For comparison, also included are performance figures - where the flex driver was built as <c>non-reentrant</c> flex - (figures within parenthesis). </p> + <p>For comparison, also included are first, performance figures with + megaco (including the measurement software) and asn1 applications + hipe-compiled (second figure in the time columns, note that per bin + decode had some issues so those figures are not included), and second, + performance figures where the flex driver was built as + <c>non-reentrant</c> flex + (third figure in the time columns, + only valid for text codecs using the flex-scanner, + figures within parenthesis). </p> <table> <row> @@ -67,122 +73,122 @@ <row> <cell align="left" valign="middle">pretty</cell> <cell align="right" valign="middle">336</cell> - <cell align="right" valign="middle">22</cell> - <cell align="right" valign="middle">76</cell> - <cell align="right" valign="middle">98</cell> + <cell align="right" valign="middle">20 / 13</cell> + <cell align="right" valign="middle">75 / 40</cell> + <cell align="right" valign="middle">95 / 53</cell> </row> <row> <cell align="left" valign="middle">pretty [flex]</cell> <cell align="right" valign="middle">336</cell> - <cell align="right" valign="middle">22 (22)</cell> - <cell align="right" valign="middle">41 (40)</cell> - <cell align="right" valign="middle">63 (62)</cell> + <cell align="right" valign="middle">20 / 13 / 20</cell> + <cell align="right" valign="middle">39 / 33 / 38</cell> + <cell align="right" valign="middle">59 / 46 / 58</cell> </row> <!-- COMPACT --> <row> <cell align="left" valign="middle">compact</cell> <cell align="right" valign="middle">181</cell> - <cell align="right" valign="middle">19</cell> - <cell align="right" valign="middle">63</cell> - <cell align="right" valign="middle">82</cell> + <cell align="right" valign="middle">17 / 10</cell> + <cell align="right" valign="middle">62 / 35</cell> + <cell align="right" valign="middle">79 / 45</cell> </row> <row> <cell align="left" valign="middle">compact [flex]</cell> <cell align="right" valign="middle">181</cell> - <cell align="right" valign="middle">19 (19)</cell> - <cell align="right" valign="middle">38 (36)</cell> - <cell align="right" valign="middle">57 (55)</cell> + <cell align="right" valign="middle">17 / 10 / 17</cell> + <cell align="right" valign="middle">37 / 31 / 36</cell> + <cell align="right" valign="middle">54 / 41 / 53</cell> </row> <!-- PER --> <row> <cell align="left" valign="middle">per bin</cell> <cell align="right" valign="middle">91</cell> - <cell align="right" valign="middle">63</cell> - <cell align="right" valign="middle">69</cell> - <cell align="right" valign="middle">132</cell> + <cell align="right" valign="middle">60 / 29</cell> + <cell align="right" valign="middle">64 / -</cell> + <cell align="right" valign="middle">124 / -</cell> </row> <row> <cell align="left" valign="middle">per bin [driver]</cell> <cell align="right" valign="middle">91</cell> - <cell align="right" valign="middle">43</cell> - <cell align="right" valign="middle">45</cell> - <cell align="right" valign="middle">88</cell> + <cell align="right" valign="middle">39 / 24</cell> + <cell align="right" valign="middle">42 / 26</cell> + <cell align="right" valign="middle">81 / 50</cell> </row> <row> <cell align="left" valign="middle">per bin [native]</cell> <cell align="right" valign="middle">91</cell> - <cell align="right" valign="middle">47</cell> - <cell align="right" valign="middle">51</cell> - <cell align="right" valign="middle">99</cell> + <cell align="right" valign="middle">45 / 21</cell> + <cell align="right" valign="middle">48 / -</cell> + <cell align="right" valign="middle">93 / -</cell> </row> <row> <cell align="left" valign="middle">per bin [driver,native]</cell> <cell align="right" valign="middle">91</cell> - <cell align="right" valign="middle">26</cell> - <cell align="right" valign="middle">29</cell> - <cell align="right" valign="middle">55</cell> + <cell align="right" valign="middle">25 / 15</cell> + <cell align="right" valign="middle">27 / 18</cell> + <cell align="right" valign="middle">52 / 33</cell> </row> <!-- BER --> <row> <cell align="left" valign="middle">ber bin</cell> <cell align="right" valign="middle">165</cell> - <cell align="right" valign="middle">35</cell> - <cell align="right" valign="middle">42</cell> - <cell align="right" valign="middle">77</cell> + <cell align="right" valign="middle">32 / 19</cell> + <cell align="right" valign="middle">38 / 21</cell> + <cell align="right" valign="middle">70 / 40</cell> </row> <row> <cell align="left" valign="middle">ber bin [driver]</cell> <cell align="right" valign="middle">165</cell> - <cell align="right" valign="middle">35</cell> - <cell align="right" valign="middle">37</cell> - <cell align="right" valign="middle">72</cell> + <cell align="right" valign="middle">32 / 19</cell> + <cell align="right" valign="middle">33 / 20</cell> + <cell align="right" valign="middle">65 / 39</cell> </row> <row> <cell align="left" valign="middle">ber bin [native]</cell> <cell align="right" valign="middle">165</cell> - <cell align="right" valign="middle">19</cell> - <cell align="right" valign="middle">26</cell> - <cell align="right" valign="middle">45</cell> + <cell align="right" valign="middle">17 / 11</cell> + <cell align="right" valign="middle">25 / 13</cell> + <cell align="right" valign="middle">42 / 24</cell> </row> <row> <cell align="left" valign="middle">ber bin [driver,native]</cell> <cell align="right" valign="middle">165</cell> - <cell align="right" valign="middle">19</cell> - <cell align="right" valign="middle">20</cell> - <cell align="right" valign="middle">39</cell> + <cell align="right" valign="middle">17 / 11</cell> + <cell align="right" valign="middle">17 / 12</cell> + <cell align="right" valign="middle">34 / 23</cell> </row> <!-- ERLANG --> <row> <cell align="left" valign="middle">erl_dist</cell> <cell align="right" valign="middle">875</cell> - <cell align="right" valign="middle">5</cell> - <cell align="right" valign="middle">10</cell> - <cell align="right" valign="middle">15</cell> + <cell align="right" valign="middle">5 / 5</cell> + <cell align="right" valign="middle">10 / 10</cell> + <cell align="right" valign="middle">15 / 15</cell> </row> <row> <cell align="left" valign="middle">erl_dist [megaco_compressed]</cell> <cell align="right" valign="middle">405</cell> - <cell align="right" valign="middle">6</cell> - <cell align="right" valign="middle">7</cell> - <cell align="right" valign="middle">13</cell> + <cell align="right" valign="middle">6 / 4</cell> + <cell align="right" valign="middle">7 / 4</cell> + <cell align="right" valign="middle">13 / 8</cell> </row> <row> <cell align="left" valign="middle">erl_dist [compressed]</cell> <cell align="right" valign="middle">345</cell> - <cell align="right" valign="middle">86</cell> - <cell align="right" valign="middle">21</cell> - <cell align="right" valign="middle">107</cell> + <cell align="right" valign="middle">47 / 47</cell> + <cell align="right" valign="middle">20 / 20</cell> + <cell align="right" valign="middle">67 / 67</cell> </row> <row> <cell align="left" valign="middle">erl_dist [megaco_compressed,compressed]</cell> <cell align="right" valign="middle">200</cell> - <cell align="right" valign="middle">71</cell> - <cell align="right" valign="middle">12</cell> - <cell align="right" valign="middle">83</cell> + <cell align="right" valign="middle">34 / 33</cell> + <cell align="right" valign="middle">11 / 9</cell> + <cell align="right" valign="middle">45 / 42</cell> </row> <tcaption>Codec performance</tcaption> @@ -201,8 +207,8 @@ <p>When running SMP erlang on a multi-core machine the "throughput" is significantly higher. The mstone1 test is an extreme test, but it shows what is gained by using the reentrant flex-scanner. </p> - <image file="mstone1.gif"> - <icaption>MStone1 with mstone1.sh -d flex -s 8</icaption> + <image file="mstone1.jpg"> + <icaption>MStone1 with mstone1.sh -d flex -s 4</icaption> </image> </section> @@ -276,10 +282,10 @@ MEGACO/1 [124.124.124.222] <section> <title>Setup</title> <p>The measurements has been performed on a - Dell PowerEdge 1950iii with - 2* Intel Xeon L5430 @ 2.66 GHz, with 8 GB memory and - running SLES 10 SP2 x86_64, kernel 2.6.16.60-0.34-smp. - Software versions was open source OTP R13B and megaco-3.11.</p> + HP xw4600 Workstation with + a Intel(R) Core(TM)2 Quad CPU Q9550 @ 2.83GHz, with 4 GB memory and + running Ubuntu 10.04 x86_64, kernel 2.6.32-22-generic. + Software versions was open source OTP R13B04 (megaco-3.14).</p> </section> <section> @@ -302,7 +308,7 @@ MEGACO/1 [124.124.124.222] to our fastest text encoder (compact). </p> </item> <item> - <p>our fastest binary decoder (ber) is about 47% (44%) faster than our + <p>our fastest binary decoder (ber) is about 54% (61%) faster than our fastest text decoder (compact). </p> </item> </list> diff --git a/lib/megaco/doc/src/megaco_user.xml b/lib/megaco/doc/src/megaco_user.xml index 7332fa684d..7987ed3392 100644 --- a/lib/megaco/doc/src/megaco_user.xml +++ b/lib/megaco/doc/src/megaco_user.xml @@ -504,7 +504,7 @@ protocol_version() = integer() ]]></code> not, is also included in the <c><![CDATA[UserReply]]></c>. </p> <p>The <c><![CDATA[ReplyData]]></c> defaults to <c><![CDATA[megaco:lookup(ConnHandle, reply_data)]]></c>, - but may be explicitely overridden by a + but may be explicitly overridden by a <c><![CDATA[megaco:cast/3]]></c> option in order to forward info about the calling context of the originating process.</p> <p>At <c><![CDATA[success()]]></c>, the <c><![CDATA[UserReply]]></c> either contains:</p> diff --git a/lib/megaco/doc/src/mstone1-s8flex.log b/lib/megaco/doc/src/mstone1-s8flex.log deleted file mode 100644 index d9d28399f3..0000000000 --- a/lib/megaco/doc/src/mstone1-s8flex.log +++ /dev/null @@ -1,234 +0,0 @@ - ---------------------------------------------- -Factor 01 - -erl -noshell -smp +S 8 -pa /ldisk/bmk/pgm/otp-r13b-m311p08-re/lib/erlang/lib/megaco-3.11/examples/meas -s megaco_codec_mstone1 start_flex time_test 01 -s init stop - -OS: unix-linux: 2.6.16 -System architecture: x86_64-unknown-linux-gnu -OTP release: R13B -System version: Erlang R13B (erts-5.7.1) [source] [64-bit] [smp:8:8] [rq:8] [async-threads:0] [hipe] [kernel-poll:false] -Heap type: private -Global heap size: 0 -Thread support: true -Thread pool size: 0 -Process limit: 32768 -SMP support: true -Num schedulers: 8 -Scheduler bindings: {0,1,4,5,2,3,6,7} -Scheduler bind type: thread_no_node_processor_spread -Cpu topology: [{processor,[{core,{logical,0}},{core,{logical,4}},{core,{logical,2}},{core,{logical,6}}]},{processor,[{core,{logical,1}},{core,{logical,5}},{core,{logical,3}},{core,{logical,7}}]}] -Megaco version: megaco-3.11-p08 -ASN.1 version: 1.6.10 - - * starting runners [16] ................ done - * await runners ready ................ done - * now snooze - * release them - -16 runners -Runner heap size data: - Min: 75025 - Max: 1682835 - Avg: 582577 -Runner reductions data: - Min: 927126711 - Max: 5292487523 - Avg: 1929935038 - -MStone: 63283727 - ---------------------------------------------- -Factor 02 - -erl -noshell -smp +S 8 -pa /ldisk/bmk/pgm/otp-r13b-m311p08-re/lib/erlang/lib/megaco-3.11/examples/meas -s megaco_codec_mstone1 start_flex time_test 02 -s init stop - -OS: unix-linux: 2.6.16 -System architecture: x86_64-unknown-linux-gnu -OTP release: R13B -System version: Erlang R13B (erts-5.7.1) [source] [64-bit] [smp:8:8] [rq:8] [async-threads:0] [hipe] [kernel-poll:false] -Heap type: private -Global heap size: 0 -Thread support: true -Thread pool size: 0 -Process limit: 32768 -SMP support: true -Num schedulers: 8 -Scheduler bindings: {0,1,4,5,2,3,6,7} -Scheduler bind type: thread_no_node_processor_spread -Cpu topology: [{processor,[{core,{logical,0}},{core,{logical,4}},{core,{logical,2}},{core,{logical,6}}]},{processor,[{core,{logical,1}},{core,{logical,5}},{core,{logical,3}},{core,{logical,7}}]}] -Megaco version: megaco-3.11-p08 -ASN.1 version: 1.6.10 - - * starting runners [32] ................................ done - * await runners ready ................................ done - * now snooze - * release them - -32 runners -Runner heap size data: - Min: 75025 - Max: 1346269 - Avg: 388569 -Runner reductions data: - Min: 645498054 - Max: 2774469009 - Avg: 943407719 - -MStone: 61441342 - ---------------------------------------------- -Factor 04 - -erl -noshell -smp +S 8 -pa /ldisk/bmk/pgm/otp-r13b-m311p08-re/lib/erlang/lib/megaco-3.11/examples/meas -s megaco_codec_mstone1 start_flex time_test 04 -s init stop - -OS: unix-linux: 2.6.16 -System architecture: x86_64-unknown-linux-gnu -OTP release: R13B -System version: Erlang R13B (erts-5.7.1) [source] [64-bit] [smp:8:8] [rq:8] [async-threads:0] [hipe] [kernel-poll:false] -Heap type: private -Global heap size: 0 -Thread support: true -Thread pool size: 0 -Process limit: 32768 -SMP support: true -Num schedulers: 8 -Scheduler bindings: {0,1,4,5,2,3,6,7} -Scheduler bind type: thread_no_node_processor_spread -Cpu topology: [{processor,[{core,{logical,0}},{core,{logical,4}},{core,{logical,2}},{core,{logical,6}}]},{processor,[{core,{logical,1}},{core,{logical,5}},{core,{logical,3}},{core,{logical,7}}]}] -Megaco version: megaco-3.11-p08 -ASN.1 version: 1.6.10 - - * starting runners [64] ................................................................ done - * await runners ready ................................................................ done - * now snooze - * release them - -64 runners -Runner heap size data: - Min: 75025 - Max: 1682835 - Avg: 462690 -Runner reductions data: - Min: 395464832 - Max: 916378232 - Avg: 507760636 - -MStone: 66958216 - ---------------------------------------------- -Factor 08 - -erl -noshell -smp +S 8 -pa /ldisk/bmk/pgm/otp-r13b-m311p08-re/lib/erlang/lib/megaco-3.11/examples/meas -s megaco_codec_mstone1 start_flex time_test 08 -s init stop - -OS: unix-linux: 2.6.16 -System architecture: x86_64-unknown-linux-gnu -OTP release: R13B -System version: Erlang R13B (erts-5.7.1) [source] [64-bit] [smp:8:8] [rq:8] [async-threads:0] [hipe] [kernel-poll:false] -Heap type: private -Global heap size: 0 -Thread support: true -Thread pool size: 0 -Process limit: 32768 -SMP support: true -Num schedulers: 8 -Scheduler bindings: {0,1,4,5,2,3,6,7} -Scheduler bind type: thread_no_node_processor_spread -Cpu topology: [{processor,[{core,{logical,0}},{core,{logical,4}},{core,{logical,2}},{core,{logical,6}}]},{processor,[{core,{logical,1}},{core,{logical,5}},{core,{logical,3}},{core,{logical,7}}]}] -Megaco version: megaco-3.11-p08 -ASN.1 version: 1.6.10 - - * starting runners [128] ................................................................................................................................ done - * await runners ready ................................................................................................................................ done - * now snooze - * release them - -128 runners -Runner heap size data: - Min: 75025 - Max: 832040 - Avg: 173900 -Runner reductions data: - Min: 236710819 - Max: 457961244 - Avg: 269562568 - -MStone: 72098418 - ---------------------------------------------- -Factor 16 - -erl -noshell -smp +S 8 -pa /ldisk/bmk/pgm/otp-r13b-m311p08-re/lib/erlang/lib/megaco-3.11/examples/meas -s megaco_codec_mstone1 start_flex time_test 16 -s init stop - -OS: unix-linux: 2.6.16 -System architecture: x86_64-unknown-linux-gnu -OTP release: R13B -System version: Erlang R13B (erts-5.7.1) [source] [64-bit] [smp:8:8] [rq:8] [async-threads:0] [hipe] [kernel-poll:false] -Heap type: private -Global heap size: 0 -Thread support: true -Thread pool size: 0 -Process limit: 32768 -SMP support: true -Num schedulers: 8 -Scheduler bindings: {0,1,4,5,2,3,6,7} -Scheduler bind type: thread_no_node_processor_spread -Cpu topology: [{processor,[{core,{logical,0}},{core,{logical,4}},{core,{logical,2}},{core,{logical,6}}]},{processor,[{core,{logical,1}},{core,{logical,5}},{core,{logical,3}},{core,{logical,7}}]}] -Megaco version: megaco-3.11-p08 -ASN.1 version: 1.6.10 - - * starting runners [256] ................................................................................................................................................................................................................................................................ done - * await runners ready ................................................................................................................................................................................................................................................................ done - * now snooze - * release them - -256 runners -Runner heap size data: - Min: 75025 - Max: 317811 - Avg: 131652 -Runner reductions data: - Min: 134104991 - Max: 163429204 - Avg: 142654707 - -MStone: 77139535 - ---------------------------------------------- -Factor 32 - -erl -noshell -smp +S 8 -pa /ldisk/bmk/pgm/otp-r13b-m311p08-re/lib/erlang/lib/megaco-3.11/examples/meas -s megaco_codec_mstone1 start_flex time_test 32 -s init stop - -OS: unix-linux: 2.6.16 -System architecture: x86_64-unknown-linux-gnu -OTP release: R13B -System version: Erlang R13B (erts-5.7.1) [source] [64-bit] [smp:8:8] [rq:8] [async-threads:0] [hipe] [kernel-poll:false] -Heap type: private -Global heap size: 0 -Thread support: true -Thread pool size: 0 -Process limit: 32768 -SMP support: true -Num schedulers: 8 -Scheduler bindings: {0,1,4,5,2,3,6,7} -Scheduler bind type: thread_no_node_processor_spread -Cpu topology: [{processor,[{core,{logical,0}},{core,{logical,4}},{core,{logical,2}},{core,{logical,6}}]},{processor,[{core,{logical,1}},{core,{logical,5}},{core,{logical,3}},{core,{logical,7}}]}] -Megaco version: megaco-3.11-p08 -ASN.1 version: 1.6.10 - - * starting runners [512] ................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................ done - * await runners ready ................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................ done - * now snooze - * release them - -512 runners -Runner heap size data: - Min: 75025 - Max: 196418 - Avg: 107328 -Runner reductions data: - Min: 71186547 - Max: 74170110 - Avg: 72380653 - -MStone: 78820851 diff --git a/lib/megaco/doc/src/mstone1.gif b/lib/megaco/doc/src/mstone1.gif Binary files differdeleted file mode 100644 index 54c9c5514c..0000000000 --- a/lib/megaco/doc/src/mstone1.gif +++ /dev/null diff --git a/lib/megaco/doc/src/mstone1.jpg b/lib/megaco/doc/src/mstone1.jpg Binary files differindex b417429a08..3edc65faf1 100644 --- a/lib/megaco/doc/src/mstone1.jpg +++ b/lib/megaco/doc/src/mstone1.jpg diff --git a/lib/megaco/doc/src/mstone1.png b/lib/megaco/doc/src/mstone1.png Binary files differdeleted file mode 100644 index 19af210abc..0000000000 --- a/lib/megaco/doc/src/mstone1.png +++ /dev/null diff --git a/lib/megaco/doc/src/mstone1.ps b/lib/megaco/doc/src/mstone1.ps deleted file mode 100644 index 6436a4eb43..0000000000 --- a/lib/megaco/doc/src/mstone1.ps +++ /dev/null @@ -1,1959 +0,0 @@ -%!PS-Adobe-3.0 -%%Creator: GIMP PostScript file plugin V 1.17 by Peter Kirchgessner -%%Title: mstone1_html_m5496b992.ps -%%CreationDate: Fri May 29 19:07:25 2009 -%%DocumentData: Clean7Bit -%%LanguageLevel: 2 -%%Pages: 1 -%%BoundingBox: 14 14 476 247 -%%EndComments -%%BeginProlog -% Use own dictionary to avoid conflicts -10 dict begin -%%EndProlog -%%Page: 1 1 -% Translate for offset -14.173228346456694 14.173228346456694 translate -% Translate to begin of first scanline -0 231.99920747433686 translate -460.99842519685041 -231.99920747433686 scale -% Image geometry -461 232 8 -% Transformation matrix -[ 461 0 0 232 0 0 ] -% Strings to hold RGB-samples per scanline -/rstr 461 string def -/gstr 461 string def -/bstr 461 string def -{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop} -{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop} -{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop} -true 3 -%%BeginData: 120502 ASCII Bytes -colorimage -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -i;[-^"<[I>jo>>[s!S-Pn#nhl!"q57bl%G=s7lKks8;orq>UEis7ZKkpAapfqu?Nmr:^0\rj;e) -s8Dutrr<#nq!DD]s0Gl?!Ao]1s8;oe!<;Hd"Sr)ls7>sarVlfr/b/l@q#CBds82ck([qD(r;Z+- -8G3#_q>X&-q#CBlrVZ]fs7lWkrV6<jq"ssfrrVrprVcaFr<)rsrr)lpo`#!n$31)/s8VZin5BJi -oDZ*k&-j;?o`+scYV-/(\,61)<Vugjs8VP@2$sI+9X"<ms7ZKmo_\Zn>9<i*IeWm8s8W#ss6a>7 -!'%(Ss5mc1$9F^WqXX[`s7QE7?l9"V-$I''!:^$grVccn!WW2js8VWhoDeR_rsA5qr;V'f!%3Qh -rVnG1s8W&:BG^ja+`,[)rrEc4s7u]mq>Wh_s8Vrqr;ZWnp](3as8)ckq>^KXrr35rs8Vlns8W)t -ruq.6s7?$[s8VurqZ$9hs7--bmf3=ap\k-lp1<7`r;Zfpir=N~> -i;[-^"<[I>jo>>[s!S-Pn#nhl!"q57bl%G=s7lKks8;orq>UEis7ZKkpAapfqu?Nmr:^0\rj;e) -s8Dutrr<#nq!DD]s0Gl?!Ao]1s8;oe!<;Hd"Sr)ls7>sarVlfr/b/l@q#CBds82ck([qD(r;Z+- -8G3#_q>X&-q#CBlrVZ]fs7lWkrV6<jq"ssfrrVrprVcaFr<)rsrr)lpo`#!n$31)/s8VZin5BJi -oDZ*k&-j;?o`+scYV-/(\,61)<Vugjs8VP@2$sI+9X"<ms7ZKmo_\Zn>9<i*IeWm8s8W#ss6a>7 -!'%(Ss5mc1$9F^WqXX[`s7QE7?l9"V-$I''!:^$grVccn!WW2js8VWhoDeR_rsA5qr;V'f!%3Qh -rVnG1s8W&:BG^ja+`,[)rrEc4s7u]mq>Wh_s8Vrqr;ZWnp](3as8)ckq>^KXrr35rs8Vlns8W)t -ruq.6s7?$[s8VurqZ$9hs7--bmf3=ap\k-lp1<7`r;Zfpir=N~> -i;[-^"<[I>jo>>[s!S-Pn#nhl!"q57bl%G=s7lKks8;orq>UEis7ZKkpAapfqu?Nmr:^0\rj;e) -s8Dutrr<#nq!DD]s0Gl?!Ao]1s8;oe!<;Hd"Sr)ls7>sarVlfr/b/l@q#CBds82ck([qD(r;Z+- -8G3#_q>X&-q#CBlrVZ]fs7lWkrV6<jq"ssfrrVrprVcaFr<)rsrr)lpo`#!n$31)/s8VZin5BJi -oDZ*k&-j;?o`+scYV-/(\,61)<Vugjs8VP@2$sI+9X"<ms7ZKmo_\Zn>9<i*IeWm8s8W#ss6a>7 -!'%(Ss5mc1$9F^WqXX[`s7QE7?l9"V-$I''!:^$grVccn!WW2js8VWhoDeR_rsA5qr;V'f!%3Qh -rVnG1s8W&:BG^ja+`,[)rrEc4s7u]mq>Wh_s8Vrqr;ZWnp](3as8)ckq>^KXrr35rs8Vlns8W)t -ruq.6s7?$[s8VurqZ$9hs7--bmf3=ap\k-lp1<7`r;Zfpir=N~> -iVtA&rr<bBqu6Wds4%SZs+<S^q"W^NJ3s8@meQb[r9s[crVuors69R`q#::FqZ$Qjrr<#ks/l_1 -r;Z`qs8N&ns8Pa:s7KNEj7gnuGk1l7O91hXnc8^Ws6ose')2G)!<<)is8VZas8VrqrrE)krVmPV -&W6Sfs*kU(s7G^Ys8;ors8V]hrsAN$rqZTir;ZforVm9("8i,tnGE7bp'gKjs%rUhq>]s9#70bt -s'(TAs2e'#me,NGYlD]_]Dqa-s8)]oRic.Ls6/p>1H44gs7ZKls7'<Ae,7KeMuWhJs7>OU'qaXY -Q!44a2h^2\T3:=UruCM-s-G.0iqhZ[?qLA7s8VoprVuI#kl(P[k5Y)Prr`3!o'ZMW0P!u3s56>% -pAY*cs7lVu-^WlnhTC"&s7lX)XnMbos8C%?!<<)ts8N&js8VQes8)]o"nMKhs7,aYrs/&nq"+Oc -qY^?m%efr!rr;lqo()MSr;ZHQrr3?"s8C2KpAP$krq5=OJ,~> -iVtA&rr<bBqu6Wds4%SZs+<S^q"W^NJ3s8@meQb[r9s[crVuors69R`q#::FqZ$Qjrr<#ks/l_1 -r;Z`qs8N&ns8Pa:s7KNEj7gnuGk1l7O91hXnc8^Ws6ose')2G)!<<)is8VZas8VrqrrE)krVmPV -&W6Sfs*kU(s7G^Ys8;ors8V]hrsAN$rqZTir;ZforVm9("8i,tnGE7bp'gKjs%rUhq>]s9#70bt -s'(TAs2e'#me,NGYlD]_]Dqa-s8)]oRic.Ls6/p>1H44gs7ZKls7'<Ae,7KeMuWhJs7>OU'qaXY -Q!44a2h^2\T3:=UruCM-s-G.0iqhZ[?qLA7s8VoprVuI#kl(P[k5Y)Prr`3!o'ZMW0P!u3s56>% -pAY*cs7lVu-^WlnhTC"&s7lX)XnMbos8C%?!<<)ts8N&js8VQes8)]o"nMKhs7,aYrs/&nq"+Oc -qY^?m%efr!rr;lqo()MSr;ZHQrr3?"s8C2KpAP$krq5=OJ,~> -iVtA&rr<bBqu6Wds4%SZs+<S^q"W^NJ3s8@meQb[r9s[crVuors69R`q#::FqZ$Qjrr<#ks/l_1 -r;Z`qs8N&ns8Pa:s7KNEj7gnuGk1l7O91hXnc8^Ws6ose')2G)!<<)is8VZas8VrqrrE)krVmPV -&W6Sfs*kU(s7G^Ys8;ors8V]hrsAN$rqZTir;ZforVm9("8i,tnGE7bp'gKjs%rUhq>]s9#70bt -s'(TAs2e'#me,NGYlD]_]Dqa-s8)]oRic.Ls6/p>1H44gs7ZKls7'<Ae,7KeMuWhJs7>OU'qaXY -Q!44a2h^2\T3:=UruCM-s-G.0iqhZ[?qLA7s8VoprVuI#kl(P[k5Y)Prr`3!o'ZMW0P!u3s56>% -pAY*cs7lVu-^WlnhTC"&s7lX)XnMbos8C%?!<<)ts8N&js8VQes8)]o"nMKhs7,aYrs/&nq"+Oc -qY^?m%efr!rr;lqo()MSr;ZHQrr3?"s8C2KpAP$krq5=OJ,~> -iVsMdrr>bfrr;ors%6/hq@)lhn,E=ko(;q^s8)9bru_14rVuWlqZ$Tcs7cE_s7lWorV?Kn!&)Lr -r;Z`qs8N#t.'ZYLmeleYs82cG/-#GF7K>jVr"Sl)p@SC]pAb'j)>O7*s8;osp%\Od(]aO7s8DZk -s)AFjq8OP?nGiIerU]p`s5<nV%JTntp\jaaoDejOs7Q9grs&E(qu?Zqqu6UQ!<;cmo`+C[rV/$r -$Ma5lo)J[grSmnXnR7@Ts8Rmls8W)unGfm(c27P*s8;QiK1>k?q"Odf!:]se$J-*hkPtP]s-Irp -rr4S:s+4_[rVuTks7u]ap]&\`dIcf*s7?9jli@"`l2UY\rrE)lrVuoos8Dull2:Q%q#:`hrr;HX -!WVlnnGi%.&^(.JoDeF^rVua+<^-N_)#aJ;:`9!,nG`I\s8V`hs8VZimf2kXs7QBk(ARe,qu?Hk -s7lWks8V9^lhUDWs8)ZfqYq*#s8Duis8V]j>.4G(r;ZHMs*t~> -iVsMdrr>bfrr;ors%6/hq@)lhn,E=ko(;q^s8)9bru_14rVuWlqZ$Tcs7cE_s7lWorV?Kn!&)Lr -r;Z`qs8N#t.'ZYLmeleYs82cG/-#GF7K>jVr"Sl)p@SC]pAb'j)>O7*s8;osp%\Od(]aO7s8DZk -s)AFjq8OP?nGiIerU]p`s5<nV%JTntp\jaaoDejOs7Q9grs&E(qu?Zqqu6UQ!<;cmo`+C[rV/$r -$Ma5lo)J[grSmnXnR7@Ts8Rmls8W)unGfm(c27P*s8;QiK1>k?q"Odf!:]se$J-*hkPtP]s-Irp -rr4S:s+4_[rVuTks7u]ap]&\`dIcf*s7?9jli@"`l2UY\rrE)lrVuoos8Dull2:Q%q#:`hrr;HX -!WVlnnGi%.&^(.JoDeF^rVua+<^-N_)#aJ;:`9!,nG`I\s8V`hs8VZimf2kXs7QBk(ARe,qu?Hk -s7lWks8V9^lhUDWs8)ZfqYq*#s8Duis8V]j>.4G(r;ZHMs*t~> -iVsMdrr>bfrr;ors%6/hq@)lhn,E=ko(;q^s8)9bru_14rVuWlqZ$Tcs7cE_s7lWorV?Kn!&)Lr -r;Z`qs8N#t.'ZYLmeleYs82cG/-#GF7K>jVr"Sl)p@SC]pAb'j)>O7*s8;osp%\Od(]aO7s8DZk -s)AFjq8OP?nGiIerU]p`s5<nV%JTntp\jaaoDejOs7Q9grs&E(qu?Zqqu6UQ!<;cmo`+C[rV/$r -$Ma5lo)J[grSmnXnR7@Ts8Rmls8W)unGfm(c27P*s8;QiK1>k?q"Odf!:]se$J-*hkPtP]s-Irp -rr4S:s+4_[rVuTks7u]ap]&\`dIcf*s7?9jli@"`l2UY\rrE)lrVuoos8Dull2:Q%q#:`hrr;HX -!WVlnnGi%.&^(.JoDeF^rVua+<^-N_)#aJ;:`9!,nG`I\s8V`hs8VZimf2kXs7QBk(ARe,qu?Hk -s7lWks8V9^lhUDWs8)ZfqYq*#s8Duis8V]j>.4G(r;ZHMs*t~> -hu>A1^]NWns8UpUgAq7!D=RZ+n,!(^!XA]1qu=Z&&kLmDs7cu%,760Ys8Mqh.K^9HrVmB&!W;ur -s8W)uqu8sss8)`p./i`:k5bP^F=I8:JGoQKrrBGN!B&+$!!!$$s7QDa0-1[tp&>$ls6ose+nu"/ -/bh7Ss8VWhSfo'pRf<?bb<$_4_Z0Z5!j*[M9Z?]'s#p;_qu?Zqs6T4S!;$6im/Qq^potP)!<<&j -s7H?hs61U)ru9Php&!_is76-gs6(<As6+D9(1oI>r(2A7rr4,.p&FgUs7bF]s8W#ss6)5Xs7uTm -rr5gAlMpMVrr;]_rr3@+L]@DRs8Mrjmf*:brsIui$2sc%!!WE/kl(Miq=4LTs8NAjs8VcZ)?'S! -k5SDNs8)cqpAb*knc&U.$0_Efp?`1<!;ZQmndM'D"XDHk*"4[RqY'shXY^#%PlLafMEq4nc^?0] -1u/'/ruAa=*'MXCrs[:"2Xh6@s6fle']f;88cSDXs8DoWs*t~> -hu>A1^]NWns8UpUgAq7!D=RZ+n,!(^!XA]1qu=Z&&kLmDs7cu%,760Ys8Mqh.K^9HrVmB&!W;ur -s8W)uqu8sss8)`p./i`:k5bP^F=I8:JGoQKrrBGN!B&+$!!!$$s7QDa0-1[tp&>$ls6ose+nu"/ -/bh7Ss8VWhSfo'pRf<?bb<$_4_Z0Z5!j*[M9Z?]'s#p;_qu?Zqs6T4S!;$6im/Qq^potP)!<<&j -s7H?hs61U)ru9Php&!_is76-gs6(<As6+D9(1oI>r(2A7rr4,.p&FgUs7bF]s8W#ss6)5Xs7uTm -rr5gAlMpMVrr;]_rr3@+L]@DRs8Mrjmf*:brsIui$2sc%!!WE/kl(Miq=4LTs8NAjs8VcZ)?'S! -k5SDNs8)cqpAb*knc&U.$0_Efp?`1<!;ZQmndM'D"XDHk*"4[RqY'shXY^#%PlLafMEq4nc^?0] -1u/'/ruAa=*'MXCrs[:"2Xh6@s6fle']f;88cSDXs8DoWs*t~> -hu>A1^]NWns8UpUgAq7!D=RZ+n,!(^!XA]1qu=Z&&kLmDs7cu%,760Ys8Mqh.K^9HrVmB&!W;ur -s8W)uqu8sss8)`p./i`:k5bP^F=I8:JGoQKrrBGN!B&+$!!!$$s7QDa0-1[tp&>$ls6ose+nu"/ -/bh7Ss8VWhSfo'pRf<?bb<$_4_Z0Z5!j*[M9Z?]'s#p;_qu?Zqs6T4S!;$6im/Qq^potP)!<<&j -s7H?hs61U)ru9Php&!_is76-gs6(<As6+D9(1oI>r(2A7rr4,.p&FgUs7bF]s8W#ss6)5Xs7uTm -rr5gAlMpMVrr;]_rr3@+L]@DRs8Mrjmf*:brsIui$2sc%!!WE/kl(Miq=4LTs8NAjs8VcZ)?'S! -k5SDNs8)cqpAb*knc&U.$0_Efp?`1<!;ZQmndM'D"XDHk*"4[RqY'shXY^#%PlLafMEq4nc^?0] -1u/'/ruAa=*'MXCrs[:"2Xh6@s6fle']f;88cSDXs8DoWs*t~> -hu=Gls!)ggr:-(+q$-Q.*rnZciW&rUr<<3#HEe%,rPo\lq=jqll18LAq"DES`;\%HNq`SHrrN&t -rVuoss8MF/q#C?nh=psLqi"MGs(0mabZ+TBs764eh"6%KrVmE&q>^,f0WtH)25fU?s82Wls7ZKm -g(jo5kPtDYXuF;bc8V'gY9D$HaYCQorr?WSr*M;YrVm'""8i,to`"k0r"U.P+0tq?s5tW#rrM9X -s8V3\r6eJYq>V#urr3)e$M45qs%7iJs6<$gp=)Y:U&N7op@eO`s8V9^s7?8R6N@)]s8)a6Shg?n -N;qlVV)86&S*L%Rr;Zff)WLPbs8V3\s8)Quq#C<is8W#tmJd+jqGDJ:s8Duarr3c/s8R::cMu?[ -J,''*n,ND(g&M*Ms7#sd!s/<QFT2;3KeMlps8V`f"BX+<M?$H#s)'jms8&H8^])G=M>mQ_f_'Cq -8)j2O62:KF^+I@_as>1!!,:ots'SRus8Q(cqZ$@$pAb!hrr(pXJ,~> -hu=Gls!)ggr:-(+q$-Q.*rnZciW&rUr<<3#HEe%,rPo\lq=jqll18LAq"DES`;\%HNq`SHrrN&t -rVuoss8MF/q#C?nh=psLqi"MGs(0mabZ+TBs764eh"6%KrVmE&q>^,f0WtH)25fU?s82Wls7ZKm -g(jo5kPtDYXuF;bc8V'gY9D$HaYCQorr?WSr*M;YrVm'""8i,to`"k0r"U.P+0tq?s5tW#rrM9X -s8V3\r6eJYq>V#urr3)e$M45qs%7iJs6<$gp=)Y:U&N7op@eO`s8V9^s7?8R6N@)]s8)a6Shg?n -N;qlVV)86&S*L%Rr;Zff)WLPbs8V3\s8)Quq#C<is8W#tmJd+jqGDJ:s8Duarr3c/s8R::cMu?[ -J,''*n,ND(g&M*Ms7#sd!s/<QFT2;3KeMlps8V`f"BX+<M?$H#s)'jms8&H8^])G=M>mQ_f_'Cq -8)j2O62:KF^+I@_as>1!!,:ots'SRus8Q(cqZ$@$pAb!hrr(pXJ,~> -hu=Gls!)ggr:-(+q$-Q.*rnZciW&rUr<<3#HEe%,rPo\lq=jqll18LAq"DES`;\%HNq`SHrrN&t -rVuoss8MF/q#C?nh=psLqi"MGs(0mabZ+TBs764eh"6%KrVmE&q>^,f0WtH)25fU?s82Wls7ZKm -g(jo5kPtDYXuF;bc8V'gY9D$HaYCQorr?WSr*M;YrVm'""8i,to`"k0r"U.P+0tq?s5tW#rrM9X -s8V3\r6eJYq>V#urr3)e$M45qs%7iJs6<$gp=)Y:U&N7op@eO`s8V9^s7?8R6N@)]s8)a6Shg?n -N;qlVV)86&S*L%Rr;Zff)WLPbs8V3\s8)Quq#C<is8W#tmJd+jqGDJ:s8Duarr3c/s8R::cMu?[ -J,''*n,ND(g&M*Ms7#sd!s/<QFT2;3KeMlps8V`f"BX+<M?$H#s)'jms8&H8^])G=M>mQ_f_'Cq -8)j2O62:KF^+I@_as>1!!,:ots'SRus8Q(cqZ$@$pAb!hrr(pXJ,~> -i;ZpV!<8Drq>9\2SG36as8TND%g5M.s8N)mrr5.-s8)bi70!8hq"t*c#l4KZ`;fi:gFN=$s8N,t -s8Dutrr<#=.KBDCq#CBdq8EQds8Vid#64So&b,f+rr3>[%fcM.s7l3c-Ii%p"P4Ii$2+8s*:Npm -s*k`&s7u]p6.>E)s3!1t6+Hspp8p1ErrE&u"8*3)o)AZ'r<)rsrr;lkqu?]pr7;p=s8R?rs6g^& -s7Q0err<$rs8VNoqZ$![rt=f#s7H=ZWrK@ps8Du7!8?u:$NL#%oD\CPr9aO!$.f%Js7H0f!%,\^ -dO::Y"X1b_`$(]@q>]j^rrE)hs7cNm'CGer!<<*%!WWu9!<;9WrM:1ui;N[.m.^P[rr<!\!!!Er -qZ$?js7Gmgs6]jUp](9^nc/@cs-aGes7RD(rrE)os8N)us#ol^gA(^=!<;Wi38aE/p?a[3!WVfl -mg&CQs8E3"s7&%Vs8W&%2ZEi^lMpGI!8mbC!hKAas"VUpr;?TnjSs`~> -i;ZpV!<8Drq>9\2SG36as8TND%g5M.s8N)mrr5.-s8)bi70!8hq"t*c#l4KZ`;fi:gFN=$s8N,t -s8Dutrr<#=.KBDCq#CBdq8EQds8Vid#64So&b,f+rr3>[%fcM.s7l3c-Ii%p"P4Ii$2+8s*:Npm -s*k`&s7u]p6.>E)s3!1t6+Hspp8p1ErrE&u"8*3)o)AZ'r<)rsrr;lkqu?]pr7;p=s8R?rs6g^& -s7Q0err<$rs8VNoqZ$![rt=f#s7H=ZWrK@ps8Du7!8?u:$NL#%oD\CPr9aO!$.f%Js7H0f!%,\^ -dO::Y"X1b_`$(]@q>]j^rrE)hs7cNm'CGer!<<*%!WWu9!<;9WrM:1ui;N[.m.^P[rr<!\!!!Er -qZ$?js7Gmgs6]jUp](9^nc/@cs-aGes7RD(rrE)os8N)us#ol^gA(^=!<;Wi38aE/p?a[3!WVfl -mg&CQs8E3"s7&%Vs8W&%2ZEi^lMpGI!8mbC!hKAas"VUpr;?TnjSs`~> -i;ZpV!<8Drq>9\2SG36as8TND%g5M.s8N)mrr5.-s8)bi70!8hq"t*c#l4KZ`;fi:gFN=$s8N,t -s8Dutrr<#=.KBDCq#CBdq8EQds8Vid#64So&b,f+rr3>[%fcM.s7l3c-Ii%p"P4Ii$2+8s*:Npm -s*k`&s7u]p6.>E)s3!1t6+Hspp8p1ErrE&u"8*3)o)AZ'r<)rsrr;lkqu?]pr7;p=s8R?rs6g^& -s7Q0err<$rs8VNoqZ$![rt=f#s7H=ZWrK@ps8Du7!8?u:$NL#%oD\CPr9aO!$.f%Js7H0f!%,\^ -dO::Y"X1b_`$(]@q>]j^rrE)hs7cNm'CGer!<<*%!WWu9!<;9WrM:1ui;N[.m.^P[rr<!\!!!Er -qZ$?js7Gmgs6]jUp](9^nc/@cs-aGes7RD(rrE)os8N)us#ol^gA(^=!<;Wi38aE/p?a[3!WVfl -mg&CQs8E3"s7&%Vs8W&%2ZEi^lMpGI!8mbC!hKAas"VUpr;?TnjSs`~> -i;ZRO!rha,VZ*Y'q#:?oq>1$WrNT!/K`2#Prq?EUpAb0Z'`[_(s8DQf"98B(!!!*$!#,/'s7??i -s8Dutrr;l;1]$nHnFuq^^&YY=s7?3h')2D+s6]meqtC$iqYgNkr;Z@0r;['9"oeT&s8MlnruTZ) -'bKO-s76?n&-r7F!:^KhqXjgf&H;A3jo>5T!;uk'r<)rsrp]U\s6Tdbs6]:rrn7A3s8N*!s6K^b -q>]DNE:j/>mJ$YXmKijjpAaabs6q>Op%n]W!<<#k$iBl"s8VZinGgT1](Q*qs8VWc&`EKbqU6\Z -!:]RUs4J1drtY2*(ubMpo`"mk$3:)/s8V?`rVultrr38t,anQ0r:p<jrVo=_l&%7PpVo^Equ?<^ -s8N`"qXFOb!!!N=oDK$rm38#!TH`n#$2"8lknEpgq>UHps8;j)nFHSZ!"&]3!!*$!s8VQa#lai) -nc8[h)%HEAnbr=frW)uur;YkTDZ>J/s8;fp9=k!!rrDuXs*t~> -i;ZRO!rha,VZ*Y'q#:?oq>1$WrNT!/K`2#Prq?EUpAb0Z'`[_(s8DQf"98B(!!!*$!#,/'s7??i -s8Dutrr;l;1]$nHnFuq^^&YY=s7?3h')2D+s6]meqtC$iqYgNkr;Z@0r;['9"oeT&s8MlnruTZ) -'bKO-s76?n&-r7F!:^KhqXjgf&H;A3jo>5T!;uk'r<)rsrp]U\s6Tdbs6]:rrn7A3s8N*!s6K^b -q>]DNE:j/>mJ$YXmKijjpAaabs6q>Op%n]W!<<#k$iBl"s8VZinGgT1](Q*qs8VWc&`EKbqU6\Z -!:]RUs4J1drtY2*(ubMpo`"mk$3:)/s8V?`rVultrr38t,anQ0r:p<jrVo=_l&%7PpVo^Equ?<^ -s8N`"qXFOb!!!N=oDK$rm38#!TH`n#$2"8lknEpgq>UHps8;j)nFHSZ!"&]3!!*$!s8VQa#lai) -nc8[h)%HEAnbr=frW)uur;YkTDZ>J/s8;fp9=k!!rrDuXs*t~> -i;ZRO!rha,VZ*Y'q#:?oq>1$WrNT!/K`2#Prq?EUpAb0Z'`[_(s8DQf"98B(!!!*$!#,/'s7??i -s8Dutrr;l;1]$nHnFuq^^&YY=s7?3h')2D+s6]meqtC$iqYgNkr;Z@0r;['9"oeT&s8MlnruTZ) -'bKO-s76?n&-r7F!:^KhqXjgf&H;A3jo>5T!;uk'r<)rsrp]U\s6Tdbs6]:rrn7A3s8N*!s6K^b -q>]DNE:j/>mJ$YXmKijjpAaabs6q>Op%n]W!<<#k$iBl"s8VZinGgT1](Q*qs8VWc&`EKbqU6\Z -!:]RUs4J1drtY2*(ubMpo`"mk$3:)/s8V?`rVultrr38t,anQ0r:p<jrVo=_l&%7PpVo^Equ?<^ -s8N`"qXFOb!!!N=oDK$rm38#!TH`n#$2"8lknEpgq>UHps8;j)nFHSZ!"&]3!!*$!s8VQa#lai) -nc8[h)%HEAnbr=frW)uur;YkTDZ>J/s8;fp9=k!!rrDuXs*t~> -hu@6fqYsn^r],f2pC$Qlr;ZZoo`)`;r;ccirt=o&s8)a"r;Qcsrr;fps8)frnG`Idp%JF^rW2rs -rVuoss8C)%s8;QirV=&7VZ-Vis82WjqZ$<or;Qcls76$qs82lspAb-mpAY'qq>L*lq"k!i,P;$$ -<AiSg48AjU#Q"/es8Vrq"nqurr9=[irrE)os8N*!rr2pHr<)rsrr<#oqZ$Tfs8V<cs$L;rp\4si -rVuors7Q9[#QO?Iec5@Bk8aL$)uKX8o`#-hs8W"65kb,l2ZN[Sp](!_s0)d1q#::5qt:!h+m]1* -s8N*[email protected]"BoEY0ls7u]gs8;j*q"4NE-3*K7rVccqs7cQbs8NYkq>^KR -(]471s8VmuR/[+$p&F[a!;lcrs8?dlr]Y<$rrDrqs8N)urtG)5oD&@c!VcWo#4MQgs8;Wi!;ZWo -$3B\ss8!'"s8NPrrr3c)&afl"s7,ma`ZXe%I/X*FqC:.ps8:mVJ,~> -hu@6fqYsn^r],f2pC$Qlr;ZZoo`)`;r;ccirt=o&s8)a"r;Qcsrr;fps8)frnG`Idp%JF^rW2rs -rVuoss8C)%s8;QirV=&7VZ-Vis82WjqZ$<or;Qcls76$qs82lspAb-mpAY'qq>L*lq"k!i,P;$$ -<AiSg48AjU#Q"/es8Vrq"nqurr9=[irrE)os8N*!rr2pHr<)rsrr<#oqZ$Tfs8V<cs$L;rp\4si -rVuors7Q9[#QO?Iec5@Bk8aL$)uKX8o`#-hs8W"65kb,l2ZN[Sp](!_s0)d1q#::5qt:!h+m]1* -s8N*[email protected]"BoEY0ls7u]gs8;j*q"4NE-3*K7rVccqs7cQbs8NYkq>^KR -(]471s8VmuR/[+$p&F[a!;lcrs8?dlr]Y<$rrDrqs8N)urtG)5oD&@c!VcWo#4MQgs8;Wi!;ZWo -$3B\ss8!'"s8NPrrr3c)&afl"s7,ma`ZXe%I/X*FqC:.ps8:mVJ,~> -hu@6fqYsn^r],f2pC$Qlr;ZZoo`)`;r;ccirt=o&s8)a"r;Qcsrr;fps8)frnG`Idp%JF^rW2rs -rVuoss8C)%s8;QirV=&7VZ-Vis82WjqZ$<or;Qcls76$qs82lspAb-mpAY'qq>L*lq"k!i,P;$$ -<AiSg48AjU#Q"/es8Vrq"nqurr9=[irrE)os8N*!rr2pHr<)rsrr<#oqZ$Tfs8V<cs$L;rp\4si -rVuors7Q9[#QO?Iec5@Bk8aL$)uKX8o`#-hs8W"65kb,l2ZN[Sp](!_s0)d1q#::5qt:!h+m]1* -s8N*[email protected]"BoEY0ls7u]gs8;j*q"4NE-3*K7rVccqs7cQbs8NYkq>^KR -(]471s8VmuR/[+$p&F[a!;lcrs8?dlr]Y<$rrDrqs8N)urtG)5oD&@c!VcWo#4MQgs8;Wi!;ZWo -$3B\ss8!'"s8NPrrr3c)&afl"s7,ma`ZXe%I/X*FqC:.ps8:mVJ,~> -iVuRLrrE*!c4-6IhZ*3Js8Dutp](9kiY;Csmf3;>]Dqa,Z7GtT!;lfrrW)uu/@,<Uq>^*ep&Fgf -s7cQno_SUfjVRgop\Fif$G?05s"aTPs8VZhquH`r!rr2rrrW5s!<<)op/@des7u]frrMros8W#f -s+gd-o%O@us8P$^rr2pPo`$SRn,NBj5PP0Xs763i!WW,mrr;uupAb$es8;fpqu?]nat*Jo!"o84 -!"')5s7cNm?J6(ms'UW]rVrNjs82irrX.T`#6"2okSn.3s"pbPs8W)unc,-\YlF_&s8N&urr6/k -q>('@1\+qDq=Xd80DYPGpAap8%I<]as8;co!<3>us7H?kr;Qrjs7cT(rr30!s8Vfirr)it']T,l -$gIusp]'a_oY_[/q#::<qYpQqo`tNsaoJaJhZ!NVs8;fp!rr;trW)ZlnG`Lgqu8@Pr;S>F$MON! -rrW5ur;Qius8+jcq#BZi49#EVs8;iqs"]65cg^u/r=Ar$s8DunjSs`~> -iVuRLrrE*!c4-6IhZ*3Js8Dutp](9kiY;Csmf3;>]Dqa,Z7GtT!;lfrrW)uu/@,<Uq>^*ep&Fgf -s7cQno_SUfjVRgop\Fif$G?05s"aTPs8VZhquH`r!rr2rrrW5s!<<)op/@des7u]frrMros8W#f -s+gd-o%O@us8P$^rr2pPo`$SRn,NBj5PP0Xs763i!WW,mrr;uupAb$es8;fpqu?]nat*Jo!"o84 -!"')5s7cNm?J6(ms'UW]rVrNjs82irrX.T`#6"2okSn.3s"pbPs8W)unc,-\YlF_&s8N&urr6/k -q>('@1\+qDq=Xd80DYPGpAap8%I<]as8;co!<3>us7H?kr;Qrjs7cT(rr30!s8Vfirr)it']T,l -$gIusp]'a_oY_[/q#::<qYpQqo`tNsaoJaJhZ!NVs8;fp!rr;trW)ZlnG`Lgqu8@Pr;S>F$MON! -rrW5ur;Qius8+jcq#BZi49#EVs8;iqs"]65cg^u/r=Ar$s8DunjSs`~> -iVuRLrrE*!c4-6IhZ*3Js8Dutp](9kiY;Csmf3;>]Dqa,Z7GtT!;lfrrW)uu/@,<Uq>^*ep&Fgf -s7cQno_SUfjVRgop\Fif$G?05s"aTPs8VZhquH`r!rr2rrrW5s!<<)op/@des7u]frrMros8W#f -s+gd-o%O@us8P$^rr2pPo`$SRn,NBj5PP0Xs763i!WW,mrr;uupAb$es8;fpqu?]nat*Jo!"o84 -!"')5s7cNm?J6(ms'UW]rVrNjs82irrX.T`#6"2okSn.3s"pbPs8W)unc,-\YlF_&s8N&urr6/k -q>('@1\+qDq=Xd80DYPGpAap8%I<]as8;co!<3>us7H?kr;Qrjs7cT(rr30!s8Vfirr)it']T,l -$gIusp]'a_oY_[/q#::<qYpQqo`tNsaoJaJhZ!NVs8;fp!rr;trW)ZlnG`Lgqu8@Pr;S>F$MON! -rrW5ur;Qius8+jcq#BZi49#EVs8;iqs"]65cg^u/r=Ar$s8DunjSs`~> -i;Yn5#Q4Q#*tUm@jSo\OD2u@1qr,"6UAl%`o)Hi4ci(g)b5_A?s7lKd!rr;B*jb_$L2$\fmJd[r -s7>s^rrGR1rr3@j)795>s7ZKks7QBjs$-SancAUes7uceruJoTrVrlC\Gt3F;Y'ngs6BUZs3h7G -s7cAY!87.V(qo_+N`l+s'AEK&-+j3W!:0[\quufnrrhE_)#4(/s*XYB?@_><^a#H>s8VBarrV]a -s$`OBm`S"Lr:SMI^A#;IcN!_?oD`*\s'Jk-`^Kl^dUl2Hs7bp[qYuBfaT)59s8P"Us7--F(V'.f -1kYhf'tO@m4,rq2q>1-kn[KQqf_G0uR0!*`s6Td`o`+pks6sYsrr;imqZ$Bis(h*'qK><Wq8,F= -s8VZip\k-##*Rp8qUgcKlMgq[rVoLj:]L@`!W)irq>p0Zs8NH+s8MWjrVuo4(rGb2L/IsNs763\ -!W)irq>p0es1BSnrn8$orrr2ps8Dip[fA)]s7--5:[e8^rqtgVJ,~> -i;Yn5#Q4Q#*tUm@jSo\OD2u@1qr,"6UAl%`o)Hi4ci(g)b5_A?s7lKd!rr;B*jb_$L2$\fmJd[r -s7>s^rrGR1rr3@j)795>s7ZKks7QBjs$-SancAUes7uceruJoTrVrlC\Gt3F;Y'ngs6BUZs3h7G -s7cAY!87.V(qo_+N`l+s'AEK&-+j3W!:0[\quufnrrhE_)#4(/s*XYB?@_><^a#H>s8VBarrV]a -s$`OBm`S"Lr:SMI^A#;IcN!_?oD`*\s'Jk-`^Kl^dUl2Hs7bp[qYuBfaT)59s8P"Us7--F(V'.f -1kYhf'tO@m4,rq2q>1-kn[KQqf_G0uR0!*`s6Td`o`+pks6sYsrr;imqZ$Bis(h*'qK><Wq8,F= -s8VZip\k-##*Rp8qUgcKlMgq[rVoLj:]L@`!W)irq>p0Zs8NH+s8MWjrVuo4(rGb2L/IsNs763\ -!W)irq>p0es1BSnrn8$orrr2ps8Dip[fA)]s7--5:[e8^rqtgVJ,~> -i;Yn5#Q4Q#*tUm@jSo\OD2u@1qr,"6UAl%`o)Hi4ci(g)b5_A?s7lKd!rr;B*jb_$L2$\fmJd[r -s7>s^rrGR1rr3@j)795>s7ZKks7QBjs$-SancAUes7uceruJoTrVrlC\Gt3F;Y'ngs6BUZs3h7G -s7cAY!87.V(qo_+N`l+s'AEK&-+j3W!:0[\quufnrrhE_)#4(/s*XYB?@_><^a#H>s8VBarrV]a -s$`OBm`S"Lr:SMI^A#;IcN!_?oD`*\s'Jk-`^Kl^dUl2Hs7bp[qYuBfaT)59s8P"Us7--F(V'.f -1kYhf'tO@m4,rq2q>1-kn[KQqf_G0uR0!*`s6Td`o`+pks6sYsrr;imqZ$Bis(h*'qK><Wq8,F= -s8VZip\k-##*Rp8qUgcKlMgq[rVoLj:]L@`!W)irq>p0Zs8NH+s8MWjrVuo4(rGb2L/IsNs763\ -!W)irq>p0es1BSnrn8$orrr2ps8Dip[fA)]s7--5:[e8^rqtgVJ,~> -iW!firrVHbrNuX@s8VEcs8SNf$kESHV#UI_"[rC]b=3"4d-L0##PA&rr;urpm_([r$!!kqs8VZj -gAh3Os8;Wgs0P_rs7-Nt!!j#6!<<&up&F:OrrDTh!<<#rrrE)mQkqs[s6d<?)&#W\rt#&-CAS]8 -s6fp`s&1*3s/n^'!(aa!p!bT#3kt^jp^@,js6p$gqY:*jo`,F$!<E06n[2F:"Y$2Gs8;oslMh%f -p]%j$%gXtTs7?9j_C>O3`;]f5q>^2]./_t&$nf,N!#pR`s7H$br;Zd,qu@E4p+?=BrVuo=/-7/T -s7c!"0*E>KrVlosr;Q^iY&59h!&@X2rW)Wkq#(*iq#L9k!!a#7!<<)n,l.B<r;HZqqM61+15c,( -p&G'drUo^;9cO3J/7-Etnc8^gs.0D#rVults8Dor!<3!&ncSOFs8N3#s"O2E;ZmM4Yl=t$qssae -s8Dor!<;ogs0t>r1Xc'u!<<)pm/QeZ"JYYbs6sBqs8VuTs*t~> -iW!firrVHbrNuX@s8VEcs8SNf$kESHV#UI_"[rC]b=3"4d-L0##PA&rr;urpm_([r$!!kqs8VZj -gAh3Os8;Wgs0P_rs7-Nt!!j#6!<<&up&F:OrrDTh!<<#rrrE)mQkqs[s6d<?)&#W\rt#&-CAS]8 -s6fp`s&1*3s/n^'!(aa!p!bT#3kt^jp^@,js6p$gqY:*jo`,F$!<E06n[2F:"Y$2Gs8;oslMh%f -p]%j$%gXtTs7?9j_C>O3`;]f5q>^2]./_t&$nf,N!#pR`s7H$br;Zd,qu@E4p+?=BrVuo=/-7/T -s7c!"0*E>KrVlosr;Q^iY&59h!&@X2rW)Wkq#(*iq#L9k!!a#7!<<)n,l.B<r;HZqqM61+15c,( -p&G'drUo^;9cO3J/7-Etnc8^gs.0D#rVults8Dor!<3!&ncSOFs8N3#s"O2E;ZmM4Yl=t$qssae -s8Dor!<;ogs0t>r1Xc'u!<<)pm/QeZ"JYYbs6sBqs8VuTs*t~> -iW!firrVHbrNuX@s8VEcs8SNf$kESHV#UI_"[rC]b=3"4d-L0##PA&rr;urpm_([r$!!kqs8VZj -gAh3Os8;Wgs0P_rs7-Nt!!j#6!<<&up&F:OrrDTh!<<#rrrE)mQkqs[s6d<?)&#W\rt#&-CAS]8 -s6fp`s&1*3s/n^'!(aa!p!bT#3kt^jp^@,js6p$gqY:*jo`,F$!<E06n[2F:"Y$2Gs8;oslMh%f -p]%j$%gXtTs7?9j_C>O3`;]f5q>^2]./_t&$nf,N!#pR`s7H$br;Zd,qu@E4p+?=BrVuo=/-7/T -s7c!"0*E>KrVlosr;Q^iY&59h!&@X2rW)Wkq#(*iq#L9k!!a#7!<<)n,l.B<r;HZqqM61+15c,( -p&G'drUo^;9cO3J/7-Etnc8^gs.0D#rVults8Dor!<3!&ncSOFs8N3#s"O2E;ZmM4Yl=t$qssae -s8Dor!<;ogs0t>r1Xc'u!<<)pm/QeZ"JYYbs6sBqs8VuTs*t~> -i;X>_s8V`gp]('^s8Vrqp&Fdcrs\o,s82-^s7cQjs7Z9frs.uks6ojbrq69j!qH9]rr3T*s8Vur -s7lNlqu?<gqGZ/Kp&=tMrVuogs8DriqZ$Tos8VQes8N#trpTmdn,<1Rs8N&ls6fpeo`"^erqufk -s8;oqs7H'bq>^<err3f1s8Voms7u]ks8)3\s8Duos8)chpAb$hru1D,oDARbqt^9lo_/=Qq#C9j -s7H?kp\+UUr;Q^#q=OUbmJlhXrsnkos("jhs7,^\m.LDYrr)j"q>9d`qtg=(med%ali6\Yl1Y/W -rVuWlqYpL$o)Jafrr;Wjqu$Hn!r;Wjqu7Ass7H?es75sOs8VN&)?9U6rVu`jrr3;rm/QPJs7cQn -r;Q^&mf3:dnFu_Js8;iq+Su-8q!\4^rr2rsn,N:bs8)cqnc/X^pAb0Ps8VKds6Tab-h%'7rr2rs -n,*.as8N&uq#C*ds7?9jqu;`uiW&oWiEbsQs7QEjr8dm.~> -i;X>_s8V`gp]('^s8Vrqp&Fdcrs\o,s82-^s7cQjs7Z9frs.uks6ojbrq69j!qH9]rr3T*s8Vur -s7lNlqu?<gqGZ/Kp&=tMrVuogs8DriqZ$Tos8VQes8N#trpTmdn,<1Rs8N&ls6fpeo`"^erqufk -s8;oqs7H'bq>^<err3f1s8Voms7u]ks8)3\s8Duos8)chpAb$hru1D,oDARbqt^9lo_/=Qq#C9j -s7H?kp\+UUr;Q^#q=OUbmJlhXrsnkos("jhs7,^\m.LDYrr)j"q>9d`qtg=(med%ali6\Yl1Y/W -rVuWlqYpL$o)Jafrr;Wjqu$Hn!r;Wjqu7Ass7H?es75sOs8VN&)?9U6rVu`jrr3;rm/QPJs7cQn -r;Q^&mf3:dnFu_Js8;iq+Su-8q!\4^rr2rsn,N:bs8)cqnc/X^pAb0Ps8VKds6Tab-h%'7rr2rs -n,*.as8N&uq#C*ds7?9jqu;`uiW&oWiEbsQs7QEjr8dm.~> -i;X>_s8V`gp]('^s8Vrqp&Fdcrs\o,s82-^s7cQjs7Z9frs.uks6ojbrq69j!qH9]rr3T*s8Vur -s7lNlqu?<gqGZ/Kp&=tMrVuogs8DriqZ$Tos8VQes8N#trpTmdn,<1Rs8N&ls6fpeo`"^erqufk -s8;oqs7H'bq>^<err3f1s8Voms7u]ks8)3\s8Duos8)chpAb$hru1D,oDARbqt^9lo_/=Qq#C9j -s7H?kp\+UUr;Q^#q=OUbmJlhXrsnkos("jhs7,^\m.LDYrr)j"q>9d`qtg=(med%ali6\Yl1Y/W -rVuWlqYpL$o)Jafrr;Wjqu$Hn!r;Wjqu7Ass7H?es75sOs8VN&)?9U6rVu`jrr3;rm/QPJs7cQn -r;Q^&mf3:dnFu_Js8;iq+Su-8q!\4^rr2rsn,N:bs8)cqnc/X^pAb0Ps8VKds6Tab-h%'7rr2rs -n,*.as8N&uq#C*ds7?9jqu;`uiW&oWiEbsQs7QEjr8dm.~> -i;WrSs7H?^rr3]+s8Vlns8DutqssdTr:p<dmJlnWrr4#2s8V`hpAb'jr9F=^mJm.bs6BXaoDeLZ -qu?WkoDS[shbO4Hs8VlomJm4WrVm5is7cNfs8VQfs6ose!;QNm$iL&&s69R`p](-jmJ[&$kPX`I -o)JRds7lWon+QeMs8)9co)JF\r;R-'q#:6is8W#ms6Tab"RuHjs82fq%I=&js8Voprr<#ks8W&s -rsSi+s6p!bs7lWfs7cKl)u9)A+Fhr3s68@=90rUUq>]XXrU0^cqXjgfnGW@eo)AY)q#CBdr;ZQl -nGiOUs6fdas8)Hho)8Lcq$[6%rr<#mr:Bs`qtL$g&H2Y(s$X6kq#C9jo`+Uas8;lr$i9o'nc/Ld -s6BXYoD\b(r;ZTms7lNYs7$'`s8VQfs6p!frVc`umI^GSrr3?)nc/@Qs8VQfs6]gc"7Q9in,<8+ -p\Og]s763hs7Z0dnFkWSI/j$Bnkn9Do`"mjp>c1'~> -i;WrSs7H?^rr3]+s8Vlns8DutqssdTr:p<dmJlnWrr4#2s8V`hpAb'jr9F=^mJm.bs6BXaoDeLZ -qu?WkoDS[shbO4Hs8VlomJm4WrVm5is7cNfs8VQfs6ose!;QNm$iL&&s69R`p](-jmJ[&$kPX`I -o)JRds7lWon+QeMs8)9co)JF\r;R-'q#:6is8W#ms6Tab"RuHjs82fq%I=&js8Voprr<#ks8W&s -rsSi+s6p!bs7lWfs7cKl)u9)A+Fhr3s68@=90rUUq>]XXrU0^cqXjgfnGW@eo)AY)q#CBdr;ZQl -nGiOUs6fdas8)Hho)8Lcq$[6%rr<#mr:Bs`qtL$g&H2Y(s$X6kq#C9jo`+Uas8;lr$i9o'nc/Ld -s6BXYoD\b(r;ZTms7lNYs7$'`s8VQfs6p!frVc`umI^GSrr3?)nc/@Qs8VQfs6]gc"7Q9in,<8+ -p\Og]s763hs7Z0dnFkWSI/j$Bnkn9Do`"mjp>c1'~> -i;WrSs7H?^rr3]+s8Vlns8DutqssdTr:p<dmJlnWrr4#2s8V`hpAb'jr9F=^mJm.bs6BXaoDeLZ -qu?WkoDS[shbO4Hs8VlomJm4WrVm5is7cNfs8VQfs6ose!;QNm$iL&&s69R`p](-jmJ[&$kPX`I -o)JRds7lWon+QeMs8)9co)JF\r;R-'q#:6is8W#ms6Tab"RuHjs82fq%I=&js8Voprr<#ks8W&s -rsSi+s6p!bs7lWfs7cKl)u9)A+Fhr3s68@=90rUUq>]XXrU0^cqXjgfnGW@eo)AY)q#CBdr;ZQl -nGiOUs6fdas8)Hho)8Lcq$[6%rr<#mr:Bs`qtL$g&H2Y(s$X6kq#C9jo`+Uas8;lr$i9o'nc/Ld -s6BXYoD\b(r;ZTms7lNYs7$'`s8VQfs6p!frVc`umI^GSrr3?)nc/@Qs8VQfs6]gc"7Q9in,<8+ -p\Og]s763hs7Z0dnFkWSI/j$Bnkn9Do`"mjp>c1'~> -hu=5brVuosp%J+TrVu`ds8V?\s8Vt's8Muss7QB^s7cQiqu?]ds8VQfqtg3^s8VWas7cQjoD/Fd -rqZT]s82ior:^0\s8N&^mJlt]mJm4[s7u]ds8N#toDeXdq>'^`s7u]nqu>mQs8)ZnqXOUUs7u]f -rr3,hq>^EjrVmT+rr;ilqu?]ls8Vfmq>^3hrqcZkrr5afo`+:Xs6Ta_nc/XYs7$'gn,*.Ts8V]j -irArVq"+O\s7uTipAb0[rVHKmmf1RE0,FTt+@_mPq#B[Vs7Q-dn+m"`o`+dfoDS%Us82fn#lj]" -o(rCbm/?n_&,Gu"q>L?ir;ZEhs82fgrVlg,li6taq"OgHs8Vlgs7--grW)Kert4r#s8Vcls7lEi -meZtRs7QElrquuas7cQer;RN-s8V]jrr2rhs8)ccs7QEfs8;o`rr2p8rVuoos7lWds8V]jrr2rh -s8W&ps7H?bs7lQm&b5]]%TrQ*pAb0ks8Vrks8W)Ys*t~> -hu=5brVuosp%J+TrVu`ds8V?\s8Vt's8Muss7QB^s7cQiqu?]ds8VQfqtg3^s8VWas7cQjoD/Fd -rqZT]s82ior:^0\s8N&^mJlt]mJm4[s7u]ds8N#toDeXdq>'^`s7u]nqu>mQs8)ZnqXOUUs7u]f -rr3,hq>^EjrVmT+rr;ilqu?]ls8Vfmq>^3hrqcZkrr5afo`+:Xs6Ta_nc/XYs7$'gn,*.Ts8V]j -irArVq"+O\s7uTipAb0[rVHKmmf1RE0,FTt+@_mPq#B[Vs7Q-dn+m"`o`+dfoDS%Us82fn#lj]" -o(rCbm/?n_&,Gu"q>L?ir;ZEhs82fgrVlg,li6taq"OgHs8Vlgs7--grW)Kert4r#s8Vcls7lEi -meZtRs7QElrquuas7cQer;RN-s8V]jrr2rhs8)ccs7QEfs8;o`rr2p8rVuoos7lWds8V]jrr2rh -s8W&ps7H?bs7lQm&b5]]%TrQ*pAb0ks8Vrks8W)Ys*t~> -hu=5brVuosp%J+TrVu`ds8V?\s8Vt's8Muss7QB^s7cQiqu?]ds8VQfqtg3^s8VWas7cQjoD/Fd -rqZT]s82ior:^0\s8N&^mJlt]mJm4[s7u]ds8N#toDeXdq>'^`s7u]nqu>mQs8)ZnqXOUUs7u]f -rr3,hq>^EjrVmT+rr;ilqu?]ls8Vfmq>^3hrqcZkrr5afo`+:Xs6Ta_nc/XYs7$'gn,*.Ts8V]j -irArVq"+O\s7uTipAb0[rVHKmmf1RE0,FTt+@_mPq#B[Vs7Q-dn+m"`o`+dfoDS%Us82fn#lj]" -o(rCbm/?n_&,Gu"q>L?ir;ZEhs82fgrVlg,li6taq"OgHs8Vlgs7--grW)Kert4r#s8Vcls7lEi -meZtRs7QElrquuas7cQer;RN-s8V]jrr2rhs8)ccs7QEfs8;o`rr2p8rVuoos7lWds8V]jrr2rh -s8W&ps7H?bs7lQm&b5]]%TrQ*pAb0ks8Vrks8W)Ys*t~> -iVs,Srr<#ms8Mus..mQ;qu?Wpp]'m]s8Dutqt^9lkl:JYq"FUbs82Efs7uWfs82inp&4mi!Vl?e -rt+u$s8VZir;ZNks8)<dp&FFYs$cb`s7?9jhZ*KJs82]nq"t'js7u]ns8;Qfs7QElkl:VRq#Bsc -p&F[\s6TIZq>^-fnc/OSs8Dusr;ZEhq>^Kbs7cQmrVlrnqtU*h!qPsWrr4&<o`+OSs8W)up](9_ -s7$'Zs7Q0es7cBiq>^6ip%\Od!9jF^#Pe?!q#CBnq#::&p&G'cs5j:\kPkMAs5s=\(]+1&s7u]b -s8)cms8)cps6BXap%SLdq#::@o)J"Lo`+shs7u3bo`"Xcs60LLs8VEbs8;`nq==Rcl2UJWqu$K^ -rr3)us8W)trr`#qr:g'f+o1]qs6'FZq#C6gs7lKcs8UsUs7cQfr;Z0as7Pp^s82cort"Ppq#C6g -s7lKkq>^0grVc`q(%M>!s7QElq>^9jrqufcs8W)rs8VuWs*t~> -iVs,Srr<#ms8Mus..mQ;qu?Wpp]'m]s8Dutqt^9lkl:JYq"FUbs82Efs7uWfs82inp&4mi!Vl?e -rt+u$s8VZir;ZNks8)<dp&FFYs$cb`s7?9jhZ*KJs82]nq"t'js7u]ns8;Qfs7QElkl:VRq#Bsc -p&F[\s6TIZq>^-fnc/OSs8Dusr;ZEhq>^Kbs7cQmrVlrnqtU*h!qPsWrr4&<o`+OSs8W)up](9_ -s7$'Zs7Q0es7cBiq>^6ip%\Od!9jF^#Pe?!q#CBnq#::&p&G'cs5j:\kPkMAs5s=\(]+1&s7u]b -s8)cms8)cps6BXap%SLdq#::@o)J"Lo`+shs7u3bo`"Xcs60LLs8VEbs8;`nq==Rcl2UJWqu$K^ -rr3)us8W)trr`#qr:g'f+o1]qs6'FZq#C6gs7lKcs8UsUs7cQfr;Z0as7Pp^s82cort"Ppq#C6g -s7lKkq>^0grVc`q(%M>!s7QElq>^9jrqufcs8W)rs8VuWs*t~> -iVs,Srr<#ms8Mus..mQ;qu?Wpp]'m]s8Dutqt^9lkl:JYq"FUbs82Efs7uWfs82inp&4mi!Vl?e -rt+u$s8VZir;ZNks8)<dp&FFYs$cb`s7?9jhZ*KJs82]nq"t'js7u]ns8;Qfs7QElkl:VRq#Bsc -p&F[\s6TIZq>^-fnc/OSs8Dusr;ZEhq>^Kbs7cQmrVlrnqtU*h!qPsWrr4&<o`+OSs8W)up](9_ -s7$'Zs7Q0es7cBiq>^6ip%\Od!9jF^#Pe?!q#CBnq#::&p&G'cs5j:\kPkMAs5s=\(]+1&s7u]b -s8)cms8)cps6BXap%SLdq#::@o)J"Lo`+shs7u3bo`"Xcs60LLs8VEbs8;`nq==Rcl2UJWqu$K^ -rr3)us8W)trr`#qr:g'f+o1]qs6'FZq#C6gs7lKcs8UsUs7cQfr;Z0as7Pp^s82cort"Ppq#C6g -s7lKkq>^0grVc`q(%M>!s7QElq>^9jrqufcs8W)rs8VuWs*t~> -i;X\as8Duqs8DrsoDe1Ws7uTms7H?kq#C-hq#14/pAagcs7cQkrr;orpAb0is8Vrps8Vijrr3#q -rVlg%q>^Hhr;ZHgrVmN%s8W)ss7?9is7H?bs8Vrqs8)`p$hsYss8)ZnrVuonp&4mmq#C!arVllp -rr3>ss8)c`s8M`lqYU3j!q?6frVpj2s8;osoDeOar;Z`hs8N&uoDJLcq>U<lqu-Ejrr;cks82Tk -p&Fjdrr<#os8Duas8V]gp]'d\p&Fdas7?9eq#C-es8)cqq#CBhs8Vfmp](3js8)<dq"asirr;fe -s8N&umJm4_s8Vinqu?Whqu9"Ns7ZKmrr<#ss8Vigs82]nr;Zfrqu?]mqu?9fqu?]hs82imrVuHg -s8)Egnc/7]p[\@`s763ir;$Bcs8Vrqs8)`p&,Q>+p](9ks763irqHHmqYgEon,<7oqZ$Tls8W)u -p&>!fqYpm$s8)Whs7QEjr;Q^"p](9kr;PdWJ,~> -i;X\as8Duqs8DrsoDe1Ws7uTms7H?kq#C-hq#14/pAagcs7cQkrr;orpAb0is8Vrps8Vijrr3#q -rVlg%q>^Hhr;ZHgrVmN%s8W)ss7?9is7H?bs8Vrqs8)`p$hsYss8)ZnrVuonp&4mmq#C!arVllp -rr3>ss8)c`s8M`lqYU3j!q?6frVpj2s8;osoDeOar;Z`hs8N&uoDJLcq>U<lqu-Ejrr;cks82Tk -p&Fjdrr<#os8Duas8V]gp]'d\p&Fdas7?9eq#C-es8)cqq#CBhs8Vfmp](3js8)<dq"asirr;fe -s8N&umJm4_s8Vinqu?Whqu9"Ns7ZKmrr<#ss8Vigs82]nr;Zfrqu?]mqu?9fqu?]hs82imrVuHg -s8)Egnc/7]p[\@`s763ir;$Bcs8Vrqs8)`p&,Q>+p](9ks763irqHHmqYgEon,<7oqZ$Tls8W)u -p&>!fqYpm$s8)Whs7QEjr;Q^"p](9kr;PdWJ,~> -i;X\as8Duqs8DrsoDe1Ws7uTms7H?kq#C-hq#14/pAagcs7cQkrr;orpAb0is8Vrps8Vijrr3#q -rVlg%q>^Hhr;ZHgrVmN%s8W)ss7?9is7H?bs8Vrqs8)`p$hsYss8)ZnrVuonp&4mmq#C!arVllp -rr3>ss8)c`s8M`lqYU3j!q?6frVpj2s8;osoDeOar;Z`hs8N&uoDJLcq>U<lqu-Ejrr;cks82Tk -p&Fjdrr<#os8Duas8V]gp]'d\p&Fdas7?9eq#C-es8)cqq#CBhs8Vfmp](3js8)<dq"asirr;fe -s8N&umJm4_s8Vinqu?Whqu9"Ns7ZKmrr<#ss8Vigs82]nr;Zfrqu?]mqu?9fqu?]hs82imrVuHg -s8)Egnc/7]p[\@`s763ir;$Bcs8Vrqs8)`p&,Q>+p](9ks763irqHHmqYgEon,<7oqZ$Tls8W)u -p&>!fqYpm$s8)Whs7QEjr;Q^"p](9kr;PdWJ,~> -JcF^/#QFZ$rVuoqp\b$qp\Y!grVuWkrs&?"s82Wlq#:9pqY:$grs\c%q#:<cs8W#ss8)]nrrMrl -qu6lrrr;Qhs8DZk'DVUss8VZis7cQnirB&Ls8;corVca!pAb!hp@nReqYU:(q>C9mkl:\Os8VWf -s7$'grdk+1s*t~> -JcF^/#QFZ$rVuoqp\b$qp\Y!grVuWkrs&?"s82Wlq#:9pqY:$grs\c%q#:<cs8W#ss8)]nrrMrl -qu6lrrr;Qhs8DZk'DVUss8VZis7cQnirB&Ls8;corVca!pAb!hp@nReqYU:(q>C9mkl:\Os8VWf -s7$'grdk+1s*t~> -JcF^/#QFZ$rVuoqp\b$qp\Y!grVuWkrs&?"s82Wlq#:9pqY:$grs\c%q#:<cs8W#ss8)]nrrMrl -qu6lrrr;Qhs8DZk'DVUss8VZis7cQnirB&Ls8;corVca!pAb!hp@nReqYU:(q>C9mkl:\Os8VWf -s7$'grdk+1s*t~> -JcF[.$1Iomo(MnZqYU6jruM"/s8Vrqs7uEhrVH6fr;HWoqtg?mr9X%Tqu?9drr3#up&=slq"ajf -!r)9Zrr32as8VEbs7Z3e%eB&fo`+FUrq$0in+-MQrr3B"s8N#ns8Vccs8MW`rrVrcpAY'po`+s` -m/6kcq>:3bJcFd1J,~> -JcF[.$1Iomo(MnZqYU6jruM"/s8Vrqs7uEhrVH6fr;HWoqtg?mr9X%Tqu?9drr3#up&=slq"ajf -!r)9Zrr32as8VEbs7Z3e%eB&fo`+FUrq$0in+-MQrr3B"s8N#ns8Vccs8MW`rrVrcpAY'po`+s` -m/6kcq>:3bJcFd1J,~> -JcF[.$1Iomo(MnZqYU6jruM"/s8Vrqs7uEhrVH6fr;HWoqtg?mr9X%Tqu?9drr3#up&=slq"ajf -!r)9Zrr32as8VEbs7Z3e%eB&fo`+FUrq$0in+-MQrr3B"s8N#ns8Vccs8MW`rrVrcpAY'po`+s` -m/6kcq>:3bJcFd1J,~> -JcF^/%/p4rnc/Oequ?]pq=ssh'Dhb*s8;oqq>^?ls8)Wms7u]pq>UC,rVlisqu?]fs8Vufq>^Ko -q>:'es8Vs"s7?6irUfmb!WDckrrMchr;RE/s7QElo)JUep](9bs8Vris8;]ms82`o&,Z2&pA=mi -p&+L_s7QEjoR[&&s*t~> -JcF^/%/p4rnc/Oequ?]pq=ssh'Dhb*s8;oqq>^?ls8)Wms7u]pq>UC,rVlisqu?]fs8Vufq>^Ko -q>:'es8Vs"s7?6irUfmb!WDckrrMchr;RE/s7QElo)JUep](9bs8Vris8;]ms82`o&,Z2&pA=mi -p&+L_s7QEjoR[&&s*t~> -JcF^/%/p4rnc/Oequ?]pq=ssh'Dhb*s8;oqq>^?ls8)Wms7u]pq>UC,rVlisqu?]fs8Vufq>^Ko -q>:'es8Vs"s7?6irUfmb!WDckrrMchr;RE/s7QElo)JUep](9bs8Vris8;]ms82`o&,Z2&pA=mi -p&+L_s7QEjoR[&&s*t~> -JcF^/(%VD)qZ$Qpp\Xges8Dfmp[eFbli6e[rrV]hn,E>7o_8Ccqu-Hgs8VQfs7uKes7Q3bs8Dfc -s8W)oqu$<gs7H9cs7cQmq#:Eps7-*g%.sT!oDe4Wrr<#ps7-*g"7H0fr;Q]trr;rlrseu'qu$<g -s8W)us6K^^rr3/us8W#srdk+1s*t~> -JcF^/(%VD)qZ$Qpp\Xges8Dfmp[eFbli6e[rrV]hn,E>7o_8Ccqu-Hgs8VQfs7uKes7Q3bs8Dfc -s8W)oqu$<gs7H9cs7cQmq#:Eps7-*g%.sT!oDe4Wrr<#ps7-*g"7H0fr;Q]trr;rlrseu'qu$<g -s8W)us6K^^rr3/us8W#srdk+1s*t~> -JcF^/(%VD)qZ$Qpp\Xges8Dfmp[eFbli6e[rrV]hn,E>7o_8Ccqu-Hgs8VQfs7uKes7Q3bs8Dfc -s8W)oqu$<gs7H9cs7cQmq#:Eps7-*g%.sT!oDe4Wrr<#ps7-*g"7H0fr;Q]trr;rlrseu'qu$<g -s8W)us6K^^rr3/us8W#srdk+1s*t~> -JcF[.#k@rpk5Y>Qs8N#t(&7\+s7--hp](9boDej^s8;`ns7c-art>>2s7$'_q>^Enqu?]kr;ZZo -rr)itp\Fgg"nqTfmJleQrrq`gpAaa]rr2uirVlokrVlfsp&+gnmeHh^l2LMY!<2rs%eof!s82Hg -s7lKgl2USXrr2ukJcFg2J,~> -JcF[.#k@rpk5Y>Qs8N#t(&7\+s7--hp](9boDej^s8;`ns7c-art>>2s7$'_q>^Enqu?]kr;ZZo -rr)itp\Fgg"nqTfmJleQrrq`gpAaa]rr2uirVlokrVlfsp&+gnmeHh^l2LMY!<2rs%eof!s82Hg -s7lKgl2USXrr2ukJcFg2J,~> -JcF[.#k@rpk5Y>Qs8N#t(&7\+s7--hp](9boDej^s8;`ns7c-art>>2s7$'_q>^Enqu?]kr;ZZo -rr)itp\Fgg"nqTfmJleQrrq`gpAaa]rr2uirVlokrVlfsp&+gnmeHh^l2LMY!<2rs%eof!s82Hg -s7lKgl2USXrr2ukJcFg2J,~> -JcF^/48/^Js8Vuls82]er;Zfrs8V?RrrDBbs8;ojs8;ons8W)urU]j`o)&ISs8McXFo^7rs8Duq -p\k'fqu-Ntp]1?or:U(%r;HZ\&c_Fts8Vhn*]"3&mIpMY!r)`crr2ujp](9ls82cp%eTens4'Rf -"`;Naq#C?dJcFd1J,~> -JcF^/48/^Js8Vuls82]er;Zfrs8V?RrrDBbs8;ojs8;ons8W)urU]j`o)&ISs8McXFo^7rs8Duq -p\k'fqu-Ntp]1?or:U(%r;HZ\&c_Fts8Vhn*]"3&mIpMY!r)`crr2ujp](9ls82cp%eTens4'Rf -"`;Naq#C?dJcFd1J,~> -JcF^/48/^Js8Vuls82]er;Zfrs8V?RrrDBbs8;ojs8;ons8W)urU]j`o)&ISs8McXFo^7rs8Duq -p\k'fqu-Ntp]1?or:U(%r;HZ\&c_Fts8Vhn*]"3&mIpMY!r)`crr2ujp](9ls82cp%eTens4'Rf -"`;Naq#C?dJcFd1J,~> -JcF^/-2dN;li-GSr:g6kn,E@Zs82`opCRAopAFsds8VTgmelPRs7uZnrsSi+irB#\7h5S!oCi1` -!;ZWo"oSE!o`"pjrrW&mq=t!irVum9!;HEbqu?[9l2C\_p](9clMpn^s8)?Zs8VihrrDlorseo+ -rUg-hs8P0/lg\Larr3#moR[&&s*t~> -JcF^/-2dN;li-GSr:g6kn,E@Zs82`opCRAopAFsds8VTgmelPRs7uZnrsSi+irB#\7h5S!oCi1` -!;ZWo"oSE!o`"pjrrW&mq=t!irVum9!;HEbqu?[9l2C\_p](9clMpn^s8)?Zs8VihrrDlorseo+ -rUg-hs8P0/lg\Larr3#moR[&&s*t~> -JcF^/-2dN;li-GSr:g6kn,E@Zs82`opCRAopAFsds8VTgmelPRs7uZnrsSi+irB#\7h5S!oCi1` -!;ZWo"oSE!o`"pjrrW&mq=t!irVum9!;HEbqu?[9l2C\_p](9clMpn^s8)?Zs8VihrrDlorseo+ -rUg-hs8P0/lg\Larr3#moR[&&s*t~> -JcF[.70Shd+M3OG(8Um.riJ-[/>)nA!WWc1nO!I@pA+RkQkUF6p](9Z5mogQpAb*e!<;fns7H0f -s7`BG!%k)JrrAE$%^k^!rrrAh1CKlXrr<#s'EJ16!<N)tm7IOWlhUPL0]i8m.eNN9"o"lL!%k)G -rsJr/p](.$nGiOds7_*EjSs`~> -JcF[.70Shd+M3OG(8Um.riJ-[/>)nA!WWc1nO!I@pA+RkQkUF6p](9Z5mogQpAb*e!<;fns7H0f -s7`BG!%k)JrrAE$%^k^!rrrAh1CKlXrr<#s'EJ16!<N)tm7IOWlhUPL0]i8m.eNN9"o"lL!%k)G -rsJr/p](.$nGiOds7_*EjSs`~> -JcF[.70Shd+M3OG(8Um.riJ-[/>)nA!WWc1nO!I@pA+RkQkUF6p](9Z5mogQpAb*e!<;fns7H0f -s7`BG!%k)JrrAE$%^k^!rrrAh1CKlXrr<#s'EJ16!<N)tm7IOWlhUPL0]i8m.eNN9"o"lL!%k)G -rsJr/p](.$nGiOds7_*EjSs`~> -JcF[..fjAaQ4IQjSJV>+r#*$@ZY&_,!VucoBlsB/Du]M9EU];5rVu\0POZ/#rVlg4!<;rro_ngb -oD]r@p:4Q/r;_W1Te#U2rrD]js$?PYqdcSnI/s6Gr;ZNk!<;s#qYsojrO?nJs80N!rD:6%r;Z]p -s8N&poD]r@p:4Q/s8Vur;N:_9CgR/<s8W)kJcFg2J,~> -JcF[..fjAaQ4IQjSJV>+r#*$@ZY&_,!VucoBlsB/Du]M9EU];5rVu\0POZ/#rVlg4!<;rro_ngb -oD]r@p:4Q/r;_W1Te#U2rrD]js$?PYqdcSnI/s6Gr;ZNk!<;s#qYsojrO?nJs80N!rD:6%r;Z]p -s8N&poD]r@p:4Q/s8Vur;N:_9CgR/<s8W)kJcFg2J,~> -JcF[..fjAaQ4IQjSJV>+r#*$@ZY&_,!VucoBlsB/Du]M9EU];5rVu\0POZ/#rVlg4!<;rro_ngb -oD]r@p:4Q/r;_W1Te#U2rrD]js$?PYqdcSnI/s6Gr;ZNk!<;s#qYsojrO?nJs80N!rD:6%r;Z]p -s8N&poD]r@p:4Q/s8Vur;N:_9CgR/<s8W)kJcFg2J,~> -JcF[.0`_7Pm/["_rrDuqq\P"Ks7lWf!<;cm)#4'e"98B$s7?6js7cNrp]'8"r:Kpe"T.lks&]-q -s8*=Xl14lQrrMurncSplqYpNop%/.^q\o#)lkB<ks8)cj!qH9js6ps$o(!^or;-Fi=C^=is7cQa -pAb-ls8*=Xl14lQoDe^fi#Mdt+m](%rqV-Fir=N~> -JcF[.0`_7Pm/["_rrDuqq\P"Ks7lWf!<;cm)#4'e"98B$s7?6js7cNrp]'8"r:Kpe"T.lks&]-q -s8*=Xl14lQrrMurncSplqYpNop%/.^q\o#)lkB<ks8)cj!qH9js6ps$o(!^or;-Fi=C^=is7cQa -pAb-ls8*=Xl14lQoDe^fi#Mdt+m](%rqV-Fir=N~> -JcF[.0`_7Pm/["_rrDuqq\P"Ks7lWf!<;cm)#4'e"98B$s7?6js7cNrp]'8"r:Kpe"T.lks&]-q -s8*=Xl14lQrrMurncSplqYpNop%/.^q\o#)lkB<ks8)cj!qH9js6ps$o(!^or;-Fi=C^=is7cQa -pAb-ls8*=Xl14lQoDe^fi#Mdt+m](%rqV-Fir=N~> -JcF^/$2+o.s8Nhls82lrrt=44'K<T$rrDfnoF9p^rsJf&%0$89!<<)b"onW-!<<)nqZQou1AUY? -s8VfTC*kdZr:L'ipAY-mr:Bsg!"9S/p\t9hmJd1ds8)WdrrE*!#QOf-!"&f.rr4;CciM>is8;ob -rsf#/rVuTRC*kdZr;ZfdmV%I@pP)lEs8Vopqgne.s*t~> -JcF^/$2+o.s8Nhls82lrrt=44'K<T$rrDfnoF9p^rsJf&%0$89!<<)b"onW-!<<)nqZQou1AUY? -s8VfTC*kdZr:L'ipAY-mr:Bsg!"9S/p\t9hmJd1ds8)WdrrE*!#QOf-!"&f.rr4;CciM>is8;ob -rsf#/rVuTRC*kdZr;ZfdmV%I@pP)lEs8Vopqgne.s*t~> -JcF^/$2+o.s8Nhls82lrrt=44'K<T$rrDfnoF9p^rsJf&%0$89!<<)b"onW-!<<)nqZQou1AUY? -s8VfTC*kdZr:L'ipAY-mr:Bsg!"9S/p\t9hmJd1ds8)WdrrE*!#QOf-!"&f.rr4;CciM>is8;ob -rsf#/rVuTRC*kdZr;ZfdmV%I@pP)lEs8Vopqgne.s*t~> -JcF[.9*#"cp':Wir!EB$me$MYYS6d2!<;lp)<h+^+Sl$;s7l?jq<e2+q#C$ds6KRX!rW)or;Zfr -qZ$<ipUCP0rrDofrrDrqs8;Hbqu6U#pFPJ,li@(arr4eM!;uisq=G*qq"k$_m/-fe<Fc'rrq?B` -rVuirqZ$<ipUCP0qtpEk$1e#orrE)js8VP=s5X-0~> -JcF[.9*#"cp':Wir!EB$me$MYYS6d2!<;lp)<h+^+Sl$;s7l?jq<e2+q#C$ds6KRX!rW)or;Zfr -qZ$<ipUCP0rrDofrrDrqs8;Hbqu6U#pFPJ,li@(arr4eM!;uisq=G*qq"k$_m/-fe<Fc'rrq?B` -rVuirqZ$<ipUCP0qtpEk$1e#orrE)js8VP=s5X-0~> -JcF[.9*#"cp':Wir!EB$me$MYYS6d2!<;lp)<h+^+Sl$;s7l?jq<e2+q#C$ds6KRX!rW)or;Zfr -qZ$<ipUCP0rrDofrrDrqs8;Hbqu6U#pFPJ,li@(arr4eM!;uisq=G*qq"k$_m/-fe<Fc'rrq?B` -rVuirqZ$<ipUCP0qtpEk$1e#orrE)js8VP=s5X-0~> -JcF[.!!*#u0`_4QrX/5rs'j%=]aXr@1=c$n?B+`3AGu65m/QSYqZ$S"N:4]/o)8Ug"RQ0goDe7X -rsiM>m'7u<nIts&q?m#trr)j?rr;ZT@C>fB&+9Jtqtp:#rV['&s)En[c=ZqQs0b8o8YQ.`"Si#l -r:p9k"CeJ!Z6oSN%J'N_C&.Oa70!;Nqu?PEs5a31~> -JcF[.!!*#u0`_4QrX/5rs'j%=]aXr@1=c$n?B+`3AGu65m/QSYqZ$S"N:4]/o)8Ug"RQ0goDe7X -rsiM>m'7u<nIts&q?m#trr)j?rr;ZT@C>fB&+9Jtqtp:#rV['&s)En[c=ZqQs0b8o8YQ.`"Si#l -r:p9k"CeJ!Z6oSN%J'N_C&.Oa70!;Nqu?PEs5a31~> -JcF[.!!*#u0`_4QrX/5rs'j%=]aXr@1=c$n?B+`3AGu65m/QSYqZ$S"N:4]/o)8Ug"RQ0goDe7X -rsiM>m'7u<nIts&q?m#trr)j?rr;ZT@C>fB&+9Jtqtp:#rV['&s)En[c=ZqQs0b8o8YQ.`"Si#l -r:p9k"CeJ!Z6oSN%J'N_C&.Oa70!;Nqu?PEs5a31~> -JcF^/9`,:rq>(Ttn*UP_j8Z/$%48ggrQHBWs62]U-2[]A!;ulq!<;ZgqHa.WK)blHoF:j#p\uiF -p\jib0-DUPs8N)ls8N*!qt^-cs8Dor#Nn&HW<rV!r;Q^3!<2uus81be"W!X.naRmpjPMT[q#C$c -rtkJ/pS]_f-Fs0LnGhn@D#a]1jn\QKpA':>j8XW~> -JcF^/9`,:rq>(Ttn*UP_j8Z/$%48ggrQHBWs62]U-2[]A!;ulq!<;ZgqHa.WK)blHoF:j#p\uiF -p\jib0-DUPs8N)ls8N*!qt^-cs8Dor#Nn&HW<rV!r;Q^3!<2uus81be"W!X.naRmpjPMT[q#C$c -rtkJ/pS]_f-Fs0LnGhn@D#a]1jn\QKpA':>j8XW~> -JcF^/9`,:rq>(Ttn*UP_j8Z/$%48ggrQHBWs62]U-2[]A!;ulq!<;ZgqHa.WK)blHoF:j#p\uiF -p\jib0-DUPs8N)ls8N*!qt^-cs8Dor#Nn&HW<rV!r;Q^3!<2uus81be"W!X.naRmpjPMT[q#C$c -rtkJ/pS]_f-Fs0LnGhn@D#a]1jn\QKpA':>j8XW~> -JcF^/!:p-h!W)corrD9^rt"f&s8DuknGiO]q>^<gs8)`p%/BJpnc/XZs8VQfs7QBk)"djoq>^Kg -s82iroCN"\p\4^fq#:0^s8Drs)>sL2s8VKds82Bes8Ducqu?]bs7c3dp](*hrtbA/nc/Rds7lTn -s8;`ms82iroCN"\p\t1#o(N"]s8;osrVuBbJcFd1J,~> -JcF^/!:p-h!W)corrD9^rt"f&s8DuknGiO]q>^<gs8)`p%/BJpnc/XZs8VQfs7QBk)"djoq>^Kg -s82iroCN"\p\4^fq#:0^s8Drs)>sL2s8VKds82Bes8Ducqu?]bs7c3dp](*hrtbA/nc/Rds7lTn -s8;`ms82iroCN"\p\t1#o(N"]s8;osrVuBbJcFd1J,~> -JcF^/!:p-h!W)corrD9^rt"f&s8DuknGiO]q>^<gs8)`p%/BJpnc/XZs8VQfs7QBk)"djoq>^Kg -s82iroCN"\p\4^fq#:0^s8Drs)>sL2s8VKds82Bes8Ducqu?]bs7c3dp](*hrtbA/nc/Rds7lTn -s8;`ms82iroCN"\p\t1#o(N"]s8;osrVuBbJcFd1J,~> -JcFX-!V?<hrtbJ2s82`os8N#ms8VHbs8V`ks8Dipo`"k/oDejbs82irq>^Kas7ZKhs7ZEkp&G'[ -s8VZgrrMWbrVlllrr<#rs8NE(s8W)ps7uZorVlg>p&>!jrVuTkq#CBjp&G'hrr)los6]jYs8Vck -s6fpeo)AY!p]'a_s7ZKgs7uWnnGi66s5X-0~> -JcFX-!V?<hrtbJ2s82`os8N#ms8VHbs8V`ks8Dipo`"k/oDejbs82irq>^Kas7ZKhs7ZEkp&G'[ -s8VZgrrMWbrVlllrr<#rs8NE(s8W)ps7uZorVlg>p&>!jrVuTkq#CBjp&G'hrr)los6]jYs8Vck -s6fpeo)AY!p]'a_s7ZKgs7uWnnGi66s5X-0~> -JcFX-!V?<hrtbJ2s82`os8N#ms8VHbs8V`ks8Dipo`"k/oDejbs82irq>^Kas7ZKhs7ZEkp&G'[ -s8VZgrrMWbrVlllrr<#rs8NE(s8W)ps7uZorVlg>p&>!jrVuTkq#CBjp&G'hrr)los6]jYs8Vck -s6fpeo)AY!p]'a_s7ZKgs7uWnnGi66s5X-0~> -l2LbZrr33!r;Zfks8Dor!rDrkrr33%s7lQmq>1'i%fZM$s8W)uoDeF^q"FadJcC<$JcGWIJ,~> -l2LbZrr33!r;Zfks8Dor!rDrkrr33%s7lQmq>1'i%fZM$s8W)uoDeF^q"FadJcC<$JcGWIJ,~> -l2LbZrr33!r;Zfks8Dor!rDrkrr33%s7lQmq>1'i%fZM$s8W)uoDeF^q"FadJcC<$JcGWIJ,~> -kl1_]oD8@a+8l07nb`@^s8Vccr;Zfqs8Dutp\=dcs8Micp&G'jq#13noCdb8JcC<$r;V9~> -kl1_]oD8@a+8l07nb`@^s8Vccr;Zfqs8Dutp\=dcs8Micp&G'jq#13noCdb8JcC<$r;V9~> -kl1_]oD8@a+8l07nb`@^s8Vccr;Zfqs8Dutp\=dcs8Micp&G'jq#13noCdb8JcC<$r;V9~> -l2Le]rVc`uq"+ObrVlosr;-EnpAY'srr<#trVuWXrr3#tqu6Ttr;-BfJcC<$JcGWIJ,~> -l2Le]rVc`uq"+ObrVlosr;-EnpAY'srr<#trVuWXrr3#tqu6Ttr;-BfJcC<$JcGWIJ,~> -l2Le]rVc`uq"+ObrVlosr;-EnpAY'srr<#trVuWXrr3#tqu6Ttr;-BfJcC<$JcGWIJ,~> -l2Lnbs8Vokrr3]'rr;ohs8DlqmJ[(Sn,NF_rr;c^rr3N*s8Vuks8W#ss7Z'as7u>=s+13$s8;nI~> -l2Lnbs8Vokrr3]'rr;ohs8DlqmJ[(Sn,NF_rr;c^rr3N*s8Vuks8W#ss7Z'as7u>=s+13$s8;nI~> -l2Lnbs8Vokrr3]'rr;ohs8DlqmJ[(Sn,NF_rr;c^rr3N*s8Vuks8W#ss7Z'as7u>=s+13$s8;nI~> -kPl+kq#(0kp&G'goDS^hqu??^rVm#ss7uWlrr3&lrVlcq!rW)trr<#sJcC<$JcGTHJ,~> -kPl+kq#(0kp&G'goDS^hqu??^rVm#ss7uWlrr3&lrVlcq!rW)trr<#sJcC<$JcGTHJ,~> -kPl+kq#(0kp&G'goDS^hqu??^rVm#ss7uWlrr3&lrVlcq!rW)trr<#sJcC<$JcGTHJ,~> -l2Le^qu6Trp\b$j&,lP.o)8U\s8Vfms7?6hq#:9rnc/OepAY(!r:g6`qYL6er;ZVEs+13$s8;nI~> -l2Le^qu6Trp\b$j&,lP.o)8U\s8Vfms7?6hq#:9rnc/OepAY(!r:g6`qYL6er;ZVEs+13$s8;nI~> -l2Le^qu6Trp\b$j&,lP.o)8U\s8Vfms7?6hq#:9rnc/OepAY(!r:g6`qYL6er;ZVEs+13$s8;nI~> -k5Q_)rr<#lp&FX`s7cQhs7Z<hs8DutqZ$0ep%&.[s8Dunr;ZNbrVlumqZ#u7s+13$s8;nI~> -k5Q_)rr<#lp&FX`s7cQhs7Z<hs8DutqZ$0ep%&.[s8Dunr;ZNbrVlumqZ#u7s+13$s8;nI~> -k5Q_)rr<#lp&FX`s7cQhs7Z<hs8DutqZ$0ep%&.[s8Dunr;ZNbrVlumqZ#u7s+13$s8;nI~> -l2NC0s8VZis-XfMeGlm-(Uj@a(F-Njs1fWp`W*e''u0d[+<@ojZmug4oDc6F+LZk$JcD,;qYog\ -J,~> -l2NC0s8VZis-XfMeGlm-(Uj@a(F-Njs1fWp`W*e''u0d[+<@ojZmug4oDc6F+LZk$JcC<$qu;0~> -l2NC0s8VZis-XfMeGlm-(Uj@a(F-Njs1fWp`W*e''u0d[+<@ojZmug4oDc6F+LZk$JcC<$qu;0~> -kl1\ZoD\bA%ahRUp-P1O7/o??WB1(V1pE]9s!snQ1B0J7[5.VFUS]gHpH,d[2uipUq>L6k"o82u -rr2kIs+13LrrE&rquQEerr2?cJ,~> -kl1\ZoD\bA%ahRUp-P1O7/o??WB1(V1pE]9s!snQ1B0J7[5.VFUS]gHpH,d[2uipUq>L6k"o82u -rr2kIs+13FrrDfYs*t~> -kl1\ZoD\bA%ahRUp-P1O7/o??WB1(V1pE]9s!snQ1B0J7[5.VFUS]gHpH,d[2uipUq>L6k"o82u -rr2kIs+13FrrDo\s*t~> -l2NL9s8;]mlP[^`$iD+2k8!J#q">Ens!$P(%e(55mhPj5n(nl\"97^,li.:Trs/Jtrr)j'q=O[Z -qu6Nms8RZJJc)PG"T.iaq"t'g!r2comf.e~> -l2NL9s8;]mlP[^`$iD+2k8!J#q">Ens!$P(%e(55mhPj5n(nl\"97^,li.:Trs/Jtrr)j'q=O[Z -qu6Nms8RZJJc)MF!r2WhrVllqm/MS~> -l2NL9s8;]mlP[^`$iD+2k8!J#q">Ens!$P(%e(55mhPj5n(nl\"97^,li.:Trs/Jtrr)j'q=O[Z -qu6Nms8RZJJc)PG!ri)qk5Tr~> -l2NU)s8Drps.0Bb$LA6%rrE'!p[8CfrW)ue"9/B$m0<7es8NGs%J0T$s8N-"q?luns8Vrkp\t6l -JcC<$WW*;(r;QTerr2KfrpKf:~> -l2NU)s8Drps.0Bb$LA6%rrE'!p[8CfrW)ue"9/B$m0<7es8NGs%J0T$s8N-"q?luns8Vrkp\t6l -JcC<$V>gYls8V]Ws*t~> -l2NU)s8Drps.0Bb$LA6%rrE'!p[8CfrW)ue"9/B$m0<7es8NGs%J0T$s8N-"q?luns8Vrkp\t6l -JcC<$V>gYps8VcYs*t~> -kl37.q>^?ln,Mndrr_WI%f[:DknNde&aoK(r"Abl)u:6+lk9<uqtL?frt"Df$i^/8lc--3ZEBq2 -\$`TIZ`\kdJ[DD`$)t/6\[:u.r;Q]`s*t~> -kl37.q>^?ln,Mndrr_WI%f[:DknNde&aoK(r"Abl)u:6+lk9<uqtL?frt"Df$i^/8lc--3ZEBq2 -\$`TIZ`\kdJ[DD`#H=r4\[;&0rTsQ7~> -kl37.q>^?ln,Mndrr_WI%f[:DknNde&aoK(r"Abl)u:6+lk9<uqtL?frt"Df$i^/8lc--3ZEBq2 -\$`TIZ`\kdJ[DD`"f\`2\[;"os*t~> -l2LhPs7ZEk/aB<BqF%]f9E.#MO];AW6Ck#<s%/0S8,[email protected]]nkcH]1AgtKs8D`lrrpF: -rr<#rJcC<$V>gVpnA4o"s8MZjJ,~> -l2LhPs7ZEk/aB<BqF%]f9E.#MO];AW6Ck#<s%/0S8,[email protected]]nkcH]1AgtKs8D`lrrpF: -rr<#rJcC<$V>g\qn%eu&li2J~> -l2LhPs7ZEk/aB<BqF%]f9E.#MO];AW6Ck#<s%/0S8,[email protected]]nkcH]1AgtKs8D`lrrpF: -rr<#rJcC<$VuQeq"8V>urTaE5~> -kl3XAp[S:Q0Esl%s3(fr[f=G^/[k3L_^-&Grjt9(\c8o_*P_Wt"<tV[rPK-YbQ%,1s8W&ts891u -rr2uoJcC<$V#LSq[f?(#qu?]qo`'F~> -kl3XAp[S:Q0Esl%s3(fr[f=G^/[k3L_^-&Grjt9(\c8o_*P_Wt"<tV[rPK-YbQ%,1s8W&ts891u -rr2uoJcC<$VuI&"rr2\urq66hmJh\~> -kl3XAp[S:Q0Esl%s3(fr[f=G^/[k3L_^-&Grjt9(\c8o_*P_Wt"<tV[rPK-YbQ%,1s8W&ts891u -rr2uoJcC<$W;d/%q"ss]Z2F4jm/MS~> -kl2"Xs8V?\s7Z?is8;]m#l"B!nGi:Ws7?0g"76'dnc&Omp](0ks7#XZrs\i&r;Q`%s8W)up&Fi= -s+13LrrDurrrTY/qYL6lrq-5@~> -kl2"Xs8V?\s7Z?is8;]m#l"B!nGi:Ws7?0g"76'dnc&Omp](0ks7#XZrs\i&r;Q`%s8W)up&Fi= -s+13Lrs&8rrr9;'p?Va/~> -kl2"Xs8V?\s7Z?is8;]m#l"B!nGi:Ws7?0g"76'dnc&Omp](0ks7#XZrs\i&r;Q`%s8W)up&Fi= -s+13MrsJ_tq"jijqt'^`rU0]9~> -kl344s7ZKmoDedgs7lWor;ZTmrr;ims8W)urVuoprqlWnrVucps7QEhs8;omrr<#srr3<(s0;V( -qu?TorIP!"s/#_sYQ+:ls8W)js*t~> -kl344s7ZKmoDedgs7lWor;ZTmrr;ims8W)urVuoprqlWnrVucps7QEhs8;omrr<#srr3<(s0;V( -qu?TorIP!"s/H#&rr)]mX8_YTs*t~> -kl344s7ZKmoDedgs7lWor;ZTmrr;ims8W)urVuoprqlWnrVucps7QEhs8;omrr<#srr3<(s0;V( -qu?TorIP!"s/Q)+rVQBaql'D[qu-K]s*t~> -kl1bPs8VcjrttV4rr;TipAb0jp]('hrVuWhs6]jbp&G$irsAZ$s7lWoq=t!eq>UN&s8.BIJcDPG -$N9u(pU1%rs8N&lrVllro`'F~> -kl1bPs8VcjrttV4rr;TipAb0jp]('hrVuWhs6]jbp&G$irsAZ$s7lWoq=t!eq>UN&s8.BIJcDPG -$N0l%p9akos8;ojrVllro`'F~> -kl1bPs8VcjrttV4rr;TipAb0jp]('hrVuWhs6]jbp&G$irsAZ$s7lWoq=t!eq>UN&s8.BIJcDPG -$MsSsoWnGgrVccirVllro`'F~> -kPkYPs8VZhs8Va"rVuohs760hnbiFYrr3,mq#C3frVm;ss8V<_q#9jas7cQeq>UN&s8.BIJcDPG -$N9u(s0Mb$s6fpbrr2uroDa=~> -kPkYPs8VZhs8Va"rVuohs760hnbiFYrr3,mq#C3frVm;ss8V<_q#9jas7cQeq>UN&s8.BIJcDPG -$N9u(s0Mb$s6fpbrr2uroDa=~> -kPkYPs8VZhs8Va"rVuohs760hnbiFYrr3,mq#C3frVm;ss8V<_q#9jas7cQeq>UN&s8.BIJcDPG -$N9u(s0Mb$s6fpbrr2uroDa=~> -l2LkRs8;?brsSPns8Vlorr;ZkoDJUf%/Khks82iro`+Uas5j7[$2FDtrr<#os8VulrrTP,qgncu -s/#bqrWW2sr361urr*&tmf3=_oDa=~> -l2LkRs8;?brsSPns8Vlorr;ZkoDJUf%/Khks82iro`+Uas5j7[$2FDtrr<#os8VulrrTP,qgncu -s.KAnZ2ae%rri5es8Vlcs*t~> -l2LkRs8;?brsSPns8Vlorr;ZkoDJUf%/Khks82iro`+Uas5j7[$2FDtrr<#os8VulrrTP,qgncu -s.KAlZi'h,qsOLapAOX`J,~> -kl1YUrr2ugrr3Dqs8Vfbs8VQfpAap[rr<#d'*%D"s7u]cs8Vc`s7Pj\q"jm_p\t<$s8.BIJcDSH -$NBqsnG0$[qu#sPrr3#pp%/36~> -kl1YUrr2ugrr3Dqs8Vfbs8VQfpAap[rr<#d'*%D"s7u]cs8Vc`s7Pj\q"jm_p\t<$s8.BIJcDMF -"9/&pXoA>$o^Mk[!VuBZs*t~> -kl1YUrr2ugrr3Dqs8Vfbs8VQfpAap[rr<#d'*%D"s7u]cs8Vc`s7Pj\q"jm_p\t<$s8.BIJcDJE -!r`/(rr3#no)AXjp[\:Ts*t~> -kl:\]/H5JFRL9Y(s1KZs_#D:j*5V[TV]62ks/d[j_Yq7g'Y"+^*$`N(s1g$'`q]B0!jhq(JcC<$ -V>h#&q"<qHWq,o\r;6HmrUKo<~> -kl:\]/H5JFRL9Y(s1KZs_#D:j*5V[TV]62ks/d[j_Yq7g'Y"+^*$`N(s1g$'`q]B0!jhq(JcC<$ -UAk\ss0MV%s8W#qs8;orrq-5@~> -kl:\]/H5JFRL9Y(s1KZs_#D:j*5V[TV]62ks/d[j_Yq7g'Y"+^*$`N(s1g$'`q]B0!jhq(JcC<$ -T`5#'rVm*$rVu`mrVZ<fJ,~> -kl1Y\rr4G=+j7n>n5#UR6N9H@VFKqP:SXONpcYFE4o\<LX@E4JT;"sIqbWcO9_eVhZiBoRs+13H -rt,,$o'Z.anFcP9r:U*bs8Vugs*t~> -kl1Y\rr4G=+j7n>n5#UR6N9H@VFKqP:SXONpcYFE4o\<LX@E4JT;"sIqbWcO9_eVhZiBoRs+13E -rso&.bPM5;kl:AVp](6hrq6;A~> -kl1Y\rr4G=+j7n>n5#UR6N9H@VFKqP:SXONpcYFE4o\<LX@E4JT;"sIqbWcO9_eVhZiBoRs+13C -rrCRJrs.ojq#C$cqtB[^J,~> -l2NC/s8V?`ruf+h0)l"HpBpU.l1,/TrsJ;b%0$P)q#L3lrT=@a!<;@!nG`d[r;cWm!jhq(JcC<$ -V>gPmq#CU2k5PDWq=F4XJ,~> -l2NC/s8V?`ruf+h0)l"HpBpU.l1,/TrsJ;b%0$P)q#L3lrT=@a!<;@!nG`d[r;cWm!jhq(JcC<$ -V#LN!$3^_7!so#ElMpn[q!\7^p&BO~> -l2NC/s8V?`ruf+h0)l"HpBpU.l1,/TrsJ;b%0$P)q#L3lrT=@a!<;@!nG`d[r;cWm!jhq(JcC<$ -V#Lr8)&!bs%L`X^mJm4\p?_\Ks*t~> -kPm..s8VSc$4`*r&+KT#rrE)s!<;iqs8E&u$Le!#rsJ,m!:pisrW)un!<;[+q>($lZiBoRs7?9d -rpg$cro*k[rqu]nrr)lsrr)cprlP0KrquZhq"OIUq>C0irl>$Lq#D6N+;uIN-33i9p&G'^oDa=~> -kPm..s8VSc$4`*r&+KT#rrE)s!<;iqs8E&u$Le!#rsJ,m!:pisrW)un!<;[+q>($lZiBoRs8;om -rnm_arr;utrr;utrr;utrm(NJrr;utrr;u`s8DrbrrE&srrE&CrsfPt3^5_o5<AuIr:U*io(2m3~> -kPm..s8VSc$4`*r&+KT#rrE)s!<;iqs8E&u$Le!#rsJ,m!:pisrW)un!<;[+q>($lZiBoRs7u]m -rS[\arVuirrVuirrVuirrR1`FrV6EYrTX@\rQP9P,#D<E=Bnm#%fcM!qtodZo`'F~> -l2O!Hp&G'Zs!,1n/,fqFo*t^4k4T;br"A8_$iV(,pC$m0o&gD\$M3d#s8NE#r<WB"s7+16Za[38 -b-JC`\?<;tZMh'.ZN%6:[CEcY]"G\dZh^g(Z2_-0Zhq'-Z2:^:Z*UdEZaI-IZaI-IZaI-IZa02- -&[/4DXKAt8Zb<`DVmNG5WMd#lZN%6S[Bm9I[Bm?O]WecLYe@BY]!f/WYIq<TYJIQU^9tAU[C-"B -!O\s,!!!&t!"G@3Yd1jK]!o/W]<eEFiNick\ZiNGTs_B+Z4X&9'a"sH!"feCo(r:apA=adp&BO~> -l2O!Hp&G'Zs!,1n/,fqFo*t^4k4T;br"A8_$iV(,pC$m0o&gD\$M3d#s8NE#r<WB"s7+16Za[38 -b-JC`\?<;pZ2q59riuL,rN61)Z2(`rZMV!-Z4+"DZ*LX?Z*LX?Z*LY)Z4XFN_R-SWY-PaNY->UF -_Qg2JrNZ1(rj2I+(p^KV\?E0CXh([I[B[*CWjf7@Wk>LA\Zu.?rj;^5&?Z-C"WRaQ$3UF*a0W([ -Z*jS:"1bb:\`'n#Y.CmIYbJS9qQg[?#!k4A5Wq\'#64`#s7c*aJ,~> -l2O!Hp&G'Zs!,1n/,fqFo*t^4k4T;br"A8_$iV(,pC$m0o&gD\$M3d#s8NE#r<WB"s7+16Za[38 -b-JC`\?<;tZN%95[^<LB[/[E3Yl:d,Xfeu*[f3Z6ZN%0+ZMq6.[LomNY->(5Y->(5Y->(5Y->.9 -o!Aq:`3unXXK]CM[(!u_`3ZZF[f3Z6ZMq*-XoYi8rNcI-s0=MiX/rG%[Ap^@Xg"n(Z`UL0\>ld@ -ZG+/j]XbGVZ`OBC&1nkG+VbKhca^?iY-P77Z+@?E^#?C)Ye7<QZD>"AqR$jK-#RIKH?4=@*<6'4 -q!\+Os*t~> -kPm[Dli6JUfY7df;3naMs$EN[3;WGJWNSJT9V&.Ps$E$a5kI[>X#U.J8?.bGs7QElq"4Obs1eC% -r;ZfmJcGKEs82rqr;6Hjs8Mcms8N#q"T/,or;?'a*rc3=s8N&ts8N&ts8N&rpYkT=s8VuorqZ9_ -q!7bRl2Lh_rVQQn"nquqqZ$KlrsA,nrr;cnmJZq\rVd?)p])<Y#7Vab/-,8$lMgMUrrr#nrq?-[ -iq!6@p$)JK!VGjWoaC0f'ESXB!!EZ0i:6gH!r)<cp&BO~> -kPm[Dli6JUfY7df;3naMs$EN[3;WGJWNSJT9V&.Ps$E$a5kI[>X#U.J8?.bGs7QElq"4Obs1eC% -r;ZfmL&_)Ms8Duq"T/&mr;OP4!Uog_rr`#ms8N#t!qlTnr;Hfurr;ugrr`/rqYpKo&G?&!pAXjd -rquc\rqcWdrp0L\s8N&u'a-H^0KiB!7g&e[nc/7\q>1!YrVucQrrW0!pAP!kr;$@"#=^mR91DK= -#P.WfrrDuhs*t~> -kPm[Dli6JUfY7df;3naMs$EN[3;WGJWNSJT9V&.Ps$E$a5kI[>X#U.J8?.bGs7QElq"4Obs1eC% -r;ZfmJcG]KrqulprU^'hrUBjXrUBgkn+ZeXqXjU]rrDcds8W&sqZ6Qjq>CEkqY:!fr=JMrp[e:T -qtp3dkPP#Nnb_\Ns8W)urt5`0=\r[[AmuMTqt^9drV?3ao$.1F/9uQ(O,/C),Q@B2pA"O\o`'F~> -l2NI:qu?]fs0MnKWW0RV(!?*f&Mq#us0`ONf)NBG!6"oF3!IM*`sX*Co`)`G+3"$Pqu6s"Y5/+t -rr;ioM>R;MqYU9is8E6#qtg0aqY9sap\Xmb!r2Werqc-]')_Y)qu$?hqu$?hqu$<fq#:6_rr3f. -s8MrppAa^]r;QWnr;QWnr;QWnr;QWiqu6U/qZ$'brq$-gmJcVMrq$-[rqZQmqYUs$pZVZ0)?L9H -![%L4o(VtXnc&OlrqZBbo'52r#2J>b%LFF&qB$:h!#PeC!<<-2!:p'eo)JU]rq6;A~> -l2NI:qu?]fs0MnKWW0RV(!?*f&Mq#us0`ONf)NBG!6"oF3!IM*`sX*Co`)`G+3"$Pqu6s"Y5/+t -rr;ioM>R;KrqlQgs7lZkrqccpqu#gX!rVrnmJ@[qqtg3dqtg3dqtg3dr;Zcrr9aL_qt9pf!r2fc -qYCBmqYU-dqYpBhr;ZZort>>,rpTjdo`+sZs7,pbo`+O_qY'pqqZT_a2F]qm63R5d"n;Qlrr;uR -rs&E$67s]U55@DR#=LXE845^.'`\41n,NFdo`'F~> -l2NI:qu?]fs0MnKWW0RV(!?*f&Mq#us0`ONf)NBG!6"oF3!IM*`sX*Co`)`G+3"$Pqu6s"Y5/+t -rr;ioLAUuKp](3j!rr6!r;HBequ$ZtrVuipnbX-uqt^-bqt^-bqt^-bqtpEiqtK:Iq"XI[rrrDp -qsF:Zr;6NirV-<brq-6a!r)Ndr;R<%s8Vlos7$'[qu?Bip&Fs_rs0KZD.nHOF(H6errD`CrrcOr -6=*ai=:e[fEGgA_J9>QXs8V`Rq#10`s*t~> -l2Lq`s8W&trVlg*k5,,Ks7u]prTjI_rVlg=p\k*[s8W)up&G$krVuK`s7Q9ds8N&uqtg9krVcc* -rr3&qs8ITLs8N#qrVQWo#64]&rr;utrr2ZlrVl`pnc&%X!VQBdrrVoooBuVYrqcO0o^)MQr:^'^ -q=O@ToD&.Op\=IFq=O+Mq>U7Vq=sXQlMq8)$31&2'`d[kh=pR=q"s(Hq!mu#,Tn9R+s8'P+s8'P -+s8'P+s8'P+s8'P+s8'P+s8'P*%i/fl2KiYkiV*kkiV*k!$2IS#71YT!:p-grrW,krq6;A~> -l2Lq`s8W&trVlg*k5,,Ks7u]prTjI_rVlg=p\k*[s8W)up&G$krVuK`s7Q9ds8N&uqtg9krVcc* -rr3&qs8IlTqu-WrrlG-1rXJo$rVuosrr)`nrq6<\rr;Qgq#;-)nGiLfq>^9jrVZ]ls8Vrps8DHe -rUopb3<qB17mo^73s>T`lMpb]qu>jZs8N$S4[2+p5!M4q5!M4q5!M4q5!M4q5!M4q5!M4q5!M4q -3))='rs/it4$lD-5Xu%Xs8W'!s82HgJ,~> -l2Lq`s8W&trVlg*k5,,Ks7u]prTjI_rVlg=p\k*[s8W)up&G$krVuK`s7Q9ds8N&uqtg9krVcc* -rr3&qs8IiSrr'e8!;l?`&FfGhq"FFVq"t$]qs4%NpA=^bq>:0ir;QfpoD\airq-3mp&G'jp\tUF ->'5@LMM5FXs8VrnrrDHbs!'m0<)ut!<)ut!<)ut!<)ut!<)ut!<)ut!<)ut!<)usp@SZRq%jl"& -F*rCSC)m9Rq"OUaqt0o=~> -kl21ms8)cqoD7tVs7-'fli6\Xrt4\hs8;oso)Jacs7c9ap&F[[qu6lms82irrqlWn#Hn%(p%&.\ -r/1LNs8W'1rVH<ap\+7NpA=jhrr;utrr;usqu-?ir;QfsrU]mdrpTjln,NF_qu?]irVllmnc&Xh -qtg/6qt9j\qtp*So^hbEp$;;Cp##H7n+?;Eq"aa\p\"+E,60.m"Tn`.+93]A-n7J,1FPd6/1i@D -p\Ogar;-?fr;-?fr;-?fr;-?fr;-?fr;-?fr;-?frquchq#($crqucnrqucj!#lO^$P<dc!;Gp] -s7H6erq6;A~> -kl21ms8)cqoD7tVs7-'fli6\Xrt4\hs8;oso)Jacs7c9ap&F[[qu6lms82irrqlWn#Hn%(p%&.\ -r/1ISrVZWm!ri/tq#:TurVlcprVlcbrW)oorq$-jrr)Ecs8NMorr2N\rr2Hdrqucbnc&Ibrr2rt -#5eH!s8W&krr3&us7uZo"7?-gqu-QprqudT64I-P92\AW9*RRK3B0\a4>BYZ3'B>&rr2lqrVlcp -rVlcprVlcprVlcprVlcprVlcprVlcprr3,tq>^Blq>Up-4#oPk7QE[>s6fmcoD\@]J,~> -kl21ms8)cqoD7tVs7-'fli6\Xrt4\hs8;oso)Jacs7c9ap&F[[qu6lms82irrqlWn#Hn%(p%&.\ -r/(CUr;-9frq69qr;QWnr;QWmrql`lrW2rrr;?-c!WMiao+:WjjnSW>nGE+Nq=sUSjn/BHqY:!_ -rs&B#q>:'^oD&=cp@J;"="8Z'IZ'#7DB;bZ8OZ`?764X,6qU)-rrN#qpAYU;<*EmMEaW,is6fa[ -n,;kXJ,~> -kPkYOs8VQdrs8B!s7cBis7l-`rrr2tp&G'brr2umrr3<!s8W#jp&Fddq>C6srr<#qp\)"Gs82g& -rquTfp\"1Lp\smdqu63e%fZD*r;QWnr;QWnr;QWnnG`mls8W&tqu6Whnc/UVruqC=q"a^\q"a^Q -p%e1Nq!RnKm.'Z3n+,]5l13p+nes;<r\4X3/Li++!!O#6!"TG;lf[g/hY$X7nFQ;Clh0'5!;lNj% -g4(&,SM7;*WZ$9r;ZNkrq-5@~> -kPkYOs8VQdrs8B!s7cBis7l-`rrr2tp&G'brr2umrr3<!s8W#jp&Fddq>C6srr<#qp\)"Is8W)u -rVlfdrrE&trrE&fs8N#es8W';rVlcprVlcprVlcprVlTls8Duqs8Vf]rqZTjnc&Ugq#;3(s8W#q -s7cQnr;Zfns8Vloq>^*es!g;pr\tZR4$,V*&iWKN1/U+k%KHA+s6BXarVHNn!rW)uir'&VpAOaa -o(`.nrt.7Y8Noa13X#K^p\sdTs*t~> -kPkYOs8VQdrs8B!s7cBis7l-`rrr2tp&G'brr2umrr3<!s8W#jp&Fddq>C6srr<#qp\)"Hs8;ig -s8Dlrqu-Kcs8DopqZ-Tbruh46qY9p^qY9p^qY9p^qY9[YqtpEms8Vl`qt9[PoCVnWrU9ajqu?]n -r;ZE[rrY2T8kT%Q$VO:q0jK$KCm&jA,lR`CpA"XfrSmMSo'c;Ap?VMI%fI8:>@_,X>>Pn2r:BdU -o)F4~> -kl2:\s8)?ep](3lmJm4Js8D9`s7QBk!r;lgrr3,pnGhqIrr3#uqu6U#o_\Udrr;]hqu6o,rVuon -rUfl9rs/Q$r;$-^p%\4[s8N&rs8MTh0E2"Ns8N&ts8N&ts8N&rq=j[Yq"ORXq"ORXq"ORYqr7GG -m.Bo;q"a=WrV6Ebrq$%2qtTp\p\=LXp[Iq@p\=CPp[mq>ng$+K.4[1k1+"I@n+ZhV)u'$rnE9iY% -hf-P&etE6mdfi;p\=LWp%7G<pYc&On,<7dn+cqY!!`Sfs8Vurs7c0cJ,~> -kl2:\s8)?ep](3lmJm4Js8D9`s7QBk!r;lgrr3,pnGhqIrr3#uqu6U#o_\Udrr;]hqu6o,rVuon -rUflAs8;iss8McmrVcfsrr2Kgq>T=P%d*fkq#CBjs8VNer:p<al2Lt_s6p!fr;$?l%Jp)]7RB*s -6RY8Z3WK*Rrs0/k5"\.59K<IZrrN)tqu6Zjrr:sV!9jC\!9j7X&H;e7%1<CH#m:e(rqlEgrq?!a -J,~> -kl2:\s8)?ep](3lmJm4Js8D9`s7QBk!r;lgrr3,pnGhqIrr3#uqu6U#o_\Udrr;]hqu6o,rVuon -rUfl>s8Mujs8DfpqYg9krV$9jrVcWnq>gENrrD6Xrs&&oq!e"DrUKmfrU9am5uUQK85M0>6Uq(T -s8)fpr;R$W??D'^Q],2lo)I\D!93tP!93hL&GlV>)BKk?*YfOZrV?'bs82HgJ,~> -l2NC7s8W#sqZ$<hs8Vrds8Vfms8Dorq#C<mrqcZns8W#ss6BX]qZ$?jl2Ue[s7ZEk$iB_ss8B>' -s8Vrqrdk+JrrN,srql?f"TJ>srr2!Y!WMlco`FmR"Sr*6!s%ifqtg3cq"a^\q"a^\q"a^\q"a^[ -pDEEU0/G+;.O[5/./!6!o^_YIo^VSEp%S4[p`&u$oBQB%&el>n&M4"Jo'lDKoCr(Uq!n%Mo).MI -#Pe>ir:g6kp%n\!rqlK_jLa@>o]lGUs82ieoDa=~> -l2NC7s8W#sqZ$<hs8Vrds8Vfms8Dorq#C<mrqcZns8W#ss6BX]qZ$?jl2Ue[s7ZEk$iB_ss8B>' -s8VrqreUULrqHHhrq$0frW<-!ro*kbp(7B6"Vq:Q";:k2jSobf4#f;X5;G&a4#[-=q#C?mrrW0! -rqQL)r!#GE4A%Xq8-Jkjr;Zfprr2p"qu?]piVs/Xs76*^s8Vccrs\VKpAb0_s82cfrp]pZs*t~> -l2NC7s8W#sqZ$<hs8Vrds8Vfms8Dorq#C<mrqcZns8W#ss6BX]qZ$?jl2Ue[s7ZEk$iB_ss8B>' -s8Vrqre1=OrVQKlr;clrrVucoqZ$HmrV-?krVcTpqYU0\rUBgsr#$%d*&&K`)']Rgs8VuYrs;:h -:.A2O6;U0<p&>0oq>'mdrVm-H@pa/,G]%"(e,K[Js76*^s8VcbrrCpTrs&5tqYTscp%/36~> -kPkVVs82cp#Oh]mq>^*eq>UBpr;HKl"8)Wgr;Q^&rVuors8)clrqQKm$iU#%rr2lqZ2FOqq>UDO -rr;ouqu-NkrrDrqrrW3"r;Q]rrql`qrWE,rqu-Bj$NL,*r;Zfjs8W)tr;QcqrVllorVlues8VK] -ruh42!%8]k*$#V',QRB+o^)5Co(DSHo_%hKo_%kLo_%nQ0a96gp%S+QnG`.iq"ORXq"ORXq"ORX -rV-BhrqcfrqsOgd!!Vuhq=XXYrql`ls7cWhp=&X?p\XXTm]cBYpAF=XJ,~> -kPkVVs82cp#Oh]mq>^*eq>UBpr;HKl"8)Wgr;Q^&rVuors8)clrqQKm$iU#%rr2lqZ2FOqq>UDJ -rr)fqrW`#prr;utr;Q]rqYpKorVc`qs7uX*s8Dups8VZhrqcKjrqlZnq>L9upAP!js6]jdmIpPd -"@[email protected]'$57.>h!;Z-arAjm=s#U6@62gf`r:'acrY5>1rr)if&H`@D('Y<Q#lal(qZ$E5rr`,q -q7Z_+!ri/srr2QiJ,~> -kPkVVs82cp#Oh]mq>^*eq>UBpr;HKl"8)Wgr;Q^&rVuors8)clrqQKm$iU#%rr2lqZ2FOqq>UDO -rqud4rqcHbp@RYBo(;SLqZ$Top\Xg`q>1$er;ZZn&cDV)rV?Ehnb`4Xp\Xj_qYU!bqZufiqu?]` -s8VK[rs9EF>$5lf@oQVOm/R)\s%Ebm8Ol388,rVgs7kgX$2b\M()%u3*tAk]rrW3"rQ,!@pA=a) -r;ZfqnGe"~> -l2Me&r;Q`rli6bEs76!`rr;Tirr<#ns8VQfp&"X]rVc`ujT#8Trr3<#s8Dutnb)bUrqucr[f$.+ -q=ojI"9/2pr;?Qpqu$KnrWE)qs7lEirqlcqq>UZsrV$'es8;iq#6+Z&q#CB[r;Quus8Vros7Z6f -(@hGG+pJ&S%2ffZmG7-jnEoB/kOS*`q(*+1p@e7Sp\+@Tpt#63oCr%Nqss[bqZ6Wor;R2es8DNa [email protected]'^^qu?]q1&UqDp\=LXp\=LXp\=LXp\=LXp\=LXp\=LXp\=LXp\=LXp\=LXp\=LXp\=LX -p\=R`rWN/$nF?GCs*t~> -l2Me&r;Q`rli6bEs76!`rr;Tirr<#ns8VQfp&"X]rVc`ujT#8Trr3<#s8Dutnb)bUrqucr[f$.+ -q=o^ErVdK/nb2t]s8Vrps8W#sp\t-irr;uhruM%9pA+agqu6Wos7u]mp&=sQs8Dusrq??joCi1P -q>UEo('['#4$?#$7QLbRoDeXdrqHHfs8O`8qE+a>rr)rurr)j$iW&rVs8W&ds8N#trVuj*jT#8R -s8VrqhuEHKr58O=Zh=%ls8N#rr;cihs*t~> -l2Me&r;Q`rli6bEs76!`rr;Tirr<#ns8VQfp&"X]rVc`ujT#8Trr3<#s8Dutnb)bUrqucr[f$.+ -q=oXC"T.ufkj89>%Ia#js8N&kqtg-bqYgBbrs/K#pA+agq>:0f#57ohnGE%ArqZotqXXFVmI9o8 -q=t!i#p*N"D/joGE*FC\rrE&srrb>P8P)SR9E7i_rs%TbrVZ]oq<7hiirB#Ns8VurirAfQrr<#s -rQG3FrVHKmZhX@^s*t~> -l2NC8s7c-brs8Z1!<:7_'Z'gh%kG'Xs2$#sci:I>%D;_D.NcD)aors)s8BhG'$U=S$2aPoqYRSs -rqlNjs,-dYrVH<drV$6prqZ?br;?Hls8N#p!WN,trr;rqrXAMqr9s[WqYC0\s8VimrrW≺Q^! -r:p<lrV6C/h>eDn":>,2"!7Nt+[Ik+.lSD0-n"TSqXP6jp\=RZq=sd\q=sUWq=XROrU^!krVQKj -rr)isrqQKnrVlisrQ5'Br:p6d\EX$D~> -l2NC8s7c-brs8Z1!<:7_'Z'gh%kG'Xs2$#sci:I>%D;_D.NcD)aors)s8BhG'$U=S$2aPoqYRSs -rqlNjs,$aTs8W)tr<W?"r:g!cs8W)srsSf*qu6QnrVlfrrr;fnrVmi5r;Z9do(MkWn,E@Ys8N&l -qtU*crU]LVrUfs_r>,G$*()8G:d.9-9,.(Z=%YA681[Iq3:6_LqZ$Tns75a[r;R9+rVcWbqu$3c -pAFmhs8Drss8;]ls8=_NrVZWlrVZWlrVZWlrVZWlrVZWlrVZWlrVZWlrVZWlrVZWlrVZWlrVZWl -rVQEiqRHP)rr2lp!<2WjJ,~> -l2NC8s7c-brs8Z1!<:7_'Z'gh%kG'Xs2$#sci:I>%D;_D.NcD)aors)s8BhG'$U=S$2aPoqYRSs -rqlNjs,-gRrsSi&p\"1MmdKlCq#($h"o.ujq>C0hrrN,srVl]o)u]g:o)8"Lo_e%RqssX_qt9^X -q=OCIkk=`;oD8.rs8Ful>^qc]IV<[Ss$gHs5t=a0=$o=<rrN-!oDSdgq>9mjq=4@\qu?Zprs&H! -rVcWgq"snHr;-6`q=j^Zq=j^Zq=j^Zq=j^Zq=j^Zq=j^Zq=j^Zq=j^Zq=j^Zq=j^Zq=j^Zq>'aU -q=V2plMlA~> -l2NR5s8Vons6fp#8Gt65WD*%EV2nRTqa6pO4T@p2YtG$cVR8kS:TU0Xs6rdaSh^-<r;QZnrs-"4 -s8;Qdp&'^I"9/2pr;?Qpqu6U&o(;ePo'GW2qu6Tls8MrnrsJc'pA"7Vq=4:Xr;HU#rVl3`pAXaa -p\t.FnG`@VpAY!gqu-Ejqu-<W!"]qQ!!!60-3,pkg#__eo]P`:n`oc=oCVYHoCVbNqY:B^qsjRU -oDAIUs8W)orsST$s8DrskPtAXs8Kt:"T5t5rqc!]J,~> -l2NR5s8Vons6fp#8Gt65WD*%EV2nRTqa6pO4T@p2YtG$cVR8kS:TU0Xs6rdaSh^-<r;QZnrs-"4 -s8;Qdp&'ODs8ET.rq-0gs75j]rVu`cq#CBmrr2`n!<2or"oA2ms8Vljrs8W(mf3%]pAapes!@=; -s7?*es8N&ts8N&ts8E3`:JF5J90cD\:]Kh[s7u]err<#mnc&monGi1]p\+Ucli.Opr;6BUqYKaQ -r8[hMrr;lpqZ$TpdJa(E"T,e0qYC'g!<)orp&BO~> -l2NR5s8Vons6fp#8Gt65WD*%EV2nRTqa6pO4T@p2YtG$cVR8kS:TU0Xs6rdaSh^-<r;QZnrs-"4 -s8;Qdp&'LC#lFJnmeZeWo(W+_"8r/us8DiprVZZqrVQTurVufqs8Mfn#4VZgs7lWjrr3,os8Vij -pAYOF@Y0JmMhlG#,%1HErVllro`#3qq"aa_rVuokq>^'b!rM]`rV$9d%f6(erVc?]rS[SDqtg$^ -qYC9jqY&D1#kn,lqY%>op\4%SJ,~> -kl3=(rVuo[s8P-ts!R+($N1\=kna!j'CY](q%NJk*;gN0kR.=krpBs^rse2a$NKu#rr`&dYPeA! -!W2kRrVl]qrVlcq%fH@lq"=4JmdKZ9kkX];rr3'!rVc`lrVliq%/fu!q=!SBp%%kPpZ;>J2tHb6 -q!e(Qo]t\pkMk[h'dY(N,:+Q\-:Rt\!!WE'!tu:ImI^)>lhBcAq!7_Nq"a^\q"a^\q=jdkp&+CY -nc&OZrrE&tr;ciqrrE&mrs&>qqu?]qrVZZArs&5os8TM(rp0T7~> -kl3=(rVuo[s8P-ts!R+($N1\=kna!j'CY](q%NJk*;gN0kR.=krpBs^rse2a$NKu#rr`&dYPeA! -!W2kNrVl]tqu$<imJ6bdp&FXRs8;for;uusrqcQrrr<#no)&Femem(fqu?Nmq>C70p](6ms"m#. -5sdk(5s\TU8hrq,3CQM##6+W,rVHQes8VZVrs&<!pAajdrU]perVcZoqu?Kqo_\Ucrql^"p\=Ub -s8Drpr;lipdej@Er;Z`"pA+^errN-!rVlKiJ,~> -kl3=(rVuo[s8P-ts!R+($N1\=kna!j'CY](q%NJk*;gN0kR.=krpBs^rse2a$NKu#rr`&dYPeA! -!W2kRrVc`rrVZNns7H-e#laktnbr:Zqtp?l"oJ,mqu-KkrrDllrrD`Zrt@t,='8U-='8R?*,f;? -MLC)$?6&kB"8r3!q!A"aq#C$co)8.T!;lZn&cMUuq=s[UoC;GIqYKdTpA=a_q9o$Eq=XR\poO&Z -qu-Hms8DTiJ,~> -l2NsBr;Zcrs7*<[s7QHjquZluq!e^krrE)e"TJK%nHARhs8N>o&G5i&s8N-"q@!,rs8Vicr;Zf* -q"=@SrV;$E"98;R"o/-##i>CVqu6`sr;?Km&H;V)lM1,@oCD#0nE9B/o&0N<%ajk9m5$+8-6FQB -,ShQcqW&LWiW'Z($j7%B)\E)EkPP)Nr9XFUrql]^q>:!f!VcKirrDTPrs8Q&qWn1\q>]dYrrDuq -rltKCr;Zcs]D_d.rpg#=~> -l2NsBr;Zcrs7*<[s7QHjquZluq!e^krrE)e"TJK%nHARhs8N>o&G5i&s8N-"q@!,rs8Vicr;Zf* -q"=@SrV;3JrVd<*rr:pg!sAf9"pkG9)!Lqu!<2ip!<2lq%IsJuqZ$Tgr;ZNkr;Z9crsdres8>;D -2aT_u.mu9]q#:ck#VnV:92e,L1^j?PrVm)hs7ZKjs6fmarVZ`oqu6Wq!VcKirrDWhrseu-rr;ut -rr;utrr;usq#(KnrqYs]s82i]r;Qcpp\ufDs8N&ts8N&ts8N&ts8N&ts8N&ts8N&ts8N&ts8N&t -s8N&ts8N&ts8N&trVm#t[f61'r;Zcqo`'F~> -l2NsBr;Zcrs7*<[s7QHjquZluq!e^krrE)e"TJK%nHARhs8N>o&G5i&s8N-"q@!,rs8Vicr;Zf* -q"=@SrV;0Irr)ir$gf,U+=8]e+r:n=nc&OjrVQQlrVluuqu-KlrrDfdrrE#srrDKdrs;Li7T`c" -6sWSlp\tU?<,I>KQ@*sW*<5R-rrVckqYpKpnG`FcquH`lrtbA)qtg0alM18RrVQQjrVQQjrVQQj -rV-=%q>9gDo^hMGjnelOrVcTer@@pHs8Durs8Durs8Durs8Durs8Durs8Durs8Durs8Durs8Dur -s8Durs8Dor#6">&q"O[ar;Qisqu-3fJ,~> -kl3jEs7lW`s"_XprtYCr(\&79p_EE#+lWG6lPolq&cW7.jW4@$s7@?!rsIui#lal(m)ulG\@8'X -^U:8PYe#[ss0_j76FF/'U:(%C*Yf>&(F^R/Z_FJ(ZaI-FZE^U<ZaI-GZE^U9_iLt&TWt8tWMu=: -,oJcc'gEZd.&*]9Wgp9(Xfeh#qQ1U=V?SRa$ig86$R>_U_6:/LXi[QQYeR<]q7$F5qQq!H[^`]C -Z`h'KZEpjCZEpjCZEpjCZMLp-Z4O:MU8tc7[\p72WkPa@Xg5G7YPYR[ZE^^?ZE^^?ZE^^?ZE^^? -ZE^^?ZE^^?ZE^^?ZE^^?ZE^^?ZE^^?ZE^^?ZE^[5Zc8m@rr`8ur;Q6dJ,~> -kl3jEs7lW`s"_XprtYCr(\&79p_EE#+lWG6lPolq&cW7.jW4@$s7@?!rsIui#lal(m)ulG\@8'X -^U:8PYe#[srNR*AZ*CU7_ZMtd5X@Uo6okRhX0/\4Z2Ls1Za-mArNcI0+3^.c]s>Pa`P0'i5WUMo -1Fc?Y4[$9g[^`<La1AmpY55^I\Y]d'4@M:r68^t4Z,!HJZDkg>[B.!>`3fBK!4)I-'t1NZZ_t+3 -]X"iJZE^^?ZE^^?ZE^_4YlM$-Yn+FBYJ.oj[C<EA]s4fF[_):?1:"6lZa-pCZa-pCZa-pCZa-pC -Za-pCZa-pCZa-pCZa-pCZa-pCZa-pCZa-mFXgQ-Arr2fps8MZjJ,~> -kl3jEs7lW`s"_XprtYCr(\&79p_EE#+lWG6lPolq&cW7.jW4@$s7@?!rsIui#lal(m)ulG\@8'X -^U:8PYe#[s!3lI*6a3l)]=6?4?"n.sC0+P3(<j(hYct:7YdCdG['6^;Yd1XE\'q(lb.uEDeBcIV -;+j,^6p"sH:/8mV`P]"#d)3f?\,*u[_QFebApefOH!OSeYe-[0XJj.9[]R->_6O!Ds/lF)Y-7], -'st<TZ)+\+]!/EEYd1L=Yd1L=Yd1M4ZN%9G[^WfX]>Le]`5oj)\?;^>YH=t8](`Kf['I'E['I'E -['I'E['I'E['I'E['I'E['I'E['I'E['I'E['I'E['I'E['[EK[)8I0qYU0is8)fpp&BO~> -l2O!HqYU<mrO#K%s7nsOX>p5BT;jsPpb8bD5lWU1\h3qMUouWT6_UD6s7JCXUc/8Gs8W#lrVZN' -p\"I`s7lNErtGD3rr;utrr;utrr;utrqlWns8Moq"oeQ%r;6KPs7?6crtYG#n,OIE#R1_N*u=qH -nG)nYrquZhrqQKirqZTh+7_9=2^1"".4?K%i:6<enF?#3nE]N-o_&4Up\t!frqcNnrVuTlrVllr -rr3)ss8W#cs8W&rrrDo]rt58.p\XXSp[.MFqu?QmrquNfqu"e>"T8,qqn2n-"9/5rrpg#=~> -l2O!HqYU<mrO#K%s7nsOX>p5BT;jsPpb8bD5lWU1\h3qMUouWT6_UD4rq/:XVE"VLs8W&ns8W)4 -qtL*is7lNUrXJo,s8N&ts8N&ts8N&tlMph^nc/Lco)A^hnc/Ufs8Dus%fcA)"[GC;5t4(.3=#T` -n,Emq69%Lk68CV`3(``As5s=\%Jg&%s82ims7Q0eqZ$Tjr=o;6"Uk\K#R:\;s82irqYpBjo_na_ -qu6Hl#6+Z%s8Mrlrr)rsq!\7\rWiK#s8;coqYpKo"T/2us80k:"oePu\GlI's8W)js*t~> -l2O!HqYU<mrO#K%s7nsOX>p5BT;jsPpb8bD5lWU1\h3qMUouWT6_UD5s7\U_V)SACqtp0\r;Z`/ -qY'mfs7lHSrser,rVuirrVuirrVuirnbrFd$2so(qtU$bs8W&rrs8T'rVuirrVuins76-Ws8Doo -rs9o^EH->RBkLEfm/IAb6W--E5Y4L9=oSF$pA"Xkrr;`hs8;Tj(^Cd"2)dWM,9-scp%7tLqtp?a -rVH0`qYL3drq6?erqcWks8DuorVllpnc/XfoD]$orV?Bks89k9"SfD$qYU0i!r`#pp&BO~> -l2Le`p&=tNqDQUus7=eL+3OT)%OAj`s25osa8`h!'Z0je+;D`n^Dn<>oDciH&&J8Cs8VHbqXF6W -q"+CSrr2otr9F:arVuoqpAYj+r;QWnr;QWnr;QWnr;QN`o^i+Tqu6lms7>mSqu6-c!rW)oqu6Zo -rVm)sr:p*br8dYNs8)fqrr3l8qtKR[&J,6N!!*B@!9`J7o(D84nE00+.K(Y7.P!&$0^SJrp[7hN -q>'p`qt^-bqt^-bqt^-drpg!prqlK_o()GIqu4S7rVl`m!<2rsq#8V>#6+T$qmc\*rr<#tnGe"~> -l2Le`p&=tMqDQUus7=eL+3OT)%OAj`s25osa8`h!'Z0je+;D`n^Dn66mJb0F'?:(Ms8VKds82i% -s8;olrr3*"pA=deqZ-E^r!*-!r;Q`ks8N!$s8N&ts8MHd$haPps7uTiq>^6ip%JFbrr)cuqu6?h -o_najr;QHirWiDts82`ns6'1Ws8Mrp%fZM.#!#(@845a37gT.lrr3/qq>^<ks8>(f5!;%k4?iT@ -p&FgErrE&gs8Drbrs&K&rr;utrh'2orr;l)s8Dfo!<2TiJ,~> -l2Le`p&=tTqDQUus7=eL+3OT)%OAj`s25osa8`h!'Z0je+;D`n^Dn9;nc-fR'Z0_;o^gu6q=Xcj -s7u]erVcWlpAFmgrrDuerso#&rVQ?drVHKirVQQjrUKdarsSJrq>KdKmI1#Lqt0mf#lFStrVQQj -rVQKj"ShibqXFI[!r2W`rqZZnrVZZqme$PZrr)j',$f8;K7\Q"GVJjk#$"Jp:/">Sr^m.i!<(@G -s8Dups8Dorq>L<iqYc]Z"T,V*qu-Bk!<)QiJ,~> -kPkh^q"=[[s8)ckrr2uirr3?&s8W#gs82irrpTjd#6"Q$s7QE[rr3r1q=j[^pAapfs6B@Ll`K^G -p$hkPs8N&urr;l`rs&H!p&G'kqWe(br:Tgas7Q'`s8VclrrVrfr;-HhrVZZspAa^[s8W'2k5P8W -nG`%Yr;QWnr;QTgp\F^cr$_C.m/S(2#64`+#m11Z0IJ7t/MI5M+<g(9lKdd'md]l.p\=L[o_e<3 -s3UcLrr;l)s8D9`J,~> -kPkh^q"=[[s8)ckrr2uirr3?&s8W#gs82irrpTjd)#aI6s7QE[rr)feqYL-iq>^0gs7--hrk\U6% -/U#!s8)]loDA%Kqtfm\#QO_uo`+siq<%\`r;-6gp\4[_qY^'es8;ckr;I,qrpKdbrVl]nr;HZ\r -r3&ls7c'`(Ae%<84#p984lN9#k^VF2)RK^(HOK7q#:Tgs8W)uq>^2?s3UcLrr;l)s8D9`J,~> -kPkh^q"=[[s8)ckrr2uirr3?&s8W#gs82irrpTjd#6"Q$s7QE[rr3?#rr;rqo(M>>p?MYW!5ea8 -$iBtus82irq>^6fs76'nqYg9co)8Oap\FdYqu6U'qXsg`oB>E0qYg*`rr;oms82ims8;or!rr8u -rVI#lqs4.VqYU'bq>:3Zrr3&os8)3a'I[m?JV&f=Li>6O@STHe;d2"X<`f(r!;ZTn!r`/oJcF*s -"oeQ!\,ZEms*t~> -l2Lk_rVucnrr`5ks8Dor$3'\ts7lWop]'j`rt+_us8M`fr;Zfrr;Zfqr;??grrDT`!"/Mcrr)Qj -o`+sdqt'Rfq>C9mpAb$gkl21hp](9hn,E@erpT[_s7c?arr`8uqtpBg(%hM)nc&OSrq69ip&=ab -rqHHes8MNertGA2rVuirq=<tDo(;VJo'PQ>!"Su.*<cQh!%[=.p%.qMo'u50n*]W4n*oo>p%\.F -r;?5=s3CWJrr;l)s8D9`J,~> -l2Lk_rVucnrr`5ks8Dor$3'\ts7lWop]'j`rt+_us8M`fr;ZfppAP!is8Vrorrhur#6bP8#Rh4P -"97fhqXaXQr;?9Yrs&K&s7ZKirV?Horr)Hd#6"AkrVccmrVm0"s8DoiqZ$Qoo`$$-s8VZis6]j[ -s8Vfmq>UEfs7H?gnGiOdrVZWlrVZWgrsf;j9fbj?7m0]Y6hp]YqY^?noCr7fqXOUaon!.grrrE% -qmZV(li2J~> -l2Lk_rVucnrr`5ks8Dor$3'\ts7lWop]'j`rsJ;os8M`fr;Zfqq#(.-p\Xg`qt:C5)Bfn1',_Gk -s763iqZ$Ejs7-'frr_upqu,aY"8VKWo`"mjqYpL&o^VJEp@S"NpA"O`q>V9/s8V`ks6p!_s8Vlo -qu?]dp?VGCk4\NFo)S^_rsC8_Jp!!4KQM]!?gRdpp&G'bJcF$q"oeQ!\,ZEms*t~> -kl1h]s7H?dpAP"+nGiO_s7lWorr;rms8;okqu?Wps82cp3;NURs7u]oqYpHnp[e@Z!$!+*(D%K$ -(]a-qnGN:Xr:KRUo^_YFo^_YFo^_YFo^_YIpA4^_r;-3d!<2He$i^2"o(2bUoCDVTrqZTorr2`m -q#C$sq=s[Uq=j[Oq=s^Vq=ss]!:Kd_!;63d0_d">,pt)i.46AG!$MCH!!*HA(BEmrr;Q*\jnJK) -p\":Rp\4IXq>9aOs8Vurs8ITLd/O:Ks80;*rTjK6~> -kl1h]s7H?dpAP"+nGiO_s7lWorr;rms8;okqu?Wps82cp+o209rq6<kqu?WpoC;h[!\ll-5rq1i -1)']^o`+sas7c6Vrrr?"s8Dusp\t6loDB-ts8VZhs8W&ts8Dutrpp'`rsSf'r;HQkrVccrrVc`q -$MON"rr)lsqu$<]r;Qcmq>UOX4$#G%3>OY=-5'9A8PDZF6pCnUrVulds6K^bl1b2_p@/+^qYU9j -JcF*s"oeQ!\,ZEms*t~> -kl1h]s7H?dpAP"+nGiO_s7lWorr;rms8;okqu?Wps82cp,PhB<rUg-irVucnnFHVZ(JnXZBjb=K -9.']=rVuoos8N&urpfpGrr`5nk4\WN!qt^MrVHQk!<)Ee!;lTl!W)?arrDiirtA%&:J48M8P;uK -21KRsMM?P"@j:mO"o&&ks8Vifrs/Ajs8VlhqtksEd/O:Ks80;*rTjK6~> -kPlUqs8DWjlKnQGs8W&mq=t!irr;rms8;okqu?Wps82cp$2OW"s7ZKlqYpKns!.11!$`6`#nA'm -'EHeXq"aLVo_%kKq"ag_qt^-bqt^-bqt^3f"o.ueqtoaEq\eSrs7bpNp%J+Pna6)NroWkDo(;VL -q"agdqu7K(b4YDkkOnK:me-5;nFcAAmd93!lQdtU-3*?5nF?MM)Y3=Z!"L%M"9K>_*WZ!7rqcZp -p@nL_n,3"WrVQWmJcEgk"oeQ!\,ZEms*t~> -kPlUqs8DWjlKnQGs8W&mq=t!irr;rms8;okqu?Wps82cp$2OW"s7ZKmr;Z`prXAN#"[>((4$QD% -1_]6TrrDr]rrrB$q>^Kbl2M:_s8MZfs8Mlkrr;lfrr;H\s8N!.rVufJs8Vcbs8W#ps8Vflr;Qos -q>WE<q)S3L(D/Z)3CQ2'83@1Xs8)Bes7cBis7$'erVQNmrrrE"rr2clJcF*s"oeQ!\,ZEms*t~> -kPlUqs8DWjlKnQGs8W&mq=t!irr;rms8;okqu?Wps82cp$Mj`#rUg-iqu?QlrVm0QDK9fOMj&I" -48o0_q#0s`qu#j]"9&9"p$)JYo)JFPrr<#srr3)hpAadXs8MusrrD$WrrE&grrH&$qG[Gmp\tdX ->^U74F)l)!)uos8o`+shrr2ukrVulrs8;oq#5e5mqY'a`JcF-t"oeQ!\,ZEms*t~> -l2Le_rr2rtrVZ[)oD/FcrqHBkq#CBgs7?3h.e3H:rq?0cs8W&mrr2lqs8;ons82?e)&<tl!"',N -!:B@Eq"=+KnEKK7oCWUena6,HoD&.Vq=sd\q=ssbo(rOes6g*d!%A'>s82K[o(;SIp\=LYqY^9i -rVH3XiUZI.kOS3/l1,`K1+!e_)CR'Yq!0'imdK`=pA"FVoBcMu'-.Z'(CDntr;Z*_s7?9jlMpn^ -q#:Nrq"OggrIP!prrrE%qmZV(li2J~> -l2Le_rr2rtrVZ[)oD/FcrqHBkq#CBgs7?3h$M"&orq?0cs8W&mr;RN,rq?<ir<GAM8jG6u3BIBD -s7cQnqtpC+rr;utrr;utrr;utrr2cfs8VrVrsS)r"U>YK$k`dK#3ts_s8Moos8N)hrr3N's8Vrk -s!gB&2_@-I5XIL(s8W)qr=oGs2b65)4t9,+s8M'WqX=F`lMgh\rVuiq#Q+>go)AX]rdk*rrrrE% -qmZV(li2J~> -l2Le_rr2rtrVZ[)oD/FcrqHBkq#CBgs7?3h'(Po"rq?0cs8W&krVulsrV-9brr39ZDh4+:MiE.- -0`:qQp](3gn,ECbir9Jdj968>-6+'R*Yek>rU0[crqQL"2c*:?6rm&d?;p7k'cC"QCM@Zn6X('# -rS[JFm/R+Ps8Dcmr;lforqcurp@%GGq"":[JcF-t"oeQ!\,ZEms*t~> -kl2"gs763ilMpeOs7Q9h$N'l'r:Bscs8W)err4>Drr<#ks6fpdr:0UYqu?Qns7l!^)A)rP$j@7b -!$NjE3'/S]l0@g+&FfAepuD/=o(2YNq"ORXq"aI[&+oo%!Ytq@!!!'(('=O9o`"mjrY#/)q"=:M -naZ,:nF?&d.P2i",Q9:r+nGX##5%?Vp$256q=Og`qu6EkpAbEqo`+mis7ZHl!<)Nh!W2hHs3L]K -rr;l)s8D9`J,~> -kl2"gs763ilMpeOs7Q9h$N'l'r:Bscs8W)err33$rr<#ks6fmd!;6?g(]X4-rqlTu6:3b':dIN@ -$9("(5!q.+qX"4bmf31]rosFolhgVe5<_:l3Bo\l$2sbdrp]pk-osLH68SU)$Sh\\rr<#rs8Vlo -p@S@brr2j4rr3!(&-N:D"rIRLr9sUUrr2Kgs8;Zirqc]nrVHTmrVlil!<.QLd/O:Ks80;*rTjK6~> -kl2"gs763ilMpeOs7Q9h$N'l'r:Bscs8W)err33$rr<#ks6fmd#57oiq>0[\rr3K]Fb"muOaVOr -.o/l.8kqV9rrD]arrDc`mh4FEoFG5ACh@?sBjD8An)4'@rUTsl2+L8':I+nP!'^>\"oSE#q>^3^ -rrN)qrq[W5rs',X'd"D8//&Kjlh9W;q!\1Yq=OIVq"XUYrq?EgrVH]gp&"]=s3^iMrr;l)s8D9` -J,~> -kPnc_s8Vo\4:*)*bo7P9s2b`r_"RfH*?3'!]d4B0rkfim_uIIk*Q[UF`>B6.s8W&nnGjCA!<<-) -&/P?6p%e+Ppa@UI+=JWf-n6Vp-n6Vp-n6Vp.jlf&2"C/3pC?urrr;utrr;utrr;utrr)j)q#Cj6 -!"'&5%LiF6rVuos/,];>pFe-M.k3"s.Om"Bme-5@o^MJFo^hYHp[n@Rq#($[qYU-dqYU-drUp0s -p@J%GmG7F)s8Moq!;6'c#QFc&s8)]oo7?qgrrrE%qmZV(li2J~> -kPmX?s8Vo\4:*)*bo7P9s2b`r_"RfH*?3'!]d4B0rkfim_uIIk*QdgNaVki2rr)`orrtb\4[;J' -6Tt\QruC\1s"cZ'1d!l^4?GYe4?GYe4?GYe4>SfW55Y9@s8W'-p]Nl_4'#BD<C$c_rr2`nr]L*A -s#LAar;Zfos8;`n!r`/nrr2ump](9ms8Doo)#+".qYL6hs7$'as7cKhr;Q`ro_e^drr;lp#Q=]$ -s7uTmnq$hfrrrE%qmZV(li2J~> -kPmX?s8Vo\4:*)*bo7P9s2b`r_"RfH*?3'!]d4B0rkfim_uIIk+3jEWar(]&q"ajfs!;N4H$t6g -Eb-Kmrte+!>YS3t<E)st<E)st<E)st<DYnC7S!.O%fQ2!q"jd^q"jd^q"jd^rqHus&8@&EOH=RB -BG1%6q#1'h#t7?U92&)U9LhPCrs&>snbE"YnbDq`qtg*]o`"Fbo^M\VrVQU)r;6$Vo(;bTqsa@T -pA4X^qZd#rrV-0en:CVdrrrE%qmZV(li2J~> -l2NC4s8)9cs&Qi5s8G<VXu?;ASuFdNq_YOO49$h,[5.bEVmS;W6)1;3rq&1WVE4_V/bnf8&f(uh -!"T_e!:om^rquZgp%7qSrr;utrr;utrr;utrr;okp[R`01+FaL00q0=-7C2h-7C2e1Fja?mca00 -j7**P!WrK4!!!K/mk5b0-7C8k.P*1Gq"t!grr;upq"a^\q"a^\q"a^\q"agdjSoD_q==(KqtpEn -rq$0irr2fqrdk*srs&H$s8B;#qWn03~> -l2NC4s8)9cs&Qi5s8G<VXu?;ASuFdNq_YOO49$h,[5.bEVmS;W6)1;4rqAO_V`4PR#n&ge8PCm* -4@954rrr;r5!1YXq)SI9*B?/@3]T5Z7m&d2s7u]ppAYml8Ou9G6TRdDs$AL=48q;*s8W',rVlcp -rVlcprVlcprVc`qrVZQprVlfls8N#ps8Muus8ITL`;^&?rr;r'qYKOXJ,~> -l2NpCs8)9cs&Qi5s8G<VXu?;ASuFdNq_YOO49$h,[5.bEVmS;W6)1A;s8G6lU+l62q#::6=)iSF -GCFRM,PV3KrV66aqY9p^qY9p^qY9pcrVlsi76Nd064?:X;H$Il;H$Ii?WL#"rtI&$It)ctGB.gK -s%u-Y9MA&M7n#eurrr;pq"F@Orp^-_pA"O`qu6ZprqHfrrVuorqtTs`qu-JEs2Y-DrVliqZhjOa -s*t~> -kl40Ms7c3b'(,_lrs%rW*W?cJp([,u,38b6n.kul(&ng5hA?1os6L]irW_Qb#ljr$o(2o'*<Hf_ -+rha+n+QYVr;69_o_/4Srt52&o()P;p\=LXp\=LXp\=FNq<]Qmj6[j>.N]]f,6.iH"onW9$3gJK -lg*s+nF?&>o_%nNq>:'erVZQaq#L<^r;Z`hrsSf'q!mhFq#(0lrVZZj"T/,ss8DoorVQWjrV-Eh -qgn[nqum#qs80@ks*t~> -kl3jDs7c3b'(,_lrs%rW*W?cJp([,u,38b6n.kul(&ng5hA?1os6LZhrX%fg#lXc#q>Ugi9fGI( -90G<=q"jses8;rtn,<Ffqu?-PrtPD*s"Ql)2E"5h#=:sU6oA+I6jGF?rri?"rVZW^quHWcqZ$Eo -r;6Ekqu?Nkqu?QorVlfsrVZTlrUp*brIOmoqum#qs80@ks*t~> -kl3dBs7c3b'(,_lrs%rW*W?cJp([,u,38b6n.kul(&ng5hA?1os6_*'rsn>m!:fOGnc'2"A6Etl -H"L2!rr<#r!<2rs!;#gK!;$0h!;PjZ&Q3(F<D[.",BJHjHu>(-FX'?Irri?!qYL-Krrr>qq"OIS -rUU0bp\=U_r;R3%p\4IZr;ZcoqY0a\rVZWnqYpQpJc*so"TJ8tqmktkJ,~> -kl3F6nc/Ld###Msrs\r)!<3&nmg/sm!<;KirrE)d#5/3"rsJ<+oD\pmrW)ll$MaZ$r878L!X.N^ -rVlotr:'U`q%*8pn+lVAme6>Ip%J(Pp%A1R%/9>ep[RqNn+ZAE!"o21(]aU:#QXMSo_JF_qtp3a -pA"CTo^q_Fp&+F]!WN#gqZQ`iq"aabqu$BlqZZfjo_&"WrVllqrqQTmrr2rrrr)cnqu?Hmqu20H -dJjFLqt@Q"qY0@VJ,~> -kl3sEnc/Ld###Msrs\r)!<3&nmg/sm!<;KirrE)d#5/3"rsJ<+oD\ghrW3&r$i'`$s6L+"%hB$V -$3peKlMpk^rVcWorU9b<rqQNlo(W+^rVlcprVlcprVlcprVlips8Vrqs7u]nrt/'u7R^3I6UqI_ -li$_Ys8@NKJcGNF#6"Gm\GuF"m/MS~> -kl3gAnc/Ld###Msrs\r)!<3&nmg/sm!<;KirrE)d#5/3"rsJ<+oD]'qrs&N""mk^Jo\p,b(`O2) -'+PHdm,e6MrVuoor9""i.t`V5LQmaLH6`Ias8W)t^]4?2!<)fps8.BI_#FW;qt@Q"qY0@VJ,~> -l2O!Ds82`opBT3n!<3&\r"B#Es616iq[r8m%/^b4mMl!9i9V*V!;lQtq#:iend>Eis80jCR@9nB -Xe)/qV8\u&[0*eBZ*El(#G86-Vmre2_"b5hZ*U^AZ*U^<Y.UdEVR3_0Yakb'!!E?'!<E0#Y,oON -]=PS`\$iWGXfSP%Vl-W&o!S%p!jJc*rMojuqlTk!!O/p0[0a1DY-"h1ZaI3Ir367.r3?7*!O8t^ -[*c5`Z+\>RrTaE5~> -l2O<Ms82`opBT3n!<3&\r"B#Es616iq[r8m%/^b4mMl!9i9V*V!;lKmoDT9cp'guos8C9ZXgZ'U -`3Z\fY0*9@Za-j?Yd(L?o!J^u[CNBPYdDCE\0/>l\[]2[\[/`\ZG!EO]WelB"@GOK83oa:2$UOr -aL8MU[f<f>\@&cS\,Nl;\+-g*[IUd'[fX"I\,3T9\$i`QrNuR3s0hs8rj;U2!4;O/J[Ee2"L5Y` -T`+0UJ,~> -l2P,ds82`opBT3n!<3&\r"B#Es616iq[r8m%/^b4mMl!9i9V*V!;lU!q>V/tpBgWZoC'Q,X1?-U -^9"?LWQ(C8\@o\ra2uB:\\#Da\\#Da\\#Da\\#DN\\55`[(+6R]_T/V[^a8_^p(Jd[_K!`EI3Cl -I"HlW*Pf;4\,NcD\%0,`]=knm^VIXu[e$g)Yk,%"[(F-Q^B;0a]tOEWrOr6G!P,Z<Z3dnJ]=khe -['6dCrO;j9qmcX9!P#Rh[*c5`Z+\>RrTaE5~> -l2NF7s8Mfnn5ZX7*</=(Y!DeCViasYqEgaN56"35Yt+ahU9$iO<3)Wcs79$cS1aU9rs[TYp%7pW -o_\O`o)AXQrs/Q$q>C$cq=a[\,5Cj%o^_YFo^_bDn+H)@pZhDDo*HKT*#^+/*$t[]mc4!6rqQKg -s8LdQ!VuEeo`"O_p\ssfq#UBlr;Qosq=sd`rVufp!<;inJcF*s#5S2k[f?:)m/MS~> -l2NF7s8Mfnn5ZX7*</=(Y!DeCViasYqEgaN56"35Yt+ahU9$iO<3)QXr:*UdTeu`Irs%3Wrr<#* -r;Q]rpAFpnrr<#trposmrVuors8;oqqYL-jrqQL7r;6Nis8Vlos8!Kt6UO%/01\Y@s8)9arVZTl -r;?Nhs7-'grU]perpKgcrqZQordk*ars&;spU:,"rp9Z8~> -l2NdAs8Mfnn5ZX7*</=(Y!DeCViasYqEgaN56"35Yt+ahU9$iO<3)TZrUa'pUbqi@p@Zl2rVuo+ -rr2otp\Y!jrTO7]rVHNorqZHss7c9fp&G'err3BR@VB:YBi&Y\)?9a9p\t<nqtpBhnb_nP!;l0` -s8)fpqYpTnqLS[^rs&;spU:,"rp9Z8~> -kPm1,s8)cD*u:1Bb8))/s2bm*[djC8,o+l-]0$Y8s03sm^]2I[--#ub_@$dkqu-Nos82iq$G$36 -r;Zcjlhp\[li.1cq#C!ds8)Tl!WMokp^6Teq!@eEp\=LJs7cR%!U':Mq"aa_qu$Hmg&D-Qq>'p_ -s7llrr;?Qnr;QTn"T8)kqu20H])MiAs8;3_J,~> -kPm^;s8)cD*u:1Bb8))/s2bm*[djC8,o+l-]0$Y8s03sm^]2I[+hdgO_[mO,s8W)us7c?hs0qq# -qZ$Tjn+m"Sr!<9#qY:*_s8VrcrrrB$s7cQirr3JurW!'*!s\o7$NpUos8DTirr2rt*WH*<s8N&t -s8N&ts8N#qr;6Ehr;6Ehr;6Ehr;6H]s8W'"rVlfms8W&rrrE%Ls2+d;\GuKms*t~> -kPn$Ds8)cD*u:1Bb8))/s2bm*[djC8,o+l-]0$Y8s03sm^]2I[+Lq1C`=j'7s8;]hqY'jes181( -rVuoonGiIaqY9^TpAOO]#5\,po`+sfq#C3h(&.\*nbr+Xs8Vur#8nNq'G)-+)%5[&rtkY2qY'XT -o_/.YrVQQjrVQQjrVQQjrVQ0^!;l3a"8hrkrVQTsrVHBhrVuTiJcF!p!kA:.li2J~> -l2Ltarr<#ns8)`p"nqQfqZ$*ars8B!s7$'`pAaa^rr_WfrUKgcs8)upl0\KBq#13no=Ou$#6"Js -q>'pcl2Lb[mJdFfpAasgs8DcmrsJPnq>0j]nG*%`q;;2\rr;utrr;utrr;utroa:`rqlTjJcEF` -#5e5qppC"sli2J~> -l2Ltarr<#ns8)`p"nqQfqZ$*ars8B!s7$'`pAaa^ru:>)rUKperUp3hs8VZ^s75aYo_SFKYl4P" -rr)$[!<2ut!;Z?gq#1Woo)A=]rqZ6bnGN:c$2s`#rr;fkn,E:`rq6:"rr;utrr;utrr;utroO1Z -rW)oqrWN2trVlforr`8ur;Q]qp&9OBdJjFJq>U/rrVPp\J,~> -l2Ltarr<#ns8)`p"nqQfqZ$*ars8B!s7$'`pAaa^ru:>)rUKpbo]u;Ks8Voks7Q$aqZ$TcXRu5] -qu-Hm"oJ/ko_/.PqZ-Qnr;cTcrV6C"p[eFYs8VrfqWR_MrrVlbmJ?k_rVl]lqZ$L%s8Durs8Dur -s8DurnGa='qY9p`[email protected]"Xa`rrr;pq"t$gr;6Njr:g<hrIP!srs&ArrqNl! -qs494~> -l2M1fs6fpequ?Ths8N&srr3f1s8N≺Zfrs8Dutqu6Kjs8Dups8Vflrrr>toD/:\qYpQ,rVm,r -r;6<equ$HmrtbV3rqucnrqucnrqucnrr2lrs7lWorTaC_rVZ[#q!n1[s7c-an,NFeo)Aair:Bdc -rosFbrqucpJcE=]"8o_0rp0T7~> -l2M1fs6fpequ?Ths8N&srr4SGs8N≺Zfrs8Dutqu6Kjs8Dups8Vcjq>^Bmqu?]orr)Whp%nQh -rV?Hlp?2Ger;Z]hrr;forr;utrr;usrVHElq>L4)qt0g^r9jLYq"k!hq"k$gn,2qXrr)iqf`1mK -rVulrrVc`prquirr;Zfrs8;uts7?5@s3CWHr42k,li2J~> -l2M1fs6fpequ?Ths8N&srr4#7s8N≺Zfrs8Dutqu6Kjs8Dups8VW]nG)k[rqucrrVca"X7PiU -qt0gd"o\>pq"X^Vq[`K!qt'd`q"t$erVQQjrVcQl!;ufq')qY(p\*\?rVlfrs8)cqo]>f>r;@!" -rVQQjrVQQjrVb^T!r2K_rqQNirqHoqo^qbIqu-Egq"jmdr;Qrtq"Xa`rVZQmqY^*hqYc!Fci4+F -\c;Zps*t~> -q>Uj"r;ZEhq#1-jqu?$^rsAT$s8Drqs7lBbrr3&os8Drs&,c2%q>^Enp\Y!Xs8DWjrr)j'rVQWl -s8VlgrqcHj!k/..rr;lpr;R3)s8N&ts8N&ts8N&tgA_0PrVllsh#HsEkPkP]JcE=]"oeQ!\,ZEm -s*t~> -q>Uj"r;ZEhq#1-jqu?$^rsAT$s8Drqs7lBbrr3&os8Drs&,c2%q>^Enp\Y!Xs8DWjrr)j+rVQTg -s8Vois82irrr2oq"9,V*qVqM_rr;utrr;utrr;utli-_[q#1<orlkE@rWN9#s8W)ns8W)urrE%L -s24j?rr;l)s8D9`J,~> -q>Uj"r;ZEhq#1-jqu?$^rsAT$s8Drqs7lBbrr3&os8Drs&,c2%q>^Enp\Y!Xs8DWjrr)j'rV??_ -rVucks8Dcn"L7jurVcTmlhq4krVuirrVuirrVuibrr`5sqYU*g"8hrlrVZ[$rVuirrVuirrSRVV -rVQKfrVZNnrVufoqu?Tm!<;]iJcF*s"oeQ!\,ZEms*t~> -p\tj!s7H-es6p!Xs7#a^r:^-iqY^?or:g-h#4hcnnbiFYrr3,mq#C3frVm;ss8V<_q#9jas7cQe -q>UN&s8.BIJcDMF"oeQ!\,ZEms*t~> -p\tj!s7H-es6p!Xs7#a^r:^-iqY^?or:g-h#4hcnnbiFYrr3,mq#C3frVm;ss8V<_q#9jas7cQe -q>UN&s8.BIJcDMF"oeQ!\,ZEms*t~> -p\tj!s7H-es6p!Xs7#a^r:^-iqY^?or:g-h#4hcnnbiFYrr3,mq#C3frVm;ss8V<_q#9jas7cQe -q>UN&s8.BIJcDMF"oeQ!\,ZEms*t~> -q>Ud!oDeRbs8MEcp&+h'o)JO]s8DQhp%eC\s82<cq>^'arr3E&r:0gas8V`kp&G'Rrr3<"qu?Zq -s7u]pqt^6nZiBoRs+13FrrrE%qmZV(li2J~> -q>Ud!oDeRbs8MEcp&+h'o)JO]s8DQhp%eC\s82<cq>^'arr3E&r:0gas8V`kp&G'Rrr3<"qu?Zq -s7u]pqt^6nZiBoRs+13FrrrE%qmZV(li2J~> -q>Ud!oDeRbs8MEcp&+h'o)JO]s8DQhp%eC\s82<cq>^'arr3E&r:0gas8V`kp&G'Rrr3<"qu?Zq -s7u]pqt^6nZiBoRs+13FrrrE%qmZV(li2J~> -pAZ!*s80]#%KAEas8MBbqZ$Hmo`+seq#CBgrr32pn,N+]q"4Rcs6^O"mf3=_s763ip%/4Vn,N1Z -qtTpc!jhq(JcC<$U]1Mss80;*rTjK6~> -pAZ!*s80]#%KAEas8MBbqZ$Hmo`+seq#CBgrr32pn,N+]q"4Rcs6^O"mf3=_s763ip%/4Vn,N1Z -qtTpc!jhq(JcC<$U]1Mss80;*rTjK6~> -pAZ!*s80]#%KAEas8MBbqZ$Hmo`+seq#CBgrr32pn,N+]q"4Rcs6^O"mf3=_s763ip%/4Vn,N1Z -qtTpc!jhq(JcC<$U]1Mss80;*rTjK6~> -q#;'+s8Vrq-)ptB!<;lks8Dutnb2eTrW"8Jm^`ZEbl>X"*5V[TV]62ks/d[j_Yq7g'Y"+^*$`N( -s1g$'`q]B0!jhq(JcC<$U]1Mss80;*rTjK6~> -q#;'+s8Vrq-)ptB!<;lks8Dutnb2eTrW"8Jm^`ZEbl>X"*5V[TV]62ks/d[j_Yq7g'Y"+^*$`N( -s1g$'`q]B0!jhq(JcC<$U]1Mss80;*rTjK6~> -q#;'+s8Vrq-)ptB!<;lks8Dutnb2eTrW"8Jm^`ZEbl>X"*5V[TV]62ks/d[j_Yq7g'Y"+^*$`N( -s1g$'`q]B0!jhq(JcC<$U]1Mss80;*rTjK6~> -q>UftoDe4XrtEc[h\Q4k#lO8cr;ZZorrE&u,[email protected](0R&3@>s%fD^7JK$ASj!*LSubE]2P6^9 -nG?%ORnWVW!jhq(JcC<$U]1Mss80;*rTjK6~> -q>UftoDe4XrtEc[h\Q4k#lO8cr;ZZorrE&u,[email protected](0R&3@>s%fD^7JK$ASj!*LSubE]2P6^9 -nG?%ORnWVW!jhq(JcC<$U]1Mss80;*rTjK6~> -q>UftoDe4XrtEc[h\Q4k#lO8cr;ZZorrE&u,[email protected](0R&3@>s%fD^7JK$ASj!*LSubE]2P6^9 -nG?%ORnWVW!jhq(JcC<$U]1Mss80;*rTjK6~> -p\tX"s8)E0*WRLunGN+]s"4!Fs8Morqu?0_*o?E;n.b-X$2=H,na?nd#5.clq#^NX"oeT&lP/jg -#j_Ehq#:E%s8.BIJcDMF"oeQ!\,ZEms*t~> -p\tX"s8)E0*WRLunGN+]s"4!Fs8Morqu?0_*o?E;n.b-X$2=H,na?nd#5.clq#^NX"oeT&lP/jg -#j_Ehq#:E%s8.BIJcDMF"oeQ!\,ZEms*t~> -p\tX"s8)E0*WRLunGN+]s"4!Fs8Morqu?0_*o?E;n.b-X$2=H,na?nd#5.clq#^NX"oeT&lP/jg -#j_Ehq#:E%s8.BIJcDMF"oeQ!\,ZEms*t~> -q>W\Yr:U*es8VinoDejgrr;cns7--_rtYnZWrE(nrrE'!s82lsq#UNp!WEGprs8W3m/I(W'));) -s7cTooG.2trrTP,qgncus.fStrr;l)s8D9`J,~> -q>W\Yr:U*es8VinoDejgrr;cns7--_rtYnZWrE(nrrE'!s82lsq#UNp!WEGprs8W3m/I(W'));) -s7cTooG.2trrTP,qgncus.fStrr;l)s8D9`J,~> -q>W\Yr:U*es8VinoDejgrr;cns7--_rtYnZWrE(nrrE'!s82lsq#UNp!WEGprs8W3m/I(W'));) -s7cTooG.2trrTP,qgncus.fStrr;l)s8D9`J,~> -q#:Kqs7--Zrr5I^s82irq#C<hs7lWor;X5>rZ1Cl&-!:)p(%-#''\imrYjqn$iCP+k6q:soC3In -rsAK!#lX]$n]7o?\$;aOZF%*NY.&tfJ[4gO#Ip\<X1#I?[DB-QUrTd=]Dqiqs*t~> -q#:Kqs7--Zrr5I^s82irq#C<hs7lWor;X5>rZ1Cl&-!:)p(%-#''\imrYjqn$iCP+k6q:soC3In -rsAK!#lX]$n]7o?\$;aOZF%*NY.&tfJ[4gO#Ip\<X1#I?[DB-QUrTd=]Dqiqs*t~> -q#:Kqs7--Zrr5I^s82irq#C<hs7lWor;X5>rZ1Cl&-!:)p(%-#''\imrYjqn$iCP+k6q:soC3In -rsAK!#lX]$n]7o?\$;aOZF%*NY.&tfJ[4gO#Ip\<X1#I?[DB-QUrTd=]Dqiqs*t~> -q#:Baq#::aloYFO!<<&ns7u]hs7lEili47%q+Qs]3r_OBW&XYL;5p`^nP#LQ7fPf@]Kl*]SZ=aM -mmsI?:&jnds7l6bs8Tk0o_eahq18Qss7$'grVum!p&FQrrrqE^]CYpnm/MS~> -q#:Baq#::aloYFO!<<&ns7u]hs7lEili47%q+Qs]3r_OBW&XYL;5p`^nP#LQ7fPf@]Kl*]SZ=aM -mmsI?:&jnds7l6bs8Tk0o_eahq18Qss7$'grVum!p&FQrrrqE^]CYpnm/MS~> -q#:Baq#::aloYFO!<<&ns7u]hs7lEili47%q+Qs]3r_OBW&XYL;5p`^nP#LQ7fPf@]Kl*]SZ=aM -mmsI?:&jnds7l6bs8Tk0o_eahq18Qss7$'grVum!p&FQrrrqE^]CYpnm/MS~> -q#:d#rqufr!6bE:s8W#rrr4Y<qZ$T[3WKf0s0+!fbOige1V3Vd[Ls,%s1CJp`;d5)"j?qd$R43p -s1oTq`VB?-rs8P*q>^Kos8)_GqgnY7qZlQhs6TdWs6%5q#6+Z&qR?J$li2J~> -q#:d#rqufr!6bE:s8W#rrr4Y<qZ$T[3WKf0s0+!fbOige1V3Vd[Ls,%s1CJp`;d5)"j?qd$R43p -s1oTq`VB?-rs8P*q>^Kos8)_GqgnY7qZlQhs6TdWs6%5q#6+Z&qR?J$li2J~> -q#:d#rqufr!6bE:s8W#rrr4Y<qZ$T[3WKf0s0+!fbOige1V3Vd[Ls,%s1CJp`;d5)"j?qd$R43p -s1oTq`VB?-rs8P*q>^Kos8)_GqgnY7qZlQhs6TdWs6%5q#6+Z&qR?J$li2J~> -q>Vc1s8VZirJ.0Hs6]jdrV$3_q#CBms6K^bo'QJWq=jphrTjI_rVlg=p\k*[s8W)up&G$krVuK` -s7Q9ds8N&uqtg9krVcc*rr3&qs8ITLJcG3=!;lcq!Ufp$rs&5tqOd`dq<\-3~> -q>Vc1s8VZirJ.0Hs6]jdrV$3_q#CBms6K^bo'QJWq=jphrTjI_rVlg=p\k*[s8W)up&G$krVuK` -s7Q9ds8N&uqtg9krVcc*rr3&qs8ITLJcG3=!;lcq!Ufp$rs&5tqOd`dq<\-3~> -q>Vc1s8VZirJ.0Hs6]jdrV$3_q#CBms6K^bo'QJWq=jphrTjI_rVlg=p\k*[s8W)up&G$krVuK` -s7Q9ds8N&uqtg9krVcc*rr3&qs8ITLJcG3=!;lcq!Ufp$rs&5tqOd`dq<\-3~> -q#;H6o)JLT#QOi-#Pn5ks82irq!\7Ys8Vins8N&uo`+Xart4\hs8;oso)Jacs7c9ap&F[[qu6lm -s82irrqlWn#Hn%(p%&.\r.4iurpfsms7$'Ys8Vlf_#=Q<mf10"p%dtSJ,~> -q#;H6o)JLT#QOi-#Pn5ks82irq!\7Ys8Vins8N&uo`+Xart4\hs8;oso)Jacs7c9ap&F[[qu6lm -s82irrqlWn#Hn%(p%&.\r.4iurpfsms7$'Ys8Vlf_#=Q<mf10"p%dtSJ,~> -q#;H6o)JLT#QOi-#Pn5ks82irq!\7Ys8Vins8N&uo`+Xart4\hs8;oso)Jacs7c9ap&F[[qu6lm -s82irrqlWn#Hn%(p%&.\r.4iurpfsms7$'Ys8Vlf_#=Q<mf10"p%dtSJ,~> -q#:Ees7cHk!:'L^s7?9j&,lOus8)coq>^Hks8N&nnc&Olq#C$es7QBk!;HKm$2=K"r:]g`p]('e -rs&K&s82Qa[=S@/s6'C`r;ZW.rs&>is6m#gq<S'2~> -q#:Ees7cHk!:'L^s7?9j&,lOus8)coq>^Hks8N&nnc&Olq#C$es7QBk!;HKm$2=K"r:]g`p]('e -rs&K&s82Qa[=S@/s6'C`r;ZW.rs&>is6m#gq<S'2~> -q#:Ees7cHk!:'L^s7?9j&,lOus8)coq>^Hks8N&nnc&Olq#C$es7QBk!;HKm$2=K"r:]g`p]('e -rs&K&s82Qa[=S@/s6'C`r;ZW.rs&>is6m#gq<S'2~> -q>V3(s7--bo`+FYs8VTgs8)cos8;coqYpL%r:p<bo)JaUs8VckrrW#ro`"jnp@/+Mo)AXirql]p -#P@olrr2rkqtpBuZMjh'q>Ks\JcC<$nc&g^s7ZKm!;+#*"SD]os7bjZJ,~> -q>V3(s7--bo`+FYs8VTgs8)cos8;coqYpL%r:p<bo)JaUs8VckrrW#ro`"jnp@/+Mo)AXirql]p -#P@olrr2rkqtpBuZMjh'q>Ks\JcC<$nc&g^s7ZKm!;+#*"SD]os7bjZJ,~> -q>V3(s7--bo`+FYs8VTgs8)cos8;coqYpL%r:p<bo)JaUs8VckrrW#ro`"jnp@/+Mo)AXirql]p -#P@olrr2rkqtpBuZMjh'q>Ks\JcC<$nc&g^s7ZKm!;+#*"SD]os7bjZJ,~> -q>Up&s8Vlis2-8h-b]Q[qYgF&qYg9jo`+sbs7ZEkj8T)Yr>P_2s8DusqZ$Nos8;oslMpbXs7lW\ -s8Vrqp&=q#s82Wjs8TS-s8MciqY^?2rr`8urr14C!<2lq"8r&nr9XFcrqu]ndJj:Iqu$Bls8;lr -!WN#crW3&uj8T2[qu6Tp#6+8pru%7F_#FT9s8O10+TDBCqt^-gnc++~> -q>Up&s8Vlis2-8h-b]Q[qYgF&qYg9jo`+sbs7ZEkj8T)Yr>P_2s8DusqZ$Nos8;oslMpbXs7lTW -rr2cop\k*uqtU*hr3Q>$s82cprVl0`!<2rsrVlZn%K?D,s8N&ts8N&ts8N#rr;ciorrE&srSdbG -rrW,qrVQTprr)ffrmh&Crr2p"rquZkrr3'!rVb+C!r`#orVm6'rr;Zimf7>-oDHN+#laVspAeq. -p@S7^s8MZjJ,~> -q>Up&s8Vlis2-8h-b]Q[qYgF&qYg9jo`+sbs7ZEkj8T)Yr>P_2s8DusqZ$Nos8;oslMpbXs7lWY -s8VrqpAOprq=a[`rNuP's8)Qk!<)ln$iTu$qu-Ejqu-EjqtU-Lrr`/pqYT%I!<)Nd!<)0^r;HTo -ir/9ErVaS4#lX8fl2YZ$m/+["%JBA[!*fNoo)8UcqYL0]s*t~> -q>UNos5EtW0,_.lW#bp<nGi:`rV-?lr;ZQhs8Vopq>C6lqt^6krp]sfpAa^\s8VfmrVuKho_ndq -rr<#smelkXrqud%_>jQ4o^qPFr;?Tprlb<DqtU!WdJs4F!W;rqrrrDro(;\UrVlrss8Dor!;?9h -"oe>jp&"aarrrAss8Vurp\k?drr)imr;HWert4\knc/V4s8V?Yrr<#onb2eTrVQZkp\P!iqu-Hr -s8)cqqs==sq<.JOr;ZT_s"hs<eNEm$rqZQbpA"X5rsV6Hf%!:js75XAq>TsVs*t~> -q>UNos5EtW3#T*uW#bp<nGi:`rV-?lr;ZQhs8Vopq>C6lqt^6krp]sfpAa^\s8VfmrVuKho`+mc -qt9pfs7?0g"oSAuqmHA#rs&H%s8DimrU0^cr;ccpr<3,urr2lqrYPV6rVcZmr;HQlr;HQlr;HQj -qY9g[qu6Tp#PnArp@n@Qr8[bUrq$-lrq?![qu7<+oBlACr:p3dqtoj[q>:'erVlEg"TJ8ts8;Tj -!;-9j!WE&srr2irr;HR0r;6EirUU!cq"=^Yrq-6ho(i=brr)iprrE#js8Dp"s7uZnqX=D"qt0IZ -qYpH`r;ZB`!+JB,!;H$`qZ$3^q#Ab@&H2>'>t7Wim.gV\rVuoerVlKiJ,~> -q>UNos5EtW3Z5="W#bp<nGi:`rV-?lr;ZQhs8Vopq>C6lqt^6krp]sfpAa^\s8VfmrVuKho`+pi -s7lTlr9sOXrqcioqtp<#rquors8;co')VCpp@e:Tq"FLVq"FLVq"FLXrVHNj!<(sX"8)'NlMUY^ -r8R_WrV6!X!;l]os8Dor"T/5qs8;iq!;HKm#lFJnq"jshs8Droqt^Kko_SFXqY0ahlhL5Lo_AFU -rs8W(qY'[ap]($brrE&rrrE&os8DrprrE&`rtYG2q#CBis8(jB!*D6S!;,sarr;cjao;nMo\fd, -+#!]Yp&4LEnbW.Ss*t~> -q>V$$oDeCUr>)[4aTVY>rr2`lrr5+Sp[/"-!rp(X*Q.ok+Y:A)s3(lm])Tl"$GHJN)AU^#_B0rJ -r;X>?)U@sOq>'scqu?]&s8Vf\o_&"Wqu6ZqbPqeDq"=Oar;5"Ds8N#qrVm'!o^MDCkl1SgpAajd -rVulss82]n"TJ2eo_eRc(]474qu?]qs8MurrVlcprVHQor;Z6`s8Drqrri2ts8W)trt+o'o`"kC -R5"[8q"t*kqt0dbrW2omq#19krqQTlr8[eWqtpBt.C\('hVKWsrt"]Og>N#2aYj+gnauhWs7Z*b -J,~> -q>V$$oDeCUr>)[4aTVY>rr2`lrr4tOp[/"-!rp(X*Q.ok+Y:A)s3(lm])Tl"$GHJN)AU^#_B0f; -n,0O()UnQ_s8MunpA"N\pAOmcrVm#uqYL-hmf3(]rVccqnbiXgqY9m`rr)j#rq,XJqYT:NrVcit -rqHEprqH*^r;RGtr;$-Oqt0m^q=jgcp&"O]r;HWfrtbJ2s8)`prVuiqrVlcprVlWms8Dueqtg?m -rY>5(qtg*`rVZ0as8Vcm9*"nis7u?^qu6]pqsj[nrr)clqXO@TlhC2Gq$$HPmJm4crq6<k"oqOc -5s&TWrqZWcrqcHcde=(ChZ.4M8Q8=_qYgErp\XCWp&BO~> -q>V$$oDeCUr>)[4aTVY>rr2`lrr5"Pp[/"-!rp(X*Q.ok+Y:A)s3(lm])Tl"$GHJN)AU^#_B0iB -pA_Q2(sV[Lq"XUWoCi$Yq"j[SrVHNrqXjFTmeZq[!<(sX"7tmCo@s9Tqtg3dqtg3dqtg3dqtg3f -rri;tqu?0brrr)qp](-iqu6ftqY9j_rVulqrVHinqu-6drVQQhq$6TiqtU'Sp\jpf&c;P,rqu`p -s8N&soB60E!;-3`rrN,tpAb'hs82fl"S2?_mIp,C&bG5RoCVbIo^D&%!&c5Q&jHBqoDn7WoZH_7 -n^IP"#o5*T!;cQ`m-X<5s*t~> -p\tNsq>^9"0)up+rr4kSs8Vfjs8;osoKrWQ9T-)NoKT4>7K<3NWiA>Z4.<9KqFmTh4mPS;RlCBI -6F!.Dqu$6frr)is^&J$6p&+^^q>Us&q>0p`q>0p`q>0p`q>1*ds8)`ms8;rsqu7<.rVlcprVlcp -rVlcprVlcnr;HWo$N0bjrq6<kr;?Qmir8rWs8Muqr;7c8r;[email protected]:Rq#:9jpuD2; -rr2rtrqc?[p&=Xa!WMohrrDWerrDroq#C-kr;QQkrtG,+s6K\MfuV5Rs7H9is7Q0es8;Qi"oe/a -o_8=FrtU]@S!:=ORO>\\s8VlX_Cq.>WKX3Nq4uH9%%f5Ian,2gd]F5^rnHrBJ,~> -p\tNsq>^9"0)up+rr4eQs8Vfjs8;osoKrWQ9T-)NoKT4>7K<3NWiA>Z4.<9KqFmTh4mPS;R4eF7 -4KtG?s8W&rrt58/Z2=M!q#C<fqtg*_qYL-go)ARerr2rr!;ufm,5V38rr)iprr)iprr)iprr)ir -s8Dilr;Zfjs7?3fr;Zfrir&iQ!r;]hrVH]pqu$?jquZ`mrql^!p&4@Zs82`o"7-!Wrr2frrVlfr -!;lWg#Pe5or;??]p\=UflLk&Irqc]nr;Q`ps8N)rrVmT%o_n@Y!+nW+!<;ujoBH&Ms7c-Zrqlcj -qYL9lr;R0(qtTmKmdB,tl/h=(mhkERh.g/4>]F%h!+\8o8jZQl!*<<><bZ"<B@:B(BF8?L<'EEF -@0$9+h>R3Eq#0mcJ,~> -p\tNsq>^9"0)up+rr4kSs8Vfjs8;osoKrWQ9T-)NoKT4>7K<3NWiA>Z4.<9KqFmTh4mPS;RPFjA -5-CG:r;HBfqu-HuZi0dsnb`1ZrVm#tq"4:Yo)A^erqZQjs8Dip!WDoeq#^9\o`"jurUT@8o^r1` -rq,jYj8JEG%K6+rpA"Obr;ZWns7Q?hrs/8tr;Zfqqtoj^!<)Zl!;63gqYpNp!<)lr'_V7pdEqqa -/P6$.mI9c+gZ\G/pA4dg!;cQks83E(q=jXTnEfMsiT&SFh::*Je/6Z^`()^`6X2oG!&4p5)$:gF -!'<>?3_`&c9+Fl#=>23=*_^&DrU\+tp@A66~> -p\tBks8V]brr3;sl2U2<s8V`ks8MpNJT;(p#5Rfortaep$1.[!lg>#X!<;3^rrr&S&,uq#q]GY2 -$hO9'rqcKhrquK]pTX5g!<2Tf"T/#iq>'scs8;orn,ERjq=sjbrqufrq?6]fp%eU@s8Dp"s8N#q -qu-?gq[W/lm.gAHrUf%Cp%A(Pr;HWsrqlWfrrDucrs&>so`+pjrr)j#o)&Ieq"O^d"ZX]]s4]Tm -rs#*`Y`QMjV=UJaWk,k=rru-=p%mV!6G`[.-EH#!iP.#Fs7Yp]J,~> -p\tBks8V]brr3;sl2U2<s8V`ks8MpOJT;(p#5Rfortaep$1.[!lg>#X!<;3^rrr&S&,uq#q&Aqu -#OhNss8;fos8MfdpT45jrr<!%rVlcorr)iqc2[hCrVluqqZ$QQrs/Q%rVZWlrVZTl!rW#qpAYEl -s7QElr;ZHOrVlrss8W&s"98B!r;6?nqY^'arVQZjqY1!c"nqTWnEg/Nrtk8's8Vferr2cjnGuKK -<_*5gr:0=Ms8W&l!V#RQpC[6!rr)clq=jUSnn)'B8TRsBo4.f.*,P<Dn*f*"p%8;Z9L1X7!:]IH -lgXB1n*of8n*n]m&b52f6W@8a;ulXio`+mXq=jj\s*t~> -p\tBks8V]brr3;sl2U2<s8V`ks8MpGJT;(p#5Rfortaep$1.[!lg>#X!<;3^rrr&S&,uq#qAf2& -#k%KorVQEir<i5ior\)fq>'mar;HWtrVQHgiVsPfq"jd^q"jd^q"jd^q"jXLn,*+a$MsDeqYpNp -p?V,BdJj7BpAX[mq#16mr;ZEfq!n4Tl2(D[rSRW"rVuWlrVuirrVuieq>^Efp&FpalGrrH%5K:2 -h!!e\hp^$3rp9aKjnJ0Amg\[NlKIBjiDiHS2e#0Go1'B]85[gbdFcOhc,BZ)+VFbj!<1FLcdU@i -b0pjUjo?e_2DIl*s8V<MmHX9BJ,~> -q#:?\r;QfmqYpLgrr<#bq#CB^q#@ZVp&t'rs6'mX!<<'+s8N*!rW)s'qu6]s!rr9#o*,*m!WW06 -s69X_qu?ZhpA=a_\ao1`rVuWjq"OFQp%\C\r:Bmhr;-3fpC$ZdoC;>>mdBK0nbVkV%K#nlo_%tT -qu$HhrqksYpu)#CqZm&rqtTdSp\Xph&c;M#q>C9ks8N&uiq2s3q>1*grrN,qqY:*i"nM<_o`"jc -rs&E$s5a4[r9jRi38<]ts7OMnq>UW=VQ-r"QMREbVlQkuVkg#WR>Qk"rrDo_rrDlkrrta&i8$d# -oYLP5;7<p\2#mLNrr2p!q>1*`s*t~> -q#:?\r;QfmqYpLSrr<#bq#CB^q#@ZVp&t'rs6'mX!<<'+s8N*!rW)s'qu6]s!rr9#o*,*m!<<'1 -r8n"Uq>^KkqYpL+_u96(r;ZKirVlisrr)clq=F@^q>:-gs8Mfn!;uHb!;uir$2sbtqtp?frr;Nf -rrE&Vr:g'jqYU0grr3#uqu6BmqZ$Qos8W!0pAY*Urr;cnr;-6ap\4CVqu$?hr;Zd$oC`%Ss8N#o -r=&H!rSRSPp\jp`q"a^aq>C./rVZQckQ#6V7lNS.!:]aMmHF65b_9S@E+N#F@hE0W?=%#J@Us(X -AG5fdqrmqQoCsI$h=:"'q"!eAm.p,N6!.[uo\TE?p$);?p\=LXp\=LWde4"Aqt17n6>-AjoD\di -rW2imo`'F~> -q#:?\r;QfmqYpLSrr<#bq#CB^q#@ZVp&t'rs6'mX!<<'+s8N*!rW)s'qu6]s!rr9#o*,*m!<)j, -rT=1Xr;Zfmqu6U%_YN]op\OFTp@nL\!;l-_!<)lrqu%0)q>:!bq>:!bq>:!bq>9gJkk>#U$N9et -qu?]gqX!P?i;4#_qu-Ejqu-Ejqu-Ejp[J1J"7>UMq>L=)qt01?lhLA>s8Vrqq=jUWqt0pgpAt9f -p\uoGs8V3\s8N&np%S.Rp%S.Uq"ja]q"j[OfDmf5'+5U3!9*.qcagp8Wae@b:.$f55n?=R9MS>Z -;,^Ij<9NQ)m+Usr(Y\6:j7Dg0n_W?]!&$T(!9)>mmHNEniQCHrnb_eU/fdOaoD&@Zn*]l>s*t~> -q#<MSs6fpY!<<)_6hgQZq>^Kbp](9`7*kK;rrD3O+9)fCgB7?Q$1I-rjUgtB)Y4F-jWX=@g[bdP -o+LHg-3!o[m)6-6Yb7/nZ+%?VYe%-CX/W2(ZF.15\c9/=[f<`CZa-g>YHG%0XK/M3o=$B][Bd$@ -ZF.6S^8J3?Wj&S'[C*HN[^EQO[^EQO[^EQO[^EQO[^EQO[^EQO[^ERB[K!]5\,<cj[B-I9]Yh_+ -^7r0>SAW1]*R)$qb,r.HZ*h-T^;.S$]sY)MZF.-M\uWibbKRQ=`VI@V^Vmq?Xi8,tbl#ccbT=mM -dF5dtI#0Pac27P@qp;o)D47&oX-U*?j5]+[lh][ekje97mc`]de]cL[ZbX#E[^ETS\%&oW\%&oW -\%&oW][OR+\?*<b\\5_n0#+Hh.DEC"Z+mZR^p^YZ[C3KO[^`iX\@K,[\@K,[\@K,[\@K,[\@K,[ -\@K,[\@K,[\@K,[\@K,[\@K,[\@K,[[^r`S5-R0Lrs8Pcqu?<fp\"IWs*t~> -q#=Fms6fpY!<<)_6hgQZq>^Kbp](9`7*kK;rrD3O+9)fCgB7?Q$1I-rjUgtB)Y4F-jWX=@g[bjR -o+C6^+T;6;lc?NI]!%sX]=YP[Xh20W]tM%h\$i^7[/[Q6[f<i:\,s4P])K<+]!o,U[^EQO[^EQO -[^EQO\%92^\$i]O[()j7[B[9LXgkjK\$icS\$icS\$icS\$icS\$icS\$icS\$icSqmZL3r3[]X -]tM"bZ*1@9TY7\)^9aa<[\oqCZb`cT\$`TKZ*:F:[JmZ7[L'@9]WeuYVm<M+qPaatX/E^sXJi8$ -r2K[q*iZ6IZ_)VQFUMhW68qJ%:i$,+F`M\L>&ob"U7e<^qP/J3S!f_8StVpVVRNh0]XXrOYHG"1 -Xfee/Xfee/Xfee,[ALUPV5C;b['ZP-B1uV3WOAq2\Zi9MYd(F;Yd(F:YHP+4Y-5"3Y-5"3Y-5"3 -Y-5"3Y-5"3Y-5"3Y-5"3Y-5"3Y-5"3Y-5"3Y-5"4\u(MgA,u8ms7?9jp$r'4~> -q#<MSs6fpY!<<)_6hgQZq>^Kbp](9`7*kK;rrD3O+9)fCgB7?Q$1I-rjUgtB)Y4F-jWX=@g[baM -nIOp\,l[fWnB&,N\ZDRN]"5>UW3`\2Z*LaFrONBK]">Pc]">Pc]">QM]D]>>\0JGl[^NQO['m?M -['m?M['m?MYGA&&]u%Us[^rEM_7-eDQa,PY!4;@'*jMcGWiN8-\@\lb];)s9RK0=ZS].kLX1>UC -Z*LgLrkJKH%D0-Y['?1.Vm*7iUnOIXU'RBeTX]uXTqnCXTH9\uW2Pr#<Ghe.,ngG&)`(Lp6=X.o -8iBXiKS4r3N;A6WLPh+ROcu&tS=?UXT<kYlZE^[@Z*U^AZ*U^AZ*U^AZ+[<S_QC5ZXgbU.!+n\p -!2d61Y._*H]sP)PZF$pEZF$pEZF$pEZF$pEZF$pEZF$pEZF$pEZF$pEZF$pEZF$pEZF$pEZF$pE -ZF$pE[)/Va!($\LnGi+Tn`BK8s*t~> -q>Uirr;Zff%1iL>$E3aus"F3Js7lWj!W`H1!(a0)0DJ#0XBG,o8"m"Gs$``h2ZH:AY<;hDX0"\[ -r_Su\9)/Dc#kRHXp%5NWn+ck]#lFAenauVSrquBb!<2Ng!<2Tc!;uirs8;lr"o\K#r;?*2s8Vch -rrW2cq>UC$2PM;ns8Duhm.gMSrrE&]rrf7%WMc]oWW/psV?NluV3I:[rVm3I]]e\]gpnO,s8:jU -!<)Bd&GH._nb`+]s82Bes!FE^s8Drss89q;&GGo!s![pIrq5UPrqH'Tkkk&QJ,~> -q>Uirr;Zff%1iL>$E3aus"sQOs7lWj!W`H1!(a0)0DJ#0XBG,o8"m"Gs$``h2ZH:AY<;hDX05"g -s%o#V6h1*QrqH*brs$IBp\4CXp\Fghrpg!jrVQKiqtgBirqc`mr:'abrWrH!qsXFYrr2KfrZ2%< -s8N&ts8N&ts8N&ts8N&ts8N&ts8N&ts8N&trVufps8Duqrqc]prr3Z-p%.kOqsj[apZ;Hc!;H'S -s7l<ertYM0q=s^Zqu-KkqYBmZoCLu/nEB<-p[/7QmUU'E@:B.Cs'bq:(hIDl<`O[ooCMJPAlL]Y -6"0imroNqJp\Fg`"7u'Xq"j^cp$r%N!qGmSrq6Kir:]g_rq^L-qYC!`qYC!`qYC!`q;qPCs8MN^ -q>L!_l2Y>pp[7qOqsj=Tq>1!bqtg3dqYC!`qYC!`qYC!`qYC!`qYC!`qYC!`qYC!`qYC!`qYC!` -qYC!`qYC!`qYC!`r;Q]nl2gGLs8Vurs82fqr:L#>~> -q>Uirr;Zff%1iL>$E3aus"F3Js7lWj!W`H1!(a0)0DJ#0XBG,o8"m"Gs$``h2ZH:AY<;hDX0+e\ -rD&]W9)/Dc!W)QirsQdFqY^6ipA4RZqYU3j%f6)!qtg3dqtg3dqtg3go`#X(s8DfhqY9p^qY9p^ -qY9p^qY9^Xr;Qfpn,<7gp\OU^`r?DEk5\`enaH#JqtL*i!<)Zl$iBYdjPS,+c,7Q@chPrndaLc` -91MYO9c-Z):-UsW[GgK9!(/FQ-RD4^n+PZ+h;Ii&p]L-Xq"X^[!;6<^rUgEhp%\CUo(r4QrrVln -q"t'rr;Z9eB`Rbt_>b#Em*5U]l2CYZp[mhDs8DTiJ,~> -pAY?ks7u`qs6ose4n8RGs8;ojs8VZirrE)B((eIb_BBZ4s8'eS+M%Nl&KJsn_]Kc5p<=Nk]DMN; -,TOl)qYpNoqtTmVU@nN_rtbG'p%\Fas8Monqu$?hqu$?hqu$?hrp]sZqZ-WprrE&srs'kMs82fb -s8C(>!<)os"Y)ae^p5QVrs$$1XerV*WVNIoUopcbrt>>2.88OIc7Aq]q>^Kos8W&nr;Q]rrn.5d -nabu6s8;omq=t!i)?9U6p\Opiq>^H9rt+htq>\50s7tpRoDS^\o()\Ns*t~> -pAY?ks7u`qs6ose2=^_?s8;ojs8VZirrE)B((eIb_BBZ4s8'eS+M%Nl&KJsn_]Kc5p<=Nm_#OGI -+rA&loD/C`rs,k0rqlHbo(W%]s8;Ee!;uck!;ZWj!;ZTi!;l<d!WDrqr@7^>pB9dYq#0XYoDS[e -rr)iprr)iprr)iprr)iprr)iprr)iprr)iprr)lsrWW9"r;HQkrqdi9s8D]_mdBQ8n,)hN!!$G% -?NBW]q"spdrVZNep@\(Mrq?Bb$M<o[n^r1uBO>[`pgOJ7BP$GkmHj0;m/?;OmelMsnbrLd!!#tg -?3'oqs82Wbrr)]dq>C3hqu$EjrVZWlqtg<es7uZj#Q+5lr;6Egr:0Y"o`+p`r:'R_s7Q3[!;Z-^ -o_8=_pAOmbr;ccDq[WT(s76)irr<#ms7H0fq==Q9~> -pAY?ks7u`qs6ose1\(M=s8;ojs8VZirrE)B((eIb_BBZ4s8'eS+M%Nl&KJsn_]Kc5p<=Nj])2H: -,oao)qtg<mZMa_'q"F^^!;l`p&,l4spA"@VpA"@VpA"@VqtC'irU0O_qY^?qoBcP>rr3&qs75+J% -f?5%rVQQjrVQQjrVQQjrqHNjrVZ[/qsj^e;EIYSjP]Lunal;>n+$&DrVI*$p@Ib>k2F6h8P;9C4 -\#6<#=M<[ccsqih"0>5jno#C!!#2=8c\#8rVuicqrdt\r;Q`qrp]pfrV?Hsr;ZWoo^'?ms6'cSk -k>&Qs6oLMn+-L/~> -q>UH_rr3#rr;?R,p\Y!_s8VurrVuKhs82Tfs7-'f)Z'C3p%n^_s7c6do_SU`s7cQnqZ$EkoDA@\ -rr2ulrr33#o(`%N]D;:&s8;*\!;l]o!<2uq!<2ut!rN#op&>'hr;Q]t/"IsbrrV`jqY:'orVuTj -s7baW!;ufq!<2Wj#<Blgs7b3p9)S\kSY)UNrh^%$X0&G&Vkg#WOfmI=$hsGks8P'h0)th@p&=sk -r:'acrr<#nrr;ofqZ[!!s7l?frVllsqu6Zoo(gZ0"TJH$`;fi9r;Qitqu69gJ,~> -q>UH_rr3#rr;?R,p\Y!_s8VurrVuKhs82Tfs7-'f0DbVHp%n^_s7c6do_SU`s7cQnqZ$ElqZ$Qn -rr)c`qY^?ipAY*g^\7Nto^VSLrVlg:rqlKcqu?WprVlfrrr;utrr;usq>'maqssX^rqcX"r;$6] -qssXYqYMuErVlcmr:oj`@K?6%rq-3_rVcZmr;HQlr;-?_qYg$ar;HQlr;HQlr;HQlr;HQmq>Vf: -s8)copAOm]na,K#jlu4)mdC-W:eX/M@K>ETjn&%YCM@HoAnCpOs(24B#\[Y!i:Z^8m.^&D"SMEZ -p%A:Ws7cQgs7luur;Z`mjT&fkr;Q]tr;-?jrX8](rVlcprVlcprVlfprr2rrr;Q'_!<2rs$2jYs -s8W)qq"am's8W!(ppC"us8MunqYU3]s*t~> -q>UH_rr3#rr;?R,p\Y!_s8VurrVuKhs82Tfs7-'f)Z'C3p%n^_s7c6do_SU`s7cQnqZ$EjoDAC\ -rr2umrVm&qr;ZN.rVQTsqtTs`rVmE-q"a^\p\O[]q"jd^q"jmcrsJN#rVuipqtp6drU'UmqWlo: -6icTMs7u]jpAY-lmJeU2oCVYHoCVYAoC2ADlh'T&g"G-8i8WeWf$FCK,97CC493.@`m`=+r^ISo -92SDQ6UXI<:K1FrHJA&`qXOFUoCN(WqsaUkp@6u>>la*WptYlLrUTjcrV?HtrVH6ZnalOnqu6Tu -qsUHSq>UBrrV6*_o)F4~> -pAYumlZDFF(]_bZs8;ols8)]gs82ijp](!Urr3&ls7Q?j"oJ>orVucort>>*s7uZns7c']qu$?i -r:p<lpAY*lrWDu,s7H0fs8M`l!;?0e''0)js8N&rqYBs]p\+I`s7H?gp&>$frr3-U=No1#0`M(P -psT0[VLb87Xg5@>Vk93F/&Td%r;Ys!b=8,/M5K\?"8r2lroO1[rr;ltq<S%ZrrjDBs8;]imf*Ii -qtTs^q>L3jr;HTqr;6*]"oSE"q"XjerrDuprrN&no(^Z/!W2forr^"8rVl0`J,~> -pAYumlZDFF(]_bZs8;ols8)]gs82ijp](!Urr3&ls7Q?j"oJ>orVucors8Vus7uZns7c-as8W$% -qXa[anbrIdrsAP0qrdbKn+lk[rr3B*qt^'br:g-eqYKRTr!E8uqVM2Gs8N&tqYq]9qW@YAqY'dZ -p\+@Tp\+@Xl1t/>!!$A:<rgkJqrmnPqY1*Zo)ACco(_nJp]:6hrVQWk2Yle9q=s94>\[k[?X7#L -BkqbiE)]:Z9MeGj!)@?*Dt<JhnF,i6md9H1n*ol<o_.VHqt0jZnGW:^s8;fns8N#t#4VZfp[eI[ -rVmN.q>'mcs8N&ts8N&ts8N&ts8M]krVl-_!ri)prr3'!r;FD1%fZA'ppL,"s8Dikq>'pdoDa=~> -pAYumlZDFF(]_bZs8;ols8)]gs82ijp](!Urr3&ls7Q?j"oJ>orVucort>>*s7uZns7c$[qYg9j -rVHQop\t0rrVQ8ps7-$e"9&#gqY^?trV6?iqtodWrVum)rSmkQrVZQgq=saap'(9ls7cQmpAY[% -lML;4!!"o=2#tnprTX1Sp]9gRrqHQcq"=4Q47qq(lKINslKINhlKINfHV.429i"P^;c-7c!'VG7 -!#R"[email protected]\air2dhW=4kqqM,WoDeX_p&ORMnbCo>%K6(uq"jd^q"jd^q"jdb -qZ$HmrVlisrC$PZq"41Mq"X^\qY9p^qY9p^qY9p^qY9p^qY9p^qY9p^qY9p^qY9p^qY9p^qY9p^ -qY9p^qY9p^qY9p^qY9p^qY9pcrr_u!qYgEn"9&)kqXXZ:~> -q>V3+s5j8W_#IB#]cR4Mrr<#nrVuosp&4mpmf3:\s8Voort"`!s5X.Equ?9[pAb0Ns8;iq)tj-s -rr2corqH-ds8N&ds/c8#pA"1Qn+c\Rq>U6prr;uts8DWjs8E0!rpg$`q#:?nn,EVZf]i/&o?p>( -rro6_Xe)tpn>-,\rMBOk"d-*aX/NQ&rsJZ's!k\Hs5_D)3pZeMq#C!YqtU!Xp]13bs8Dp$s8Dut -rr;rjrtbV6rr;utrr;utrr;utrqlNeqtp<jrosFor:osXq>C6kq=sa\r;69ar5/I>r;6Nk[f#su -r9aN7~> -q>V3+s5j8W_#IB#]cR4Mrr<#nrVuosp&4mpmf3:\s8Voort"`!s5X.Equ?9[pAb0Ns8;iq(\dt! -s8VrprUo^[rqZHVrhKJlp%nF_q>1*srV?$\qXOFRqYL!gqYpHn!qcNgq>VT8p%S4XqYL!ar;6Eh -r;6<]naGiF>!b>39N2#Ylga!'qX+UWj^_8*?$0QGA--7MA,Tm:@3J<]=^tiYcL1;to'u8Aq#'jc -quBu1;E@`S!:94Ho(MkSrV-Hgq"jsd#Q4Q!rqHHfp[/"Zrq??sq=sdNq==L_r;-TkoCVqErtYP2 -qtg-aqu-Qos8N&ts8N&ts8N&ti;Y_7s8N&ts8N&ts8N&ts8N&ts8N&ts8N&ts8N&ts8N&ts8N&t -s8N&ts8N&ts8N&urr2f)s8N#t"o\AsrVlfgs*t~> -q>V3+s5j8W_#IB#]cR4Mrr<#nrVuosp&4mpmf3:\s8Voort"`!s5X.Equ?9[pAb0Ns8;lr'`IV! -mJ[(_s8Vris8DZaiUiT6s8Drs"oJ8loCVnXrr`9#s8DZk#lOPrq"j=OnbE"T#l+AnrVHQms82Zm -&c;4jn)sa=*YT)54TO[2n_)Ojcj.t=7Pmk)=$lII&P5bq;Gg=h;GfS_92net^u=SUm3V,Wj4XJg -2('/'6icB:naH&=n*TT6oChhDm-O-0oCVhSp&Fjcmf*:co(rggp]'jbq"j^Sn+6>Brs8Mnn+$#A -pA4a_rs\l+rVuirrVuirrVuifs8W#tqu6OUs8Durs8Durs8Durs8Durs8Durs8Durs8Durs8Dur -s8Durs8Durs8Durs8Durs8Durs8Durs8Durr;Qfp[J^%,rVQHgo)F4~> -q#;Q2s8N)hl3R1K$N'l$s7u]os7lWop\4^Us8VBas8)cqnbN%]!VuBarrqWdq>0sfrr*,pr:9mf -rq66i&(LXZq=O1<mI^2OrquZgq>UBorUp0lqt]gCrstKh/\C!,s8V`G[k3`/T;DC`!N33PrsJ\s -p\+VB_T(HF/+`f:rWr8dr;?Hiq"X[Vp]^Kkrr;utqu.$%rqucqqZ$0erqQ*_q#Bm`ir98]q=sa\ -qu$Biq>^3iq8*(=q=j^XYkRhbp\=X`nGe"~> -q#;Q2s8N)hl3R1K$N'l$s7u]os7lWop\4^Us8VBas8)cqnbN%]!VuBarrhQcq>1!ert5),oD\aa -mJZt\qn`4+rVuorq#;!*qY9d[r;-<fr;6Ehr;6HjrV$6js83/rp%.bEnF,l;rqHTcq"OR[pC[)[ -BlF&W><#5J6WI4g@VBOjqI^%EDsZrVn)*O'mfDkCqWn.G$g-a>kjS9Cq=j^^rr2p-o_&8f4'5ql -n+,T.qYU3fr;cimrrN#frVloqrSdbYnb_DErVm0%qtg0dqY'[^lMpn`s8Don!<)Kfn,Ejrs8N&t -s8N&ts8N&ts3goFrrN)0q#:?noDa=~> -q#;Q2s8N)hl3R1K$N'l$s7u]os7lWop\4^Us8VBas8)cqnbN%]!VuBartjo!q=s[[rVccms7cQn -q!.YHna3RJnbi@c"o@iXmIU,NrrE&krr_u`kk+iFqX4IPlMg/Qk3_O&q<S[L@ql!94q\nY)EL=f ->[h#5qF(WV:!1`#c+V<kblQ;KpYcD6iSi\XpA=a`rV-iqnCuXs3>t+b!;$'WqX=Fbrq5XX!WDfa -p&aOSkPkM]qZQWaoCi.OrsJYpn+#r>o_/(WrVHO&rVuirrVuirrVuirrU0\JrVuirrVuirrVuir -rVuirrVuirrVuirrVuirrVuirrVuirrVuirrVuirrVuirrVuirrVuirrVuirrVQTp]DV[2rVQQl -o)F4~> -q>V6-s8DF;\oV`gdnTlBqu?]prr;lqs82fq-Mld&p\44Qp&Fmfs6BFRs7Q!`mJleFs7ZKmq=ssh -jo>>>qt^-drVm9)s8O2@s82BKlL+EErsAW#m/HGPrp0RKqYom^"KA;i^6JJm%%s6\s8OCMaQVg! -^*Lc!$iB\ghYdER1runm+TDE@rWr2rrr;uqqt^-^rrE#crr`2pqt^'b%K-,$s8VienaYo:p\4L^ -rrW)mr.G"[r:fgTn>u9Qo'u5=nb)_UoDa=~> -q>V6-s8DF;\oV`gdnTlBqu?]prr;lqs82fq,5U@"p\44Qp&Fmfs6BFRs7Q!`mJleFs7ZKmq=ssg -jT#8Br;R*%r;,^Pm/ZSPrUp0qnc/+Ys6]jQp\u!-rU9OSna5W(j5AhNiT'@cBP(Lt;u1,=C4kCB -qZ'nm;GfMj!;QQanb;nR"7#XNmeunMo)[email protected]&Dp?q_Ss8Dlorr2p.n,N@Y!,,AB!:]d[ -qYg0err2lr!<)cl#Q+Apqt9g]r:9gUrrN)hq#:Epr;Q3c!WMuqq?-WmrVi)^!5%LqJ,~> -q>V6-s8DF;\oV`gdnTlBqu?]prr;lqs82fq,5U@"p\44Qp&Fmfs6BFRs7Q!`mJleFs7ZKmq=smb -hu3N:r;R*"q"!>+gAogko)8S/p?h#'kjA$;lhg)HrTO4CrVQQjrVQQioC),9jR)j5rp^9Xe'c60 -8jHfDqF_ArDU.Y3!'(u@*tCa?j6bjcq<S4AmH<R/mIKKBlgXcC#P%9Xq"FLPqYpL*rVQKjrVkpN -m,7q@6<aH_eGfOGnb<OZq#16frr)`jq"X^_lMh_"qtg$YoC;;:mI0cDqY9p^qY9p^qY9p^qtg<e -rq??drVAnVqY9p^qY9p^qY9p^qY9p^qY9p^qY9p^qY9p^qY9p^qY9p^qY9p^qY9p^qY9p^qY9p^ -qY9p^qY9p^qYL*gs8Th3s8Muds*t~> -q#:]ls7s;3-g1M6g@kOG$1RupqXOL`li-e\rrW&rrr2p)o`+p\s7lW[s8V!TrrqWdqsXR]rr35j -rql0ZjSAZMrs1-T9E5%iht6@#rrDlorsbNXVkKrdXg5:AZEL+3o)B*fs8O<I]tDH9s7#s[rs&H% -s7lQmpuhYunc/Xas8DfjrVuosqY0XTiqi]T4dI&es763fpA=jgrr`8uqtp0gs8;ormf*=cq>L3h -r;?Qnrsnedg[ah-p\Fggs8MT[qr[qYrW2rri;X5bs8N&ts8N&ts8N&td/OUTq=aRTZ2++fo'l): -o_J(XJ,~> -q#:]ls7s;3-g1M6g@kOG$1RupqXOL`li-e\rrW&rrr2p)o`+p\s7lW[s8V!Ts%_eXqsXR]s8N#a -s8Vopmf34]oD87V!+Q0#qu6'ap\t'apA"L^rVQ?cnau_Tqtg3dqtg3dqtf4Fp[*!*D.-dW>$+j, -=_D;flKdoin+uG_o(`7Zs7--k;GhE6rU^'gp\Y6fr;?$Ur9s.QrVQTl%JfthrVcHhr;ZfrrVlfp -rs\5dp[J;i!;cQVrVlWjrr)j*rVZTlqu$?hqss=Mo_n[YquH]crs&2rs8VWhrr)lsrr)lgrWrK! -q"aa^qu$EWs8W)urV-?lrkAC5rj_b'!ri/tp&BO~> -q#:]ls7s;3-g1M6g@kOG$1RupqXOL`li-e\rrW&rrr2p)o`+p\s7lW[s8V!Ts"!=5qsXR]rVQKW -rVuZmmJZkQlgO3(!(R%EmJ62Mo'tl"gu%/Um-X--jluO.#jq!*lK[AC<,)>?raH1E?!'^%cd:1R -eG@W+gZS+kn_!mB-mqXfjPoh%oDA@`#5A/to(W1TkPkYTs8VuorrW2trr)j'kje0(!)N[cqX!SK -s8)iqr9aOTr<E#nqsrkIq>C6qqtTgWqs47grVH6ZnaGl3n+cAKs8)cjrq?Bes8'P."oA#is8Th4 -s8Mucs*t~> -q>UNhs7H9i48o3Zr;ZT_o)JX^qu?]R49,Ynp;8<i]CWlL(XN-Taql/>rP9I!`9tAU'ZC$g(E1<n -s1&sW^%_@%q>UBt,F$?a74n!.%_8(0WiN/#WiN.g^S$gejSoVeq=t!i3OL=9rV6?js8)Ttm/HAN -rq69inbi@arqm-"r:Bg[nbMJFq>:'h!qcEirVm-=s8VWhrp9X`lMgk[nG`Lfnc&dgs8MK_rr)j! -q=XCSl2USYm/I@hq>($is8Mrq]DhlFrr3-#q"47Wnc++~> -q>UNhs7H9i2uWdVr;ZT_o)JX^qu?]R49,Ynp;8<i]CWlL(XN-Taql/>rP9I!`9tAU'ZC$g(E'sb -rjs3hbPqM^p&+[K!)Zic!!)]goCqb?kN;!on*fYjlfm]oE)ZRA'39Kg<GU^emIp>Oqu$ElrUK^Y -nc&=anG;qmp[RnTs7uBV!,V`3rr;rkm.pMU#OVQYs8Vfms6BOfrr;fos8)cfrVllsrqmT2o`"jg -qY'R^r;#UWs7$'crVZQjr;Q]crrDiarr<#rrr;osr;6@!pA=@Ys7u]pq=jX\r;Z<cqYp<jnbiRh -rVZWgs8Ms*rr)iprr)iprr)iprm1NJs8MukZMF=qr;Qlsq"Xg\s*t~> -q>UNhs7H9i=T/:"r;ZT_o)JX^qu?]R49,Ynp;8<i]CWlL(XN-Taql/>rP9I!`9tAU'ZC$g(Dja\ -rO<mcbQ%V>m.'Go!'WY!!!)`kq>0I9f@/4#gtpl'gtLN3@79rj#ZON?=%m)Wki)O+rp0gUn*9Q: -m/HVWlh^5cp@S+Zs7>I.!*90dq#CBkn,3%]"n2K[s8VlVrrr5us7u]drVuorq>U`ro)S"7h"Ld> -rr3-"qtg0dr;?`prVQQkqu6Nop@A1Mrr_liqXF@]"8;-LqTAj<rO`(4q"=Uc_#FB6qZ-T`s*t~> -q#:]ps8W)hs7cNks7Q?j4T5<[p\b'Os1o-C7%0oCs$3QY55P:,Y*i&]33B#?s";*_2?,h:UJ1Rb -6'S`3nb2t^rVn4@_;F#"XtBYQ%A0T(['-F$TUNQdX/`_srs&Apo^VSNq#:9onFuVU!U0F[rrjGC -s82Whrr;fl"nMTco)/+IquH`qr;ZX#p%e1Rq!n+Oq>Bja"oJ?"r;Q]arrDrqrrW&krnIGRrVHHl -"8MQaqsj[drqcNnrqu]nm/ICkqt^'crr2imr4Dt/_YsK9rqZH\s*t~> -q#:]ps8W)hs7cNks7Q?j:]:=np\b'Os1o-C7%0oCs$3QY55P:,Y*i&]33B#?s";*_2?,h:U.G"V -6'\uCqu?]ql1P*iA5P^";?61Nnmu6:?!h&QAl`tQ@:4$'lM9ZMlK@O!nFH;Hr;$?mp\t-mn+QSV -&cD:qrU9dcmIUDQqu?]kp\+R]rrr,rqtC'akl1hcs82irqu$I*rqu]kr;?HjrVH0_r:L$hr;Q]r -rqu]orV6Bmr;Q]sqtTX[!<2los8;lnrq['#q>9[Ys8W)sp\":Xr;ZBe!<2`mqu6Wo&cDV*rVZWl -rVZWlrVZWmrr)firrE&drAOTPr;HQlr;HQlr;HQlr;HQlr;HQlr;HQlr;HQlr;HQlr;HQlr;HQl -r;HQlrVZQcYk\"krr)j!qtKmap&BO~> -q#:]ps8W)hs7cNks7Q?j:]:=np\b'Os1o-C7%0oCs$3QY55P:,Y*i&]33B#?s";*_2?,h:TLJGL -6'o5Jr;QTehWOrA;E67#70)cAo4)!(;cHe%>=iEt<)[8Hh>5n8i8s(ck3VF#lL"!-n,DhYo`+jg -rrMchq#:^"s8Vclqrd;GnbD_U"o&&pq>^<Trs/N&qZ$Tls8N#ts8Dcn#Q"Dmip?4+qu6U!rVH<_ -q"XU[!;?Eg!VZ-SqZ-T`rri)nqYL0frr`&bn,%_:$MsMqs1\O5rVQKjn,In~> -q>V--rVud&!!*-$!s&8srr;rso`+jgs#BGS(&nd3oaUj8jn0>^rtOtp#lPb*miDB;l1Y5Y&Fnro -rq[N%lPTNrlMpl8Y,g1Gj4)>O315TZrrN,srqc]pn,NFequ?]qrVtgT!<;lor;?ToXoAD#r;Zco -!<2KfqYgNqroX7Zrr<#trk&11]);U.rp]r<~> -q>V--rVud&!!*-$!s&8srr;rso`+jgs#BGS(&nd3oaUj8jn0>^rtOtp#lPb*miDB;l1Y5Y&Fo$" -s7mDojV\!slMU2Q?qFO%6V1T^!,cEJp&t'^p\FXSq#:'lqYU3hrp0Rcrqu]mrr`2rqu$Ems82lr -ci<Y:qZ$EkgAh$Krr)corVluur;HTls7?6\rtPJ4rr;utrr;utrr;utrr;utrr;ugs#^5[rr;ut -rr;utrr;utrr;utrr;utrr;utrr;utrr;utrr;utrr;utrr;utrr;utrr;utrr;utrr;us#5nJs -[/Kt&r;Qlur;HWfs*t~> -q>V--rVud&!!*-$!s&8srr;rso`+jgs$?(\(&nd3oaUj8jn0>^rtOtp#lPb*miDB;l1Y5Y&Fnoj -q"5Emmiqf3kk=0>;`mT3,:l2F!+&jrn+$#Aq"jdZo(2qUqtU!`!;l-_"o\;mq"js&rrr;rq"jmd -rVuor!;kXOmJm1aqYpZrqYL/BrsAW#s8KP.rr;rqmf.e~> -q#="Xs7Xl<A]=TIrr2rtq>^?lrTsRVrs8\-nc8^i!<3'!rs&2s!;QQoqZ-Zr!;d!#q@*B(s8E)e -rri<#!WMckoDehRf[A[;gr)U3s+13Hrs&E#q7-J'rp9Z8~> -q#=.\s7Xl<A]=TIrr2rtq>^?lrTsRVrs8\-nc8^i!<3'!rs&2s!;QQoqZ-Zr!;d!#q@*B(s8NH! -rrDTc!<2ipm.o`CE)TD)=]YUmnG2t\r;uuurdk*#s0)G,r;QN%s8Dr`s*t~> -q#=4^s7Xl<A]=TIrr2rtq>^?lrTsRVrs8\-nc8^i!<3'!rs&2s!;QQoqZ-Zr!;d!#q@*B(s8;r_ -qZ?Zp$ig5)jQtIu@mVn(4$!Amh!4G'qgncus/Z/(r;QN%s8Dr`s*t~> -q>XOqs82iqs0jm1LuA='oDeC]s7lWjp&FEX+9*5Riu72%lf&rbrtb.e*rcN:o+:p0n)"oM&,PT% -r:qN2q%rbnoDYo?k;g)qa@SVE`RD-*\[f2Y[^EMo[Xkll[KX%B]?$WBlMlA~> -q>XOqs82iqs0jm1LuA='oDeC]s7lWjp&FEX+9*5Riu72%lf&rbrtb.e*rcN:o+:p0n)"oM&,PZ. -s7dGtmhGTnrr8^pXoMI%;ZHfbS@PH'[^EQO[^W_s[Xkll[KX%B]?$WBlMlA~> -q>XOqs82iqs0jm1LuA='oDeC]s7lWjp&FEX+9*5Riu72%lf&rbrtb.e*rcN:o+:p0n)"oM&,PQ# -qXts'qAoV4q"BlASH),H56(\:MQ3)HZ*LaF[^<Dm[Xkll[KX%B]?$WBlMlA~> -q>Uius8VZip](%s"r->$s"jZSr;6Nor;Zf5*q2@^\OZZP\Z%aarD9K&0CrG3XZHJSOhXKc8"ueF -qtig\Ud+bLnFHPX!]-rAqu6ZorVH]nq"X]:qgnXMqZm/rp[u)srVGm\J,~> -q>Uius8VZip](%s"r->$s"FBOr;6Nor;Zf5*q2@^\OZZP\Z%aarD9K&0CrG3XZHJSOhXKc8"ukM -rV&FDRQUNJ%K,qi!+#Z\nb2hRs82`nqZHcprVV6DJbubM#QOSnost,$qX"64~> -q>Uius8VZip](%s"r->$s$H_br;6Nor;Zf5*q2@^\OZZP\Z%aarD9K&0CrG3XZHJSOhXKc8"uhH -qY3@PUI5(]q=4"Ak2QG=!7'Win*]uFp\ssjp\+@WJbt#qZMOn,q"OHls8Df\s*t~> -p&@;Is0XU6MYHl9s7lWks8Vi^rriQ?ZM;im#K$Mc&Ke[cs.gD=ci:F%)8kjO/c`H^cl3nFr;X\` -(s_O;naZAErr39Fs8W)ts7l-]r;HWpquH_Is+13Trr`6"r4;.mJ,~> -p&@,Ds0XU6MYHl9s7lWks8Vi^rriQ?ZM;im#K$Mc&Ke[cs.gD=ci:F%)8kjO/c`H^cl3tLrVa>I% -F"GBrsSMuq!8"QpZqSRr;)!EJcD\K"9&8t]'96F~> -p&@\Ts0XU6MYHl9s7lWks8Vi^rriQ?ZM;im#K$Mc&Ke[cs.gD=ci:F%)8kjO/c`H^cl3qLs8Tk[ -'@64DqtTgEmHrp6n+#N0qtp3grrrAuq"FL]JcC<$Z2Xq)s89Ims*t~> -q#;Vss8Tl*ABFlOoDe^fp%A@Grr<#ls7QEis6fperVlinp]'pTrVm!!p](-fs8Vd:s7ZBPs8W#s -s82KZl.bt3qZ"Y:rU9ORp%S4Vr;HQkq>1#?rIOpQrVlg"rNuFrrp9Z8~> -q#;Vss8Tl*ABFlOoDe^fp%A@Grr<#ls7QEis6fperVlinp]'pTrVm!!p](-fs8Vcus7cQUrVQ'\ -rr)j&o)Ja]r4;RsoDJUirr)forrE%LrIOpQrVlg"rNuFrrp9Z8~> -q#;Vss8Tl*ABFlOoDe^fp%A@Grr<#ls7QEis6fperVlinp]'pTrVm!!p](-fs8Vd-s7u]\s8Vfm -s8DikoA]K;lh7m]q"":]"oJ)go_/05rIOpQrVlg"rNuFrrp9Z8~> -pAY0b"TAB,!WW<#qtg?mpAY(:mJZtZo`+g_s8VfmpAb-ls7u]ds7ZK_s8VNerp]a`s7ZKkrql`q -s8!B+p@RnDnG*"KYke%co%E[$qu6Tp"9/2prdk*#s0D\)qZ?fr\*<pC~> -pAY0b"TAB,!WW<#qtg?mpAY(BmJZtZo`+g_s8VfmpAb-ls7u]ds7ZK_s8VNerp]a`s7ZKls8Vrl -qsjCZqYpT`[/L".mJln[s8ITLJcDhOs8)ltrO;%kJ,~> -pAY0b"TAB,!WW<#qtg?mpAY(8mJZtZo`+g_s8VfmpAb-ls7u]ds7ZK_s8VNerp]a`s7Z<h$hEob -q"jj_q>L9Y[Jg+,mf3._rrrAuq"FL]JcC<$ZN't%!rr5.l2Q8~> -q#:s*s82ios8V`kp&G!es7cQnnG`G)qZ$Tns8Vrqs8D`ms8;osrVuons8W&sq#16mpBLZlrpKUV -rr)j.r:0FOp$hkUVtJs7nac5Grr)j!rqlTlJcC<$YQ"b&[J]gtm/MS~> -q#:s*s82ios8V`kp&G!es7cQnnG`G)qZ$Tns8Vrqs8D`ms8;osrVuons8W&sq#16mpC.)rs7QEd -r;HTks8W&srrr9!s0;Upqu?ZoJcC<$WrE5![J]gtm/MS~> -q#:s*s82ios8V`kp&G!es7cQnnG`G)qZ$Tns8Vrqs8D`ms8;osrVuons8W&sq#16mpB1His82cp% -K#qsqXaR^s82irZN'FhrrDrqq>gJFs+13Rrri5,r:p3Vs*t~> -kl3.%s7--hp]'gaq#Bpbp&Fdds82fqr;Zfls8W)up](6ms7Q*cpAFIUpAY!i%K?8!o_JLaYkRqe -o(`+Ys8Vusrdk*#s0D\)rWN9!ZhjOas*t~> -kl3:)s7--hp]'gaq#Bpbp&Fdds82fqr;Zfls8W)up](6ms7Q*cpAb!hqu?ZprVQTo"o\8prqs5( -rrE&trri;tqYU5Bs+13Qs8W'$s895"qWn03~> -kl2sus7--hp]'gaq#Bpbp&Fdds82fqr;Zfls8W)up](6ms7Q*cpA=miqZZ`jqu-Eirr3,.q>L9g -q>^HmJcC<$Z2ak'"TSD+qYKOXJ,~> -l2LbQrVllnrr2uYrr482s8DWjrVlfks763`s763imf3:Uq>^Kgs82TcpAFsarr;ioqu6o-rVl`g -r:U!brrW2trdk*#s/uA'\c;Wos*t~> -l2LbQrVllnrr2uYrr3i&s8DWjrVlfks763`s763imf3:Uq>^KgrVmB,s8MTbqt9gbrr)fnrNcG& -$2a_opA=[]qY^>Ds+13NrrTb2rTjK6~> -l2LbQrVllnrr2uYrr3i&s8DWjrVlfks763`s763imf3:Uq>^KgqYp]gpA"4Qqu6o(o_A4Sq==<3 -s+13HrrTb2rTjK6~> -kl1hcs6B.SlMgekq>9jbs7$'apAadQrVluupAb$ers8Aos7c?Jq>9m\s8W#t^%D=+rqubHs+13U -rri2lqtIP`s*t~> -kl1hcs6B.SlMgekq>9jbs7$'apAadQrVluupAb$ertbA(s7lW[s8Vlorr)cmqu$?co('*crr2p& -rquWgq"jmdJcC<$YQ"b%pA=Tml2Q8~> -kl1hcs6B.SlMgekq>9jbs7$'apAadQrVluupAb$ers8Aos8)c_s8Vilr;lrtrVm3#Y4M;Xq"X^_ -rIP!"s/Q)%qY'g\[d!gB~> -kl1YErr4JG1]S,[qpuYr\Gsba*kVIPUD46bs0O*i`9t/h!4i-W*#lopqm@X\aS5N1"M+R4qt9aa -!WN%Krdk'Rrr2p#rjVn(rp9Z8~> -kl1YErr4YL1]S,[qpuYr\Gsba*kVIPUD46bs0O*i`9t/h!4i-W*$*3%s19Wl`q00+p\Xjeq@9P$ -qt0IZqtg-aq"adarIOs!rilD$rri>1rql]]s*t~> -kl1YErr4SJ1]S,[qpuYr\Gsba*kVIPUD46bs0O*i`9t/h!4i-W*$!6's19Tja7TE3rVZ[&Vt0EF -l1k#Jr;?Qks+10#rj)P&rri>1rql]]s*t~> -kPm.-s8;`Zs0F$O2P@W<s"1aZ4S/JHW4=VQ>EGpIs%/<e8c(uNV*Y.T2kc]urqZQo_>aH9q>^GF -s+13Ks8Vs!s805'rp0T7~> -kPmU:s8;`Zs0F$O2P@W<s"1aZ4S/JHW4=VQ>EGpIs%/<e8c(uNV*Y.V4/\c4s8MfeqY^3er3Q:u -s8)`ps8;oo"8r,srdk*#s0;V(qZQrr[Jp0ks*t~> -kPm+,s8;`Zs0F$O2P@W<s"1aZ4S/JHW4=VQ>EGpIs%/<e8c(uNV*Y.U3iAZ6rr2utrVlosZi9e& -o_\LarIP!"s/Z2"qZQrr[Jp0ks*t~> -kl1\\qY^@AlllBAm-keX)X?9$s8Ni'k9'^0o(!@l$LZabmg]'Y'`[tGn*UYZqYL3l[Jp10qYBj^ -qu6Tp!WN"JqgnXKqZd*!s80;*rTjK6~> -kl1\\qY^@KlllBAm-keX)X?9$s8Ni'k9'^0o(!@l$LZabmg]'W%fQ/@p%B-uqYpHlrr<#qWqHAj -rs8Q&qtg*_q>'l<qgnXKqZd*!s80;*rTjK6~> -kl1\\qY^@?lllBAm-keX)X?9$s8Ni'k9'^0o(!@l$LZabmg]'X%fQ)=p%TC$rsJ`%poaGms8N&p -rquZmrIOisqm$#&s8Dup\,ZEms*t~> -kl3p<s8VZis7^YtrrDTh!<3'!rrr)q!;HKnqZ-Zr!;cs"q@!<'s8NT&rrMWa!;Q$[rqH$\qu">/ -oChkJme?PVJcC<$WrE;&r:d]#q"="RJ,~> -kl3I/s8VZis7^YtrrDTh!<3'!rrr)q!;HKnqZ-Zr!;cs"q@!<'s8E/er;lTk"98)ps7l9drs$11 -oDS^hrr2rprdk*#s02M-rquN"s7l9Rs*t~> -kl3[5s8VZis7^YtrrDTh!<3'!rrr)q!;HKnqZ-Zr!;cs"q@!<'s8<&ar;l]n#QOf's8)<]q"r#0 -qu6TqrIP!"s/5l$rquN"s7l9Rs*t~> -kPmO8s8VclQWsIb&,G`'r>"Dc'DDG>n+-e`*pE&4r"&)f!ril'm2Z0+)rolpo_/1M`N68LY,'4D -riH<uYH4q5r3Ls[J[2Pd"LP8;`hVeuJ,~> -kPmjAs8VclQWsIb&,G`'r>"Dc'DDG>n+-e`*pE&4r"&)f!ril'kn<^c)s?H1rVcceag&:dZ_PUI -[_'5Z]="uNZ%933ZE:D8[&gXSUZqf/~> -kPm+,s8VclQWsIb&,G`'r>"Dc'DDG>n+-e`*pE&4r"&)f!ril'kRmL`)sZc9rr3T'b,qhNXf9j_ -]=bh_\[8`LZMh"YZ@T<dZ37P9[)Sm*s*t~> -l2NF7s7ZKfs+Y.cqYrsWSk&`HX/%oTs!b4D:\clIUHec9[APt`5b"cIqYrjG[l3pTrX#q2qY^9g -qu$HmJcC<$WrE8%s80;*rTjK6~> -l2NF7s7ZKfs+Y.cqYrsWSk&`HX/%oTs!b4D:\clIUHec9[APt`5b"]CpAI:B\2sH]rrTP+qgncu -s.fStrr;l)s8D9`J,~> -l2NF7s7ZKfs+Y.cqYrsWSk&`HX/%oTs!b4D:\clIUHec9[APt`5b"`Cp&77D\i]cds8Mrs[=S@/ -s.TGrrr;l)s8D9`J,~> -kl37(s8W)n+92cLpWF-s_XtbW(s`-TbS_;9s2Q<1_<8KG*khTt'c4[bs100ca8#Z9ZiBoRs+13F -rrrE%qmZV(li2J~> -kl37(s8W)n+92cLpWF-s_XtbW(s`-TbS_;9s2Q<1_<8KG*khTt'c4[bs100ca8#Z9ZiBoRs+13F -rrrE%qmZV(li2J~> -kl37(s8W)n+92cLpWF-s_XtbW(s`-TbS_;9s2Q<1_<8KG*khTt'c4[bs100ca8#Z9ZiBoRs+13F -rrrE%qmZV(li2J~> -l2M4js8Dffs7cQfp](6fmJ[%lo`+p\s8)c^s8UpRrrqZep$)MQrr3/gs8VfmlhUP^ZiBoRs+13F -rrrE%qmZV(li2J~> -l2M4js8Dffs7cQfp](6fmJ[%lo`+p\s8)c^s8UpRrrqZep$)MQrr3/gs8VfmlhUP^ZiBoRs+13F -rrrE%qmZV(li2J~> -l2M4js8Dffs7cQfp](6fmJ[%lo`+p\s8)c^s8UpRrrqZep$)MQrr3/gs8VfmlhUP^ZiBoRs+13F -rrrE%qmZV(li2J~> -l2N=)s7lWomf3%Xs7?'dqZ$TkpAasfs6BIYs7>XXli6bNs7?9jp@J=ajT#8ApAY3#s8.BIJcDMF -"oeQ!\,ZEms*t~> -l2N=)s7lWomf3%Xs7?'dqZ$TkpAasfs6BIYs7>XXli6bNs7?9jp@J=ajT#8ApAY3#s8.BIJcDMF -"oeQ!\,ZEms*t~> -l2N=)s7lWomf3%Xs7?'dqZ$TkpAasfs6BIYs7>XXli6bNs7?9jp@J=ajT#8ApAY3#s8.BIJcDMF -"oeQ!\,ZEms*t~> -kl2:hrqHHmoD/.\p&G'jq=jphnbN+_&,lP-q>^Kls8DipmJlnZqYgEqq#Bs]rrTP,qgncus.fSt -rr;l)s8D9`J,~> -kl2:hrqHHmoD/.\p&G'jq=jphnbN+_&,lP-q>^Kls8DipmJlnZqYgEqq#Bs]rrTP,qgncus.fSt -rr;l)s8D9`J,~> -kl2:hrqHHmoD/.\p&G'jq=jphnbN+_&,lP-q>^Kls8DipmJlnZqYgEqq#Bs]rrTP,qgncus.fSt -rr;l)s8D9`J,~> -l2Lq_rr<#sq#:9qp&G']rr2umrr3N#qu>XTlMU\Sp%JFckl:JWrs/8tn,NFas8Mio!jhq(JcC<$ -U]1Mss80;*rTjK6~> -l2Lq_rr<#sq#:9qp&G']rr2umrr3N#qu>XTlMU\Sp%JFckl:JWrs/8tn,NFas8Mio!jhq(JcC<$ -U]1Mss80;*rTjK6~> -l2Lq_rr<#sq#:9qp&G']rr2umrr3N#qu>XTlMU\Sp%JFckl:JWrs/8tn,NFas8Mio!jhq(JcC<$ -U]1Mss80;*rTjK6~> -kPl(^s8Vfmme?SXrVuiaq#C!brrr5urr<#jrVm,ms7lNis8VEarr`2tqt9aa!jhq(JcC<$U]1Ms -s80;*rTjK6~> -kPl(^s8Vfmme?SXrVuiaq#C!brrr5urr<#jrVm,ms7lNis8VEarr`2tqt9aa!jhq(JcC<$U]1Ms -s80;*rTjK6~> -kPl(^s8Vfmme?SXrVuiaq#C!brrr5urr<#jrVm,ms7lNis8VEarr`2tqt9aa!jhq(JcC<$U]1Ms -s80;*rTjK6~> -kl1hYs8MQgq>L=9nc/Xfs8Vlls7Q3fo`+UYs7lNlp&Fm^s8Vros7cQkr;Q]ro(i:eZiBoRs+13F -rrrE%qmZV(li2J~> -kl1hYs8MQgq>L=9nc/Xfs8Vlls7Q3fo`+UYs7lNlp&Fm^s8Vros7cQkr;Q]ro(i:eZiBoRs+13F -rrrE%qmZV(li2J~> -kl1hYs8MQgq>L=9nc/Xfs8Vlls7Q3fo`+UYs7lNlp&Fm^s8Vros7cQkr;Q]ro(i:eZiBoRs+13F -rrrE%qmZV(li2J~> -kPm78qu?WfI/s<Daqbl3rPB]m`;f\T)'H<d^)%O/s25fr])9Ph'>OSI]HeE6s8W&rrr3<(s0D\) -qtg?mrIP!"s/,eur42k,li2J~> -kPm78qu?WfI/s<Daqbl3rPB]m`;f\T)'H<d^)%O/s25fr])9Ph'>OSI]HeE6s8W&rrr3<(s0D\) -qtg?mrIP!"s/,eur42k,li2J~> -kPm78qu?WfI/s<Daqbl3rPB]m`;f\T)'H<d^)%O/s25fr])9Ph'>OSI]HeE6s8W&rrr3<(s0D\) -qtg?mrIP!"s/,eur42k,li2J~> -l2NF.s7lWkrr@TSs6rU[Z9&"TTWD;es$rca2uc+BXZ6;NT!L?T0s7TGpARmTV+(%UrsSc%r;Q`- -s8W&ns8@NKJcD\K#5e5qppC"sli2J~> -l2NF.s7lWkrr@TSs6rU[Z9&"TTWD;es$rca2uc+BXZ6;NT!L?T0s7TGpARmTV+(%UrsSc%r;Q`- -s8W&ns8@NKJcD\K#5e5qppC"sli2J~> -l2NF.s7lWkrr@TSs6rU[Z9&"TTWD;es$rca2uc+BXZ6;NT!L?T0s7TGpARmTV+(%UrsSc%r;Q`- -s8W&ns8@NKJcD\K#5e5qppC"sli2J~> -kl3j6oDedds8N)mrsmcK(B4j:gB7?Q$1I0qkmd=D*V0d/koT^Ch=D!Rndk![+oh*1s8W&ts88qi -qZ$Kmp&0IAJcDSH!kA:.li2J~> -kl3j6oDedds8N)mrsmcK(B4j:gB7?Q$1I0qkmd=D*V0d/koT^Ch=D!Rndk![+oh*1s8W&ts88qi -qZ$Kmp&0IAJcDSH!kA:.li2J~> -kl3j6oDedds8N)mrsmcK(B4j:gB7?Q$1I0qkmd=D*V0d/koT^Ch=D!Rndk![+oh*1s8W&ts88qi -qZ$Kmp&0IAJcDSH!kA:.li2J~> -l2LbQrVnPCs6TgdrrE*!"8i0!rsJf+!<<'!rs/N&"9/N(rrD]qs8N*!rt,.l!;cTms8D`lrrBt7 -rrDtJs+13Jrs&;spU:,"rp9Z8~> -l2LbQrVnPCs6TgdrrE*!"8i0!rsJf+!<<'!rs/N&"9/N(rrD]qs8N*!rt,.l!;cTms8D`lrrBt7 -rrDtJs+13Jrs&;spU:,"rp9Z8~> -l2LbQrVnPCs6TgdrrE*!"8i0!rsJf+!<<'!rs/N&"9/N(rrD]qs8N*!rt,.l!;cTms8D`lrrBt7 -rrDtJs+13Jrs&;spU:,"rp9Z8~> -kl37/rVu*]p&>B_s!$Xp$2bS%q[)Wh$L@-drrW5b!<38siY)8!lMDUppBgBf$i^/8lc--3ZEBJ4 -ZEC=9Ye>UpJ[DA_"L5Y`T`+0UJ,~> -kl37/rVu*]p&>B_s!$Xp$2bS%q[)Wh$L@-drrW5b!<38siY)8!lMDUppBgBf$i^/8lc--3ZEBJ4 -ZEC=9Ye>UpJ[DA_"L5Y`T`+0UJ,~> -kl37/rVu*]p&>B_s!$Xp$2bS%q[)Wh$L@-drrW5b!<38siY)8!lMDUppBgBf$i^/8lc--3ZEBJ4 -ZEC=9Ye>UpJ[DA_"L5Y`T`+0UJ,~> -l2NU9s82cprUp0js78RJSk8rHVO'aOqEh3^6hN^1Yu(<kUTd)J8uS79s8P<hTfiAOs8Vrkrr35C -s8)Wks7lMCs+13Krs&H!p:1/!p[%p1~> -l2NU9s82cprUp0js78RJSk8rHVO'aOqEh3^6hN^1Yu(<kUTd)J8uS79s8P<hTfiAOs8Vrkrr35C -s8)Wks7lMCs+13Krs&H!p:1/!p[%p1~> -l2NU9s82cprUp0js78RJSk8rHVO'aOqEh3^6hN^1Yu(<kUTd)J8uS79s8P<hTfiAOs8Vrkrr35C -s8)Wks7lMCs+13Krs&H!p:1/!p[%p1~> -l2NL;s8Vuds7lQno`)<K-aWie+Y:A)s3(lk]`$+u%_D\N*=pg"`u?,Co`)?2)U\<Trr)j!q=LZ^ -rVlosqLSQqr2KSsrqcZl\`s-E~> -l2NL;s8Vuds7lQno`)<K-aWie+Y:A)s3(lk]`$+u%_D\N*=pg"`u?,Co`)?2)U\<Trr)j!q=LZ^ -rVlosqLSQqr2KSsrqcZl\`s-E~> -l2NL;s8Vuds7lQno`)<K-aWie+Y:A)s3(lk]`$+u%_D\N*=pg"`u?,Co`)?2)U\<Trr)j!q=LZ^ -rVlosqLSQqr2KSsrqcZl\`s-E~> -kl2_#qu?]as7H?hqu?$_s7H?gq>UEnnGiI_s7c-bs7ZHl&GcA%rr2fpp\k-jnGiOdq>L9l#.+@0 -qss^_JcC<$W;d)#rr;r'qYKOXJ,~> -kl2_#qu?]as7H?hqu?$_s7H?gq>UEnnGiI_s7c-bs7ZHl&GcA%rr2fpp\k-jnGiOdq>L9l#.+@0 -qss^_JcC<$W;d)#rr;r'qYKOXJ,~> -kl2_#qu?]as7H?hqu?$_s7H?gq>UEnnGiI_s7c-bs7ZHl&GcA%rr2fpp\k-jnGiOdq>L9l#.+@0 -qss^_JcC<$W;d)#rr;r'qYKOXJ,~> -^Ae<5s8VukrrTP,qgncus.fStrr;l)s8D9`J,~> -^Ae<5s8VukrrTP,qgncus.fStrr;l)s8D9`J,~> -^Ae<5s8VukrrTP,qgncus.fStrr;l)s8D9`J,~> -_>ac5s8MrrnGiL`rrTP,qgncus.fStrr;l)s8D9`J,~> -_>ac5s8MrrnGiL`rrTP,qgncus.fStrr;l)s8D9`J,~> -_>ac5s8MrrnGiL`rrTP,qgncus.fStrr;l)s8D9`J,~> -_#FW2s8N&os7Z9g!jhq(JcC<$U]1Mss80;*rTjK6~> -_#FW2s8N&os7Z9g!jhq(JcC<$U]1Mss80;*rTjK6~> -_#FW2s8N&os7Z9g!jhq(JcC<$U]1Mss80;*rTjK6~> -_#FW7s8Vurs7Z9g!jhq(JcC<$U]1Mss80;*rTjK6~> -_#FW7s8Vurs7Z9g!jhq(JcC<$U]1Mss80;*rTjK6~> -_#FW7s8Vurs7Z9g!jhq(JcC<$U]1Mss80;*rTjK6~> -_>a`(s7?9jr;HEj!jhq(JcC<$U]1Mss80;*rTjK6~> -_>a`(s7?9jr;HEj!jhq(JcC<$U]1Mss80;*rTjK6~> -_>a`(s7?9jr;HEj!jhq(JcC<$U]1Mss80;*rTjK6~> -^Ae>R*$)ilq>UN&s8.BIJcDMF"oeQ!\,ZEms*t~> -^Ae>R*$)ilq>UN&s8.BIJcDMF"oeQ!\,ZEms*t~> -^Ae>R*$)ilq>UN&s8.BIJcDMF"oeQ!\,ZEms*t~> -_>a`1s5uVCRRd/Q!jhq(JcC<$U]1Mss80;*rTjK6~> -_>a`1s5uVCRRd/Q!jhq(JcC<$U]1Mss80;*rTjK6~> -_>a`1s5uVCRRd/Q!jhq(JcC<$U]1Mss80;*rTjK6~> -_#FT-rsA2p!;QQqZiBoRs+13FrrrE%qmZV(li2J~> -_#FT-rsA2p!;QQqZiBoRs+13FrrrE%qmZV(li2J~> -_#FT-rsA2p!;QQqZiBoRs+13FrrrE%qmZV(li2J~> -_>b>Hs7uitp]^]js8W#lrr;r+rVuiis8Vr1rr`&rs7jS5"8MorpqHb4rr;rns8W&6rs/N%s8W)q -s80Y4#58)rrPAC*li2J~> -_>b>Hs7uitp]^]js8W#lrr;r+rVuiis8Vr1rr`&rs7jS5"8MorpqHb4rr;rns8W&6rs/N%s8W)q -s80Y4#58)rrPAC*li2J~> -_>b>Hs7uitp]^]js8W#lrr;r+rVuiis8Vr1rr`&rs7jS5"8MorpqHb4rr;rns8W&6rs/N%s8W)q -s80Y4#58)rrPAC*li2J~> -_#FT8rsJ#j!<3!-m)ulG\@8KOW4BOJXgl3Q#H5;AZF-jC\&ko\\$`BHZEq3B_6O<QYd_'G\>QgP -Z3S"FYcb[<^oY>Ws02X=Vu#]YJ,~> -_#FT8rsJ#j!<3!-m)ulG\@8KOW4BOJXgl3Q#H5;AZF-jC\&ko\\$`BHZEq3B_6O<QYd_'G\>QgP -Z3S"FYcb[<^oY>Ws02X=Vu#]YJ,~> -_#FT8rsJ#j!<3!-m)ulG\@8KOW4BOJXgl3Q#H5;AZF-jC\&ko\\$`BHZEq3B_6O<QYd_'G\>QgP -Z3S"FYcb[<^oY>Ws02X=Vu#]YJ,~> -_>b>LnbYhCY<i3cs8Vicr;Zf;r;$BfrV?H/rs-11rqZTlqYA85#Pn5os7uZg]>4FNq>C9cp;H^A -rs/Q"rVHH,q=hW'"SK>'s7bm[J,~> -_>b>LnbYhCY<i3cs8Vicr;Zf;r;$BfrV?H/rs-11rqZTlqYA85#Pn5os7uZg]>4FNq>C9cp;H^A -rs/Q"rVHH,q=hW'"SK>'s7bm[J,~> -_>b>LnbYhCY<i3cs8Vicr;Zf;r;$BfrV?H/rs-11rqZTlqYA85#Pn5os7uZg]>4FNq>C9cp;H^A -rs/Q"rVHH,q=hW'"SK>'s7bm[J,~> -^]+N1`[qeMoD8Cb#5I_aqu?]jrr9h5"0DP&rr)l=rVc`urr<#"_>X<3!rfS,_>X<3!j)D$_>OW2 -r;Zeur;ZTZs*t~> -^]+N1`[qeMoD8Cb#5I_aqu?]jrr9h5"0DP&rr)l=rVc`urr<#"_>X<3!rfS,_>X<3!j)D$_>OW2 -r;Zeur;ZTZs*t~> -^]+N1`[qeMoD8Cb#5I_aqu?]jrr9h5"0DP&rr)l=rVc`urr<#"_>X<3!rfS,_>X<3!j)D$_>OW2 -r;Zeur;ZTZs*t~> -_>ao5rVu]fs763cr;QZnrs-74q>U-dp@c?&#.+@0n+Z\Wa8ZABqY0IYs0KQA#5\,js8Vu"^]4?+ -!rDr'^&J91s/Q,!o'HC,~> -_>ao5rVu]fs763cr;QZnrs-74q>U-dp@c?&#.+@0n+Z\Wa8ZABqY0IYs0KQA#5\,js8Vu"^]4?+ -!rDr'^&J91s/Q,!o'HC,~> -_>ao5rVu]fs763cr;QZnrs-74q>U-dp@c?&#.+@0n+Z\Wa8ZABqY0IYs0KQA#5\,js8Vu"^]4?+ -!rDr'^&J91s/Q,!o'HC,~> -^]+K0s8Vrqp\t0rqt^'aqmHG'"8r3!rPAI8\,?:*rVt"=rVm!!s89@Brquctqn<$GrW3&urr3&7 -r;XV4"S_l_s/G8_J,~> -^]+K0s8Vrqp\t0rqt^'aqmHG'"8r3!rPAI8\,?:*rVt"=rVm!!s89@Brquctqn<$GrW3&urr3&7 -r;XV4"S_l_s/G8_J,~> -^]+K0s8Vrqp\t0rqt^'aqmHG'"8r3!rPAI8\,?:*rVt"=rVm!!s89@Brquctqn<$GrW3&urr3&7 -r;XV4"S_l_s/G8_J,~> -_>al@s76-gs8;cjqu6Nn#H@S"rU^'hqSE15_!V!srrD`6rrD`jrrW&a^qp$Ur;ZZfs7+>(_>ac: -qu?]b`pio>rrU%/q!7s1~> -_>al@s76-gs8;cjqu6Nn#H@S"rU^'hqSE15_!V!srrD`6rrD`jrrW&a^qp$Ur;ZZfs7+>(_>ac: -qu?]b`pio>rrU%/q!7s1~> -_>al@s76-gs8;cjqu6Nn#H@S"rU^'hqSE15_!V!srrD`6rrD`jrrW&a^qp$Ur;ZZfs7+>(_>ac: -qu?]b`pio>rrU%/q!7s1~> -_#FQ8s8Vchrr3<'r;HWorVlfrn,E=fp]&)/!;ZWo"8qups2k9?rrMrnrr2uo_>X]8s8Mios763+ -rW3&prr3&ms8Tq7#QOPurp]sfqX"64~> -_#FQ8s8Vchrr3<'r;HWorVlfrn,E=fp]&)/!;ZWo"8qups2k9?rrMrnrr2uo_>X]8s8Mios763+ -rW3&prr3&ms8Tq7#QOPurp]sfqX"64~> -_#FQ8s8Vchrr3<'r;HWorVlfrn,E=fp]&)/!;ZWo"8qups2k9?rrMrnrr2uo_>X]8s8Mios763+ -rW3&prr3&ms8Tq7#QOPurp]sfqX"64~> -\,QO+q>:-j#5/#joDejfaSuM;s82`fs8Voorr`/us8L%<"8ViooY1>/r;Zfgs7X;/"TJ2rq"t$i -"oA9!q#Bj.rsSi#rqucgs8W#sq>0FWJ,~> -\,QO+q>:-j#5/#joDejfaSuM;s82`fs8Voorr`/us8L%<"8ViooY1>/r;Zfgs7X;/"TJ2rq"t$i -"oA9!q#Bj.rsSi#rqucgs8W#sq>0FWJ,~> -\,QO+q>:-j#5/#joDejfaSuM;s82`fs8Voorr`/us8L%<"8ViooY1>/r;Zfgs7X;/"TJ2rq"t$i -"oA9!q#Bj.rsSi#rqucgs8W#sq>0FWJ,~> -\c2^!r;HWtp&FXRrVlolrQ5'@nGiCbrs%rls8;fpqo8X@q>^Hos8)cl_>a]7qu?*am_8]-qZ$Tk -m/Q_Rr:0dd!V?-7rs&E$qYgHjq#:9sirB&Us7bm[J,~> -\c2^!r;HWtp&FXRrVlolrQ5'@nGiCbrs%rls8;fpqo8X@q>^Hos8)cl_>a]7qu?*am_8]-qZ$Tk -m/Q_Rr:0dd!V?-7rs&E$qYgHjq#:9sirB&Us7bm[J,~> -\c2^!r;HWtp&FXRrVlolrQ5'@nGiCbrs%rls8;fpqo8X@q>^Hos8)cl_>a]7qu?*am_8]-qZ$Tk -m/Q_Rr:0dd!V?-7rs&E$qYgHjq#:9sirB&Us7bm[J,~> -\,QU(qt'jWrr3)so`+j0rrr<"p[/"Qr;Qous8W&qaSuJ9s8VlmrqjJ1!;QQn!W23!rt"i!s6p!f -nG`Ifo`+RYs8:4C%.X5prr;rfs8Vrgs7kp[J,~> -\,QU(qt'jWrr3)so`+j0rrr<"p[/"Qr;Qous8W&qaSuJ9s8VlmrqjJ1!;QQn!W23!rt"i!s6p!f -nG`Ifo`+RYs8:4C%.X5prr;rfs8Vrgs7kp[J,~> -\,QU(qt'jWrr3)so`+j0rrr<"p[/"Qr;Qous8W&qaSuJ9s8VlmrqjJ1!;QQn!W23!rt"i!s6p!f -nG`Ifo`+RYs8:4C%.X5prr;rfs8Vrgs7kp[J,~> -\c2[%rVm#fs)SCsrr3&ls8L.?!<2ut"Ss&;&XrXt!W2f9rs&2so_ngJ#JpEErUg,o!#)NNrsngQ -$NKkS4UE5-s69R`o[*U<q>UC%mJles"p2(#.Kgcpm/MS~> -\c2[%rVm#fs)SCsrr3&ls8L.?!<2ut"Ss&;&XrXt!W2f9rs&2so_ngJ#JpEErUg,o!#)NNrsngQ -$NKkS4UE5-s69R`o[*U<q>UC%mJles"p2(#.Kgcpm/MS~> -\c2[%rVm#fs)SCsrr3&ls8L.?!<2ut"Ss&;&XrXt!W2f9rs&2so_ngJ#JpEErUg,o!#)NNrsngQ -$NKkS4UE5-s69R`o[*U<q>UC%mJles"p2(#.Kgcpm/MS~> -\,Qd&s7u[#K+%_ZpAY'lm`>D;p$r(Zs8TDDs7H?gs8L+>#O29Ws8Upu#J^9BrX@)l%J@R;$3Yt] -s8-'Ho)8FRrr2uid/OXPs6fmdm.UJX_\<(Gq614ms*t~> -\,Qd&s7u[#K+%_ZpAY'lm`>D;p$r(Zs8TDDs7H?gs8L+>#O29Ws8Upu#J^9BrX@)l%J@R;$3Yt] -s8-'Ho)8FRrr2uid/OXPs6fmdm.UJX_\<(Gq614ms*t~> -\,Qd&s7u[#K+%_ZpAY'lm`>D;p$r(Zs8TDDs7H?gs8L+>#O29Ws8Upu#J^9BrX@)l%J@R;$3Yt] -s8-'Ho)8FRrr2uid/OXPs6fmdm.UJX_\<(Gq614ms*t~> -\c2s5s8Mlos5a(Xrr3#uo>gk2rr)j&p&F(fs7ZKkrPnjAr;$'XRt1^Yrs&?"q@VQ0*l%^aq#gQp% -K#qqs8W#es8:4C%f5htoD\dcr3@F?s7uR9m/MS~> -\c2s5s8Mlos5a(Xrr3#uo>gk2rr)j&p&F(fs7ZKkrPnjAr;$'XRt1^Yrs&?"q@VQ0*l%^aq#gQp% -K#qqs8W#es8:4C%f5htoD\dcr3@F?s7uR9m/MS~> -\c2s5s8Mlos5a(Xrr3#uo>gk2rr)j&p&F(fs7ZKkrPnjAr;$'XRt1^Yrs&?"q@VQ0*l%^aq#gQp% -K#qqs8W#es8:4C%f5htoD\dcr3@F?s7uR9m/MS~> -\,Qp:s8MlprsSYpq>^KnrlG*En,N+]q=0?)rVlrqs80q<#Pn5rp#m+d!5\[?r:Bra!W]+i_>b&/ -rrE)k&j6i#l2:SUs8VT9rt#)#s8W)dp%8:uU\XrhFFifYJ,~> -\,Qp:s8MlprsSYpq>^KnrlG*En,N+]q=0?)rVlrqs80q<#Pn5rp#m+d!5\[?r:Bra!W]+i_>b&/ -rrE)k&j6i#l2:SUs8VT9rt#)#s8W)dp%8:uU\XrhFFifYJ,~> -\,Qp:s8MlprsSYpq>^KnrlG*En,N+]q=0?)rVlrqs80q<#Pn5rp#m+d!5\[?r:Bra!W]+i_>b&/ -rrE)k&j6i#l2:SUs8VT9rt#)#s8W)dp%8:uU\XrhFFifYJ,~> -\GuU+s8NE!s7-0ds8W#rqT/[Ir;ZHis8JBds7?9cs8)cmao;VCs8MmObl7d[rri0<^r[M/rsT#( -rrU?i'*&"*s7l?8rso#-rq-6jp](8b*<5i(>jME?~> -\GuU+s8NE!s7-0ds8W#rqT/[Ir;ZHis8JBds7?9cs8)cmao;VCs8MmObl7d[rri0<^r[M/rsT#( -rrU?i'*&"*s7l?8rso#-rq-6jp](8b*<5i(>jME?~> -\GuU+s8NE!s7-0ds8W#rqT/[Ir;ZHis8JBds7?9cs8)cmao;VCs8MmObl7d[rri0<^r[M/rsT#( -rrU?i'*&"*s7l?8rso#-rq-6jp](8b*<5i(>jME?~> -Z2Y".s82Khs7+21&,cD's88Eds82ils8Vrqp<!=Fp](3l!!!]5%IsJps7$'^a8Z>A&^\K3r5&C@ -q>UHps#dX8*;9F/c2S=Os7?9jp](!b_%cg6@/g)js*t~> -Z2Y".s82Khs7+21&,cD's88Eds82ils8Vrqp<!=Fp](3l!!!]5%IsJps7$'^a8Z>A&^\K3r5&C@ -q>UHps#dX8*;9F/c2S=Os7?9jp](!b_%cg6@/g)js*t~> -Z2Y".s82Khs7+21&,cD's88Eds82ils8Vrqp<!=Fp](3l!!!]5%IsJps7$'^a8Z>A&^\K3r5&C@ -q>UHps#dX8*;9F/c2S=Os7?9jp](!b_%cg6@/g)js*t~> -Z2Y"Cl2UeZq!cB)%fQG-k5PGb!!MTel2UVRa8ZSErTjL`lNQhYqu?]ba8ZA=r;Vm#$(\j2%fHJ/ -jP)9eUAt)is82ipdJjaSs8W&hs5"Xp$H2`?!!E;gs*t~> -Z2Y"Cl2UeZq!cB)%fQG-k5PGb!!MTel2UVRa8ZSErTjL`lNQhYqu?]ba8ZA=r;Vm#$(\j2%fHJ/ -jP)9eUAt)is82ipdJjaSs8W&hs5"Xp$H2`?!!E;gs*t~> -Z2Y"Cl2UeZq!cB)%fQG-k5PGb!!MTel2UVRa8ZSErTjL`lNQhYqu?]ba8ZA=r;Vm#$(\j2%fHJ/ -jP)9eUAt)is82ipdJjaSs8W&hs5"Xp$H2`?!!E;gs*t~> -Z2Y'ls7ZKes8Vr;s8W!!p&G']rVm&ts8Dipn]Ce;rVuops6Td`s7?3h!WMl9rs/N&q#:<noCB`t -&,cJ-qu?]cs8N&js8;`nrmC`Qqu?Tos7cQnrr;inrrD]Xs*t~> -Z2Y'ls7ZKes8Vr;s8W!!p&G']rVm&ts8Dipn]Ce;rVuops6Td`s7?3h!WMl9rs/N&q#:<noCB`t -&,cJ-qu?]cs8N&js8;`nrmC`Qqu?Tos7cQnrr;inrrD]Xs*t~> -Z2Y'ls7ZKes8Vr;s8W!!p&G']rVm&ts8Dipn]Ce;rVuops6Td`s7?3h!WMl9rs/N&q#:<noCB`t -&,cJ-qu?]cs8N&js8;`nrmC`Qqu?Tos7cQnrr;inrrD]Xs*t~> -Yl=q*rVufqs8L+>%.F5pnc.qRp%n@]s7FA3&,?1is8VuerqZ6eqs4:^qoJd>jo>AF^Ae`?rVQNk -s7uQlqu?]gs8W)Ers\/is7c*Us8Vrjs7?!Ns*t~> -Yl=q*rVufqs8L+>%.F5pnc.qRp%n@]s7FA3&,?1is8VuerqZ6eqs4:^qoJd>jo>AF^Ae`?rVQNk -s7uQlqu?]gs8W)Ers\/is7c*Us8Vrjs7?!Ns*t~> -Yl=q*rVufqs8L+>%.F5pnc.qRp%n@]s7FA3&,?1is8VuerqZ6eqs4:^qoJd>jo>AF^Ae`?rVQNk -s7uQlqu?]gs8W)Ers\/is7c*Us8Vrjs7?!Ns*t~> -Z2XjrnG`Fgq=MZ+$gRcds8Vlor9"%Zou6q=nc𝔒ZforVufnaSuMCs8DornGN*rrsSW%li7"\ -s8Vrqs7Xh>s8;os#jM!]s8D'Zs6o4PJ,~> -Z2XjrnG`Fgq=MZ+$gRcds8Vlor9"%Zou6q=nc𝔒ZforVufnaSuMCs8DornGN*rrsSW%li7"\ -s8Vrqs7Xh>s8;os#jM!]s8D'Zs6o4PJ,~> -Z2XjrnG`Fgq=MZ+$gRcds8Vlor9"%Zou6q=nc𝔒ZforVufnaSuMCs8DornGN*rrsSW%li7"\ -s8Vrqs7Xh>s8;os#jM!]s8D'Zs6o4PJ,~> -YQ"b&mf3=^aSue?s7cQnnbi4^m/R+^pAas0rrDHcrsA>tp[J4Rs8VrmaSuMAs8;iqqu?Z3rs/)n -s8W&pq=O[d"8;cpnB_+Ep\k-lqt^*\s8Mcms5s:Hs*t~> -YQ"b&mf3=^aSue?s7cQnnbi4^m/R+^pAas0rrDHcrsA>tp[J4Rs8VrmaSuMAs8;iqqu?Z3rs/)n -s8W&pq=O[d"8;cpnB_+Ep\k-lqt^*\s8Mcms5s:Hs*t~> -YQ"b&mf3=^aSue?s7cQnnbi4^m/R+^pAas0rrDHcrsA>tp[J4Rs8VrmaSuMAs8;iqqu?Z3rs/)n -s8W&pq=O[d"8;cpnB_+Ep\k-lqt^*\s8Mcms5s:Hs*t~> -Z2Xmns8;lr!;sn;"T&/ks82cp"o[ras8Vo7rsJ\is8Vlms8Vrhq8WF<pAa^^s7O,+!W)HdrrrAr -p&Fjcd/OUMs8V?`s763im/6\Zs7kp[J,~> -Z2Xmns8;lr!;sn;"T&/ks82cp"o[ras8Vo7rsJ\is8Vlms8Vrhq8WF<pAa^^s7O,+!W)HdrrrAr -p&Fjcd/OUMs8V?`s763im/6\Zs7kp[J,~> -Z2Xmns8;lr!;sn;"T&/ks82cp"o[ras8Vo7rsJ\is8Vlms8Vrhq8WF<pAa^^s7O,+!W)HdrrrAr -p&Fjcd/OUMs8V?`s763im/6\Zs7kp[J,~> -Z2Xn(s7ZEk!<("=%JTc"o`+s`s8;osrV$!+rsnZ#rr;lps8V]js82iroZ7%9r;Zfls8Kh6&,?2! -s8VZ_s8N&urVuHgq9]-Bo)8Rf!<)lr"T&/hs7>UWJ,~> -Z2Xn(s7ZEk!<("=%JTc"o`+s`s8;osrV$!+rsnZ#rr;lps8V]js82iroZ7%9r;Zfls8Kh6&,?2! -s8VZ_s8N&urVuHgq9]-Bo)8Rf!<)lr"T&/hs7>UWJ,~> -Z2Xn(s7ZEk!<("=%JTc"o`+s`s8;osrV$!+rsnZ#rr;lps8V]js82iroZ7%9r;Zfls8Kh6&,?2! -s8VZ_s8N&urVuHgq9]-Bo)8Rf!<)lr"T&/hs7>UWJ,~> -JcD\K$i^,(rqQ?is7cQfqYpL&rqufbs8Vclq>^9frVm*#s8;Qis6kO=Zi>O~> -JcD\K$i^,(rqQ?is7cQfqYpL&rqufbs8Vclq>^9frVm*#s8;Qis6kO=Zi>O~> -JcD\K$i^,(rqQ?is7cQfqYpL&rqufbs8Vclq>^9frVm*#s8;Qis6kO=Zi>O~> -JcD_L"8)Nkqu6U'nG*"ZqZ$<io)JadrVmB'qX=IMs7bs]s763irUtgBZN#F~> -JcD_L"8)Nkqu6U'nG*"ZqZ$<io)JadrVmB'qX=IMs7bs]s763irUtgBZN#F~> -JcD_L"8)Nkqu6U'nG*"ZqZ$<io)JadrVmB'qX=IMs7bs]s763irUtgBZN#F~> -JcD\K#PJ,skP5&Vq#::#o_.tXp[nL^q>]j]rr`,to'u_Z#6"T$s7$'eJcE+WJ,~> -JcD\K#PJ,skP5&Vq#::#o_.tXp[nL^q>]j]rr`,to'u_Z#6"T$s7$'eJcE+WJ,~> -JcD\K#PJ,skP5&Vq#::#o_.tXp[nL^q>]j]rr`,to'u_Z#6"T$s7$'eJcE+WJ,~> -JcD_L%IF,nrq731!!W#pnc/:\rt4`"s7lWbq=FXPs8VfhpAb$UJcDtSJ,~> -JcD_L%IF,nrq731!!W#pnc/:\rt4`"s7lWbq=FXPs8VfhpAb$UJcDtSJ,~> -JcD_L%IF,nrq731!!W#pnc/:\rt4`"s7lWbq=FXPs8VfhpAb$UJcDtSJ,~> -JcDYJ(B"(0!<)ros7`Y[qZ$!UqYL6Xs8VZnrr3B#s6BX_o`+pbs8DYBs0VfV~> -JcDYJ(B"(0!<)ros7`Y[qZ$!UqYL6Xs8VZnrr3B#s6BX_o`+pbs8DYBs0VfV~> -JcDYJ(B"(0!<)ros7`Y[qZ$!UqYL6Xs8VZnrr3B#s6BX_o`+pbs8DYBs0VfV~> -JcD\K%IX/op'^Tks8W#X+WmHXrtN=!%3G$N!W_f!)%smerr?X.s8VM<s0M`U~> -JcD\K%IX/op'^Tks8W#X+WmHXrtN=!%3G$N!W_f!)%smerr?X.s8VM<s0M`U~> -JcD\K%IX/op'^Tks8W#X+WmHXrtN=!%3G$N!W_f!)%smerr?X.s8VM<s0M`U~> -JcDYJ,Q.-4$NL2-q>^3hj8f&KruR9cs7cNns8OOQW&XD@!TX4FpOW@Ms*t~> -JcDYJ,Q.-4$NL2-q>^3hj8f&KruR9cs7cNns8OOQW&XD@!TX4FpOW@Ms*t~> -JcDYJ,Q.-4$NL2-q>^3hj8f&KruR9cs7cNns8OOQW&XD@!TX4FpOW@Ms*t~> -JcD_Ls8)ouqYL9kruD$,-OBeQs7H]rs7lWg"8_usqu-TqrrE)qs8VkFs0M`U~> -JcD_Ls8)ouqYL9kruD$,-OBeQs7H]rs7lWg"8_usqu-TqrrE)qs8VkFs0M`U~> -JcD_Ls8)ouqYL9kruD$,-OBeQs7H]rs7lWg"8_usqu-TqrrE)qs8VkFs0M`U~> -JcDYJ"8)We!<3!=p&>01rrDikrud@%s7-*ro`$&DYVGtR!<;cmqtksEZi>O~> -JcDYJ"8)We!<3!=p&>01rrDikrud@%s7-*ro`$&DYVGtR!<;cmqtksEZi>O~> -JcDYJ"8)We!<3!=p&>01rrDikrud@%s7-*ro`$&DYVGtR!<;cmqtksEZi>O~> -JcD_L!:^!f,P)ZLnGi7\Sdtl&q!J+-,6\YYs.2mR[1!_Rs8EQ/s4mYSq18RQs*t~> -JcD_L!:^!f,P)ZLnGi7\Sdtl&q!J+-,6\YYs.2mR[1!_Rs8EQ/s4mYSq18RQs*t~> -JcD_L!:^!f,P)ZLnGi7\Sdtl&q!J+-,6\YYs.2mR[1!_Rs8EQ/s4mYSq18RQs*t~> -JcD\K-1g[,p\"LbrVulsp%n^]s8Dorq#16Wq>^Kis8VinqXaR_s7Z&8s0M`U~> -JcD\K-1g[,p\"LbrVulsp%n^]s8Dorq#16Wq>^Kis8VinqXaR_s7Z&8s0M`U~> -JcD\K-1g[,p\"LbrVulsp%n^]s8Dorq#16Wq>^Kis8VinqXaR_s7Z&8s0M`U~> -JcDYJ!W)WkrsSc"s8V-Zp&FjVs7H<j&F9Arq>('cq#C-gs8Vops6tU>Zi>O~> -JcDYJ!W)WkrsSc"s8V-Zp&FjVs7H<j&F9Arq>('cq#C-gs8Vops6tU>Zi>O~> -JcDYJ!W)WkrsSc"s8V-Zp&FjVs7H<j&F9Arq>('cq#C-gs8Vops6tU>Zi>O~> -JcD_L$M+5sqYfmXqZ$6crr2ulrVlrmqYC-j!V?9hrsAT#s6]gbmf3=^JcE+WJ,~> -JcD_L$M+5sqYfmXqZ$6crr2ulrVlrmqYC-j!V?9hrsAT#s6]gbmf3=^JcE+WJ,~> -JcD_L$M+5sqYfmXqZ$6crr2ulrVlrmqYC-j!V?9hrsAT#s6]gbmf3=^JcE+WJ,~> -JcD\K"o/#qq>^!aruLn7m/R(bq=s1Rs8Dorp&G'Ym/R%arr;`fs763eJcE+WJ,~> -JcD\K"o/#qq>^!aruLn7m/R(bq=s1Rs8Dorp&G'Ym/R%arr;`fs763eJcE+WJ,~> -JcD\K"o/#qq>^!aruLn7m/R(bq=s1Rs8Dorp&G'Ym/R%arr;`fs763eJcE+WJ,~> -JcD_L%fZM.qu>XTqY1$gs8V`irVm,js8;oos6fmbrs/,plMpVYs87HJZi>O~> -JcD_L%fZM.qu>XTqY1$gs8V`irVm,js8;oos6fmbrs/,plMpVYs87HJZi>O~> -JcD_L%fZM.qu>XTqY1$gs8V`irVm,js8;oos6fmbrs/,plMpVYs87HJZi>O~> -JcF^/s8Miorr1RMrr*T%rr;Kfp&G'is8MThs8)ces8;iprt"o)s7H?`s8VrqqZ$T_s8%<H[/YX~> -JcE"Ts8Mlp'D2>)nGi1\rV-<hmJ["Yrq$-cqu6U+q#CBds7H?kqZ$Els6]j_JcE+WJ,~> -JcFR+r;HTorr(LL'D)8(o)JIas82irnc/Xds7?9fr;Q^,q#CBds7H?kqZ$Els6]j_JcE+WJ,~> -JcFa0"9.ujrql^8qY]s_oD\des8Vros82ioq>^?bs8Dipp%\Odp\t0mpAP!kpAY'pqXjgemJZt^ -rqQKtqt:!es8V]irt4l&qtL-crVuops8Vloqu?Wnrr3N*rVQWiq>^Kfs7ZK_s8VflrsJc*q#:<n -rVufqq>UBonq$hrs*t~> -JcF^/-2RZArquTks8W#sq>^-frql`qqYgHks8;]mqt:!fqu??arr;`lrrDckrrDclrWN#gs8VWc -s!7UBpA+I[p%eISnG`.[rpg$fs7?9fp]($es8Vurs7lWks8Doqrt"u)qu?Hes8VclpAa[_s7ZHl -$NC)#rr<#ss8;omrr2uhJcFO*J,~> -JcFR++o([(qYU*gp\jUUq>('jqYgHks8;]mqt:!fqu??arr;`lrrDckrs8>urVcQas8VZ[ru:e- -s8)cqo)8LdoDe^^s7lQms82irq#C6krVc`q&,Q8%s7lEis7QEcs7--hpAY(!rr;cms8W&tr;ZTl -rrDV@s4mX)~> -JcFa0"TJ;qq"t'j#5J&mo(2YUrr4)-s8Vops8;osp&G'equ?]ns7ZHlpAap[q>L!ds7,j_rs8Q% -l21AUr;Q]prs\Z%s5X.Zqu?]fqu?TlrrN&mr;S>2s7lHis8Vcks75d]rVuZ`s8VNdqYL6dqt]g_ -mf3%Us8W#sr;Z]pr;ZQcJcFI(J,~> -JcFX-$MjGqrVlKes82`nrVn22s8Vops8;osp&G'equ?]ns7ZHlpAap[q>L!ds6oRYrr;ormJ6br -rp]jai;EECrVl?\rV6?krr<#rq#(.CkPt>Rrr<#krr;Q\s8Dumo)JaXrqcKkp\XdWs6fp]p](9k -s8;ops8;olp4<7ts*t~> -JcFX-2#I"ApA".Ns8)QfqY'^_mJm4^s8W#ss7QElq"t*kqu?Bhs7ZKfo_JIYs8VTZrVuoqs6f[^ -'DVV-kPtSZs8V`fs7uZmr;Zfpq#(.CkPt>Rrr<#krr;Q\s8Dumo)JaXrqcKkp\XdWs6fp]p](9k -s8;ops8;olp4<7ts*t~> -JcF^/!VlWms!%:=s8;]^q"t'br;ZZos8;ihs8D-\s7?9gmf2eVs7?-frr2p.n,MqVs8W)hq=ikG -o_eXdrVm<*o]Yc=kj\96r:U!brr3u7s60L_p](-Ys8Vopp&Fpfs8VWgs8Drns8W&krVluqs8Vfl -rsSDtnc/4Us6p!fmJd+b!W)M@s4mX)~> -JcF^/#5S8urqQ'\rr2uprr3l1q>^?ls8;ihs8D-\s7?9gmf2eVs7?-frr2p+n,MqVrr2c`q=iqL -q#(0lrr<!(rVQWjs8Vrqp\t3mrZ(_5kl:\Ws826as7u]fs82cps7-*grVlZns8DZirr`)ss7ZHl -$hF>fs7?$cn,NFTrr2ouqY#L?h#Dm~> -JcF^/-i<rBqXX"Hqu?]os8Vubo)8Ics8;ihs8D-\s7?9gmf2eVs7?-frr2p+n,MqVs8Vudq=inK -p\=aqp@nUYrVuTkpAb-kruCk7kl:\Ws826as7u]fs82cps7-*grVlZns8DZirr`)ss7ZHl$hF>f -s7?$cn,NFTrr2ouqY#L?h#Dm~> -JcF[.!VZNlrs/Dkq""+Oq=FRb$iL&)qu?]ks7Gj]rr2p(qt'ddq>^KaqtpBm"7cEgr;Q`rrW<#s -rqud,r9`56qsNb7p$i"Np\+Xdrr4#,p]($fs8DEdmJm4Js7#^]p%n^Qs7c9\s7H3foDS\#nFZ,J -li6eQs7u]bs7QEjrIP"%s*t~> -JcF[.#kIfhrqcHas8;lr!;6<j$iL&)qu?]ks7Gj]rr2p(qt'ddq>^KaqtpBm"S)NfqYp9is8E-! -s8Vols!RC;qu?Nmr;Q`rme?bVrr;rcs6]jdjo=iCs7Q6gl2UMPp&F[]rq$*g&Ff>Zs6K^\o`+ae -nc/:^rV_<Ig&HR~> -JcF^/#Q=,apA"@Up\b%&o_SF_s8;osqu?]ks7Gj]rr2p(qt'ddq>^KaqtpBm"7cEfqtg?mrVZNn -qW\"U$2aJon,<"\q>^EmruLP%s7lTnrU9dRs8V3\nFchSqZ#g[p\4@\o_\XZrVmGuo^2\Es7u<e -q>^!bp&G!hJcFF'J,~> -JcFR+/,]GFo^;/;mHsiOnc/OTrqcZpnbi1[s8V`[s7--hrVuoppAa^`q#16moD\amlMpkMq"aq% -jRW?Jn*095s8V]kMYmAQpAP!j!Vu?drrW3"nGE4do_SIb"7-!equ6U1r:p<lqu6Wgs8W)dq#BOW -nc/O^s71a@h#Dm~> -JcF^/0E1hIqtL-jrVZ]qqtC'hm/R"OrqcZpnbi1[s8V`[s7--hrVuoppAa^`q#16moD\^llMpnP -qYpKsrr)fnrr3#smf!.lr;HX+Q2gjapAP!j!Vu?drrW3"nGE4do_SIb"7-!equ6U1r:p<lqu6Wg -s8W)dq#BOWnc/O^s71a@h#Dm~> -JcFa0#6"Dhq"=7Wq>VW:l2CPJrqcZpnbi1[s8V`[s7--hrVuoppAa^`q#16moD\aolMpnMp\k!f -q@iYtl1+B,o(MkOqYU*qOoPF_pAP!j!Vu?drrW3"nGE4do_SIb"7-!equ6U1r:p<lqu6Wgs8W)d -q#BOWnc/O^s71a@h#Dm~> -JcF^/!<)lr!WLRF!!)3]rrDurrrM]`rr4#<s8Dutmf34ZlNHGOs6]j\q#BUYs7lWis7u`pp\Fh: -q#C@Fro2i8s8;Ef,i\_%s8W&rqu?]`q>^Ejr;Zfhp&":Zs8)chrVmf)s7QElr<Duqo(2nZs7Yj[ -s8;osq!nFbq>,[Bg])d~> -JcF^/%JKYtr;ZfP!t,\D!se/krW)lqrrM]`rr48Cs8Dutmf34ZlNHGOs6]j\q#BUYs7ZHfs7u`q -q#CBnrr)cmrr4;0!<;uds7b[S$o%#I!WW2urVQWpmJ6e\qu$Koo_&+Os8VrqpAP"0n,N(\s8</q -s75d]r;ZKXs8W#ss7l-bs7uMBs4dR(~> -JcFa0%f>bcp@eIbjUr[b*#TRdrr2urrr3#ip&=t6rr;rss6fpbpZhtGs8VKdp\=dQs8Vopq>^9k -rU]p_q#0n7oBbi)!:St(pA!kE!\EX:"98E"rVQWpmJ6e\qu$Koo_&+Os8VrqpAP"0n,N(\s8</q -s75d]r;ZKXs8W#ss7l-bs7uMBs4dR(~> -JcFU,0_b/5nc0@A)Bf+Tr9a@cDZ@!m+M@Hb&2:6coEBRJi"l@nquD0F4octcq#GsYf`1pNpAY1] -W>PR54o>:eK_YWI\-+Rmp[8T=!9F1Zr:g8On\HRa[/[?N$cW/?!/D$K!!!K.#^?;2!@ln'!.G1* -rr<Q0s8VqHs4mX)~> -JcF^/rr+VFoDeh(1,q3S$ig.jqZ^s<Z7@'1pV@CpXo@qrHO8UH!!)osIK)J2-f"LtIh:94rW)rt -:&b+hr;6Bho)MJbs8Mi`li.3-NW0%Z\-+Rmp[8T=!9F1Zr:g8On\HRa[/[?N$cW/?!/D$K!!!K. -#^?;2!@ln'!.G1*rr<Q0s8VqHs4mX)~> -JcFa02#I(Aq""+Xs!^]E=&pLEs7#skDZ@!m+M@Hb&2:6coEBRJi"l@nquD0F4octcq#H![gAh-P -;#C+ap@S"KoC(o*!)`gamdp/BqZ(>hrrW51">[:Wmga[EjT#5Wp]-<D_']f$s0*LO`W,Z4LCNMK -!"Jr6GQ0c+.bst&IL"O*!"T)0s8%<Hh#Dm~> -JcF[.2ZECKq<[JK.L[aH!:0I[r<;BU0s\bNs!GUg3rf-ZT>a@o"98$!iq39N_(,HbT#O%lrrrH" -q#:FNb/tt+rt#2#*9R>",e^!,s8N(qcoh4)s!S!#ruo+n3:8Z;djG+p!2mk'rs\kr!oEtUs4Jao -$(K:1p%o!ns8;bFs4mX)~> -JcF^/>Q4Hjs8Vrq##$dG3s>E[rqlr_o.dPi0)m98Z9&$a!M@>%o`P6e#NGCUs1p2b!1^tmqYpa! -r;ZfrrVZTjq=Xe^;?6Xln`TB@#Q,n7!WF@XUbDcJ!2\%)qu6UD"4mJq^;;kt28.Hcs8N(sa$K_6 -rUBsGs8DuN-MRn:cpdX)#QFc$qgne&s*t~> -JcFa0"9&)fnGW@j,&^P'>p0+G8d4DL0s\bNs!GUg3rf-ZT>a@o"98$!iq39N_(,HbT>s:prr`/l -qY'XToCMM>joALi!:9+@nG)h[pa#;0r?T(P0E;%PV9h@%rr4AKf)Ho-_Dps@^!e>.rrAt;62qAl -nH.SIrVtOtp^*G:7J6N_rr;onJcFO*J,~> -JcF[.s8FeI2Bi\4*tSl'!$3pLqZHll"98E-q[NT+#l+6"s7-Bf!rW''s8S?*'F=C6s7cTorrE&u -:@eGbqi?2_*N[!.S.UX>YQ+V'mu;r"oaLK^)#rk,s7??l!!*$!s8N'!$j-G6"oo5(rsA_u!<3W! -rr_upRj&+Ao+(g#!<;rsrVuZiJcFO*J,~> -JcF[.2#dOP6T$>*7QNIq$SO\"qucum"98E-q[NT+#l+6"s7-Bf!rW''s8S?*'F=C6rq6?lrrE&u -:@A,[mX]1l!+@fjAH6XYC#eq!ooF_*oaLK^)#rk,s7??l!!*$!s8N'!$j-G6"oo5(rsA_u!<3W! -rr_upRj&+Ao+(g#!<;rsrVuZiJcFO*J,~> -JcF^/J,T<Fs%GgJ0l:B,B.6DM5Q:icp&k?q#l>)3!!rAr"on,tp&b0l#QOgh*Y\nR!rr&ts8N)r -qYK=Io]:=,@fT_&BjLdM@WUo.$1j12!qcuon/22j#ljMtrr<'!!<<'!!"8r/#6k/>nG`gpo`5"' -n,EL`s-k2<"nN6(rs&Q(quH]qq"oXBh#Dm~> -JcFa0s8G"LqtTIEjo>c2%3PZ6o_ACcs8Oghs6ot:](5n$quHQl!<3E%rrE)h(<PnCrr`<$&G#K) -p@S:Zrr2urrr3'UdD@%'s#L/ZlQ-60*P8Bip\t6nrrE#os6g9on1)iYp\u8Ns8W#s!:g'jo`4@Y -!<<!&eF3bD!<;cooCidipjrJ!s*t~> -JcF[.%/9f%q#C@"1.sPq"o\H#F9)@@0u3hXs!bPMs8Vusq>LBo$Mj]%s7$lHli@%frr*K"oagch -qtL*br9jFWp]+T!!;cB\jR2aKs61C$rZ/VP)#+%1s8N)tqZ$!js6qMcp%SJ,_Z0Z6rrDTh!qcQ[ -rrE)t#Lr5KrrE)n!V?$rp\9=>gAc[~> -JcF[.!;QKl"XmMo?Y^nbs)\8@s"V=hn,FiJo)Jaf!;ZTorsJT%!<;R)am9$-"98B6o(<IanFlAF -n+>`4mcXXa>la0Tna6&B!WD:("TKLSX;L^3!<<'!rVHQ_$30KEdIm86*Q%jVr;QcerrVinm/I(c -r<LjA#lao)pAsm[&,5jMs4[L'~> -JcFa0%K?5!q=jC<lMr4O$n;8VmO%o5s5q6=);P#=*Z!,hrrE)s%KE(ZnIYa#9)o8-e-,gO!;-;\ -7fE>erql]s15d%Is#^;]s.Bkp_uq1.s7u`frrDoqmf*:en%fhOjnlt9'A`We!<<'!s/\TW%dO'i -!"/ej&HDb1s8ScZs7,o9s4mX)~> -JcFR+2uW@J#"_6=9a1RopAY-mk/82Vh"]JB(=;FJ!<;s+s.D:?&HDc'!!s+a"TJB#o`(COs8N&t -p\k"[q"Xn[#QOhpmHXZRs8A8fo>CbRci<hAo`"pfs6fmes6mc@&*<],*#%0,rrE*!!<9,fn.+a` -:B1b&kRddo!<<(m6N?TOJcFO*J,~> -JcFI("X7_q<c'&Zs)nDBk/82Vh"]JB(=;FJ!<;s+s.D:?&HDc'!!s+a"TSK%o`(=Jqtg0an+HDJ -oB#6;7KDoIlgX<<!<)kb#kZ%<+4'u`!;-9kqZ$!`!<;N((_>a*`#KHHrVlltrrE)#6gtTNs%`V& -!9b!orrE*!TgJeLq18S$s*t~> -JcFa0#QFAjo^q\GmeZtdnb)_Drr4#6s5CEdk5Y1pr;Zfrs8W&ns8Vfiqu?]qp]'a_pAY'qrqu<d -s8Drs#lXSrq>WSFp[.t[!qZ<arVlurs5WhOrt5),s763ir;Q`rqt-f`s8Vtprr35ls8ViZs8W)s -rsJ>sqY'ses7H'cnq$hos*t~> -JcF^/%/g/&rVHQo%0d"L$jHY1!:9^b*r,co[f>LipVm(1s8N&urV?KnpA=aes8McmnG`(Zrr4&= -oDejerr)fdp&Fg[)=RUsrqH3Ys7c?cpAXpgj7`HO&c)J,o)Jafrr<#qoV_Tds8/bors/#ms7bjZ -s8Mus$M+5npAb'jo_8CVJcFF'J,~> -JcFI("X+p2/g_P:rrDKdruLn7iO8dKs7aM1s8W)us8Dcns7Z?es8W)ms7$'_rVm#tnGW7Wrq[Du -m.'6,'ArECo_/(IqXaO[q>^<kj7`HO&c)J,o)Jafrr<#qoV_Tds8/bors/#ms7bjZs8Mus$M+5n -pAb'jo_8CVJcFF'J,~> -JcFa0*<,j2kPY2Iq![b4mdBW<k4elEo`+m`s8Vins6K[a"8DiqpAY(!fDkgArVu]cr;ZKhrs/E" -r;QZcs8N#t$hO2lp%e7Tqu?]qo)/Lpp%\Ods7Q<ep\*bKrr`8ss8)`p)#F%)o`+XRs8VQ^s8W&r -s8V?Vs8V?`qtKse!;;!Dg])d~> -JcFX-#OMKip](0kq#14%med%Ro`+m`s8Vins6K[a"8DiqpAY(&fDkgArVu]cr;ZEgrr<#rrVm#k -s8)`mrr3#jm/I"hrr)Wlq>^KorX/>nrr<#kr;66^k5PA_rqcZkrr3i3q"s^`p@&%]n+Zk^rVccr -l1P)Vl2UYTqYpQhJcFL)J,~> -JcFX-"7Z?jqYC.#nbiFVo`+m`s8Vins6K[a"8DiqpAY(!fDkgArVu]cr;ZHgrrDrqrt>8!qtL!a -qXX:DjnAKEp%\7Wnc&CorVuQcrr<#kr;66^k5PA_rqcZkrr3i3q"s^`p@&%]n+Zk^rVccrl1P)V -l2UYTqYpQhJcFL)J,~> -JcFa0"TIKZrqHEl+S5*sp##99rr;lqnc/X]s7ZHls8Mues8W&os7--ds82cp!rN#mrr4>9lMpkT -q>C0is7--dr;69hs82H]r;-Ejnbhn?s8W&rs7cQls8;lr#lF>qp@81_pZ_YV!;$3i!VH9grs88s -r:p<lrr;Tgrs8MqrV?<is7uJAs4mX)~> -JcF^/%-dflp\t3mp\=dgm/$_](]47&s8V`kpAY*lrr)Bes8Dfonc/Ldqu-O&qu?Hirqu9Ns8Vil -rVluirqH?frt>80qu?]ks75ITs8Dorp](3lr;Q^%qtC'`nc/X`l2CV^oD\ajo_\Xf#k\/pq#CBn -s7?3h#lF>oq>1-kq>#UAh#Dm~> -JcF^/-ggs6p&"XbpA=mio)/Obqt^9^s8V`kpAY*lrr)Bes8Dfonc/Ldqu-O&qu?Hjs8DKQs8Vfj -rVmQ$s7lHfp\Oa`p\"FVq>0UXmH+6Er<<5qs8Duqrr39$pAajVs8ViXrVllhrr3#kqu6U$o`+ja -s8W)uoDS[pqtC!aqZ$Tkq18S$s*t~> -JcFa0!ri,srr3r9s8W#qp\b$cq#CBXs8VEbs7uB_s8VZis7H6grsA5ls7c6emJm4Zrr2ugrr4PK -n,)_Sr;Q]qs8)Qjs8V?`rr;umo_\IZq"FRas8)0`q#C0iq"jgdqu?]jrr3Don,NCenF6>Tnc/UW -rVmK!s7cQgmJm(^s8W&ts6p!frIP"(s*t~> -JcFU,*W5m-pAXmer;Zflo`"mSs8VEbs7uB_s8VZis7H6grsnSqs7c6emJm4Zs8N#brr2p!oDeX` -rsSMfoDJRFr;-HnrV?Bk&cD\/qX4CYs7u]iqYC0gs8Vimrs\;`s8N&fnGE7Us8MKcrt4c#p]($U -s82cps8Dutn,NFdJcFO*J,~> -JcFX-*rYm+l0\38q=spbmca9>kl:\Ks8Vogp](9as8V`hrr3GtqZ$<`s6]jdp&G'jm/?qco`+aa -rsSYpp](9Rs7uWjp[\:Z')25%s8)0`q#C0iq"jgdqu?]jrr3Don,NCenF6>Tnc/UWrVmK!s7cQg -mJm(^s8W&ts6p!frIP"(s*t~> -JcF^/"Sr&ns8Dor"8`&mr;Q^;qZ$Tjs8Vurs8;lgs8V`ks82cks8VNes7u]pqu?<frsAW%q#:3_ -r;-6frr2os!;HKm%/U#'oDJLMq!n+XrVZWo'Dqgus8W#ps7ZKis7cNmrqlQlqu6U4qu?WprqZEj -s8;ogs8VTgpAb0ks7?9]pOWA!s*t~> -JcF^/;YpFhrq-0fp](!fq>C9mrV?Knq#CBks8W#ro`+s`s8VupqZ$T`s8Vops82igrql]krV6Em -p](6krr<#srV?<XrVHB\rr;ips7?9is8W&qrVmQ.s6p!fr;?Tgs82ijrr;upqZ$HlrttY5rVulm -qZ$Tns7?9jnGi4^s8Duhs75o8s4dR(~> -JcF^/3r]0RqWmbEme6/HoCVbJo(E%_q#CBks8W#ro`+s`s8VupqZ$T`s8Vops82igs8)]krV6Em -q#CBnqYpQerr3E!s8DQdqWn%NqYgBjrVmQ.s6p!fr;?Tgs82ijrr;upqZ$HlrttY5rVulmqZ$Tn -s7?9jnGi4^s8Duhs75o8s4dR(~> -JcDeNr;Q<frVlfoJcDPGJ,~> -JcFR+rVkLMs8MZj!WN&prdk*=s*t~> -JcFU,!<)imrVc`m!<(%>qYc!FV#Pr~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -JcC<$JcE+WJ,~> -%%EndData -showpage -%%Trailer -end -%%EOF diff --git a/lib/megaco/doc/src/notes.xml b/lib/megaco/doc/src/notes.xml index 99a3784402..81c9305542 100644 --- a/lib/megaco/doc/src/notes.xml +++ b/lib/megaco/doc/src/notes.xml @@ -35,6 +35,85 @@ thus constitutes one section in this document. The title of each section is the version number of Megaco.</p> + <section><title>Megaco 3.15</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Fixing auto-import issues.</p> + <p> + Own Id: OTP-8842</p> + </item> + </list> + </section> + +</section> + +<section> + <title>Megaco 3.14.1.1</title> + + <p>Version 3.14.1.1 supports code replacement in runtime from/to + version 3.14.1, 3.14, 3.13, 3.12 and 3.11.3.</p> + + <section> + <title>Improvements and new features</title> + +<!-- + <p>-</p> +--> + + <list type="bulleted"> + <item> + <p>Updated the + <seealso marker="megaco_performance">performance</seealso> + chapter. </p> + <p>Own Id: OTP-8696</p> + </item> + + </list> + + </section> + + <section> + <title>Fixed bugs and malfunctions</title> + <p>-</p> + +<!-- + <list type="bulleted"> + <item> + <p>A race condition when, during high load, processing + both the original and a resent message and delivering + this as two separate messages to the user. </p> + <p>Note that this solution only protects against multiple + reply deliveries! </p> + <p>Own Id: OTP-8529</p> + <p>Aux Id: Seq 10915</p> + </item> + + <item> + <p>Fix shared libraries installation. </p> + <p>The flex shared lib(s) were incorrectly installed as data + files. </p> + <p>Peter Lemenkov</p> + <p>Own Id: OTP-8627</p> + </item> + + <item> + <p>Eliminated a possible race condition while creating + pending counters. </p> + <p>Own Id: OTP-8634</p> + <p>Aux Id: Seq 11579</p> + </item> + + </list> +--> + + </section> + + </section> <!-- 3.14.1.1 --> + + <section> <title>Megaco 3.14.1</title> @@ -66,7 +145,7 @@ <list type="bulleted"> <item> - <p>A raise condition when, during high load, processing + <p>A race condition when, during high load, processing both the original and a resent message and delivering this as two separate messages to the user. </p> <p>Note that this solution only protects against multiple @@ -84,7 +163,7 @@ </item> <item> - <p>Eliminated a possible raise condition while creating + <p>Eliminated a possible race condition while creating pending counters. </p> <p>Own Id: OTP-8634</p> <p>Aux Id: Seq 11579</p> @@ -142,7 +221,7 @@ <item> <p>Callbacks, when the callback module is unknown (undefined), results in warning messages. </p> - <p>A raise condition scenario. As part of a cancelation operation, + <p>A race condition scenario. As part of a cancelation operation, replies with waiting acknowledgements is cancelled. This includes informing the user (via a call to the handle_trans_ack callback function). It is possible that at this point the connection data @@ -674,13 +753,16 @@ <list type="bulleted"> <item> - <p>Unexpected <seealso marker="megaco_user#unexpected_trans">handle_unexpected_reply</seealso> callbacks. </p> - <p>The <seealso marker="megaco_user">megaco_user</seealso> callback function + <p>Unexpected + <seealso marker="megaco_user#unexpected_trans">handle_unexpected_reply</seealso> + callbacks. </p> + <p>The <seealso marker="megaco_user">megaco_user</seealso> callback + function <seealso marker="megaco_user#unexpected_trans">handle_unexpected_reply</seealso> could during high load be called with unexpected values for the Trans - argument, such as an <c>TransactionReply</c> where <c>transactionResult</c> - had the value <c>{error, timeout}</c>. This was a result of a raise condition - and has now been fixed. </p> + argument, such as an <c>TransactionReply</c> where + <c>transactionResult</c> had the value <c>{error, timeout}</c>. + This was a result of a race condition and has now been fixed. </p> <p>Own Id: OTP-7926</p> <p>Aux Id: Seq 11255</p> </item> @@ -875,416 +957,6 @@ </section> </section> <!-- 3.10 --> - - <section> - <title>Megaco 3.9.4</title> - - <p>Version 3.9.4 supports code replacement in runtime from/to - version 3.9.3, 3.9.2, 3.9.1.1, 3.9.1, 3.9, 3.8.2, 3.8.1 and 3.8 except - when using any of the drivers (flex for text or asn1 for binary).</p> - - <section> - <title>Improvements and new features</title> - <p>-</p> - -<!-- - <list type="bulleted"> - <item> - <p>Miscellaneous dialyzer related and test case cleanup. </p> - <p>Own Id: OTP-7614</p> - </item> - - </list> ---> - </section> - - <section> - <title>Fixed bugs and malfunctions</title> -<!-- - <p>-</p> ---> - - <list type="bulleted"> - <item> - <p>Segmenting a reply failed (with a badmatch) if the message - did not actually need to be segmented (e.g. was within the - size limit, - <seealso marker="megaco#ui_max_pdu_size">max_pdu_size</seealso>). </p> - <p>Own Id: OTP-7733</p> - <p>Aux Id: Seq 11168</p> - </item> - - <item> - <p>Improve the error handling of megaco_tcp for received - messages. </p> - <p>Own Id: OTP-7728</p> - </item> - - </list> - - </section> - - <section> - <title>Incompatibilities</title> - <p>-</p> - -<!-- - <list type="bulleted"> - <item> - <p>For those implementing their own codec's, the new megaco_encoder - behaviour will require three more functions. See above for more - info. </p> - <p>Own Id: OTP-7168</p> - <p>Aux Id: Seq 10867</p> - </item> - - </list> ---> - - </section> - </section> <!-- 3.9.3.1 --> - - - <section> - <title>Megaco 3.9.3</title> - - <p>Version 3.9.3 supports code replacement in runtime from/to - version 3.9.2, 3.9.1.1, 3.9.1, 3.9, 3.8.2, 3.8.1 and 3.8 except - when using any of the drivers (flex for text or asn1 for binary).</p> - - <section> - <title>Improvements and new features</title> - <p>-</p> - -<!-- - <list type="bulleted"> - <item> - <p>Miscellaneous dialyzer related and test case cleanup. </p> - <p>Own Id: OTP-7614</p> - </item> - - </list> ---> - </section> - - <section> - <title>Fixed bugs and malfunctions</title> -<!-- - <p>-</p> ---> - - <list type="bulleted"> - <item> - <p>Memory leak in the flex scanner. There was a memory - leak in the flex scanner function handling - Property Parameters. </p> - <p>Own Id: OTP-7700</p> - <p>Aux Id: Seq 11126</p> - </item> - - </list> - - </section> - - <section> - <title>Incompatibilities</title> - <p>-</p> - -<!-- - <list type="bulleted"> - <item> - <p>For those implementing their own codec's, the new megaco_encoder - behaviour will require three more functions. See above for more - info. </p> - <p>Own Id: OTP-7168</p> - <p>Aux Id: Seq 10867</p> - </item> - - </list> ---> - - </section> - </section> <!-- 3.9.3 --> - - - <section> - <title>Megaco 3.9.2</title> - - <p>Version 3.9.2 supports code replacement in runtime from/to - version 3.9.1.1, 3.9.1, 3.9, 3.8.2, 3.8.1 and 3.8 except - when using any of the drivers (flex for text or asn1 for binary).</p> - - <section> - <title>Improvements and new features</title> - <p>-</p> - -<!-- - <list type="bulleted"> - <item> - <p>Miscellaneous dialyzer related and test case cleanup. </p> - <p>Own Id: OTP-7614</p> - </item> - - </list> ---> - </section> - - <section> - <title>Fixed bugs and malfunctions</title> -<!-- - <p>-</p> ---> - - <list type="bulleted"> - <item> - <p>The text encoders (v1, v2, v3, ...) all failed to - properly encode the DigitMapDescriptor. </p> - <p>Own Id: OTP-7671</p> - <p>Aux Id: Seq 11113</p> - </item> - - <item> - <p>The mini decoder some time incorrectly identifies - plain text as tokens. </p> - <p>Own Id: OTP-7672</p> - <p>Aux Id: Seq 11103</p> - </item> - - </list> - - </section> - - <section> - <title>Incompatibilities</title> - <p>-</p> - -<!-- - <list type="bulleted"> - <item> - <p>For those implementing their own codec's, the new megaco_encoder - behaviour will require three more functions. See above for more - info. </p> - <p>Own Id: OTP-7168</p> - <p>Aux Id: Seq 10867</p> - </item> - - </list> ---> - - </section> - </section> <!-- 3.9.2 --> - - - <section> - <title>Megaco 3.9.1.1</title> - - <p>Version 3.9.1.1 supports code replacement in runtime from/to - version 3.9.1, 3.9, 3.8.2, 3.8.1 and 3.8 except - when using any of the drivers (flex for text or asn1 for binary).</p> - - <section> - <title>Improvements and new features</title> -<!-- - <p>-</p> ---> - - <list type="bulleted"> - <item> - <p>Miscellaneous dialyzer related and test case cleanup. </p> - <p>Own Id: OTP-7614</p> - </item> - - </list> - </section> - - <section> - <title>Fixed bugs and malfunctions</title> - <p>-</p> - -<!-- - <list type="bulleted"> - <item> - <p>[text] The flex scanner did not allow an empty quotedString - in propertyParm. </p> - <p>Own Id: OTP-7573</p> - <p>Aux Id: Seq 11062</p> - </item> - - <item> - <p>[text] Unable to decode a version 2 message with a - topologyTriple containing an (optional) eventStream. </p> - <p>Own Id: OTP-7576</p> - <p>Aux Id: Seq 11066</p> - </item> - - </list> ---> - - </section> - - <section> - <title>Incompatibilities</title> - <p>-</p> - -<!-- - <list type="bulleted"> - <item> - <p>For those implementing their own codec's, the new megaco_encoder - behaviour will require three more functions. See above for more - info. </p> - <p>Own Id: OTP-7168</p> - <p>Aux Id: Seq 10867</p> - </item> - - </list> ---> - - </section> - </section> <!-- 3.9.1.1 --> - - - <section> - <title>Megaco 3.9.1</title> - - <p>Version 3.9.1 supports code replacement in runtime from/to - version 3.9, 3.8.2, 3.8.1 and 3.8 except - when using any of the drivers (flex for text or asn1 for binary).</p> - - <section> - <title>Improvements and new features</title> - <p>-</p> - -<!-- - <list type="bulleted"> - <item> - <p>[text] The text codec(s) has been optimized. The parsing of - "property parameters" has been moved to the scanner(s). Which means - that when decoding messages containing property parameters, using - the flex scanner, decode time(s) will be reduced. The reduction - depends on the message, but can be as large as 25%. </p> - <p>Own Id: OTP-7431</p> - </item> - - </list> ---> - </section> - - <section> - <title>Fixed bugs and malfunctions</title> -<!-- - <p>-</p> ---> - - <list type="bulleted"> - <item> - <p>[text] The flex scanner did not allow an empty quotedString - in propertyParm. </p> - <p>Own Id: OTP-7573</p> - <p>Aux Id: Seq 11062</p> - </item> - - <item> - <p>[text] Unable to decode a version 2 message with a - topologyTriple containing an (optional) eventStream. </p> - <p>Own Id: OTP-7576</p> - <p>Aux Id: Seq 11066</p> - </item> - - </list> - - </section> - - <section> - <title>Incompatibilities</title> - <p>-</p> - -<!-- - <list type="bulleted"> - <item> - <p>For those implementing their own codec's, the new megaco_encoder - behaviour will require three more functions. See above for more - info. </p> - <p>Own Id: OTP-7168</p> - <p>Aux Id: Seq 10867</p> - </item> - - </list> ---> - - </section> - </section> <!-- 3.9.1 --> - - - <section> - <title>Megaco 3.9</title> - - <p>Version 3.9 supports code replacement in runtime from/to - version 3.8.2, 3.8.1 and 3.8 except - when using any of the drivers (flex for text or asn1 for binary).</p> - - <section> - <title>Improvements and new features</title> -<!-- - <p>-</p> ---> - - <list type="bulleted"> - <item> - <p>[text] The text codec(s) has been optimized. The parsing of - "property parameters" has been moved to the scanner(s). Which means - that when decoding messages containing property parameters, using - the flex scanner, decode time(s) will be reduced. The reduction - depends on the message, but can be as large as 25%. </p> - <p>Own Id: OTP-7431</p> - </item> - - </list> - </section> - - <section> - <title>Fixed bugs and malfunctions</title> - <p>-</p> - -<!-- - <list type="bulleted"> - <item> - <p>If a TransactionRequest arrives while a user is - connecting (is in the callback function - handle_connect as a result of a megaco:connect call), - megaco responds with a pending message and then drops - the request.</p> - <p>These messages will now be silently dropped, forcing the - other side to resend. </p> - <p>Own Id: OTP-7192</p> - <p>Aux Id: Seq 10884</p> - </item> - - </list> ---> - - </section> - - <section> - <title>Incompatibilities</title> - <p>-</p> - -<!-- - <list type="bulleted"> - <item> - <p>For those implementing their own codec's, the new megaco_encoder - behaviour will require three more functions. See above for more - info. </p> - <p>Own Id: OTP-7168</p> - <p>Aux Id: Seq 10867</p> - </item> - - </list> ---> - - </section> - </section> <!-- 3.9 --> - - <!-- section> <title>Release notes history</title> <p>For information about older versions see diff --git a/lib/megaco/doc/src/notes_history.xml b/lib/megaco/doc/src/notes_history.xml index 640b62230f..220ed4bbb1 100644 --- a/lib/megaco/doc/src/notes_history.xml +++ b/lib/megaco/doc/src/notes_history.xml @@ -33,6 +33,415 @@ </header> <section> + <title>Megaco 3.9.4</title> + + <p>Version 3.9.4 supports code replacement in runtime from/to + version 3.9.3, 3.9.2, 3.9.1.1, 3.9.1, 3.9, 3.8.2, 3.8.1 and 3.8 except + when using any of the drivers (flex for text or asn1 for binary).</p> + + <section> + <title>Improvements and new features</title> + <p>-</p> + +<!-- + <list type="bulleted"> + <item> + <p>Miscellaneous dialyzer related and test case cleanup. </p> + <p>Own Id: OTP-7614</p> + </item> + + </list> +--> + </section> + + <section> + <title>Fixed bugs and malfunctions</title> +<!-- + <p>-</p> +--> + + <list type="bulleted"> + <item> + <p>Segmenting a reply failed (with a badmatch) if the message + did not actually need to be segmented (e.g. was within the + size limit, + <seealso marker="megaco#ui_max_pdu_size">max_pdu_size</seealso>). </p> + <p>Own Id: OTP-7733</p> + <p>Aux Id: Seq 11168</p> + </item> + + <item> + <p>Improve the error handling of megaco_tcp for received + messages. </p> + <p>Own Id: OTP-7728</p> + </item> + + </list> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + +<!-- + <list type="bulleted"> + <item> + <p>For those implementing their own codec's, the new megaco_encoder + behaviour will require three more functions. See above for more + info. </p> + <p>Own Id: OTP-7168</p> + <p>Aux Id: Seq 10867</p> + </item> + + </list> +--> + + </section> + </section> <!-- 3.9.3.1 --> + + + <section> + <title>Megaco 3.9.3</title> + + <p>Version 3.9.3 supports code replacement in runtime from/to + version 3.9.2, 3.9.1.1, 3.9.1, 3.9, 3.8.2, 3.8.1 and 3.8 except + when using any of the drivers (flex for text or asn1 for binary).</p> + + <section> + <title>Improvements and new features</title> + <p>-</p> + +<!-- + <list type="bulleted"> + <item> + <p>Miscellaneous dialyzer related and test case cleanup. </p> + <p>Own Id: OTP-7614</p> + </item> + + </list> +--> + </section> + + <section> + <title>Fixed bugs and malfunctions</title> +<!-- + <p>-</p> +--> + + <list type="bulleted"> + <item> + <p>Memory leak in the flex scanner. There was a memory + leak in the flex scanner function handling + Property Parameters. </p> + <p>Own Id: OTP-7700</p> + <p>Aux Id: Seq 11126</p> + </item> + + </list> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + +<!-- + <list type="bulleted"> + <item> + <p>For those implementing their own codec's, the new megaco_encoder + behaviour will require three more functions. See above for more + info. </p> + <p>Own Id: OTP-7168</p> + <p>Aux Id: Seq 10867</p> + </item> + + </list> +--> + + </section> + </section> <!-- 3.9.3 --> + + + <section> + <title>Megaco 3.9.2</title> + + <p>Version 3.9.2 supports code replacement in runtime from/to + version 3.9.1.1, 3.9.1, 3.9, 3.8.2, 3.8.1 and 3.8 except + when using any of the drivers (flex for text or asn1 for binary).</p> + + <section> + <title>Improvements and new features</title> + <p>-</p> + +<!-- + <list type="bulleted"> + <item> + <p>Miscellaneous dialyzer related and test case cleanup. </p> + <p>Own Id: OTP-7614</p> + </item> + + </list> +--> + </section> + + <section> + <title>Fixed bugs and malfunctions</title> +<!-- + <p>-</p> +--> + + <list type="bulleted"> + <item> + <p>The text encoders (v1, v2, v3, ...) all failed to + properly encode the DigitMapDescriptor. </p> + <p>Own Id: OTP-7671</p> + <p>Aux Id: Seq 11113</p> + </item> + + <item> + <p>The mini decoder some time incorrectly identifies + plain text as tokens. </p> + <p>Own Id: OTP-7672</p> + <p>Aux Id: Seq 11103</p> + </item> + + </list> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + +<!-- + <list type="bulleted"> + <item> + <p>For those implementing their own codec's, the new megaco_encoder + behaviour will require three more functions. See above for more + info. </p> + <p>Own Id: OTP-7168</p> + <p>Aux Id: Seq 10867</p> + </item> + + </list> +--> + + </section> + </section> <!-- 3.9.2 --> + + + <section> + <title>Megaco 3.9.1.1</title> + + <p>Version 3.9.1.1 supports code replacement in runtime from/to + version 3.9.1, 3.9, 3.8.2, 3.8.1 and 3.8 except + when using any of the drivers (flex for text or asn1 for binary).</p> + + <section> + <title>Improvements and new features</title> +<!-- + <p>-</p> +--> + + <list type="bulleted"> + <item> + <p>Miscellaneous dialyzer related and test case cleanup. </p> + <p>Own Id: OTP-7614</p> + </item> + + </list> + </section> + + <section> + <title>Fixed bugs and malfunctions</title> + <p>-</p> + +<!-- + <list type="bulleted"> + <item> + <p>[text] The flex scanner did not allow an empty quotedString + in propertyParm. </p> + <p>Own Id: OTP-7573</p> + <p>Aux Id: Seq 11062</p> + </item> + + <item> + <p>[text] Unable to decode a version 2 message with a + topologyTriple containing an (optional) eventStream. </p> + <p>Own Id: OTP-7576</p> + <p>Aux Id: Seq 11066</p> + </item> + + </list> +--> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + +<!-- + <list type="bulleted"> + <item> + <p>For those implementing their own codec's, the new megaco_encoder + behaviour will require three more functions. See above for more + info. </p> + <p>Own Id: OTP-7168</p> + <p>Aux Id: Seq 10867</p> + </item> + + </list> +--> + + </section> + </section> <!-- 3.9.1.1 --> + + + <section> + <title>Megaco 3.9.1</title> + + <p>Version 3.9.1 supports code replacement in runtime from/to + version 3.9, 3.8.2, 3.8.1 and 3.8 except + when using any of the drivers (flex for text or asn1 for binary).</p> + + <section> + <title>Improvements and new features</title> + <p>-</p> + +<!-- + <list type="bulleted"> + <item> + <p>[text] The text codec(s) has been optimized. The parsing of + "property parameters" has been moved to the scanner(s). Which means + that when decoding messages containing property parameters, using + the flex scanner, decode time(s) will be reduced. The reduction + depends on the message, but can be as large as 25%. </p> + <p>Own Id: OTP-7431</p> + </item> + + </list> +--> + </section> + + <section> + <title>Fixed bugs and malfunctions</title> +<!-- + <p>-</p> +--> + + <list type="bulleted"> + <item> + <p>[text] The flex scanner did not allow an empty quotedString + in propertyParm. </p> + <p>Own Id: OTP-7573</p> + <p>Aux Id: Seq 11062</p> + </item> + + <item> + <p>[text] Unable to decode a version 2 message with a + topologyTriple containing an (optional) eventStream. </p> + <p>Own Id: OTP-7576</p> + <p>Aux Id: Seq 11066</p> + </item> + + </list> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + +<!-- + <list type="bulleted"> + <item> + <p>For those implementing their own codec's, the new megaco_encoder + behaviour will require three more functions. See above for more + info. </p> + <p>Own Id: OTP-7168</p> + <p>Aux Id: Seq 10867</p> + </item> + + </list> +--> + + </section> + </section> <!-- 3.9.1 --> + + + <section> + <title>Megaco 3.9</title> + + <p>Version 3.9 supports code replacement in runtime from/to + version 3.8.2, 3.8.1 and 3.8 except + when using any of the drivers (flex for text or asn1 for binary).</p> + + <section> + <title>Improvements and new features</title> +<!-- + <p>-</p> +--> + + <list type="bulleted"> + <item> + <p>[text] The text codec(s) has been optimized. The parsing of + "property parameters" has been moved to the scanner(s). Which means + that when decoding messages containing property parameters, using + the flex scanner, decode time(s) will be reduced. The reduction + depends on the message, but can be as large as 25%. </p> + <p>Own Id: OTP-7431</p> + </item> + + </list> + </section> + + <section> + <title>Fixed bugs and malfunctions</title> + <p>-</p> + +<!-- + <list type="bulleted"> + <item> + <p>If a TransactionRequest arrives while a user is + connecting (is in the callback function + handle_connect as a result of a megaco:connect call), + megaco responds with a pending message and then drops + the request.</p> + <p>These messages will now be silently dropped, forcing the + other side to resend. </p> + <p>Own Id: OTP-7192</p> + <p>Aux Id: Seq 10884</p> + </item> + + </list> +--> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + +<!-- + <list type="bulleted"> + <item> + <p>For those implementing their own codec's, the new megaco_encoder + behaviour will require three more functions. See above for more + info. </p> + <p>Own Id: OTP-7168</p> + <p>Aux Id: Seq 10867</p> + </item> + + </list> +--> + + </section> + </section> <!-- 3.9 --> + + + <section> <title>Megaco 3.8.2</title> <p>Version 3.8.2 supports code replacement in runtime from/to @@ -901,7 +1310,7 @@ <list> <item> <p>When timers expire while a connection cancel - (megaco:cancel) is in progress, there is a raise + (megaco:cancel) is in progress, there is a race condition possibility. This has been eliminated. </p> <p>Own Id: OTP-6921</p> <p>Aux Id: Seq 10450</p> @@ -1166,7 +1575,7 @@ <list type="bulleted"> <item> <p>When replies arrive during a call to megaco:cancel - there is a raise condition possibility. This has been + there is a race condition possibility. This has been eliminated. </p> <p>Own Id: OTP-6276</p> <p>Aux Id: Seq 10450</p> diff --git a/lib/megaco/examples/meas/megaco_codec_meas.erl b/lib/megaco/examples/meas/megaco_codec_meas.erl index 88b34105ac..51ee396338 100644 --- a/lib/megaco/examples/meas/megaco_codec_meas.erl +++ b/lib/megaco/examples/meas/megaco_codec_meas.erl @@ -1,7 +1,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 @@ -43,6 +43,8 @@ %% API +%% Avoid warning for local function error/2 clashing with autoimported BIF. +-compile({no_auto_import,[error/2]}). -export([start/0, start/1]). -export([start1/0]). diff --git a/lib/megaco/examples/meas/megaco_codec_mstone_lib.erl b/lib/megaco/examples/meas/megaco_codec_mstone_lib.erl index 31df945777..040af9826b 100644 --- a/lib/megaco/examples/meas/megaco_codec_mstone_lib.erl +++ b/lib/megaco/examples/meas/megaco_codec_mstone_lib.erl @@ -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 @@ -26,6 +26,8 @@ %% API +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([start_flex_scanner/0, stop_flex_scanner/1, expanded_messages/2, expanded_messages/3, set_default_sched_bind/0, diff --git a/lib/megaco/src/app/megaco.appup.src b/lib/megaco/src/app/megaco.appup.src index f939f5e6cf..66068f650f 100644 --- a/lib/megaco/src/app/megaco.appup.src +++ b/lib/megaco/src/app/megaco.appup.src @@ -127,92 +127,56 @@ %% | %% v %% 3.14.1 +%% | +%% v +%% 3.14.1.1 +%% | +%% v +%% 3.15 %% %% {"%VSN%", [ - {"3.14", - [ - {load_module, megaco_messenger, soft_purge, soft_purge, [megaco_monitor]}, - {update, megaco_monitor, soft, soft_purge, soft_purge, []}, - {update, megaco_config, soft, soft_purge, soft_purge, []} - ] - }, - {"3.13", - [ - {load_module, megaco_messenger, soft_purge, soft_purge, [megaco_monitor]}, - {load_module, megaco_filter, soft_purge, soft_purge, []}, - {update, megaco_monitor, soft, soft_purge, soft_purge, []}, - {update, megaco_config, soft, soft_purge, soft_purge, []}, - {update, megaco_flex_scanner_handler, {advanced, downgrade_to_pre_3_13_1}, - soft_purge, soft_purge, []} - ] - }, - {"3.12", + {"3.14.1.1", [ - {load_module, megaco_filter, soft_purge, soft_purge, []}, - {load_module, megaco_udp, soft_purge, soft_purge, []}, - {load_module, megaco_messenger, soft_purge, soft_purge, [megaco_monitor]}, - {update, megaco_config, soft, soft_purge, soft_purge, []}, - {update, megaco_monitor, soft, soft_purge, soft_purge, []}, - {update, megaco_flex_scanner_handler, {advanced, downgrade_to_pre_3_13_1}, - soft_purge, soft_purge, []} - ] - }, - {"3.11.3", - [ - {load_module, megaco_filter, soft_purge, soft_purge, []}, - {load_module, megaco_udp, soft_purge, soft_purge, []}, - {load_module, megaco_messenger, soft_purge, soft_purge, - [megaco_config, megaco_monitor]}, - {update, megaco_monitor, soft, soft_purge, soft_purge, []}, - {update, megaco_config, {advanced, upgrade_from_pre_3_12}, - soft_purge, soft_purge, []}, - {update, megaco_flex_scanner_handler, {advanced, downgrade_to_pre_3_13_1}, - soft_purge, soft_purge, []} + {load_module, megaco_binary_transformer_prev3a, soft_purge, soft_purge, []}, + {load_module, megaco_binary_transformer_prev3b, soft_purge, soft_purge, []}, + {load_module, megaco_binary_transformer_prev3c, soft_purge, soft_purge, []}, + {load_module, megaco_sdp, soft_purge, soft_purge, []}, + {load_module, megaco_compact_text_encoder_v1, soft_purge, soft_purge, []}, + {load_module, megaco_pretty_text_encoder_v1, soft_purge, soft_purge, []}, + {load_module, megaco_compact_text_encoder_v2, soft_purge, soft_purge, []}, + {load_module, megaco_pretty_text_encoder_v2, soft_purge, soft_purge, []}, + {load_module, megaco_compact_text_encoder_prev3a, soft_purge, soft_purge, []}, + {load_module, megaco_pretty_text_encoder_prev3a, soft_purge, soft_purge, []}, + {load_module, megaco_compact_text_encoder_prev3b, soft_purge, soft_purge, []}, + {load_module, megaco_pretty_text_encoder_prev3b, soft_purge, soft_purge, []}, + {load_module, megaco_compact_text_encoder_prev3c, soft_purge, soft_purge, []}, + {load_module, megaco_pretty_text_encoder_prev3c, soft_purge, soft_purge, []}, + {load_module, megaco_compact_text_encoder_v3, soft_purge, soft_purge, []}, + {load_module, megaco_pretty_text_encoder_v3, soft_purge, soft_purge, []} ] } ], [ - {"3.14", - [ - {load_module, megaco_messenger, soft_purge, soft_purge, [megaco_monitor]}, - {update, megaco_monitor, soft, soft_purge, soft_purge, []}, - {update, megaco_config, soft, soft_purge, soft_purge, []} - ] - }, - {"3.13", - [ - {load_module, megaco_messenger, soft_purge, soft_purge, [megaco_monitor]}, - {load_module, megaco_filter, soft_purge, soft_purge, []}, - {update, megaco_monitor, soft, soft_purge, soft_purge, []}, - {update, megaco_config, soft, soft_purge, soft_purge, []}, - {update, megaco_flex_scanner_handler, {advanced, upgrade_from_pre_3_13_1}, - soft_purge, soft_purge, []} - ] - }, - {"3.12", - [ - {load_module, megaco_filter, soft_purge, soft_purge, []}, - {load_module, megaco_udp, soft_purge, soft_purge, []}, - {load_module, megaco_messenger, soft_purge, soft_purge, [megaco_monitor]}, - {update, megaco_config, soft, soft_purge, soft_purge, []}, - {update, megaco_monitor, soft, soft_purge, soft_purge, []}, - {update, megaco_flex_scanner_handler, {advanced, upgrade_from_pre_3_13_1}, - soft_purge, soft_purge, []} - ] - }, - {"3.11.3", + {"3.14.1.1", [ - {load_module, megaco_filter, soft_purge, soft_purge, []}, - {load_module, megaco_udp, soft_purge, soft_purge, []}, - {load_module, megaco_messenger, soft_purge, soft_purge, - [megaco_config, megaco_monitor]}, - {update, megaco_monitor, soft, soft_purge, soft_purge, []}, - {update, megaco_config, {advanced, downgrade_to_pre_3_12}, - soft_purge, soft_purge, []}, - {update, megaco_flex_scanner_handler, {advanced, upgrade_from_pre_3_13_1}, - soft_purge, soft_purge, []} + {load_module, megaco_binary_transformer_prev3a, soft_purge, soft_purge, []}, + {load_module, megaco_binary_transformer_prev3b, soft_purge, soft_purge, []}, + {load_module, megaco_binary_transformer_prev3c, soft_purge, soft_purge, []}, + {load_module, megaco_sdp, soft_purge, soft_purge, []}, + {load_module, megaco_compact_text_encoder_v1, soft_purge, soft_purge, []}, + {load_module, megaco_pretty_text_encoder_v1, soft_purge, soft_purge, []}, + {load_module, megaco_compact_text_encoder_v2, soft_purge, soft_purge, []}, + {load_module, megaco_pretty_text_encoder_v2, soft_purge, soft_purge, []}, + {load_module, megaco_compact_text_encoder_prev3a, soft_purge, soft_purge, []}, + {load_module, megaco_pretty_text_encoder_prev3a, soft_purge, soft_purge, []}, + {load_module, megaco_compact_text_encoder_prev3b, soft_purge, soft_purge, []}, + {load_module, megaco_pretty_text_encoder_prev3b, soft_purge, soft_purge, []}, + {load_module, megaco_compact_text_encoder_prev3c, soft_purge, soft_purge, []}, + {load_module, megaco_pretty_text_encoder_prev3c, soft_purge, soft_purge, []}, + {load_module, megaco_compact_text_encoder_v3, soft_purge, soft_purge, []}, + {load_module, megaco_pretty_text_encoder_v3, soft_purge, soft_purge, []} ] } ] diff --git a/lib/megaco/src/binary/megaco_binary_transformer_prev3a.erl b/lib/megaco/src/binary/megaco_binary_transformer_prev3a.erl index 609947c933..ba4324f4f2 100644 --- a/lib/megaco/src/binary/megaco_binary_transformer_prev3a.erl +++ b/lib/megaco/src/binary/megaco_binary_transformer_prev3a.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% 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 @@ -1619,11 +1619,3 @@ verify_count(Count, Min, Max) -> true -> error({count_not_an_integer, Count}) end. - - -%% ------------------------------------------------------------------- - -error(Reason) -> - erlang:error(Reason). - - diff --git a/lib/megaco/src/binary/megaco_binary_transformer_prev3b.erl b/lib/megaco/src/binary/megaco_binary_transformer_prev3b.erl index baca84bbfe..8e42353b9b 100644 --- a/lib/megaco/src/binary/megaco_binary_transformer_prev3b.erl +++ b/lib/megaco/src/binary/megaco_binary_transformer_prev3b.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 @@ -1619,11 +1619,3 @@ verify_count(Count, Min, Max) -> true -> error({count_not_an_integer, Count}) end. - - -%% ------------------------------------------------------------------- - -error(Reason) -> - erlang:error(Reason). - - diff --git a/lib/megaco/src/binary/megaco_binary_transformer_prev3c.erl b/lib/megaco/src/binary/megaco_binary_transformer_prev3c.erl index 8d2f9eea38..c26d1fa99d 100644 --- a/lib/megaco/src/binary/megaco_binary_transformer_prev3c.erl +++ b/lib/megaco/src/binary/megaco_binary_transformer_prev3c.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 @@ -1746,11 +1746,3 @@ verify_count(Count, Min, Max) -> true -> error({count_not_an_integer, Count}) end. - - -%% ------------------------------------------------------------------- - -error(Reason) -> - erlang:error(Reason). - - diff --git a/lib/megaco/src/binary/megaco_binary_transformer_v3.erl b/lib/megaco/src/binary/megaco_binary_transformer_v3.erl index cef49b03fd..1ff7c86e82 100644 --- a/lib/megaco/src/binary/megaco_binary_transformer_v3.erl +++ b/lib/megaco/src/binary/megaco_binary_transformer_v3.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 @@ -1753,11 +1753,3 @@ verify_count(Count, Min, Max) -> true -> error({count_not_an_integer, Count}) end. - - -%% ------------------------------------------------------------------- - -error(Reason) -> - erlang:error(Reason). - - diff --git a/lib/megaco/src/engine/megaco_sdp.erl b/lib/megaco/src/engine/megaco_sdp.erl index 90911fe24a..37f28cac59 100644 --- a/lib/megaco/src/engine/megaco_sdp.erl +++ b/lib/megaco/src/engine/megaco_sdp.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,6 +38,8 @@ %% External exports %%---------------------------------------------------------------------- +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([ decode/1, encode/1, get_sdp_record_from_PropertyGroup/2 diff --git a/lib/megaco/src/text/megaco_text_gen_prev3a.hrl b/lib/megaco/src/text/megaco_text_gen_prev3a.hrl index b1ddb10a4e..81916cb9ec 100644 --- a/lib/megaco/src/text/megaco_text_gen_prev3a.hrl +++ b/lib/megaco/src/text/megaco_text_gen_prev3a.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% 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 @@ -2924,10 +2924,6 @@ verify_count(Count, Min, Max) -> end. -%% ------------------------------------------------------------------- - -error(Reason) -> - erlang:error(Reason). %% ------------------------------------------------------------------- diff --git a/lib/megaco/src/text/megaco_text_gen_prev3b.hrl b/lib/megaco/src/text/megaco_text_gen_prev3b.hrl index 8a4af877dc..83d25c83c9 100644 --- a/lib/megaco/src/text/megaco_text_gen_prev3b.hrl +++ b/lib/megaco/src/text/megaco_text_gen_prev3b.hrl @@ -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 @@ -2945,10 +2945,6 @@ verify_count(Count, Min, Max) -> end. -%% ------------------------------------------------------------------- - -error(Reason) -> - erlang:error(Reason). %% ------------------------------------------------------------------- diff --git a/lib/megaco/src/text/megaco_text_gen_prev3c.hrl b/lib/megaco/src/text/megaco_text_gen_prev3c.hrl index 11db906846..458809ca75 100644 --- a/lib/megaco/src/text/megaco_text_gen_prev3c.hrl +++ b/lib/megaco/src/text/megaco_text_gen_prev3c.hrl @@ -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 @@ -3421,10 +3421,6 @@ verify_count(Count, Min, Max) -> end. -%% ------------------------------------------------------------------- - -error(Reason) -> - erlang:error(Reason). %% ------------------------------------------------------------------- diff --git a/lib/megaco/src/text/megaco_text_gen_v1.hrl b/lib/megaco/src/text/megaco_text_gen_v1.hrl index b150c9ba58..0726d68941 100644 --- a/lib/megaco/src/text/megaco_text_gen_v1.hrl +++ b/lib/megaco/src/text/megaco_text_gen_v1.hrl @@ -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 @@ -2386,10 +2386,6 @@ verify_count(Count, Min, Max) -> end. -%% ------------------------------------------------------------------- - -error(Reason) -> - erlang:error(Reason). % d(F) -> % d(F, []). diff --git a/lib/megaco/src/text/megaco_text_gen_v2.hrl b/lib/megaco/src/text/megaco_text_gen_v2.hrl index 6cfcac8664..8e12efe65a 100644 --- a/lib/megaco/src/text/megaco_text_gen_v2.hrl +++ b/lib/megaco/src/text/megaco_text_gen_v2.hrl @@ -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 @@ -2772,10 +2772,6 @@ verify_count(Count, Min, Max) -> end. -%% ------------------------------------------------------------------- - -error(Reason) -> - erlang:error(Reason). %% ------------------------------------------------------------------- diff --git a/lib/megaco/src/text/megaco_text_gen_v3.hrl b/lib/megaco/src/text/megaco_text_gen_v3.hrl index 1c19a4aa8b..ce2e5e508d 100644 --- a/lib/megaco/src/text/megaco_text_gen_v3.hrl +++ b/lib/megaco/src/text/megaco_text_gen_v3.hrl @@ -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 @@ -3436,10 +3436,6 @@ verify_count(Count, Min, Max) -> end. -%% ------------------------------------------------------------------- - -error(Reason) -> - erlang:error(Reason). %% ------------------------------------------------------------------- diff --git a/lib/megaco/vsn.mk b/lib/megaco/vsn.mk index 63c9ab0ef7..9fc0e0f2fa 100644 --- a/lib/megaco/vsn.mk +++ b/lib/megaco/vsn.mk @@ -1,130 +1,4 @@ APPLICATION = megaco -MEGACO_VSN = 3.14.1 +MEGACO_VSN = 3.15 PRE_VSN = APP_VSN = "$(APPLICATION)-$(MEGACO_VSN)$(PRE_VSN)" - -TICKETS = 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/doc/src/Mnesia_chap5.xmlsrc b/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc index 3ec0aa37f5..1c7e3662e1 100644 --- a/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc +++ b/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>1997</year><year>2009</year> + <year>1997</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>Miscellaneous Mnesia Features</title> @@ -885,16 +885,16 @@ ok <item>Removes the subscription on events of type <c>Event-Category</c></item> </taglist> - <p><c>Event-Category</c> may either be the atom <c>system</c>, or + <p><c>Event-Category</c> may either be the atom <c>system</c>, the atom <c>activity</c>, or one of the tuples <c>{table, Tab, simple}</c>, <c>{table, Tab, detailed}</c>. The old event-category <c>{table, Tab}</c> is the same event-category as <c>{table, Tab, simple}</c>. The subscribe functions activate a subscription of events. The events are delivered as messages to the process evaluating the <c>mnesia:subscribe/1</c> function. The syntax of - system events is <c>{mnesia_system_event, Event}</c> and - <c>{mnesia_table_event, Event}</c> for table events. What system - events and table events means is described below. - </p> + system events is <c>{mnesia_system_event, Event}</c>, + <c>{mnesia_activity_event, Event}</c> for activity events, and + <c>{mnesia_table_event, Event}</c> for table events. What the various + event types mean is described below.</p> <p>All system events are subscribed by Mnesia's gen_event handler. The default gen_event handler is <c>mnesia_event</c>. But it may be changed by using the application @@ -1039,8 +1039,26 @@ ok </section> <section> + <title>Activity Events</title> + <p>Currently, there is only one type of activity event:</p> + <taglist> + <tag><c>{complete, ActivityID}</c></tag> + <item> + <p>This event occurs when a transaction that caused a modification to the database + has completed. It is useful for determining when a set of table events + (see below) caused by a given activity have all been sent. Once the this event + has been received, it is guaranteed that no further table events with the same + ActivityID will be received. Note that this event may still be received even + if no table events with a corresponding ActivityID were received, depending on + the tables to which the receiving process is subscribed.</p> + <p>Dirty operations always only contain one update and thus no activity event is sent.</p> + </item> + </taglist> + </section> + + <section> <title>Table Events</title> - <p>Another category of events are table events, which are + <p>The final category of events are table events, which are events related to table updates. There are two types of table events simple and detailed. </p> diff --git a/lib/mnesia/doc/src/mnesia.xml b/lib/mnesia/doc/src/mnesia.xml index d76471d922..5d3bcf830e 100644 --- a/lib/mnesia/doc/src/mnesia.xml +++ b/lib/mnesia/doc/src/mnesia.xml @@ -1135,7 +1135,7 @@ mnesia:create_table(person, </list> <p>If two processes perform <c>mnesia:dirty_update_counter/3</c> simultaneously, both updates will take effect without the - risk of loosing one of the updates. The new value + risk of losing one of the updates. The new value <c>NewVal</c> of the counter is returned.</p> <p>If <c>Key</c> don't exits, a new record is created with the value <c>Incr</c> if it is larger than 0, otherwise it is set to 0.</p> diff --git a/lib/mnesia/doc/src/notes.xml b/lib/mnesia/doc/src/notes.xml index 66242398d9..2352f11b93 100644 --- a/lib/mnesia/doc/src/notes.xml +++ b/lib/mnesia/doc/src/notes.xml @@ -37,6 +37,37 @@ bugfixes for every release of Mnesia. Each release of Mnesia thus constitutes one section in this document. The title of each section is the version number of Mnesia.</p> + + <section><title>Mnesia 4.4.15</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Eliminated warnings for auto-imported BIF clashes.</p> + <p> + Own Id: OTP-8840</p> + </item> + </list> + </section> + +</section> + +<section><title>Mnesia 4.4.14</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Added mnesia:subscribe(activity) contributed by Bernard + Duggan.</p> + <p> + Own Id: OTP-8519</p> + </item> + </list> + </section> + + </section> <section><title>Mnesia 4.4.13</title> diff --git a/lib/mnesia/examples/mnesia_meter.erl b/lib/mnesia/examples/mnesia_meter.erl index ea74d8691b..68094c4431 100644 --- a/lib/mnesia/examples/mnesia_meter.erl +++ b/lib/mnesia/examples/mnesia_meter.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% %% @@ -407,7 +407,7 @@ run(Nodes, Config, FunOverhead) -> stop(Nodes), Res. -run_meter(M, Nodes, FunOverhead) when record(M, meter) -> +run_meter(M, Nodes, FunOverhead) when is_record(M, meter) -> io:format(".", []), case catch init_records(M#meter.init, ?TIMES) of {atomic, ok} -> diff --git a/lib/mnesia/src/mnesia.appup.src b/lib/mnesia/src/mnesia.appup.src index b3b9297db2..47c9bf9979 100644 --- a/lib/mnesia/src/mnesia.appup.src +++ b/lib/mnesia/src/mnesia.appup.src @@ -1,69 +1,7 @@ %% -*- erlang -*- {"%VSN%", - [ - {"4.4.12", - [ - {update, mnesia, soft, soft_purge, soft_purge, []}, - {update, mnesia_loader, soft, soft_purge, soft_purge, []}, - {update, mnesia_monitor, soft, soft_purge, soft_purge, []}, - {update, mnesia_tm, soft, soft_purge, soft_purge, []} - ] - }, - {"4.4.11", - [ - {update, mnesia, soft, soft_purge, soft_purge, []}, - {update, mnesia_loader, soft, soft_purge, soft_purge, []}, - {update, mnesia_monitor, soft, soft_purge, soft_purge, []}, - {update, mnesia_tm, soft, soft_purge, soft_purge, []}, - {update, mnesia_locker, soft, soft_purge, soft_purge, []}, - {update, mnesia_controller, soft, soft_purge, soft_purge, []} - ] - }, - {"4.4.10", - [ - {update, mnesia, soft, soft_purge, soft_purge, []}, - {update, mnesia_loader, soft, soft_purge, soft_purge, []}, - {update, mnesia_monitor, soft, soft_purge, soft_purge, []}, - {update, mnesia_tm, soft, soft_purge, soft_purge, []}, - {update, mnesia_locker, soft, soft_purge, soft_purge, []}, - {update, mnesia_controller, soft, soft_purge, soft_purge, []} - ] - }, - {"4.4.9", [{restart_application, mnesia}]}, - {"4.4.8", [{restart_application, mnesia}]}, - {"4.4.7", [{restart_application, mnesia}]} + [ ], [ - {"4.4.12", - [ - {update, mnesia, soft, soft_purge, soft_purge, []}, - {update, mnesia_loader, soft, soft_purge, soft_purge, []}, - {update, mnesia_monitor, soft, soft_purge, soft_purge, []}, - {update, mnesia_tm, soft, soft_purge, soft_purge, []} - ] - }, - {"4.4.11", - [ - {update, mnesia, soft, soft_purge, soft_purge, []}, - {update, mnesia_loader, soft, soft_purge, soft_purge, []}, - {update, mnesia_monitor, soft, soft_purge, soft_purge, []}, - {update, mnesia_tm, soft, soft_purge, soft_purge, []}, - {update, mnesia_locker, soft, soft_purge, soft_purge, []}, - {update, mnesia_controller, soft, soft_purge, soft_purge, []} - ] - }, - {"4.4.10", - [ - {update, mnesia, soft, soft_purge, soft_purge, []}, - {update, mnesia_loader, soft, soft_purge, soft_purge, []}, - {update, mnesia_monitor, soft, soft_purge, soft_purge, []}, - {update, mnesia_tm, soft, soft_purge, soft_purge, []}, - {update, mnesia_locker, soft, soft_purge, soft_purge, []}, - {update, mnesia_controller, soft, soft_purge, soft_purge, []} - ] - }, - {"4.4.9", [{restart_application, mnesia}]}, - {"4.4.8", [{restart_application, mnesia}]}, - {"4.4.7", [{restart_application, mnesia}]} ] }. diff --git a/lib/mnesia/src/mnesia_controller.erl b/lib/mnesia/src/mnesia_controller.erl index 9bc480e619..0298b382a6 100644 --- a/lib/mnesia/src/mnesia_controller.erl +++ b/lib/mnesia/src/mnesia_controller.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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% %% @@ -52,6 +52,7 @@ async_dump_log/1, sync_dump_log/1, connect_nodes/1, + connect_nodes/2, wait_for_schema_commit_lock/0, release_schema_commit_lock/0, create_table/1, @@ -94,7 +95,7 @@ load_and_reply/2, send_and_reply/2, wait_for_tables_init/2, - connect_nodes2/2 + connect_nodes2/3 ]). -import(mnesia_lib, [set/2, add/2]). @@ -420,12 +421,15 @@ try_schedule_late_disc_load(Tabs, Reason, MsgTag) -> [[Tabs, Reason, MsgTag], AbortReason]) end. -connect_nodes(Ns) -> +connect_nodes(Ns) -> + connect_nodes(Ns, fun default_merge/1). + +connect_nodes(Ns, UserFun) -> case mnesia:system_info(is_running) of no -> {error, {node_not_running, node()}}; yes -> - Pid = spawn_link(?MODULE,connect_nodes2,[self(),Ns]), + Pid = spawn_link(?MODULE,connect_nodes2,[self(),Ns, UserFun]), receive {?MODULE, Pid, Res, New} -> case Res of @@ -443,7 +447,7 @@ connect_nodes(Ns) -> end end. -connect_nodes2(Father, Ns) -> +connect_nodes2(Father, Ns, UserFun) -> Current = val({current, db_nodes}), abcast([node()|Ns], {merging_schema, node()}), {NewC, OldC} = mnesia_recover:connect_nodes(Ns), @@ -451,7 +455,7 @@ connect_nodes2(Father, Ns) -> New1 = mnesia_lib:intersect(Ns, Connected), New = New1 -- Current, process_flag(trap_exit, true), - Res = try_merge_schema(New), + Res = try_merge_schema(New, UserFun), Msg = {schema_is_merged, [], late_merge, []}, multicall([node()|Ns], Msg), After = val({current, db_nodes}), @@ -465,7 +469,7 @@ connect_nodes2(Father, Ns) -> merge_schema() -> AllNodes = mnesia_lib:all_nodes(), - case try_merge_schema(AllNodes) of + case try_merge_schema(AllNodes, fun default_merge/1) of ok -> schema_is_merged(); {aborted, {throw, Str}} when is_list(Str) -> @@ -474,8 +478,11 @@ merge_schema() -> fatal("Failed to merge schema: ~p~n", [Else]) end. -try_merge_schema(Nodes) -> - case mnesia_schema:merge_schema() of +default_merge(F) -> + F([]). + +try_merge_schema(Nodes, UserFun) -> + case mnesia_schema:merge_schema(UserFun) of {atomic, not_merged} -> %% No more nodes that we need to merge the schema with ok; @@ -488,11 +495,11 @@ try_merge_schema(Nodes) -> im_running(OldFriends, NewFriends), im_running(NewFriends, OldFriends), - try_merge_schema(Nodes); + try_merge_schema(Nodes, UserFun); {atomic, {"Cannot get cstructs", Node, Reason}} -> dbg_out("Cannot get cstructs, Node ~p ~p~n", [Node, Reason]), timer:sleep(1000), % Avoid a endless loop look alike - try_merge_schema(Nodes); + try_merge_schema(Nodes, UserFun); Other -> Other end. @@ -1842,17 +1849,20 @@ reply(ReplyTo, Reply) -> add_worker(Worker = #dump_log{}, State) -> InitBy = Worker#dump_log.initiated_by, Queue = State#state.dumper_queue, - case lists:keymember(InitBy, #dump_log.initiated_by, Queue) of - true when Worker#dump_log.opt_reply_to == undefined -> - %% The same threshold has been exceeded again, - %% before we have had the possibility to - %% process the older one. - DetectedBy = {dump_log, InitBy}, - Event = {mnesia_overload, DetectedBy}, - mnesia_lib:report_system_event(Event); - _ -> - ignore - end, + Status = + case lists:keymember(InitBy, #dump_log.initiated_by, Queue) of + true when Worker#dump_log.opt_reply_to == undefined -> + %% The same threshold has been exceeded again, + %% before we have had the possibility to + %% process the older one. + DetectedBy = {dump_log, InitBy}, + Event = {mnesia_overload, DetectedBy}, + mnesia_lib:report_system_event(Event), + true; + _ -> + false + end, + mnesia_recover:log_dump_overload(Status), Queue2 = Queue ++ [Worker], State2 = State#state{dumper_queue = Queue2}, opt_start_worker(State2); diff --git a/lib/mnesia/src/mnesia_lib.erl b/lib/mnesia/src/mnesia_lib.erl index dba808e66e..3da3dd2f5c 100644 --- a/lib/mnesia/src/mnesia_lib.erl +++ b/lib/mnesia/src/mnesia_lib.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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% %% @@ -113,6 +113,9 @@ mkcore/1, not_active_here/1, other_val/2, + overload_read/0, + overload_read/1, + overload_set/2, pad_name/3, random_time/2, read_counter/1, @@ -551,6 +554,33 @@ cs_to_nodes(Cs) -> Cs#cstruct.disc_only_copies ++ Cs#cstruct.disc_copies ++ Cs#cstruct.ram_copies. + +overload_types() -> + [mnesia_tm, mnesia_dump_log]. + +valid_overload_type(T) -> + case lists:member(T, overload_types()) of + false -> + erlang:error(bad_type); + true -> + true + end. + +overload_set(Type, Bool) when is_boolean(Bool) -> + valid_overload_type(Type), + set({overload, Type}, Bool). + +overload_read() -> + [{T, overload_read(T)} || T <- overload_types()]. + +overload_read(T) -> + case ?catch_val({overload, T}) of + {'EXIT',_} -> + valid_overload_type(T), + false; + Flag when is_boolean(Flag) -> + Flag + end. dist_coredump() -> dist_coredump(all_nodes()). diff --git a/lib/mnesia/src/mnesia_monitor.erl b/lib/mnesia/src/mnesia_monitor.erl index 5df5df4969..5bd93d6b9b 100644 --- a/lib/mnesia/src/mnesia_monitor.erl +++ b/lib/mnesia/src/mnesia_monitor.erl @@ -256,6 +256,7 @@ init([Parent]) -> ?ets_new_table(mnesia_gvar, [set, public, named_table]), ?ets_new_table(mnesia_stats, [set, public, named_table]), set(subscribers, []), + set(activity_subscribers, []), mnesia_lib:verbose("~p starting: ~p~n", [?MODULE, self()]), Version = mnesia:system_info(version), set(version, Version), diff --git a/lib/mnesia/src/mnesia_recover.erl b/lib/mnesia/src/mnesia_recover.erl index 6c53c2e752..0ca7bf3f7f 100644 --- a/lib/mnesia/src/mnesia_recover.erl +++ b/lib/mnesia/src/mnesia_recover.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% %% @@ -36,6 +36,7 @@ incr_trans_tid_serial/0, init/0, log_decision/1, + log_dump_overload/1, log_master_nodes/3, log_mnesia_down/1, log_mnesia_up/1, @@ -70,6 +71,7 @@ unclear_decision, unclear_waitfor, tm_queue_len = 0, + log_dump_overload = false, initiated = false, early_msgs = [] }). @@ -277,6 +279,9 @@ mnesia_down(Node) -> cast({mnesia_down, Node}) end. +log_dump_overload(Flag) when is_boolean(Flag) -> + cast({log_dump_overload, Flag}). + log_master_nodes(Args, UseDir, IsRunning) -> if IsRunning == yes -> @@ -818,6 +823,12 @@ handle_cast({announce_all, Nodes}, State) -> announce_all(Nodes), {noreply, State}; +handle_cast({log_dump_overload, Flag}, State) when is_boolean(Flag) -> + Prev = State#state.log_dump_overload, + Overload = Prev orelse Flag, + mnesia_lib:overload_set(mnesia_dump_log, Overload), + {noreply, State#state{log_dump_overload = Flag}}; + handle_cast(Msg, State) -> error("~p got unexpected cast: ~p~n", [?MODULE, Msg]), {noreply, State}. @@ -851,12 +862,14 @@ handle_info(check_overload, S) -> Len > Threshold, Prev > Threshold -> What = {mnesia_tm, message_queue_len, [Prev, Len]}, mnesia_lib:report_system_event({mnesia_overload, What}), + mnesia_lib:overload_set(mnesia_tm, true), {noreply, S#state{tm_queue_len = 0}}; Len > Threshold -> {noreply, S#state{tm_queue_len = Len}}; true -> + mnesia_lib:overload_set(mnesia_tm, false), {noreply, S#state{tm_queue_len = 0}} end; undefined -> @@ -905,7 +918,23 @@ terminate(Reason, State) -> %% Purpose: Upgrade process when its code is to be changed %% Returns: {ok, NewState} %%---------------------------------------------------------------------- -code_change(_OldVsn, State, _Extra) -> +code_change(_OldVsn, {state, + Supervisor, + Unclear_pid, + Unclear_decision, + Unclear_waitfor, + Tm_queue_len, + Initiated, + Early_msgs + }, _Extra) -> + {ok, #state{supervisor = Supervisor, + unclear_pid = Unclear_pid, + unclear_decision = Unclear_decision, + unclear_waitfor = Unclear_waitfor, + tm_queue_len = Tm_queue_len, + initiated = Initiated, + early_msgs = Early_msgs}}; +code_change(_OldVsn, #state{} = State, _Extra) -> {ok, State}. %%%---------------------------------------------------------------------- diff --git a/lib/mnesia/src/mnesia_registry.erl b/lib/mnesia/src/mnesia_registry.erl index 9805d48697..202689ae5e 100644 --- a/lib/mnesia/src/mnesia_registry.erl +++ b/lib/mnesia/src/mnesia_registry.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% Copyright Ericsson AB 1998-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 @@ -65,6 +65,8 @@ %%%---------------------------------------------------------------------- %% External exports +%% Avoid warning for local function max/2 clashing with autoimported BIF. +-compile({no_auto_import,[max/2]}). -export([start_dump/2, start_restore/2]). -export([create_table/1, create_table/2]). diff --git a/lib/mnesia/src/mnesia_schema.erl b/lib/mnesia/src/mnesia_schema.erl index 354431a296..17e570b881 100644 --- a/lib/mnesia/src/mnesia_schema.erl +++ b/lib/mnesia/src/mnesia_schema.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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% %% @@ -62,6 +62,7 @@ list2cs/1, lock_schema/0, merge_schema/0, + merge_schema/1, move_table/3, opt_create_dir/2, prepare_commit/3, @@ -2650,10 +2651,16 @@ make_dump_tables([]) -> %% Merge the local schema with the schema on other nodes merge_schema() -> - schema_transaction(fun() -> do_merge_schema() end). + schema_transaction(fun() -> do_merge_schema([]) end). + +merge_schema(UserFun) -> + schema_transaction(fun() -> UserFun(fun(Arg) -> do_merge_schema(Arg) end) end). -do_merge_schema() -> + +do_merge_schema(LockTabs0) -> {_Mod, Tid, Ts} = get_tid_ts_and_lock(schema, write), + LockTabs = [{T, tab_to_nodes(T)} || T <- LockTabs0], + [get_tid_ts_and_lock(T,write) || {T,_} <- LockTabs], Connected = val(recover_nodes), Running = val({current, db_nodes}), Store = Ts#tidstore.store, @@ -2665,9 +2672,12 @@ do_merge_schema() -> mnesia:abort({bad_commit, {missing_lock, Miss}}) end, case Connected -- Running of - [Node | _] -> + [Node | _] = OtherNodes -> %% Time for a schema merging party! mnesia_locker:wlock_no_exist(Tid, Store, schema, [Node]), + [mnesia_locker:wlock_no_exist( + Tid, Store, T, mnesia_lib:intersect(Ns, OtherNodes)) + || {T,Ns} <- LockTabs], case rpc:call(Node, mnesia_controller, get_cstructs, []) of {cstructs, Cstructs, RemoteRunning1} -> LockedAlready = Running ++ [Node], @@ -2681,6 +2691,9 @@ do_merge_schema() -> end, NeedsLock = RemoteRunning -- LockedAlready, mnesia_locker:wlock_no_exist(Tid, Store, schema, NeedsLock), + [mnesia_locker:wlock_no_exist(Tid, Store, T, + mnesia_lib:intersect(Ns,NeedsLock)) + || {T,Ns} <- LockTabs], {value, SchemaCs} = lists:keysearch(schema, #cstruct.name, Cstructs), @@ -2714,6 +2727,10 @@ do_merge_schema() -> not_merged end. +tab_to_nodes(Tab) when is_atom(Tab) -> + Cs = val({Tab, cstruct}), + mnesia_lib:cs_to_nodes(Cs). + make_merge_schema(Node, [Cs | Cstructs]) -> Ops = do_make_merge_schema(Node, Cs), Ops ++ make_merge_schema(Node, Cstructs); diff --git a/lib/mnesia/src/mnesia_subscr.erl b/lib/mnesia/src/mnesia_subscr.erl index afd1704dec..93d4a86f7f 100644 --- a/lib/mnesia/src/mnesia_subscr.erl +++ b/lib/mnesia/src/mnesia_subscr.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% %% @@ -30,7 +30,8 @@ subscribers/0, report_table_event/4, report_table_event/5, - report_table_event/6 + report_table_event/6, + report_activity/1 ]). %% gen_server callbacks @@ -91,6 +92,8 @@ set_debug_level(Level, OldEnv) -> subscribe(ClientPid, system) -> change_subscr(activate, ClientPid, system); +subscribe(ClientPid, activity) -> + change_subscr(activate, ClientPid, activity); subscribe(ClientPid, {table, Tab}) -> change_subscr(activate, ClientPid, {table, Tab, simple}); subscribe(ClientPid, {table, Tab, simple}) -> @@ -102,6 +105,8 @@ subscribe(_ClientPid, What) -> unsubscribe(ClientPid, system) -> change_subscr(deactivate, ClientPid, system); +unsubscribe(ClientPid, activity) -> + change_subscr(deactivate, ClientPid, activity); unsubscribe(ClientPid, {table, Tab}) -> change_subscr(deactivate, ClientPid, {table, Tab, simple}); unsubscribe(ClientPid, {table, Tab, simple}) -> @@ -120,6 +125,15 @@ change_subscr(Kind, ClientPid, What) -> subscribers() -> [whereis(mnesia_event) | mnesia_lib:val(subscribers)]. +report_activity({dirty, _pid}) -> + ok; +report_activity(Tid) -> + case ?catch_val(activity_subscribers) of + {'EXIT', _} -> ok; + Subscribers -> + deliver(Subscribers, {mnesia_activity_event, {complete, Tid}}) + end. + report_table_event(Tab, Tid, Obj, Op) -> case ?catch_val({Tab, commit_work}) of {'EXIT', _} -> ok; @@ -300,6 +314,9 @@ code_change(_OldVsn, State, _Extra) -> do_change({activate, ClientPid, system}, SubscrTab) when is_pid(ClientPid) -> Var = subscribers, activate(ClientPid, system, Var, subscribers(), SubscrTab); +do_change({activate, ClientPid, activity}, SubscrTab) when is_pid(ClientPid) -> + Var = activity_subscribers, + activate(ClientPid, activity, Var, mnesia_lib:val(Var), SubscrTab); do_change({activate, ClientPid, {table, Tab, How}}, SubscrTab) when is_pid(ClientPid) -> case ?catch_val({Tab, where_to_read}) of Node when Node == node() -> @@ -313,6 +330,9 @@ do_change({activate, ClientPid, {table, Tab, How}}, SubscrTab) when is_pid(Clien do_change({deactivate, ClientPid, system}, SubscrTab) -> Var = subscribers, deactivate(ClientPid, system, Var, SubscrTab); +do_change({deactivate, ClientPid, activity}, SubscrTab) -> + Var = activity_subscribers, + deactivate(ClientPid, activity, Var, SubscrTab); do_change({deactivate, ClientPid, {table, Tab, How}}, SubscrTab) -> Var = {Tab, commit_work}, deactivate(ClientPid, {table, Tab, How}, Var, SubscrTab); @@ -345,7 +365,7 @@ do_change(_, _) -> activate(ClientPid, What, Var, OldSubscribers, SubscrTab) -> Old = - if Var == subscribers -> + if Var == subscribers orelse Var == activity_subscribers -> OldSubscribers; true -> case lists:keysearch(subscribers, 1, OldSubscribers) of @@ -379,6 +399,9 @@ activate(ClientPid, What, Var, OldSubscribers, SubscrTab) -> add_subscr(subscribers, _What, Pid) -> mnesia_lib:add(subscribers, Pid), {ok, node()}; +add_subscr(activity_subscribers, _What, Pid) -> + mnesia_lib:add(activity_subscribers, Pid), + {ok, node()}; add_subscr({Tab, commit_work}, What, Pid) -> Commit = mnesia_lib:val({Tab, commit_work}), case lists:keysearch(subscribers, 1, Commit) of @@ -427,6 +450,8 @@ deactivate(ClientPid, What, Var, SubscrTab) -> del_subscr(subscribers, _What, Pid) -> mnesia_lib:del(subscribers, Pid); +del_subscr(activity_subscribers, _What, Pid) -> + mnesia_lib:del(activity_subscribers, Pid); del_subscr({Tab, commit_work}, What, Pid) -> Commit = mnesia_lib:val({Tab, commit_work}), case lists:keysearch(subscribers, 1, Commit) of @@ -473,6 +498,8 @@ do_handle_exit([{ClientPid, What} | Tail]) -> case What of system -> del_subscr(subscribers, What, ClientPid); + activity -> + del_subscr(activity_subscribers, What, ClientPid); {_, Tab, _Level} -> del_subscr({Tab, commit_work}, What, ClientPid) end, diff --git a/lib/mnesia/src/mnesia_text.erl b/lib/mnesia/src/mnesia_text.erl index f1a28bf43d..ab1362f6b6 100644 --- a/lib/mnesia/src/mnesia_text.erl +++ b/lib/mnesia/src/mnesia_text.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. +%% Copyright Ericsson AB 1996-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 @@ -20,6 +20,8 @@ %% -module(mnesia_text). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([parse/1, file/1, load_textfile/1, dump_to_textfile/1]). load_textfile(File) -> diff --git a/lib/mnesia/src/mnesia_tm.erl b/lib/mnesia/src/mnesia_tm.erl index d42109c3da..f3ffac5493 100644 --- a/lib/mnesia/src/mnesia_tm.erl +++ b/lib/mnesia/src/mnesia_tm.erl @@ -1733,7 +1733,9 @@ do_commit(Tid, C, DumperMode) -> R = do_snmp(Tid, C#commit.snmp), R2 = do_update(Tid, ram_copies, C#commit.ram_copies, R), R3 = do_update(Tid, disc_copies, C#commit.disc_copies, R2), - do_update(Tid, disc_only_copies, C#commit.disc_only_copies, R3). + R4 = do_update(Tid, disc_only_copies, C#commit.disc_only_copies, R3), + mnesia_subscr:report_activity(Tid), + R4. %% Update the items do_update(Tid, Storage, [Op | Ops], OldRes) -> diff --git a/lib/mnesia/test/Makefile b/lib/mnesia/test/Makefile index a4f32e3f78..4f98efaed1 100644 --- a/lib/mnesia/test/Makefile +++ b/lib/mnesia/test/Makefile @@ -109,7 +109,7 @@ release_spec: opt release_tests_spec: opt $(INSTALL_DIR) $(RELSYSDIR) $(INSTALL_DATA) mnesia.spec mnesia.spec.vxworks $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR) - $(INSTALL_PROGRAM) mt $(INSTALL_PROGS) $(RELSYSDIR) + $(INSTALL_SCRIPT) mt $(INSTALL_PROGS) $(RELSYSDIR) # chmod -f -R u+w $(RELSYSDIR) # @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) diff --git a/lib/mnesia/test/mnesia_evil_coverage_test.erl b/lib/mnesia/test/mnesia_evil_coverage_test.erl index 06674d9eef..4fbf1b4003 100644 --- a/lib/mnesia/test/mnesia_evil_coverage_test.erl +++ b/lib/mnesia/test/mnesia_evil_coverage_test.erl @@ -61,6 +61,7 @@ all(suite) -> unsupp_user_props, record_name, snmp_access, + subscriptions, iteration, debug_support, sorted_ets, @@ -1775,6 +1776,239 @@ get_keys(Tab, Key) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +-record(tab, {i, e1, e2}). % Simple test table + +subscriptions(doc) -> + ["Test the event subscription mechanism"]; +subscriptions(suite) -> + [subscribe_standard, + subscribe_extended]. + +subscribe_extended(doc) -> + ["Test the extended set of events, test with and without checkpoints. "]; +subscribe_extended(suite) -> + []; +subscribe_extended(Config) when is_list(Config) -> + [N1, N2]=Nodes=?acquire_nodes(2, Config), + Tab1 = etab, + Storage = mnesia_test_lib:storage_type(ram_copies, Config), + Def1 = [{Storage, [N1, N2]}, {attributes, record_info(fields, tab)}], + ?match({atomic, ok}, mnesia:create_table(Tab1, Def1)), + + Tab2 = bag, + Def2 = [{Storage, [N1, N2]}, + {type, bag}, + {record_name, Tab1}, + {attributes, record_info(fields, tab)}], + ?match({atomic, ok}, mnesia:create_table(Tab2, Def2)), + + ?match({ok, N1}, mnesia:subscribe({table, Tab1, detailed})), + ?match({ok, N1}, mnesia:subscribe({table, Tab2, detailed})), + + ?match({error, {already_exists, _}}, mnesia:subscribe({table, Tab1, simple})), + ?match({error, {badarg, {table, Tab1, bad}}}, mnesia:subscribe({table, Tab1, bad})), + + ?match({ok, N1}, mnesia:subscribe(activity)), + test_ext_sub(Tab1, Tab2), + + ?match({ok, N1}, mnesia:unsubscribe(activity)), + ?match({ok, N1}, mnesia:subscribe({table, Tab1, detailed})), + ?match({atomic, ok}, mnesia:clear_table(Tab1)), + ?match({mnesia_table_event, {delete, schema, {schema, Tab1}, [{schema, Tab1, _}],_}}, recv_event()), + ?match({mnesia_table_event, {write, schema, {schema, Tab1, _}, [], _}}, recv_event()), + + ?match({atomic, ok}, mnesia_schema:clear_table(Tab2)), + ?match({mnesia_table_event, {delete, schema, {schema, Tab2}, [{schema, Tab2, _}],_}}, + recv_event()), + ?match({mnesia_table_event, {write, schema, {schema, Tab2, _}, [], _}}, recv_event()), + + ?match({ok, N1}, mnesia:unsubscribe({table, Tab2, detailed})), + {ok, _, _} = mnesia:activate_checkpoint([{name, testing}, + {ram_overrides_dump, true}, + {max, [Tab1, Tab2]}]), + ?match({ok, N1}, mnesia:subscribe({table, Tab2, detailed})), + ?match({ok, N1}, mnesia:subscribe(activity)), + test_ext_sub(Tab1, Tab2), + + ?verify_mnesia(Nodes, []). + +test_ext_sub(Tab1, Tab2) -> + %% The basics + Rec1 = {Tab1, 1, 0, 0}, + Rec2 = {Tab1, 1, 1, 0}, + Rec3 = {Tab1, 2, 1, 0}, + Rec4 = {Tab1, 2, 2, 0}, + + Write = fun(Tab, Rec) -> + mnesia:transaction(fun() -> mnesia:write(Tab, Rec, write) + end) + end, + Delete = fun(Tab, Rec) -> + mnesia:transaction(fun() -> mnesia:delete(Tab, Rec, write) + end) + end, + DelObj = fun(Tab, Rec) -> + mnesia:transaction(fun() -> mnesia:delete_object(Tab, Rec, write) + end) + end, + + S = self(), + D = {dirty, self()}, + %% SET + ?match(ok, mnesia:dirty_write(Rec1)), + ?match({mnesia_table_event, {write, Tab1, Rec1, [], D}}, recv_event()), + ?match(ok, mnesia:dirty_write(Rec3)), + ?match({mnesia_table_event, {write, Tab1, Rec3, [], D}}, recv_event()), + ?match(ok, mnesia:dirty_write(Rec1)), + ?match({mnesia_table_event, {write, Tab1, Rec1, [Rec1], D}}, recv_event()), + ?match({atomic, ok}, Write(Tab1, Rec2)), + ?match({mnesia_table_event, {write, Tab1, Rec2, [Rec1], {tid,_,S}}}, recv_event()), + ?match({mnesia_activity_event, {complete, {tid,_,S}}}, recv_event()), + ?match(ok, mnesia:dirty_delete({Tab1, 2})), + ?match({mnesia_table_event, {delete, Tab1, {Tab1, 2}, [Rec3], D}}, recv_event()), + ?match({atomic, ok}, DelObj(Tab1, Rec2)), + ?match({mnesia_table_event, {delete, Tab1, Rec2, [Rec2], {tid,_,S}}}, recv_event()), + ?match({mnesia_activity_event, {complete, {tid,_,S}}}, recv_event()), + + ?match({atomic, ok}, Delete(Tab1, 1)), + ?match({mnesia_table_event, {delete, Tab1, {Tab1, 1}, [], {tid,_,S}}}, recv_event()), + ?match({mnesia_activity_event, {complete, {tid,_,S}}}, recv_event()), + + ?match({ok, _N1}, mnesia:unsubscribe({table, Tab1, detailed})), + + %% BAG + + ?match({atomic, ok}, Write(Tab2, Rec1)), + ?match({mnesia_table_event, {write, Tab2, Rec1, [], {tid,_,S}}}, recv_event()), + ?match({mnesia_activity_event, {complete, {tid,_,S}}}, recv_event()), + ?match({atomic, ok}, Write(Tab2, Rec4)), + ?match({mnesia_table_event, {write, Tab2, Rec4, [], {tid,_,S}}}, recv_event()), + ?match({mnesia_activity_event, {complete, {tid,_,S}}}, recv_event()), + ?match({atomic, ok}, Write(Tab2, Rec3)), + ?match({mnesia_table_event, {write, Tab2, Rec3, [Rec4], {tid,_,S}}}, recv_event()), + ?match({mnesia_activity_event, {complete, {tid,_,S}}}, recv_event()), + ?match({atomic, ok}, Write(Tab2, Rec2)), + ?match({mnesia_table_event, {write, Tab2, Rec2, [Rec1], {tid,_,S}}}, recv_event()), + ?match({mnesia_activity_event, {complete, {tid,_,S}}}, recv_event()), + ?match({atomic, ok}, Write(Tab2, Rec1)), + ?match({mnesia_table_event, {write, Tab2, Rec1, [Rec1, Rec2], {tid,_,S}}}, recv_event()), + ?match({mnesia_activity_event, {complete, {tid,_,S}}}, recv_event()), + ?match({atomic, ok}, DelObj(Tab2, Rec2)), + ?match({mnesia_table_event, {delete, Tab2, Rec2, [Rec2], {tid,_,S}}}, recv_event()), + ?match({mnesia_activity_event, {complete, {tid,_,S}}}, recv_event()), + ?match({atomic, ok}, Delete(Tab2, 1)), + ?match({mnesia_table_event, {delete, Tab2, {Tab2, 1}, [Rec1], {tid,_,S}}}, recv_event()), + ?match({mnesia_activity_event, {complete, {tid,_,S}}}, recv_event()), + ?match({atomic, ok}, Delete(Tab2, 2)), + ?match({mnesia_table_event, {delete, Tab2, {Tab2, 2}, [Rec4, Rec3], {tid,_,S}}}, recv_event()), + ?match({mnesia_activity_event, {complete, {tid,_,S}}}, recv_event()), + ok. + + +subscribe_standard(doc) -> + ["Tests system events and the orignal table events"]; +subscribe_standard(suite) -> []; +subscribe_standard(Config) when is_list(Config)-> + [N1, N2]=?acquire_nodes(2, Config), + Tab = tab, + + Storage = mnesia_test_lib:storage_type(disc_copies, Config), + Def = [{Storage, [N1, N2]}, {attributes, record_info(fields, tab)}], + + ?match({atomic, ok}, mnesia:create_table(Tab, Def)), + + %% Check system events + ?match({ok, N1}, mnesia:subscribe(system)), + ?match({ok, N1}, mnesia:subscribe(activity)), + + ?match([], mnesia_test_lib:kill_mnesia([N2])), + ?match({mnesia_system_event, {mnesia_down, N2}}, recv_event()), + ?match(timeout, recv_event()), + + ?match([], mnesia_test_lib:start_mnesia([N2], [Tab])), + ?match({mnesia_activity_event, _}, recv_event()), + ?match({mnesia_system_event,{mnesia_up, N2}}, recv_event()), + + ?match(true, lists:member(self(), mnesia:system_info(subscribers))), + ?match([], mnesia_test_lib:kill_mnesia([N1])), + timer:sleep(500), + mnesia_test_lib:flush(), + ?match([], mnesia_test_lib:start_mnesia([N1], [Tab])), + ?match(timeout, recv_event()), + + ?match({ok, N1}, mnesia:subscribe(system)), + ?match({error, {already_exists, system}}, mnesia:subscribe(system)), + ?match(stopped, mnesia:stop()), + ?match({mnesia_system_event, {mnesia_down, N1}}, recv_event()), + ?match({error, {node_not_running, N1}}, mnesia:subscribe(system)), + ?match([], mnesia_test_lib:start_mnesia([N1, N2], [Tab])), + + %% Check table events + ?match({ok, N1}, mnesia:subscribe(activity)), + Old_Level = mnesia:set_debug_level(trace), + ?match({ok, N1}, mnesia:subscribe({table,Tab})), + + ?match({atomic, ok}, + mnesia:transaction(fun() -> mnesia:write(#tab{i=155}) end)), + Self = self(), + ?match({mnesia_table_event, {write, _, _}}, recv_event()), + ?match({mnesia_activity_event, {complete, {tid, _, Self}}}, recv_event()), + + ?match({ok, N1}, mnesia:unsubscribe({table,Tab})), + ?match({ok, N1}, mnesia:unsubscribe(activity)), + + ?match({atomic, ok}, + mnesia:transaction(fun() -> mnesia:write(#tab{i=255}) end)), + + ?match(timeout, recv_event()), + mnesia:set_debug_level(Old_Level), + + %% Check deletion of replica + + ?match({ok, N1}, mnesia:subscribe({table,Tab})), + ?match({ok, N1}, mnesia:subscribe(activity)), + ?match(ok, mnesia:dirty_write(#tab{i=355})), + ?match({mnesia_table_event, {write, _, _}}, recv_event()), + ?match({atomic, ok}, mnesia:del_table_copy(Tab, N1)), + ?match({mnesia_activity_event, _}, recv_event()), + ?match(ok, mnesia:dirty_write(#tab{i=455})), + ?match(timeout, recv_event()), + + ?match({atomic, ok}, mnesia:move_table_copy(Tab, N2, N1)), + ?match({mnesia_activity_event, _}, recv_event()), + ?match({ok, N1}, mnesia:subscribe({table,Tab})), + ?match(ok, mnesia:dirty_write(#tab{i=555})), + ?match({mnesia_table_event, {write, _, _}}, recv_event()), + ?match({atomic, ok}, mnesia:move_table_copy(Tab, N1, N2)), + ?match({mnesia_activity_event, _}, recv_event()), + ?match(ok, mnesia:dirty_write(#tab{i=655})), + ?match(timeout, recv_event()), + + ?match({atomic, ok}, mnesia:add_table_copy(Tab, N1, ram_copies)), + ?match({mnesia_activity_event, _}, recv_event()), + ?match({ok, N1}, mnesia:subscribe({table,Tab})), + ?match({error, {already_exists, {table,Tab, simple}}}, + mnesia:subscribe({table,Tab})), + ?match(ok, mnesia:dirty_write(#tab{i=755})), + ?match({mnesia_table_event, {write, _, _}}, recv_event()), + + ?match({atomic, ok}, mnesia:delete_table(Tab)), + ?match({mnesia_activity_event, _}, recv_event()), + ?match(timeout, recv_event()), + + mnesia_test_lib:kill_mnesia([N1]), + + ?verify_mnesia([N2], [N1]). + +recv_event() -> + receive + Event -> Event + after 1000 -> + timeout + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% iteration(doc) -> ["Verify that the iteration functions works as expected"]; iteration(suite) -> diff --git a/lib/mnesia/vsn.mk b/lib/mnesia/vsn.mk index 31cc8f8513..bce0f7b739 100644 --- a/lib/mnesia/vsn.mk +++ b/lib/mnesia/vsn.mk @@ -1,16 +1 @@ - -MNESIA_VSN = 4.4.13 - -TICKETS = 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 +MNESIA_VSN = 4.4.15 diff --git a/lib/observer/doc/src/notes.xml b/lib/observer/doc/src/notes.xml index 48c7c21363..3d7c4fa269 100644 --- a/lib/observer/doc/src/notes.xml +++ b/lib/observer/doc/src/notes.xml @@ -31,6 +31,21 @@ <p>This document describes the changes made to the Observer application.</p> +<section><title>Observer 0.9.8.3</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The test suite has been updated for R14A.</p> + <p> + Own Id: OTP-8708</p> + </item> + </list> + </section> + +</section> + <section><title>Observer 0.9.8.2</title> <section><title>Improvements and New Features</title> diff --git a/lib/observer/test/Makefile b/lib/observer/test/Makefile new file mode 100644 index 0000000000..6f1430b00a --- /dev/null +++ b/lib/observer/test/Makefile @@ -0,0 +1,90 @@ +# ``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 via the world wide web 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. +# +# The Initial Developer of the Original Code is Ericsson Utvecklings AB. +# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings +# AB. All Rights Reserved.'' +# +# $Id$ +# +include $(ERL_TOP)/make/target.mk +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +MODULES = \ + observer_SUITE \ + crashdump_viewer_SUITE \ + etop_SUITE \ + ttb_SUITE \ + crashdump_helper + +ERL_FILES= $(MODULES:%=%.erl) + +TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) +INSTALL_PROGS= $(TARGET_FILES) + +EMAKEFILE=Emakefile +COVERFILE=observer.cover + +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/observer_test + +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +ERL_MAKE_FLAGS += -pa $(ERL_TOP)/lib/test_server/ebin +ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include + +EBIN = . + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- +.PHONY: make_emakefile + +make_emakefile: + $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) \ + $(MODULES) >> $(EMAKEFILE) + +tests debug opt: make_emakefile + cd $(ERL_TOP)/lib/test_server/src && \ + $(MAKE) ../ebin/test_server_line.beam + erl $(ERL_MAKE_FLAGS) -make + +clean: + rm -f $(EMAKEFILE) + rm -f $(TARGET_FILES) + rm -f core + +docs: + +# ---------------------------------------------------- +# Special targets +# ---------------------------------------------------- + +# ---------------------------------------------------- +# Release Target +# ---------------------------------------------------- +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: opt + +release_tests_spec: make_emakefile + $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DATA) observer.spec observer.dynspec $(EMAKEFILE) \ + $(COVERFILE) $(ERL_FILES) \ + $(RELSYSDIR) + @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + +release_docs_spec: + + diff --git a/lib/observer/test/crashdump_helper.erl b/lib/observer/test/crashdump_helper.erl new file mode 100644 index 0000000000..43b3db738f --- /dev/null +++ b/lib/observer/test/crashdump_helper.erl @@ -0,0 +1,61 @@ +%% +%% %CopyrightBegin% +%% +%% 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 +%% 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(crashdump_helper). +-export([n1_proc/2,remote_proc/2]). +-compile(r11). +-include("test_server.hrl"). + +n1_proc(N2,Creator) -> + spawn(fun() -> n1_proc(Creator,N2,x,[]) end). +n1_proc(Creator,N2,P2,L) when P2==x;length(L)<2-> + receive + {N2,P} -> + n1_proc(Creator,N2,P,L); + P -> + n1_proc(Creator,N2,P2,[P|L]) + end; +n1_proc(Creator,_N2,P2,_L) -> + register(aaaaaaaa,self()), + process_flag(save_calls,3), + ets:new(cdv_test_ordset_table,[ordered_set]), + erlang:send_after(1000000,self(),cdv_test_timer_message), + Port = hd(erlang:ports()), + Fun = fun() -> ok end, + Ref = make_ref(), + Pid = self(), + Bin = list_to_binary(lists:seq(1, 255)), + SubBin = element(1, split_binary(element(2, split_binary(Bin, 8)), 17)), + DictionaryValue = {"list",atom,42,54.654,math:pow(2,1023),{}, + Port,Fun,Ref,Pid, + Bin,SubBin,83974938738373873,-38748762783736367}, + put(dictionary_key,DictionaryValue), + spawn(fun() -> register(aaaaaaab,self()), + receive after infinity -> ok end + end), + link(P2), + Creator ! {self(),done}, + receive after infinity -> ok end. + +remote_proc(P1,Creator) -> + spawn(fun() -> + P1 ! {node(),self()}, + Creator ! {self(),done}, + receive after infinity -> ok end + end). diff --git a/lib/observer/test/crashdump_viewer_SUITE.erl b/lib/observer/test/crashdump_viewer_SUITE.erl new file mode 100644 index 0000000000..fcf383dc2e --- /dev/null +++ b/lib/observer/test/crashdump_viewer_SUITE.erl @@ -0,0 +1,723 @@ +%% +%% %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% +%% + +-module(crashdump_viewer_SUITE). + +%% Test functions +-export([all/1,translate/1,start/1,fini/1,load_file/1, + non_existing/1,not_a_crashdump/1,old_crashdump/1]). +-export([init_per_suite/1, end_per_suite/1]). +-export([init_per_testcase/2, end_per_testcase/2]). + +-include("test_server.hrl"). +-include("test_server_line.hrl"). +-include_lib("kernel/include/file.hrl"). + +-include_lib("stdlib/include/ms_transform.hrl"). + +-define(default_timeout, ?t:minutes(30)). +-define(sl_alloc_vsns,[r9b]). + +init_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir,Config), + Fs = filelib:wildcard(filename:join(DataDir,"*translated*")), + lists:foreach(fun(F) -> file:delete(F) end,Fs), + catch crashdump_viewer:stop(), + Dog = ?t:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. +end_per_testcase(_Case, Config) -> + Dog=?config(watchdog, Config), + ?t:timetrap_cancel(Dog), + ok. + +all(suite) -> + [translate,{conf,start,[load_file,non_existing,not_a_crashdump, + old_crashdump],fini}]. + +init_per_suite(doc) -> + ["Create a lot of crashdumps which can be used in the testcases below"]; +init_per_suite(Config) when is_list(Config) -> + Dog = ?t:timetrap(?default_timeout), + application:start(inets), % will be using the http client later + http:set_options([{ipv6,disabled}]), + DataDir = ?config(data_dir,Config), + Rels = [R || R <- [r12b,r13b], ?t:is_release_available(R)] ++ [current], + io:format("Creating crash dumps for the following releases: ~p", [Rels]), + AllDumps = create_dumps(DataDir,Rels), + ?t:timetrap_cancel(Dog), + [{dumps,AllDumps}|Config]. + +translate(suite) -> + []; +translate(doc) -> + ["Test that crash dumps from OTP R9B can be translated"]; +translate(Config) when is_list(Config) -> + DataDir = ?config(data_dir,Config), + OutFile = filename:join(DataDir,"translated"), + + R9BFiles = filelib:wildcard(filename:join(DataDir,"r9b_dump.*")), + AllFiles = R9BFiles, + lists:foreach( + fun(File) -> + io:format("Translating file: ~s~n",[File]), + ok = crashdump_translate:old2new(File,OutFile), + check_result(File,OutFile) + end, + AllFiles), + ok. + +start(suite) -> + []; +start(doc) -> + ["Test start and stop of the Crashdump Viewer"]; +start(Config) when is_list(Config) -> + %% Set a much shorter timeout here... We don't have all the time in world. + AngryDog = ?t:timetrap(?t:seconds(30)), + Port = start_cdv(), + true = is_pid(whereis(crashdump_viewer_server)), + true = is_pid(whereis(web_tool)), + Html = contents(Port,"start_page"), + "Welcome to the Web BasedErlang Crash Dump Analyser" = strip(Html), + ok = crashdump_viewer:stop(), + timer:sleep(10), % give some time to stop + undefined = whereis(crashdump_viewer_server), + undefined = whereis(web_tool), + Url = cdv_url(Port,"start_page"), + {error,_} = http:request(get,{Url,[]},[],[]), +% exit(whereis(httpc_manager),kill), + ?t:timetrap_cancel(AngryDog), + ok. + +fini(Config) when is_list(Config) -> + ok. + +load_file(suite) -> + []; +load_file(doc) -> + ["Load files into the tool and view all pages"]; +load_file(Config) when is_list(Config) -> + case ?t:is_debug() of + true -> + {skip,"Debug-compiled emulator -- far too slow"}; + false -> + load_file_1(Config) + end. + + +load_file_1(Config) -> + DataDir = ?config(data_dir,Config), + Port = start_cdv(), + + AllFiles = filelib:wildcard(filename:join(DataDir,"r*_dump.*")), + lists:foreach( + fun(File) -> + browse_file(Port,File), + special(Port,File) + end, + AllFiles), + ok = crashdump_viewer:stop(). + +non_existing(suite) -> + []; +non_existing(doc) -> + ["Try to load nonexisting file"]; +non_existing(Config) when is_list(Config) -> + Port = start_cdv(), + Url = "http://localhost:"++Port++"/cdv_erl/crashdump_viewer/read_file", + Html = request_sync(post,{Url,[],[],"path=nonexistingfile"}), + "Please wait..." = title(Html), + "An error occured:nonexistingfile is not an Erlang crash dump" = + strip(wait(10,Port,"redirect")), + ok = crashdump_viewer:stop(). + +old_crashdump(doc) -> + ["Try to load nonexisting file"]; +old_crashdump(Config) when is_list(Config) -> + Port = start_cdv(), + DataDir = ?config(data_dir, Config), + OldCrashDump = filename:join(DataDir, "old_format.dump"), + Url = "http://localhost:"++Port++"/cdv_erl/crashdump_viewer/read_file", + Html = request_sync(post,{Url,[],[],"path="++OldCrashDump}), + "Please wait..." = title(Html), + Str = "An error occured:The crashdump "++OldCrashDump++ + " is in the pre-R10B format, which is no longer supported.", + Str = strip(wait(10,Port,"redirect")), + ok = crashdump_viewer:stop(). + + +not_a_crashdump(suite) -> + []; +not_a_crashdump(doc) -> + ["Try to load a file which is not an erlang crashdump"]; +not_a_crashdump(Config) when is_list(Config) -> + Port = start_cdv(), + NoCrashdump = code:which(?MODULE), + Url = "http://localhost:"++Port++"/cdv_erl/crashdump_viewer/read_file", + Html = request_sync(post,{Url,[],[],"path="++NoCrashdump}), + "Please wait..." = title(Html), + Str = "An error occured:"++NoCrashdump++" is not an Erlang crash dump", + Str = strip(wait(10,Port,"redirect")), + ok = crashdump_viewer:stop(), +% exit(whereis(httpc_manager),kill), + ok. + + + +end_per_suite(doc) -> + ["Remove generated crashdumps"]; +end_per_suite(Config) when is_list(Config) -> + Dumps = ?config(dumps,Config), + lists:foreach(fun(CD) -> ok = file:delete(CD) end,Dumps), + lists:keydelete(dumps,1,Config). + + +%%%----------------------------------------------------------------- +%%% Internal +start_cdv() -> + ?t:capture_start(), + ok = crashdump_viewer:start(), + "WebTool is available at http://localhost:" ++ Where = + lists:flatten(?t:capture_get()), + ?t:capture_stop(), + [Port|_] = string:tokens(Where,"/"), + Port. + + +check_result(File,OutFile) -> + {ok,#file_info{size=FS}} = file:read_file_info(File), + {ok,#file_info{size=OFS}} = file:read_file_info(OutFile), + Rel = + if OFS > 0 -> FS/OFS; + true -> 1.25 + end, + if Rel>0.75, Rel<1.25 -> ok; + true -> ?t:fail({unreasonable_size,File,FS,OFS}) + end, + {ok,Fd} = file:open(OutFile,[read]), + "=erl_crash_dump:0.0\n" = io:get_line(Fd,''), + case is_truncated(File) of + true -> + ok; + false -> + {ok,_} = file:position(Fd,{eof,-5}), + case io:get_line(Fd,'') of + "=end\n" -> ok; + Other -> ?t:fail({truncated,File,Other}) + end + end, + ok = file:close(Fd). + + +%% Read a page and check that the page title matches Title +contents(Port,Link) -> + Url = cdv_url(Port,Link), + request_sync(get,{Url,[]}). + +cdv_url(Port,Link) -> + "http://localhost:" ++ Port ++ "/cdv_erl/crashdump_viewer/" ++ Link. + +request_sync(Method,HTTPReqCont) -> + case http:request(Method, + HTTPReqCont, + [{timeout,30000}], + [{full_result, false}]) of + {ok,{200,Html}} -> + Html; + {ok,{Code,Html}} -> + io:format("~s\n", [Html]), + io:format("Received ~w from http:request(...) with\nMethod=~w\n" + "HTTPReqCont=~p\n", + [Code,Method,HTTPReqCont]), + ?t:fail(); + Other -> + io:format( + "Received ~w from http:request(...) with\nMethod=~w\n" + "HTTPReqCont=~p\n", + [Other,Method,HTTPReqCont]), + ?t:fail() + end. + + + + +strip([$<|Html]) -> + strip(drop_tag(Html)); +strip([$\n|Html]) -> + strip(Html); +strip([X|Html]) -> + [X|strip(Html)]; +strip([]) -> + []. +drop_tag([$>|Html]) -> + Html; +drop_tag([_|Html]) -> + drop_tag(Html). + +title(Port,Link,Title) -> + Html = contents(Port,Link), + Title = title(Html). + +wait(0,_Port,Link) -> + ?t:fail({wait,Link,timeout}); +wait(Time,Port,Link) -> + Html = contents(Port,Link), + case title(Html) of + "Please wait..." -> + timer:sleep(1000), + wait(Time-1,Port,Link); + _Title -> + Html + end. + +title([$<,$T,$I,$T,$L,$E,$>|Html]) -> + title_end(Html); +title([_|Html]) -> + title(Html); +title([]) -> + []. + +title_end([$<,$/,$T,$I,$T,$L,$E,$>|_]) -> + []; +title_end([X|Html]) -> + [X|title_end(Html)]. + + +%%%----------------------------------------------------------------- +%%% General check of what is displayed for a dump +browse_file(Port,File) -> + io:format("Browsing file: ~s~n",[File]), + + %% The page where a filename can be entered + title(Port,"read_file_frame","Read File"), + + %% Load a file + Url = "http://localhost:"++Port++"/cdv_erl/crashdump_viewer/read_file", + Html = request_sync(post,{Url,[],[],"path="++File}), + "Please wait..." = title(Html), + "Crashdump Viewer Start Page" = title(wait(10,Port,"start_page")), + + %% The frame with the initial information for a dump + title(Port,"initial_info_frame","General Information"), + + %% Topmost frame of the page + FilenameFrame = contents(Port,"filename_frame"), + Match = "FilenameCrashdump currently viewed:" ++ File, + true = lists:prefix(Match,strip(FilenameFrame)), + + %% Toggle a menu item and check that it explodes/collapses + title(Port,"menu_frame","Menu"), + exploded = toggle_menu(Port), + collapsed = toggle_menu(Port), + + %% Open each page in menu and check that correct title is shown + title(Port,"general_info","General Information"), + title(Port,"processes","Process Information"), + title(Port,"sort_procs?sort=state","Process Information"), + title(Port,"sort_procs?sort=state","Process Information"), + title(Port,"sort_procs?sort=pid","Process Information"), + title(Port,"sort_procs?sort=pid","Process Information"), + title(Port,"sort_procs?sort=msg_q_len","Process Information"), + title(Port,"sort_procs?sort=msg_q_len","Process Information"), + title(Port,"sort_procs?sort=reds","Process Information"), + title(Port,"sort_procs?sort=reds","Process Information"), + title(Port,"sort_procs?sort=mem","Process Information"), + title(Port,"sort_procs?sort=mem","Process Information"), + title(Port,"sort_procs?sort=name","Process Information"), + title(Port,"sort_procs?sort=name","Process Information"), + title(Port,"sort_procs?sort=init_func","Process Information"), + title(Port,"sort_procs?sort=init_func","Process Information"), + title(Port,"ports","Port Information"), + title(Port,"ets_tables","ETS Table Information"), + title(Port,"timers","Timer Information"), + title(Port,"fun_table","Fun Information"), + title(Port,"atoms","Atoms"), + title(Port,"dist_info","Distribution Information"), + title(Port,"loaded_modules","Loaded Modules Information"), + title(Port,"hash_tables","Hash Table Information"), + title(Port,"index_tables","Index Table Information"), + title(Port,"memory","Memory Information"), + title(Port,"allocated_areas","Information about allocated areas"), + title(Port,"allocator_info","Allocator Information"), + + case is_truncated(File) of + true -> + ok; + _ -> + proc_details(Port), + port_details(Port), + title(Port,"loaded_mod_details?mod=kernel","kernel") + end, + + ok. + + +special(Port,File) -> + case filename:extension(File) of + ".full_dist" -> + contents(Port,"processes"), + AllProcs = contents(Port,"sort_procs?sort=name"), + + %% I registered a process as aaaaaaaa in the full_dist dumps + %% to make sure it will be the first in the list when sorted + %% on names. There are some special data here, s� I'll thoroughly + %% read the process details for this process. Other processes + %% are just briefly traversed. + {Pid,Rest1} = get_first_process(AllProcs), + + ProcDetails = contents(Port,"proc_details?pid=" ++ Pid), + ProcTitle = "Process " ++ Pid, + ProcTitle = title(ProcDetails), + title(Port,"ets_tables?pid="++Pid,"ETS Tables for Process "++Pid), + title(Port,"timers?pid="++Pid,"Timers for Process "++Pid), + + case filename:basename(File) of + "r10b_dump.full_dist" -> + [MsgQueueLink,DictLink,StackDumpLink] = + expand_memory_links(ProcDetails), + MsgQueue = contents(Port,MsgQueueLink), + "MsgQueue" = title(MsgQueue), + title(Port,DictLink,"Dictionary"), + title(Port,StackDumpLink,"StackDump"), + + ExpandBinaryLink = expand_binary_link(MsgQueue), + title(Port,ExpandBinaryLink,"Expanded binary"), + lookat_all_pids(Port,Rest1); + _ -> + ok + end; + ".250atoms" -> + Html1 = contents(Port,"atoms"), + NextLink1 = next_link(Html1), + "Atoms" = title(Html1), + Html2 = contents(Port,NextLink1), + NextLink2 = next_link(Html2), + "Atoms" = title(Html2), + Html3 = contents(Port,NextLink2), + "" = next_link(Html3), + "Atoms" = title(Html3); + _ -> + ok + end, + case filename:basename(File) of + "r10b_dump." ++ _ -> + lookat_all_pids(Port,contents(Port,"processes")); + "r11b_dump." ++ _ -> + lookat_all_pids(Port,contents(Port,"processes")); + _ -> + ok + end, + ok. + + +lookat_all_pids(Port,Pids) -> + case get_first_process(Pids) of + {Pid,Rest} -> + ProcDetails = contents(Port,"proc_details?pid=" ++ Pid), + ProcTitle = "Process " ++ Pid, + ProcTitle = title(ProcDetails), + title(Port,"ets_tables?pid="++Pid,"ETS Tables for Process "++Pid), + title(Port,"timers?pid="++Pid,"Timers for Process "++Pid), + + MemoryLinks = expand_memory_links(ProcDetails), + lists:foreach( + fun(Link) -> + Cont = contents(Port,Link), + true = lists:member(title(Cont), + ["MsgQueue", + "Dictionary", + "StackDump"]) + end, + MemoryLinks), + lookat_all_pids(Port,Rest); + false -> + ok + end. + + +get_first_process([]) -> + false; +get_first_process(Html) -> + case Html of + "<TD><A HREF=\"./proc_details?pid=" ++ Rest -> + {string:sub_word(Rest,1,$"),Rest}; + [_H|T] -> + get_first_process(T) + end. + +expand_memory_links(Html) -> + case Html of + "<B>MsgQueue</B></TD><TD COLSPAN=3><A HREF=\"./" ++ Rest -> + [string:sub_word(Rest,1,$")|expand_memory_links(Rest)]; + "<B>Dictionary</B></TD><TD COLSPAN=3><A HREF=\"./" ++ Rest -> + [string:sub_word(Rest,1,$")|expand_memory_links(Rest)]; + "<B>StackDump</B></TD><TD COLSPAN=3><A HREF=\"./" ++ Rest -> + [string:sub_word(Rest,1,$")]; + [_H|T] -> + expand_memory_links(T); + [] -> + [] + end. + +expand_binary_link(Html) -> + case Html of + "<A HREF=\"./expand_binary?pos=" ++ Rest -> + "expand_binary?pos=" ++ string:sub_word(Rest,1,$"); + [_H|T] -> + expand_binary_link(T) + end. + + +next_link(Html) -> + case Html of + "<A HREF=\"./next?pos=" ++ Rest -> + "next?pos=" ++ string:sub_word(Rest,1,$"); + [_H|T] -> + next_link(T); + [] -> + [] + end. + + + +toggle_menu(Port) -> + Html = contents(Port,"toggle?index=10"), + check_toggle(Html). + +check_toggle(Html) -> + case Html of + "<A HREF=\"./toggle?index=10\"><IMG SRC=\"/crashdump_viewer/collapsd.gif\"" ++ _ -> + collapsed; + "<A HREF=\"./toggle?index=10\"><IMG SRC=\"/crashdump_viewer/exploded.gif\"" ++ _ -> + exploded; + [_H|T] -> + check_toggle(T) + end. + + +proc_details(Port) -> + ProcDetails = contents(Port,"proc_details?pid=<0.0.0>"), + "Process <0.0.0>" = title(ProcDetails), + + ExpandLink = expand_link(ProcDetails), + title(Port,ExpandLink,"StackDump"), + + Unknown = contents(Port,"proc_details?pid=<0.9999.0>"), + "Could not find process: <0.9999.0>" = title(Unknown). + +expand_link(Html) -> + case Html of + "<B>StackDump</B></TD><TD COLSPAN=3><A HREF=\"./" ++ Rest -> + string:sub_word(Rest,1,$"); + [_H|T] -> + expand_link(T) + end. + + +port_details(Port) -> + Port1 = contents(Port,"ports?port=Port<0.1>"), + "#Port<0.1>" = title(Port1), + + Port0 = contents(Port,"ports?port=Port<0.0>"), + "Could not find port: #Port<0.0>" = title(Port0). + +is_truncated(File) -> + case filename:extension(filename:rootname(File)) of + ".trunc" -> true; + _ -> false + end. + + +%%%----------------------------------------------------------------- +%%% +create_dumps(DataDir,Rels) -> + create_dumps(DataDir,Rels,[]). +create_dumps(DataDir,[Rel|Rels],Acc) -> + Fun = fun() -> do_create_dumps(DataDir,Rel) end, + Pa = filename:dirname(code:which(?MODULE)), + {SlAllocDumps,Dumps,DosDump} = + ?t:run_on_shielded_node(Fun, compat_rel(Rel) ++ "-pa " ++ Pa), + create_dumps(DataDir,Rels,SlAllocDumps ++ Dumps ++ Acc ++ DosDump); +create_dumps(_DataDir,[],Acc) -> + Acc. + +do_create_dumps(DataDir,Rel) -> + SlAllocDumps = + case lists:member(Rel,?sl_alloc_vsns) of + true -> + [dump_with_args(DataDir,Rel,"no_sl_alloc","+Se false"), + dump_with_args(DataDir,Rel,"sl_alloc_1","+Se true +Sr 1"), + dump_with_args(DataDir,Rel,"sl_alloc_2","+Se true +Sr 2")]; + false -> + [] + end, + CD1 = full_dist_dump(DataDir,Rel), + CD2 = dump_with_args(DataDir,Rel,"port_is_unix_fd","-oldshell"), + DosDump = + case os:type() of + {unix,sunos} -> dos_dump(DataDir,Rel,CD1); + _ -> [] + end, + case Rel of + current -> + CD3 = dump_with_args(DataDir,Rel,"instr","+Mim true"), + {SlAllocDumps, [CD1,CD2,CD3], DosDump}; + _ -> + {SlAllocDumps, [CD1,CD2], DosDump} + end. + + +%% Create a dump which has two visible nodes, one hidden and one +%% not connected node, and with monitors and links between nodes. +full_dist_dump(DataDir,Rel) -> + Opt = rel_opt(Rel), + Pz = "-pz " ++ filename:dirname(code:which(?MODULE)), + PzOpt = [{args,Pz}], + {ok,N1} = ?t:start_node(n1,peer,Opt ++ PzOpt), + {ok,N2} = ?t:start_node(n2,peer,Opt ++ PzOpt), + {ok,N3} = ?t:start_node(n3,peer,Opt ++ PzOpt), + {ok,N4} = ?t:start_node(n4,peer,Opt ++ [{args,"-hidden " ++ Pz}]), + Creator = self(), + + HelperMod = crashdump_helper, + + P1 = rpc:call(N1,HelperMod,n1_proc,[N2,Creator]), + P2 = rpc:call(N2,HelperMod,remote_proc,[P1,Creator]), + P3 = rpc:call(N3,HelperMod,remote_proc,[P1,Creator]), + P4 = rpc:call(N4,HelperMod,remote_proc,[P1,Creator]), + + get_response(P2), + get_response(P3), + get_response(P4), + get_response(P1), + + L = lists:seq(0,255), + BigMsg = {message,list_to_binary(L),L}, + Port = hd(erlang:ports()), + {aaaaaaaa,N1} ! {short,message,1,2.5,"hello world",Port,{}}, + {aaaaaaaa,N1} ! BigMsg, + + ?t:stop_node(N3), + DumpName = "full_dist", + CD = dump(N1,DataDir,Rel,DumpName), + + ?t:stop_node(N2), + ?t:stop_node(N4), + CD. + +get_response(P) -> + receive {P,done} -> ok + after 3000 -> ?t:fail({get_response_timeout,P,node(P)}) + end. + + +dump_with_args(DataDir,Rel,DumpName,Args) -> + RelOpt = rel_opt(Rel), + Opt = RelOpt ++ [{args,Args}], + {ok,N1} = ?t:start_node(n1,peer,Opt), + CD = dump(N1,DataDir,Rel,DumpName), + ?t:stop_node(n1), + CD. + + + +dump(Node,DataDir,Rel,DumpName) -> + rpc:call(Node,erlang,halt,[DumpName]), + Crashdump0 = filename:join(filename:dirname(code:which(?t)), + "erl_crash_dump.n1"), + Crashdump1 = filename:join(DataDir, dump_prefix(Rel)++DumpName), + ok = rename(Crashdump0,Crashdump1), + Crashdump1. + +rename(From,To) -> + ok = check_complete(From), + case file:rename(From,To) of + {error,exdev} -> + {ok,_} = file:copy(From,To), + ok = file:delete(From); + ok -> + ok + end. + +check_complete(File) -> + check_complete1(File,5). + +check_complete1(_File,0) -> + {error,enoent}; +check_complete1(File,N) -> + case file:read_file_info(File) of + {error,enoent} -> + timer:sleep(500), + check_complete1(File,N-1); + {ok,#file_info{size=Size}} -> + check_complete2(File,Size) + end. + +check_complete2(File,Size) -> + timer:sleep(500), + case file:read_file_info(File) of + {ok,#file_info{size=Size}} -> + ok; + {ok,#file_info{size=OtherSize}} -> + check_complete2(File,OtherSize) + end. + +dos_dump(DataDir,Rel,Dump) -> + DosDumpName = filename:join(DataDir,dump_prefix(Rel)++"dos"), + Cmd = "unix2dos " ++ Dump ++ " > " ++ DosDumpName, + Port = open_port({spawn,Cmd},[exit_status]), + receive + {Port,{exit_status,0}} -> + [DosDumpName]; + {Port,{exit_status,_Error}} -> + ?t:comment("Couldn't run \'unix2dos\'"), + [] + end. + +rel_opt(Rel) -> + case Rel of + r9b -> [{erl,[{release,"r9b_patched"}]}]; + r9c -> [{erl,[{release,"r9c_patched"}]}]; + r10b -> [{erl,[{release,"r10b_patched"}]}]; + r11b -> [{erl,[{release,"r11b_patched"}]}]; + r12b -> [{erl,[{release,"r12b_patched"}]}]; + r13b -> [{erl,[{release,"r13b_patched"}]}]; + current -> [] + end. + +dump_prefix(Rel) -> + case Rel of + r9b -> "r9b_dump."; + r9c -> "r9c_dump."; + r10b -> "r10b_dump."; + r11b -> "r11b_dump."; + r12b -> "r12b_dump."; + r13b -> "r13b_dump."; + current -> "r14b_dump." + end. + +compat_rel(Rel) -> + case Rel of + r9b -> "+R9 "; + r9c -> "+R9 "; + r10b -> "+R10 "; + r11b -> "+R11 "; + r12b -> "+R12 "; + r13b -> "+R13 "; + current -> "" + end. diff --git a/lib/observer/test/crashdump_viewer_SUITE_data/old_format.dump b/lib/observer/test/crashdump_viewer_SUITE_data/old_format.dump new file mode 100644 index 0000000000..2c8944fa9d --- /dev/null +++ b/lib/observer/test/crashdump_viewer_SUITE_data/old_format.dump @@ -0,0 +1,3991 @@ +<Erlang crash dump> +Mon Feb 17 10:48:12 2003 + +Slogan: saf + + +Erlang (BEAM) emulator version 5.0.2.23 +Compiled on Wed Dec 4 11:11:21 2002 + +Process Information +-------------------------------------------------- +<0.0.0> Waiting. Registered as: init +Spawned as: otp_ring0:start/2 +Message buffer data: 4 words +Link list: [<0.5.0>,<0.4.0>,<0.2.0>] +Reductions 3125 stack+heap 610 old_heap_sz=233 +Heap unused=417 OldHeap unused=233 +Stack dump: +program counter = 0x31a2cc (init:loop/1 + 20) +cp = 0xfcec8 (<terminate process normally>) +arity = 0 + +3169f8 Return addr 0xFCEC8 (<terminate process normally>) +y(0) {state,[{'-root',[<<53 bytes>>]},{'-progname',[<<3 bytes>>]},{'-home',[<<10 bytes>>]}],[],[],[{application_controller,<0.5.0>},{error_logger,<0.4.0>},{erl_prim_loader,<0.2.0>}],<0.1.0>,{started,started},{"OTP APN 181 01","R7B01"},[]} +-------------------------------------------------- +<0.2.0> Waiting. Registered as: erl_prim_loader +Spawned as: erl_prim_loader:start_it/4 +Message buffer data: 0 words +Link list: [<0.0.0>,#Port<0.2>] +Reductions 13587 stack+heap 610 old_heap_sz=610 +Heap unused=358 OldHeap unused=610 +Stack dump: +program counter = 0x32963c (erl_prim_loader:loop/3 + 52) +cp = 0xfcec8 (<terminate process normally>) +arity = 0 + +4289dc Return addr 0xFCEC8 (<terminate process normally>) +y(0) ["/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/kernel-2.6.3.15/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/stdlib-1.9.4.4/ebin"] +y(1) <0.1.0> +y(2) {state,[],none,get_from_port_efile,stop_port,exit_port,#Port<0.2>,infinity,dummy_in_handler} +y(3) infinity +-------------------------------------------------- +<0.4.0> Waiting. Registered as: error_logger +Spawned as: proc_lib:init_p/5 +Message buffer data: 0 words +Link list: [<0.19.0>,<0.0.0>] +Dictionary: [{'$initial_call',{gen,init_it,[gen_event,<0.1.0>,<0.1.0>,{local,error_logger},[],[],[]]}},{'$ancestors',[<0.1.0>]}] +Reductions 1462 stack+heap 1597 old_heap_sz=0 +Heap unused=1180 OldHeap unused=0 +Stack dump: +program counter = 0x33f0c0 (gen_event:loop/4 + 40) +cp = 0x33480c (proc_lib:init_p/5 + 164) +arity = 0 + +334244 Return addr 0x33480C (proc_lib:init_p/5 + 164) +y(0) [] +y(1) [{handler,error_logger,false,[],false},{handler,error_logger_tty_h,false,{<0.19.0>,error_logger},false}] +y(2) error_logger +y(3) <0.1.0> + +334258 Return addr 0xFCEC8 (<terminate process normally>) +y(0) Catch 0x33480C (proc_lib:init_p/5 + 164) +y(1) gen +y(2) init_it +y(3) [gen_event,<0.1.0>,<0.1.0>,{local,error_logger},[],[],[]] +-------------------------------------------------- +<0.5.0> Waiting. Registered as: application_controller +Spawned as: proc_lib:init_p/5 +Message buffer data: 4 words +Link list: [<0.7.0>,<0.0.0>] +Dictionary: [{'$initial_call',{gen,init_it,[gen_server,<0.1.0>,<0.1.0>,{local,application_controller},application_controller,{application,kernel,[{description,"ERTS CXC 138 10"},{vsn,"2.6.3.15"},{id,[]},{modules,[application,application_controller,application_master,application_starter,auth,code,code_aux,code_server,code_server_int,dist_util,erl_boot_server,erl_distribution,erl_open_port,erl_prim_loader,erl_reply,erlang,error_handler,error_logger,file,global,global_group,global_search,group,heart,inet6_tcp,inet6_tcp_dist,inet6_udp,inet_config,inet_hosts,inet_gethost_native,inet_tcp_dist,otp_pre_init,init,kernel,kernel_config,net,net_adm,net_kernel,os,ram_file,rpc,user,user_drv,user_sup,disk_log,disk_log_1,disk_log_server,disk_log_sup,dist_ac,erl_atom_cache,erl_ddll,erl_epmd,erl_external,erts_debug,fixtable_server,gen_tcp,gen_udp,prim_inet,inet,inet_db,inet_dns,inet_parse,inet_res,inet_tcp,inet_udp,pg2,seq_trace,socks5,socks5_auth,socks5_tcp,socks5_udp,wrap_log_reader,otp_ring0]},{registered,[application_controller,erl_reply,auth,boot_server,code_server,disk_log_server,disk_log_sup,erl_prim_loader,error_logger,file_server,fixtable_server,global_group,global_name_server,heart,init,kernel_config,kernel_sup,net_kernel,net_sup,rex,user,os_server,ddll_server,erl_epmd,inet_db,pg2]},{applications,[]},{included_applications,[]},{env,[{error_logger,tty}]},{start_phases,undefined},{maxT,infinity},{maxP,infinity},{mod,{kernel,[]}}]},[]]}},{'$ancestors',[<0.1.0>]}] +Reductions 527 stack+heap 1597 old_heap_sz=0 +Heap unused=833 OldHeap unused=0 +Stack dump: +program counter = 0x34ff24 (gen_server:loop/6 + 52) +cp = 0x33480c (proc_lib:init_p/5 + 164) +arity = 0 + +3ed70c Return addr 0x33480C (proc_lib:init_p/5 + 164) +y(0) [] +y(1) infinity +y(2) application_controller +y(3) {state,[],[],[],[{stdlib,undefined},{kernel,<0.7.0>}],[],[{stdlib,permanent},{kernel,permanent}],[],[]} +y(4) application_controller +y(5) <0.1.0> + +3ed728 Return addr 0xFCEC8 (<terminate process normally>) +y(0) Catch 0x33480C (proc_lib:init_p/5 + 164) +y(1) gen +y(2) init_it +y(3) [gen_server,<0.1.0>,<0.1.0>,{local,application_controller},application_controller,{application,kernel,[{description,"ERTS CXC 138 10"},{vsn,"2.6.3.15"},{id,[]},{modules,[application,application_controller,application_master,application_starter,auth,code,code_aux,code_server,code_server_int,dist_util,erl_boot_server,erl_distribution,erl_open_port,erl_prim_loader,erl_reply,erlang,error_handler,error_logger,file,global,global_group,global_search,group,heart,inet6_tcp,inet6_tcp_dist,inet6_udp,inet_config,inet_hosts,inet_gethost_native,inet_tcp_dist,otp_pre_init,init,kernel,kernel_config,net,net_adm,net_kernel,os,ram_file,rpc,user,user_drv,user_sup,disk_log,disk_log_1,disk_log_server,disk_log_sup,dist_ac,erl_atom_cache,erl_ddll,erl_epmd,erl_external,erts_debug,fixtable_server,gen_tcp,gen_udp,prim_inet,inet,inet_db,inet_dns,inet_parse,inet_res,inet_tcp,inet_udp,pg2,seq_trace,socks5,socks5_auth,socks5_tcp,socks5_udp,wrap_log_reader,otp_ring0]},{registered,[application_controller,erl_reply,auth,boot_server,code_server,disk_log_server,disk_log_sup,erl_prim_loader,error_logger,file_server,fixtable_server,global_group,global_name_server,heart,init,kernel_config,kernel_sup,net_kernel,net_sup,rex,user,os_server,ddll_server,erl_epmd,inet_db,pg2]},{applications,[]},{included_applications,[]},{env,[{error_logger,tty}]},{start_phases,undefined},{maxT,infinity},{maxP,infinity},{mod,{kernel,[]}}]},[]] +-------------------------------------------------- +<0.7.0> Waiting. +Spawned as: proc_lib:init_p/5 +Message buffer data: 0 words +Link list: [<0.8.0>,<0.5.0>] +Dictionary: [{'$initial_call',{application_master,init,[<0.5.0>,<0.6.0>,{appl_data,kernel,[application_controller,erl_reply,auth,boot_server,code_server,disk_log_server,disk_log_sup,erl_prim_loader,error_logger,file_server,fixtable_server,global_group,global_name_server,heart,init,kernel_config,kernel_sup,net_kernel,net_sup,rex,user,os_server,ddll_server,erl_epmd,inet_db,pg2],undefined,{kernel,[]},[application,application_controller,application_master,application_starter,auth,code,code_aux,code_server,code_server_int,dist_util,erl_boot_server,erl_distribution,erl_open_port,erl_prim_loader,erl_reply,erlang,error_handler,error_logger,file,global,global_group,global_search,group,heart,inet6_tcp,inet6_tcp_dist,inet6_udp,inet_config,inet_hosts,inet_gethost_native,inet_tcp_dist,otp_pre_init,init,kernel,kernel_config,net,net_adm,net_kernel,os,ram_file,rpc,user,user_drv,user_sup,disk_log,disk_log_1,disk_log_server,disk_log_sup,dist_ac,erl_atom_cache,erl_ddll,erl_epmd,erl_external,erts_debug,fixtable_server,gen_tcp,gen_udp,prim_inet,inet,inet_db,inet_dns,inet_parse,inet_res,inet_tcp,inet_udp,pg2,seq_trace,socks5,socks5_auth,socks5_tcp,socks5_udp,wrap_log_reader,otp_ring0],[],infinity,infinity},normal]}},{'$ancestors',[<0.6.0>]}] +Reductions 45 stack+heap 377 old_heap_sz=377 +Heap unused=306 OldHeap unused=377 +Stack dump: +program counter = 0x339ee0 (application_master:main_loop/2 + 28) +cp = 0x33480c (proc_lib:init_p/5 + 164) +arity = 0 + +347174 Return addr 0x33480C (proc_lib:init_p/5 + 164) +y(0) {state,<0.8.0>,{appl_data,kernel,[application_controller,erl_reply,auth,boot_server,code_server,disk_log_server,disk_log_sup,erl_prim_loader,error_logger,file_server,fixtable_server,global_group,global_name_server,heart,init,kernel_config,kernel_sup,net_kernel,net_sup,rex,user,os_server,ddll_server,erl_epmd,inet_db,pg2],undefined,{kernel,[]},[application,application_controller,application_master,application_starter,auth,code,code_aux,code_server,code_server_int,dist_util,erl_boot_server,erl_distribution,erl_open_port,erl_prim_loader,erl_reply,erlang,error_handler,error_logger,file,global,global_group,global_search,group,heart,inet6_tcp,inet6_tcp_dist,inet6_udp,inet_config,inet_hosts,inet_gethost_native,inet_tcp_dist,otp_pre_init,init,kernel,kernel_config,net,net_adm,net_kernel,os,ram_file,rpc,user,user_drv,user_sup,disk_log,disk_log_1,disk_log_server,disk_log_sup,dist_ac,erl_atom_cache,erl_ddll,erl_epmd,erl_external,erts_debug,fixtable_server,gen_tcp,gen_udp,prim_inet,inet,inet_db,inet_dns,inet_parse,inet_res,inet_tcp,inet_udp,pg2,seq_trace,socks5,socks5_auth,socks5_tcp,socks5_udp,wrap_log_reader,otp_ring0],[],infinity,infinity},[],0,<0.0.0>} +y(1) <0.5.0> + +347180 Return addr 0xFCEC8 (<terminate process normally>) +y(0) Catch 0x33480C (proc_lib:init_p/5 + 164) +y(1) application_master +y(2) init +y(3) [<0.5.0>,<0.6.0>,{appl_data,kernel,[application_controller,erl_reply,auth,boot_server,code_server,disk_log_server,disk_log_sup,erl_prim_loader,error_logger,file_server,fixtable_server,global_group,global_name_server,heart,init,kernel_config,kernel_sup,net_kernel,net_sup,rex,user,os_server,ddll_server,erl_epmd,inet_db,pg2],undefined,{kernel,[]},[application,application_controller,application_master,application_starter,auth,code,code_aux,code_server,code_server_int,dist_util,erl_boot_server,erl_distribution,erl_open_port,erl_prim_loader,erl_reply,erlang,error_handler,error_logger,file,global,global_group,global_search,group,heart,inet6_tcp,inet6_tcp_dist,inet6_udp,inet_config,inet_hosts,inet_gethost_native,inet_tcp_dist,otp_pre_init,init,kernel,kernel_config,net,net_adm,net_kernel,os,ram_file,rpc,user,user_drv,user_sup,disk_log,disk_log_1,disk_log_server,disk_log_sup,dist_ac,erl_atom_cache,erl_ddll,erl_epmd,erl_external,erts_debug,fixtable_server,gen_tcp,gen_udp,prim_inet,inet,inet_db,inet_dns,inet_parse,inet_res,inet_tcp,inet_udp,pg2,seq_trace,socks5,socks5_auth,socks5_tcp,socks5_udp,wrap_log_reader,otp_ring0],[],infinity,infinity},normal] +-------------------------------------------------- +<0.8.0> Waiting. +Spawned as: application_master:start_it/4 +Message buffer data: 0 words +Link list: [<0.9.0>,<0.7.0>] +Reductions 113 stack+heap 233 old_heap_sz=377 +Heap unused=59 OldHeap unused=377 +Stack dump: +program counter = 0x33b324 (application_master:loop_it/4 + 40) +cp = 0xfcec8 (<terminate process normally>) +arity = 0 + +330c30 Return addr 0xFCEC8 (<terminate process normally>) +y(0) {state,tty} +y(1) kernel +y(2) <0.9.0> +y(3) <0.7.0> +-------------------------------------------------- +<0.9.0> Waiting. Registered as: kernel_sup +Spawned as: proc_lib:init_p/5 +Message buffer data: 306 words +Link list: [<0.22.0>,<0.21.0>,<0.17.0>,<0.16.0>,<0.15.0>,<0.14.0>,<0.13.0>,<0.11.0>,<0.10.0>,<0.8.0>] +Dictionary: [{'$initial_call',{gen,init_it,[gen_server,<0.8.0>,<0.8.0>,{local,kernel_sup},supervisor,{{local,kernel_sup},kernel,[]},[]]}},{'$ancestors',[<0.8.0>]}] +Reductions 7060 stack+heap 1597 old_heap_sz=0 +Heap unused=209 OldHeap unused=0 +Stack dump: +program counter = 0x34ff24 (gen_server:loop/6 + 52) +cp = 0x33480c (proc_lib:init_p/5 + 164) +arity = 0 + +3a6384 Return addr 0x33480C (proc_lib:init_p/5 + 164) +y(0) [] +y(1) infinity +y(2) supervisor +y(3) {state,{local,kernel_sup},one_for_all,[{child,<0.22.0>,kernel_safe_sup,{supervisor,start_link,[{local,kernel_safe_sup},kernel,safe]},permanent,infinity,supervisor,[kernel]},{child,<0.21.0>,kernel_config,{kernel_config,start_link,[]},permanent,2000,worker,[kernel_config]},{child,<0.17.0>,user,{user_sup,start,[]},temporary,2000,supervisor,[user_sup]},{child,<0.16.0>,code_server,{code,start_link,[]},permanent,2000,worker,[code]},{child,<0.15.0>,file_server,{file,start_link,[]},permanent,2000,worker,[file]},{child,<0.14.0>,global_group,{global_group,start_link,[]},permanent,2000,worker,[global_group]},{child,undefined,net_sup,{erl_distribution,start_link,[]},permanent,infinity,supervisor,[erl_distribution]},{child,<0.13.0>,inet_db,{inet_db,start_link,[]},permanent,2000,worker,[inet_db]},{child,<0.11.0>,global_name_server,{global,start_link,[]},permanent,2000,worker,[global]},{child,<0.10.0>,rex,{rpc,start_link,[]},permanent,2000,worker,[rpc]}],[],0,1,[],kernel,[]} +y(4) kernel_sup +y(5) <0.8.0> + +3a63a0 Return addr 0xFCEC8 (<terminate process normally>) +y(0) Catch 0x33480C (proc_lib:init_p/5 + 164) +y(1) gen +y(2) init_it +y(3) [gen_server,<0.8.0>,<0.8.0>,{local,kernel_sup},supervisor,{{local,kernel_sup},kernel,[]},[]] +-------------------------------------------------- +<0.10.0> Waiting. Registered as: rex +Spawned as: proc_lib:init_p/5 +Message buffer data: 0 words +Link list: [<0.9.0>] +Dictionary: [{'$initial_call',{gen,init_it,[gen_server,<0.9.0>,<0.9.0>,{local,rex},rpc,[],[]]}},{'$ancestors',[kernel_sup,<0.8.0>]}] +Reductions 31 stack+heap 233 old_heap_sz=0 +Heap unused=147 OldHeap unused=0 +Stack dump: +program counter = 0x34ff24 (gen_server:loop/6 + 52) +cp = 0x33480c (proc_lib:init_p/5 + 164) +arity = 0 + +38e734 Return addr 0x33480C (proc_lib:init_p/5 + 164) +y(0) [] +y(1) infinity +y(2) rpc +y(3) [] +y(4) rex +y(5) <0.9.0> + +38e750 Return addr 0xFCEC8 (<terminate process normally>) +y(0) Catch 0x33480C (proc_lib:init_p/5 + 164) +y(1) gen +y(2) init_it +y(3) [gen_server,<0.9.0>,<0.9.0>,{local,rex},rpc,[],[]] +-------------------------------------------------- +<0.11.0> Waiting. Registered as: global_name_server +Spawned as: proc_lib:init_p/5 +Message buffer data: 0 words +Link list: [<0.12.0>,<0.9.0>] +Dictionary: [{'$initial_call',{gen,init_it,[gen_server,<0.9.0>,<0.9.0>,{local,global_name_server},global,[],[]]}},{'$ancestors',[kernel_sup,<0.8.0>]}] +Reductions 44 stack+heap 233 old_heap_sz=0 +Heap unused=100 OldHeap unused=0 +Stack dump: +program counter = 0x34ff24 (gen_server:loop/6 + 52) +cp = 0x33480c (proc_lib:init_p/5 + 164) +arity = 0 + +39abec Return addr 0x33480C (proc_lib:init_p/5 + 164) +y(0) [] +y(1) infinity +y(2) global +y(3) {state,true,[],[],[],[],'nonode@nohost',<0.12.0>} +y(4) global_name_server +y(5) <0.9.0> + +39ac08 Return addr 0xFCEC8 (<terminate process normally>) +y(0) Catch 0x33480C (proc_lib:init_p/5 + 164) +y(1) gen +y(2) init_it +y(3) [gen_server,<0.9.0>,<0.9.0>,{local,global_name_server},global,[],[]] +-------------------------------------------------- +<0.12.0> Waiting. +Spawned as: global:init_the_locker/1 +Message buffer data: 0 words +Link list: [<0.11.0>] +Reductions 3 stack+heap 233 old_heap_sz=0 +Heap unused=215 OldHeap unused=0 +Stack dump: +program counter = 0x3abf20 (global:loop_the_locker/2 + 112) +cp = 0x3abd50 (global:init_the_locker/1 + 112) +arity = 0 + +31766c Return addr 0x3ABD50 (global:init_the_locker/1 + 112) +y(0) [] +y(1) [] +y(2) [] +y(3) [] +y(4) [] +y(5) [] +y(6) infinity +y(7) {multi,undefined,[]} +y(8) <0.11.0> + +317694 Return addr 0xFCEC8 (<terminate process normally>) +y(0) [] +-------------------------------------------------- +<0.13.0> Waiting. Registered as: inet_db +Spawned as: proc_lib:init_p/5 +Message buffer data: 0 words +Link list: [<0.9.0>] +Dictionary: [{'$initial_call',{gen,init_it,[gen_server,<0.9.0>,<0.9.0>,{local,inet_db},inet_db,[],[]]}},{'$ancestors',[kernel_sup,<0.8.0>]}] +Reductions 420 stack+heap 233 old_heap_sz=0 +Heap unused=119 OldHeap unused=0 +Stack dump: +program counter = 0x34ff24 (gen_server:loop/6 + 52) +cp = 0x33480c (proc_lib:init_p/5 + 164) +arity = 0 + +336e04 Return addr 0x33480C (proc_lib:init_p/5 + 164) +y(0) [] +y(1) infinity +y(2) inet_db +y(3) {state,inet_db,inet_cache,inet_hosts,#Ref<0.0.0.6>} +y(4) inet_db +y(5) <0.9.0> + +336e20 Return addr 0xFCEC8 (<terminate process normally>) +y(0) Catch 0x33480C (proc_lib:init_p/5 + 164) +y(1) gen +y(2) init_it +y(3) [gen_server,<0.9.0>,<0.9.0>,{local,inet_db},inet_db,[],[]] +-------------------------------------------------- +<0.14.0> Waiting. Registered as: global_group +Spawned as: proc_lib:init_p/5 +Message buffer data: 0 words +Link list: [<0.9.0>] +Dictionary: [{'$initial_call',{gen,init_it,[gen_server,<0.9.0>,<0.9.0>,{local,global_group},global_group,[],[]]}},{registered_names,[undefined]},{'$ancestors',[kernel_sup,<0.8.0>]},{send,[undefined]},{whereis_name,[undefined]}] +Reductions 71 stack+heap 233 old_heap_sz=0 +Heap unused=80 OldHeap unused=0 +Stack dump: +program counter = 0x34ff24 (gen_server:loop/6 + 52) +cp = 0x33480c (proc_lib:init_p/5 + 164) +arity = 0 + +3eb47c Return addr 0x33480C (proc_lib:init_p/5 + 164) +y(0) [] +y(1) infinity +y(2) global_group +y(3) {state,no_conf,true,[],[],[],[],[],'nonode@nohost',[],normal,normal} +y(4) global_group +y(5) <0.9.0> + +3eb498 Return addr 0xFCEC8 (<terminate process normally>) +y(0) Catch 0x33480C (proc_lib:init_p/5 + 164) +y(1) gen +y(2) init_it +y(3) [gen_server,<0.9.0>,<0.9.0>,{local,global_group},global_group,[],[]] +-------------------------------------------------- +<0.15.0> Waiting. Registered as: file_server +Spawned as: proc_lib:init_p/5 +Message buffer data: 208 words +Link list: [#Port<0.4>,<0.9.0>] +Dictionary: [{'$initial_call',{gen,init_it,[gen_server,<0.9.0>,<0.9.0>,{local,file_server},file,[],[]]}},{'$ancestors',[kernel_sup,<0.8.0>]}] +Reductions 43458 stack+heap 6765 old_heap_sz=0 +Heap unused=2485 OldHeap unused=0 +Stack dump: +program counter = 0x34ff24 (gen_server:loop/6 + 52) +cp = 0x33480c (proc_lib:init_p/5 + 164) +arity = 0 + +3de984 Return addr 0x33480C (proc_lib:init_p/5 + 164) +y(0) [] +y(1) infinity +y(2) file +y(3) #Port<0.4> +y(4) file_server +y(5) <0.9.0> + +3de9a0 Return addr 0xFCEC8 (<terminate process normally>) +y(0) Catch 0x33480C (proc_lib:init_p/5 + 164) +y(1) gen +y(2) init_it +y(3) [gen_server,<0.9.0>,<0.9.0>,{local,file_server},file,[],[]] +-------------------------------------------------- +<0.16.0> Waiting. Registered as: code_server +Spawned as: proc_lib:init_p/5 +Message buffer data: 508 words +Link list: [<0.9.0>] +Dictionary: [{'$initial_call',{gen,init_it,[gen_server,<0.9.0>,<0.9.0>,{local,code_server},code_server,["/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched",interactive],[]]}},{'$ancestors',[kernel_sup,<0.8.0>]}] +Reductions 71231 stack+heap 17711 old_heap_sz=0 +Heap unused=8909 OldHeap unused=0 +Stack dump: +program counter = 0x34ff24 (gen_server:loop/6 + 52) +cp = 0x33480c (proc_lib:init_p/5 + 164) +arity = 0 + +45128c Return addr 0x33480C (proc_lib:init_p/5 + 164) +y(0) [] +y(1) infinity +y(2) code_server +y(3) {state,"/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched",[".","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/kernel-2.6.3.15/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/stdlib-1.9.4.4/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/tv-2.0.3/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/tools-1.6.3.1/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/toolbar-1.0.4/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/ssl-2.3.2/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/snmp-3.3.7/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/sasl-1.9.2/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/runtime_tools-1.1.6/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/pman-2.4/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/parsetools-1.1/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/os_mon-1.4.2/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/orber-3.4.1/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/odbc-0.8.2/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/observer-0.9.1/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/mnesia_session-1.1.4/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/mnesia-3.10.7/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/mnemosyne-1.2.5/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/mesh-1.1.0/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/megaco-1.0.4/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/jinterface-1.2.1","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/inets-2.6.5/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/ic-4.2/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/gs-1.3.8/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/eva-2.0.2.1/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/etk-0.9.3/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/erl_interface-3.2.9","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/debugger-1.5.3/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/crypto-1.1.2/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/cosTransactions-1.2/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/cosTime-1.1/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/cosNotification-1.1/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/cosEvent-2.1/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/compiler-3.0.1.2/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/comet-1.1","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/asn1-1.3.1.4/ebin","/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/lib/appmon-2.0.1/ebin","/home/siri/erlang","/ldisk/siri/tools/distel-3.1/ebin"],9,10,[],interactive} +y(4) code_server +y(5) <0.9.0> + +4512a8 Return addr 0xFCEC8 (<terminate process normally>) +y(0) Catch 0x33480C (proc_lib:init_p/5 + 164) +y(1) gen +y(2) init_it +y(3) [gen_server,<0.9.0>,<0.9.0>,{local,code_server},code_server,["/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched",interactive],[]] +-------------------------------------------------- +<0.17.0> Waiting. +Spawned as: proc_lib:init_p/5 +Message buffer data: 156 words +Link list: [<0.19.0>,<0.9.0>] +Dictionary: [{'$initial_call',{gen,init_it,[gen_server,<0.9.0>,<0.9.0>,supervisor_bridge,[user_sup,[],self],[]]}},{'$ancestors',[kernel_sup,<0.8.0>]}] +Reductions 80 stack+heap 233 old_heap_sz=0 +Heap unused=44 OldHeap unused=0 +Stack dump: +program counter = 0x34ff24 (gen_server:loop/6 + 52) +cp = 0x33480c (proc_lib:init_p/5 + 164) +arity = 0 + +3cf014 Return addr 0x33480C (proc_lib:init_p/5 + 164) +y(0) [] +y(1) infinity +y(2) supervisor_bridge +y(3) {state,user_sup,<0.19.0>,<0.19.0>,{<0.17.0>,user_sup}} +y(4) <0.17.0> +y(5) <0.9.0> + +3cf030 Return addr 0xFCEC8 (<terminate process normally>) +y(0) Catch 0x33480C (proc_lib:init_p/5 + 164) +y(1) gen +y(2) init_it +y(3) [gen_server,<0.9.0>,<0.9.0>,supervisor_bridge,[user_sup,[],self],[]] +-------------------------------------------------- +<0.18.0> Waiting. +Spawned as: user_drv:server/2 +Message buffer data: 0 words +Link list: [<0.20.0>,<0.19.0>,#Port<0.5>] +Dictionary: [{eof,false}] +Reductions 473 stack+heap 377 old_heap_sz=377 +Heap unused=178 OldHeap unused=377 +Stack dump: +program counter = 0x39ec48 (user_drv:server_loop/5 + 44) +cp = 0xfcec8 (<terminate process normally>) +arity = 0 + +32db5c Return addr 0xFCEC8 (<terminate process normally>) +y(0) {3,2,<0.20.0>,[{1,<0.19.0>,{}},{2,<0.20.0>,{shell,start,[]}}]} +y(1) <0.19.0> +y(2) <0.20.0> +y(3) #Port<0.5> +y(4) #Port<0.5> +-------------------------------------------------- +<0.19.0> Waiting. Registered as: user +Spawned as: group:server/2 +Message buffer data: 0 words +Link list: [<0.4.0>,<0.17.0>,<0.18.0>] +Dictionary: [{line_buffer,[]},{kill_buffer,[]}] +Reductions 968 stack+heap 987 old_heap_sz=610 +Heap unused=497 OldHeap unused=610 +Stack dump: +program counter = 0x368db0 (group:server_loop/3 + 32) +cp = 0xfcec8 (<terminate process normally>) +arity = 0 + +420ecc Return addr 0xFCEC8 (<terminate process normally>) +y(0) [] +y(1) undefined +y(2) <0.18.0> +-------------------------------------------------- +<0.20.0> Waiting. +Spawned as: group:server/2 +Message buffer data: 0 words +Link list: [<0.23.0>,<0.18.0>] +Dictionary: [{line_buffer,["halt(\"saf\").\n","\n"]},{shell,<0.23.0>},{kill_buffer,[]}] +Reductions 1643 stack+heap 377 old_heap_sz=233 +Heap unused=268 OldHeap unused=233 +Stack dump: +program counter = 0x368db0 (group:server_loop/3 + 32) +cp = 0xfcec8 (<terminate process normally>) +arity = 0 + +3edd1c Return addr 0xFCEC8 (<terminate process normally>) +y(0) [] +y(1) <0.23.0> +y(2) <0.18.0> +-------------------------------------------------- +<0.21.0> Waiting. +Spawned as: proc_lib:init_p/5 +Message buffer data: 0 words +Link list: [<0.9.0>] +Dictionary: [{'$initial_call',{gen,init_it,[gen_server,<0.9.0>,<0.9.0>,kernel_config,[],[]]}},{'$ancestors',[kernel_sup,<0.8.0>]}] +Reductions 39 stack+heap 233 old_heap_sz=0 +Heap unused=78 OldHeap unused=0 +Stack dump: +program counter = 0x34ff24 (gen_server:loop/6 + 52) +cp = 0x33480c (proc_lib:init_p/5 + 164) +arity = 0 + +3683a4 Return addr 0x33480C (proc_lib:init_p/5 + 164) +y(0) [] +y(1) infinity +y(2) kernel_config +y(3) [] +y(4) <0.21.0> +y(5) <0.9.0> + +3683c0 Return addr 0xFCEC8 (<terminate process normally>) +y(0) Catch 0x33480C (proc_lib:init_p/5 + 164) +y(1) gen +y(2) init_it +y(3) [gen_server,<0.9.0>,<0.9.0>,kernel_config,[],[]] +-------------------------------------------------- +<0.22.0> Waiting. Registered as: kernel_safe_sup +Spawned as: proc_lib:init_p/5 +Message buffer data: 0 words +Link list: [<0.9.0>] +Dictionary: [{'$initial_call',{gen,init_it,[gen_server,<0.9.0>,<0.9.0>,{local,kernel_safe_sup},supervisor,{{local,kernel_safe_sup},kernel,safe},[]]}},{'$ancestors',[kernel_sup,<0.8.0>]}] +Reductions 60 stack+heap 233 old_heap_sz=0 +Heap unused=82 OldHeap unused=0 +Stack dump: +program counter = 0x34ff24 (gen_server:loop/6 + 52) +cp = 0x33480c (proc_lib:init_p/5 + 164) +arity = 0 + +32fae4 Return addr 0x33480C (proc_lib:init_p/5 + 164) +y(0) [] +y(1) infinity +y(2) supervisor +y(3) {state,{local,kernel_safe_sup},one_for_one,[],[],4,3600,[],kernel,safe} +y(4) kernel_safe_sup +y(5) <0.9.0> + +32fb00 Return addr 0xFCEC8 (<terminate process normally>) +y(0) Catch 0x33480C (proc_lib:init_p/5 + 164) +y(1) gen +y(2) init_it +y(3) [gen_server,<0.9.0>,<0.9.0>,{local,kernel_safe_sup},supervisor,{{local,kernel_safe_sup},kernel,safe},[]] +-------------------------------------------------- +<0.23.0> Waiting. +Spawned as: shell:server/1 +Message buffer data: 31 words +Link list: [<0.27.0>,<0.20.0>] +Dictionary: [] +Reductions 111 stack+heap 233 old_heap_sz=0 +Heap unused=173 OldHeap unused=0 +Stack dump: +program counter = 0x41ae64 (shell:shell_rep/3 + 36) +cp = 0x419728 (shell:server_loop/4 + 1016) +arity = 0 + +39e014 Return addr 0x419728 (shell:server_loop/4 + 1016) +y(0) [] +y(1) [] +y(2) [] +y(3) <0.27.0> + +39e028 Return addr 0xFCEC8 (<terminate process normally>) +y(0) [] +y(1) 1 +y(2) [{call,3,{atom,3,halt},[{string,3,"saf"}]}] +y(3) [] +y(4) [] +y(5) [] +-------------------------------------------------- +<0.27.0> Running. +Spawned as: shell:evaluator/3 +Last scheduled in for: erlang:halt/1 +Message buffer data: 0 words +Link list: [<0.23.0>] +Reductions 24 stack+heap 233 old_heap_sz=0 +Heap unused=120 OldHeap unused=0 +Stack dump: +program counter = 0x119c54 (unknown function) +cp = 0x422188 (erl_eval:expr/3 + 1112) + +399a48 Return addr 0x421C74 (erl_eval:exprs/4 + 52) +y(0) [] +y(1) [] +y(2) [] +y(3) [] + +399a5c Return addr 0x41B3D0 (shell:eval_loop/2 + 240) +y(0) [] +y(1) {eval,{shell,local_func},[<0.23.0>]} + +399a68 Return addr 0xFCEC8 (<terminate process normally>) +y(0) [] +y(1) [] +y(2) [] +y(3) <0.23.0> +-------------------------------------------------- + +Zombie Process Information +Processes kept: 0 +-------------------------------------------------- + +Port Information +-------------------------------------------------- +<1> +Connected: #Port<0.0> +Port controls linked-in driver: async +-------------------------------------------------- +<2> +Connected: <0.2.0> +Links: <0.2.0> +Port controls linked-in driver: efile +-------------------------------------------------- +<4> +Connected: <0.15.0> +Links: <0.15.0> +Port controls linked-in driver: efile +-------------------------------------------------- +<5> +Connected: <0.18.0> +Links: <0.18.0> +Port controls linked-in driver: tty_sl -c -e +-------------------------------------------------- + +Internal Table Information +-------------------------------------------------- +Hash Table(atom_tab), size(2411), used(1777), objs(3269), depth(8) +Index Table(atom_tab), size(3300), limit(1048576), used(3270), rate(100) +Atom space 33915/65544 +Hash Table(module_code), size(97), used(49), objs(61), depth(3) +Index Table(module_code), size(70), limit(65536), used(61), rate(10) +Hash Table(export_list), size(1201), used(895), objs(1558), depth(6) +Index Table(export_list), size(1600), limit(65536), used(1558), rate(100) +Hash Table(process_reg), size(23), used(12), objs(13), depth(2) +Mmap chunks 0 +Mmap size 0/0 +Allocated binary 37252 +Allocated by process_desc 11040 +Allocated by table_desc 1120 +Allocated by link_desc 2880 +Allocated by atom_desc 78720 +Allocated by export_desc 62400 +Allocated by module_desc 3200 +Allocated by preg_desc 320 +-------------------------------------------------- + +ETS tables +-------------------------------------------------- +In slot 9 +Table 9(with name)code +Owner <0.16.0> +Buckets: 256 +Table's got 220 objects +Table's got 11372 words of active data + +In slot 10 +Table 10(with name)code_names +Owner <0.16.0> +Buckets: 256 +Table's got 39 objects +Table's got 5947 words of active data + +In slot 264 +Table file_io_servers(with name)file_io_servers +Owner <0.15.0> +Buckets: 256 +Table's got 0 objects +Table's got 0 words of active data + +In slot 875 +Table inet_hosts(with name)inet_hosts +Owner <0.13.0> +Buckets: 256 +Table's got 4 objects +Table's got 112 words of active data + +In slot 899 +Table inet_db(with name)inet_db +Owner <0.13.0> +Buckets: 256 +Table's got 20 objects +Table's got 234 words of active data + +In slot 1202 +Table ac_tab(with name)ac_tab +Owner <0.5.0> +Buckets: 256 +Table's got 6 objects +Table's got 508 words of active data + +In slot 1607 +Table global_names(with name)global_names +Owner <0.11.0> +Buckets: 256 +Table's got 0 objects +Table's got 0 words of active data + +In slot 1619 +Table global_locks(with name)global_locks +Owner <0.11.0> +Buckets: 256 +Table's got 0 objects +Table's got 0 words of active data + +In slot 1620 +Table global_names_ext(with name)global_names_ext +Owner <0.11.0> +Buckets: 256 +Table's got 0 objects +Table's got 0 words of active data + +In slot 1842 +Table inet_cache(with name)inet_cache +Owner <0.13.0> +Buckets: 256 +Table's got 0 objects +Table's got 0 words of active data + + +Timers +-------------------------------------------------- +message=refresh_timeout, pid=<0.13.0>, time left 3593292 ms +-------------------------------------------------- + +Distribution Information +Not alive + +Loaded Modules Information +-------------------------------------------------- +otp_ring0 448 +init 28000 +prim_inet 34800 +erl_prim_loader 14187 +erlang 5751 +error_handler 1691 +heart 6093 +error_logger 6347 +gen_event 17687 +gen 7142 +proc_lib 10250 +application_controller 54728 +gen_server 16422 +sys 11562 +lists 19762 +application 2515 +application_master 10640 +kernel 7059 +supervisor 21159 +rpc 11856 +global 41295 +inet_db 36752 +inet_config 11809 +inet_udp 2471 +inet 26666 +inet_parse 21970 +os 5922 +filename 16858 +inet_hosts 3811 +erl_distribution 2524 +global_group 32620 +net_kernel 35168 +file 30538 +erl_open_port 3319 +code 7146 +ets 15083 +fixtable_server 10283 +code_server 24117 +code_server_int 2053 +code_aux 1704 +string 7538 +user_sup 2503 +supervisor_bridge 2587 +user_drv 12046 +group 8588 +io_lib 8661 +edlin 17419 +io_lib_format 12167 +shell 12096 +kernel_config 3254 +error_logger_tty_h 6287 +erl_eval 26214 +orddict 4878 +c 23302 +io 6522 +erl_scan 15973 +erl_parse 132363 +user_default 1034 +io_lib_pretty 6503 +erl_internal 3634 + +Totals. Current code = 933777 Old code = 0 +-------------------------------------------------- + +Atoms +-------------------------------------------------- +false +true +'_' +'nonode@nohost' +fun +infinity +timeout +normal +call +return +'DOWN' +'EXIT' +all +allocated +allocated_areas +allocator +and +andthen +arity +attributes +backtrace +backtrace_depth +badarg +badarith +badarity +badcookie +badfile +badmatch +badsig +badfun +bag +band +binary +bnot +bor +bxor +bsl +bsr +caller +case_clause +catchlevel +cd +clear +close +closed +command +compile +compressed +connect +connected +const +context_switches +cpu_timestamp +current_function +data +debug_flags +dexit +depth +dgroup_leader +dictionary +disable_trace +display_items +dist +'/' +div +dlink +dmonitor_node +dmonitor_p +'$$' +'$_' +'$dictionary' +dsend +dsend_nosuspend +dunlink +duplicate_bag +elib_malloc +emulator +enable_trace +env +eof +eol +'=:=' +'==' +erlang +error +error_handler +error_logger +exit_status +existing +exiting +exports +fd +fix_alloc +flags +fullsweep_after +fullsweep_if_old_binaries +function +functions +function_clause +garbage_collection +gc_end +gc_start +'>=' +generational +get_seq_token +get_tcw +getenv +getting_linked +getting_unlinked +global +'>' +heap_block_size +heap_size +heap_sizes +hidden +hide +high +id +if_clause +imports +in +index +initial_call +input +internal_error +instruction_counts +invalid +is_seq_trace +io +keep_zombies +keypos +kill +killed +known +label +last_calls +'=<' +line +links +local +low +'<' +machine +match_spec +max +maximum +max_tables +max_processes +mbuf_size +memory +message +message_queue_len +messages +min_heap_size +'-' +module +module_info +monitored_by +monitors +more +name +named_table +'=/=' +'/=' +net_kernel +new +nocatch +noconnect +noconnection +nocookie +node +nodedown +noeol +nofile +noproc +not +not_purged +notalive +nouse_stdio +objects +old_heap_block_size +old_heap_size +on_load +or +ordered_set +orelse +os_type +os_version +out +output +owner +packet +'+' +pid +port +print +priority +private +process +process_count +process_limit +process_dump +procs +protected +protection +public +purify +quantify +receive +recent_size +reductions +register +registered_name +rem +return_from +return_to +return_trace +run_queue +runnable +running +runtime +save_calls +see_zombies +sequential_tracer +sequential_trace_token +serial +set +set_on_first_link +set_on_first_spawn +set_on_link +set_on_spawn +set_seq_token +set_tcw +silent +size +sl_alloc +stack_size +start +status +stderr_to_stdout +stop +stream +suspend +suspended +system_limit +system_version +'SYSTEM' +table +this +thread_pool_size +timeout_value +'*' +timestamp +trace +trace_ts +traced +trace_control_word +tracer +trap_exit +type +undef +undefined +undefined_function +undefined_lambda +unregister +ultrasparc_read_pic1 +ultrasparc_read_tick1 +ultrasparc_read_pic2 +ultrasparc_read_tick2 +ultrasparc_set_pcr +use_mmap_table +use_stdio +used +uniq +value +version +visible +waiting +wall_clock +xor +abs +append +apply +atom_to_list +binary_to_list +binary_to_term +check_process_code +concat_binary +date +delete_module +display +display_string +display_nl +element +erase +exit +float +float_to_list +fun_info +function_exported +garbage_collect +get +get_keys +group_leader +halt +hash +phash +hd +info +integer_to_list +is_alive +length +link +list_to_atom +list_to_binary +list_to_float +list_to_integer +list_to_pid +list_to_tuple +load_module +loaded +localtime +localtime_to_universaltime +make_ref +md5 +md5_init +md5_update +md5_final +module_loaded +monitor_node +nodes +now +open_port_prim +pid_to_list +port_info +ports +pre_loaded +process_flag +process_info +processes +purge_module +put +registered +round +self +send +send_nosuspend +setelement +spawn +spawn_link +split_binary +statistics +subtract +term_to_binary +throw +time +tl +trunc +tuple_to_list +universaltime +universaltime_to_localtime +unlink +whereis +spawn_opt +setnode +dist_exit +dist_unlink +dist_link +port_command +port_control +port_close +port_connect +trace_pattern +trace_info +suspend_process +resume_process +yield +bump_reductions +math +cos +cosh +sin +sinh +tan +tanh +acos +acosh +asin +asinh +atan +atanh +erf +erfc +exp +log +log10 +sqrt +atan2 +pow +old_binary_to_term +start_timer +send_after +cancel_timer +read_timer +make_tuple +append_element +seq_trace +seq_trace_info +seq_trace_print +system_flag +system_info +ref_to_list +port_to_list +fun_to_list +monitor +demonitor +process_display +is_process_alive +fault +is_builtin +is_atom +is_list +is_tuple +is_constant +is_float +is_integer +is_number +is_pid +is_port +is_reference +is_binary +is_function +is_record +match_spec_test +'$put' +'$get' +'$get_keys' +'$erase' +ets +db_delete +delete +first +fixtable +lookup +lookup_element +db_info +last +match +match_delete +db_match_object +next +prev +insert +rename +slot +update_counter +select +match_spec_compile +match_spec_run +os +putenv +getpid +lists +member +reverse +keymember +keysearch +vector +from_list +to_list +erts_debug +disassemble +make_fun +'$end_of_table' +ok +tcp +tcp_closed +tcp_error +udp +udp_closed +udp_error +inet_async +inet_reply +empty_out_q +otp_ring0 +boot +init +run +fatal +'does not export' +'/1' +get_arguments +get_plain_arguments +get_argument +script_id +bs2as +bs2ss +get_args +get_flag +get_flags +get_status +fetch_loaded +ensure_loaded +make_permanent +request +restart +reboot +prepare_run_args +s +b2a +b2s +map +values_to_atoms_again +flags_to_atoms_again +starting +state +to_string +things_to_string +halt_string +crash +boot_loop +progress +started +'init terminating in do_boot' +garb_boot_loop +new_kernelpid +ignore +'could not start kernel pid' +loop +not_allowed +handle_msg +new_state +do_handle_msg +notfound +user +'-boot' +'-config' +set_flag +stopping +do_stop +clear_system +stop_heart +shutdown +shutdown_pids +get_heart +heart +shutdown_kernel_pid +shutdown_loop +shutdown_timeout +resend +kill_all_pids +alive_processes +filter +get_pids +kill_em +kill_all_ports +unload +do_unload +sub +del +terminate +'Kernel pid terminated' +kernel_pid +sleep +start_prim_loader +erl_prim_loader +set_path +'can not start loader' +add_to_kernel +prim_load_flags +'-loader' +'-hosts' +none +'-id' +'-path' +do_boot +'-root' +'-mode' +'-init_debug' +'-boot_var' +bootfile +path_flags +'-pa' +'-pz' +get_boot +not_found +'can not get bootfile' +'bootfile format error' +get_file +script +eval_script +kernel_load_completed +embedded +path +primLoad +preLoaded +kernelProcess +debug +load_modules +fix_path +add_var +extract_var +get_var_value +get_var_val +start_in_kernel +start_em +start_it +load_mod +shutdown_timer +'-shutdown_time' +timer +flush_timout +parse_boot_args +arg +end_args +start_arg +start_arg2 +flag +check +get_flag_list +get_flag_args +to_strings +get_argument1 +set_argument +concat +search +extension +'-values_to_atoms_again/1-fun-0-' +'-boot/1-fun-0-' +'-bs2ss/1-fun-0-' +'-bs2as/1-fun-0-' +'can not load' +'unexpected command in bootfile' +prim_inet +open +inet6 +inet +einval +fdopen +open1 +fdopen1 +open0 +dgram +udp_inet +tcp_inet +subs_empty_out_q +close_pend_loop +send_pend +bind +connect0 +async_connect +accept +accept0 +accept_opts +keepalive +nodelay +active +async_accept +listen +sendto +recv +recv0 +async_recv +recvfrom +recvfrom0 +peername +setpeername +sockname +setsockname +setopt +setopts +getopt +getopts +getiflist +ifget +ifset +subscribe +getstat +getfd +getindex +gettype +getstatus +gethostname +getservbyname +getservbyname1 +getservbyport +getservbyport1 +unrecv +detach +attach +is_sockopt_val +enc_opt +send_timeout +bit8 +low_watermark +high_watermark +exit_on_close +deliver +mode +header +buffer +drop_membership +add_membership +multicast_loop +multicast_ttl +multicast_if +recbuf +sndbuf +broadcast +linger +dontroute +reuseaddr +dec_opt +type_opt +tpkt +fcgi +cdr +asn1 +sunrm +raw +enum +off +on +once +term +list +ip +bool +int +uint +type_value +bitenumlist +ether +enc_value +loopback +any +dec_value +borlist +enum_vals +enum_names +enum_val +enum_name +encode_opt_val +enc_opt_val +encode_opts +enc_opts +decode_opt_val +dec_opt_val +type_ifopt +netmask +addr +broadaddr +dstaddr +mtu +hwaddr +multicast +no_pointtopoint +pointtopoint +no_broadcast +down +up +enc_ifopt +dec_ifopt +decode_ifopts +encode_ifopts +encode_ifopt_val +encode_subs +enc_subs +decode_subs +dec_subs +encode_stats +enc_stats +send_oct +recv_oct +send_avg +send_max +send_cnt +recv_dvi +recv_avg +recv_max +recv_cnt +decode_stats +dec_stats +dec_status +bound +connecting +accepting +listening +busy +enc_time +encode_ifname +build_iflist +rev +ip_to_bytes +ip4_to_bytes +ip6_to_bytes +get_ip +get_ip4 +get_ip6 +ctl_cmd +internal +get_from_port_inet +stop_port +inet_exit_port +dummy_in_handler +efile +get_from_port_efile +exit_port +get_from_port +init_ack +get_path +handle_input +get_from_port1 +'prim_load port died' +die +port_died +get_from_port_efile1 +find_master +connect_master +ebusy +find_loop +find_collect +noport +badrecord +inet_in_handler +get_from_port_inet1 +tcp_options +tcp_timeout +udp_options +ll_tcp_connect +ll_udp_open +ll_open_set_bind +ll_close +port_error +absolute_filename +win32 +send_all +keysort +keyins +to_strs +ipv4_list +einal +ipv4_address +ipv4_addr +'-progname' +'-home' +'no -loader flag' +'no -hosts flag' +'no -id flag' +'no -path flag' +'no -boot flag' +preloaded +application +application_controller +application_master +application_starter +auth +code +code_aux +code_server +code_server_int +dist_util +erl_boot_server +erl_distribution +erl_open_port +erl_reply +file +global_group +global_search +group +inet6_tcp +inet6_tcp_dist +inet6_udp +inet_config +inet_hosts +inet_gethost_native +inet_tcp_dist +otp_pre_init +kernel +kernel_config +net +net_adm +ram_file +rpc +user_drv +user_sup +disk_log +disk_log_1 +disk_log_server +disk_log_sup +dist_ac +erl_atom_cache +erl_ddll +erl_epmd +erl_external +fixtable_server +gen_tcp +gen_udp +inet_db +inet_dns +inet_parse +inet_res +inet_tcp +inet_udp +pg2 +socks5 +socks5_auth +socks5_tcp +socks5_udp +wrap_log_reader +beam_lib +bplus_tree +c +calendar +dets +dict +digraph +digraph_utils +edlin +epp +eval_bits +erl_bits +erl_compile +erl_eval +erl_id_trans +erl_internal +erl_lint +erl_parse +erl_posix_msg +erl_pp +erl_scan +erl_tar +error_logger_file_h +error_logger_tty_h +filelib +filename +gen +gen_event +gen_fsm +gen_server +io_lib +io_lib_format +io_lib_fread +io_lib_pretty +lib +log_mf_h +orddict +ordsets +otp_internal +pg +pool +proc_lib +queue +random +regexp +sets +shell +shell_default +slave +string +supervisor +supervisor_bridge +sys +unix +win32reg +modules_loaded +start_link +description +vsn +modules +boot_server +file_server +global_name_server +kernel_sup +net_sup +rex +os_server +ddll_server +applications +included_applications +tty +start_phases +maxT +maxP +mod +init_kernel_started +load +stdlib +timer_server +rsh_starter +take_over_monitor +pool_master +applications_loaded +start_boot +permanent +erlangrc +'no -mode flag' +'no -init_debug flag' +sunos +open_port +crasher +'** Can not start ~w:~w,~w on ~w **~n' +error_msg +disconnect_node +disconnect +sand +sor +sxor +snot +sgt +sge +slt +sle +seq +seqeq +sneq +sneqeq +ignored +set_cookie +get_cookie +'-fun_info/1-fun-0-' +interpret +eval +stub_function +wait_for_init_ack +no_heart +start_error +set_cmd +clear_cmd +cycle +wait +start_portprogram +port_problem +get_heart_timeouts +check_start_heart +bad_heart_flag +wait_ack +bad_cmd +port_terminated +no_reboot_shutdown +do_cycle_port_program +stop_error +send_heart_beat +send_heart_cmd +send_shutdown +report_problem +root +progname +home +format +error_report +std_error +info_report +std_info +info_msg +error_info +notify +swap_handler +logfile +swap +add_report_handler +add_handler +delete_report_handler +delete_handler +simple_logger +which_handlers +allready_have_logfile +no_log_file +go_back +handle_event +handle_info +handle_call +bad_query +lost_messages +handle_event2 +tag_event +add_node +display2 +nice +nice_tuple +is_string +nolink +init_it +debug_options +add_sup_handler +sync_notify +swap_sup_handler +call1 +system +handle_system_msg +print_event +handle_debug +get_modules +terminate_server +do_unlink +foreach +handle_exit +terminate_supervised +system_continue +system_terminate +system_code_change +zf +server_add_handler +handler +server_add_sup_handler +server_delete_handler +module_not_found +server_swap_handler +s_s_h +split_and_terminate +swapped +server_notify +no +server_update +remove_handler +remove +do_swap +new_handler +split +server_call +bad_module +replace +server_call_update +do_terminate +report_terminate +gen_event_EXIT +report_error +stop_handlers +the_handlers +list_to_set +set_to_list +format_status +items +'-get_modules/1-fun-0-' +'-the_handlers/1-fun-0-' +'-system_code_change/4-fun-0-' +code_change +'-terminate_supervised/4-fun-0-' +parent_terminated +'-do_unlink/2-fun-0-' +already_started +do_spawn +init_it2 +do_call +wait_resp_mon +wait_resp +reply +where +whereis_name +name_register +register_name +yes +spawn_opts +opt +init_p +ensure_link +'$ancestors' +'$initial_call' +exit_p +sync_wait +ack +flush +init_call +translate_initial_call +trans_init +crash_report +my_info +get_ancestors +ancestors +get_cleaned_dictionary +clean_dict +get_dictionary +linked_info +make_neighbour_reports1 +neighbour +make_neighbour_report +get_initial_call +max_neighbours +neighbours +visit +adjacents +no_trap +get_process_info +translate_process_info +get_my_name +proc_info +badrpc +format_own +format_link +format_report +format_rep +load_application +unload_application +start_application +start_boot_application +bad_environment_value +already_loaded +flatten +stop_application +which_applications +loaded_applications +ac_tab +control_application +change_application_data +prep_config_change +config_change +get_pid_env +'$1' +get_env +get_pid_all_env +get_all_env +'$2' +get_pid_key +get_key +appl +get_pid_all_key +get_all_key +start_type +get_master +get_application +get_application_module +appl_data +permit_application +set_env +'invalid configuration file' +'load error' +check_conf_data +'configuration must be a list ended by <dot><whitespace>' +check_para_kernel +distributed +check_distributed +check_para +keydelete +ac_application_stopped +not_started +ac_load_application_req +noreply +ac_application_unloaded +not_loaded +distributed_application +only_loaded +ac_start_application_req +permissions +start_p_false +loading +handle_cast +application_started +handle_application_started +temporary +transient +ac_start_application_reply +ac_change_application_req +ac_load_application_reply +takeover +failover +not_running +stop_it +ac_application_not_run +keyreplace +cntrl +notify_cntrl_started +ac_application_run +del_cntrl +get_loaded +do_load_application +foldl +check_start_cond +do_start +spawn_starter +init_starter +cast +start_appl +stop_appl +stopped +keysearchdelete +ksd +keyreplaceadd +validRestartType +invalid_restart_type +nd +get_restart_type +get_appl_name +bad_application +make_appl +path_consult +format_error +make_appl_i +badstartspec +invalid_name +invalid_options +do_change_apps +do_change_appl +get_opt +get_cmd_env +conv +make_term +dot +parse_term +get_env_i +merge_env +merge_app_env +get_env_key +add_env +del_env +check_user +do_prep_config_change +do_config_change +sort +module_not_defined +application_not_found +do_config_diff +check_conf +config +load_file +tokens +done +nth +'[' +']' +parse_file +open_file +get_new_appl +change_appl +info_started +started_at +info_exited +exited +reply_to_requester +update_permissions +test_change_apps +test_do_change_appl +test_make_apps +'-reply_to_requester/3-fun-0-' +'-check_conf/0-fun-0-' +basename +dirname +join +config_error +'-do_config_diff/3-fun-0-' +'-add_env/2-fun-0-' +'-get_cmd_env/1-fun-0-' +'-do_change_apps/3-fun-0-' +'-start_appl/3-fun-0-' +'-check_start_cond/4-fun-0-' +'-unload/2-fun-0-' +'-load/2-fun-0-' +'-terminate/2-fun-0-' +'-handle_call/3-fun-2-' +'-handle_call/3-fun-1-' +'-handle_call/3-fun-0-' +'-get_application_module/1-fun-1-' +'-get_application_module/1-fun-0-' +'-get_all_env/1-fun-0-' +'-loaded_applications/0-fun-0-' +'$gen_call' +do_cast +'$gen_cast' +abcast +multi_call +send_nodes +start_monitor +unmonitor +rec_nodes +rec_nodes_rest +bad_return_value +dispatch +handle_common_reply +print_log +dbg_options +generic_debug +dbg_opts +get_debug +resume +change_code +log_to_file +no_debug +install +send_system_msg +mfa +suspend_loop +do_cmd +unknown_system_msg +debug_cmd +write +unknown_debug +do_change_code +standard_io +init_stat +get_stat +messages_out +messages_in +current_time +start_time +no_statistics +stat +trim +sublist +install_debug +remove_debug +close_log_file +'-print_log/1-fun-0-' +nthtail +prefix +suffix +sum +duplicate +min +sublist_2 +split2 +init_merge_lists +mergeit +rmergeit +combine +merge +merge2 +rmerge +rmerge2 +thing_to_list +flat_length +flatlength +keydelete3 +keyreplace3 +keysort2 +samkeyrun +keymerge +keymap +fsplit_1 +fsplit_1_1 +fsplit_2 +fmergel +rfmergel +fmerge2_1 +fmerge2_2 +rfmerge2_1 +rfmerge2_2 +flatmap +foldr +mapfoldl +mapfoldr +takewhile +dropwhile +splitwith +'-filter/3-fun-0-' +'-map/3-fun-0-' +'-filter/2-fun-0-' +'-concat/1-fun-0-' +takeover_application +permit +permit_only_loaded_application +spawn_request +here_i_am +get_child +init_loop +io_request +main_loop +terminate_loop +bad_keys +start_it_old +start_it_new +start_the_app +start_supervisor +bad_return +loop_it +prep_stop +shutdown_error +get_child_i +terminate_child_i +terminate_child +kill_children +kill_all_procs +set_timer +exit_after +'-kill_all_procs/0-fun-1-' +'-kill_all_procs/0-fun-0-' +'-kill_children/1-fun-0-' +get_error_logger_type +swap_error_logger +args +safe +one_for_one +one_for_all +worker +kernel_safe_sup +config_zombies +get_code_args +nostick +start_dist_ac +start_ddll +start_boot_server +get_boot_args +boot_server_slaves +start_disk_log +start_pg2 +do_distribution_change +distribution_changed +distribution_not_changed +is_dist_changed +do_global_groups_change +global_groups_changed +global_groups_added +global_groups_removed +is_gg_changed +global_groups +bad_config +start_child +restart_child +delete_child +which_children +check_childspecs +simple_one_for_one +supervisor_data +init_children +start_spec +init_dynamic +bad_start_spec +start_children +do_start_child +child +do_start_child_i +check_flags +bad_flags +update_childspec +update_childspec1 +update_chsp +handle_start_child +already_present +do_restart +child_terminated +reached_max_restart_intensity +rest_for_one +terminate_children +brutal_kill +state_del_child +del_child +split_child +replace_child +do_replace_child +remove_child +init_state +init_state1 +invalid_type +validStrategy +invalid_strategy +validIntensity +invalid_intensity +validPeriod +invalid_period +supname +check_startspec +duplicate_child_name +check_childspec +invalid_child_spec +validChildType +invalid_child_type +validName +validFunc +invalid_mfa +validShutdown +invalid_shutdown +validMods +dynamic +invalid_modules +add_restart +inPeriod +difference +offender +reason +errorContext +supervisor_report +extract_child +child_type +restart_type +report_progress +'-validMods/1-fun-0-' +invalid_module +'-update_chsp/2-fun-0-' +block_call +sbcast +nonexisting_name +set_group_leader +rpc_check +eval_everywhere +multicall +multi_server_call +safe_multi_server_call +async_call +infinite +nb_yield +do_yield +promise_reply +parallel_eval +map_nodes +pmap +build_args +pinfo +'-parallel_eval/1-fun-0-' +'-async_call/4-fun-0-' +'-multicall/4-fun-0-' +'-handle_cast/2-fun-0-' +sync +safe_whereis_name +node_disconnected +random_exit_name +unregister_name +re_register_name +registered_names +global_names +tab2list +register_name_external +unregister_name_external +set_lock +lock_on_nodes +del_lock +check_replies +trans +aborted +trans_all_known +get_known +global_locks +global_names_ext +connect_all +unregister_ext +register_ext +get_known_v2 +get_protocol_version +get_names_ext +new_nodes +lock_is_set +in_sync +async_del_name +async_del_lock +sync_tag_my +prot_vsn +wait_lock +pre_connect +sync_tag_his +init_connect +resolved +exchange +nodeup +test_vsn_tag_nodeup +locker +save_ops +his_the_locker +his_locker +his_locker_new +do_whereis +resend_pre_connect +ins_name +ins_name_ext +handle_set_lock +before_or_false +index_or_false +is_lock_set +handle_del_lock +do_ops +do_ops_ext +start_the_locker +init_the_locker +multi +locker_exited +remove_node +find_node_tag +loop_the_locker +cancel +lock_set +start_locker +init_locker +loop_locker +lock +d_lock +try_again_locker +cancel_locker +exchange_names +resolve_it +minmax +random_notify_name +global_name_conflict +notify_all_name +cnode +dolink +dolink_ext +dounlink +is_pid_used +check_exit +del_names +del_name +del_locks +continue +del_locks2 +do_node_down +do_node_down_names +do_node_down_names_ext +do_node_down_locks +do_node_down_locks2 +get_names +random_sleep +random_seed +seed +uniform +dec +send_again +change_our_node_name +start_sync +sync_init +sync_loop +synced +check_sync_nodes +get_own_nodes +get_own_nodes_with_errors +cs +'-sync_loop/2-fun-0-' +'-sync_init/2-fun-0-' +'-del_name/2-fun-0-' +'-do_ops_ext/2-fun-0-' +'-do_ops/1-fun-0-' +'-resolved/5-fun-1-' +'-resolved/5-fun-0-' +'-unregister_name_external/1-fun-0-' +'-register_name_external/3-fun-0-' +'-registered_names/0-fun-0-' +'-re_register_name/3-fun-0-' +'-unregister_name/1-fun-0-' +'-register_name/3-fun-0-' +reset +add_resolv +resolv +add_hosts +hosts +add_host +del_host +clear_hosts +add_ns +ins_ns +del_ns +add_alt_ns +ins_alt_ns +del_alt_ns +add_search +ins_search +del_search +set_hostname +set_domain +set_lookup +set_recurse +set_timeout +set_retry +set_inet6 +set_usevc +set_socks_server +set_socks_port +add_socks_methods +del_socks_methods +add_socks_noproxy +del_socks_noproxy +set_cache_size +set_cache_refresh +clear_cache +set_tcp_module +tcp_module +set_udp_module +udp_module +add_rc +consult +add_rc_bin +add_rc_list +add_rc_list_int +translate_lookup +yp +dns +native +nisplus +nis +get_rc +cache_refresh +cache_size +host +socks5_noproxy +socks5_methods +socks5_port +socks5_server +usevc +retry +alt_nameserver +nameserver +domain +res_domain +res_ns +res_alt_ns +cache_refresh_interval +res_timeout +res_retry +rety +res_usevc +res_inet6 +res_search +get_rc_noproxy +get_rc_ns +res_option +recurse +next_id +res_recurse +res_lookup +res_id +socks_option +server +noproxy +methods +hostname +db_get +add_rr +dns_rr +del_rr +res_cache_answer +getbyname +dots +getbysearch +make_hostent +aaaa +a +hostent +hostent_by_domain +nxdomain +lookup_type +lookup_cname +cname +lookup_ptr +ptr +lookup_rr +res_hostent_by_domain +res_lookup_type +gethostbyaddr +res_gethostbyaddr +ent_gethostbyaddr +dnip +formerr +dnt +register_socket +unregister_socket +socket +lookup_socket +inet_cache +reset_db +visible_string +refresh_timeout +do_add_rr +cache_rr +times +do_lookup_rr +match_rr +match_object +filter_rr +lower_rr +tolower +arpa_addr_in_dn +int_ip6_dn +dig +dn_ip6_int +dn_in_addr_arpa +dnib +hex +init_timer +stop_timer +do_refresh_cache +alloc_entry +delete_n_oldest +delete_older +'-delete_older/5-fun-0-' +'-do_refresh_cache/4-fun-0-' +'-res_lookup_type/3-fun-0-' +'-lookup_ptr/1-fun-0-' +'-lookup_cname/1-fun-0-' +'-lookup_type/2-fun-0-' +'-res_cache_answer/1-fun-0-' +'-add_rc_list_int/1-fun-1-' +badopt +'-add_rc_list_int/1-fun-0-' +'-add_hosts/1-fun-0-' +unix_sv +linux +freebsd +'bsd/os' +host_conf_linux +gethostbyname +host_conf_freebsd +host_conf_bsdos +nsswitch_conf +vxworks +no_ERLRESCONF +standalone_host +handle_native_lookup +is_native +wins +add_dns_lookup +inet_dns_when_nis +set_search_dom +load_resolv +chars +load_hosts +win32_load_from_registry +read +nt +windows +change_key +win32_load1 +expand +win32_split_line +split_line +win32_get_strings +not_string +vxworks_load_hosts +cmd +hosts_vxworks +check_hostShow +next_line +load_rc +load_inetrc +which_file +cwd +inetrc_dir +warning +inet_warnings +parse_inetrc +parse_inetrc_skip_line +more_chars +'scan_.inetrc' +'parse_.inetrc' +'-vxworks_load_hosts/0-fun-0-' +'-win32_load1/3-fun-1-' +'-win32_load1/3-fun-0-' +address +'-load_hosts/2-fun-0-' +'-set_hostname/1-fun-0-' +getserv +getaddr +getaddr_tm +udp_close +controlling_process +udp_controlling_process +optuniquify +getif +withsocket +pushf +popf +gethostbyname_tm +gethostbyaddr_tm +getll +getaddrs +options +stats +connect_options +connect_opts +con_opt +ifaddr +con_add +listen_options +backlog +listen_opts +list_opt +list_add +udp_opts +udp_opt +udp_add +add_opt +translate_ip +getaddrs_tm +ipv6_address +bytes_to_ip6 +i +foreign_address +local_address +sent +ii +smax +info_lines +i_line +h_line +h_field +hh_field +upper +fmt_status +fmt_addr +enotconn +ntoa +fmt_port +tcp_sockets +udp_sockets +port_list +exbadseq +exbadport +tcp_close +tcp_controlling_process +not_owner +tcp_sync_input +udp_sync_input +'-port_list/1-fun-0-' +'-h_line/1-fun-0-' +'-i_line/3-fun-0-' +'-info_lines/3-fun-0-' +'-ii/3-fun-2-' +'-ii/3-fun-1-' +'-ii/3-fun-0-' +'-gethostname/0-fun-0-' +'-getif/1-fun-0-' +'-getif/0-fun-0-' +'-ifset/2-fun-0-' +'-ifget/2-fun-0-' +'-getiflist/0-fun-0-' +services +noname +delete_options +protocols +netmasks +networks +parse_fd +skip +parse_cs +get_line +read_line +'' +collect_line +cur +position +port_proto +is_vis1 +is_dom1 +is_dom_ldh +is_dom2 +ipv6_addr1 +ipv6_addr2 +ipv6_addr3 +x4 +tox +tod +mkaddr +ds4 +zero +dig_to_dec +dig_to_hex +shex +split_mid +split_end +split_comma +split_mid_comma +'-networks/2-fun-0-' +'-netmasks/2-fun-0-' +'-protocols/2-fun-0-' +'-nsswitch_conf/2-fun-0-' +'-host_conf_bsdos/2-fun-0-' +'-host_conf_freebsd/2-fun-0-' +'-host_conf_linux/2-fun-0-' +'-resolv/2-fun-0-' +'-hosts_vxworks/1-fun-0-' +'-hosts/2-fun-0-' +'-rpc/2-fun-0-' +'-services/2-fun-0-' +find_executable +pathtype +relative +find_executable1 +verify_executable +read_file_info +file_info +split_path +get_cwd +reverse_element +extensions +unix_cmd +unix_cmd1 +start_port +unix_get_data +eot +mk_cmd +validate +validate1 +get_data +absname +absolute +volumerelative +absname_vr +absname_pretty +device +basename1 +skip_prefix +not_device +skip_prefix1 +join1 +maybe_remove_dirsep +unix_pathtype +win32_pathtype +rootname +rootname2 +vxworks_split +unix_split +win32_split +nativename +win32_nativename +separators +find_src +source_search_rules +try +which +filter_options +outdir +export_all +fast +d +parse_transform +get_source_file +source_file +source_by_rules +source_file_not_found +try_rule +readable_file +regular +read_write +make_abs_path +major_os_type +vxworks_first +vxworks_first2 +find_name +'-find_name/3-fun-1-' +'-find_name/3-fun-0-' +no_epmd +epmd_module +protocol_childspecs +start_p +sname +shortnames +lname +longnames +ticktime +net_ticktime +net_sup_dynamic +monitor_nodes +not_boolean +own_nodes +ng_add_check +registered_names_test +send_test +whereis_name_test +global_group_not_runnig +no_conf +publish_type +'invalid global_groups definition' +test3844zty +whereis_test +illegal_function_call +names_test +names +agreed +not_agreed +global_group_check +monitoring +other_groups +no_contact +sync_error +synced_nodes +own_group_nodes +own_group_name +illegal_message +registered_names_res +find_name_res +send_res +conf_check +config_ok +cont +config_scan +original +no_name +'node defined twice' +grp_tuple +sync_check_node +ping +pong +pang +sync_check_init +sync_check +no_global_group_configuration +delete_all +send_monitor +safesend +not_own_group +safesend_nc +check_exit_reg +not_found_ignored +check_exit_send +check_exit_where +kill_global_group_check +disconnect_nodes +force_nodedown +publish_arg +own_group +no_group +publish_on_nodes +update_publish_nodes +'-force_nodedown/1-fun-0-' +'-disconnect_nodes/1-fun-0-' +'-sync_check_init/8-fun-0-' +'-init/1-fun-0-' +kernel_apply +allow +node_info +nodes_info +verbose +set_net_ticktime +new_ticktime +get_net_ticktime +ticktime_res +hidden_connect +publish_on_node +connect_node +hidden_connect_node +sys_dist +barred_connection +dist_auto_connect +never +ticker +tick +bad_cookie +not_implemented +is_auth +pending +up_pending +tick_change +ongoing_change_to +unchanged +longer +shorter +change_initiated +do_spawn_link +no_network +remark_pending +set_monitors +is_pending +remarked +bad_request +accept_pending +connection +already_pending +inserted +do_nodeup +pend_nodeup +registered_send +accept_connection +controller +unsupported_protocol +transition_period_end +aux_tick +do_handle_exit +remove_conn_pid +listen_exit +accept_exit +conn_own_exit +nodeup_exit +monitor_exit +pending_own_exit +ticker_exit +get_conn +pending_nodedown +up_pending_nodedown +up_nodedown +mark_sys_dist_nodedown +do_disconnect +disconnect_pid +get_nodes +to_integer +ticker_loop +start_aux_ticker +aux_ticker +aux_ticker1 +bye +send_list +setup +bad_node +net_address +select_mod +unsupported_address_type +get_proto_mod +lookup_pend +del_pend +init_node +create_name +create_hostpart +short +long +proto_dist +childspecs +start_protos +duplicate_name +sync_cookie +std_monitors +connecttime +net_setuptime +get_node_info +invalid_key +get_nodes_info +reply_waiting +reply_waiting1 +all_atoms +restart_ticker +print_info +display_info +fmt_address +fetch +nformat +getnode +'-print_info/0-fun-0-' +'-create_hostpart/2-fun-0-' +'-init_node/2-fun-0-' +'-handle_info/2-fun-1-' +'-handle_info/2-fun-0-' +'-terminate/2-fun-2-' +'-terminate/2-fun-1-' +nodistribution +pid2name +file_io_servers +set_cwd +make_dir +del_dir +read_link_info +read_link +write_file_info +list_dir +read_file +make_link +make_symlink +write_file +unused +rawopen +raw_read_file_info +raw_write_file_info +get_chars +enomem +pread +put_chars +pwrite +truncate +new_bindings +path_eval +consult_stream +eval_stream +parse_erl_exprs +exprs +path_open +enoent +path_open1 +change_mode +change_owner +change_group +change_time +master +start_slave +'can not get remote filer ' +start_relay +relay +'Port controlling ~w terminated in file_server' +do_read_file +do_write_file +fm_op +list_dir_op +collect_files +write_file_info_op +info_to_list +int_to_bytes +date_to_bytes +file_loop +file_request +get_until +requests +io_requests +position_file +get_until1 +ll_raw_open +ll_open +emfile +ll_write +ll_pwrite +ll_sync +ll_read +ll_pread +ll_lseek +ll_truncate +ll_command +mkport +file_name2 +check_binary +open_mode +new_open_mode +translate_old_mode +character +this_is_an_error +file_position +bof +get_response +bad_response_from_port +transform_ints +file_type +symlink +directory +other +file_access +i32 +getints +check_and_call +check_args +io_reply +file_reply +wait_file_reply +terminated +delete_env_var +change_env_var +single_os_type +uc_lc_equal +uc_lc_match +strict_match +precedes +uc_lc_precedes +make_binary +add_nul_chars +transform_settings +transform_one +objfile_extension +load_abs +load_binary +purge +soft_purge +is_loaded +get_object_code +all_loaded +root_dir +dir +lib_dir +compiler_dir +uc_dir +priv_dir +stick_dir +unstick_dir +add_path +add_pathz +add_patha +add_paths +add_pathsz +add_pathsa +del_path +replace_path +rel_loaded_p +interpreted +delete_interpret +delete_int +interpret_binary +add_uc +stick +interactive +do_stick_dirs +do_s +get_mode +which2 +non_existing +clash +build +decorate +filter2 +has_ext +do_foldl +do_foldr +table_closed +safe_fixtable +erlang_db_match_object +local_info +safe_fixed +do_filter +tab2file +badtab +log_terms +get_objs +file2tab +read_only +repaired +init_file2tab +chunk +fill_tab +file2tab_error +old_file2tab +mk_tab +insert_all +mem +tabs +prinfo +prinfo2 +is_reg +hform +pad_right +'EOT (q)uit (p)Digits (k)ill /Regexp -->' +'(c)ontinue (q)uit (p)Digits (k)ill /Regexp -->' +choice +re +quit +nonl +right +strip +print_number +do_display +do_display_items +do_display_item +substr +re_search +re_display +print_re_num +re_match +check_fixtable_access +'-hform/6-fun-0-' +'-i/0-fun-0-' +fixit +releaseit +do_fixtable +server_init +fixtable_server_sup +call_unchecked +fixtable_processes +fixtable_owners +fixtable_tables +handle_request +handle_request2 +caller_dead +badrequest +insert_owner +wipe_table_owner +wipe_table +wipe_process +'-wipe_process/4-fun-0-' +'-wipe_table/4-fun-0-' +'-handle_request2/5-fun-0-' +del_interpret +do_purge +to_atom +add_interpret +load_interpret +do_ensure +do_delete +init_db +fix +init_insert +add_module +make_path +choose_bundles +cr_b +vsn_to_num +is_vsn +is_numstr +choose +add_loader_path +pa +pz +exclude_pa_pz +excl +strip_path +add +add1 +add_pa_pz +get_arg +exclude +get_name +get_name1 +get_name2 +check_path +bad_directory +bad_path +do_add +maybe_update +update +normalize +init_namedb +code_names +insert_name +bad_name +del_path1 +insert_old_shadowed +replace_path1 +check_pars +del_ebin +replace_name +delete_name +delete_name_dir +lookup_name +do_dir +'bad request to code' +stick_library +unstick_library +putem +sticky +eraseem +get_mods +do_load_binary +modp +try_load_module +sticky_directory +int_list +mod_to_bin +do_soft_purge +ints +all_l +strip_mod_info +'-exclude/2-fun-0-' +'-is_numstr/1-fun-0-' +'-is_vsn/1-fun-0-' +'-vsn_to_num/1-fun-0-' +'-choose_bundles/1-fun-1-' +'-choose_bundles/1-fun-0-' +tell_interpreter +no_interpreter +delete_modules +len +equal +chr +rchr +str +rstr +span +cspan +substr1 +tokens1 +tokens2 +copies +words +both +w_count +left +sub_word +s_word +strip_left +strip_right +strip_right_1 +l_pad +r_pad +centre +sub_string +re_sh_to_awk +sh_to_awk +re_parse +parse +nomatch +re_sub +re_gsub +gsub +re_split +beam_opcodes +beam_dict +beam_asm +beam_listing +beam_flatten +beam_type +beam_jump +beam_block +beam_bs +v3_codegen +v3_life +v3_kernel_pp +v3_kernel +core_pp +core_lint +core_parse +core_scan +corec +core_lib +sys_core_inline +sys_core_fold +v3_core_opt +v3_core +sys_pre_expand +sys_pre_attributes +nouser +'Cannot get remote user' +relay1 +start_user +wait_for_user_p +get_user +x +noinput +noinp_shell +oldshell +sys_xerl +start_out +badcall +terminate_pid +'tty_sl -c -e' +server1 +server_loop +port_bytes +switch_loop +switch_cmd +'?' +atom +k +r +j +h +q +integer +interrupt +get_node +unknown_group +list_commands +beep +edit_line +get_line_timeout +blink +delete_chars +move_rel +insert_chars +put_int16 +gr_new +gr_get_num +gr_get_num1 +gr_add_cur +gr_set_cur +gr_set_num +gr_set_num1 +gr_del_pid +gr_del_pid1 +gr_cur_pid +gr_list +line_buffer +start_shell +start_shell1 +exit_shell +deep_char_list +send_drv +send_drv_reqs +interrupted +get_line1 +erase_line +prompt +edit_line1 +redraw_line +new_stack +stack +up_stack +down_stack +prompt_bytes +scan +reserved_word +fwrite +fread +indentation +fwrite_g +write_tail +write_port +write_ref +write_bin_tail +write_binary +bin_to_list_max +write_vector +write_vector_contents +write_atom +quote_atom +name_chars +name_char +write_string +write_string1 +string_char +write_char +char_list +printable_list +nl +collect_chars +collect_chars1 +collect_line1 +kill_buffer +edit +meta +ctlx +new_line +tab +whitespace_only +prefix_arg +ctlu +key_map +yank +transpose_char +kill_line +forward_delete_char +forward_char +end_of_line +beginning_of_line +backward_delete_char +backward_char +auto_blink +yank_pop +transpose_word +kill_word +forward_word +backward_word +backward_kill_word +do_op +over_word +over_non_word +word_char +over_white +over_paren +over_paren_auto +erase_inp +redraw +length_before +length_after +expand_module_name +expand_function_name +print_matches +col_print +field_width +match1 +longest_common_head +same_head +all_tails +collect +collect_cseq +precision +field_value +pad_char +collect_cc +pcount +decr_pc +control +fwrite_e +float_e +float_man +float_exp +fwrite_f +float_f +float_data +char +newline +adjust_error +adjust +user_default +no_control_g +get_command +get_command1 +expand_hist +expand_exprs +expand_expr +if +catch +tuple +block +lc +case +remote +record_field +cons +record +record_index +op +v +e +expand_cs +clause +expand_fields +expand_quals +generate +no_command +expr +add_cmd +get_cmd +del_cmd +shell_cmd +shell_rep +shell_req +start_eval +evaluator +eval_loop +local_func +init_dict +f +b +var +del_binding +bindings +expr_list +list_bindings +'-get_command/4-fun-0-' +go +sync_nodes +wait_nodes +mandatory_nodes_down +check_up +get_sync_data +get_sync_timeout +sync_nodes_timeout +get_sync_mandatory_nodes +sync_nodes_mandatory +get_sync_optional_nodes +sync_nodes_optional +'-wait_nodes/2-fun-0-' +install_prev +write_events +write_events1 +write_event +string_p +string_p1 +write_time +t +t1 +month +arg_list +nil +field +bif +bin +clauses +unbound +expr_grp +eval_lc +eval_lc1 +is_guard_test +eval_fun +'-inside-a-shell-fun-' +eval_op +'--' +'++' +'!' +if_clauses +case_clauses +receive_clauses +merge_queue +recv_all +match_clause +guard +guard1 +guard0 +guard_test +type_test +reference +number +constant +string_to_conses +match_bits +match_tuple +match_list +match_list1 +dict_to_list +binding +find +add_binding +store +add_bindings +merge_bindings +is_constant_expr +eval_expr +partial_eval +ev_expr +ret_expr +'-ev_expr/1-fun-0-' +'-merge_bindings/2-fun-0-' +'-add_bindings/2-fun-0-' +'-match1/3-fun-1-' +'-match1/3-fun-0-' +'-eval_lc1/4-fun-0-' +'-expr/3-fun-21-' +'-expr/3-fun-20-' +'-expr/3-fun-19-' +'-expr/3-fun-18-' +'-expr/3-fun-17-' +'-expr/3-fun-16-' +'-expr/3-fun-15-' +'-expr/3-fun-14-' +'-expr/3-fun-13-' +'-expr/3-fun-12-' +'-expr/3-fun-11-' +'-expr/3-fun-10-' +'-expr/3-fun-9-' +'-expr/3-fun-8-' +'-expr/3-fun-7-' +'-expr/3-fun-6-' +'-expr/3-fun-5-' +'-expr/3-fun-4-' +'-expr/3-fun-3-' +'-expr/3-fun-2-' +'-expr/3-fun-1-' +'-expr/3-fun-0-' +guard_expr +argument_limit +undef_record +badexpr +':' +'.' +bad_filter +is_key +fetch_keys +append_list +fold +list_to_dict +'-from_list/1-fun-0-' +help +report_warnings +report_errors +machine_load +output_generated +check_load +lc_batch +'@o' +'@i' +'@d' +split_def +nc +ni +l +zi +i1 +mfa_string +iformat +all_procs +palive +pzombie +bt +m +relative_name +strip_cwd +mformat +f_p_e +bi +print_object_file +get_compile_time +compiletime +notime +get_compile_options +compiler_options +get_src_file +get_compile_info +print_exports +split_print_exports +print_time +nregs +regs +all_regs +print_node_regs +display_name_info +pwhereis +pline +rformat +pwd +ls +ls_print +lengths +w +get_proc_mem +get_non_proc_mem +atom_table +module_table +export_table +register_table +loaded_code +static +process_desc +proc_bin_desc +link_desc +atom_desc +export_desc +module_desc +preg_desc +plist_desc +fixed_deletion_desc +bif_timer_rec_desc +atom_space +get_mem +get_ets_mem +total +atom_used +get_proc_mem_if_needed +get_allocated_areas_if_needed +get_ets_mem_if_needed +'-get_proc_mem/0-fun-0-' +'-print_node_regs/1-fun-0-' +'-all_regs/0-fun-0-' +'-nregs/0-fun-0-' +'-m/0-fun-1-' +'-m/0-fun-0-' +'-all_procs/0-fun-0-' +'-i1/1-fun-0-' +'-i/1-fun-1-' +'-i/1-fun-0-' +'-alive_processes/0-fun-0-' +'-lc_batch/1-fun-0-' +'-lc/1-fun-0-' +scan_erl_seq +parse_erl_seq +parse_exprs +to_tuple +o_request +conv_reason +scan_erl_exprs +scan_erl_form +parse_erl_form +parse_form +arguments +default_input +default_output +wait_io_mon_reply +fix_error_start_line +string_pre_scan +is_end +string_thing +base +illegal +pre_scan +'\'' +'"' +'%' +pre_string +pre_string_error +pre_char +pre_escape +pre_comment +pre_dot +pre_error +scan1 +'||' +':-' +'->' +'>>' +'<=' +'<<' +'<-' +scan_atom +scan_variable +scan_name +scan_string +scan_char +scan_escape +escape_char +scan_number +scan_integer +scan_after_int +scan_based_int +scan_after_fraction +scan_exponent +scan_exponent1 +scan_dot +scan_error +begin +when +query +of +end +let +after +'(' +')' +mkop +build_attribute +import +export +attribute +farity_list +record_tuple +record_fields +build_function +build_rule +rule +build_fun +check_clauses +mapl +normalise +normalise_list +abstract +abstract_string +abstract_list +'{' +'}' +tokens_tail +',' +'|' +tokens_tuple +inop_prec +'#' +'=' +preop_prec +func_prec +max_prec +parse_and_scan +return_error +yeccpars1 +'$end' +yeccerror +yecctoken2string +'~w' +reserved_symbol +'~s' +yeccpars2 +bit_type +lc_expr +bit_type_list +lc_exprs +';' +function_clauses +bin_elements +default +cr_clauses +fun_clauses +rule_clauses +expr_700 +strings +rule_clause +record_expr +fun_clause +cr_clause +bin_element +expr_800 +expr_100 +tail +expr_200 +expr_500 +expr_300 +fun_expr +function_call +rule_body +opt_bit_type_list +opt_bit_size_expr +clause_guard +clause_body +bit_expr +expr_600 +receive_expr +list_comprehension +case_expr +query_expr +if_expr +expr_max +argument_list +form +clause_args +prefix_op +mult_op +list_op +comp_op +bit_size_expr +attr_val +atomic +add_op +expr_400 +yeccgoto +'-abstract/2-fun-0-' +'-abstract/1-fun-0-' +'-normalise/1-fun-0-' +'-check_clauses/3-fun-0-' +missing_in_goto_table +parser +missing_state_in_action_table +uh +mk +make +tt +gl +get_loopdata +distel +print_tag_tuple +print_tail +write_length +write_length_list +nl_indent +guard_bif +arith_op +bool_op +send_op +op_type +comp +arith +behaviour_info +obsolete + +<End of Erlang crash dump> diff --git a/lib/observer/test/crashdump_viewer_SUITE_data/r10b_dump.trunc.100atoms b/lib/observer/test/crashdump_viewer_SUITE_data/r10b_dump.trunc.100atoms new file mode 100644 index 0000000000..921c27bd0e --- /dev/null +++ b/lib/observer/test/crashdump_viewer_SUITE_data/r10b_dump.trunc.100atoms @@ -0,0 +1,13135 @@ +=erl_crash_dump:0.1 +Wed Apr 21 13:22:44 2004 +Slogan: eheap_alloc: Cannot allocate 785672 bytes of memory (of type "heap"). +System version: Erlang (BEAM) emulator version 5.4 [source] [hipe] [threads:0] +Compiled: Thu Dec 18 14:07:45 2003 +Atoms: 5614 +=memory +total: 653336887 +processes: 1768396 +processes_used: 1765460 +system: 651568491 +atom: 244837 +atom_used: 237116 +binary: 648618369 +code: 2158413 +ets: 225620 +=hash_table:atom_tab +size: 4813 +used: 3304 +objs: 5614 +depth: 7 +=index_table:atom_tab +size: 5700 +limit: 1048576 +used: 5614 +rate: 100 +=hash_table:module_code +size: 97 +used: 69 +objs: 107 +depth: 5 +=index_table:module_code +size: 110 +limit: 65536 +used: 107 +rate: 10 +=hash_table:export_list +size: 2411 +used: 1674 +objs: 2843 +depth: 6 +=index_table:export_list +size: 2900 +limit: 65536 +used: 2843 +rate: 100 +=hash_table:process_reg +size: 47 +used: 16 +objs: 23 +depth: 3 +=hash_table:fun_table +size: 397 +used: 261 +objs: 400 +depth: 4 +=hash_table:node_table +size: 11 +used: 1 +objs: 1 +depth: 1 +=hash_table:dist_table +size: 11 +used: 1 +objs: 1 +depth: 1 +=allocated_areas +processes: 1765460 1768396 +ets: 225620 +sys_misc: 24634 +static: 295033 +atom_space: 65544 57967 +binary: 648618369 +atom_table: 42141 +module_table: 920 +export_table: 21336 +register_table: 252 +fun_table: 1650 +module_refs: 1024 +loaded_code: 1968915 +dist_table: 159 +node_table: 131 +bits_bufs_size: 19 +bif_timer: 13392 +link_lh: 0 +dist_buf: 0 +proc: 15080 13576 +atom_entry: 137152 137008 +export_entry: 138448 137632 +module_entry: 4872 4352 +reg_proc: 1000 592 +link_nh: 2464 2080 +link_sh: 832 192 +proc_list: 24 24 +fun_entry: 22584 22584 +db_tab: 1632 1632 +=allocator:sys_alloc +option e: true +option m: libc +=allocator:temp_alloc +versions: 0.9 2.1 +option e: true +option sbct: 524288 +option asbcst: 4145152 +option rsbcst: 90 +option rsbcmt: 80 +option mmbcs: 65536 +option mmsbc: 256 +option mmmbc: 10 +option lmbcs: 5242880 +option smbcs: 1048576 +option mbcgs: 10 +option as: af +mbcs blocks: 0 9 9 +mbcs blocks size: 0 35376 35376 +mbcs carriers: 1 1 1 +mbcs mseg carriers: 0 +mbcs sys_alloc carriers: 1 +mbcs carriers size: 65568 65568 65568 +mbcs mseg carriers size: 0 +mbcs sys_alloc carriers size: 65568 +sbcs blocks: 0 0 0 +sbcs blocks size: 0 0 0 +sbcs carriers: 0 0 0 +sbcs mseg carriers: 0 +sbcs sys_alloc carriers: 0 +sbcs carriers size: 0 0 0 +sbcs mseg carriers size: 0 +sbcs sys_alloc carriers size: 0 +temp_alloc calls: 6155 +temp_free calls: 6155 +temp_realloc calls: 29 +mseg_alloc calls: 0 +mseg_dealloc calls: 0 +mseg_realloc calls: 0 +sys_alloc calls: 1 +sys_free calls: 0 +sys_realloc calls: 0 +=allocator:sl_alloc +option e: false +=allocator:std_alloc +option e: false +=allocator:ll_alloc +versions: 0.9 2.1 +option e: true +option sbct: 4294967295 +option asbcst: 0 +option rsbcst: 0 +option rsbcmt: 0 +option mmbcs: 2097152 +option mmsbc: 0 +option mmmbc: 0 +option lmbcs: 5242880 +option smbcs: 1048576 +option mbcgs: 10 +option as: aobf +mbcs blocks: 592 592 592 +mbcs blocks size: 2838520 2863304 2863304 +mbcs carriers: 2 2 2 +mbcs mseg carriers: 0 +mbcs sys_alloc carriers: 2 +mbcs carriers size: 3145760 3145760 3145760 +mbcs mseg carriers size: 0 +mbcs sys_alloc carriers size: 3145760 +sbcs blocks: 0 0 0 +sbcs blocks size: 0 0 0 +sbcs carriers: 0 0 0 +sbcs mseg carriers: 0 +sbcs sys_alloc carriers: 0 +sbcs carriers size: 0 0 0 +sbcs mseg carriers size: 0 +sbcs sys_alloc carriers size: 0 +ll_alloc calls: 592 +ll_free calls: 0 +ll_realloc calls: 235 +mseg_alloc calls: 0 +mseg_dealloc calls: 0 +mseg_realloc calls: 0 +sys_alloc calls: 2 +sys_free calls: 0 +sys_realloc calls: 0 +=allocator:eheap_alloc +versions: 2.1 2.1 +option e: true +option sbct: 524288 +option asbcst: 4145152 +option rsbcst: 50 +option rsbcmt: 80 +option mmbcs: 524288 +option mmsbc: 256 +option mmmbc: 10 +option lmbcs: 5242880 +option smbcs: 1048576 +option mbcgs: 10 +option mbsd: 3 +option as: gf +mbcs blocks: 56 102 102 +mbcs blocks size: 833280 1638920 1638920 +mbcs carriers: 2 3 3 +mbcs mseg carriers: 1 +mbcs sys_alloc carriers: 1 +mbcs carriers size: 1998880 3047456 3047456 +mbcs mseg carriers size: 1474560 +mbcs sys_alloc carriers size: 524320 +sbcs blocks: 0 0 0 +sbcs blocks size: 0 0 0 +sbcs carriers: 0 0 0 +sbcs mseg carriers: 0 +sbcs sys_alloc carriers: 0 +sbcs carriers size: 0 0 0 +sbcs mseg carriers size: 0 +sbcs sys_alloc carriers size: 0 +eheap_alloc calls: 6971 +eheap_free calls: 6914 +eheap_realloc calls: 461 +mseg_alloc calls: 16 +mseg_dealloc calls: 14 +mseg_realloc calls: 0 +sys_alloc calls: 3 +sys_free calls: 0 +sys_realloc calls: 0 +=allocator:binary_alloc +option e: false +=allocator:ets_alloc +option e: false +=allocator:fix_alloc +option e: true +proc: 15080 13576 +atom_entry: 137152 137008 +export_entry: 138448 137632 +module_entry: 4872 4352 +reg_proc: 1000 592 +link_nh: 2464 2080 +link_sh: 832 192 +proc_list: 24 24 +fun_entry: 22584 22584 +db_tab: 1632 1632 +=allocator:mseg_alloc +version: 0.9 +option amcbf: 4194304 +option rmcbf: 20 +option mcs: 5 +option cci: 1000 +cached_segments: 0 +cache_hits: 13 +segments: 2 +segments_watermark: 2 +mseg_alloc calls: 16 +mseg_dealloc calls: 14 +mseg_realloc calls: 0 +mseg_create calls: 4 +mseg_destroy calls: 1 +mseg_clear_cache calls: 6 +mseg_check_cache calls: 2 +=allocator:alloc_util +option mmc: 1024 +option ycs: 1048576 +=allocator:instr +option m: false +option s: false +option t: false +=proc:<0.0.0> +State: Waiting +Name: init +Spawned as: otp_ring0:start/2 +Spawned by: [] +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.5.0>,<0.4.0>,<0.2.0>] +Reductions: 3851 +Stack+heap: 377 +OldHeap: 610 +Heap unused: 53 +OldHeap unused: 610 +Program counter: 0x1f496c (init:loop/1 + 20) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.2.0> +State: Waiting +Name: erl_prim_loader +Spawned as: erlang:apply/2 +Spawned by: <0.1.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.0.0>,#Port<0.2>] +Reductions: 201036 +Stack+heap: 987 +OldHeap: 987 +Heap unused: 923 +OldHeap unused: 987 +Program counter: 0x20cc94 (erl_prim_loader:loop/3 + 52) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.4.0> +State: Waiting +Name: error_logger +Spawned as: proc_lib:init_p/5 +Spawned by: <0.1.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.21.0>,<0.0.0>] +Reductions: 296 +Stack+heap: 6765 +OldHeap: 0 +Heap unused: 851 +OldHeap unused: 0 +Program counter: 0x21f5b8 (gen_event:loop/4 + 40) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.5.0> +State: Waiting +Name: application_controller +Spawned as: proc_lib:init_p/5 +Spawned by: <0.1.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.7.0>,<0.0.0>] +Reductions: 1508 +Stack+heap: 1597 +OldHeap: 0 +Heap unused: 835 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.7.0> +State: Waiting +Spawned as: proc_lib:init_p/5 +Spawned by: <0.6.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.8.0>,<0.5.0>] +Reductions: 23 +Stack+heap: 377 +OldHeap: 0 +Heap unused: 79 +OldHeap unused: 0 +Program counter: 0x248d04 (application_master:main_loop/2 + 28) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.8.0> +State: Waiting +Spawned as: application_master:start_it/4 +Spawned by: <0.7.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.9.0>,<0.7.0>] +Reductions: 91 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 177 +OldHeap unused: 0 +Program counter: 0x24a26c (application_master:loop_it/4 + 40) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.9.0> +State: Waiting +Name: kernel_sup +Spawned as: proc_lib:init_p/5 +Spawned by: <0.8.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.24.0>,<0.23.0>,<0.19.0>,<0.18.0>,<0.17.0>,<0.16.0>,<0.15.0>,<0.14.0>,<0.11.0>,<0.10.0>,<0.8.0>] +Reductions: 7402 +Stack+heap: 610 +OldHeap: 987 +Heap unused: 311 +OldHeap unused: 987 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.10.0> +State: Waiting +Name: rex +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.9.0>] +Reductions: 44 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 144 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.11.0> +State: Waiting +Name: global_name_server +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.13.0>,<0.12.0>,<0.9.0>] +Reductions: 47 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 98 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.12.0> +State: Waiting +Spawned as: global:init_the_locker/1 +Spawned by: <0.11.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.11.0>] +Reductions: 3 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 227 +OldHeap unused: 0 +Program counter: 0x261340 (global:loop_the_locker/2 + 92) +CP: 0x261184 (global:init_the_locker/1 + 112) +arity = 0 +=proc:<0.13.0> +State: Waiting +Spawned as: erlang:apply/2 +Spawned by: <0.11.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.11.0>] +Reductions: 4 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 221 +OldHeap unused: 0 +Program counter: 0x265288 (global:collect_deletions/2 + 76) +CP: 0x2651ac (global:loop_the_deleter/1 + 36) +arity = 0 +=proc:<0.14.0> +State: Waiting +Name: inet_db +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.9.0>] +Reductions: 376 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 30 +OldHeap unused: 233 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.15.0> +State: Waiting +Name: global_group +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.9.0>] +Reductions: 71 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 92 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.16.0> +State: Waiting +Name: file_server_2 +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 1 +Heap fragment data: 119 +Link list: [{from,<0.17.0>,#Ref<0.0.0.22>},#Port<0.4>,<0.9.0>] +Reductions: 83605 +Stack+heap: 4181 +OldHeap: 4181 +Heap unused: 1720 +OldHeap unused: 4181 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.17.0> +State: Waiting +Name: file_server +Spawned as: erlang:apply/2 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [{to,<0.16.0>,#Ref<0.0.0.22>},<0.9.0>] +Reductions: 12 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 207 +OldHeap unused: 0 +Program counter: 0x2a18e8 (old_file_server:relay_loop/3 + 32) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.18.0> +State: Waiting +Name: code_server +Spawned as: erlang:apply/2 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.9.0>] +Reductions: 108900 +Stack+heap: 6765 +OldHeap: 6765 +Heap unused: 4389 +OldHeap unused: 6765 +Program counter: 0x2a6e64 (code_server:loop/1 + 64) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.19.0> +State: Waiting +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.21.0>,<0.9.0>] +Reductions: 74 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 180 +OldHeap unused: 233 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.20.0> +State: Waiting +Spawned as: user_drv:server/2 +Spawned by: <0.19.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.22.0>,<0.21.0>,#Port<0.72>] +Reductions: 596 +Stack+heap: 233 +OldHeap: 377 +Heap unused: 214 +OldHeap unused: 377 +Program counter: 0x2ca4e0 (user_drv:server_loop/5 + 56) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.21.0> +State: Waiting +Name: user +Spawned as: group:server/2 +Spawned by: <0.20.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.4.0>,<0.19.0>,<0.20.0>] +Reductions: 26 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 202 +OldHeap unused: 0 +Program counter: 0x2cd9d8 (group:server_loop/3 + 32) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.22.0> +State: Waiting +Spawned as: group:server/2 +Spawned by: <0.20.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [{from,<0.49.0>,#Ref<0.0.0.307>},<0.25.0>,<0.20.0>] +Reductions: 1244 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 40 +OldHeap unused: 233 +Program counter: 0x2cf238 (group:get_line1/3 + 1652) +CP: 0x2cf230 (group:get_line1/3 + 1644) +arity = 0 +=proc:<0.23.0> +State: Waiting +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.9.0>] +Reductions: 45 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 63 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.24.0> +State: Waiting +Name: kernel_safe_sup +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.31.0>,<0.9.0>] +Reductions: 133 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 198 +OldHeap unused: 233 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.25.0> +State: Waiting +Spawned as: erlang:apply/2 +Spawned by: <0.22.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.49.0>,<0.27.0>,<0.22.0>] +Reductions: 161 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 169 +OldHeap unused: 0 +Program counter: 0x2e0d00 (shell:get_command1/4 + 40) +CP: 0x2e06fc (shell:server_loop/6 + 140) +arity = 0 +=proc:<0.27.0> +State: Waiting +Spawned as: erlang:apply/2 +Spawned by: <0.25.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.25.0>] +Reductions: 506 +Stack+heap: 4181 +OldHeap: 0 +Heap unused: 1131 +OldHeap unused: 0 +Program counter: 0x2e2bbc (shell:eval_loop/2 + 32) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.31.0> +State: Waiting +Name: inet_gethost_native_sup +Spawned as: proc_lib:init_p/5 +Spawned by: <0.24.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.32.0>,<0.24.0>] +Reductions: 49 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 87 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.32.0> +State: Waiting +Name: inet_gethost_native +Spawned as: inet_gethost_native:server_init/2 +Spawned by: <0.31.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 1 +Heap fragment data: 118 +Link list: [#Port<0.105>,<0.31.0>] +Reductions: 65 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 13 +OldHeap unused: 0 +Program counter: 0x4ad840 (inet_gethost_native:main_loop/1 + 20) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.33.0> +State: Waiting +Name: web_tool +Spawned as: proc_lib:init_p/5 +Spawned by: <0.27.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.41.0>] +Reductions: 131773 +Stack+heap: 6765 +OldHeap: 6765 +Heap unused: 2941 +OldHeap unused: 6765 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.41.0> +State: Waiting +Name: websup +Spawned as: proc_lib:init_p/5 +Spawned by: <0.33.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.48.0>,<0.33.0>] +Reductions: 118 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 205 +OldHeap unused: 233 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.43.0> +State: Waiting +Name: httpd_sup__127_0_0_1__8888 +Spawned as: proc_lib:init_p/5 +Spawned by: <0.33.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.46.0>,<0.45.0>,<0.44.0>] +Reductions: 1220 +Stack+heap: 6765 +OldHeap: 0 +Heap unused: 277 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.44.0> +State: Waiting +Name: httpd_acc_sup__127_0_0_1__8888 +Spawned as: proc_lib:init_p/5 +Spawned by: <0.43.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.47.0>,<0.43.0>] +Reductions: 147 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 77 +OldHeap unused: 233 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.45.0> +State: Waiting +Name: httpd_misc_sup__127_0_0_1__8888 +Spawned as: proc_lib:init_p/5 +Spawned by: <0.43.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.43.0>] +Reductions: 52 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 80 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.46.0> +State: Waiting +Name: httpd__127_0_0_1__8888 +Spawned as: proc_lib:init_p/5 +Spawned by: <0.43.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.43.0>] +Reductions: 2905 +Stack+heap: 6765 +OldHeap: 10946 +Heap unused: 138 +OldHeap unused: 10946 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.47.0> +State: Waiting +Spawned as: proc_lib:init_p/5 +Spawned by: <0.44.0> +Started: Wed Apr 21 13:22:18 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [#Port<0.161>,#Port<0.141>,<0.44.0>] +Reductions: 874 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 190 +OldHeap unused: 233 +Program counter: 0x1fe798 (prim_inet:accept0/2 + 96) +CP: 0x1feb04 (prim_inet:async_accept/2 + 380) +arity = 0 +=proc:<0.48.0> +State: Waiting +Name: crashdump_viewer_server +Spawned as: proc_lib:init_p/5 +Spawned by: <0.41.0> +Started: Wed Apr 21 13:22:18 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.56.0>,<0.41.0>] +Reductions: 1913 +Stack+heap: 987 +OldHeap: 987 +Heap unused: 524 +OldHeap unused: 987 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.49.0> +State: Waiting +Spawned as: erlang:apply/2 +Spawned by: <0.25.0> +Started: Wed Apr 21 13:22:18 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [{to,<0.22.0>,#Ref<0.0.0.307>},<0.25.0>] +Reductions: 15 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 190 +OldHeap unused: 0 +Program counter: 0x301d58 (io:wait_io_mon_reply/2 + 28) +CP: 0x30174c (io:parse_erl_exprs/3 + 92) +arity = 0 +=proc:<0.56.0> +State: Garbing +Spawned as: erlang:apply/2 +Last scheduled in for: erlang:garbage_collect/0 +Spawned by: <0.48.0> +Started: Wed Apr 21 13:22:27 2004 +Message queue length: 0 +Number of heap fragments: 1 +Heap fragment data: 121 +Link list: [#Port<0.158>,#Port<0.157>,<0.48.0>] +Reductions: 2420470 +Stack+heap: 121393 +OldHeap: 0 +Heap unused: 22172 +OldHeap unused: 0 +New heap start: FE5768E0 +New heap top: FE5D7734 +Stack top: FE5ED130 +Stack end: FE5ED1A4 +Old heap start: 0 +Old heap top: 0 +Old heap end: 0 +Program counter: 0x1a4980 (unknown function) +CP: 0x20710c (prim_file:read/2 + 436) +=port:#Port<0.1> +Slot: 1 +Connected: #Port<0.0> +Port controls linked-in driver: async +=port:#Port<0.2> +Slot: 2 +Connected: <0.2.0> +Links: <0.2.0> +Port controls linked-in driver: efile +=port:#Port<0.4> +Slot: 4 +Connected: <0.16.0> +Links: <0.16.0> +Port controls linked-in driver: efile +=port:#Port<0.72> +Slot: 72 +Connected: <0.20.0> +Links: <0.20.0> +Port controls linked-in driver: tty_sl -c -e +=port:#Port<0.105> +Slot: 105 +Connected: <0.32.0> +Links: <0.32.0> +Port controls external process: inet_gethost 4 +=port:#Port<0.141> +Slot: 141 +Connected: <0.47.0> +Links: <0.47.0> +Port controls linked-in driver: tcp_inet +=port:#Port<0.157> +Slot: 157 +Connected: <0.56.0> +Links: <0.56.0> +Port controls linked-in driver: efile +=port:#Port<0.158> +Slot: 158 +Connected: <0.56.0> +Links: <0.56.0> +Port controls linked-in driver: efile +=port:#Port<0.161> +Slot: 161 +Connected: <0.47.0> +Links: <0.47.0> +Port controls linked-in driver: tcp_inet +=ets:<0.18.0> +Slot: 9 +Table: 9 +Name: code +Buckets: 256 +Objects: 289 +Words: 14108 +=ets:<0.18.0> +Slot: 10 +Table: 10 +Name: code_names +Buckets: 256 +Objects: 47 +Words: 4334 +=ets:<0.32.0> +Slot: 11 +Table: 11 +Name: ign_requests +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.32.0> +Slot: 12 +Table: 12 +Name: ign_req_index +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.33.0> +Slot: 13 +Table: 13 +Name: app_data +Buckets: 256 +Objects: 7 +Words: 952 +=ets:<0.46.0> +Slot: 15 +Table: 15 +Name: httpd_mime__127_0_0_1__8888 +Buckets: 256 +Objects: 105 +Words: 5742 +=ets:<0.11.0> +Slot: 84 +Table: global_names +Name: global_names +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.11.0> +Slot: 95 +Table: global_locks +Name: global_locks +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.11.0> +Slot: 96 +Table: global_names_ext +Name: global_names_ext +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.14.0> +Slot: 316 +Table: inet_cache +Name: inet_cache +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.48.0> +Slot: 340 +Table: cdv_menu_table +Name: cdv_menu_table +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.48.0> +Slot: 341 +Table: cdv_dump_index_table +Name: cdv_dump_index_table +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.48.0> +Slot: 342 +Table: cdv_decode_heap_table +Name: cdv_decode_heap_table +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.16.0> +Slot: 780 +Table: file_io_servers +Name: file_io_servers +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.46.0> +Slot: 984 +Table: httpd_conf__127_0_0_1__8888 +Name: httpd_conf__127_0_0_1__8888 +Buckets: 256 +Objects: 17 +Words: 1176 +=ets:<0.14.0> +Slot: 1342 +Table: inet_hosts +Name: inet_hosts +Buckets: 256 +Objects: 4 +Words: 421 +=ets:<0.14.0> +Slot: 1362 +Table: inet_db +Name: inet_db +Buckets: 256 +Objects: 20 +Words: 671 +=ets:<0.5.0> +Slot: 1655 +Table: ac_tab +Name: ac_tab +Buckets: 256 +Objects: 6 +Words: 843 +=timer:<0.14.0> +Message: refresh_timeout +Time left: 3565692 ms +=node:'nonode@nohost' +=no_distribution +=loaded_modules +Current code: 1968915 +Old code: 0 +=mod:otp_ring0 +Current size: 489 +=mod:init +Current size: 30110 +=mod:prim_inet +Current size: 35532 +=mod:prim_file +Current size: 24965 +=mod:erl_prim_loader +Current size: 19607 +=mod:erlang +Current size: 11137 +=mod:error_handler +Current size: 2389 +Current attributes: 836C00000001680264000376736E6C000000016E100030769A34345F26EF6D3433254FF2AE576A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613161216802640006736F757263656B00342F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6572726F725F68616E646C65722E65726C6A +=mod:heart +Current size: 6687 +Current attributes: 836C00000001680264000376736E6C000000016E10003094F7BECF345494DDBB4D7186E694186A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261086802640006736F757263656B002C2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F68656172742E65726C6A +=mod:error_logger +Current size: 7051 +Current attributes: 836C00000001680264000376736E6C000000016E10004E3347F841DEAE2EB6A74389E6E127146A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613161246802640006736F757263656B00332F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6572726F725F6C6F676765722E65726C6A +=mod:gen_event +Current size: 18288 +Current attributes: 836C00000001680264000376736E6C000000016E1000336F22DF1EA75E0EA4AE65D3B8C34F946A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61346802640006736F757263656B00302F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F67656E5F6576656E742E65726C6A +=mod:gen +Current size: 7129 +Current attributes: 836C00000001680264000376736E6C000000016E10007BE6AEB66EF48D8B33323C89C9936A526A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61316802640006736F757263656B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F67656E2E65726C6A +=mod:proc_lib +Current size: 11658 +Current attributes: 836C00000001680264000376736E6C000000016E10005C589A8C9BD2E1F2E895E765CAE983406A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E612D6802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F70726F635F6C69622E65726C6A +=mod:application_controller +Current size: 55249 +Current attributes: 836C00000002680264000376736E6C000000016E10003372E1AB0410565065FA086086A721316A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613061246802640006736F757263656B003D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6170706C69636174696F6E5F636F6E74726F6C6C65722E65726C6A +=mod:gen_server +Current size: 18728 +Current attributes: 836C00000001680264000376736E6C000000016E10004C5E93533036DAC7698FC4112F59CF236A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61396802640006736F757263656B00312F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F67656E5F7365727665722E65726C6A +=mod:sys +Current size: 11589 +Current attributes: 836C00000001680264000376736E6C000000016E1000E12B0E8267551204BD5924BAB9629ADF6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612F61176802640006736F757263656B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F7379732E65726C6A +=mod:lists +Current size: 18638 +Current attributes: 836C00000002680264000376736E6C000000016E10001E95B32C30E4CDAF0BDD1ABA58CBB5F36A680264000A646570726563617465646C0000000B68026400066B65796D617061046802640003616C6C61036802640003616E79610368026400036D617061036802640007666C61746D617061036802640005666F6C646C61046802640005666F6C64726104680264000666696C746572610368026400086D6170666F6C646C610468026400086D6170666F6C647261046802640007666F726561636861036A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61116802640006736F757263656B002C2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6C697374732E65726C6A +=mod:application +Current size: 2666 +Current attributes: 836C00000001680264000376736E6C000000016E1000C0C5A7B67B306300FEFF9D91AA50ECB36A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6130611F6802640006736F757263656B00322F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6170706C69636174696F6E2E65726C6A +=mod:application_master +Current size: 10912 +Current attributes: 836C00000001680264000376736E6C000000016E1000360420F5CEB80AD7DD51B3A8A0E2AFA26A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613061266802640006736F757263656B00392F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6170706C69636174696F6E5F6D61737465722E65726C6A +=mod:kernel +Current size: 7639 +Current attributes: 836C00000002680264000376736E6C000000016E10004D418ACCB0F948D4D3CA6B9A81B462746A68026400096265686176696F75726C0000000164000A73757065727669736F726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261336802640006736F757263656B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6B65726E656C2E65726C6A +=mod:supervisor +Current size: 24469 +Current attributes: 836C00000002680264000376736E6C000000016E1000979F65727577135484BE0892A35087CC6A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612F61126802640006736F757263656B00312F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F73757065727669736F722E65726C6A +=mod:rpc +Current size: 14539 +Current attributes: 836C00000002680264000376736E6C000000016E10008C5D6242D36B3201E3B11E82D5E1581E6A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6133610F6802640006736F757263656B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F7270632E65726C6A +=mod:gb_trees +Current size: 8274 +Current attributes: 836C00000001680264000376736E6C000000016E1000094BEFDE7B866EF2CB6FCD895AC2EE056A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D612B6802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F67625F74726565732E65726C6A +=mod:global +Current size: 40753 +Current attributes: 836C00000002680264000376736E6C000000016E10001D02C89BDE6CB2052F099894683C14CA6A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613161386802640006736F757263656B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F676C6F62616C2E65726C6A +=mod:inet_db +Current size: 34555 +Current attributes: 836C00000001680264000376736E6C000000016E1000C1CF6A6F2E83D4EBC23D2CCECBF376226A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6132611A6802640006736F757263656B002E2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F64622E65726C6A +=mod:inet_config +Current size: 13575 +Current attributes: 836C00000001680264000376736E6C000000016E1000650F6571C03BC9C16BB7973A747565066A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261166802640006736F757263656B00322F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F636F6E6669672E65726C6A +=mod:os +Current size: 5997 +Current attributes: 836C00000001680264000376736E6C000000016E100017144CD766A604A9DFBA0B58C8FCA78B6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613361056802640006736F757263656B00292F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6F732E65726C6A +=mod:inet_udp +Current size: 2451 +Current attributes: 836C00000001680264000376736E6C000000016E1000ACB163E87A687A6683B50B331C6E289B6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261306802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F7564702E65726C6A +=mod:inet +Current size: 28288 +Current attributes: 836C00000001680264000376736E6C000000016E10009B9AD400F0BAF6AAF17A4788A4EFF11E6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6132610C6802640006736F757263656B002B2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65742E65726C6A +=mod:inet_parse +Current size: 21928 +Current attributes: 836C00000001680264000376736E6C000000016E1000E0E65454C096847749930EDC1C53C80B6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261266802640006736F757263656B00312F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F70617273652E65726C6A +=mod:filename +Current size: 17411 +Current attributes: 836C00000001680264000376736E6C000000016E100068085214F459D51A3E08819BF8D7698A6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61296802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F66696C656E616D652E65726C6A +=mod:inet_hosts +Current size: 3745 +Current attributes: 836C00000001680264000376736E6C000000016E1000E7430304E86230057150DEE5D279881F6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261226802640006736F757263656B00312F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F686F7374732E65726C6A +=mod:erl_distribution +Current size: 2512 +Current attributes: 836C00000002680264000376736E6C000000016E1000CDE49D63ACA767E0D49679657E99D2046A68026400096265686176696F75726C0000000164000A73757065727669736F726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613161186802640006736F757263656B00372F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F65726C5F646973747269627574696F6E2E65726C6A +=mod:global_group +Current size: 30960 +Current attributes: 836C00000002680264000376736E6C000000016E10008ECE759E5920988CA3ACFF34B32F86736A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6131613B6802640006736F757263656B00332F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F676C6F62616C5F67726F75702E65726C6A +=mod:net_kernel +Current size: 37648 +Current attributes: 836C00000002680264000376736E6C000000016E1000967CE7DE41F9B39906CCCF3225E6E5286A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613361026802640006736F757263656B00312F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6E65745F6B65726E656C2E65726C6A +=mod:file_server +Current size: 8372 +Current attributes: 836C00000002680264000376736E6C000000016E1000EF90906EC6204204AC0A77C4A25B65236A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6131612D6802640006736F757263656B00322F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F66696C655F7365727665722E65726C6A +=mod:old_file_server +Current size: 3074 +Current attributes: 836C00000001680264000376736E6C000000016E1000C802085DD76D4EFBA6A8F528FECB94B36A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6131612F6802640006736F757263656B00362F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6F6C645F66696C655F7365727665722E65726C6A +=mod:code +Current size: 7419 +Current attributes: 836C00000001680264000376736E6C000000016E1000AE618E3041C8E3807A3719CD5140DF5E6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6130612E6802640006736F757263656B002B2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F636F64652E65726C6A +=mod:code_server +Current size: 30811 +Current attributes: 836C00000001680264000376736E6C000000016E0F00BFB96248C2CA8601B4CB7F543F52E26A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613061346802640006736F757263656B00322F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F636F64655F7365727665722E65726C6A +=mod:code_aux +Current size: 1736 +Current attributes: 836C00000001680264000376736E6C000000016E10007A90DB53FCCECD52504F20E7A3B6BAE26A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613061316802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F636F64655F6175782E65726C6A +=mod:packages +Current size: 3119 +Current attributes: 836C00000001680264000376736E6C000000016E1000044DC8EEB65F178AE23EF2465E1954496A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613361076802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F7061636B616765732E65726C6A +=mod:hipe_unified_loader +Current size: 37330 +Current attributes: 836C00000001680264000376736E6C000000016E1000DABD57945702E56F4B3AA7B7B19C1D166A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613361326802640006736F757263656B003A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F686970655F756E69666965645F6C6F616465722E65726C6A +=mod:hipe_sparc_loader +Current size: 1821 +Current attributes: 836C00000001680264000376736E6C000000016E1000582BC55E9FADFF879C2C45D25A6CB7E56A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C7564656802640001696B00322F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F2E2E2F686970652F6D61696E6802640001696B00312F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F2E2E2F686970652F72746C6802640001696B00332F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F2E2E2F686970652F737061726364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6133612B6802640006736F757263656B00382F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F686970655F73706172635F6C6F616465722E65726C6A +=mod:ets +Current size: 16577 +Current attributes: 836C00000002680264000376736E6C000000016E100033D982AC91129E5FC35E0AC3337A4EB56A680264000A646570726563617465646C0000000168026400086669787461626C6561026A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D611C6802640006736F757263656B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6574732E65726C6A +=mod:lists_sort +Current size: 38692 +Current attributes: 836C00000001680264000376736E6C000000016E1000E17EC92FA9AA3199DD71701C215044616A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000B68026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736802640006696E6C696E656C0000000468026400096D65726765335F3132610768026400096D65726765335F32316107680264000A726D65726765335F31326107680264000A726D65726765335F323161076A6802640006696E6C696E656C00000004680264000A756D65726765335F31326108680264000A756D65726765335F32316108680264000C72756D65726765335F3132616107680264000C72756D65726765335F31326261086A6802640006696E6C696E656C00000004680264000C6B65796D65726765335F3132610C680264000C6B65796D65726765335F3231610C680264000D726B65796D65726765335F3132610C680264000D726B65796D65726765335F3231610C6A6802640006696E6C696E656C00000006680264000D756B65796D65726765335F3132610D680264000D756B65796D65726765335F3231610D680264000F72756B65796D65726765335F313261610B680264000F72756B65796D65726765335F323161610D680264000F72756B65796D65726765335F313262610D680264000F72756B65796D65726765335F323162610C6A6A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61166802640006736F757263656B00312F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6C697374735F736F72742E65726C6A +=mod:user_sup +Current size: 2355 +Current attributes: 836C00000002680264000376736E6C000000016E100074BA860804CB4D60D6908C705E6544BD6A68026400096265686176696F75726C0000000164001173757065727669736F725F6272696467656A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613361246802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F757365725F7375702E65726C6A +=mod:supervisor_bridge +Current size: 2944 +Current attributes: 836C00000002680264000376736E6C000000016E10001590DDC10CF8A9D09763CDB7479678ED6A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612F61156802640006736F757263656B00382F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F73757065727669736F725F6272696467652E65726C6A +=mod:user_drv +Current size: 14630 +Current attributes: 836C00000001680264000376736E6C000000016E1000F29F3B193A1EB1ADA9975D97E51BF0E86A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613361216802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F757365725F6472762E65726C6A +=mod:group +Current size: 10165 +Current attributes: 836C00000001680264000376736E6C000000016E1000F6427D0DA330BBFAD5D4C19058516FF36A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261066802640006736F757263656B002C2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F67726F75702E65726C6A +=mod:io_lib +Current size: 12601 +Current attributes: 836C00000002680264000376736E6C000000016E10004160DD78F37EE7C72F7C5B6A751DB7F56A680264000A646570726563617465646C0000000468026400047363616E610168026400047363616E610268026400047363616E6103680264000D72657365727665645F776F726461016A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61036802640006736F757263656B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F696F5F6C69622E65726C6A +=mod:edlin +Current size: 18178 +Current attributes: 836C00000001680264000376736E6C000000016E100035D752FCBA8ED7F4D26990EF3E6A1A526A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612C61016802640006736F757263656B002C2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F65646C696E2E65726C6A +=mod:io_lib_format +Current size: 16189 +Current attributes: 836C00000001680264000376736E6C000000016E10004F382F327C456F83F33C3D5EBFBD87906A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61066802640006736F757263656B00342F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F696F5F6C69625F666F726D61742E65726C6A +=mod:kernel_config +Current size: 3295 +Current attributes: 836C00000002680264000376736E6C000000016E100077B8EE6C9E95FBBE5DB0371F6DB235226A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261356802640006736F757263656B00342F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6B65726E656C5F636F6E6669672E65726C6A +=mod:shell +Current size: 22571 +Current attributes: 836C00000001680264000376736E6C000000016E10007D1354325618EB98A5BD4E8F41E6A0226A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612F61016802640006736F757263656B002C2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F7368656C6C2E65726C6A +=mod:error_logger_tty_h +Current size: 7773 +Current attributes: 836C00000002680264000376736E6C000000016E10001502D55D6C1777F07E2E05CDD91D16986A68026400096265686176696F75726C0000000164000967656E5F6576656E746A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61196802640006736F757263656B00392F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6572726F725F6C6F676765725F7474795F682E65726C6A +=mod:erl_eval +Current size: 33481 +Current attributes: 836C00000002680264000376736E6C000000016E1000D06903753C86BBC49A5CBD789CCB09B66A680264000A646570726563617465646C00000004680264000373657161026802640003736571610368026400086172675F6C697374610268026400086172675F6C69737461036A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612C610D6802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F65726C5F6576616C2E65726C6A +=mod:orddict +Current size: 4872 +Current attributes: 836C00000002680264000376736E6C000000016E100078DCF69F3949D79BC54168266A3ABF566A680264000A646570726563617465646C00000002680264000C646963745F746F5F6C6973746101680264000C6C6973745F746F5F6469637461016A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61236802640006736F757263656B002E2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6F7264646963742E65726C6A +=mod:c +Current size: 19555 +Current attributes: 836C00000001680264000376736E6C000000016E10003FACCF5DE16ABBC988ABF0811980C33B6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612B61136802640006736F757263656B00282F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F632E65726C6A +=mod:io +Current size: 7417 +Current attributes: 836C00000002680264000376736E6C000000016E1000E2F2A6094B3C3D945865225D0620E7546A680264000A646570726563617465646C00000007680264000B70617273655F65787072736102680264000C7363616E5F65726C5F7365716101680264000C7363616E5F65726C5F7365716102680264000C7363616E5F65726C5F7365716103680264000D70617273655F65726C5F7365716101680264000D70617273655F65726C5F7365716102680264000D70617273655F65726C5F73657161036A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61006802640006736F757263656B00292F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F696F2E65726C6A +=mod:file +Current size: 20795 +Current attributes: 836C00000002680264000376736E6C000000016E1000D291AF77EE8B08B792B7FE99274504506A680264000A646570726563617465646C00000001680264000966696C655F696E666F61016A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613161276802640006736F757263656B002B2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F66696C652E65726C6A +=mod:file_io_server +Current size: 12071 +Current attributes: 836C00000001680264000376736E6C000000016E1000A5A8C4E2B2646855AD5C617CB216CB966A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6131612A6802640006736F757263656B00352F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F66696C655F696F5F7365727665722E65726C6A +=mod:erl_scan +Current size: 21891 +Current attributes: 836C00000001680264000376736E6C000000016E100094F386F0C378B258E5D9CEADD4F03B6A6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61116802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F65726C5F7363616E2E65726C6A +=mod:erl_parse +Current size: 161233 +Current attributes: 836C00000001680264000376736E6C000000016E10000E8CBC32C293BFC1FBC721CE918062236A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000968026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F76617273640006696E6C696E656802640004686970656C000000016802640008726567616C6C6F6364000B6C696E6561725F7363616E6A6A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61076802640006736F757263656B00302F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F65726C5F70617273652E65726C6A +=mod:erl_lint +Current size: 73159 +Current attributes: 836C00000001680264000376736E6C000000016E1000D1D2A7D6DDFD1195CB180993C76FD2CD6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612C61156802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F65726C5F6C696E742E65726C6A +=mod:ordsets +Current size: 3257 +Current attributes: 836C00000002680264000376736E6C000000016E1000FD39D8FD846511128F5670BA28600F676A680264000A646570726563617465646C0000000468026400076E65775F7365746100680264000B7365745F746F5F6C6973746101680264000B6C6973745F746F5F7365746101680264000673756273657461026A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61256802640006736F757263656B002E2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6F7264736574732E65726C6A +=mod:dict +Current size: 15637 +Current attributes: 836C00000002680264000376736E6C000000016E1000BC846E7EF85045A5D76190CE9B1AE97C6A680264000A646570726563617465646C00000002680264000C646963745F746F5F6C6973746101680264000C6C6973745F746F5F6469637461016A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612B61356802640006736F757263656B002B2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F646963742E65726C6A +=mod:otp_internal +Current size: 7133 +Current attributes: 836C00000001680264000376736E6C000000016E1000DC494F64DE590AFC4919DFEB0EB026B66A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61206802640006736F757263656B00332F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6F74705F696E7465726E616C2E65726C6A +=mod:user_default +Current size: 1261 +Current attributes: 836C00000002680264000376736E6C000000016E1000505078ACD9B84D514FC6DA2BE249E6756A6802640006617574686F726C0000000164001765656973686E6E406565692E6572696373736F6E2E73656A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000368026400036377646B00112F686F6D652F736972692F65726C616E6768026400066F75746469726B00112F686F6D652F736972692F65726C616E676400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D461036116610D612C61126802640006736F757263656B00222F686F6D652F736972692F65726C616E672F757365725F64656661756C742E65726C6A +=mod:tt +Current size: 2959 +Current attributes: 836C00000002680264000376736E6C000000016E10001D71FD5A55D3BCBF06BFEDF2426C3C386A6802640006617574686F726C0000000164001765656973686E6E406565692E6572696373736F6E2E73656A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000368026400036377646B00112F686F6D652F736972692F65726C616E6768026400066F75746469726B00112F686F6D652F736972692F65726C616E676400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D461036116610D612B610C6802640006736F757263656B00182F686F6D652F736972692F65726C616E672F74742E65726C6A +=mod:distel +Current size: 18214 +Current attributes: 836C00000002680264000376736E6C000000016E1000CC9C9EF141459249C1CCA00993B2E29A6A6802640006617574686F726C000000016400116C756B6540626C75657461696C2E636F6D6A6A +Current compilation info: 836C0000000368026400076F7074696F6E736C0000000664000276336400107761726E5F756E757365645F7661727364000A64656275675F696E666F68026400066F75746469726B00046562696E68026400036377646B001C2F6C6469736B2F736972692F746F6F6C732F64697374656C2D332E3164000A6578706F72745F616C6C6A680264000776657273696F6E6B0003342E31680264000474696D65680662000007D2610B6114610B610361336A +=mod:crashdump_viewer +Current size: 125756 +Current attributes: 836C00000001680264000376736E6C000000016E10002DC5D9D96190A2D5F27FAC3FA3D5C7956A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868026400036377646B00212F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F73726368026400066F75746469726B00292F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F6562696E6802640001696B002C2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F696E636C7564656802640001696B00322F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F2E2E2F65742F696E636C7564656802640001696B003F2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F2E2E2F2E2E2F6C69627261726965732F65742F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F76617273680264000F70617273655F7472616E73666F726D64000C6D735F7472616E73666F726D6A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461146108611B61366802640006736F757263656B00362F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F637261736864756D705F7669657765722E65726C6A +=mod:webtool +Current size: 29229 +Current attributes: 836C00000002680264000376736E6C000000016E10008AEEF06B60527A3390CBC2C98083CC0A6A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00202F636C656172636173652F6F74702F746F6F6C732F776562746F6F6C2F73726368026400066F75746469726B00282F636C656172636173652F6F74702F746F6F6C732F776562746F6F6C2F7372632F2E2E2F6562696E64000A64656275675F696E666F6400107761726E5F756E757365645F76617273680264000F70617273655F7472616E73666F726D64000C6D735F7472616E73666F726D6A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104610661086106612D6802640006736F757263656B002C2F636C656172636173652F6F74702F746F6F6C732F776562746F6F6C2F7372632F776562746F6F6C2E65726C6A +=mod:gen_tcp +Current size: 3574 +Current attributes: 836C00000001680264000376736E6C000000016E1000C965E4EAFDAA94D7F21EDCBE30B21E7B6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613161316802640006736F757263656B002E2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F67656E5F7463702E65726C6A +=mod:inet_tcp +Current size: 2743 +Current attributes: 836C00000001680264000376736E6C000000016E1000C4AFE0B49768E4CF78B2C42EA1D3DB7F6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6132612B6802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F7463702E65726C6A +=mod:inet_gethost_native +Current size: 15611 +Current attributes: 836C00000002680264000376736E6C000000016E10005D8CD4277D0BD2425B9C26036AE314506A68026400096265686176696F75726C0000000164001173757065727669736F725F6272696467656A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261206802640006736F757263656B003A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F676574686F73745F6E61746976652E65726C6A +=mod:filelib +Current size: 7202 +Current attributes: 836C00000001680264000376736E6C000000016E10007B42AA23FF99DF2CD9D586635B77556A6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61266802640006736F757263656B002E2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F66696C656C69622E65726C6A +=mod:httpd_util +Current size: 24068 +Current attributes: 836C00000002680264000376736E6C000000016E10008D99E096221B88D542E52CB9C8377F6D6A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104611561066128613B6802640006736F757263656B00312F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F7574696C2E65726C6A +=mod:webtool_sup +Current size: 695 +Current attributes: 836C00000002680264000376736E6C000000016E1000FA5449E12816CF3AD0A3085BB26CDB9B6A68026400096265686176696F75726C0000000164000A73757065727669736F726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000468026400036377646B00202F636C656172636173652F6F74702F746F6F6C732F776562746F6F6C2F73726368026400066F75746469726B00282F636C656172636173652F6F74702F746F6F6C732F776562746F6F6C2F7372632F2E2E2F6562696E64000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461066108610761236802640006736F757263656B00302F636C656172636173652F6F74702F746F6F6C732F776562746F6F6C2F7372632F776562746F6F6C5F7375702E65726C6A +=mod:httpd_conf +Current size: 33659 +Current attributes: 836C00000002680264000376736E6C000000016E1000E3198FBDC73BC48CB7D0C1C762B8F1AB6A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861116802640006736F757263656B00312F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F636F6E662E65726C6A +=mod:regexp +Current size: 13698 +Current attributes: 836C00000001680264000376736E6C000000016E10009DD44F3D02F8328BE3ABF4DDA89E0CAE6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61376802640006736F757263656B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F7265676578702E65726C6A +=mod:string +Current size: 7740 +Current attributes: 836C00000002680264000376736E6C000000016E10005521DDF38903D46D7C53DB864266F7456A680264000A646570726563617465646C00000007680264000C72655F73685F746F5F61776B6101680264000872655F70617273656101680264000872655F6D617463686102680264000672655F7375626103680264000772655F677375626103680264000872655F73706C697461026802640005696E64657861026A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612F610F6802640006736F757263656B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F737472696E672E65726C6A +=mod:httpd +Current size: 7563 +Current attributes: 836C00000002680264000376736E6C000000016E1000BFD190D951EB3CAD2CC72ADEF20886906A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861036802640006736F757263656B002C2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470642E65726C6A +=mod:httpd_sup +Current size: 4068 +Current attributes: 836C00000003680264000376736E6C000000016E10007FA5C790118F18F3D20A2BFAF0229F0A6A68026400076170705F76736E6B000B696E6574732D332E302E3768026400096265686176696F75726C0000000164000A73757065727669736F726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861366802640006736F757263656B00302F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F7375702E65726C6A +=mod:httpd_acceptor_sup +Current size: 2161 +Current attributes: 836C00000003680264000376736E6C000000016E10003E6F9289B64C13F1EC8A1184BACF055F6A68026400076170705F76736E6B000B696E6574732D332E302E3768026400096265686176696F75726C0000000164000A73757065727669736F726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104611561066128610C6802640006736F757263656B00392F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F6163636570746F725F7375702E65726C6A +=mod:httpd_verbosity +Current size: 2672 +Current attributes: 836C00000002680264000376736E6C000000016E100018B6F407D391872421748F87877DAAF36A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612961036802640006736F757263656B00362F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F766572626F736974792E65726C6A +=mod:timer +Current size: 8223 +Current attributes: 836C00000001680264000376736E6C000000016E10001D0D64DB1B923D1B3B9497655C43B4AD6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612F611A6802640006736F757263656B002C2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F74696D65722E65726C6A +=mod:httpd_misc_sup +Current size: 2066 +Current attributes: 836C00000003680264000376736E6C000000016E100092342F38AC16C074DDC21532FBFB52C26A68026400076170705F76736E6B000B696E6574732D332E302E3768026400096265686176696F75726C0000000164000A73757065727669736F726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104611561066128611F6802640006736F757263656B00352F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F6D6973635F7375702E65726C6A +=mod:httpd_manager +Current size: 28916 +Current attributes: 836C00000003680264000376736E6C000000016E100013F7A1E6A4B6407A0A1892A794EE10A36A68026400076170705F76736E6B000B696E6574732D332E302E3768026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104611561066128611B6802640006736F757263656B00342F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F6D616E616765722E65726C6A +=mod:mod_alias +Current size: 6720 +Current attributes: 836C00000002680264000376736E6C000000016E10002F35C36060B4AC45474440381D146AB96A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612961106802640006736F757263656B00302F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F616C6961732E65726C6A +=mod:mod_auth +Current size: 25168 +Current attributes: 836C00000002680264000376736E6C000000016E100083F3CA0C7A3E7B5E19A635A7F916595D6A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612961166802640006736F757263656B002F2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F617574682E65726C6A +=mod:mod_esi +Current size: 22534 +Current attributes: 836C00000002680264000376736E6C000000016E1000513E3FF733E1E6592B86CB55B9C14E086A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612A61026802640006736F757263656B002E2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F6573692E65726C6A +=mod:mod_actions +Current size: 3625 +Current attributes: 836C00000002680264000376736E6C000000016E10008E5437921662830490CA76DFF88548966A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104611561066129610C6802640006736F757263656B00322F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F616374696F6E732E65726C6A +=mod:mod_cgi +Current size: 25891 +Current attributes: 836C00000002680264000376736E6C000000016E1000F91D405488188F1BD25110B4ED9EE8786A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612961306802640006736F757263656B002E2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F6367692E65726C6A +=mod:mod_include +Current size: 34923 +Current attributes: 836C00000002680264000376736E6C000000016E1000B9CCE88D63DD6AC49D5DF533C46B97D56A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612A61176802640006736F757263656B00322F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F696E636C7564652E65726C6A +=mod:mod_dir +Current size: 13488 +Current attributes: 836C00000002680264000376736E6C000000016E1000EF620CB4B5DE5586ED681347496DA1C86A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612961356802640006736F757263656B002E2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F6469722E65726C6A +=mod:mod_get +Current size: 4672 +Current attributes: 836C00000002680264000376736E6C000000016E1000AD2730B6BE6AF875A500AF4857C4D7F86A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612A61076802640006736F757263656B002E2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F6765742E65726C6A +=mod:mod_head +Current size: 3074 +Current attributes: 836C00000002680264000376736E6C000000016E1000CAF803B9FA6A28D4153BC109B00D7DF96A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612A610B6802640006736F757263656B002F2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F686561642E65726C6A +=mod:mod_log +Current size: 8546 +Current attributes: 836C00000002680264000376736E6C000000016E1000F9664B54861260DEA081249379219AF86A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612A611B6802640006736F757263656B002E2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F6C6F672E65726C6A +=mod:mod_disk_log +Current size: 15160 +Current attributes: 836C00000002680264000376736E6C000000016E1000DDA1E88A9C423A2866B56425DF36F5C66A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612961396802640006736F757263656B00332F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F6469736B5F6C6F672E65726C6A +=mod:httpd_socket +Current size: 7426 +Current attributes: 836C00000002680264000376736E6C000000016E1000B831219096661E4D2E200A07C4A9A7776A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861326802640006736F757263656B00332F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F736F636B65742E65726C6A +=mod:httpd_acceptor +Current size: 4472 +Current attributes: 836C00000002680264000376736E6C000000016E1000A501686DF4E4053E7D978E0CA162BEC56A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861076802640006736F757263656B00352F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F6163636570746F722E65726C6A +=mod:io_lib_pretty +Current size: 8171 +Current attributes: 836C00000001680264000376736E6C000000016E1000CD397E11D2D380D02A4BC6EE309B98CB6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E610C6802640006736F757263656B00342F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F696F5F6C69625F7072657474792E65726C6A +=mod:httpd_request_handler +Current size: 26393 +Current attributes: 836C00000002680264000376736E6C000000016E100021C280A5EB5B9CCD00A2C418A341202A6A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861296802640006736F757263656B003C2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F726571756573745F68616E646C65722E65726C6A +=mod:calendar +Current size: 7158 +Current attributes: 836C00000002680264000376736E6C000000016E10008C44498546709037F8D72DA4AF8B7FB76A680264000A646570726563617465646C00000001680264001C6C6F63616C5F74696D655F746F5F756E6976657273616C5F74696D6561016A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612B61166802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F63616C656E6461722E65726C6A +=mod:httpd_parse +Current size: 9977 +Current attributes: 836C00000002680264000376736E6C000000016E1000174653BAA652261FEB44FFDED99E50B76A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861246802640006736F757263656B00322F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F70617273652E65726C6A +=mod:httpd_response +Current size: 13535 +Current attributes: 836C00000002680264000376736E6C000000016E1000785B247D894BA08A40D814EF11F848976A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104611561066128612D6802640006736F757263656B00352F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F726573706F6E73652E65726C6A +=mod:crashdump_viewer_html +Current size: 68343 +Current attributes: 836C00000001680264000376736E6C000000016E1000AE414770FDB0806C5583FF8D6D71DC766A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00212F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F73726368026400066F75746469726B00292F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F6562696E6802640001696B002C2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F696E636C7564656802640001696B00322F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F2E2E2F65742F696E636C7564656802640001696B003F2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F2E2E2F2E2E2F6C69627261726965732F65742F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461146108611C61026802640006736F757263656B003B2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F637261736864756D705F7669657765725F68746D6C2E65726C6A +=mod:crashdump_translate +Current size: 89840 +Current attributes: 836C00000001680264000376736E6C000000016E100038F332287181E933A76CEF4799BDB6416A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000668026400036377646B00212F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F73726368026400066F75746469726B00292F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F6562696E6802640001696B002C2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F696E636C7564656802640001696B00322F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F2E2E2F65742F696E636C7564656802640001696B003F2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F2E2E2F2E2E2F6C69627261726965732F65742F696E636C75646564000A64656275675F696E666F6A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D461046115610B611661106802640006736F757263656B00392F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F637261736864756D705F7472616E736C6174652E65726C6A +=fun +Module: crashdump_viewer_html +Uniq: 9122590 +Index: 0 +Address: 526308 +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 77168418 +Index: 14 +Address: 26541c +Native_address: bcf04 +Refc: 1 +=fun +Module: inet_parse +Uniq: 88083515 +Index: 9 +Address: 284c30 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 36747896 +Index: 4 +Address: 26df84 +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 80395734 +Index: 8 +Address: 265838 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 103184573 +Index: 5 +Address: 2fa59c +Native_address: bce80 +Refc: 1 +=fun +Module: erl_lint +Uniq: 88265811 +Index: 24 +Address: 34f6a0 +Native_address: bcefc +Refc: 1 +=fun +Module: global_group +Uniq: 9644262 +Index: 2 +Address: 292cec +Native_address: bcef4 +Refc: 1 +=fun +Module: net_kernel +Uniq: 100885585 +Index: 0 +Address: 29eb2c +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 128335479 +Index: 6 +Address: 26de84 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_prim_loader +Uniq: 42988083 +Index: 1 +Address: 210c14 +Native_address: bcf04 +Refc: 1 +=fun +Module: dict +Uniq: 7105125 +Index: 7 +Address: 354f84 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 29030584 +Index: 8 +Address: 234978 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 29214351 +Index: 2 +Address: 285660 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_config +Uniq: 5158633 +Index: 4 +Address: 274034 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 74624950 +Index: 25 +Address: 34f63c +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 6477018 +Index: 3 +Address: 2adb6c +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 117885138 +Index: 7 +Address: 2ffff8 +Native_address: bcefc +Refc: 1 +=fun +Module: dict +Uniq: 47566924 +Index: 6 +Address: 354fb8 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 114637756 +Index: 12 +Address: 313c60 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 121316204 +Index: 31 +Address: 313a68 +Native_address: bced4 +Refc: 1 +=fun +Module: code_server +Uniq: 61363639 +Index: 12 +Address: 2ad6a4 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_config +Uniq: 116208699 +Index: 3 +Address: 274094 +Native_address: bcefc +Refc: 1 +=fun +Module: global_group +Uniq: 113750737 +Index: 0 +Address: 292d54 +Native_address: bcefc +Refc: 1 +=fun +Module: gen_event +Uniq: 12853672 +Index: 0 +Address: 222e74 +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 108046357 +Index: 12 +Address: 4ab0b0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 111569299 +Index: 47 +Address: 34e80c +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 20108653 +Index: 15 +Address: 2f9f94 +Native_address: bcea4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 45252965 +Index: 15 +Address: 313c0c +Native_address: bced4 +Refc: 1 +=fun +Module: webtool +Uniq: 12437425 +Index: 9 +Address: 4ab3e0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 30942993 +Index: 22 +Address: 34f6ec +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_parse +Uniq: 93430337 +Index: 3 +Address: 33b100 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_parse +Uniq: 6604883 +Index: 2 +Address: 33b16c +Native_address: bcefc +Refc: 1 +=fun +Module: rpc +Uniq: 36867745 +Index: 5 +Address: 255e28 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 90563105 +Index: 1 +Address: 285708 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 18519297 +Index: 7 +Address: 26ddfc +Native_address: bcef4 +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 8058975 +Index: 16 +Address: 4a36b4 +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 30694569 +Index: 7 +Address: 27d018 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_config +Uniq: 76933943 +Index: 0 +Address: 2741b4 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 9033258 +Index: 6 +Address: 4a4690 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 74851752 +Index: 5 +Address: 4a4798 +Native_address: bcef4 +Refc: 1 +=fun +Module: global +Uniq: 50855382 +Index: 4 +Address: 2659a8 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 39211582 +Index: 52 +Address: 34e504 +Native_address: bceec +Refc: 1 +=fun +Module: file_server +Uniq: 77665472 +Index: 0 +Address: 2a0dec +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_eval +Uniq: 57487277 +Index: 8 +Address: 2fa3c4 +Native_address: bce94 +Refc: 1 +=fun +Module: webtool +Uniq: 87386575 +Index: 11 +Address: 4ab1c8 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 58991950 +Index: 8 +Address: 4a4338 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 118859163 +Index: 17 +Address: 4a34d4 +Native_address: bcefc +Refc: 1 +=fun +Module: dict +Uniq: 38265609 +Index: 12 +Address: 354dec +Native_address: bcefc +Refc: 1 +=fun +Module: supervisor +Uniq: 56903339 +Index: 1 +Address: 2527c4 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_hosts +Uniq: 129504763 +Index: 0 +Address: 28aae8 +Native_address: bcefc +Refc: 1 +=fun +Module: dict +Uniq: 44817307 +Index: 10 +Address: 354e3c +Native_address: bceec +Refc: 1 +=fun +Module: erl_lint +Uniq: 52856894 +Index: 41 +Address: 34eb70 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 22623360 +Index: 23 +Address: 34f5d4 +Native_address: bceec +Refc: 1 +=fun +Module: orddict +Uniq: 34963136 +Index: 0 +Address: 2fbbbc +Native_address: bcef4 +Refc: 1 +=fun +Module: erlang +Uniq: 24496633 +Index: 0 +Address: 213744 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 99313855 +Index: 27 +Address: 2f9914 +Native_address: bcef4 +Refc: 1 +=fun +Module: httpd_util +Uniq: 99137703 +Index: 3 +Address: 4b5dfc +Native_address: bcefc +Refc: 1 +=fun +Module: gen_event +Uniq: 124043500 +Index: 3 +Address: 222b84 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 102650878 +Index: 22 +Address: 313b48 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 13333720 +Index: 12 +Address: 34fb2c +Native_address: bcef4 +Refc: 1 +=fun +Module: global_group +Uniq: 133457 +Index: 5 +Address: 292a80 +Native_address: bcefc +Refc: 1 +=fun +Module: net_kernel +Uniq: 64640983 +Index: 4 +Address: 29e944 +Native_address: bcefc +Refc: 1 +=fun +Module: rpc +Uniq: 7580218 +Index: 2 +Address: 255f08 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_lint +Uniq: 131850870 +Index: 59 +Address: 34e6b8 +Native_address: bcef4 +Refc: 1 +=fun +Module: inet_parse +Uniq: 56617403 +Index: 10 +Address: 284b40 +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 108680306 +Index: 4 +Address: 4ab5e0 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 90880071 +Index: 2 +Address: 26e150 +Native_address: bcefc +Refc: 1 +=fun +Module: file_io_server +Uniq: 23980778 +Index: 0 +Address: 30ac30 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_eval +Uniq: 12006418 +Index: 19 +Address: 2f9d54 +Native_address: bce80 +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 81701030 +Index: 8 +Address: 526228 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 71013875 +Index: 1 +Address: 4a4ddc +Native_address: bcf04 +Refc: 1 +=fun +Module: distel +Uniq: 87740845 +Index: 2 +Address: 35c0e0 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_eval +Uniq: 90782401 +Index: 17 +Address: 2f9e8c +Native_address: bced4 +Refc: 1 +=fun +Module: shell +Uniq: 133882676 +Index: 6 +Address: 2e52ac +Native_address: bcef4 +Refc: 1 +=fun +Module: inet_parse +Uniq: 105698088 +Index: 3 +Address: 2855b4 +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 58370899 +Index: 0 +Address: 27d370 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 15274536 +Index: 25 +Address: 2f9a94 +Native_address: bcef4 +Refc: 1 +=fun +Module: supervisor +Uniq: 94349557 +Index: 0 +Address: 252844 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_parse +Uniq: 33328185 +Index: 1 +Address: 33b1d8 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 86971387 +Index: 16 +Address: 313db0 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 53364473 +Index: 38 +Address: 34ee84 +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 128145687 +Index: 0 +Address: 4ab944 +Native_address: bcee4 +Refc: 1 +=fun +Module: c +Uniq: 98651404 +Index: 10 +Address: 2fff20 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 78224618 +Index: 0 +Address: 313dcc +Native_address: bced4 +Refc: 1 +=fun +Module: shell +Uniq: 40779085 +Index: 11 +Address: 2e50c8 +Native_address: bcef4 +Refc: 1 +=fun +Module: c +Uniq: 93517350 +Index: 4 +Address: 300090 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 58551291 +Index: 0 +Address: 234f14 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 10055518 +Index: 17 +Address: 526170 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 15795706 +Index: 19 +Address: 313bd4 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 31129467 +Index: 13 +Address: 313c44 +Native_address: bced4 +Refc: 1 +=fun +Module: old_file_server +Uniq: 115635393 +Index: 0 +Address: 2a1a4c +Native_address: bcf04 +Refc: 2 +=fun +Module: erl_eval +Uniq: 65839696 +Index: 22 +Address: 2f9c00 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 69275064 +Index: 28 +Address: 313aa0 +Native_address: bced4 +Refc: 1 +=fun +Module: dict +Uniq: 55938066 +Index: 11 +Address: 354d6c +Native_address: bceec +Refc: 1 +=fun +Module: supervisor +Uniq: 22323433 +Index: 3 +Address: 252688 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 129726129 +Index: 29 +Address: 313abc +Native_address: bced4 +Refc: 1 +=fun +Module: dict +Uniq: 84346832 +Index: 0 +Address: 3550fc +Native_address: bceec +Refc: 1 +=fun +Module: shell +Uniq: 102096820 +Index: 7 +Address: 2e5290 +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 70385762 +Index: 11 +Address: 27cf44 +Native_address: bcefc +Refc: 1 +=fun +Module: mod_cgi +Uniq: 1483038 +Index: 0 +Address: 4ec2e8 +Native_address: bcefc +Refc: 1 +=fun +Module: dict +Uniq: 3664813 +Index: 1 +Address: 3550b4 +Native_address: bcef4 +Refc: 1 +=fun +Module: inet +Uniq: 131143671 +Index: 6 +Address: 27d08c +Native_address: bcef4 +Refc: 1 +=fun +Module: inet_config +Uniq: 46286977 +Index: 2 +Address: 2740b0 +Native_address: bcefc +Refc: 1 +=fun +Module: mod_esi +Uniq: 49099432 +Index: 0 +Address: 4e522c +Native_address: bcefc +Refc: 1 +=fun +Module: application_master +Uniq: 95764905 +Index: 2 +Address: 24aaa8 +Native_address: bcefc +Refc: 1 +=fun +Module: packages +Uniq: 62890926 +Index: 0 +Address: 2ae814 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 41564771 +Index: 35 +Address: 3139f8 +Native_address: bced4 +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 95490768 +Index: 0 +Address: 4a4dc0 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_scan +Uniq: 121559432 +Index: 3 +Address: 313d78 +Native_address: bced4 +Refc: 1 +=fun +Module: httpd_conf +Uniq: 21152662 +Index: 0 +Address: 4be5a0 +Native_address: bcefc +Refc: 1 +=fun +Module: net_kernel +Uniq: 41630916 +Index: 5 +Address: 29e914 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 19747201 +Index: 5 +Address: 313d24 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 100584837 +Index: 36 +Address: 34f0f4 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 64635712 +Index: 15 +Address: 34f94c +Native_address: bcef4 +Refc: 1 +=fun +Module: net_kernel +Uniq: 46398361 +Index: 3 +Address: 29e9a4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 86699817 +Index: 27 +Address: 313b2c +Native_address: bced4 +Refc: 1 +=fun +Module: distel +Uniq: 40869731 +Index: 0 +Address: 35c12c +Native_address: bcf04 +Refc: 1 +=fun +Module: inet +Uniq: 83701641 +Index: 1 +Address: 27d33c +Native_address: bcefc +Refc: 1 +=fun +Module: mod_auth +Uniq: 85845790 +Index: 0 +Address: 4dfd84 +Native_address: bcefc +Refc: 1 +=fun +Module: shell +Uniq: 101292714 +Index: 9 +Address: 2e519c +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 134173702 +Index: 1 +Address: 265b68 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 92433687 +Index: 6 +Address: 2ad9f4 +Native_address: bcef4 +Refc: 1 +=fun +Module: dict +Uniq: 62315241 +Index: 8 +Address: 354f38 +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 11615541 +Index: 12 +Address: 265530 +Native_address: bcefc +Refc: 1 +=fun +Module: hipe_unified_loader +Uniq: 11160090 +Index: 2 +Address: 2b6bb4 +Native_address: bcef4 +Refc: 1 +=fun +Module: application_controller +Uniq: 12116524 +Index: 15 +Address: 2342c4 +Native_address: bcef4 +Refc: 1 +=fun +Module: mod_log +Uniq: 61620901 +Index: 2 +Address: 4fc670 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 23665189 +Index: 12 +Address: 4a3b94 +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 43844413 +Index: 0 +Address: 300100 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 100514258 +Index: 6 +Address: 313d08 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 54271286 +Index: 17 +Address: 34f8a0 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 47017252 +Index: 3 +Address: 26dfa0 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 1228304 +Index: 7 +Address: 4a45a4 +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 127131470 +Index: 10 +Address: 2655a0 +Native_address: bcefc +Refc: 1 +=fun +Module: file_server +Uniq: 22638227 +Index: 1 +Address: 2a0e20 +Native_address: bcf04 +Refc: 1 +=fun +Module: code_server +Uniq: 112704920 +Index: 15 +Address: 2ad488 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 88302875 +Index: 2 +Address: 2fa76c +Native_address: bceb4 +Refc: 1 +=fun +Module: inet_hosts +Uniq: 85808984 +Index: 1 +Address: 28ab18 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_parse +Uniq: 106391799 +Index: 0 +Address: 33b22c +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 25830519 +Index: 5 +Address: 27d0c0 +Native_address: bcefc +Refc: 1 +=fun +Module: shell +Uniq: 110491036 +Index: 1 +Address: 2e5398 +Native_address: bcef4 +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 13128736 +Index: 5 +Address: 52627c +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 84644982 +Index: 21 +Address: 313b9c +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 120577486 +Index: 3 +Address: 34fffc +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 4504456 +Index: 44 +Address: 34e938 +Native_address: bceec +Refc: 1 +=fun +Module: mod_disk_log +Uniq: 28754183 +Index: 0 +Address: 500140 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 88043334 +Index: 14 +Address: 313c28 +Native_address: bced4 +Refc: 1 +=fun +Module: code_server +Uniq: 61592373 +Index: 0 +Address: 2adc28 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_scan +Uniq: 74468346 +Index: 26 +Address: 313ad8 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 69896253 +Index: 21 +Address: 2f9c40 +Native_address: bce80 +Refc: 1 +=fun +Module: global_group +Uniq: 59656873 +Index: 4 +Address: 292ac0 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 103891261 +Index: 2 +Address: 4a4d70 +Native_address: bcefc +Refc: 1 +=fun +Module: httpd_util +Uniq: 89619733 +Index: 0 +Address: 4b5e64 +Native_address: bcefc +Refc: 1 +=fun +Module: shell +Uniq: 133201466 +Index: 10 +Address: 2e5180 +Native_address: bceec +Refc: 1 +=fun +Module: webtool +Uniq: 32159369 +Index: 2 +Address: 4ab820 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 76861396 +Index: 2 +Address: 2adbb0 +Native_address: bcefc +Refc: 1 +=fun +Module: mod_log +Uniq: 48206487 +Index: 0 +Address: 4fc6f0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 118996551 +Index: 28 +Address: 34f384 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 12593774 +Index: 50 +Address: 34e60c +Native_address: bcef4 +Refc: 1 +=fun +Module: httpd_request_handler +Uniq: 48542841 +Index: 1 +Address: 50e88c +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 56178490 +Index: 9 +Address: 4a420c +Native_address: bcefc +Refc: 1 +=fun +Module: distel +Uniq: 88212576 +Index: 4 +Address: 35bf44 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 79562132 +Index: 29 +Address: 34f368 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 129524917 +Index: 32 +Address: 34f2c0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 54029891 +Index: 23 +Address: 2f9af0 +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 108872092 +Index: 4 +Address: 27d0f0 +Native_address: bcef4 +Refc: 1 +=fun +Module: application_controller +Uniq: 40905124 +Index: 6 +Address: 234ac0 +Native_address: bcef4 +Refc: 1 +=fun +Module: code_server +Uniq: 50124876 +Index: 10 +Address: 2ad760 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 791358 +Index: 48 +Address: 34e7b0 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 18404828 +Index: 24 +Address: 313af4 +Native_address: bced4 +Refc: 1 +=fun +Module: httpd_util +Uniq: 13278653 +Index: 1 +Address: 4b5e48 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 110307423 +Index: 13 +Address: 284a7c +Native_address: bcefc +Refc: 1 +=fun +Module: rpc +Uniq: 99592247 +Index: 0 +Address: 256118 +Native_address: bcf04 +Refc: 1 +=fun +Module: global +Uniq: 99918211 +Index: 2 +Address: 265af4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 71442319 +Index: 27 +Address: 34f510 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 7612785 +Index: 13 +Address: 2fa0fc +Native_address: bce80 +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 56095795 +Index: 15 +Address: 4a38a0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 23626796 +Index: 25 +Address: 313b10 +Native_address: bced4 +Refc: 1 +=fun +Module: file_server +Uniq: 126074974 +Index: 2 +Address: 2a0cac +Native_address: bcef4 +Refc: 1 +=fun +Module: inet_config +Uniq: 104278122 +Index: 1 +Address: 274154 +Native_address: bcefc +Refc: 1 +=fun +Module: sys +Uniq: 90854051 +Index: 0 +Address: 240344 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 113334594 +Index: 2 +Address: 313d5c +Native_address: bced4 +Refc: 1 +=fun +Module: inet_parse +Uniq: 8832142 +Index: 7 +Address: 284e30 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 9159706 +Index: 42 +Address: 34eb54 +Native_address: bceec +Refc: 1 +=fun +Module: inet_db +Uniq: 123946665 +Index: 8 +Address: 26e494 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 3149789 +Index: 1 +Address: 5262d0 +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 48288621 +Index: 11 +Address: 2ffed8 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 8953292 +Index: 20 +Address: 4a4d54 +Native_address: bcee4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 9632158 +Index: 4 +Address: 34ff88 +Native_address: bcefc +Refc: 1 +=fun +Module: net_kernel +Uniq: 31111567 +Index: 7 +Address: 29e8c8 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 85307443 +Index: 10 +Address: 2fa29c +Native_address: bcec4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 104417191 +Index: 7 +Address: 313cd0 +Native_address: bced4 +Refc: 1 +=fun +Module: dict +Uniq: 43625777 +Index: 5 +Address: 354fec +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 92698798 +Index: 3 +Address: 4ab780 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 39074546 +Index: 6 +Address: 2fa54c +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 71451126 +Index: 5 +Address: 234b98 +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 122084387 +Index: 6 +Address: 300038 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 9625924 +Index: 14 +Address: 284a60 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 128777368 +Index: 11 +Address: 313c7c +Native_address: bced4 +Refc: 1 +=fun +Module: webtool +Uniq: 10203723 +Index: 7 +Address: 4ab4f8 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 35032400 +Index: 10 +Address: 313c98 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 17252586 +Index: 34 +Address: 313a14 +Native_address: bced4 +Refc: 1 +=fun +Module: code_server +Uniq: 7177165 +Index: 11 +Address: 2ad734 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 115778175 +Index: 3 +Address: 4a4930 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 96440880 +Index: 51 +Address: 34e590 +Native_address: bcefc +Refc: 1 +=fun +Module: hipe_unified_loader +Uniq: 68275407 +Index: 0 +Address: 2b7340 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 88854488 +Index: 16 +Address: 2f9f04 +Native_address: bcebc +Refc: 1 +=fun +Module: global +Uniq: 26353848 +Index: 13 +Address: 2654e8 +Native_address: bcf04 +Refc: 3 +=fun +Module: global +Uniq: 93414722 +Index: 11 +Address: 265568 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 11194189 +Index: 60 +Address: 34fe0c +Native_address: bcef4 +Refc: 1 +=fun +Module: c +Uniq: 125189992 +Index: 8 +Address: 2fffdc +Native_address: bcefc +Refc: 1 +=fun +Module: dict +Uniq: 112472016 +Index: 2 +Address: 355088 +Native_address: bceec +Refc: 1 +=fun +Module: shell +Uniq: 104426442 +Index: 5 +Address: 2e52e0 +Native_address: bceec +Refc: 1 +=fun +Module: global +Uniq: 17426458 +Index: 0 +Address: 265bc4 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 81191039 +Index: 5 +Address: 2ada48 +Native_address: bcef4 +Refc: 1 +=fun +Module: inet_parse +Uniq: 71765042 +Index: 5 +Address: 284f74 +Native_address: bcefc +Refc: 1 +=fun +Module: init +Uniq: 85855821 +Index: 2 +Address: 1fa298 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 70586122 +Index: 10 +Address: 4a3fe4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 87067911 +Index: 49 +Address: 34e708 +Native_address: bcef4 +Refc: 1 +=fun +Module: distel +Uniq: 63126735 +Index: 1 +Address: 35c0fc +Native_address: bcf04 +Refc: 1 +=fun +Module: c +Uniq: 58270309 +Index: 1 +Address: 3000e4 +Native_address: bcefc +Refc: 1 +=fun +Module: ets +Uniq: 80538457 +Index: 1 +Address: 2bc1a0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 69827241 +Index: 9 +Address: 34fd70 +Native_address: bcef4 +Refc: 1 +=fun +Module: dict +Uniq: 103968752 +Index: 3 +Address: 355054 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 117175573 +Index: 21 +Address: 34f728 +Native_address: bcef4 +Refc: 1 +=fun +Module: shell +Uniq: 57865450 +Index: 2 +Address: 2e537c +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 14705965 +Index: 20 +Address: 313b80 +Native_address: bced4 +Refc: 1 +=fun +Module: webtool +Uniq: 85360931 +Index: 6 +Address: 4ab56c +Native_address: bcefc +Refc: 1 +=fun +Module: kernel_config +Uniq: 41755598 +Index: 0 +Address: 2d9e20 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 7110547 +Index: 37 +Address: 34ef14 +Native_address: bcef4 +Refc: 1 +=fun +Module: application_controller +Uniq: 28091577 +Index: 16 +Address: 234244 +Native_address: bcef4 +Refc: 2 +=fun +Module: code_server +Uniq: 96448152 +Index: 14 +Address: 2ad4e4 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 40177568 +Index: 13 +Address: 4a39a4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 31948320 +Index: 58 +Address: 34dfdc +Native_address: bcef4 +Refc: 1 +=fun +Module: global +Uniq: 54153760 +Index: 7 +Address: 265854 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 60156260 +Index: 3 +Address: 5262b4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 1010616 +Index: 2 +Address: 350064 +Native_address: bcef4 +Refc: 1 +=fun +Module: init +Uniq: 96784459 +Index: 1 +Address: 1fa2b4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 48691771 +Index: 18 +Address: 313bb8 +Native_address: bced4 +Refc: 1 +=fun +Module: global +Uniq: 26895060 +Index: 9 +Address: 265710 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 109625093 +Index: 7 +Address: 2ad8fc +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 59436171 +Index: 1 +Address: 3500dc +Native_address: bcef4 +Refc: 1 +=fun +Module: dict +Uniq: 92768306 +Index: 9 +Address: 354f04 +Native_address: bcefc +Refc: 1 +=fun +Module: global_group +Uniq: 106430008 +Index: 3 +Address: 292b38 +Native_address: bcefc +Refc: 1 +=fun +Module: init +Uniq: 79749196 +Index: 6 +Address: 1fa01c +Native_address: bceec +Refc: 1 +=fun +Module: erl_eval +Uniq: 6014929 +Index: 9 +Address: 2fa324 +Native_address: bceac +Refc: 1 +=fun +Module: application_controller +Uniq: 57051922 +Index: 7 +Address: 234a28 +Native_address: bcef4 +Refc: 1 +=fun +Module: net_kernel +Uniq: 77043468 +Index: 6 +Address: 29e8e4 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 36176045 +Index: 9 +Address: 52620c +Native_address: bcefc +Refc: 1 +=fun +Module: rpc +Uniq: 35862809 +Index: 3 +Address: 255edc +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 113649451 +Index: 4 +Address: 2850a0 +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 67943969 +Index: 5 +Address: 2658f4 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 109003032 +Index: 16 +Address: 5260d0 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 104711447 +Index: 13 +Address: 525f5c +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 107666872 +Index: 9 +Address: 27cfb0 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 89410000 +Index: 10 +Address: 5261f0 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 47356870 +Index: 11 +Address: 284ab4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 17873449 +Index: 56 +Address: 34e1e8 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 8839441 +Index: 33 +Address: 34f25c +Native_address: bcefc +Refc: 1 +=fun +Module: gen_event +Uniq: 82513204 +Index: 2 +Address: 222c18 +Native_address: bcefc +Refc: 1 +=fun +Module: application_master +Uniq: 5973059 +Index: 0 +Address: 24ab7c +Native_address: bcefc +Refc: 1 +=fun +Module: inet_gethost_native +Uniq: 127832132 +Index: 0 +Address: 4b065c +Native_address: bcefc +Refc: 2 +=fun +Module: crashdump_viewer_html +Uniq: 39322658 +Index: 14 +Address: 525f40 +Native_address: bcefc +Refc: 1 +=fun +Module: gen_server +Uniq: 100284021 +Index: 0 +Address: 23d288 +Native_address: bcf04 +Refc: 1 +=fun +Module: inet_parse +Uniq: 17430070 +Index: 12 +Address: 284a98 +Native_address: bcefc +Refc: 1 +=fun +Module: init +Uniq: 97509773 +Index: 3 +Address: 1fa27c +Native_address: bcefc +Refc: 1 +=fun +Module: distel +Uniq: 32364818 +Index: 3 +Address: 35c050 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 58576084 +Index: 32 +Address: 313a4c +Native_address: bced4 +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 38384851 +Index: 14 +Address: 4a3988 +Native_address: bceec +Refc: 1 +=fun +Module: application_controller +Uniq: 14139883 +Index: 4 +Address: 234d78 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 122590256 +Index: 0 +Address: 2fa8b4 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 14705629 +Index: 11 +Address: 2fa22c +Native_address: bcedc +Refc: 1 +=fun +Module: erl_eval +Uniq: 9273769 +Index: 4 +Address: 2fa684 +Native_address: bcee4 +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 87950142 +Index: 11 +Address: 5261d4 +Native_address: bcefc +Refc: 1 +=fun +Module: mod_log +Uniq: 54913678 +Index: 1 +Address: 4fc6b0 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 28370334 +Index: 0 +Address: 26e4b0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 24927227 +Index: 40 +Address: 34ed4c +Native_address: bceec +Refc: 1 +=fun +Module: erl_scan +Uniq: 105437500 +Index: 33 +Address: 313a30 +Native_address: bced4 +Refc: 1 +=fun +Module: application_controller +Uniq: 10921695 +Index: 1 +Address: 234eac +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 112431564 +Index: 55 +Address: 34e22c +Native_address: bceec +Refc: 1 +=fun +Module: webtool +Uniq: 129460863 +Index: 5 +Address: 4ab5c4 +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 89001648 +Index: 3 +Address: 27d2ec +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 36199507 +Index: 8 +Address: 27cfe4 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 35620771 +Index: 2 +Address: 5262ec +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 83214871 +Index: 18 +Address: 2f9e34 +Native_address: bceec +Refc: 1 +=fun +Module: code_server +Uniq: 122455383 +Index: 1 +Address: 2adc0c +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_lint +Uniq: 22389488 +Index: 31 +Address: 34f1b8 +Native_address: bceec +Refc: 1 +=fun +Module: erl_eval +Uniq: 41869059 +Index: 12 +Address: 2fa1d4 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 18130505 +Index: 45 +Address: 34e904 +Native_address: bcefc +Refc: 1 +=fun +Module: hipe_unified_loader +Uniq: 107414126 +Index: 1 +Address: 2b706c +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 116638945 +Index: 28 +Address: 2f98f8 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 48465762 +Index: 9 +Address: 2348c8 +Native_address: bcefc +Refc: 1 +=fun +Module: httpd_request_handler +Uniq: 87633852 +Index: 0 +Address: 50e97c +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 28213098 +Index: 8 +Address: 4ab42c +Native_address: bcefc +Refc: 1 +=fun +Module: gen_event +Uniq: 123630574 +Index: 4 +Address: 222b58 +Native_address: bcefc +Refc: 1 +=fun +Module: dict +Uniq: 127425508 +Index: 13 +Address: 354eb4 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 95048118 +Index: 16 +Address: 2ad46c +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 108661978 +Index: 19 +Address: 34f75c +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 21272619 +Index: 13 +Address: 34fad8 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 29943747 +Index: 17 +Address: 313bf0 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 120240397 +Index: 4 +Address: 313d94 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 124060676 +Index: 0 +Address: 350124 +Native_address: bcef4 +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 100975346 +Index: 6 +Address: 526260 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 61421476 +Index: 4 +Address: 2ada9c +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 45197232 +Index: 7 +Address: 34fe5c +Native_address: bcef4 +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 3151900 +Index: 15 +Address: 525f24 +Native_address: bcefc +Refc: 1 +=fun +Module: httpd_util +Uniq: 77509245 +Index: 2 +Address: 4b5e2c +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 94110229 +Index: 8 +Address: 2ad7e4 +Native_address: bcef4 +Refc: 3 +=fun +Module: rpc +Uniq: 101217130 +Index: 1 +Address: 2560c4 +Native_address: bcf04 +Refc: 1 +=fun +Module: lists +Uniq: 103647452 +Index: 0 +Address: 244b7c +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 37841211 +Index: 9 +Address: 2ad77c +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 40109251 +Index: 54 +Address: 34e2b4 +Native_address: bcef4 +Refc: 1 +=fun +Module: init +Uniq: 98012300 +Index: 0 +Address: 1fa2d0 +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 73604759 +Index: 10 +Address: 4ab270 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 12042434 +Index: 1 +Address: 313d40 +Native_address: bced4 +Refc: 1 +=fun +Module: shell +Uniq: 127137775 +Index: 4 +Address: 2e531c +Native_address: bcf04 +Refc: 1 +=fun +Module: inet +Uniq: 45498037 +Index: 12 +Address: 27cec0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 122441107 +Index: 34 +Address: 34f1d4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 70933889 +Index: 46 +Address: 34e8d0 +Native_address: bcef4 +Refc: 1 +=fun +Module: inet +Uniq: 69850797 +Index: 2 +Address: 27d308 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 103965539 +Index: 13 +Address: 234684 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 29979659 +Index: 30 +Address: 313a84 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 17148721 +Index: 20 +Address: 34f778 +Native_address: bcefc +Refc: 1 +=fun +Module: httpd_response +Uniq: 100673049 +Index: 0 +Address: 5165dc +Native_address: bcefc +Refc: 1 +=fun +Module: inet_gethost_native +Uniq: 10508176 +Index: 1 +Address: 4b04dc +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 32476064 +Index: 57 +Address: 34e1c4 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 74835078 +Index: 9 +Address: 313cec +Native_address: bced4 +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 60689814 +Index: 19 +Address: 4a3b78 +Native_address: bceec +Refc: 1 +=fun +Module: erl_lint +Uniq: 39269715 +Index: 5 +Address: 34ff14 +Native_address: bcef4 +Refc: 1 +=fun +Module: shell +Uniq: 112923172 +Index: 0 +Address: 2e5404 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_eval +Uniq: 43010824 +Index: 14 +Address: 2fa03c +Native_address: bce8c +Refc: 1 +=fun +Module: global +Uniq: 82495254 +Index: 3 +Address: 265ac8 +Native_address: bcefc +Refc: 1 +=fun +Module: shell +Uniq: 48568081 +Index: 8 +Address: 2e5220 +Native_address: bcefc +Refc: 1 +=fun +Module: init +Uniq: 77236637 +Index: 7 +Address: 1fa000 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_eval +Uniq: 109386574 +Index: 1 +Address: 2fa804 +Native_address: bce9c +Refc: 1 +=fun +Module: erl_lint +Uniq: 42613220 +Index: 14 +Address: 34f980 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 67093144 +Index: 23 +Address: 313b64 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 86833790 +Index: 11 +Address: 34fbe8 +Native_address: bcefc +Refc: 1 +=fun +Module: net_kernel +Uniq: 6344855 +Index: 1 +Address: 29eabc +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 5149749 +Index: 35 +Address: 34f220 +Native_address: bcefc +Refc: 1 +=fun +Module: init +Uniq: 93451769 +Index: 5 +Address: 1fa120 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 117428568 +Index: 11 +Address: 234758 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 15225890 +Index: 4 +Address: 526298 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 120760477 +Index: 2 +Address: 234cdc +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 88561919 +Index: 3 +Address: 3000ac +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 108931174 +Index: 8 +Address: 313cb4 +Native_address: bced4 +Refc: 1 +=fun +Module: rpc +Uniq: 122901192 +Index: 4 +Address: 255e44 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_lint +Uniq: 32985930 +Index: 10 +Address: 34fc40 +Native_address: bcef4 +Refc: 1 +=fun +Module: global_group +Uniq: 97968498 +Index: 1 +Address: 292b7c +Native_address: bcef4 +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 45671671 +Index: 18 +Address: 4a32d0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 117968056 +Index: 3 +Address: 2fa6ec +Native_address: bcecc +Refc: 1 +=fun +Module: init +Uniq: 108717591 +Index: 4 +Address: 1fa194 +Native_address: bcf04 +Refc: 1 +=fun +Module: supervisor +Uniq: 15091954 +Index: 2 +Address: 2526dc +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 65707495 +Index: 6 +Address: 2658a4 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 34473969 +Index: 17 +Address: 2ad450 +Native_address: bcef4 +Refc: 2 +=fun +Module: crashdump_viewer_html +Uniq: 124296602 +Index: 7 +Address: 526244 +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 23074707 +Index: 15 +Address: 265460 +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 25972856 +Index: 10 +Address: 27cf74 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 43110452 +Index: 24 +Address: 2f9ad4 +Native_address: bceec +Refc: 1 +=fun +Module: code_server +Uniq: 106445918 +Index: 13 +Address: 2ad660 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 116071286 +Index: 12 +Address: 5261b8 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 130814477 +Index: 8 +Address: 284cfc +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 121017037 +Index: 39 +Address: 34ed80 +Native_address: bcef4 +Refc: 1 +=fun +Module: ets +Uniq: 104895267 +Index: 0 +Address: 2bc1bc +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 104682437 +Index: 11 +Address: 4a3de0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 70248777 +Index: 30 +Address: 34f30c +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 13274975 +Index: 5 +Address: 300074 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 98442771 +Index: 53 +Address: 34e2d0 +Native_address: bceec +Refc: 1 +=fun +Module: erl_eval +Uniq: 69829006 +Index: 7 +Address: 2fa47c +Native_address: bce80 +Refc: 1 +=fun +Module: old_file_server +Uniq: 36444943 +Index: 1 +Address: 2a1a80 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_lint +Uniq: 58719455 +Index: 26 +Address: 34f5f0 +Native_address: bcefc +Refc: 1 +=fun +Module: timer +Uniq: 42505885 +Index: 0 +Address: 4cd62c +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 54682479 +Index: 20 +Address: 2f9d08 +Native_address: bcf04 +Refc: 1 +=fun +Module: gen_event +Uniq: 86070332 +Index: 1 +Address: 222d7c +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 54728136 +Index: 9 +Address: 2fff68 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 16474219 +Index: 3 +Address: 234c60 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 108831556 +Index: 10 +Address: 234810 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 72053761 +Index: 16 +Address: 34f8ec +Native_address: bcef4 +Refc: 1 +=fun +Module: net_kernel +Uniq: 65127616 +Index: 2 +Address: 29ea04 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 126167637 +Index: 14 +Address: 234640 +Native_address: bcef4 +Refc: 1 +=fun +Module: inet_parse +Uniq: 113704917 +Index: 0 +Address: 285788 +Native_address: bcefc +Refc: 1 +=fun +Module: mod_disk_log +Uniq: 75279647 +Index: 1 +Address: 500100 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 119218247 +Index: 5 +Address: 26df68 +Native_address: bcef4 +Refc: 1 +=fun +Module: httpd_util +Uniq: 85690044 +Index: 4 +Address: 4b5d6c +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 53075592 +Index: 1 +Address: 26e16c +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 39490182 +Index: 2 +Address: 3000c8 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 75189006 +Index: 12 +Address: 234714 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 14980808 +Index: 43 +Address: 34eb38 +Native_address: bceec +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 16463468 +Index: 4 +Address: 4a4914 +Native_address: bcee4 +Refc: 1 +=fun +Module: dict +Uniq: 99965326 +Index: 4 +Address: 355020 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 36900786 +Index: 6 +Address: 284f3c +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 45447147 +Index: 18 +Address: 34f794 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 32353825 +Index: 6 +Address: 34fe78 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 134052338 +Index: 8 +Address: 34fdc0 +Native_address: bceec +Refc: 1 +=fun +Module: application_master +Uniq: 23840924 +Index: 1 +Address: 24aae0 +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 108282500 +Index: 1 +Address: 4ab918 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_prim_loader +Uniq: 31081110 +Index: 0 +Address: 210c68 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_eval +Uniq: 54275742 +Index: 26 +Address: 2f9a4c +Native_address: bcef4 +Refc: 1 +=fun +Module: shell +Uniq: 45083091 +Index: 3 +Address: 2e5350 +Native_address: bcf04 +Refc: 3 +=proc_stack:<0.0.0> +3a48bc:SReturn addr 0x156F90 (<terminate process normally>) +y0:H371264 +=proc_heap:<0.0.0> +371264:t9:A5:state,H3710D8,N,N,H3710F4,P<0.1.0>,H37128C,H3710FC,N +3710FC:t2:H371138,H371140 +371140:lI80|H371194 +371194:lI49|H3711E0 +3711E0:lI48|H371204 +371204:lI66|N +371138:lI79|H37118C +37118C:lI84|H3711D8 +3711D8:lI80|H3711FC +3711FC:lI32|H37120C +37120C:lI32|H371214 +371214:lI65|H37121C +37121C:lI80|H371224 +371224:lI78|H37122C +37122C:lI32|H371234 +371234:lI49|H37123C +37123C:lI56|H371244 +371244:lI49|H37124C +37124C:lI32|H371254 +371254:lI48|H37125C +37125C:lI49|N +37128C:t2:A7:started,A7:started +3710F4:lH371124|H371130 +371124:t2:A16:application_controller,P<0.5.0> +371130:lH371178|H371184 +371178:t2:AC:error_logger,P<0.4.0> +371184:lH3711CC|N +3711CC:t2:AF:erl_prim_loader,P<0.2.0> +3710D8:lH3710E0|H3710EC +3710E0:t2:A5:-root,H371108 +371108:lH371148|N +371148:Yh13:2F636C656172636173652F6F74702F65727473 +3710EC:lH371110|H37111C +371110:t2:A9:-progname,H371164 +371164:lH37119C|N +37119C:Yh1D:2F636C656172636173652F6F74702F657274732F62696E2F6365726C20 +37111C:lH37116C|N +37116C:t2:A5:-home,H3711C4 +3711C4:lH3711E8|N +3711E8:YhA:2F686F6D652F73697269 +=proc_stack:<0.2.0> +38eca8:SReturn addr 0x156F90 (<terminate process normally>) +y0:H367D20 +y1:P<0.1.0> +y2:H367D28 +y3:A8:infinity +=proc_heap:<0.2.0> +367D20:lH367D48|H367D50 +367D48:lI47|H367D58 +367D58:lI99|H367D68 +367D68:lI108|H367D78 +367D78:lI101|H367D88 +367D88:lI97|H367D98 +367D98:lI114|H367DA8 +367DA8:lI99|H367DB8 +367DB8:lI97|H367DC8 +367DC8:lI115|H367DD8 +367DD8:lI101|H367DE8 +367DE8:lI47|H367DF8 +367DF8:lI111|H367E08 +367E08:lI116|H367E18 +367E18:lI112|H367E28 +367E28:lI47|H367E38 +367E38:lI101|H367E48 +367E48:lI114|H367E58 +367E58:lI116|H367E68 +367E68:lI115|H367E78 +367E78:lI47|H367E88 +367E88:lI108|H367E98 +367E98:lI105|H367EA8 +367EA8:lI98|H367EB8 +367EB8:lI47|H367EC8 +367EC8:lI107|H367ED8 +367ED8:lI101|H367EE8 +367EE8:lI114|H367EF8 +367EF8:lI110|H367F08 +367F08:lI101|H367F18 +367F18:lI108|H367F28 +367F28:lI47|H367F38 +367F38:lI101|H367F48 +367F48:lI98|H367F58 +367F58:lI105|H367F68 +367F68:lI110|N +367D50:lH367D60|N +367D60:lI47|H367D70 +367D70:lI99|H367D80 +367D80:lI108|H367D90 +367D90:lI101|H367DA0 +367DA0:lI97|H367DB0 +367DB0:lI114|H367DC0 +367DC0:lI99|H367DD0 +367DD0:lI97|H367DE0 +367DE0:lI115|H367DF0 +367DF0:lI101|H367E00 +367E00:lI47|H367E10 +367E10:lI111|H367E20 +367E20:lI116|H367E30 +367E30:lI112|H367E40 +367E40:lI47|H367E50 +367E50:lI101|H367E60 +367E60:lI114|H367E70 +367E70:lI116|H367E80 +367E80:lI115|H367E90 +367E90:lI47|H367EA0 +367EA0:lI108|H367EB0 +367EB0:lI105|H367EC0 +367EC0:lI98|H367ED0 +367ED0:lI47|H367EE0 +367EE0:lI115|H367EF0 +367EF0:lI116|H367F00 +367F00:lI100|H367F10 +367F10:lI108|H367F20 +367F20:lI105|H367F30 +367F30:lI98|H367F40 +367F40:lI47|H367F50 +367F50:lI101|H367F60 +367F60:lI98|H367F70 +367F70:lI105|H367F78 +367F78:lI110|N +367D28:t7:A5:state,A5:efile,N,A4:none,p<0.2>,A8:infinity,A5:false +=proc_dictionary:<0.4.0> +H3AC588 +H3AC594 +=proc_stack:<0.4.0> +3b2f14:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:H3B21E8 +y2:AC:error_logger +y3:P<0.1.0> +3b2f28:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H3AC5A8 +=proc_heap:<0.4.0> +3B21E8:lH3B2144|H3B21E0 +3B2144:t5:A7:handler,AC:error_logger,A5:false,N,A5:false +3B21E0:lH3B21BC|N +3B21BC:t5:A7:handler,A12:error_logger_tty_h,A5:false,H3AC610,A5:false +3AC610:t2:P<0.21.0>,AC:error_logger +3AC5A8:lA9:gen_event|H3AC5E8 +3AC5E8:lP<0.1.0>|H3AC608 +3AC608:lP<0.1.0>|H3AC61C +3AC61C:lH3AC624|H3AC630 +3AC624:t2:A5:local,AC:error_logger +3AC630:lN|H3AC638 +3AC638:lN|H3AC640 +3AC640:lN|N +3AC588:t2:AD:$initial_call,H3AC5B0 +3AC5B0:t3:A3:gen,A7:init_it,H3AC5A8 +3AC594:t2:AA:$ancestors,H3AC5C0 +3AC5C0:lP<0.1.0>|N +=proc_dictionary:<0.5.0> +H372E4C +H372E58 +=proc_stack:<0.5.0> +374704:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A16:application_controller +y3:H3739F4 +y4:A16:application_controller +y5:P<0.1.0> +374720:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H372ED0 +=proc_heap:<0.5.0> +3739F4:t9:A5:state,N,N,N,H373914,N,H373928,N,N +373928:lH37391C|H372F54 +37391C:t2:A6:stdlib,A9:permanent +372F54:lH372F90|N +372F90:t2:A6:kernel,A9:permanent +373914:lH373908|H372F4C +373908:t2:A6:stdlib,A9:undefined +372F4C:lH372F84|N +372F84:t2:A6:kernel,P<0.7.0> +372ED0:lAA:gen_server|H372F5C +372F5C:lP<0.1.0>|H372F9C +372F9C:lP<0.1.0>|H372FC4 +372FC4:lH372FEC|H372FF8 +372FEC:t2:A5:local,A16:application_controller +372FF8:lA16:application_controller|H373018 +373018:lH373038|H373048 +373038:t3:AB:application,A6:kernel,H373060 +373060:lH373078|H373084 +373078:t2:AB:description,H37309C +37309C:lI69|H3730C8 +3730C8:lI82|H3730FC +3730FC:lI84|H373130 +373130:lI83|H37316C +37316C:lI32|H3731A8 +3731A8:lI32|H3731E4 +3731E4:lI67|H373220 +373220:lI88|H37325C +37325C:lI67|H37329C +37329C:lI32|H3732D0 +3732D0:lI49|H3732FC +3732FC:lI51|H373328 +373328:lI56|H373348 +373348:lI32|H373368 +373368:lI49|H373388 +373388:lI48|N +373084:lH3730A4|H3730B0 +3730A4:t2:A3:vsn,H3730D0 +3730D0:lI50|H373104 +373104:lI46|H373138 +373138:lI57|N +3730B0:lH3730D8|H3730E4 +3730D8:t2:A2:id,N +3730E4:lH37310C|H373118 +37310C:t2:A7:modules,H373140 +373140:lAB:application|H373174 +373174:lA16:application_controller|H3731B0 +3731B0:lA12:application_master|H3731EC +3731EC:lA13:application_starter|H373228 +373228:lA4:auth|H373264 +373264:lA4:code|H3732A4 +3732A4:lA8:code_aux|H3732D8 +3732D8:lA8:packages|H373304 +373304:lAB:code_server|H373330 +373330:lA9:dist_util|H373350 +373350:lAF:erl_boot_server|H373370 +373370:lA10:erl_distribution|H373390 +373390:lAF:erl_prim_loader|H3733A8 +3733A8:lA9:erl_reply|H3733C0 +3733C0:lA6:erlang|H3733D8 +3733D8:lAD:error_handler|H3733F0 +3733F0:lAC:error_logger|H373408 +373408:lA4:file|H373420 +373420:lAB:file_server|H373438 +373438:lAF:old_file_server|H373450 +373450:lAE:file_io_server|H373468 +373468:lA9:prim_file|H373480 +373480:lA6:global|H373498 +373498:lAC:global_group|H3734B0 +3734B0:lAD:global_search|H3734C8 +3734C8:lA5:group|H3734E0 +3734E0:lA5:heart|H3734F8 +3734F8:lA13:hipe_unified_loader|H373510 +373510:lA11:hipe_sparc_loader|H373520 +373520:lAF:hipe_x86_loader|H373530 +373530:lA9:inet6_tcp|H373540 +373540:lAE:inet6_tcp_dist|H373550 +373550:lA9:inet6_udp|H373560 +373560:lAB:inet_config|H373570 +373570:lAA:inet_hosts|H373580 +373580:lA13:inet_gethost_native|H373590 +373590:lAD:inet_tcp_dist|H3735A0 +3735A0:lA4:init|H3735B0 +3735B0:lA6:kernel|H3735C0 +3735C0:lAD:kernel_config|H3735D0 +3735D0:lA3:net|H3735E0 +3735E0:lA7:net_adm|H3735F0 +3735F0:lAA:net_kernel|H373600 +373600:lA2:os|H373610 +373610:lA8:ram_file|H373620 +373620:lA3:rpc|H373630 +373630:lA4:user|H373640 +373640:lA8:user_drv|H373650 +373650:lA8:user_sup|H373660 +373660:lA8:disk_log|H373670 +373670:lAA:disk_log_1|H373680 +373680:lAF:disk_log_server|H373690 +373690:lAC:disk_log_sup|H3736A0 +3736A0:lA7:dist_ac|H3736B0 +3736B0:lA8:erl_ddll|H3736C0 +3736C0:lA8:erl_epmd|H3736D0 +3736D0:lAA:erts_debug|H3736E0 +3736E0:lA7:gen_tcp|H3736F0 +3736F0:lA7:gen_udp|H373700 +373700:lA9:prim_inet|H373708 +373708:lA4:inet|H373710 +373710:lA7:inet_db|H373718 +373718:lA8:inet_dns|H373720 +373720:lAA:inet_parse|H373728 +373728:lA8:inet_res|H373730 +373730:lA8:inet_tcp|H373738 +373738:lA8:inet_udp|H373740 +373740:lA3:pg2|H373748 +373748:lA9:seq_trace|H373750 +373750:lA6:socks5|H373758 +373758:lAB:socks5_auth|H373760 +373760:lAA:socks5_tcp|H373768 +373768:lAA:socks5_udp|H373770 +373770:lAF:wrap_log_reader|H373778 +373778:lA4:zlib|H373780 +373780:lA9:otp_ring0|N +373118:lH373148|H373154 +373148:t2:AA:registered,H37317C +37317C:lA16:application_controller|H3731B8 +3731B8:lA9:erl_reply|H3731F4 +3731F4:lA4:auth|H373230 +373230:lAB:boot_server|H37326C +37326C:lAB:code_server|H3732AC +3732AC:lAF:disk_log_server|H3732E0 +3732E0:lAC:disk_log_sup|H37330C +37330C:lAF:erl_prim_loader|H373338 +373338:lAC:error_logger|H373358 +373358:lAB:file_server|H373378 +373378:lAD:file_server_2|H373398 +373398:lAF:fixtable_server|H3733B0 +3733B0:lAC:global_group|H3733C8 +3733C8:lA12:global_name_server|H3733E0 +3733E0:lA5:heart|H3733F8 +3733F8:lA4:init|H373410 +373410:lAD:kernel_config|H373428 +373428:lAA:kernel_sup|H373440 +373440:lAA:net_kernel|H373458 +373458:lA7:net_sup|H373470 +373470:lA3:rex|H373488 +373488:lA4:user|H3734A0 +3734A0:lA9:os_server|H3734B8 +3734B8:lAB:ddll_server|H3734D0 +3734D0:lA8:erl_epmd|H3734E8 +3734E8:lA7:inet_db|H373500 +373500:lA3:pg2|N +373154:lH373184|H373190 +373184:t2:AC:applications,N +373190:lH3731C0|H3731CC +3731C0:t2:A15:included_applications,N +3731CC:lH3731FC|H373208 +3731FC:t2:A3:env,H373238 +373238:lH373274|N +373274:t2:AC:error_logger,A3:tty +373208:lH373240|H37324C +373240:t2:AC:start_phases,A9:undefined +37324C:lH373280|H37328C +373280:t2:A4:maxT,A8:infinity +37328C:lH3732B4|H3732C0 +3732B4:t2:A4:maxP,A8:infinity +3732C0:lH3732E8|N +3732E8:t2:A3:mod,H373314 +373314:t2:A6:kernel,N +373048:lN|N +372E4C:t2:AD:$initial_call,H372EE4 +372EE4:t3:A3:gen,A7:init_it,H372ED0 +372E58:t2:AA:$ancestors,H372EF4 +372EF4:lP<0.1.0>|N +=proc_dictionary:<0.7.0> +H369B78 +H369B5C +=proc_stack:<0.7.0> +369d64:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:H369C2C +y1:P<0.5.0> +369d70:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A12:application_master +y2:A4:init +y3:H369B2C +=proc_heap:<0.7.0> +369C2C:t6:A5:state,P<0.8.0>,H3697B0,N,I0,P<0.0.0> +3697B0:t9:A9:appl_data,A6:kernel,H369B14,A9:undefined,H3697D8,H369A3C,N,A8:infinity,A8:infinity +369A3C:lAB:application|H369A34 +369A34:lA16:application_controller|H369A2C +369A2C:lA12:application_master|H369A24 +369A24:lA13:application_starter|H369A1C +369A1C:lA4:auth|H369A14 +369A14:lA4:code|H369A0C +369A0C:lA8:code_aux|H369A04 +369A04:lA8:packages|H3699FC +3699FC:lAB:code_server|H3699F4 +3699F4:lA9:dist_util|H3699EC +3699EC:lAF:erl_boot_server|H3699E4 +3699E4:lA10:erl_distribution|H3699DC +3699DC:lAF:erl_prim_loader|H3699D4 +3699D4:lA9:erl_reply|H3699CC +3699CC:lA6:erlang|H3699C4 +3699C4:lAD:error_handler|H3699BC +3699BC:lAC:error_logger|H3699B4 +3699B4:lA4:file|H3699AC +3699AC:lAB:file_server|H3699A4 +3699A4:lAF:old_file_server|H36999C +36999C:lAE:file_io_server|H369994 +369994:lA9:prim_file|H36998C +36998C:lA6:global|H369984 +369984:lAC:global_group|H36997C +36997C:lAD:global_search|H369974 +369974:lA5:group|H36996C +36996C:lA5:heart|H369964 +369964:lA13:hipe_unified_loader|H36995C +36995C:lA11:hipe_sparc_loader|H369954 +369954:lAF:hipe_x86_loader|H36994C +36994C:lA9:inet6_tcp|H369944 +369944:lAE:inet6_tcp_dist|H36993C +36993C:lA9:inet6_udp|H369934 +369934:lAB:inet_config|H36992C +36992C:lAA:inet_hosts|H369924 +369924:lA13:inet_gethost_native|H36991C +36991C:lAD:inet_tcp_dist|H369914 +369914:lA4:init|H36990C +36990C:lA6:kernel|H369904 +369904:lAD:kernel_config|H3698FC +3698FC:lA3:net|H3698F4 +3698F4:lA7:net_adm|H3698EC +3698EC:lAA:net_kernel|H3698E4 +3698E4:lA2:os|H3698DC +3698DC:lA8:ram_file|H3698D4 +3698D4:lA3:rpc|H3698CC +3698CC:lA4:user|H3698C4 +3698C4:lA8:user_drv|H3698BC +3698BC:lA8:user_sup|H3698B4 +3698B4:lA8:disk_log|H3698AC +3698AC:lAA:disk_log_1|H3698A4 +3698A4:lAF:disk_log_server|H36989C +36989C:lAC:disk_log_sup|H369894 +369894:lA7:dist_ac|H36988C +36988C:lA8:erl_ddll|H369884 +369884:lA8:erl_epmd|H36987C +36987C:lAA:erts_debug|H369874 +369874:lA7:gen_tcp|H36986C +36986C:lA7:gen_udp|H369864 +369864:lA9:prim_inet|H36985C +36985C:lA4:inet|H369854 +369854:lA7:inet_db|H36984C +36984C:lA8:inet_dns|H369844 +369844:lAA:inet_parse|H36983C +36983C:lA8:inet_res|H369834 +369834:lA8:inet_tcp|H36982C +36982C:lA8:inet_udp|H369824 +369824:lA3:pg2|H36981C +36981C:lA9:seq_trace|H369814 +369814:lA6:socks5|H36980C +36980C:lAB:socks5_auth|H369804 +369804:lAA:socks5_tcp|H3697FC +3697FC:lAA:socks5_udp|H3697F4 +3697F4:lAF:wrap_log_reader|H3697EC +3697EC:lA4:zlib|H3697E4 +3697E4:lA9:otp_ring0|N +3697D8:t2:A6:kernel,N +369B14:lA16:application_controller|H369B0C +369B0C:lA9:erl_reply|H369B04 +369B04:lA4:auth|H369AFC +369AFC:lAB:boot_server|H369AF4 +369AF4:lAB:code_server|H369AEC +369AEC:lAF:disk_log_server|H369AE4 +369AE4:lAC:disk_log_sup|H369ADC +369ADC:lAF:erl_prim_loader|H369AD4 +369AD4:lAC:error_logger|H369ACC +369ACC:lAB:file_server|H369AC4 +369AC4:lAD:file_server_2|H369ABC +369ABC:lAF:fixtable_server|H369AB4 +369AB4:lAC:global_group|H369AAC +369AAC:lA12:global_name_server|H369AA4 +369AA4:lA5:heart|H369A9C +369A9C:lA4:init|H369A94 +369A94:lAD:kernel_config|H369A8C +369A8C:lAA:kernel_sup|H369A84 +369A84:lAA:net_kernel|H369A7C +369A7C:lA7:net_sup|H369A74 +369A74:lA3:rex|H369A6C +369A6C:lA4:user|H369A64 +369A64:lA9:os_server|H369A5C +369A5C:lAB:ddll_server|H369A54 +369A54:lA8:erl_epmd|H369A4C +369A4C:lA7:inet_db|H369A44 +369A44:lA3:pg2|N +369B2C:lP<0.5.0>|H369B24 +369B24:lP<0.6.0>|H3697A8 +3697A8:lH3697B0|H369B1C +369B1C:lA6:normal|N +369B78:t2:AD:$initial_call,H369B68 +369B68:t3:A12:application_master,A4:init,H369B2C +369B5C:t2:AA:$ancestors,H369B54 +369B54:lP<0.6.0>|N +=proc_stack:<0.8.0> +384ec0:SReturn addr 0x156F90 (<terminate process normally>) +y0:H384BDC +y1:A6:kernel +y2:P<0.9.0> +y3:P<0.7.0> +=proc_heap:<0.8.0> +384BDC:t2:A5:state,A3:tty +=proc_dictionary:<0.9.0> +H376850 +H37685C +=proc_stack:<0.9.0> +36bde8:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AA:supervisor +y3:H36B8E8 +y4:AA:kernel_sup +y5:P<0.8.0> +36be04:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H3768D4 +=proc_heap:<0.9.0> +36B8E8:tA:A5:state,H376868,AB:one_for_all,H36B8D4,N,I0,I1,N,A6:kernel,N +36B8D4:lH36B8B0|H36B6E8 +36B8B0:t8:A5:child,P<0.24.0>,AF:kernel_safe_sup,H376BF0,A9:permanent,A8:infinity,AA:supervisor,H376C00 +376C00:lA6:kernel|N +376BF0:t3:AA:supervisor,AA:start_link,H376C08 +376C08:lH376C10|H376C1C +376C10:t2:A5:local,AF:kernel_safe_sup +376C1C:lA6:kernel|H376C24 +376C24:lA4:safe|N +36B6E8:lH36B6C4|H36B490 +36B6C4:t8:A5:child,P<0.23.0>,AD:kernel_config,H376BB4,A9:permanent,I2000,A6:worker,H376BC4 +376BC4:lAD:kernel_config|N +376BB4:t3:AD:kernel_config,AA:start_link,N +36B490:lH36B498|H36B4BC +36B498:t8:A5:child,P<0.19.0>,A4:user,H376B70,A9:temporary,I2000,AA:supervisor,H376B80 +376B80:lA8:user_sup|N +376B70:t3:A8:user_sup,A5:start,N +36B4BC:lH36B4C4|H376CB0 +36B4C4:t8:A5:child,P<0.18.0>,AB:code_server,H376B0C,A9:permanent,I2000,A6:worker,H376B1C +376B1C:lA4:code|N +376B0C:t3:A4:code,AA:start_link,N +376CB0:lH376CB8|H376CDC +376CB8:t8:A5:child,P<0.17.0>,AB:file_server,H376AB8,A9:permanent,I2000,A6:worker,H376AC8 +376AC8:lAF:old_file_server|N +376AB8:t3:AF:old_file_server,AA:start_link,N +376CDC:lH376CE4|H376C2C +376CE4:t8:A5:child,P<0.16.0>,AD:file_server_2,H376A58,A9:permanent,I2000,A6:worker,H376A68 +376A68:lA4:file|H376AB0 +376AB0:lAB:file_server|H376B04 +376B04:lAE:file_io_server|H376B68 +376B68:lA9:prim_file|N +376A58:t3:AB:file_server,AA:start_link,N +376C2C:lH376C34|H376C58 +376C34:t8:A5:child,P<0.15.0>,AC:global_group,H3769F4,A9:permanent,I2000,A6:worker,H376A04 +376A04:lAC:global_group|N +3769F4:t3:AC:global_group,AA:start_link,N +376C58:lH376C60|H376C84 +376C60:t8:A5:child,A9:undefined,A7:net_sup,H37696C,A9:permanent,A8:infinity,AA:supervisor,H37697C +37697C:lA10:erl_distribution|N +37696C:t3:A10:erl_distribution,AA:start_link,N +376C84:lH376C8C|H3768A0 +376C8C:t8:A5:child,P<0.14.0>,A7:inet_db,H3768F4,A9:permanent,I2000,A6:worker,H376904 +376904:lA7:inet_db|N +3768F4:t3:A7:inet_db,AA:start_link,N +3768A0:lH376938|H37695C +376938:t8:A5:child,P<0.11.0>,A12:global_name_server,H3769B0,A9:permanent,I2000,A6:worker,H3769C0 +3769C0:lA6:global|N +3769B0:t3:A6:global,AA:start_link,N +37695C:lH3769C8|N +3769C8:t8:A5:child,P<0.10.0>,A3:rex,H376A38,A9:permanent,I2000,A6:worker,H376A48 +376A48:lA3:rpc|N +376A38:t3:A3:rpc,AA:start_link,N +376868:t2:A5:local,AA:kernel_sup +3768D4:lAA:gen_server|H376964 +376964:lP<0.8.0>|H3769EC +3769EC:lP<0.8.0>|H376A50 +376A50:lH376A9C|H376AA8 +376A9C:t2:A5:local,AA:kernel_sup +376AA8:lAA:supervisor|H376AFC +376AFC:lH376B50|H376B60 +376B50:t3:H376868,A6:kernel,N +376B60:lN|N +376850:t2:AD:$initial_call,H3768DC +3768DC:t3:A3:gen,A7:init_it,H3768D4 +37685C:t2:AA:$ancestors,H3768EC +3768EC:lP<0.8.0>|N +=proc_dictionary:<0.10.0> +H367A10 +H3679F4 +=proc_stack:<0.10.0> +367cec:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A3:rpc +y3:H367AA8 +y4:A3:rex +y5:P<0.9.0> +367d08:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H3679C4 +=proc_heap:<0.10.0> +367AA8:t2:I0,A3:nil +3679C4:lAA:gen_server|H3679BC +3679BC:lP<0.9.0>|H3679B4 +3679B4:lP<0.9.0>|H367988 +367988:lH367990|H3679AC +367990:t2:A5:local,A3:rex +3679AC:lA3:rpc|H3679A4 +3679A4:lN|H36799C +36799C:lN|N +367A10:t2:AD:$initial_call,H367A00 +367A00:t3:A3:gen,A7:init_it,H3679C4 +3679F4:t2:AA:$ancestors,H3679EC +3679EC:lAA:kernel_sup|H3679CC +3679CC:lP<0.8.0>|N +=proc_dictionary:<0.11.0> +H36ADD8 +H36ADBC +=proc_stack:<0.11.0> +36b0b4:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A6:global +y3:H36AF0C +y4:A12:global_name_server +y5:P<0.9.0> +36b0d0:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H36AD8C +=proc_heap:<0.11.0> +36AF0C:t9:A5:state,A4:true,N,N,N,N,AD:nonode@nohost,P<0.12.0>,P<0.13.0> +36AD8C:lAA:gen_server|H36AD84 +36AD84:lP<0.9.0>|H36AD7C +36AD7C:lP<0.9.0>|H36AD50 +36AD50:lH36AD58|H36AD74 +36AD58:t2:A5:local,A12:global_name_server +36AD74:lA6:global|H36AD6C +36AD6C:lN|H36AD64 +36AD64:lN|N +36ADD8:t2:AD:$initial_call,H36ADC8 +36ADC8:t3:A3:gen,A7:init_it,H36AD8C +36ADBC:t2:AA:$ancestors,H36ADB4 +36ADB4:lAA:kernel_sup|H36AD94 +36AD94:lP<0.8.0>|N +=proc_stack:<0.12.0> +36921c:SReturn addr 0x261184 (global:init_the_locker/1 + 112) +y0:N +y1:N +y2:N +y3:N +y4:N +y5:N +y6:A8:infinity +y7:H368EB0 +y8:P<0.11.0> +369244:SReturn addr 0x156F90 (<terminate process normally>) +y0:N +=proc_heap:<0.12.0> +368EB0:t3:A5:multi,A9:undefined,N +=proc_stack:<0.13.0> +3695d0:SReturn addr 0x2651AC (global:loop_the_deleter/1 + 36) +y0:A8:infinity +y1:N +y2:P<0.11.0> +3695e0:SReturn addr 0x2654F8 (global:'-start_the_deleter/1-fun-0-'/1 + 20) +y0:N +y1:N +y2:P<0.11.0> +3695f0:SReturn addr 0x156F90 (<terminate process normally>) +=proc_heap:<0.13.0> +=proc_dictionary:<0.14.0> +H36A998 +H36A9A4 +=proc_stack:<0.14.0> +372e0c:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A7:inet_db +y3:H36A9B0 +y4:A7:inet_db +y5:P<0.9.0> +372e28:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H36A9C8 +=proc_heap:<0.14.0> +36A9B0:t5:A5:state,A7:inet_db,AA:inet_cache,AA:inet_hosts,H36A9E8 +36A9E8:E21:8372000364000D6E6F6E6F6465406E6F686F737400000000060000000000000000 +36A9C8:lAA:gen_server|H36A9F8 +36A9F8:lP<0.9.0>|H36AA08 +36AA08:lP<0.9.0>|H36AA10 +36AA10:lH36AA18|H36AA24 +36AA18:t2:A5:local,A7:inet_db +36AA24:lA7:inet_db|H36AA2C +36AA2C:lN|H36AA34 +36AA34:lN|N +36A998:t2:AD:$initial_call,H36A9D0 +36A9D0:t3:A3:gen,A7:init_it,H36A9C8 +36A9A4:t2:AA:$ancestors,H36A9E0 +36A9E0:lAA:kernel_sup|H36AA00 +36AA00:lP<0.8.0>|N +=proc_dictionary:<0.15.0> +H372788 +H3727F8 +H37276C +H37280C +H372820 +=proc_stack:<0.15.0> +372a64:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AC:global_group +y3:H3728C8 +y4:AC:global_group +y5:P<0.9.0> +372a80:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H37273C +=proc_heap:<0.15.0> +3728C8:tC:A5:state,A7:no_conf,A4:true,N,N,N,N,N,AD:nonode@nohost,N,A6:normal,A6:normal +37273C:lAA:gen_server|H372734 +372734:lP<0.9.0>|H37272C +37272C:lP<0.9.0>|H372700 +372700:lH372708|H372724 +372708:t2:A5:local,AC:global_group +372724:lAC:global_group|H37271C +37271C:lN|H372714 +372714:lN|N +372788:t2:AD:$initial_call,H372778 +372778:t3:A3:gen,A7:init_it,H37273C +3727F8:t2:A10:registered_names,H3727F0 +3727F0:lA9:undefined|N +37276C:t2:AA:$ancestors,H372764 +372764:lAA:kernel_sup|H372744 +372744:lP<0.8.0>|N +37280C:t2:A4:send,H372804 +372804:lA9:undefined|N +372820:t2:AC:whereis_name,H372818 +372818:lA9:undefined|N +=proc_dictionary:<0.16.0> +H37B918 +H37B924 +=proc_stack:<0.16.0> +3d303c:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AB:file_server +y3:p<0.4> +y4:AD:file_server_2 +y5:P<0.9.0> +3d3058:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H37B930 +=proc_heap:<0.16.0> +37B930:lAA:gen_server|H37B950 +37B950:lP<0.9.0>|H37B960 +37B960:lP<0.9.0>|H37B968 +37B968:lH37B970|H37B97C +37B970:t2:A5:local,AD:file_server_2 +37B97C:lAB:file_server|H37B984 +37B984:lN|H37B98C +37B98C:lN|N +37B918:t2:AD:$initial_call,H37B938 +37B938:t3:A3:gen,A7:init_it,H37B930 +37B924:t2:AA:$ancestors,H37B948 +37B948:lAA:kernel_sup|H37B958 +37B958:lP<0.8.0>|N +=proc_stack:<0.17.0> +3763cc:SReturn addr 0x156F90 (<terminate process normally>) +y0:H376084 +y1:P<0.16.0> +y2:P<0.9.0> +=proc_heap:<0.17.0> +376084:E21:8372000364000D6E6F6E6F6465406E6F686F737400000000160000000000000000 +=proc_stack:<0.18.0> +3b98e8:SReturn addr 0x156F90 (<terminate process normally>) +y0:H38AE84 +y1:P<0.9.0> +=proc_heap:<0.18.0> +38AE84:t8:A5:state,P<0.9.0>,H3873BC,H38AEB8,I9,I10,A8:no_cache,AB:interactive +38AEB8:lH3873D4|H38AEE0 +3873D4:lI46|N +38AEE0:lH3873EC|H38AF10 +3873EC:lI47|H387404 +387404:lI99|H387424 +387424:lI108|H38744C +38744C:lI101|H38747C +38747C:lI97|H3874B4 +3874B4:lI114|H3874F4 +3874F4:lI99|H38753C +38753C:lI97|H38758C +38758C:lI115|H3875E4 +3875E4:lI101|H387644 +387644:lI47|H3876AC +3876AC:lI111|H38771C +38771C:lI116|H387794 +387794:lI112|H387814 +387814:lI47|H38789C +38789C:lI101|H38792C +38792C:lI114|H3879BC +3879BC:lI116|H387A54 +387A54:lI115|H387AF4 +387AF4:lI47|H387B9C +387B9C:lI108|H387C4C +387C4C:lI105|H387D04 +387D04:lI98|H387DC4 +387DC4:lI47|H387E8C +387E8C:lI107|H387F5C +387F5C:lI101|H388034 +388034:lI114|H388114 +388114:lI110|H3881FC +3881FC:lI101|H3882EC +3882EC:lI108|H3883E4 +3883E4:lI47|H3884E4 +3884E4:lI101|H3885EC +3885EC:lI98|H3886FC +3886FC:lI105|H388814 +388814:lI110|N +38AF10:lH38740C|H38AF48 +38740C:lI47|H38742C +38742C:lI99|H387454 +387454:lI108|H387484 +387484:lI101|H3874BC +3874BC:lI97|H3874FC +3874FC:lI114|H387544 +387544:lI99|H387594 +387594:lI97|H3875EC +3875EC:lI115|H38764C +38764C:lI101|H3876B4 +3876B4:lI47|H387724 +387724:lI111|H38779C +38779C:lI116|H38781C +38781C:lI112|H3878A4 +3878A4:lI47|H387934 +387934:lI101|H3879C4 +3879C4:lI114|H387A5C +387A5C:lI116|H387AFC +387AFC:lI115|H387BA4 +387BA4:lI47|H387C54 +387C54:lI108|H387D0C +387D0C:lI105|H387DCC +387DCC:lI98|H387E94 +387E94:lI47|H387F64 +387F64:lI115|H38803C +38803C:lI116|H38811C +38811C:lI100|H388204 +388204:lI108|H3882F4 +3882F4:lI105|H3883EC +3883EC:lI98|H3884EC +3884EC:lI47|H3885F4 +3885F4:lI101|H388704 +388704:lI98|H38881C +38881C:lI105|H38892C +38892C:lI110|N +38AF48:lH387434|H38AF70 +387434:lI47|H38745C +38745C:lI99|H38748C +38748C:lI108|H3874C4 +3874C4:lI101|H387504 +387504:lI97|H38754C +38754C:lI114|H38759C +38759C:lI99|H3875F4 +3875F4:lI97|H387654 +387654:lI115|H3876BC +3876BC:lI101|H38772C +38772C:lI47|H3877A4 +3877A4:lI111|H387824 +387824:lI116|H3878AC +3878AC:lI112|H38793C +38793C:lI47|H3879CC +3879CC:lI101|H387A64 +387A64:lI114|H387B04 +387B04:lI116|H387BAC +387BAC:lI115|H387C5C +387C5C:lI47|H387D14 +387D14:lI108|H387DD4 +387DD4:lI105|H387E9C +387E9C:lI98|H387F6C +387F6C:lI47|H388044 +388044:lI119|H388124 +388124:lI101|H38820C +38820C:lI98|H3882FC +3882FC:lI116|H3883F4 +3883F4:lI111|H3884F4 +3884F4:lI111|H3885FC +3885FC:lI108|H38870C +38870C:lI47|H388824 +388824:lI101|H388934 +388934:lI98|H388A44 +388A44:lI105|H388B54 +388B54:lI110|N +38AF70:lH387464|H38AF98 +387464:lI47|H387494 +387494:lI99|H3874CC +3874CC:lI108|H38750C +38750C:lI101|H387554 +387554:lI97|H3875A4 +3875A4:lI114|H3875FC +3875FC:lI99|H38765C +38765C:lI97|H3876C4 +3876C4:lI115|H387734 +387734:lI101|H3877AC +3877AC:lI47|H38782C +38782C:lI111|H3878B4 +3878B4:lI116|H387944 +387944:lI112|H3879D4 +3879D4:lI47|H387A6C +387A6C:lI101|H387B0C +387B0C:lI114|H387BB4 +387BB4:lI116|H387C64 +387C64:lI115|H387D1C +387D1C:lI47|H387DDC +387DDC:lI108|H387EA4 +387EA4:lI105|H387F74 +387F74:lI98|H38804C +38804C:lI47|H38812C +38812C:lI116|H388214 +388214:lI118|H388304 +388304:lI47|H3883FC +3883FC:lI101|H3884FC +3884FC:lI98|H388604 +388604:lI105|H388714 +388714:lI110|N +38AF98:lH38749C|H38AFC0 +38749C:lI47|H3874D4 +3874D4:lI99|H387514 +387514:lI108|H38755C +38755C:lI101|H3875AC +3875AC:lI97|H387604 +387604:lI114|H387664 +387664:lI99|H3876CC +3876CC:lI97|H38773C +38773C:lI115|H3877B4 +3877B4:lI101|H387834 +387834:lI47|H3878BC +3878BC:lI111|H38794C +38794C:lI116|H3879DC +3879DC:lI112|H387A74 +387A74:lI47|H387B14 +387B14:lI101|H387BBC +387BBC:lI114|H387C6C +387C6C:lI116|H387D24 +387D24:lI115|H387DE4 +387DE4:lI47|H387EAC +387EAC:lI108|H387F7C +387F7C:lI105|H388054 +388054:lI98|H388134 +388134:lI47|H38821C +38821C:lI116|H38830C +38830C:lI115|H388404 +388404:lI112|H388504 +388504:lI47|H38860C +38860C:lI101|H38871C +38871C:lI98|H38882C +38882C:lI105|H38893C +38893C:lI110|N +38AFC0:lH3874DC|H38AFE8 +3874DC:lI47|H38751C +38751C:lI99|H387564 +387564:lI108|H3875B4 +3875B4:lI101|H38760C +38760C:lI97|H38766C +38766C:lI114|H3876D4 +3876D4:lI99|H387744 +387744:lI97|H3877BC +3877BC:lI115|H38783C +38783C:lI101|H3878C4 +3878C4:lI47|H387954 +387954:lI111|H3879E4 +3879E4:lI116|H387A7C +387A7C:lI112|H387B1C +387B1C:lI47|H387BC4 +387BC4:lI101|H387C74 +387C74:lI114|H387D2C +387D2C:lI116|H387DEC +387DEC:lI115|H387EB4 +387EB4:lI47|H387F84 +387F84:lI108|H38805C +38805C:lI105|H38813C +38813C:lI98|H388224 +388224:lI47|H388314 +388314:lI116|H38840C +38840C:lI111|H38850C +38850C:lI111|H388614 +388614:lI108|H388724 +388724:lI115|H388834 +388834:lI47|H388944 +388944:lI101|H388A4C +388A4C:lI98|H388B5C +388B5C:lI105|H388C6C +388C6C:lI110|N +38AFE8:lH387524|H38B008 +387524:lI47|H38756C +38756C:lI99|H3875BC +3875BC:lI108|H387614 +387614:lI101|H387674 +387674:lI97|H3876DC +3876DC:lI114|H38774C +38774C:lI99|H3877C4 +3877C4:lI97|H387844 +387844:lI115|H3878CC +3878CC:lI101|H38795C +38795C:lI47|H3879EC +3879EC:lI111|H387A84 +387A84:lI116|H387B24 +387B24:lI112|H387BCC +387BCC:lI47|H387C7C +387C7C:lI101|H387D34 +387D34:lI114|H387DF4 +387DF4:lI116|H387EBC +387EBC:lI115|H387F8C +387F8C:lI47|H388064 +388064:lI108|H388144 +388144:lI105|H38822C +38822C:lI98|H38831C +38831C:lI47|H388414 +388414:lI116|H388514 +388514:lI111|H38861C +38861C:lI111|H38872C +38872C:lI108|H38883C +38883C:lI98|H38894C +38894C:lI97|H388A54 +388A54:lI114|H388B64 +388B64:lI47|H388C74 +388C74:lI101|H388D84 +388D84:lI98|H388E9C +388E9C:lI105|H388FB4 +388FB4:lI110|N +38B008:lH387574|H38B018 +387574:lI47|H3875C4 +3875C4:lI99|H38761C +38761C:lI108|H38767C +38767C:lI101|H3876E4 +3876E4:lI97|H387754 +387754:lI114|H3877CC +3877CC:lI99|H38784C +38784C:lI97|H3878D4 +3878D4:lI115|H387964 +387964:lI101|H3879F4 +3879F4:lI47|H387A8C +387A8C:lI111|H387B2C +387B2C:lI116|H387BD4 +387BD4:lI112|H387C84 +387C84:lI47|H387D3C +387D3C:lI101|H387DFC +387DFC:lI114|H387EC4 +387EC4:lI116|H387F94 +387F94:lI115|H38806C +38806C:lI47|H38814C +38814C:lI108|H388234 +388234:lI105|H388324 +388324:lI98|H38841C +38841C:lI47|H38851C +38851C:lI116|H388624 +388624:lI101|H388734 +388734:lI115|H388844 +388844:lI116|H388954 +388954:lI95|H388A5C +388A5C:lI115|H388B6C +388B6C:lI101|H388C7C +388C7C:lI114|H388D8C +388D8C:lI118|H388EA4 +388EA4:lI101|H388FBC +388FBC:lI114|H3890D4 +3890D4:lI47|H3891EC +3891EC:lI101|H3892FC +3892FC:lI98|H38940C +38940C:lI105|H38951C +38951C:lI110|N +38B018:lH3875CC|H38AE7C +3875CC:lI47|H387624 +387624:lI99|H387684 +387684:lI108|H3876EC +3876EC:lI101|H38775C +38775C:lI97|H3877D4 +3877D4:lI114|H387854 +387854:lI99|H3878DC +3878DC:lI97|H38796C +38796C:lI115|H3879FC +3879FC:lI101|H387A94 +387A94:lI47|H387B34 +387B34:lI111|H387BDC +387BDC:lI116|H387C8C +387C8C:lI112|H387D44 +387D44:lI47|H387E04 +387E04:lI101|H387ECC +387ECC:lI114|H387F9C +387F9C:lI116|H388074 +388074:lI115|H388154 +388154:lI47|H38823C +38823C:lI108|H38832C +38832C:lI105|H388424 +388424:lI98|H388524 +388524:lI47|H38862C +38862C:lI115|H38873C +38873C:lI115|H38884C +38884C:lI108|H38895C +38895C:lI47|H388A64 +388A64:lI101|H388B74 +388B74:lI98|H388C84 +388C84:lI105|H388D94 +388D94:lI110|N +38AE7C:lH38762C|H38AEB0 +38762C:lI47|H38768C +38768C:lI99|H3876F4 +3876F4:lI108|H387764 +387764:lI101|H3877DC +3877DC:lI97|H38785C +38785C:lI114|H3878E4 +3878E4:lI99|H387974 +387974:lI97|H387A04 +387A04:lI115|H387A9C +387A9C:lI101|H387B3C +387B3C:lI47|H387BE4 +387BE4:lI111|H387C94 +387C94:lI116|H387D4C +387D4C:lI112|H387E0C +387E0C:lI47|H387ED4 +387ED4:lI101|H387FA4 +387FA4:lI114|H38807C +38807C:lI116|H38815C +38815C:lI115|H388244 +388244:lI47|H388334 +388334:lI108|H38842C +38842C:lI105|H38852C +38852C:lI98|H388634 +388634:lI47|H388744 +388744:lI115|H388854 +388854:lI110|H388964 +388964:lI109|H388A6C +388A6C:lI112|H388B7C +388B7C:lI47|H388C8C +388C8C:lI101|H388D9C +388D9C:lI98|H388EAC +388EAC:lI105|H388FC4 +388FC4:lI110|N +38AEB0:lH387694|H38AED8 +387694:lI47|H3876FC +3876FC:lI99|H38776C +38776C:lI108|H3877E4 +3877E4:lI101|H387864 +387864:lI97|H3878EC +3878EC:lI114|H38797C +38797C:lI99|H387A0C +387A0C:lI97|H387AA4 +387AA4:lI115|H387B44 +387B44:lI101|H387BEC +387BEC:lI47|H387C9C +387C9C:lI111|H387D54 +387D54:lI116|H387E14 +387E14:lI112|H387EDC +387EDC:lI47|H387FAC +387FAC:lI101|H388084 +388084:lI114|H388164 +388164:lI116|H38824C +38824C:lI115|H38833C +38833C:lI47|H388434 +388434:lI108|H388534 +388534:lI105|H38863C +38863C:lI98|H38874C +38874C:lI47|H38885C +38885C:lI115|H38896C +38896C:lI97|H388A74 +388A74:lI115|H388B84 +388B84:lI108|H388C94 +388C94:lI47|H388DA4 +388DA4:lI101|H388EB4 +388EB4:lI98|H388FCC +388FCC:lI105|H3890DC +3890DC:lI110|N +38AED8:lH387704|H38AF08 +387704:lI47|H387774 +387774:lI99|H3877EC +3877EC:lI108|H38786C +38786C:lI101|H3878F4 +3878F4:lI97|H387984 +387984:lI114|H387A14 +387A14:lI99|H387AAC +387AAC:lI97|H387B4C +387B4C:lI115|H387BF4 +387BF4:lI101|H387CA4 +387CA4:lI47|H387D5C +387D5C:lI111|H387E1C +387E1C:lI116|H387EE4 +387EE4:lI112|H387FB4 +387FB4:lI47|H38808C +38808C:lI101|H38816C +38816C:lI114|H388254 +388254:lI116|H388344 +388344:lI115|H38843C +38843C:lI47|H38853C +38853C:lI108|H388644 +388644:lI105|H388754 +388754:lI98|H388864 +388864:lI47|H388974 +388974:lI114|H388A7C +388A7C:lI117|H388B8C +388B8C:lI110|H388C9C +388C9C:lI116|H388DAC +388DAC:lI105|H388EBC +388EBC:lI109|H388FD4 +388FD4:lI101|H3890E4 +3890E4:lI95|H3891F4 +3891F4:lI116|H389304 +389304:lI111|H389414 +389414:lI111|H389524 +389524:lI108|H389624 +389624:lI115|H38971C +38971C:lI47|H389814 +389814:lI101|H38990C +38990C:lI98|H389A04 +389A04:lI105|H389AE4 +389AE4:lI110|N +38AF08:lH38777C|H38AF40 +38777C:lI47|H3877F4 +3877F4:lI99|H387874 +387874:lI108|H3878FC +3878FC:lI101|H38798C +38798C:lI97|H387A1C +387A1C:lI114|H387AB4 +387AB4:lI99|H387B54 +387B54:lI97|H387BFC +387BFC:lI115|H387CAC +387CAC:lI101|H387D64 +387D64:lI47|H387E24 +387E24:lI111|H387EEC +387EEC:lI116|H387FBC +387FBC:lI112|H388094 +388094:lI47|H388174 +388174:lI101|H38825C +38825C:lI114|H38834C +38834C:lI116|H388444 +388444:lI115|H388544 +388544:lI47|H38864C +38864C:lI108|H38875C +38875C:lI105|H38886C +38886C:lI98|H38897C +38897C:lI47|H388A84 +388A84:lI114|H388B94 +388B94:lI115|H388CA4 +388CA4:lI104|H388DB4 +388DB4:lI101|H388EC4 +388EC4:lI108|H388FDC +388FDC:lI108|H3890EC +3890EC:lI47|H3891FC +3891FC:lI101|H38930C +38930C:lI98|H38941C +38941C:lI105|H38952C +38952C:lI110|N +38AF40:lH3877FC|H38AF68 +3877FC:lI47|H38787C +38787C:lI99|H387904 +387904:lI108|H387994 +387994:lI101|H387A24 +387A24:lI97|H387ABC +387ABC:lI114|H387B5C +387B5C:lI99|H387C04 +387C04:lI97|H387CB4 +387CB4:lI115|H387D6C +387D6C:lI101|H387E2C +387E2C:lI47|H387EF4 +387EF4:lI111|H387FC4 +387FC4:lI116|H38809C +38809C:lI112|H38817C +38817C:lI47|H388264 +388264:lI101|H388354 +388354:lI114|H38844C +38844C:lI116|H38854C +38854C:lI115|H388654 +388654:lI47|H388764 +388764:lI108|H388874 +388874:lI105|H388984 +388984:lI98|H388A8C +388A8C:lI47|H388B9C +388B9C:lI112|H388CAC +388CAC:lI109|H388DBC +388DBC:lI97|H388ECC +388ECC:lI110|H388FE4 +388FE4:lI47|H3890F4 +3890F4:lI101|H389204 +389204:lI98|H389314 +389314:lI105|H389424 +389424:lI110|N +38AF68:lH387884|H38AF90 +387884:lI47|H38790C +38790C:lI99|H38799C +38799C:lI108|H387A2C +387A2C:lI101|H387AC4 +387AC4:lI97|H387B64 +387B64:lI114|H387C0C +387C0C:lI99|H387CBC +387CBC:lI97|H387D74 +387D74:lI115|H387E34 +387E34:lI101|H387EFC +387EFC:lI47|H387FCC +387FCC:lI111|H3880A4 +3880A4:lI116|H388184 +388184:lI112|H38826C +38826C:lI47|H38835C +38835C:lI101|H388454 +388454:lI114|H388554 +388554:lI116|H38865C +38865C:lI115|H38876C +38876C:lI47|H38887C +38887C:lI108|H38898C +38898C:lI105|H388A94 +388A94:lI98|H388BA4 +388BA4:lI47|H388CB4 +388CB4:lI112|H388DC4 +388DC4:lI97|H388ED4 +388ED4:lI114|H388FEC +388FEC:lI115|H3890FC +3890FC:lI101|H38920C +38920C:lI116|H38931C +38931C:lI111|H38942C +38942C:lI111|H389534 +389534:lI108|H38962C +38962C:lI115|H389724 +389724:lI47|H38981C +38981C:lI101|H389914 +389914:lI98|H389A0C +389A0C:lI105|H389AEC +389AEC:lI110|N +38AF90:lH387914|H38AFB8 +387914:lI47|H3879A4 +3879A4:lI99|H387A34 +387A34:lI108|H387ACC +387ACC:lI101|H387B6C +387B6C:lI97|H387C14 +387C14:lI114|H387CC4 +387CC4:lI99|H387D7C +387D7C:lI97|H387E3C +387E3C:lI115|H387F04 +387F04:lI101|H387FD4 +387FD4:lI47|H3880AC +3880AC:lI111|H38818C +38818C:lI116|H388274 +388274:lI112|H388364 +388364:lI47|H38845C +38845C:lI101|H38855C +38855C:lI114|H388664 +388664:lI116|H388774 +388774:lI115|H388884 +388884:lI47|H388994 +388994:lI108|H388A9C +388A9C:lI105|H388BAC +388BAC:lI98|H388CBC +388CBC:lI47|H388DCC +388DCC:lI111|H388EDC +388EDC:lI116|H388FF4 +388FF4:lI112|H389104 +389104:lI95|H389214 +389214:lI109|H389324 +389324:lI105|H389434 +389434:lI98|H38953C +38953C:lI115|H389634 +389634:lI47|H38972C +38972C:lI101|H389824 +389824:lI98|H38991C +38991C:lI105|H389A14 +389A14:lI110|N +38AFB8:lH3879AC|H38AFE0 +3879AC:lI47|H387A3C +387A3C:lI99|H387AD4 +387AD4:lI108|H387B74 +387B74:lI101|H387C1C +387C1C:lI97|H387CCC +387CCC:lI114|H387D84 +387D84:lI99|H387E44 +387E44:lI97|H387F0C +387F0C:lI115|H387FDC +387FDC:lI101|H3880B4 +3880B4:lI47|H388194 +388194:lI111|H38827C +38827C:lI116|H38836C +38836C:lI112|H388464 +388464:lI47|H388564 +388564:lI101|H38866C +38866C:lI114|H38877C +38877C:lI116|H38888C +38888C:lI115|H38899C +38899C:lI47|H388AA4 +388AA4:lI108|H388BB4 +388BB4:lI105|H388CC4 +388CC4:lI98|H388DD4 +388DD4:lI47|H388EE4 +388EE4:lI111|H388FFC +388FFC:lI115|H38910C +38910C:lI95|H38921C +38921C:lI109|H38932C +38932C:lI111|H38943C +38943C:lI110|H389544 +389544:lI47|H38963C +38963C:lI101|H389734 +389734:lI98|H38982C +38982C:lI105|H389924 +389924:lI110|N +38AFE0:lH387A44|H38B000 +387A44:lI47|H387ADC +387ADC:lI99|H387B7C +387B7C:lI108|H387C24 +387C24:lI101|H387CD4 +387CD4:lI97|H387D8C +387D8C:lI114|H387E4C +387E4C:lI99|H387F14 +387F14:lI97|H387FE4 +387FE4:lI115|H3880BC +3880BC:lI101|H38819C +38819C:lI47|H388284 +388284:lI111|H388374 +388374:lI116|H38846C +38846C:lI112|H38856C +38856C:lI47|H388674 +388674:lI101|H388784 +388784:lI114|H388894 +388894:lI116|H3889A4 +3889A4:lI115|H388AAC +388AAC:lI47|H388BBC +388BBC:lI108|H388CCC +388CCC:lI105|H388DDC +388DDC:lI98|H388EEC +388EEC:lI47|H389004 +389004:lI111|H389114 +389114:lI114|H389224 +389224:lI98|H389334 +389334:lI101|H389444 +389444:lI114|H38954C +38954C:lI47|H389644 +389644:lI101|H38973C +38973C:lI98|H389834 +389834:lI105|H38992C +38992C:lI110|N +38B000:lH387AE4|H38B010 +387AE4:lI47|H387B84 +387B84:lI99|H387C2C +387C2C:lI108|H387CDC +387CDC:lI101|H387D94 +387D94:lI97|H387E54 +387E54:lI114|H387F1C +387F1C:lI99|H387FEC +387FEC:lI97|H3880C4 +3880C4:lI115|H3881A4 +3881A4:lI101|H38828C +38828C:lI47|H38837C +38837C:lI111|H388474 +388474:lI116|H388574 +388574:lI112|H38867C +38867C:lI47|H38878C +38878C:lI101|H38889C +38889C:lI114|H3889AC +3889AC:lI116|H388AB4 +388AB4:lI115|H388BC4 +388BC4:lI47|H388CD4 +388CD4:lI108|H388DE4 +388DE4:lI105|H388EF4 +388EF4:lI98|H38900C +38900C:lI47|H38911C +38911C:lI111|H38922C +38922C:lI100|H38933C +38933C:lI98|H38944C +38944C:lI99|H389554 +389554:lI47|H38964C +38964C:lI101|H389744 +389744:lI98|H38983C +38983C:lI105|H389934 +389934:lI110|N +38B010:lH387B8C|H38B020 +387B8C:lI47|H387C34 +387C34:lI99|H387CE4 +387CE4:lI108|H387D9C +387D9C:lI101|H387E5C +387E5C:lI97|H387F24 +387F24:lI114|H387FF4 +387FF4:lI99|H3880CC +3880CC:lI97|H3881AC +3881AC:lI115|H388294 +388294:lI101|H388384 +388384:lI47|H38847C +38847C:lI111|H38857C +38857C:lI116|H388684 +388684:lI112|H388794 +388794:lI47|H3888A4 +3888A4:lI101|H3889B4 +3889B4:lI114|H388ABC +388ABC:lI116|H388BCC +388BCC:lI115|H388CDC +388CDC:lI47|H388DEC +388DEC:lI108|H388EFC +388EFC:lI105|H389014 +389014:lI98|H389124 +389124:lI47|H389234 +389234:lI111|H389344 +389344:lI98|H389454 +389454:lI115|H38955C +38955C:lI101|H389654 +389654:lI114|H38974C +38974C:lI118|H389844 +389844:lI101|H38993C +38993C:lI114|H389A1C +389A1C:lI47|H389AF4 +389AF4:lI101|H389BBC +389BBC:lI98|H389C84 +389C84:lI105|H389D4C +389D4C:lI110|N +38B020:lH387C3C|H38B028 +387C3C:lI47|H387CEC +387CEC:lI99|H387DA4 +387DA4:lI108|H387E64 +387E64:lI101|H387F2C +387F2C:lI97|H387FFC +387FFC:lI114|H3880D4 +3880D4:lI99|H3881B4 +3881B4:lI97|H38829C +38829C:lI115|H38838C +38838C:lI101|H388484 +388484:lI47|H388584 +388584:lI111|H38868C +38868C:lI116|H38879C +38879C:lI112|H3888AC +3888AC:lI47|H3889BC +3889BC:lI101|H388AC4 +388AC4:lI114|H388BD4 +388BD4:lI116|H388CE4 +388CE4:lI115|H388DF4 +388DF4:lI47|H388F04 +388F04:lI108|H38901C +38901C:lI105|H38912C +38912C:lI98|H38923C +38923C:lI47|H38934C +38934C:lI109|H38945C +38945C:lI110|H389564 +389564:lI101|H38965C +38965C:lI115|H389754 +389754:lI105|H38984C +38984C:lI97|H389944 +389944:lI95|H389A24 +389A24:lI115|H389AFC +389AFC:lI101|H389BC4 +389BC4:lI115|H389C8C +389C8C:lI115|H389D54 +389D54:lI105|H389E14 +389E14:lI111|H389ECC +389ECC:lI110|H389F7C +389F7C:lI47|H38A01C +38A01C:lI101|H38A0AC +38A0AC:lI98|H38A12C +38A12C:lI105|H38A19C +38A19C:lI110|N +38B028:lH387CF4|H38B030 +387CF4:lI47|H387DAC +387DAC:lI99|H387E6C +387E6C:lI108|H387F34 +387F34:lI101|H388004 +388004:lI97|H3880DC +3880DC:lI114|H3881BC +3881BC:lI99|H3882A4 +3882A4:lI97|H388394 +388394:lI115|H38848C +38848C:lI101|H38858C +38858C:lI47|H388694 +388694:lI111|H3887A4 +3887A4:lI116|H3888B4 +3888B4:lI112|H3889C4 +3889C4:lI47|H388ACC +388ACC:lI101|H388BDC +388BDC:lI114|H388CEC +388CEC:lI116|H388DFC +388DFC:lI115|H388F0C +388F0C:lI47|H389024 +389024:lI108|H389134 +389134:lI105|H389244 +389244:lI98|H389354 +389354:lI47|H389464 +389464:lI109|H38956C +38956C:lI110|H389664 +389664:lI101|H38975C +38975C:lI115|H389854 +389854:lI105|H38994C +38994C:lI97|H389A2C +389A2C:lI47|H389B04 +389B04:lI101|H389BCC +389BCC:lI98|H389C94 +389C94:lI105|H389D5C +389D5C:lI110|N +38B030:lH387DB4|H38B038 +387DB4:lI47|H387E74 +387E74:lI99|H387F3C +387F3C:lI108|H38800C +38800C:lI101|H3880E4 +3880E4:lI97|H3881C4 +3881C4:lI114|H3882AC +3882AC:lI99|H38839C +38839C:lI97|H388494 +388494:lI115|H388594 +388594:lI101|H38869C +38869C:lI47|H3887AC +3887AC:lI111|H3888BC +3888BC:lI116|H3889CC +3889CC:lI112|H388AD4 +388AD4:lI47|H388BE4 +388BE4:lI101|H388CF4 +388CF4:lI114|H388E04 +388E04:lI116|H388F14 +388F14:lI115|H38902C +38902C:lI47|H38913C +38913C:lI108|H38924C +38924C:lI105|H38935C +38935C:lI98|H38946C +38946C:lI47|H389574 +389574:lI109|H38966C +38966C:lI110|H389764 +389764:lI101|H38985C +38985C:lI109|H389954 +389954:lI111|H389A34 +389A34:lI115|H389B0C +389B0C:lI121|H389BD4 +389BD4:lI110|H389C9C +389C9C:lI101|H389D64 +389D64:lI47|H389E1C +389E1C:lI101|H389ED4 +389ED4:lI98|H389F84 +389F84:lI105|H38A024 +38A024:lI110|N +38B038:lH387E7C|H38B040 +387E7C:lI47|H387F44 +387F44:lI99|H388014 +388014:lI108|H3880EC +3880EC:lI101|H3881CC +3881CC:lI97|H3882B4 +3882B4:lI114|H3883A4 +3883A4:lI99|H38849C +38849C:lI97|H38859C +38859C:lI115|H3886A4 +3886A4:lI101|H3887B4 +3887B4:lI47|H3888C4 +3888C4:lI111|H3889D4 +3889D4:lI116|H388ADC +388ADC:lI112|H388BEC +388BEC:lI47|H388CFC +388CFC:lI101|H388E0C +388E0C:lI114|H388F1C +388F1C:lI116|H389034 +389034:lI115|H389144 +389144:lI47|H389254 +389254:lI108|H389364 +389364:lI105|H389474 +389474:lI98|H38957C +38957C:lI47|H389674 +389674:lI109|H38976C +38976C:lI101|H389864 +389864:lI103|H38995C +38995C:lI97|H389A3C +389A3C:lI99|H389B14 +389B14:lI111|H389BDC +389BDC:lI47|H389CA4 +389CA4:lI101|H389D6C +389D6C:lI98|H389E24 +389E24:lI105|H389EDC +389EDC:lI110|N +38B040:lH387F4C|H38B048 +387F4C:lI47|H38801C +38801C:lI99|H3880F4 +3880F4:lI108|H3881D4 +3881D4:lI101|H3882BC +3882BC:lI97|H3883AC +3883AC:lI114|H3884A4 +3884A4:lI99|H3885A4 +3885A4:lI97|H3886AC +3886AC:lI115|H3887BC +3887BC:lI101|H3888CC +3888CC:lI47|H3889DC +3889DC:lI111|H388AE4 +388AE4:lI116|H388BF4 +388BF4:lI112|H388D04 +388D04:lI47|H388E14 +388E14:lI101|H388F24 +388F24:lI114|H38903C +38903C:lI116|H38914C +38914C:lI115|H38925C +38925C:lI47|H38936C +38936C:lI108|H38947C +38947C:lI105|H389584 +389584:lI98|H38967C +38967C:lI47|H389774 +389774:lI106|H38986C +38986C:lI105|H389964 +389964:lI110|H389A44 +389A44:lI116|H389B1C +389B1C:lI101|H389BE4 +389BE4:lI114|H389CAC +389CAC:lI102|H389D74 +389D74:lI97|H389E2C +389E2C:lI99|H389EE4 +389EE4:lI101|N +38B048:lH388024|H38B050 +388024:lI47|H3880FC +3880FC:lI99|H3881DC +3881DC:lI108|H3882C4 +3882C4:lI101|H3883B4 +3883B4:lI97|H3884AC +3884AC:lI114|H3885AC +3885AC:lI99|H3886B4 +3886B4:lI97|H3887C4 +3887C4:lI115|H3888D4 +3888D4:lI101|H3889E4 +3889E4:lI47|H388AEC +388AEC:lI111|H388BFC +388BFC:lI116|H388D0C +388D0C:lI112|H388E1C +388E1C:lI47|H388F2C +388F2C:lI101|H389044 +389044:lI114|H389154 +389154:lI116|H389264 +389264:lI115|H389374 +389374:lI47|H389484 +389484:lI108|H38958C +38958C:lI105|H389684 +389684:lI98|H38977C +38977C:lI47|H389874 +389874:lI105|H38996C +38996C:lI110|H389A4C +389A4C:lI101|H389B24 +389B24:lI116|H389BEC +389BEC:lI115|H389CB4 +389CB4:lI47|H389D7C +389D7C:lI101|H389E34 +389E34:lI98|H389EEC +389EEC:lI105|H389F8C +389F8C:lI110|N +38B050:lH388104|H38B058 +388104:lI47|H3881E4 +3881E4:lI99|H3882CC +3882CC:lI108|H3883BC +3883BC:lI101|H3884B4 +3884B4:lI97|H3885B4 +3885B4:lI114|H3886BC +3886BC:lI99|H3887CC +3887CC:lI97|H3888DC +3888DC:lI115|H3889EC +3889EC:lI101|H388AF4 +388AF4:lI47|H388C04 +388C04:lI111|H388D14 +388D14:lI116|H388E24 +388E24:lI112|H388F34 +388F34:lI47|H38904C +38904C:lI101|H38915C +38915C:lI114|H38926C +38926C:lI116|H38937C +38937C:lI115|H38948C +38948C:lI47|H389594 +389594:lI108|H38968C +38968C:lI105|H389784 +389784:lI98|H38987C +38987C:lI47|H389974 +389974:lI105|H389A54 +389A54:lI99|H389B2C +389B2C:lI47|H389BF4 +389BF4:lI101|H389CBC +389CBC:lI98|H389D84 +389D84:lI105|H389E3C +389E3C:lI110|N +38B058:lH3881EC|H38B060 +3881EC:lI47|H3882D4 +3882D4:lI99|H3883C4 +3883C4:lI108|H3884BC +3884BC:lI101|H3885BC +3885BC:lI97|H3886C4 +3886C4:lI114|H3887D4 +3887D4:lI99|H3888E4 +3888E4:lI97|H3889F4 +3889F4:lI115|H388AFC +388AFC:lI101|H388C0C +388C0C:lI47|H388D1C +388D1C:lI111|H388E2C +388E2C:lI116|H388F3C +388F3C:lI112|H389054 +389054:lI47|H389164 +389164:lI101|H389274 +389274:lI114|H389384 +389384:lI116|H389494 +389494:lI115|H38959C +38959C:lI47|H389694 +389694:lI108|H38978C +38978C:lI105|H389884 +389884:lI98|H38997C +38997C:lI47|H389A5C +389A5C:lI104|H389B34 +389B34:lI105|H389BFC +389BFC:lI112|H389CC4 +389CC4:lI101|H389D8C +389D8C:lI47|H389E44 +389E44:lI101|H389EF4 +389EF4:lI98|H389F94 +389F94:lI105|H38A02C +38A02C:lI110|N +38B060:lH3882DC|H38B068 +3882DC:lI47|H3883CC +3883CC:lI99|H3884C4 +3884C4:lI108|H3885C4 +3885C4:lI101|H3886CC +3886CC:lI97|H3887DC +3887DC:lI114|H3888EC +3888EC:lI99|H3889FC +3889FC:lI97|H388B04 +388B04:lI115|H388C14 +388C14:lI101|H388D24 +388D24:lI47|H388E34 +388E34:lI111|H388F44 +388F44:lI116|H38905C +38905C:lI112|H38916C +38916C:lI47|H38927C +38927C:lI101|H38938C +38938C:lI114|H38949C +38949C:lI116|H3895A4 +3895A4:lI115|H38969C +38969C:lI47|H389794 +389794:lI108|H38988C +38988C:lI105|H389984 +389984:lI98|H389A64 +389A64:lI47|H389B3C +389B3C:lI103|H389C04 +389C04:lI115|H389CCC +389CCC:lI47|H389D94 +389D94:lI101|H389E4C +389E4C:lI98|H389EFC +389EFC:lI105|H389F9C +389F9C:lI110|N +38B068:lH3883D4|H38B070 +3883D4:lI47|H3884CC +3884CC:lI99|H3885CC +3885CC:lI108|H3886D4 +3886D4:lI101|H3887E4 +3887E4:lI97|H3888F4 +3888F4:lI114|H388A04 +388A04:lI99|H388B0C +388B0C:lI97|H388C1C +388C1C:lI115|H388D2C +388D2C:lI101|H388E3C +388E3C:lI47|H388F4C +388F4C:lI111|H389064 +389064:lI116|H389174 +389174:lI112|H389284 +389284:lI47|H389394 +389394:lI101|H3894A4 +3894A4:lI114|H3895AC +3895AC:lI116|H3896A4 +3896A4:lI115|H38979C +38979C:lI47|H389894 +389894:lI108|H38998C +38998C:lI105|H389A6C +389A6C:lI98|H389B44 +389B44:lI47|H389C0C +389C0C:lI101|H389CD4 +389CD4:lI118|H389D9C +389D9C:lI97|H389E54 +389E54:lI47|H389F04 +389F04:lI101|H389FA4 +389FA4:lI98|H38A034 +38A034:lI105|H38A0B4 +38A0B4:lI110|N +38B070:lH3884D4|H38B078 +3884D4:lI47|H3885D4 +3885D4:lI99|H3886DC +3886DC:lI108|H3887EC +3887EC:lI101|H3888FC +3888FC:lI97|H388A0C +388A0C:lI114|H388B14 +388B14:lI99|H388C24 +388C24:lI97|H388D34 +388D34:lI115|H388E44 +388E44:lI101|H388F54 +388F54:lI47|H38906C +38906C:lI111|H38917C +38917C:lI116|H38928C +38928C:lI112|H38939C +38939C:lI47|H3894AC +3894AC:lI101|H3895B4 +3895B4:lI114|H3896AC +3896AC:lI116|H3897A4 +3897A4:lI115|H38989C +38989C:lI47|H389994 +389994:lI108|H389A74 +389A74:lI105|H389B4C +389B4C:lI98|H389C14 +389C14:lI47|H389CDC +389CDC:lI101|H389DA4 +389DA4:lI116|H389E5C +389E5C:lI47|H389F0C +389F0C:lI101|H389FAC +389FAC:lI98|H38A03C +38A03C:lI105|H38A0BC +38A0BC:lI110|N +38B078:lH3885DC|H38B080 +3885DC:lI47|H3886E4 +3886E4:lI99|H3887F4 +3887F4:lI108|H388904 +388904:lI101|H388A14 +388A14:lI97|H388B1C +388B1C:lI114|H388C2C +388C2C:lI99|H388D3C +388D3C:lI97|H388E4C +388E4C:lI115|H388F5C +388F5C:lI101|H389074 +389074:lI47|H389184 +389184:lI111|H389294 +389294:lI116|H3893A4 +3893A4:lI112|H3894B4 +3894B4:lI47|H3895BC +3895BC:lI101|H3896B4 +3896B4:lI114|H3897AC +3897AC:lI116|H3898A4 +3898A4:lI115|H38999C +38999C:lI47|H389A7C +389A7C:lI108|H389B54 +389B54:lI105|H389C1C +389C1C:lI98|H389CE4 +389CE4:lI47|H389DAC +389DAC:lI101|H389E64 +389E64:lI114|H389F14 +389F14:lI108|H389FB4 +389FB4:lI95|H38A044 +38A044:lI105|H38A0C4 +38A0C4:lI110|H38A134 +38A134:lI116|H38A1A4 +38A1A4:lI101|H38A20C +38A20C:lI114|H38A274 +38A274:lI102|H38A2DC +38A2DC:lI97|H38A344 +38A344:lI99|H38A3AC +38A3AC:lI101|N +38B080:lH3886EC|H38B088 +3886EC:lI47|H3887FC +3887FC:lI99|H38890C +38890C:lI108|H388A1C +388A1C:lI101|H388B24 +388B24:lI97|H388C34 +388C34:lI114|H388D44 +388D44:lI99|H388E54 +388E54:lI97|H388F64 +388F64:lI115|H38907C +38907C:lI101|H38918C +38918C:lI47|H38929C +38929C:lI111|H3893AC +3893AC:lI116|H3894BC +3894BC:lI112|H3895C4 +3895C4:lI47|H3896BC +3896BC:lI101|H3897B4 +3897B4:lI114|H3898AC +3898AC:lI116|H3899A4 +3899A4:lI115|H389A84 +389A84:lI47|H389B5C +389B5C:lI108|H389C24 +389C24:lI105|H389CEC +389CEC:lI98|H389DB4 +389DB4:lI47|H389E6C +389E6C:lI100|H389F1C +389F1C:lI101|H389FBC +389FBC:lI98|H38A04C +38A04C:lI117|H38A0CC +38A0CC:lI103|H38A13C +38A13C:lI103|H38A1AC +38A1AC:lI101|H38A214 +38A214:lI114|H38A27C +38A27C:lI47|H38A2E4 +38A2E4:lI101|H38A34C +38A34C:lI98|H38A3B4 +38A3B4:lI105|H38A414 +38A414:lI110|N +38B088:lH388804|H38B090 +388804:lI47|H388914 +388914:lI99|H388A24 +388A24:lI108|H388B2C +388B2C:lI101|H388C3C +388C3C:lI97|H388D4C +388D4C:lI114|H388E5C +388E5C:lI99|H388F6C +388F6C:lI97|H389084 +389084:lI115|H389194 +389194:lI101|H3892A4 +3892A4:lI47|H3893B4 +3893B4:lI111|H3894C4 +3894C4:lI116|H3895CC +3895CC:lI112|H3896C4 +3896C4:lI47|H3897BC +3897BC:lI101|H3898B4 +3898B4:lI114|H3899AC +3899AC:lI116|H389A8C +389A8C:lI115|H389B64 +389B64:lI47|H389C2C +389C2C:lI108|H389CF4 +389CF4:lI105|H389DBC +389DBC:lI98|H389E74 +389E74:lI47|H389F24 +389F24:lI99|H389FC4 +389FC4:lI114|H38A054 +38A054:lI121|H38A0D4 +38A0D4:lI112|H38A144 +38A144:lI116|H38A1B4 +38A1B4:lI111|H38A21C +38A21C:lI47|H38A284 +38A284:lI101|H38A2EC +38A2EC:lI98|H38A354 +38A354:lI105|H38A3BC +38A3BC:lI110|N +38B090:lH38891C|H38B098 +38891C:lI47|H388A2C +388A2C:lI99|H388B34 +388B34:lI108|H388C44 +388C44:lI101|H388D54 +388D54:lI97|H388E64 +388E64:lI114|H388F74 +388F74:lI99|H38908C +38908C:lI97|H38919C +38919C:lI115|H3892AC +3892AC:lI101|H3893BC +3893BC:lI47|H3894CC +3894CC:lI111|H3895D4 +3895D4:lI116|H3896CC +3896CC:lI112|H3897C4 +3897C4:lI47|H3898BC +3898BC:lI101|H3899B4 +3899B4:lI114|H389A94 +389A94:lI116|H389B6C +389B6C:lI115|H389C34 +389C34:lI47|H389CFC +389CFC:lI108|H389DC4 +389DC4:lI105|H389E7C +389E7C:lI98|H389F2C +389F2C:lI47|H389FCC +389FCC:lI99|H38A05C +38A05C:lI111|H38A0DC +38A0DC:lI115|H38A14C +38A14C:lI84|H38A1BC +38A1BC:lI114|H38A224 +38A224:lI97|H38A28C +38A28C:lI110|H38A2F4 +38A2F4:lI115|H38A35C +38A35C:lI97|H38A3C4 +38A3C4:lI99|H38A41C +38A41C:lI116|H38A46C +38A46C:lI105|H38A4BC +38A4BC:lI111|H38A50C +38A50C:lI110|H38A554 +38A554:lI115|H38A59C +38A59C:lI47|H38A5E4 +38A5E4:lI101|H38A62C +38A62C:lI98|H38A66C +38A66C:lI105|H38A6A4 +38A6A4:lI110|N +38B098:lH388A34|H38B0A0 +388A34:lI47|H388B3C +388B3C:lI99|H388C4C +388C4C:lI108|H388D5C +388D5C:lI101|H388E6C +388E6C:lI97|H388F7C +388F7C:lI114|H389094 +389094:lI99|H3891A4 +3891A4:lI97|H3892B4 +3892B4:lI115|H3893C4 +3893C4:lI101|H3894D4 +3894D4:lI47|H3895DC +3895DC:lI111|H3896D4 +3896D4:lI116|H3897CC +3897CC:lI112|H3898C4 +3898C4:lI47|H3899BC +3899BC:lI101|H389A9C +389A9C:lI114|H389B74 +389B74:lI116|H389C3C +389C3C:lI115|H389D04 +389D04:lI47|H389DCC +389DCC:lI108|H389E84 +389E84:lI105|H389F34 +389F34:lI98|H389FD4 +389FD4:lI47|H38A064 +38A064:lI99|H38A0E4 +38A0E4:lI111|H38A154 +38A154:lI115|H38A1C4 +38A1C4:lI84|H38A22C +38A22C:lI105|H38A294 +38A294:lI109|H38A2FC +38A2FC:lI101|H38A364 +38A364:lI47|H38A3CC +38A3CC:lI101|H38A424 +38A424:lI98|H38A474 +38A474:lI105|H38A4C4 +38A4C4:lI110|N +38B0A0:lH388B44|H38B0A8 +388B44:lI47|H388C54 +388C54:lI99|H388D64 +388D64:lI108|H388E74 +388E74:lI101|H388F84 +388F84:lI97|H38909C +38909C:lI114|H3891AC +3891AC:lI99|H3892BC +3892BC:lI97|H3893CC +3893CC:lI115|H3894DC +3894DC:lI101|H3895E4 +3895E4:lI47|H3896DC +3896DC:lI111|H3897D4 +3897D4:lI116|H3898CC +3898CC:lI112|H3899C4 +3899C4:lI47|H389AA4 +389AA4:lI101|H389B7C +389B7C:lI114|H389C44 +389C44:lI116|H389D0C +389D0C:lI115|H389DD4 +389DD4:lI47|H389E8C +389E8C:lI108|H389F3C +389F3C:lI105|H389FDC +389FDC:lI98|H38A06C +38A06C:lI47|H38A0EC +38A0EC:lI99|H38A15C +38A15C:lI111|H38A1CC +38A1CC:lI115|H38A234 +38A234:lI80|H38A29C +38A29C:lI114|H38A304 +38A304:lI111|H38A36C +38A36C:lI112|H38A3D4 +38A3D4:lI101|H38A42C +38A42C:lI114|H38A47C +38A47C:lI116|H38A4CC +38A4CC:lI121|H38A514 +38A514:lI47|H38A55C +38A55C:lI101|H38A5A4 +38A5A4:lI98|H38A5EC +38A5EC:lI105|H38A634 +38A634:lI110|N +38B0A8:lH388C5C|H38B0B0 +388C5C:lI47|H388D6C +388D6C:lI99|H388E7C +388E7C:lI108|H388F8C +388F8C:lI101|H3890A4 +3890A4:lI97|H3891B4 +3891B4:lI114|H3892C4 +3892C4:lI99|H3893D4 +3893D4:lI97|H3894E4 +3894E4:lI115|H3895EC +3895EC:lI101|H3896E4 +3896E4:lI47|H3897DC +3897DC:lI111|H3898D4 +3898D4:lI116|H3899CC +3899CC:lI112|H389AAC +389AAC:lI47|H389B84 +389B84:lI101|H389C4C +389C4C:lI114|H389D14 +389D14:lI116|H389DDC +389DDC:lI115|H389E94 +389E94:lI47|H389F44 +389F44:lI108|H389FE4 +389FE4:lI105|H38A074 +38A074:lI98|H38A0F4 +38A0F4:lI47|H38A164 +38A164:lI99|H38A1D4 +38A1D4:lI111|H38A23C +38A23C:lI115|H38A2A4 +38A2A4:lI78|H38A30C +38A30C:lI111|H38A374 +38A374:lI116|H38A3DC +38A3DC:lI105|H38A434 +38A434:lI102|H38A484 +38A484:lI105|H38A4D4 +38A4D4:lI99|H38A51C +38A51C:lI97|H38A564 +38A564:lI116|H38A5AC +38A5AC:lI105|H38A5F4 +38A5F4:lI111|H38A63C +38A63C:lI110|H38A674 +38A674:lI47|H38A6AC +38A6AC:lI101|H38A6D4 +38A6D4:lI98|H38A6EC +38A6EC:lI105|H38A704 +38A704:lI110|N +38B0B0:lH388D74|H38B0B8 +388D74:lI47|H388E84 +388E84:lI99|H388F94 +388F94:lI108|H3890AC +3890AC:lI101|H3891BC +3891BC:lI97|H3892CC +3892CC:lI114|H3893DC +3893DC:lI99|H3894EC +3894EC:lI97|H3895F4 +3895F4:lI115|H3896EC +3896EC:lI101|H3897E4 +3897E4:lI47|H3898DC +3898DC:lI111|H3899D4 +3899D4:lI116|H389AB4 +389AB4:lI112|H389B8C +389B8C:lI47|H389C54 +389C54:lI101|H389D1C +389D1C:lI114|H389DE4 +389DE4:lI116|H389E9C +389E9C:lI115|H389F4C +389F4C:lI47|H389FEC +389FEC:lI108|H38A07C +38A07C:lI105|H38A0FC +38A0FC:lI98|H38A16C +38A16C:lI47|H38A1DC +38A1DC:lI99|H38A244 +38A244:lI111|H38A2AC +38A2AC:lI115|H38A314 +38A314:lI70|H38A37C +38A37C:lI105|H38A3E4 +38A3E4:lI108|H38A43C +38A43C:lI101|H38A48C +38A48C:lI84|H38A4DC +38A4DC:lI114|H38A524 +38A524:lI97|H38A56C +38A56C:lI110|H38A5B4 +38A5B4:lI115|H38A5FC +38A5FC:lI102|H38A644 +38A644:lI101|H38A67C +38A67C:lI114|H38A6B4 +38A6B4:lI47|H38A6DC +38A6DC:lI101|H38A6F4 +38A6F4:lI98|H38A70C +38A70C:lI105|H38A71C +38A71C:lI110|N +38B0B8:lH388E8C|H38B0C0 +388E8C:lI47|H388F9C +388F9C:lI99|H3890B4 +3890B4:lI108|H3891C4 +3891C4:lI101|H3892D4 +3892D4:lI97|H3893E4 +3893E4:lI114|H3894F4 +3894F4:lI99|H3895FC +3895FC:lI97|H3896F4 +3896F4:lI115|H3897EC +3897EC:lI101|H3898E4 +3898E4:lI47|H3899DC +3899DC:lI111|H389ABC +389ABC:lI116|H389B94 +389B94:lI112|H389C5C +389C5C:lI47|H389D24 +389D24:lI101|H389DEC +389DEC:lI114|H389EA4 +389EA4:lI116|H389F54 +389F54:lI115|H389FF4 +389FF4:lI47|H38A084 +38A084:lI108|H38A104 +38A104:lI105|H38A174 +38A174:lI98|H38A1E4 +38A1E4:lI47|H38A24C +38A24C:lI99|H38A2B4 +38A2B4:lI111|H38A31C +38A31C:lI115|H38A384 +38A384:lI69|H38A3EC +38A3EC:lI118|H38A444 +38A444:lI101|H38A494 +38A494:lI110|H38A4E4 +38A4E4:lI116|H38A52C +38A52C:lI68|H38A574 +38A574:lI111|H38A5BC +38A5BC:lI109|H38A604 +38A604:lI97|H38A64C +38A64C:lI105|H38A684 +38A684:lI110|H38A6BC +38A6BC:lI47|H38A6E4 +38A6E4:lI101|H38A6FC +38A6FC:lI98|H38A714 +38A714:lI105|H38A724 +38A724:lI110|N +38B0C0:lH388FA4|H38B0C8 +388FA4:lI47|H3890BC +3890BC:lI99|H3891CC +3891CC:lI108|H3892DC +3892DC:lI101|H3893EC +3893EC:lI97|H3894FC +3894FC:lI114|H389604 +389604:lI99|H3896FC +3896FC:lI97|H3897F4 +3897F4:lI115|H3898EC +3898EC:lI101|H3899E4 +3899E4:lI47|H389AC4 +389AC4:lI111|H389B9C +389B9C:lI116|H389C64 +389C64:lI112|H389D2C +389D2C:lI47|H389DF4 +389DF4:lI101|H389EAC +389EAC:lI114|H389F5C +389F5C:lI116|H389FFC +389FFC:lI115|H38A08C +38A08C:lI47|H38A10C +38A10C:lI108|H38A17C +38A17C:lI105|H38A1EC +38A1EC:lI98|H38A254 +38A254:lI47|H38A2BC +38A2BC:lI99|H38A324 +38A324:lI111|H38A38C +38A38C:lI115|H38A3F4 +38A3F4:lI69|H38A44C +38A44C:lI118|H38A49C +38A49C:lI101|H38A4EC +38A4EC:lI110|H38A534 +38A534:lI116|H38A57C +38A57C:lI47|H38A5C4 +38A5C4:lI101|H38A60C +38A60C:lI98|H38A654 +38A654:lI105|H38A68C +38A68C:lI110|N +38B0C8:lH3890C4|H38B0D0 +3890C4:lI47|H3891D4 +3891D4:lI99|H3892E4 +3892E4:lI108|H3893F4 +3893F4:lI101|H389504 +389504:lI97|H38960C +38960C:lI114|H389704 +389704:lI99|H3897FC +3897FC:lI97|H3898F4 +3898F4:lI115|H3899EC +3899EC:lI101|H389ACC +389ACC:lI47|H389BA4 +389BA4:lI111|H389C6C +389C6C:lI116|H389D34 +389D34:lI112|H389DFC +389DFC:lI47|H389EB4 +389EB4:lI101|H389F64 +389F64:lI114|H38A004 +38A004:lI116|H38A094 +38A094:lI115|H38A114 +38A114:lI47|H38A184 +38A184:lI108|H38A1F4 +38A1F4:lI105|H38A25C +38A25C:lI98|H38A2C4 +38A2C4:lI47|H38A32C +38A32C:lI99|H38A394 +38A394:lI111|H38A3FC +38A3FC:lI109|H38A454 +38A454:lI112|H38A4A4 +38A4A4:lI105|H38A4F4 +38A4F4:lI108|H38A53C +38A53C:lI101|H38A584 +38A584:lI114|H38A5CC +38A5CC:lI47|H38A614 +38A614:lI101|H38A65C +38A65C:lI98|H38A694 +38A694:lI105|H38A6C4 +38A6C4:lI110|N +38B0D0:lH3891DC|H38B0D8 +3891DC:lI47|H3892EC +3892EC:lI99|H3893FC +3893FC:lI108|H38950C +38950C:lI101|H389614 +389614:lI97|H38970C +38970C:lI114|H389804 +389804:lI99|H3898FC +3898FC:lI97|H3899F4 +3899F4:lI115|H389AD4 +389AD4:lI101|H389BAC +389BAC:lI47|H389C74 +389C74:lI111|H389D3C +389D3C:lI116|H389E04 +389E04:lI112|H389EBC +389EBC:lI47|H389F6C +389F6C:lI101|H38A00C +38A00C:lI114|H38A09C +38A09C:lI116|H38A11C +38A11C:lI115|H38A18C +38A18C:lI47|H38A1FC +38A1FC:lI108|H38A264 +38A264:lI105|H38A2CC +38A2CC:lI98|H38A334 +38A334:lI47|H38A39C +38A39C:lI97|H38A404 +38A404:lI115|H38A45C +38A45C:lI110|H38A4AC +38A4AC:lI49|H38A4FC +38A4FC:lI47|H38A544 +38A544:lI101|H38A58C +38A58C:lI98|H38A5D4 +38A5D4:lI105|H38A61C +38A61C:lI110|N +38B0D8:lH3892F4|H38B0E0 +3892F4:lI47|H389404 +389404:lI99|H389514 +389514:lI108|H38961C +38961C:lI101|H389714 +389714:lI97|H38980C +38980C:lI114|H389904 +389904:lI99|H3899FC +3899FC:lI97|H389ADC +389ADC:lI115|H389BB4 +389BB4:lI101|H389C7C +389C7C:lI47|H389D44 +389D44:lI111|H389E0C +389E0C:lI116|H389EC4 +389EC4:lI112|H389F74 +389F74:lI47|H38A014 +38A014:lI101|H38A0A4 +38A0A4:lI114|H38A124 +38A124:lI116|H38A194 +38A194:lI115|H38A204 +38A204:lI47|H38A26C +38A26C:lI108|H38A2D4 +38A2D4:lI105|H38A33C +38A33C:lI98|H38A3A4 +38A3A4:lI47|H38A40C +38A40C:lI97|H38A464 +38A464:lI112|H38A4B4 +38A4B4:lI112|H38A504 +38A504:lI109|H38A54C +38A54C:lI111|H38A594 +38A594:lI110|H38A5DC +38A5DC:lI47|H38A624 +38A624:lI101|H38A664 +38A664:lI98|H38A69C +38A69C:lI105|H38A6CC +38A6CC:lI110|N +38B0E0:lH38AA88|H38B0E8 +38AA88:lI47|H38AA90 +38AA90:lI104|H38AA98 +38AA98:lI111|H38AAA0 +38AAA0:lI109|H38AAA8 +38AAA8:lI101|H38AAB0 +38AAB0:lI47|H38AAB8 +38AAB8:lI115|H38AAC0 +38AAC0:lI105|H38AAC8 +38AAC8:lI114|H38AAD0 +38AAD0:lI105|H38AAD8 +38AAD8:lI47|H38AAE0 +38AAE0:lI101|H38AAE8 +38AAE8:lI114|H38AAF0 +38AAF0:lI108|H38AAF8 +38AAF8:lI97|H38AB00 +38AB00:lI110|H38AB08 +38AB08:lI103|N +38B0E8:lH38AB1C|H38B0F0 +38AB1C:lI47|H38AB2C +38AB2C:lI104|H38AB4C +38AB4C:lI111|H38AB74 +38AB74:lI109|H38ABA4 +38ABA4:lI101|H38ABC4 +38ABC4:lI47|H38ABE4 +38ABE4:lI115|H38AC04 +38AC04:lI105|H38AC24 +38AC24:lI114|H38AC3C +38AC3C:lI105|H38AC44 +38AC44:lI47|H38AC4C +38AC4C:lI116|H38AC54 +38AC54:lI111|H38AC5C +38AC5C:lI111|H38AC64 +38AC64:lI108|H38AC6C +38AC6C:lI115|H38AC74 +38AC74:lI47|H38AC7C +38AC7C:lI100|H38AC84 +38AC84:lI105|H38AC8C +38AC8C:lI115|H38AC94 +38AC94:lI116|H38AC9C +38AC9C:lI101|H38ACA4 +38ACA4:lI108|H38ACAC +38ACAC:lI47|H38ACB4 +38ACB4:lI101|H38ACBC +38ACBC:lI98|H38ACC4 +38ACC4:lI105|H38ACCC +38ACCC:lI110|N +38B0F0:lH38B0F8|N +38B0F8:lI47|H38B100 +38B100:lI104|H38B108 +38B108:lI111|H38B110 +38B110:lI109|H38B118 +38B118:lI101|H38B120 +38B120:lI47|H38B128 +38B128:lI115|H38B130 +38B130:lI105|H38B138 +38B138:lI114|H38B140 +38B140:lI105|H38B148 +38B148:lI47|H38B150 +38B150:lI79|H38B158 +38B158:lI84|H38B160 +38B160:lI80|H38B168 +38B168:lI47|H38B170 +38B170:lI103|H38B178 +38B178:lI112|H38B180 +38B180:lI114|H38B188 +38B188:lI115|H38B190 +38B190:lI95|H38B198 +38B198:lI116|H38B1A0 +38B1A0:lI114|H38B1A8 +38B1A8:lI97|H38B1B0 +38B1B0:lI99|H38B1B8 +38B1B8:lI101|H38B1C0 +38B1C0:lI47|H38B1C8 +38B1C8:lI106|H38B1D0 +38B1D0:lI97|H38B1D8 +38B1D8:lI110|N +3873BC:lI47|H3873CC +3873CC:lI99|H3873E4 +3873E4:lI108|H3873FC +3873FC:lI101|H38741C +38741C:lI97|H387444 +387444:lI114|H387474 +387474:lI99|H3874AC +3874AC:lI97|H3874EC +3874EC:lI115|H387534 +387534:lI101|H387584 +387584:lI47|H3875DC +3875DC:lI111|H38763C +38763C:lI116|H3876A4 +3876A4:lI112|H387714 +387714:lI47|H38778C +38778C:lI101|H38780C +38780C:lI114|H387894 +387894:lI116|H387924 +387924:lI115|N +=proc_dictionary:<0.19.0> +H370244 +H370250 +=proc_stack:<0.19.0> +36b45c:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A11:supervisor_bridge +y3:H36B17C +y4:P<0.19.0> +y5:P<0.9.0> +36b478:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H37025C +=proc_heap:<0.19.0> +36B17C:t5:A5:state,A8:user_sup,P<0.21.0>,P<0.21.0>,H370238 +370238:t2:P<0.19.0>,A8:user_sup +37025C:lAA:gen_server|H37027C +37027C:lP<0.9.0>|H37028C +37028C:lP<0.9.0>|H370294 +370294:lA11:supervisor_bridge|H37029C +37029C:lH3702A4|H3702AC +3702A4:lA8:user_sup|H3702B4 +3702B4:lN|H3702BC +3702BC:lA4:self|N +3702AC:lN|N +370244:t2:AD:$initial_call,H370264 +370264:t3:A3:gen,A7:init_it,H37025C +370250:t2:AA:$ancestors,H370274 +370274:lAA:kernel_sup|H370284 +370284:lP<0.8.0>|N +=proc_dictionary:<0.20.0> +H36F8A8 +=proc_stack:<0.20.0> +36a714:SReturn addr 0x156F90 (<terminate process normally>) +y0:N +y1:N +y2:H36F8C4 +y3:P<0.21.0> +y4:P<0.22.0> +y5:p<0.72> +y6:p<0.72> +=proc_heap:<0.20.0> +36F8C4:t4:I3,I2,P<0.22.0>,H36F8F0 +36F8F0:lH36F900|H36F910 +36F900:t3:I1,P<0.21.0>,H36F920 +36F920:t0: +36F910:lH36F924|N +36F924:t3:I2,P<0.22.0>,H36F93C +36F93C:t3:A5:shell,A5:start,N +36F8A8:t2:A3:eof,A5:false +=proc_dictionary:<0.21.0> +H3709DC +H3709D0 +H3709F8 +=proc_stack:<0.21.0> +370d1c:SReturn addr 0x156F90 (<terminate process normally>) +y0:N +y1:A9:undefined +y2:P<0.20.0> +=proc_heap:<0.21.0> +3709DC:t2:AB:line_buffer,N +3709D0:t2:AB:kill_buffer,N +3709F8:t2:A9:read_mode,A4:list +=proc_dictionary:<0.22.0> +H370D44 +H370D60 +H370D7C +H370D38 +=proc_stack:<0.22.0> +374a88:SReturn addr 0x2CE718 (group:get_chars_loop/7 + 80) +y0:N +y1:N +y2:A8:infinity +y3:H374A00 +y4:P<0.20.0> +y5:H374A28 +374aa4:SReturn addr 0x2CDC18 (group:io_request/5 + 48) +y0:H37499C +y1:A6:io_lib +y2:A9:get_until +y3:H3748B8 +y4:P<0.20.0> +y5:A5:start +374ac0:SReturn addr 0x2CDB2C (group:server_loop/3 + 372) +y0:P<0.49.0> +y1:P<0.22.0> +374acc:SReturn addr 0x156F90 (<terminate process normally>) +y0:N +y1:P<0.25.0> +y2:P<0.20.0> +=proc_heap:<0.22.0> +374A00:t4:A4:line,H37499C,H3749A4,A4:none +3749A4:t2:N,N +37499C:lI50|H374994 +374994:lI62|H37498C +37498C:lI32|N +374A28:t4:A5:stack,H370D58,H374A24,N +374A24:t0: +370D58:lH370D74|N +370D74:lI99|H370D88 +370D88:lI114|H370D90 +370D90:lI97|H370D98 +370D98:lI115|H370DA0 +370DA0:lI104|H370DA8 +370DA8:lI100|H370DB0 +370DB0:lI117|H370DB8 +370DB8:lI109|H370DC0 +370DC0:lI112|H370DC8 +370DC8:lI95|H370DD0 +370DD0:lI118|H370DD8 +370DD8:lI105|H370DE0 +370DE0:lI101|H370DE8 +370DE8:lI119|H370DF0 +370DF0:lI101|H370DF8 +370DF8:lI114|H370E00 +370E00:lI58|H370E08 +370E08:lI115|H370E10 +370E10:lI116|H370E18 +370E18:lI97|H370E20 +370E20:lI114|H370E28 +370E28:lI116|H370E30 +370E30:lI40|H370E38 +370E38:lI41|H370E40 +370E40:lI46|H370E48 +370E48:lI10|N +3748B8:t3:A8:erl_scan,A6:tokens,H3748B0 +3748B0:lI1|N +370D44:t2:AB:line_buffer,H370D58 +370D60:t2:A5:shell,P<0.25.0> +370D7C:t2:AB:kill_buffer,N +370D38:t2:A9:read_mode,A4:list +=proc_dictionary:<0.23.0> +H376464 +H376448 +=proc_stack:<0.23.0> +376754:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AD:kernel_config +y3:N +y4:P<0.23.0> +y5:P<0.9.0> +376770:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H376418 +=proc_heap:<0.23.0> +376418:lAA:gen_server|H376410 +376410:lP<0.9.0>|H376408 +376408:lP<0.9.0>|H376400 +376400:lAD:kernel_config|H3763F8 +3763F8:lN|H3763F0 +3763F0:lN|N +376464:t2:AD:$initial_call,H376454 +376454:t3:A3:gen,A7:init_it,H376418 +376448:t2:AA:$ancestors,H376440 +376440:lAA:kernel_sup|H376420 +376420:lP<0.8.0>|N +=proc_dictionary:<0.24.0> +H3705E0 +H3705EC +=proc_stack:<0.24.0> +36f38c:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AA:supervisor +y3:H36F018 +y4:AF:kernel_safe_sup +y5:P<0.9.0> +36f3a8:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H37063C +=proc_heap:<0.24.0> +36F018:tA:A5:state,H370644,AB:one_for_one,H36F044,N,I4,I3600,N,A6:kernel,A4:safe +36F044:lH36F04C|N +36F04C:t8:A5:child,P<0.31.0>,A17:inet_gethost_native_sup,H370650,A9:temporary,I1000,A6:worker,H370660 +370660:lA13:inet_gethost_native|N +370650:t3:A13:inet_gethost_native,AA:start_link,N +370644:t2:A5:local,AF:kernel_safe_sup +37063C:lAA:gen_server|H3706AC +3706AC:lP<0.9.0>|H3706BC +3706BC:lP<0.9.0>|H3706C4 +3706C4:lH3706CC|H3706D8 +3706CC:t2:A5:local,AF:kernel_safe_sup +3706D8:lAA:supervisor|H3706E0 +3706E0:lH3706E8|H3706F8 +3706E8:t3:H370644,A6:kernel,A4:safe +3706F8:lN|N +3705E0:t2:AD:$initial_call,H370668 +370668:t3:A3:gen,A7:init_it,H37063C +3705EC:t2:AA:$ancestors,H370678 +370678:lAA:kernel_sup|H3706B4 +3706B4:lP<0.8.0>|N +=proc_dictionary:<0.25.0> +H36E304 +H36E31C +=proc_stack:<0.25.0> +36e610:SReturn addr 0x2E06FC (shell:server_loop/6 + 140) +y0:N +y1:N +y2:P<0.27.0> +y3:P<0.49.0> +36e624:SReturn addr 0x156F90 (<terminate process normally>) +y0:N +y1:N +y2:I2 +y3:I1 +y4:N +y5:N +y6:N +y7:I20 +y8:I20 +=proc_heap:<0.25.0> +36E304:t2:H36E2F8,H36E2A8 +36E2A8:lH36E2B0|N +36E2B0:t4:A4:call,I1,H36E2C4,N +36E2C4:t4:A6:remote,I1,H36E2D8,H36E2E8 +36E2E8:t3:A4:atom,I1,A5:start +36E2D8:t3:A4:atom,I1,A10:crashdump_viewer +36E2F8:t2:A7:command,I1 +36E31C:t2:H36E310,A2:ok +36E310:t2:A6:result,I1 +=proc_stack:<0.27.0> +3bda3c:SReturn addr 0x156F90 (<terminate process normally>) +y0:N +y1:N +y2:P<0.25.0> +=proc_heap:<0.27.0> +=proc_dictionary:<0.31.0> +H36DA24 +H36DA08 +=proc_stack:<0.31.0> +36dcd4:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A11:supervisor_bridge +y3:H36DB68 +y4:A17:inet_gethost_native_sup +y5:P<0.24.0> +36dcf0:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H36D9D0 +=proc_heap:<0.31.0> +36DB68:t5:A5:state,A13:inet_gethost_native,P<0.32.0>,P<0.32.0>,H36D994 +36D994:t2:A5:local,A17:inet_gethost_native_sup +36D9D0:lAA:gen_server|H36D9C8 +36D9C8:lP<0.24.0>|H36D9C0 +36D9C0:lP<0.24.0>|H36D970 +36D970:lH36D980|H36D9B8 +36D980:t2:A5:local,A17:inet_gethost_native_sup +36D9B8:lA11:supervisor_bridge|H36D978 +36D978:lH36D9A8|H36D9B0 +36D9A8:lA13:inet_gethost_native|H36D9A0 +36D9A0:lN|H36D98C +36D98C:lH36D994|N +36D9B0:lN|N +36DA24:t2:AD:$initial_call,H36DA14 +36DA14:t3:A3:gen,A7:init_it,H36D9D0 +36DA08:t2:AA:$ancestors,H36DA00 +36DA00:lAF:kernel_safe_sup|H36D9E0 +36D9E0:lAA:kernel_sup|H36D9D8 +36D9D8:lP<0.8.0>|N +=proc_dictionary:<0.32.0> +H36CFD4 +H36D0BC +=proc_stack:<0.32.0> +36d12c:SReturn addr 0x156F90 (<terminate process normally>) +y0:H36CF18 +=proc_heap:<0.32.0> +36CF18:t8:A5:state,p<0.105>,I8000,I11,I12,P<0.31.0>,I4,H36CEF0 +36CEF0:t9:AA:statistics,I0,I0,I0,I0,I0,I0,I0,I0 +36CFD4:t2:A3:rid,I1 +36D0BC:t2:AC:num_requests,I0 +=proc_dictionary:<0.33.0> +H3905C4 +H3905D0 +=proc_stack:<0.33.0> +3ceee4:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A7:webtool +y3:H3C8570 +y4:A8:web_tool +y5:P<0.33.0> +3cef00:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H3905FC +=proc_heap:<0.33.0> +3C8570:t6:A5:state,H3905EC,I13,P<0.41.0>,H3905F4,H3C85D4 +3C85D4:lA10:crashdump_viewer|N +3905F4:lH390650|H39065C +390650:t2:A4:port,I8888 +39065C:lH3906C8|H3906D4 +3906C8:t2:AC:bind_address,H390760 +390760:t4:I127,I0,I0,I1 +3906D4:lH390774|H390780 +390774:t2:AB:server_name,H39082C +39082C:lI108|H390908 +390908:lI111|H3909DC +3909DC:lI99|H390AC0 +390AC0:lI97|H390B98 +390B98:lI108|H390C78 +390C78:lI104|H390D58 +390D58:lI111|H390E2C +390E2C:lI115|H390F10 +390F10:lI116|N +390780:lH390834|H390840 +390834:t2:AE:max_header_siz,I1024 +390840:lH390910|H39091C +390910:t2:A11:max_header_action,A8:reply414 +39091C:lH3909E4|H3909F0 +3909E4:t2:A8:com_type,A7:ip_comm +3909F0:lH390AC8|H390AD4 +390AC8:t2:A7:modules,H390BA0 +390BA0:lA9:mod_alias|H390C80 +390C80:lA8:mod_auth|H390D60 +390D60:lA7:mod_esi|H390E34 +390E34:lAB:mod_actions|H390F18 +390F18:lA7:mod_cgi|H390FF4 +390FF4:lAB:mod_include|H3910D8 +3910D8:lA7:mod_dir|H3911B4 +3911B4:lA7:mod_get|H3912A0 +3912A0:lA8:mod_head|H39139C +39139C:lA7:mod_log|H3914A0 +3914A0:lAC:mod_disk_log|N +390AD4:lH390BA8|H390BB4 +390BA8:t2:AF:directory_index,H390C88 +390C88:lH390D68|N +390D68:lI105|H390E3C +390E3C:lI110|H390F20 +390F20:lI100|H390FFC +390FFC:lI101|H3910E0 +3910E0:lI120|H3911BC +3911BC:lI46|H3912A8 +3912A8:lI104|H3913A4 +3913A4:lI116|H3914A8 +3914A8:lI109|H39159C +39159C:lI108|N +390BB4:lH390C90|N +390C90:t2:AC:default_type,H390D70 +390D70:lI116|H390E44 +390E44:lI101|H390F28 +390F28:lI120|H391004 +391004:lI116|H3910E8 +3910E8:lI47|H3911C4 +3911C4:lI112|H3912B0 +3912B0:lI108|H3913AC +3913AC:lI97|H3914B0 +3914B0:lI105|H3915A4 +3915A4:lI110|N +3905EC:lI47|H390648 +390648:lI99|H3906C0 +3906C0:lI108|H390758 +390758:lI101|H390824 +390824:lI97|H390900 +390900:lI114|H3909D4 +3909D4:lI99|H390AB8 +390AB8:lI97|H390B90 +390B90:lI115|H390C70 +390C70:lI101|H390D50 +390D50:lI47|H390E24 +390E24:lI111|H390F08 +390F08:lI116|H390FEC +390FEC:lI112|H3910D0 +3910D0:lI47|H3911AC +3911AC:lI101|H391298 +391298:lI114|H391394 +391394:lI116|H391498 +391498:lI115|H391594 +391594:lI47|H391680 +391680:lI108|H39175C +39175C:lI105|H391840 +391840:lI98|H391924 +391924:lI47|H3919F8 +3919F8:lI119|H391AC4 +391AC4:lI101|H391B90 +391B90:lI98|H391C54 +391C54:lI116|H391D18 +391D18:lI111|H391DD4 +391DD4:lI111|H391E90 +391E90:lI108|H391F5C +391F5C:lI47|H392030 +392030:lI112|H3920EC +3920EC:lI114|H3921A8 +3921A8:lI105|H392264 +392264:lI118|N +3905FC:lAA:gen_server|H390664 +390664:lP<0.27.0>|H3906DC +3906DC:lA4:self|H390788 +390788:lH390848|H390854 +390848:t2:A5:local,A8:web_tool +390854:lA7:webtool|H390924 +390924:lH3909F8|H390A04 +3909F8:t2:H3905EC,H3905F4 +390A04:lN|N +3905C4:t2:AD:$initial_call,H390614 +390614:t3:A3:gen,A7:init_it,H3905FC +3905D0:t2:AA:$ancestors,H390624 +390624:lP<0.27.0>|N +=proc_dictionary:<0.41.0> +H36DF0C +H36DF18 +=proc_stack:<0.41.0> +36eda4:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AA:supervisor +y3:H36EA3C +y4:A6:websup +y5:P<0.33.0> +36edc0:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H36DF24 +=proc_heap:<0.41.0> +36EA3C:tA:A5:state,H36DF2C,AB:one_for_one,H36EA68,N,I100,I10,N,AB:webtool_sup,N +36EA68:lH36EA70|N +36EA70:t8:A5:child,P<0.48.0>,H36DF38,H36DF44,A9:permanent,I100,A6:worker,H36DF54 +36DF54:lA10:crashdump_viewer|N +36DF44:t3:A10:crashdump_viewer,AA:start_link,N +36DF38:t2:A5:local,A17:crashdump_viewer_server +36DF2C:t2:A5:local,A6:websup +36DF24:lAA:gen_server|H36DF84 +36DF84:lP<0.33.0>|H36DF94 +36DF94:lP<0.33.0>|H36DF9C +36DF9C:lH36DFA4|H36DFB0 +36DFA4:t2:A5:local,A6:websup +36DFB0:lAA:supervisor|H36DFB8 +36DFB8:lH36DFC0|H36DFD0 +36DFC0:t3:H36DF2C,AB:webtool_sup,N +36DFD0:lN|N +36DF0C:t2:AD:$initial_call,H36DF6C +36DF6C:t3:A3:gen,A7:init_it,H36DF24 +36DF18:t2:AA:$ancestors,H36DF7C +36DF7C:lA8:web_tool|H36DF8C +36DF8C:lP<0.27.0>|N +=proc_dictionary:<0.43.0> +H39D940 +H39D94C +=proc_stack:<0.43.0> +3a42ac:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AA:supervisor +y3:H3A3E34 +y4:A1A:httpd_sup__127_0_0_1__8888 +y5:P<0.33.0> +3a42c8:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H39D9CC +=proc_heap:<0.43.0> +3A3E34:tA:A5:state,H39D960,AB:one_for_one,H3A3E20,N,I0,I1,N,A9:httpd_sup,H39DA88 +39DA88:lA9:undefined|H39DB18 +39DB18:lH39DB50|H39DB58 +39DB50:lH39DB88|H39DB94 +39DB88:t2:AB:server_root,H39DBD0 +39DBD0:lI47|H39DC0C +39DC0C:lI99|H39DC50 +39DC50:lI108|H39DC84 +39DC84:lI101|H39DCC4 +39DCC4:lI97|H39DD28 +39DD28:lI114|H39DD90 +39DD90:lI99|H39DE00 +39DE00:lI97|H39DE78 +39DE78:lI115|H39DF00 +39DF00:lI101|H39DF90 +39DF90:lI47|H39E038 +39E038:lI111|H39E0E8 +39E0E8:lI116|H39E1AC +39E1AC:lI112|H39E288 +39E288:lI47|H39E37C +39E37C:lI101|H39E478 +39E478:lI114|H39E580 +39E580:lI116|H39E69C +39E69C:lI115|H39E7B0 +39E7B0:lI47|H39E8C4 +39E8C4:lI108|H39E9D8 +39E9D8:lI105|H39EACC +39EACC:lI98|H39EBC0 +39EBC0:lI47|H39ECB4 +39ECB4:lI119|H39EDA8 +39EDA8:lI101|H39EE7C +39EE7C:lI98|H39EF50 +39EF50:lI116|H39F02C +39F02C:lI111|H39F110 +39F110:lI111|H39F1E4 +39F1E4:lI108|H39F2B0 +39F2B0:lI47|H39F36C +39F36C:lI112|H39F430 +39F430:lI114|H39F4FC +39F4FC:lI105|H39F5C0 +39F5C0:lI118|H39F694 +39F694:lI47|H39F768 +39F768:lI114|H39F83C +39F83C:lI111|H39F920 +39F920:lI111|H39F9FC +39F9FC:lI116|N +39DB94:lH39DBD8|H39DBE4 +39DBD8:t2:AD:document_root,H39DC14 +39DC14:lI47|H39DC58 +39DC58:lI99|H39DC8C +39DC8C:lI108|H39DCCC +39DCCC:lI101|H39DD30 +39DD30:lI97|H39DD98 +39DD98:lI114|H39DE08 +39DE08:lI99|H39DE80 +39DE80:lI97|H39DF08 +39DF08:lI115|H39DF98 +39DF98:lI101|H39E040 +39E040:lI47|H39E0F0 +39E0F0:lI111|H39E1B4 +39E1B4:lI116|H39E290 +39E290:lI112|H39E384 +39E384:lI47|H39E480 +39E480:lI101|H39E588 +39E588:lI114|H39E6A4 +39E6A4:lI116|H39E7B8 +39E7B8:lI115|H39E8CC +39E8CC:lI47|H39E9E0 +39E9E0:lI108|H39EAD4 +39EAD4:lI105|H39EBC8 +39EBC8:lI98|H39ECBC +39ECBC:lI47|H39EDB0 +39EDB0:lI119|H39EE84 +39EE84:lI101|H39EF58 +39EF58:lI98|H39F034 +39F034:lI116|H39F118 +39F118:lI111|H39F1EC +39F1EC:lI111|H39F2B8 +39F2B8:lI108|H39F374 +39F374:lI47|H39F438 +39F438:lI112|H39F504 +39F504:lI114|H39F5C8 +39F5C8:lI105|H39F69C +39F69C:lI118|H39F770 +39F770:lI47|H39F844 +39F844:lI114|H39F928 +39F928:lI111|H39FA04 +39FA04:lI111|H39FAD8 +39FAD8:lI116|H39FBB4 +39FBB4:lI47|H39FC80 +39FC80:lI100|H39FD44 +39FD44:lI111|H39FE10 +39FE10:lI99|N +39DBE4:lH39DC1C|H39DC28 +39DC1C:t2:AA:mime_types,H39DC60 +39DC60:lH39DC94|H39DCA0 +39DC94:t2:H39DCD4,H39DCDC +39DCDC:lI120|H39DD40 +39DD40:lI45|H39DDA8 +39DDA8:lI119|H39DE10 +39DE10:lI111|H39DE88 +39DE88:lI114|H39DF10 +39DF10:lI108|H39DFA0 +39DFA0:lI100|H39E048 +39E048:lI47|H39E0F8 +39E0F8:lI120|H39E1BC +39E1BC:lI45|H39E298 +39E298:lI118|H39E38C +39E38C:lI114|H39E488 +39E488:lI109|H39E590 +39E590:lI108|N +39DCD4:lI119|H39DD38 +39DD38:lI114|H39DDA0 +39DDA0:lI108|N +39DCA0:lH39DCE4|H39DCF0 +39DCE4:t2:H39DD48,H39DD50 +39DD50:lI120|H39DDB8 +39DDB8:lI45|H39DE20 +39DE20:lI119|H39DE98 +39DE98:lI111|H39DF18 +39DF18:lI114|H39DFA8 +39DFA8:lI108|H39E050 +39E050:lI100|H39E100 +39E100:lI47|H39E1C4 +39E1C4:lI120|H39E2A0 +39E2A0:lI45|H39E394 +39E394:lI118|H39E490 +39E490:lI114|H39E598 +39E598:lI109|H39E6AC +39E6AC:lI108|N +39DD48:lI118|H39DDB0 +39DDB0:lI114|H39DE18 +39DE18:lI109|H39DE90 +39DE90:lI108|N +39DCF0:lH39DD58|H39DD64 +39DD58:t2:H39DDC0,H39DDC8 +39DDC8:lI120|H39DE30 +39DE30:lI45|H39DEA8 +39DEA8:lI99|H39DF20 +39DF20:lI111|H39DFB0 +39DFB0:lI110|H39E058 +39E058:lI102|H39E108 +39E108:lI101|H39E1CC +39E1CC:lI114|H39E2A8 +39E2A8:lI101|H39E39C +39E39C:lI110|H39E498 +39E498:lI99|H39E5A0 +39E5A0:lI101|H39E6B4 +39E6B4:lI47|H39E7C0 +39E7C0:lI120|H39E8D4 +39E8D4:lI45|H39E9E8 +39E9E8:lI99|H39EADC +39EADC:lI111|H39EBD0 +39EBD0:lI111|H39ECC4 +39ECC4:lI108|H39EDB8 +39EDB8:lI116|H39EE8C +39EE8C:lI97|H39EF60 +39EF60:lI108|H39F03C +39F03C:lI107|N +39DDC0:lI105|H39DE28 +39DE28:lI99|H39DEA0 +39DEA0:lI101|N +39DD64:lH39DDD0|H39DDDC +39DDD0:t2:H39DE38,H39DE40 +39DE40:lI118|H39DEB8 +39DEB8:lI105|H39DF30 +39DF30:lI100|H39DFC0 +39DFC0:lI101|H39E068 +39E068:lI111|H39E110 +39E110:lI47|H39E1D4 +39E1D4:lI120|H39E2B0 +39E2B0:lI45|H39E3A4 +39E3A4:lI115|H39E4A0 +39E4A0:lI103|H39E5A8 +39E5A8:lI105|H39E6BC +39E6BC:lI45|H39E7C8 +39E7C8:lI109|H39E8DC +39E8DC:lI111|H39E9F0 +39E9F0:lI118|H39EAE4 +39EAE4:lI105|H39EBD8 +39EBD8:lI101|N +39DE38:lI109|H39DEB0 +39DEB0:lI111|H39DF28 +39DF28:lI118|H39DFB8 +39DFB8:lI105|H39E060 +39E060:lI101|N +39DDDC:lH39DE48|H39DE54 +39DE48:t2:H39DEC0,H39DEC8 +39DEC8:lI118|H39DF40 +39DF40:lI105|H39DFD0 +39DFD0:lI100|H39E070 +39E070:lI101|H39E118 +39E118:lI111|H39E1DC +39E1DC:lI47|H39E2B8 +39E2B8:lI120|H39E3AC +39E3AC:lI45|H39E4A8 +39E4A8:lI109|H39E5B0 +39E5B0:lI115|H39E6C4 +39E6C4:lI118|H39E7D0 +39E7D0:lI105|H39E8E4 +39E8E4:lI100|H39E9F8 +39E9F8:lI101|H39EAEC +39EAEC:lI111|N +39DEC0:lI97|H39DF38 +39DF38:lI118|H39DFC8 +39DFC8:lI105|N +39DE54:lH39DED0|H39DEDC +39DED0:t2:H39DF48,H39DF50 +39DF50:lI118|H39DFE0 +39DFE0:lI105|H39E078 +39E078:lI100|H39E120 +39E120:lI101|H39E1E4 +39E1E4:lI111|H39E2C0 +39E2C0:lI47|H39E3B4 +39E3B4:lI113|H39E4B0 +39E4B0:lI117|H39E5B8 +39E5B8:lI105|H39E6CC +39E6CC:lI99|H39E7D8 +39E7D8:lI107|H39E8EC +39E8EC:lI116|H39EA00 +39EA00:lI105|H39EAF4 +39EAF4:lI109|H39EBE0 +39EBE0:lI101|N +39DF48:lI113|H39DFD8 +39DFD8:lI116|N +39DEDC:lH39DF58|H39DF64 +39DF58:t2:H39DFE8,H39DFF0 +39DFF0:lI118|H39E088 +39E088:lI105|H39E130 +39E130:lI100|H39E1EC +39E1EC:lI101|H39E2C8 +39E2C8:lI111|H39E3BC +39E3BC:lI47|H39E4B8 +39E4B8:lI113|H39E5C0 +39E5C0:lI117|H39E6D4 +39E6D4:lI105|H39E7E0 +39E7E0:lI99|H39E8F4 +39E8F4:lI107|H39EA08 +39EA08:lI116|H39EAFC +39EAFC:lI105|H39EBE8 +39EBE8:lI109|H39ECCC +39ECCC:lI101|N +39DFE8:lI109|H39E080 +39E080:lI111|H39E128 +39E128:lI118|N +39DF64:lH39DFF8|H39E004 +39DFF8:t2:H39E090,H39E098 +39E098:lI118|H39E140 +39E140:lI105|H39E1FC +39E1FC:lI100|H39E2D8 +39E2D8:lI101|H39E3C4 +39E3C4:lI111|H39E4C0 +39E4C0:lI47|H39E5C8 +39E5C8:lI109|H39E6DC +39E6DC:lI112|H39E7E8 +39E7E8:lI101|H39E8FC +39E8FC:lI103|N +39E090:lI109|H39E138 +39E138:lI112|H39E1F4 +39E1F4:lI101|H39E2D0 +39E2D0:lI103|N +39E004:lH39E0A0|H39E0AC +39E0A0:t2:H39E148,H39E150 +39E150:lI118|H39E20C +39E20C:lI105|H39E2E8 +39E2E8:lI100|H39E3CC +39E3CC:lI101|H39E4C8 +39E4C8:lI111|H39E5D0 +39E5D0:lI47|H39E6E4 +39E6E4:lI109|H39E7F0 +39E7F0:lI112|H39E904 +39E904:lI101|H39EA10 +39EA10:lI103|N +39E148:lI109|H39E204 +39E204:lI112|H39E2E0 +39E2E0:lI103|N +39E0AC:lH39E158|H39E164 +39E158:t2:H39E214,H39E21C +39E21C:lI118|H39E2F8 +39E2F8:lI105|H39E3DC +39E3DC:lI100|H39E4D0 +39E4D0:lI101|H39E5D8 +39E5D8:lI111|H39E6EC +39E6EC:lI47|H39E7F8 +39E7F8:lI109|H39E90C +39E90C:lI112|H39EA18 +39EA18:lI101|H39EB04 +39EB04:lI103|N +39E214:lI109|H39E2F0 +39E2F0:lI112|H39E3D4 +39E3D4:lI101|N +39E164:lH39E224|H39E230 +39E224:t2:H39E300,H39E308 +39E308:lI116|H39E3EC +39E3EC:lI101|H39E4E0 +39E4E0:lI120|H39E5E8 +39E5E8:lI116|H39E6F4 +39E6F4:lI47|H39E800 +39E800:lI120|H39E914 +39E914:lI45|H39EA20 +39EA20:lI115|H39EB0C +39EB0C:lI103|H39EBF0 +39EBF0:lI109|H39ECD4 +39ECD4:lI108|N +39E300:lI115|H39E3E4 +39E3E4:lI103|H39E4D8 +39E4D8:lI109|H39E5E0 +39E5E0:lI108|N +39E230:lH39E310|H39E31C +39E310:t2:H39E3F4,H39E3FC +39E3FC:lI116|H39E4F0 +39E4F0:lI101|H39E5F8 +39E5F8:lI120|H39E6FC +39E6FC:lI116|H39E808 +39E808:lI47|H39E91C +39E91C:lI120|H39EA28 +39EA28:lI45|H39EB14 +39EB14:lI115|H39EBF8 +39EBF8:lI103|H39ECDC +39ECDC:lI109|H39EDC0 +39EDC0:lI108|N +39E3F4:lI115|H39E4E8 +39E4E8:lI103|H39E5F0 +39E5F0:lI109|N +39E31C:lH39E404|H39E410 +39E404:t2:H39E4F8,H39E500 +39E500:lI116|H39E608 +39E608:lI101|H39E70C +39E70C:lI120|H39E810 +39E810:lI116|H39E924 +39E924:lI47|H39EA30 +39EA30:lI120|H39EB1C +39EB1C:lI45|H39EC00 +39EC00:lI115|H39ECE4 +39ECE4:lI101|H39EDC8 +39EDC8:lI116|H39EE94 +39EE94:lI101|H39EF68 +39EF68:lI120|H39F044 +39F044:lI116|N +39E4F8:lI101|H39E600 +39E600:lI116|H39E704 +39E704:lI120|N +39E410:lH39E508|H39E514 +39E508:t2:H39E610,H39E618 +39E618:lI116|H39E71C +39E71C:lI101|H39E820 +39E820:lI120|H39E92C +39E92C:lI116|H39EA38 +39EA38:lI47|H39EB24 +39EB24:lI116|H39EC08 +39EC08:lI97|H39ECEC +39ECEC:lI98|H39EDD0 +39EDD0:lI45|H39EE9C +39EE9C:lI115|H39EF70 +39EF70:lI101|H39F04C +39F04C:lI112|H39F120 +39F120:lI97|H39F1F4 +39F1F4:lI114|H39F2C0 +39F2C0:lI97|H39F37C +39F37C:lI116|H39F440 +39F440:lI101|H39F50C +39F50C:lI100|H39F5D0 +39F5D0:lI45|H39F6A4 +39F6A4:lI118|H39F778 +39F778:lI97|H39F84C +39F84C:lI108|H39F930 +39F930:lI117|H39FA0C +39FA0C:lI101|H39FAE0 +39FAE0:lI115|N +39E610:lI116|H39E714 +39E714:lI115|H39E818 +39E818:lI118|N +39E514:lH39E620|H39E62C +39E620:t2:H39E724,H39E72C +39E72C:lI116|H39E830 +39E830:lI101|H39E93C +39E93C:lI120|H39EA40 +39EA40:lI116|H39EB2C +39EB2C:lI47|H39EC10 +39EC10:lI114|H39ECF4 +39ECF4:lI105|H39EDD8 +39EDD8:lI99|H39EEA4 +39EEA4:lI104|H39EF78 +39EF78:lI116|H39F054 +39F054:lI101|H39F128 +39F128:lI120|H39F1FC +39F1FC:lI116|N +39E724:lI114|H39E828 +39E828:lI116|H39E934 +39E934:lI120|N +39E62C:lH39E734|H39E740 +39E734:t2:H39E838,H39E840 +39E840:lI116|H39E94C +39E94C:lI101|H39EA50 +39EA50:lI120|H39EB34 +39EB34:lI116|H39EC18 +39EC18:lI47|H39ECFC +39ECFC:lI112|H39EDE0 +39EDE0:lI108|H39EEAC +39EEAC:lI97|H39EF80 +39EF80:lI105|H39F05C +39F05C:lI110|N +39E838:lI116|H39E944 +39E944:lI120|H39EA48 +39EA48:lI116|N +39E740:lH39E848|H39E854 +39E848:t2:H39E954,H39E95C +39E95C:lI116|H39EA60 +39EA60:lI101|H39EB44 +39EB44:lI120|H39EC28 +39EC28:lI116|H39ED0C +39ED0C:lI47|H39EDE8 +39EDE8:lI120|H39EEB4 +39EEB4:lI45|H39EF88 +39EF88:lI115|H39F064 +39F064:lI101|H39F130 +39F130:lI114|H39F204 +39F204:lI118|H39F2C8 +39F2C8:lI101|H39F384 +39F384:lI114|H39F448 +39F448:lI45|H39F514 +39F514:lI112|H39F5D8 +39F5D8:lI97|H39F6AC +39F6AC:lI114|H39F780 +39F780:lI115|H39F854 +39F854:lI101|H39F938 +39F938:lI100|H39FA14 +39FA14:lI45|H39FAE8 +39FAE8:lI104|H39FBBC +39FBBC:lI116|H39FC88 +39FC88:lI109|H39FD4C +39FD4C:lI108|N +39E954:lI115|H39EA58 +39EA58:lI104|H39EB3C +39EB3C:lI116|H39EC20 +39EC20:lI109|H39ED04 +39ED04:lI108|N +39E854:lH39E964|H39E970 +39E964:t2:H39EA68,H39EA70 +39EA70:lI116|H39EB54 +39EB54:lI101|H39EC38 +39EC38:lI120|H39ED1C +39ED1C:lI116|H39EDF0 +39EDF0:lI47|H39EEBC +39EEBC:lI104|H39EF90 +39EF90:lI116|H39F06C +39F06C:lI109|H39F138 +39F138:lI108|N +39EA68:lI104|H39EB4C +39EB4C:lI116|H39EC30 +39EC30:lI109|H39ED14 +39ED14:lI108|N +39E970:lH39EA78|H39EA84 +39EA78:t2:H39EB5C,H39EB64 +39EB64:lI116|H39EC48 +39EC48:lI101|H39ED2C +39ED2C:lI120|H39EDF8 +39EDF8:lI116|H39EEC4 +39EEC4:lI47|H39EF98 +39EF98:lI104|H39F074 +39F074:lI116|H39F140 +39F140:lI109|H39F20C +39F20C:lI108|N +39EB5C:lI104|H39EC40 +39EC40:lI116|H39ED24 +39ED24:lI109|N +39EA84:lH39EB6C|H39EB78 +39EB6C:t2:H39EC50,H39EC58 +39EC58:lI105|H39ED3C +39ED3C:lI109|H39EE08 +39EE08:lI97|H39EECC +39EECC:lI103|H39EFA0 +39EFA0:lI101|H39F07C +39F07C:lI47|H39F148 +39F148:lI120|H39F214 +39F214:lI45|H39F2D0 +39F2D0:lI120|H39F38C +39F38C:lI119|H39F450 +39F450:lI105|H39F51C +39F51C:lI110|H39F5E0 +39F5E0:lI100|H39F6B4 +39F6B4:lI111|H39F788 +39F788:lI119|H39F85C +39F85C:lI100|H39F940 +39F940:lI117|H39FA1C +39FA1C:lI109|H39FAF0 +39FAF0:lI112|N +39EC50:lI120|H39ED34 +39ED34:lI119|H39EE00 +39EE00:lI100|N +39EB78:lH39EC60|H39EC6C +39EC60:t2:H39ED44,H39ED4C +39ED4C:lI105|H39EE18 +39EE18:lI109|H39EEDC +39EEDC:lI97|H39EFA8 +39EFA8:lI103|H39F084 +39F084:lI101|H39F150 +39F150:lI47|H39F21C +39F21C:lI120|H39F2D8 +39F2D8:lI45|H39F394 +39F394:lI120|H39F458 +39F458:lI112|H39F524 +39F524:lI105|H39F5E8 +39F5E8:lI120|H39F6BC +39F6BC:lI109|H39F790 +39F790:lI97|H39F864 +39F864:lI112|N +39ED44:lI120|H39EE10 +39EE10:lI112|H39EED4 +39EED4:lI109|N +39EC6C:lH39ED54|H39ED60 +39ED54:t2:H39EE20,H39EE28 +39EE28:lI105|H39EEEC +39EEEC:lI109|H39EFB8 +39EFB8:lI97|H39F08C +39F08C:lI103|H39F158 +39F158:lI101|H39F224 +39F224:lI47|H39F2E0 +39F2E0:lI120|H39F39C +39F39C:lI45|H39F460 +39F460:lI120|H39F52C +39F52C:lI98|H39F5F0 +39F5F0:lI105|H39F6C4 +39F6C4:lI116|H39F798 +39F798:lI109|H39F86C +39F86C:lI97|H39F948 +39F948:lI112|N +39EE20:lI120|H39EEE4 +39EEE4:lI98|H39EFB0 +39EFB0:lI109|N +39ED60:lH39EE30|H39EE3C +39EE30:t2:H39EEF4,H39EEFC +39EEFC:lI105|H39EFC8 +39EFC8:lI109|H39F09C +39F09C:lI97|H39F160 +39F160:lI103|H39F22C +39F22C:lI101|H39F2E8 +39F2E8:lI47|H39F3A4 +39F3A4:lI120|H39F468 +39F468:lI45|H39F534 +39F534:lI114|H39F5F8 +39F5F8:lI103|H39F6CC +39F6CC:lI98|N +39EEF4:lI114|H39EFC0 +39EFC0:lI103|H39F094 +39F094:lI98|N +39EE3C:lH39EF04|H39EF10 +39EF04:t2:H39EFD0,H39EFD8 +39EFD8:lI105|H39F0AC +39F0AC:lI109|H39F170 +39F170:lI97|H39F234 +39F234:lI103|H39F2F0 +39F2F0:lI101|H39F3AC +39F3AC:lI47|H39F470 +39F470:lI120|H39F53C +39F53C:lI45|H39F600 +39F600:lI112|H39F6D4 +39F6D4:lI111|H39F7A0 +39F7A0:lI114|H39F874 +39F874:lI116|H39F950 +39F950:lI97|H39FA24 +39FA24:lI98|H39FAF8 +39FAF8:lI108|H39FBC4 +39FBC4:lI101|H39FC90 +39FC90:lI45|H39FD54 +39FD54:lI112|H39FE18 +39FE18:lI105|H39FECC +39FECC:lI120|H39FF88 +39FF88:lI109|H3A003C +3A003C:lI97|H3A00E8 +3A00E8:lI112|N +39EFD0:lI112|H39F0A4 +39F0A4:lI112|H39F168 +39F168:lI109|N +39EF10:lH39EFE0|H39EFEC +39EFE0:t2:H39F0B4,H39F0BC +39F0BC:lI105|H39F180 +39F180:lI109|H39F244 +39F244:lI97|H39F2F8 +39F2F8:lI103|H39F3B4 +39F3B4:lI101|H39F478 +39F478:lI47|H39F544 +39F544:lI120|H39F608 +39F608:lI45|H39F6DC +39F6DC:lI112|H39F7A8 +39F7A8:lI111|H39F87C +39F87C:lI114|H39F958 +39F958:lI116|H39FA2C +39FA2C:lI97|H39FB00 +39FB00:lI98|H39FBCC +39FBCC:lI108|H39FC98 +39FC98:lI101|H39FD5C +39FD5C:lI45|H39FE20 +39FE20:lI103|H39FED4 +39FED4:lI114|H39FF90 +39FF90:lI97|H3A0044 +3A0044:lI121|H3A00F0 +3A00F0:lI109|H3A0194 +3A0194:lI97|H3A0248 +3A0248:lI112|N +39F0B4:lI112|H39F178 +39F178:lI103|H39F23C +39F23C:lI109|N +39EFEC:lH39F0C4|H39F0D0 +39F0C4:t2:H39F188,H39F190 +39F190:lI105|H39F254 +39F254:lI109|H39F308 +39F308:lI97|H39F3BC +39F3BC:lI103|H39F480 +39F480:lI101|H39F54C +39F54C:lI47|H39F610 +39F610:lI120|H39F6E4 +39F6E4:lI45|H39F7B0 +39F7B0:lI112|H39F884 +39F884:lI111|H39F960 +39F960:lI114|H39FA34 +39FA34:lI116|H39FB08 +39FB08:lI97|H39FBD4 +39FBD4:lI98|H39FCA0 +39FCA0:lI108|H39FD64 +39FD64:lI101|H39FE28 +39FE28:lI45|H39FEDC +39FEDC:lI98|H39FF98 +39FF98:lI105|H3A004C +3A004C:lI116|H3A00F8 +3A00F8:lI109|H3A019C +3A019C:lI97|H3A0250 +3A0250:lI112|N +39F188:lI112|H39F24C +39F24C:lI98|H39F300 +39F300:lI109|N +39F0D0:lH39F198|H39F1A4 +39F198:t2:H39F25C,H39F264 +39F264:lI105|H39F318 +39F318:lI109|H39F3CC +39F3CC:lI97|H39F488 +39F488:lI103|H39F554 +39F554:lI101|H39F618 +39F618:lI47|H39F6EC +39F6EC:lI120|H39F7B8 +39F7B8:lI45|H39F88C +39F88C:lI112|H39F968 +39F968:lI111|H39FA3C +39FA3C:lI114|H39FB10 +39FB10:lI116|H39FBDC +39FBDC:lI97|H39FCA8 +39FCA8:lI98|H39FD6C +39FD6C:lI108|H39FE30 +39FE30:lI101|H39FEE4 +39FEE4:lI45|H39FFA0 +39FFA0:lI97|H3A0054 +3A0054:lI110|H3A0100 +3A0100:lI121|H3A01A4 +3A01A4:lI109|H3A0258 +3A0258:lI97|H3A0304 +3A0304:lI112|N +39F25C:lI112|H39F310 +39F310:lI110|H39F3C4 +39F3C4:lI109|N +39F1A4:lH39F26C|H39F278 +39F26C:t2:H39F320,H39F328 +39F328:lI105|H39F3DC +39F3DC:lI109|H39F498 +39F498:lI97|H39F55C +39F55C:lI103|H39F620 +39F620:lI101|H39F6F4 +39F6F4:lI47|H39F7C0 +39F7C0:lI120|H39F894 +39F894:lI45|H39F970 +39F970:lI99|H39FA44 +39FA44:lI109|H39FB18 +39FB18:lI117|H39FBE4 +39FBE4:lI45|H39FCB0 +39FCB0:lI114|H39FD74 +39FD74:lI97|H39FE38 +39FE38:lI115|H39FEEC +39FEEC:lI116|H39FFA8 +39FFA8:lI101|H3A005C +3A005C:lI114|N +39F320:lI114|H39F3D4 +39F3D4:lI97|H39F490 +39F490:lI115|N +39F278:lH39F330|H39F33C +39F330:t2:H39F3E4,H39F3EC +39F3EC:lI105|H39F4A8 +39F4A8:lI109|H39F56C +39F56C:lI97|H39F630 +39F630:lI103|H39F6FC +39F6FC:lI101|H39F7C8 +39F7C8:lI47|H39F89C +39F89C:lI116|H39F978 +39F978:lI105|H39FA4C +39FA4C:lI102|H39FB20 +39FB20:lI102|N +39F3E4:lI116|H39F4A0 +39F4A0:lI105|H39F564 +39F564:lI102|H39F628 +39F628:lI102|N +39F33C:lH39F3F4|H39F400 +39F3F4:t2:H39F4B0,H39F4B8 +39F4B8:lI105|H39F57C +39F57C:lI109|H39F640 +39F640:lI97|H39F704 +39F704:lI103|H39F7D0 +39F7D0:lI101|H39F8A4 +39F8A4:lI47|H39F980 +39F980:lI116|H39FA54 +39FA54:lI105|H39FB28 +39FB28:lI102|H39FBEC +39FBEC:lI102|N +39F4B0:lI116|H39F574 +39F574:lI105|H39F638 +39F638:lI102|N +39F400:lH39F4C0|H39F4CC +39F4C0:t2:H39F584,H39F58C +39F58C:lI105|H39F650 +39F650:lI109|H39F714 +39F714:lI97|H39F7D8 +39F7D8:lI103|H39F8AC +39F8AC:lI101|H39F988 +39F988:lI47|H39FA5C +39FA5C:lI112|H39FB30 +39FB30:lI110|H39FBF4 +39FBF4:lI103|N +39F584:lI112|H39F648 +39F648:lI110|H39F70C +39F70C:lI103|N +39F4CC:lH39F594|H39F5A0 +39F594:t2:H39F658,H39F660 +39F660:lI105|H39F724 +39F724:lI109|H39F7E8 +39F7E8:lI97|H39F8BC +39F8BC:lI103|H39F990 +39F990:lI101|H39FA64 +39FA64:lI47|H39FB38 +39FB38:lI106|H39FBFC +39FBFC:lI112|H39FCB8 +39FCB8:lI101|H39FD7C +39FD7C:lI103|N +39F658:lI106|H39F71C +39F71C:lI112|H39F7E0 +39F7E0:lI101|H39F8B4 +39F8B4:lI103|N +39F5A0:lH39F668|H39F674 +39F668:t2:H39F72C,H39F734 +39F734:lI105|H39F7F8 +39F7F8:lI109|H39F8CC +39F8CC:lI97|H39F998 +39F998:lI103|H39FA6C +39FA6C:lI101|H39FB40 +39FB40:lI47|H39FC04 +39FC04:lI106|H39FCC0 +39FCC0:lI112|H39FD84 +39FD84:lI101|H39FE40 +39FE40:lI103|N +39F72C:lI106|H39F7F0 +39F7F0:lI112|H39F8C4 +39F8C4:lI103|N +39F674:lH39F73C|H39F748 +39F73C:t2:H39F800,H39F808 +39F808:lI105|H39F8DC +39F8DC:lI109|H39F9A8 +39F9A8:lI97|H39FA74 +39FA74:lI103|H39FB48 +39FB48:lI101|H39FC0C +39FC0C:lI47|H39FCC8 +39FCC8:lI106|H39FD8C +39FD8C:lI112|H39FE48 +39FE48:lI101|H39FEF4 +39FEF4:lI103|N +39F800:lI106|H39F8D4 +39F8D4:lI112|H39F9A0 +39F9A0:lI101|N +39F748:lH39F810|H39F81C +39F810:t2:H39F8E4,H39F8EC +39F8EC:lI105|H39F9B8 +39F9B8:lI109|H39FA84 +39FA84:lI97|H39FB50 +39FB50:lI103|H39FC14 +39FC14:lI101|H39FCD0 +39FCD0:lI47|H39FD94 +39FD94:lI105|H39FE50 +39FE50:lI101|H39FEFC +39FEFC:lI102|N +39F8E4:lI105|H39F9B0 +39F9B0:lI101|H39FA7C +39FA7C:lI102|N +39F81C:lH39F8F4|H39F900 +39F8F4:t2:H39F9C0,H39F9C8 +39F9C8:lI105|H39FA94 +39FA94:lI109|H39FB60 +39FB60:lI97|H39FC1C +39FC1C:lI103|H39FCD8 +39FCD8:lI101|H39FD9C +39FD9C:lI47|H39FE58 +39FE58:lI103|H39FF04 +39FF04:lI105|H39FFB0 +39FFB0:lI102|N +39F9C0:lI103|H39FA8C +39FA8C:lI105|H39FB58 +39FB58:lI102|N +39F900:lH39F9D0|H39F9DC +39F9D0:t2:H39FA9C,H39FAA4 +39FAA4:lI99|H39FB70 +39FB70:lI104|H39FC2C +39FC2C:lI101|H39FCE0 +39FCE0:lI109|H39FDA4 +39FDA4:lI105|H39FE60 +39FE60:lI99|H39FF0C +39FF0C:lI97|H39FFB8 +39FFB8:lI108|H3A0064 +3A0064:lI47|H3A0108 +3A0108:lI120|H3A01AC +3A01AC:lI45|H3A0260 +3A0260:lI112|H3A030C +3A030C:lI100|H3A03B8 +3A03B8:lI98|N +39FA9C:lI112|H39FB68 +39FB68:lI100|H39FC24 +39FC24:lI98|N +39F9DC:lH39FAAC|H39FAB8 +39FAAC:t2:H39FB78,H39FB80 +39FB80:lI99|H39FC3C +39FC3C:lI104|H39FCF0 +39FCF0:lI101|H39FDAC +39FDAC:lI109|H39FE68 +39FE68:lI105|H39FF14 +39FF14:lI99|H39FFC0 +39FFC0:lI97|H3A006C +3A006C:lI108|H3A0110 +3A0110:lI47|H3A01B4 +3A01B4:lI120|H3A0268 +3A0268:lI45|H3A0314 +3A0314:lI112|H3A03C0 +3A03C0:lI100|H3A0454 +3A0454:lI98|N +39FB78:lI120|H39FC34 +39FC34:lI121|H39FCE8 +39FCE8:lI122|N +39FAB8:lH39FB88|H39FB94 +39FB88:t2:H39FC44,H39FC4C +39FC4C:lI97|H39FD00 +39FD00:lI117|H39FDBC +39FDBC:lI100|H39FE70 +39FE70:lI105|H39FF1C +39FF1C:lI111|H39FFC8 +39FFC8:lI47|H3A0074 +3A0074:lI120|H3A0118 +3A0118:lI45|H3A01BC +3A01BC:lI119|H3A0270 +3A0270:lI97|H3A031C +3A031C:lI118|N +39FC44:lI119|H39FCF8 +39FCF8:lI97|H39FDB4 +39FDB4:lI118|N +39FB94:lH39FC54|H39FC60 +39FC54:t2:H39FD08,H39FD10 +39FD10:lI97|H39FDCC +39FDCC:lI117|H39FE78 +39FE78:lI100|H39FF24 +39FF24:lI105|H39FFD0 +39FFD0:lI111|H3A007C +3A007C:lI47|H3A0120 +3A0120:lI120|H3A01C4 +3A01C4:lI45|H3A0278 +3A0278:lI114|H3A0324 +3A0324:lI101|H3A03C8 +3A03C8:lI97|H3A045C +3A045C:lI108|H3A04F8 +3A04F8:lI97|H3A059C +3A059C:lI117|H3A0648 +3A0648:lI100|H3A06F4 +3A06F4:lI105|H3A07A0 +3A07A0:lI111|N +39FD08:lI114|H39FDC4 +39FDC4:lI97|N +39FC60:lH39FD18|H39FD24 +39FD18:t2:H39FDD4,H39FDDC +39FDDC:lI97|H39FE88 +39FE88:lI117|H39FF34 +39FF34:lI100|H39FFD8 +39FFD8:lI105|H3A0084 +3A0084:lI111|H3A0128 +3A0128:lI47|H3A01CC +3A01CC:lI120|H3A0280 +3A0280:lI45|H3A032C +3A032C:lI112|H3A03D0 +3A03D0:lI110|H3A0464 +3A0464:lI45|H3A0500 +3A0500:lI114|H3A05A4 +3A05A4:lI101|H3A0650 +3A0650:lI97|H3A06FC +3A06FC:lI108|H3A07A8 +3A07A8:lI97|H3A0844 +3A0844:lI117|H3A08D0 +3A08D0:lI100|H3A0964 +3A0964:lI105|H3A09F8 +3A09F8:lI111|H3A0A94 +3A0A94:lI45|H3A0B40 +3A0B40:lI112|H3A0BEC +3A0BEC:lI108|H3A0CA8 +3A0CA8:lI117|H3A0D64 +3A0D64:lI103|H3A0E18 +3A0E18:lI105|H3A0ECC +3A0ECC:lI110|N +39FDD4:lI114|H39FE80 +39FE80:lI112|H39FF2C +39FF2C:lI109|N +39FD24:lH39FDE4|H39FDF0 +39FDE4:t2:H39FE90,H39FE98 +39FE98:lI97|H39FF44 +39FF44:lI117|H39FFE8 +39FFE8:lI100|H3A008C +3A008C:lI105|H3A0130 +3A0130:lI111|H3A01D4 +3A01D4:lI47|H3A0288 +3A0288:lI120|H3A0334 +3A0334:lI45|H3A03D8 +3A03D8:lI112|H3A046C +3A046C:lI110|H3A0508 +3A0508:lI45|H3A05AC +3A05AC:lI114|H3A0658 +3A0658:lI101|H3A0704 +3A0704:lI97|H3A07B0 +3A07B0:lI108|H3A084C +3A084C:lI97|H3A08D8 +3A08D8:lI117|H3A096C +3A096C:lI100|H3A0A00 +3A0A00:lI105|H3A0A9C +3A0A9C:lI111|N +39FE90:lI114|H39FF3C +39FF3C:lI97|H39FFE0 +39FFE0:lI109|N +39FDF0:lH39FEA0|H39FEAC +39FEA0:t2:H39FF4C,H39FF54 +39FF54:lI97|H39FFF8 +39FFF8:lI117|H3A009C +3A009C:lI100|H3A0138 +3A0138:lI105|H3A01DC +3A01DC:lI111|H3A0290 +3A0290:lI47|H3A033C +3A033C:lI120|H3A03E0 +3A03E0:lI45|H3A0474 +3A0474:lI97|H3A0510 +3A0510:lI105|H3A05B4 +3A05B4:lI102|H3A0660 +3A0660:lI102|N +39FF4C:lI97|H39FFF0 +39FFF0:lI105|H3A0094 +3A0094:lI102|N +39FEAC:lH39FF5C|H39FF68 +39FF5C:t2:H3A0000,H3A0008 +3A0008:lI97|H3A00AC +3A00AC:lI117|H3A0148 +3A0148:lI100|H3A01EC +3A01EC:lI105|H3A0298 +3A0298:lI111|H3A0344 +3A0344:lI47|H3A03E8 +3A03E8:lI120|H3A047C +3A047C:lI45|H3A0518 +3A0518:lI97|H3A05BC +3A05BC:lI105|H3A0668 +3A0668:lI102|H3A070C +3A070C:lI102|N +3A0000:lI97|H3A00A4 +3A00A4:lI105|H3A0140 +3A0140:lI102|H3A01E4 +3A01E4:lI102|N +39FF68:lH3A0010|H3A001C +3A0010:t2:H3A00B4,H3A00BC +3A00BC:lI97|H3A0158 +3A0158:lI117|H3A01FC +3A01FC:lI100|H3A02A8 +3A02A8:lI105|H3A034C +3A034C:lI111|H3A03F0 +3A03F0:lI47|H3A0484 +3A0484:lI120|H3A0520 +3A0520:lI45|H3A05C4 +3A05C4:lI97|H3A0670 +3A0670:lI105|H3A0714 +3A0714:lI102|H3A07B8 +3A07B8:lI102|N +3A00B4:lI97|H3A0150 +3A0150:lI105|H3A01F4 +3A01F4:lI102|H3A02A0 +3A02A0:lI99|N +3A001C:lH3A00C4|H3A00D0 +3A00C4:t2:H3A0160,H3A0168 +3A0168:lI97|H3A020C +3A020C:lI117|H3A02B8 +3A02B8:lI100|H3A035C +3A035C:lI105|H3A03F8 +3A03F8:lI111|H3A048C +3A048C:lI47|H3A0528 +3A0528:lI109|H3A05CC +3A05CC:lI112|H3A0678 +3A0678:lI101|H3A071C +3A071C:lI103|N +3A0160:lI109|H3A0204 +3A0204:lI112|H3A02B0 +3A02B0:lI103|H3A0354 +3A0354:lI97|N +3A00D0:lH3A0170|H3A017C +3A0170:t2:H3A0214,H3A021C +3A021C:lI97|H3A02C8 +3A02C8:lI117|H3A036C +3A036C:lI100|H3A0400 +3A0400:lI105|H3A0494 +3A0494:lI111|H3A0530 +3A0530:lI47|H3A05D4 +3A05D4:lI109|H3A0680 +3A0680:lI112|H3A0724 +3A0724:lI101|H3A07C0 +3A07C0:lI103|N +3A0214:lI109|H3A02C0 +3A02C0:lI112|H3A0364 +3A0364:lI50|N +3A017C:lH3A0224|H3A0230 +3A0224:t2:H3A02D0,H3A02D8 +3A02D8:lI97|H3A037C +3A037C:lI117|H3A0408 +3A0408:lI100|H3A049C +3A049C:lI105|H3A0538 +3A0538:lI111|H3A05DC +3A05DC:lI47|H3A0688 +3A0688:lI98|H3A072C +3A072C:lI97|H3A07C8 +3A07C8:lI115|H3A0854 +3A0854:lI105|H3A08E0 +3A08E0:lI99|N +3A02D0:lI97|H3A0374 +3A0374:lI117|N +3A0230:lH3A02E0|H3A02EC +3A02E0:t2:H3A0384,H3A038C +3A038C:lI97|H3A0418 +3A0418:lI117|H3A04AC +3A04AC:lI100|H3A0540 +3A0540:lI105|H3A05E4 +3A05E4:lI111|H3A0690 +3A0690:lI47|H3A0734 +3A0734:lI98|H3A07D0 +3A07D0:lI97|H3A085C +3A085C:lI115|H3A08E8 +3A08E8:lI105|H3A0974 +3A0974:lI99|N +3A0384:lI115|H3A0410 +3A0410:lI110|H3A04A4 +3A04A4:lI100|N +3A02EC:lH3A0394|H3A03A0 +3A0394:t2:H3A0420,H3A0428 +3A0428:lI97|H3A04BC +3A04BC:lI112|H3A0550 +3A0550:lI112|H3A05EC +3A05EC:lI108|H3A0698 +3A0698:lI105|H3A073C +3A073C:lI99|H3A07D8 +3A07D8:lI97|H3A0864 +3A0864:lI116|H3A08F0 +3A08F0:lI105|H3A097C +3A097C:lI111|H3A0A08 +3A0A08:lI110|H3A0AA4 +3A0AA4:lI47|H3A0B48 +3A0B48:lI122|H3A0BF4 +3A0BF4:lI105|H3A0CB0 +3A0CB0:lI112|N +3A0420:lI122|H3A04B4 +3A04B4:lI105|H3A0548 +3A0548:lI112|N +3A03A0:lH3A0430|H3A043C +3A0430:t2:H3A04C4,H3A04CC +3A04CC:lI97|H3A0560 +3A0560:lI112|H3A05FC +3A05FC:lI112|H3A06A0 +3A06A0:lI108|H3A0744 +3A0744:lI105|H3A07E0 +3A07E0:lI99|H3A086C +3A086C:lI97|H3A08F8 +3A08F8:lI116|H3A0984 +3A0984:lI105|H3A0A10 +3A0A10:lI111|H3A0AAC +3A0AAC:lI110|H3A0B50 +3A0B50:lI47|H3A0BFC +3A0BFC:lI120|H3A0CB8 +3A0CB8:lI45|H3A0D6C +3A0D6C:lI119|H3A0E20 +3A0E20:lI97|H3A0ED4 +3A0ED4:lI105|H3A0F90 +3A0F90:lI115|H3A105C +3A105C:lI45|H3A1130 +3A1130:lI115|H3A1204 +3A1204:lI111|H3A12D0 +3A12D0:lI117|H3A13A4 +3A13A4:lI114|H3A1480 +3A1480:lI99|H3A1564 +3A1564:lI101|N +3A04C4:lI115|H3A0558 +3A0558:lI114|H3A05F4 +3A05F4:lI99|N +3A043C:lH3A04D4|H3A04E0 +3A04D4:t2:H3A0568,H3A0570 +3A0570:lI97|H3A060C +3A060C:lI112|H3A06B0 +3A06B0:lI112|H3A0754 +3A0754:lI108|H3A07F0 +3A07F0:lI105|H3A0874 +3A0874:lI99|H3A0900 +3A0900:lI97|H3A098C +3A098C:lI116|H3A0A18 +3A0A18:lI105|H3A0AB4 +3A0AB4:lI111|H3A0B58 +3A0B58:lI110|H3A0C04 +3A0C04:lI47|H3A0CC0 +3A0CC0:lI120|H3A0D74 +3A0D74:lI45|H3A0E28 +3A0E28:lI117|H3A0EDC +3A0EDC:lI115|H3A0F98 +3A0F98:lI116|H3A1064 +3A1064:lI97|H3A1138 +3A1138:lI114|N +3A0568:lI117|H3A0604 +3A0604:lI115|H3A06A8 +3A06A8:lI116|H3A074C +3A074C:lI97|H3A07E8 +3A07E8:lI114|N +3A04E0:lH3A0578|H3A0584 +3A0578:t2:H3A0614,H3A061C +3A061C:lI97|H3A06C0 +3A06C0:lI112|H3A075C +3A075C:lI112|H3A07F8 +3A07F8:lI108|H3A087C +3A087C:lI105|H3A0908 +3A0908:lI99|H3A0994 +3A0994:lI97|H3A0A20 +3A0A20:lI116|H3A0ABC +3A0ABC:lI105|H3A0B60 +3A0B60:lI111|H3A0C0C +3A0C0C:lI110|H3A0CC8 +3A0CC8:lI47|H3A0D7C +3A0D7C:lI120|H3A0E30 +3A0E30:lI45|H3A0EE4 +3A0EE4:lI116|H3A0FA0 +3A0FA0:lI114|H3A106C +3A106C:lI111|H3A1140 +3A1140:lI102|H3A120C +3A120C:lI102|H3A12D8 +3A12D8:lI45|H3A13AC +3A13AC:lI109|H3A1488 +3A1488:lI115|N +3A0614:lI109|H3A06B8 +3A06B8:lI115|N +3A0584:lH3A0624|H3A0630 +3A0624:t2:H3A06C8,H3A06D0 +3A06D0:lI97|H3A076C +3A076C:lI112|H3A0800 +3A0800:lI112|H3A0884 +3A0884:lI108|H3A0910 +3A0910:lI105|H3A099C +3A099C:lI99|H3A0A28 +3A0A28:lI97|H3A0AC4 +3A0AC4:lI116|H3A0B68 +3A0B68:lI105|H3A0C14 +3A0C14:lI111|H3A0CD0 +3A0CD0:lI110|H3A0D84 +3A0D84:lI47|H3A0E38 +3A0E38:lI120|H3A0EEC +3A0EEC:lI45|H3A0FA8 +3A0FA8:lI116|H3A1074 +3A1074:lI114|H3A1148 +3A1148:lI111|H3A1214 +3A1214:lI102|H3A12E0 +3A12E0:lI102|H3A13B4 +3A13B4:lI45|H3A1490 +3A1490:lI109|H3A156C +3A156C:lI101|N +3A06C8:lI109|H3A0764 +3A0764:lI101|N +3A0630:lH3A06D8|H3A06E4 +3A06D8:t2:H3A0774,H3A077C +3A077C:lI97|H3A0810 +3A0810:lI112|H3A0894 +3A0894:lI112|H3A0918 +3A0918:lI108|H3A09A4 +3A09A4:lI105|H3A0A30 +3A0A30:lI99|H3A0ACC +3A0ACC:lI97|H3A0B70 +3A0B70:lI116|H3A0C1C +3A0C1C:lI105|H3A0CD8 +3A0CD8:lI111|H3A0D8C +3A0D8C:lI110|H3A0E40 +3A0E40:lI47|H3A0EF4 +3A0EF4:lI120|H3A0FB0 +3A0FB0:lI45|H3A107C +3A107C:lI116|H3A1150 +3A1150:lI114|H3A121C +3A121C:lI111|H3A12E8 +3A12E8:lI102|H3A13BC +3A13BC:lI102|H3A1498 +3A1498:lI45|H3A1574 +3A1574:lI109|H3A1648 +3A1648:lI97|H3A171C +3A171C:lI110|N +3A0774:lI109|H3A0808 +3A0808:lI97|H3A088C +3A088C:lI110|N +3A06E4:lH3A0784|H3A0790 +3A0784:t2:H3A0818,H3A0820 +3A0820:lI97|H3A089C +3A089C:lI112|H3A0920 +3A0920:lI112|H3A09AC +3A09AC:lI108|H3A0A38 +3A0A38:lI105|H3A0AD4 +3A0AD4:lI99|H3A0B78 +3A0B78:lI97|H3A0C24 +3A0C24:lI116|H3A0CE0 +3A0CE0:lI105|H3A0D94 +3A0D94:lI111|H3A0E48 +3A0E48:lI110|H3A0EFC +3A0EFC:lI47|H3A0FB8 +3A0FB8:lI120|H3A1084 +3A1084:lI45|H3A1158 +3A1158:lI116|H3A1224 +3A1224:lI114|H3A12F0 +3A12F0:lI111|H3A13C4 +3A13C4:lI102|H3A14A0 +3A14A0:lI102|N +3A0818:lI116|N +3A0790:lH3A0828|H3A0834 +3A0828:t2:H3A08A4,H3A08AC +3A08AC:lI97|H3A0930 +3A0930:lI112|H3A09B4 +3A09B4:lI112|H3A0A40 +3A0A40:lI108|H3A0ADC +3A0ADC:lI105|H3A0B80 +3A0B80:lI99|H3A0C2C +3A0C2C:lI97|H3A0CE8 +3A0CE8:lI116|H3A0D9C +3A0D9C:lI105|H3A0E50 +3A0E50:lI111|H3A0F04 +3A0F04:lI110|H3A0FC0 +3A0FC0:lI47|H3A108C +3A108C:lI120|H3A1160 +3A1160:lI45|H3A122C +3A122C:lI116|H3A12F8 +3A12F8:lI114|H3A13CC +3A13CC:lI111|H3A14A8 +3A14A8:lI102|H3A157C +3A157C:lI102|N +3A08A4:lI116|H3A0928 +3A0928:lI114|N +3A0834:lH3A08B4|H3A08C0 +3A08B4:t2:H3A0938,H3A0940 +3A0940:lI97|H3A09C4 +3A09C4:lI112|H3A0A50 +3A0A50:lI112|H3A0AEC +3A0AEC:lI108|H3A0B88 +3A0B88:lI105|H3A0C34 +3A0C34:lI99|H3A0CF0 +3A0CF0:lI97|H3A0DA4 +3A0DA4:lI116|H3A0E58 +3A0E58:lI105|H3A0F0C +3A0F0C:lI111|H3A0FC8 +3A0FC8:lI110|H3A1094 +3A1094:lI47|H3A1168 +3A1168:lI120|H3A1234 +3A1234:lI45|H3A1300 +3A1300:lI116|H3A13D4 +3A13D4:lI114|H3A14B0 +3A14B0:lI111|H3A1584 +3A1584:lI102|H3A1650 +3A1650:lI102|N +3A0938:lI114|H3A09BC +3A09BC:lI111|H3A0A48 +3A0A48:lI102|H3A0AE4 +3A0AE4:lI102|N +3A08C0:lH3A0948|H3A0954 +3A0948:t2:H3A09CC,H3A09D4 +3A09D4:lI97|H3A0A60 +3A0A60:lI112|H3A0AFC +3A0AFC:lI112|H3A0B98 +3A0B98:lI108|H3A0C44 +3A0C44:lI105|H3A0D00 +3A0D00:lI99|H3A0DB4 +3A0DB4:lI97|H3A0E60 +3A0E60:lI116|H3A0F14 +3A0F14:lI105|H3A0FD0 +3A0FD0:lI111|H3A109C +3A109C:lI110|H3A1170 +3A1170:lI47|H3A123C +3A123C:lI120|H3A1308 +3A1308:lI45|H3A13DC +3A13DC:lI116|H3A14B8 +3A14B8:lI101|H3A158C +3A158C:lI120|H3A1658 +3A1658:lI105|H3A1724 +3A1724:lI110|H3A17E8 +3A17E8:lI102|H3A18AC +3A18AC:lI111|N +3A09CC:lI116|H3A0A58 +3A0A58:lI101|H3A0AF4 +3A0AF4:lI120|H3A0B90 +3A0B90:lI105|H3A0C3C +3A0C3C:lI110|H3A0CF8 +3A0CF8:lI102|H3A0DAC +3A0DAC:lI111|N +3A0954:lH3A09DC|H3A09E8 +3A09DC:t2:H3A0A68,H3A0A70 +3A0A70:lI97|H3A0B0C +3A0B0C:lI112|H3A0BA8 +3A0BA8:lI112|H3A0C54 +3A0C54:lI108|H3A0D08 +3A0D08:lI105|H3A0DBC +3A0DBC:lI99|H3A0E68 +3A0E68:lI97|H3A0F1C +3A0F1C:lI116|H3A0FD8 +3A0FD8:lI105|H3A10A4 +3A10A4:lI111|H3A1178 +3A1178:lI110|H3A1244 +3A1244:lI47|H3A1310 +3A1310:lI120|H3A13E4 +3A13E4:lI45|H3A14C0 +3A14C0:lI116|H3A1594 +3A1594:lI101|H3A1660 +3A1660:lI120|H3A172C +3A172C:lI105|H3A17F0 +3A17F0:lI110|H3A18B4 +3A18B4:lI102|H3A1970 +3A1970:lI111|N +3A0A68:lI116|H3A0B04 +3A0B04:lI101|H3A0BA0 +3A0BA0:lI120|H3A0C4C +3A0C4C:lI105|N +3A09E8:lH3A0A78|H3A0A84 +3A0A78:t2:H3A0B14,H3A0B1C +3A0B1C:lI97|H3A0BB8 +3A0BB8:lI112|H3A0C64 +3A0C64:lI112|H3A0D10 +3A0D10:lI108|H3A0DC4 +3A0DC4:lI105|H3A0E70 +3A0E70:lI99|H3A0F24 +3A0F24:lI97|H3A0FE0 +3A0FE0:lI116|H3A10AC +3A10AC:lI105|H3A1180 +3A1180:lI111|H3A124C +3A124C:lI110|H3A1318 +3A1318:lI47|H3A13EC +3A13EC:lI120|H3A14C8 +3A14C8:lI45|H3A159C +3A159C:lI116|H3A1668 +3A1668:lI101|H3A1734 +3A1734:lI120|N +3A0B14:lI116|H3A0BB0 +3A0BB0:lI101|H3A0C5C +3A0C5C:lI120|N +3A0A84:lH3A0B24|H3A0B30 +3A0B24:t2:H3A0BC0,H3A0BC8 +3A0BC8:lI97|H3A0C74 +3A0C74:lI112|H3A0D20 +3A0D20:lI112|H3A0DCC +3A0DCC:lI108|H3A0E78 +3A0E78:lI105|H3A0F2C +3A0F2C:lI99|H3A0FE8 +3A0FE8:lI97|H3A10B4 +3A10B4:lI116|H3A1188 +3A1188:lI105|H3A1254 +3A1254:lI111|H3A1320 +3A1320:lI110|H3A13F4 +3A13F4:lI47|H3A14D0 +3A14D0:lI120|H3A15A4 +3A15A4:lI45|H3A1670 +3A1670:lI116|H3A173C +3A173C:lI99|H3A17F8 +3A17F8:lI108|N +3A0BC0:lI116|H3A0C6C +3A0C6C:lI99|H3A0D18 +3A0D18:lI108|N +3A0B30:lH3A0BD0|H3A0BDC +3A0BD0:t2:H3A0C7C,H3A0C84 +3A0C84:lI97|H3A0D30 +3A0D30:lI112|H3A0DDC +3A0DDC:lI112|H3A0E80 +3A0E80:lI108|H3A0F34 +3A0F34:lI105|H3A0FF0 +3A0FF0:lI99|H3A10BC +3A10BC:lI97|H3A1190 +3A1190:lI116|H3A125C +3A125C:lI105|H3A1328 +3A1328:lI111|H3A13FC +3A13FC:lI110|H3A14D8 +3A14D8:lI47|H3A15AC +3A15AC:lI120|H3A1678 +3A1678:lI45|H3A1744 +3A1744:lI116|H3A1800 +3A1800:lI97|H3A18BC +3A18BC:lI114|N +3A0C7C:lI116|H3A0D28 +3A0D28:lI97|H3A0DD4 +3A0DD4:lI114|N +3A0BDC:lH3A0C8C|H3A0C98 +3A0C8C:t2:H3A0D38,H3A0D40 +3A0D40:lI97|H3A0DEC +3A0DEC:lI112|H3A0E90 +3A0E90:lI112|H3A0F44 +3A0F44:lI108|H3A1000 +3A1000:lI105|H3A10CC +3A10CC:lI99|H3A1198 +3A1198:lI97|H3A1264 +3A1264:lI116|H3A1330 +3A1330:lI105|H3A1404 +3A1404:lI111|H3A14E0 +3A14E0:lI110|H3A15B4 +3A15B4:lI47|H3A1680 +3A1680:lI120|H3A174C +3A174C:lI45|H3A1808 +3A1808:lI115|H3A18C4 +3A18C4:lI118|H3A1978 +3A1978:lI52|H3A1A2C +3A1A2C:lI99|H3A1AE0 +3A1AE0:lI114|H3A1BA4 +3A1BA4:lI99|N +3A0D38:lI115|H3A0DE4 +3A0DE4:lI118|H3A0E88 +3A0E88:lI52|H3A0F3C +3A0F3C:lI99|H3A0FF8 +3A0FF8:lI114|H3A10C4 +3A10C4:lI99|N +3A0C98:lH3A0D48|H3A0D54 +3A0D48:t2:H3A0DF4,H3A0DFC +3A0DFC:lI97|H3A0EA0 +3A0EA0:lI112|H3A0F54 +3A0F54:lI112|H3A1010 +3A1010:lI108|H3A10DC +3A10DC:lI105|H3A11A8 +3A11A8:lI99|H3A1274 +3A1274:lI97|H3A1338 +3A1338:lI116|H3A140C +3A140C:lI105|H3A14E8 +3A14E8:lI111|H3A15BC +3A15BC:lI110|H3A1688 +3A1688:lI47|H3A1754 +3A1754:lI120|H3A1810 +3A1810:lI45|H3A18CC +3A18CC:lI115|H3A1980 +3A1980:lI118|H3A1A34 +3A1A34:lI52|H3A1AE8 +3A1AE8:lI99|H3A1BAC +3A1BAC:lI112|H3A1C78 +3A1C78:lI105|H3A1D3C +3A1D3C:lI111|N +3A0DF4:lI115|H3A0E98 +3A0E98:lI118|H3A0F4C +3A0F4C:lI52|H3A1008 +3A1008:lI99|H3A10D4 +3A10D4:lI112|H3A11A0 +3A11A0:lI105|H3A126C +3A126C:lI111|N +3A0D54:lH3A0E04|H3A0E10 +3A0E04:t2:H3A0EA8,H3A0EB0 +3A0EB0:lI97|H3A0F64 +3A0F64:lI112|H3A1020 +3A1020:lI112|H3A10E4 +3A10E4:lI108|H3A11B0 +3A11B0:lI105|H3A127C +3A127C:lI99|H3A1340 +3A1340:lI97|H3A1414 +3A1414:lI116|H3A14F0 +3A14F0:lI105|H3A15C4 +3A15C4:lI111|H3A1690 +3A1690:lI110|H3A175C +3A175C:lI47|H3A1818 +3A1818:lI120|H3A18D4 +3A18D4:lI45|H3A1988 +3A1988:lI115|H3A1A3C +3A1A3C:lI116|H3A1AF0 +3A1AF0:lI117|H3A1BB4 +3A1BB4:lI102|H3A1C80 +3A1C80:lI102|H3A1D44 +3A1D44:lI105|H3A1E00 +3A1E00:lI116|N +3A0EA8:lI115|H3A0F5C +3A0F5C:lI105|H3A1018 +3A1018:lI116|N +3A0E10:lH3A0EB8|H3A0EC4 +3A0EB8:t2:H3A0F6C,H3A0F74 +3A0F74:lI97|H3A1030 +3A1030:lI112|H3A10F4 +3A10F4:lI112|H3A11C0 +3A11C0:lI108|H3A1284 +3A1284:lI105|H3A1348 +3A1348:lI99|H3A141C +3A141C:lI97|H3A14F8 +3A14F8:lI116|H3A15CC +3A15CC:lI105|H3A1698 +3A1698:lI111|H3A1764 +3A1764:lI110|H3A1820 +3A1820:lI47|H3A18DC +3A18DC:lI120|H3A1990 +3A1990:lI45|H3A1A44 +3A1A44:lI115|H3A1AF8 +3A1AF8:lI104|H3A1BBC +3A1BBC:lI97|H3A1C88 +3A1C88:lI114|N +3A0F6C:lI115|H3A1028 +3A1028:lI104|H3A10EC +3A10EC:lI97|H3A11B8 +3A11B8:lI114|N +3A0EC4:lH3A0F7C|H3A0F88 +3A0F7C:t2:H3A1038,H3A1040 +3A1040:lI97|H3A1104 +3A1104:lI112|H3A11C8 +3A11C8:lI112|H3A128C +3A128C:lI108|H3A1350 +3A1350:lI105|H3A1424 +3A1424:lI99|H3A1500 +3A1500:lI97|H3A15D4 +3A15D4:lI116|H3A16A0 +3A16A0:lI105|H3A176C +3A176C:lI111|H3A1828 +3A1828:lI110|H3A18E4 +3A18E4:lI47|H3A1998 +3A1998:lI120|H3A1A4C +3A1A4C:lI45|H3A1B00 +3A1B00:lI115|H3A1BC4 +3A1BC4:lI104|N +3A1038:lI115|H3A10FC +3A10FC:lI104|N +3A0F88:lH3A1048|H3A1054 +3A1048:t2:H3A110C,H3A1114 +3A1114:lI97|H3A11D8 +3A11D8:lI112|H3A1294 +3A1294:lI112|H3A1358 +3A1358:lI108|H3A142C +3A142C:lI105|H3A1508 +3A1508:lI99|H3A15DC +3A15DC:lI97|H3A16A8 +3A16A8:lI116|H3A1774 +3A1774:lI105|H3A1830 +3A1830:lI111|H3A18EC +3A18EC:lI110|H3A19A0 +3A19A0:lI47|H3A1A54 +3A1A54:lI120|H3A1B08 +3A1B08:lI45|H3A1BCC +3A1BCC:lI110|H3A1C90 +3A1C90:lI101|H3A1D4C +3A1D4C:lI116|H3A1E08 +3A1E08:lI99|H3A1EC4 +3A1EC4:lI100|H3A1F88 +3A1F88:lI102|N +3A110C:lI110|H3A11D0 +3A11D0:lI99|N +3A1054:lH3A111C|H3A1128 +3A111C:t2:H3A11E0,H3A11E8 +3A11E8:lI97|H3A12A4 +3A12A4:lI112|H3A1368 +3A1368:lI112|H3A1434 +3A1434:lI108|H3A1510 +3A1510:lI105|H3A15E4 +3A15E4:lI99|H3A16B0 +3A16B0:lI97|H3A177C +3A177C:lI116|H3A1838 +3A1838:lI105|H3A18F4 +3A18F4:lI111|H3A19A8 +3A19A8:lI110|H3A1A5C +3A1A5C:lI47|H3A1B10 +3A1B10:lI120|H3A1BD4 +3A1BD4:lI45|H3A1C98 +3A1C98:lI110|H3A1D54 +3A1D54:lI101|H3A1E10 +3A1E10:lI116|H3A1ECC +3A1ECC:lI99|H3A1F90 +3A1F90:lI100|H3A2044 +3A2044:lI102|N +3A11E0:lI99|H3A129C +3A129C:lI100|H3A1360 +3A1360:lI102|N +3A1128:lH3A11F0|H3A11FC +3A11F0:t2:H3A12AC,H3A12B4 +3A12B4:lI97|H3A1378 +3A1378:lI112|H3A1444 +3A1444:lI112|H3A1518 +3A1518:lI108|H3A15EC +3A15EC:lI105|H3A16B8 +3A16B8:lI99|H3A1784 +3A1784:lI97|H3A1840 +3A1840:lI116|H3A18FC +3A18FC:lI105|H3A19B0 +3A19B0:lI111|H3A1A64 +3A1A64:lI110|H3A1B18 +3A1B18:lI47|H3A1BDC +3A1BDC:lI120|H3A1CA0 +3A1CA0:lI45|H3A1D5C +3A1D5C:lI109|H3A1E18 +3A1E18:lI105|H3A1ED4 +3A1ED4:lI102|N +3A12AC:lI109|H3A1370 +3A1370:lI105|H3A143C +3A143C:lI102|N +3A11FC:lH3A12BC|H3A12C8 +3A12BC:t2:H3A1380,H3A1388 +3A1388:lI97|H3A1454 +3A1454:lI112|H3A1528 +3A1528:lI112|H3A15FC +3A15FC:lI108|H3A16C8 +3A16C8:lI105|H3A178C +3A178C:lI99|H3A1848 +3A1848:lI97|H3A1904 +3A1904:lI116|H3A19B8 +3A19B8:lI105|H3A1A6C +3A1A6C:lI111|H3A1B20 +3A1B20:lI110|H3A1BE4 +3A1BE4:lI47|H3A1CA8 +3A1CA8:lI120|H3A1D64 +3A1D64:lI45|H3A1E20 +3A1E20:lI108|H3A1EDC +3A1EDC:lI97|H3A1F98 +3A1F98:lI116|H3A204C +3A204C:lI101|H3A2108 +3A2108:lI120|N +3A1380:lI108|H3A144C +3A144C:lI97|H3A1520 +3A1520:lI116|H3A15F4 +3A15F4:lI101|H3A16C0 +3A16C0:lI120|N +3A12C8:lH3A1390|H3A139C +3A1390:t2:H3A145C,H3A1464 +3A1464:lI97|H3A1538 +3A1538:lI112|H3A160C +3A160C:lI112|H3A16D0 +3A16D0:lI108|H3A1794 +3A1794:lI105|H3A1850 +3A1850:lI99|H3A190C +3A190C:lI97|H3A19C0 +3A19C0:lI116|H3A1A74 +3A1A74:lI105|H3A1B28 +3A1B28:lI111|H3A1BEC +3A1BEC:lI110|H3A1CB0 +3A1CB0:lI47|H3A1D6C +3A1D6C:lI120|H3A1E28 +3A1E28:lI45|H3A1EE4 +3A1EE4:lI107|H3A1FA0 +3A1FA0:lI111|H3A2054 +3A2054:lI97|H3A2110 +3A2110:lI110|N +3A145C:lI115|H3A1530 +3A1530:lI107|H3A1604 +3A1604:lI112|N +3A139C:lH3A146C|H3A1478 +3A146C:t2:H3A1540,H3A1548 +3A1548:lI97|H3A161C +3A161C:lI112|H3A16E0 +3A16E0:lI112|H3A179C +3A179C:lI108|H3A1858 +3A1858:lI105|H3A1914 +3A1914:lI99|H3A19C8 +3A19C8:lI97|H3A1A7C +3A1A7C:lI116|H3A1B30 +3A1B30:lI105|H3A1BF4 +3A1BF4:lI111|H3A1CB8 +3A1CB8:lI110|H3A1D74 +3A1D74:lI47|H3A1E30 +3A1E30:lI120|H3A1EEC +3A1EEC:lI45|H3A1FA8 +3A1FA8:lI107|H3A205C +3A205C:lI111|H3A2118 +3A2118:lI97|H3A21CC +3A21CC:lI110|N +3A1540:lI115|H3A1614 +3A1614:lI107|H3A16D8 +3A16D8:lI100|N +3A1478:lH3A1550|H3A155C +3A1550:t2:H3A1624,H3A162C +3A162C:lI97|H3A16F0 +3A16F0:lI112|H3A17AC +3A17AC:lI112|H3A1860 +3A1860:lI108|H3A191C +3A191C:lI105|H3A19D0 +3A19D0:lI99|H3A1A84 +3A1A84:lI97|H3A1B38 +3A1B38:lI116|H3A1BFC +3A1BFC:lI105|H3A1CC0 +3A1CC0:lI111|H3A1D7C +3A1D7C:lI110|H3A1E38 +3A1E38:lI47|H3A1EF4 +3A1EF4:lI120|H3A1FB0 +3A1FB0:lI45|H3A2064 +3A2064:lI107|H3A2120 +3A2120:lI111|H3A21D4 +3A21D4:lI97|H3A2288 +3A2288:lI110|N +3A1624:lI115|H3A16E8 +3A16E8:lI107|H3A17A4 +3A17A4:lI116|N +3A155C:lH3A1634|H3A1640 +3A1634:t2:H3A16F8,H3A1700 +3A1700:lI97|H3A17BC +3A17BC:lI112|H3A1870 +3A1870:lI112|H3A1924 +3A1924:lI108|H3A19D8 +3A19D8:lI105|H3A1A8C +3A1A8C:lI99|H3A1B40 +3A1B40:lI97|H3A1C04 +3A1C04:lI116|H3A1CC8 +3A1CC8:lI105|H3A1D84 +3A1D84:lI111|H3A1E40 +3A1E40:lI110|H3A1EFC +3A1EFC:lI47|H3A1FB8 +3A1FB8:lI120|H3A206C +3A206C:lI45|H3A2128 +3A2128:lI107|H3A21DC +3A21DC:lI111|H3A2290 +3A2290:lI97|H3A234C +3A234C:lI110|N +3A16F8:lI115|H3A17B4 +3A17B4:lI107|H3A1868 +3A1868:lI109|N +3A1640:lH3A1708|H3A1714 +3A1708:t2:H3A17C4,H3A17CC +3A17CC:lI97|H3A1880 +3A1880:lI112|H3A1934 +3A1934:lI112|H3A19E0 +3A19E0:lI108|H3A1A94 +3A1A94:lI105|H3A1B48 +3A1B48:lI99|H3A1C0C +3A1C0C:lI97|H3A1CD0 +3A1CD0:lI116|H3A1D8C +3A1D8C:lI105|H3A1E48 +3A1E48:lI111|H3A1F04 +3A1F04:lI110|H3A1FC0 +3A1FC0:lI47|H3A2074 +3A2074:lI120|H3A2130 +3A2130:lI45|H3A21E4 +3A21E4:lI104|H3A2298 +3A2298:lI116|H3A2354 +3A2354:lI116|H3A2410 +3A2410:lI112|H3A24C4 +3A24C4:lI100|H3A2580 +3A2580:lI45|H3A263C +3A263C:lI99|H3A2700 +3A2700:lI103|H3A27BC +3A27BC:lI105|N +3A17C4:lI99|H3A1878 +3A1878:lI103|H3A192C +3A192C:lI105|N +3A1714:lH3A17D4|H3A17E0 +3A17D4:t2:H3A1888,H3A1890 +3A1890:lI97|H3A1944 +3A1944:lI112|H3A19F0 +3A19F0:lI112|H3A1A9C +3A1A9C:lI108|H3A1B50 +3A1B50:lI105|H3A1C14 +3A1C14:lI99|H3A1CD8 +3A1CD8:lI97|H3A1D94 +3A1D94:lI116|H3A1E50 +3A1E50:lI105|H3A1F0C +3A1F0C:lI111|H3A1FC8 +3A1FC8:lI110|H3A207C +3A207C:lI47|H3A2138 +3A2138:lI120|H3A21EC +3A21EC:lI45|H3A22A0 +3A22A0:lI104|H3A235C +3A235C:lI100|H3A2418 +3A2418:lI102|N +3A1888:lI104|H3A193C +3A193C:lI100|H3A19E8 +3A19E8:lI102|N +3A17E0:lH3A1898|H3A18A4 +3A1898:t2:H3A194C,H3A1954 +3A1954:lI97|H3A1A00 +3A1A00:lI112|H3A1AA4 +3A1AA4:lI112|H3A1B58 +3A1B58:lI108|H3A1C1C +3A1C1C:lI105|H3A1CE0 +3A1CE0:lI99|H3A1D9C +3A1D9C:lI97|H3A1E58 +3A1E58:lI116|H3A1F14 +3A1F14:lI105|H3A1FD0 +3A1FD0:lI111|H3A2084 +3A2084:lI110|H3A2140 +3A2140:lI47|H3A21F4 +3A21F4:lI120|H3A22A8 +3A22A8:lI45|H3A2364 +3A2364:lI103|H3A2420 +3A2420:lI122|H3A24CC +3A24CC:lI105|H3A2588 +3A2588:lI112|N +3A194C:lI103|H3A19F8 +3A19F8:lI122|N +3A18A4:lH3A195C|H3A1968 +3A195C:t2:H3A1A08,H3A1A10 +3A1A10:lI97|H3A1AB4 +3A1AB4:lI112|H3A1B68 +3A1B68:lI112|H3A1C2C +3A1C2C:lI108|H3A1CE8 +3A1CE8:lI105|H3A1DA4 +3A1DA4:lI99|H3A1E60 +3A1E60:lI97|H3A1F1C +3A1F1C:lI116|H3A1FD8 +3A1FD8:lI105|H3A208C +3A208C:lI111|H3A2148 +3A2148:lI110|H3A21FC +3A21FC:lI47|H3A22B0 +3A22B0:lI120|H3A236C +3A236C:lI45|H3A2428 +3A2428:lI103|H3A24D4 +3A24D4:lI116|H3A2590 +3A2590:lI97|H3A2644 +3A2644:lI114|N +3A1A08:lI103|H3A1AAC +3A1AAC:lI116|H3A1B60 +3A1B60:lI97|H3A1C24 +3A1C24:lI114|N +3A1968:lH3A1A18|H3A1A24 +3A1A18:t2:H3A1ABC,H3A1AC4 +3A1AC4:lI97|H3A1B78 +3A1B78:lI112|H3A1C3C +3A1C3C:lI112|H3A1CF0 +3A1CF0:lI108|H3A1DAC +3A1DAC:lI105|H3A1E68 +3A1E68:lI99|H3A1F24 +3A1F24:lI97|H3A1FE0 +3A1FE0:lI116|H3A2094 +3A2094:lI105|H3A2150 +3A2150:lI111|H3A2204 +3A2204:lI110|H3A22B8 +3A22B8:lI47|H3A2374 +3A2374:lI120|H3A2430 +3A2430:lI45|H3A24DC +3A24DC:lI100|H3A2598 +3A2598:lI118|H3A264C +3A264C:lI105|N +3A1ABC:lI100|H3A1B70 +3A1B70:lI118|H3A1C34 +3A1C34:lI105|N +3A1A24:lH3A1ACC|H3A1AD8 +3A1ACC:t2:H3A1B80,H3A1B88 +3A1B88:lI97|H3A1C4C +3A1C4C:lI112|H3A1D00 +3A1D00:lI112|H3A1DB4 +3A1DB4:lI108|H3A1E70 +3A1E70:lI105|H3A1F2C +3A1F2C:lI99|H3A1FE8 +3A1FE8:lI97|H3A209C +3A209C:lI116|H3A2158 +3A2158:lI105|H3A220C +3A220C:lI111|H3A22C0 +3A22C0:lI110|H3A237C +3A237C:lI47|H3A2438 +3A2438:lI120|H3A24E4 +3A24E4:lI45|H3A25A0 +3A25A0:lI100|H3A2654 +3A2654:lI105|H3A2708 +3A2708:lI114|H3A27C4 +3A27C4:lI101|H3A2880 +3A2880:lI99|H3A2944 +3A2944:lI116|H3A2A10 +3A2A10:lI111|H3A2ADC +3A2ADC:lI114|N +3A1B80:lI100|H3A1C44 +3A1C44:lI99|H3A1CF8 +3A1CF8:lI114|N +3A1AD8:lH3A1B90|H3A1B9C +3A1B90:t2:H3A1C54,H3A1C5C +3A1C5C:lI97|H3A1D10 +3A1D10:lI112|H3A1DC4 +3A1DC4:lI112|H3A1E78 +3A1E78:lI108|H3A1F34 +3A1F34:lI105|H3A1FF0 +3A1FF0:lI99|H3A20A4 +3A20A4:lI97|H3A2160 +3A2160:lI116|H3A2214 +3A2214:lI105|H3A22C8 +3A22C8:lI111|H3A2384 +3A2384:lI110|H3A2440 +3A2440:lI47|H3A24EC +3A24EC:lI120|H3A25A8 +3A25A8:lI45|H3A265C +3A265C:lI100|H3A2710 +3A2710:lI105|H3A27CC +3A27CC:lI114|H3A2888 +3A2888:lI101|H3A294C +3A294C:lI99|H3A2A18 +3A2A18:lI116|H3A2AE4 +3A2AE4:lI111|H3A2BB0 +3A2BB0:lI114|N +3A1C54:lI100|H3A1D08 +3A1D08:lI105|H3A1DBC +3A1DBC:lI114|N +3A1B9C:lH3A1C64|H3A1C70 +3A1C64:t2:H3A1D18,H3A1D20 +3A1D20:lI97|H3A1DD4 +3A1DD4:lI112|H3A1E88 +3A1E88:lI112|H3A1F3C +3A1F3C:lI108|H3A1FF8 +3A1FF8:lI105|H3A20AC +3A20AC:lI99|H3A2168 +3A2168:lI97|H3A221C +3A221C:lI116|H3A22D0 +3A22D0:lI105|H3A238C +3A238C:lI111|H3A2448 +3A2448:lI110|H3A24F4 +3A24F4:lI47|H3A25B0 +3A25B0:lI120|H3A2664 +3A2664:lI45|H3A2718 +3A2718:lI100|H3A27D4 +3A27D4:lI105|H3A2890 +3A2890:lI114|H3A2954 +3A2954:lI101|H3A2A20 +3A2A20:lI99|H3A2AEC +3A2AEC:lI116|H3A2BB8 +3A2BB8:lI111|H3A2C74 +3A2C74:lI114|N +3A1D18:lI100|H3A1DCC +3A1DCC:lI120|H3A1E80 +3A1E80:lI114|N +3A1C70:lH3A1D28|H3A1D34 +3A1D28:t2:H3A1DDC,H3A1DE4 +3A1DE4:lI97|H3A1E98 +3A1E98:lI112|H3A1F4C +3A1F4C:lI112|H3A2000 +3A2000:lI108|H3A20B4 +3A20B4:lI105|H3A2170 +3A2170:lI99|H3A2224 +3A2224:lI97|H3A22D8 +3A22D8:lI116|H3A2394 +3A2394:lI105|H3A2450 +3A2450:lI111|H3A24FC +3A24FC:lI110|H3A25B8 +3A25B8:lI47|H3A266C +3A266C:lI120|H3A2720 +3A2720:lI45|H3A27DC +3A27DC:lI99|H3A2898 +3A2898:lI115|H3A295C +3A295C:lI104|N +3A1DDC:lI99|H3A1E90 +3A1E90:lI115|H3A1F44 +3A1F44:lI104|N +3A1D34:lH3A1DEC|H3A1DF8 +3A1DEC:t2:H3A1EA0,H3A1EA8 +3A1EA8:lI97|H3A1F5C +3A1F5C:lI112|H3A2010 +3A2010:lI112|H3A20C4 +3A20C4:lI108|H3A2178 +3A2178:lI105|H3A222C +3A222C:lI99|H3A22E0 +3A22E0:lI97|H3A239C +3A239C:lI116|H3A2458 +3A2458:lI105|H3A2504 +3A2504:lI111|H3A25C0 +3A25C0:lI110|H3A2674 +3A2674:lI47|H3A2728 +3A2728:lI120|H3A27E4 +3A27E4:lI45|H3A28A0 +3A28A0:lI99|H3A2964 +3A2964:lI112|H3A2A28 +3A2A28:lI105|H3A2AF4 +3A2AF4:lI111|N +3A1EA0:lI99|H3A1F54 +3A1F54:lI112|H3A2008 +3A2008:lI105|H3A20BC +3A20BC:lI111|N +3A1DF8:lH3A1EB0|H3A1EBC +3A1EB0:t2:H3A1F64,H3A1F6C +3A1F6C:lI97|H3A2018 +3A2018:lI112|H3A20CC +3A20CC:lI112|H3A2180 +3A2180:lI108|H3A2234 +3A2234:lI105|H3A22E8 +3A22E8:lI99|H3A23A4 +3A23A4:lI97|H3A2460 +3A2460:lI116|H3A250C +3A250C:lI105|H3A25C8 +3A25C8:lI111|H3A267C +3A267C:lI110|H3A2730 +3A2730:lI47|H3A27EC +3A27EC:lI120|H3A28A8 +3A28A8:lI45|H3A296C +3A296C:lI99|H3A2A30 +3A2A30:lI111|H3A2AFC +3A2AFC:lI109|H3A2BC0 +3A2BC0:lI112|H3A2C7C +3A2C7C:lI114|H3A2D2C +3A2D2C:lI101|H3A2DD4 +3A2DD4:lI115|H3A2E6C +3A2E6C:lI115|N +3A1F64:lI90|N +3A1EBC:lH3A1F74|H3A1F80 +3A1F74:t2:H3A2020,H3A2028 +3A2028:lI97|H3A20DC +3A20DC:lI112|H3A2190 +3A2190:lI112|H3A223C +3A223C:lI108|H3A22F0 +3A22F0:lI105|H3A23AC +3A23AC:lI99|H3A2468 +3A2468:lI97|H3A2514 +3A2514:lI116|H3A25D0 +3A25D0:lI105|H3A2684 +3A2684:lI111|H3A2738 +3A2738:lI110|H3A27F4 +3A27F4:lI47|H3A28B0 +3A28B0:lI120|H3A2974 +3A2974:lI45|H3A2A38 +3A2A38:lI99|H3A2B04 +3A2B04:lI100|H3A2BC8 +3A2BC8:lI108|H3A2C84 +3A2C84:lI105|H3A2D34 +3A2D34:lI110|H3A2DDC +3A2DDC:lI107|N +3A2020:lI118|H3A20D4 +3A20D4:lI99|H3A2188 +3A2188:lI100|N +3A1F80:lH3A2030|H3A203C +3A2030:t2:H3A20E4,H3A20EC +3A20EC:lI97|H3A21A0 +3A21A0:lI112|H3A224C +3A224C:lI112|H3A2300 +3A2300:lI108|H3A23BC +3A23BC:lI105|H3A2470 +3A2470:lI99|H3A251C +3A251C:lI97|H3A25D8 +3A25D8:lI116|H3A268C +3A268C:lI105|H3A2740 +3A2740:lI111|H3A27FC +3A27FC:lI110|H3A28B8 +3A28B8:lI47|H3A297C +3A297C:lI120|H3A2A40 +3A2A40:lI45|H3A2B0C +3A2B0C:lI98|H3A2BD0 +3A2BD0:lI99|H3A2C8C +3A2C8C:lI112|H3A2D3C +3A2D3C:lI105|H3A2DE4 +3A2DE4:lI111|N +3A20E4:lI98|H3A2198 +3A2198:lI99|H3A2244 +3A2244:lI112|H3A22F8 +3A22F8:lI105|H3A23B4 +3A23B4:lI111|N +3A203C:lH3A20F4|H3A2100 +3A20F4:t2:H3A21A8,H3A21B0 +3A21B0:lI97|H3A225C +3A225C:lI112|H3A2310 +3A2310:lI112|H3A23C4 +3A23C4:lI108|H3A2478 +3A2478:lI105|H3A2524 +3A2524:lI99|H3A25E0 +3A25E0:lI97|H3A2694 +3A2694:lI116|H3A2748 +3A2748:lI105|H3A2804 +3A2804:lI111|H3A28C0 +3A28C0:lI110|H3A2984 +3A2984:lI47|H3A2A48 +3A2A48:lI114|H3A2B14 +3A2B14:lI116|H3A2BD8 +3A2BD8:lI102|N +3A21A8:lI114|H3A2254 +3A2254:lI116|H3A2308 +3A2308:lI102|N +3A2100:lH3A21B8|H3A21C4 +3A21B8:t2:H3A2264,H3A226C +3A226C:lI97|H3A2320 +3A2320:lI112|H3A23D4 +3A23D4:lI112|H3A2480 +3A2480:lI108|H3A252C +3A252C:lI105|H3A25E8 +3A25E8:lI99|H3A269C +3A269C:lI97|H3A2750 +3A2750:lI116|H3A280C +3A280C:lI105|H3A28C8 +3A28C8:lI111|H3A298C +3A298C:lI110|H3A2A50 +3A2A50:lI47|H3A2B1C +3A2B1C:lI112|H3A2BE0 +3A2BE0:lI111|H3A2C94 +3A2C94:lI119|H3A2D44 +3A2D44:lI101|H3A2DEC +3A2DEC:lI114|H3A2E74 +3A2E74:lI112|H3A2EEC +3A2EEC:lI111|H3A2F64 +3A2F64:lI105|H3A2FD4 +3A2FD4:lI110|H3A303C +3A303C:lI116|N +3A2264:lI112|H3A2318 +3A2318:lI112|H3A23CC +3A23CC:lI116|N +3A21C4:lH3A2274|H3A2280 +3A2274:t2:H3A2328,H3A2330 +3A2330:lI97|H3A23E4 +3A23E4:lI112|H3A2488 +3A2488:lI112|H3A2534 +3A2534:lI108|H3A25F0 +3A25F0:lI105|H3A26A4 +3A26A4:lI99|H3A2758 +3A2758:lI97|H3A2814 +3A2814:lI116|H3A28D0 +3A28D0:lI105|H3A2994 +3A2994:lI111|H3A2A58 +3A2A58:lI110|H3A2B24 +3A2B24:lI47|H3A2BE8 +3A2BE8:lI112|H3A2C9C +3A2C9C:lI111|H3A2D4C +3A2D4C:lI115|H3A2DF4 +3A2DF4:lI116|H3A2E7C +3A2E7C:lI115|H3A2EF4 +3A2EF4:lI99|H3A2F6C +3A2F6C:lI114|H3A2FDC +3A2FDC:lI105|H3A3044 +3A3044:lI112|H3A30A4 +3A30A4:lI116|N +3A2328:lI97|H3A23DC +3A23DC:lI105|N +3A2280:lH3A2338|H3A2344 +3A2338:t2:H3A23EC,H3A23F4 +3A23F4:lI97|H3A2498 +3A2498:lI112|H3A2544 +3A2544:lI112|H3A25F8 +3A25F8:lI108|H3A26AC +3A26AC:lI105|H3A2760 +3A2760:lI99|H3A281C +3A281C:lI97|H3A28D8 +3A28D8:lI116|H3A299C +3A299C:lI105|H3A2A60 +3A2A60:lI111|H3A2B2C +3A2B2C:lI110|H3A2BF0 +3A2BF0:lI47|H3A2CA4 +3A2CA4:lI112|H3A2D54 +3A2D54:lI111|H3A2DFC +3A2DFC:lI115|H3A2E84 +3A2E84:lI116|H3A2EFC +3A2EFC:lI115|H3A2F74 +3A2F74:lI99|H3A2FE4 +3A2FE4:lI114|H3A304C +3A304C:lI105|H3A30AC +3A30AC:lI112|H3A3104 +3A3104:lI116|N +3A23EC:lI101|H3A2490 +3A2490:lI112|H3A253C +3A253C:lI115|N +3A2344:lH3A23FC|H3A2408 +3A23FC:t2:H3A24A0,H3A24A8 +3A24A8:lI97|H3A2554 +3A2554:lI112|H3A2600 +3A2600:lI112|H3A26B4 +3A26B4:lI108|H3A2768 +3A2768:lI105|H3A2824 +3A2824:lI99|H3A28E0 +3A28E0:lI97|H3A29A4 +3A29A4:lI116|H3A2A68 +3A2A68:lI105|H3A2B34 +3A2B34:lI111|H3A2BF8 +3A2BF8:lI110|H3A2CAC +3A2CAC:lI47|H3A2D5C +3A2D5C:lI112|H3A2E04 +3A2E04:lI111|H3A2E8C +3A2E8C:lI115|H3A2F04 +3A2F04:lI116|H3A2F7C +3A2F7C:lI115|H3A2FEC +3A2FEC:lI99|H3A3054 +3A3054:lI114|H3A30B4 +3A30B4:lI105|H3A310C +3A310C:lI112|H3A315C +3A315C:lI116|N +3A24A0:lI112|H3A254C +3A254C:lI115|N +3A2408:lH3A24B0|H3A24BC +3A24B0:t2:H3A255C,H3A2564 +3A2564:lI97|H3A2610 +3A2610:lI112|H3A26C4 +3A26C4:lI112|H3A2770 +3A2770:lI108|H3A282C +3A282C:lI105|H3A28E8 +3A28E8:lI99|H3A29AC +3A29AC:lI97|H3A2A70 +3A2A70:lI116|H3A2B3C +3A2B3C:lI105|H3A2C00 +3A2C00:lI111|H3A2CB4 +3A2CB4:lI110|H3A2D64 +3A2D64:lI47|H3A2E0C +3A2E0C:lI112|H3A2E94 +3A2E94:lI100|H3A2F0C +3A2F0C:lI102|N +3A255C:lI112|H3A2608 +3A2608:lI100|H3A26BC +3A26BC:lI102|N +3A24BC:lH3A256C|H3A2578 +3A256C:t2:H3A2618,H3A2620 +3A2620:lI97|H3A26D4 +3A26D4:lI112|H3A2780 +3A2780:lI112|H3A2834 +3A2834:lI108|H3A28F0 +3A28F0:lI105|H3A29B4 +3A29B4:lI99|H3A2A78 +3A2A78:lI97|H3A2B44 +3A2B44:lI116|H3A2C08 +3A2C08:lI105|H3A2CBC +3A2CBC:lI111|H3A2D6C +3A2D6C:lI110|H3A2E14 +3A2E14:lI47|H3A2E9C +3A2E9C:lI111|H3A2F14 +3A2F14:lI100|H3A2F84 +3A2F84:lI97|N +3A2618:lI111|H3A26CC +3A26CC:lI100|H3A2778 +3A2778:lI97|N +3A2578:lH3A2628|H3A2634 +3A2628:t2:H3A26DC,H3A26E4 +3A26E4:lI97|H3A2790 +3A2790:lI112|H3A2844 +3A2844:lI112|H3A28F8 +3A28F8:lI108|H3A29BC +3A29BC:lI105|H3A2A80 +3A2A80:lI99|H3A2B4C +3A2B4C:lI97|H3A2C10 +3A2C10:lI116|H3A2CC4 +3A2CC4:lI105|H3A2D74 +3A2D74:lI111|H3A2E1C +3A2E1C:lI110|H3A2EA4 +3A2EA4:lI47|H3A2F1C +3A2F1C:lI111|H3A2F8C +3A2F8C:lI99|H3A2FF4 +3A2FF4:lI116|H3A305C +3A305C:lI101|H3A30BC +3A30BC:lI116|H3A3114 +3A3114:lI45|H3A3164 +3A3164:lI115|H3A31AC +3A31AC:lI116|H3A31F4 +3A31F4:lI114|H3A323C +3A323C:lI101|H3A3284 +3A3284:lI97|H3A32CC +3A32CC:lI109|N +3A26DC:lI98|H3A2788 +3A2788:lI105|H3A283C +3A283C:lI110|N +3A2634:lH3A26EC|H3A26F8 +3A26EC:t2:H3A2798,H3A27A0 +3A27A0:lI97|H3A2854 +3A2854:lI112|H3A2908 +3A2908:lI112|H3A29C4 +3A29C4:lI108|H3A2A88 +3A2A88:lI105|H3A2B54 +3A2B54:lI99|H3A2C18 +3A2C18:lI97|H3A2CCC +3A2CCC:lI116|H3A2D7C +3A2D7C:lI105|H3A2E24 +3A2E24:lI111|H3A2EAC +3A2EAC:lI110|H3A2F24 +3A2F24:lI47|H3A2F94 +3A2F94:lI111|H3A2FFC +3A2FFC:lI99|H3A3064 +3A3064:lI116|H3A30C4 +3A30C4:lI101|H3A311C +3A311C:lI116|H3A316C +3A316C:lI45|H3A31B4 +3A31B4:lI115|H3A31FC +3A31FC:lI116|H3A3244 +3A3244:lI114|H3A328C +3A328C:lI101|H3A32D4 +3A32D4:lI97|H3A3314 +3A3314:lI109|N +3A2798:lI100|H3A284C +3A284C:lI109|H3A2900 +3A2900:lI115|N +3A26F8:lH3A27A8|H3A27B4 +3A27A8:t2:H3A285C,H3A2864 +3A2864:lI97|H3A2918 +3A2918:lI112|H3A29D4 +3A29D4:lI112|H3A2A90 +3A2A90:lI108|H3A2B5C +3A2B5C:lI105|H3A2C20 +3A2C20:lI99|H3A2CD4 +3A2CD4:lI97|H3A2D84 +3A2D84:lI116|H3A2E2C +3A2E2C:lI105|H3A2EB4 +3A2EB4:lI111|H3A2F2C +3A2F2C:lI110|H3A2F9C +3A2F9C:lI47|H3A3004 +3A3004:lI111|H3A306C +3A306C:lI99|H3A30CC +3A30CC:lI116|H3A3124 +3A3124:lI101|H3A3174 +3A3174:lI116|H3A31BC +3A31BC:lI45|H3A3204 +3A3204:lI115|H3A324C +3A324C:lI116|H3A3294 +3A3294:lI114|H3A32DC +3A32DC:lI101|H3A331C +3A331C:lI97|H3A334C +3A334C:lI109|N +3A285C:lI108|H3A2910 +3A2910:lI104|H3A29CC +3A29CC:lI97|N +3A27B4:lH3A286C|H3A2878 +3A286C:t2:H3A2920,H3A2928 +3A2928:lI97|H3A29E4 +3A29E4:lI112|H3A2AA0 +3A2AA0:lI112|H3A2B64 +3A2B64:lI108|H3A2C28 +3A2C28:lI105|H3A2CDC +3A2CDC:lI99|H3A2D8C +3A2D8C:lI97|H3A2E34 +3A2E34:lI116|H3A2EBC +3A2EBC:lI105|H3A2F34 +3A2F34:lI111|H3A2FA4 +3A2FA4:lI110|H3A300C +3A300C:lI47|H3A3074 +3A3074:lI111|H3A30D4 +3A30D4:lI99|H3A312C +3A312C:lI116|H3A317C +3A317C:lI101|H3A31C4 +3A31C4:lI116|H3A320C +3A320C:lI45|H3A3254 +3A3254:lI115|H3A329C +3A329C:lI116|H3A32E4 +3A32E4:lI114|H3A3324 +3A3324:lI101|H3A3354 +3A3354:lI97|H3A337C +3A337C:lI109|N +3A2920:lI108|H3A29DC +3A29DC:lI122|H3A2A98 +3A2A98:lI104|N +3A2878:lH3A2930|H3A293C +3A2930:t2:H3A29EC,H3A29F4 +3A29F4:lI97|H3A2AB0 +3A2AB0:lI112|H3A2B74 +3A2B74:lI112|H3A2C30 +3A2C30:lI108|H3A2CE4 +3A2CE4:lI105|H3A2D94 +3A2D94:lI99|H3A2E3C +3A2E3C:lI97|H3A2EC4 +3A2EC4:lI116|H3A2F3C +3A2F3C:lI105|H3A2FAC +3A2FAC:lI111|H3A3014 +3A3014:lI110|H3A307C +3A307C:lI47|H3A30DC +3A30DC:lI111|H3A3134 +3A3134:lI99|H3A3184 +3A3184:lI116|H3A31CC +3A31CC:lI101|H3A3214 +3A3214:lI116|H3A325C +3A325C:lI45|H3A32A4 +3A32A4:lI115|H3A32EC +3A32EC:lI116|H3A332C +3A332C:lI114|H3A335C +3A335C:lI101|H3A3384 +3A3384:lI97|H3A33A4 +3A33A4:lI109|N +3A29EC:lI101|H3A2AA8 +3A2AA8:lI120|H3A2B6C +3A2B6C:lI101|N +3A293C:lH3A29FC|H3A2A08 +3A29FC:t2:H3A2AB8,H3A2AC0 +3A2AC0:lI97|H3A2B84 +3A2B84:lI112|H3A2C40 +3A2C40:lI112|H3A2CF4 +3A2CF4:lI108|H3A2DA4 +3A2DA4:lI105|H3A2E44 +3A2E44:lI99|H3A2ECC +3A2ECC:lI97|H3A2F44 +3A2F44:lI116|H3A2FB4 +3A2FB4:lI105|H3A301C +3A301C:lI111|H3A3084 +3A3084:lI110|H3A30E4 +3A30E4:lI47|H3A313C +3A313C:lI111|H3A318C +3A318C:lI99|H3A31D4 +3A31D4:lI116|H3A321C +3A321C:lI101|H3A3264 +3A3264:lI116|H3A32AC +3A32AC:lI45|H3A32F4 +3A32F4:lI115|H3A3334 +3A3334:lI116|H3A3364 +3A3364:lI114|H3A338C +3A338C:lI101|H3A33AC +3A33AC:lI97|H3A33C4 +3A33C4:lI109|N +3A2AB8:lI99|H3A2B7C +3A2B7C:lI108|H3A2C38 +3A2C38:lI97|H3A2CEC +3A2CEC:lI115|H3A2D9C +3A2D9C:lI115|N +3A2A08:lH3A2AC8|H3A2AD4 +3A2AC8:t2:H3A2B8C,H3A2B94 +3A2B94:lI97|H3A2C50 +3A2C50:lI112|H3A2D04 +3A2D04:lI112|H3A2DAC +3A2DAC:lI108|H3A2E4C +3A2E4C:lI105|H3A2ED4 +3A2ED4:lI99|H3A2F4C +3A2F4C:lI97|H3A2FBC +3A2FBC:lI116|H3A3024 +3A3024:lI105|H3A308C +3A308C:lI111|H3A30EC +3A30EC:lI110|H3A3144 +3A3144:lI47|H3A3194 +3A3194:lI109|H3A31DC +3A31DC:lI115|H3A3224 +3A3224:lI119|H3A326C +3A326C:lI111|H3A32B4 +3A32B4:lI114|H3A32FC +3A32FC:lI100|N +3A2B8C:lI100|H3A2C48 +3A2C48:lI111|H3A2CFC +3A2CFC:lI99|N +3A2AD4:lH3A2B9C|H3A2BA8 +3A2B9C:t2:H3A2C58,H3A2C60 +3A2C60:lI97|H3A2D14 +3A2D14:lI112|H3A2DBC +3A2DBC:lI112|H3A2E54 +3A2E54:lI108|H3A2EDC +3A2EDC:lI105|H3A2F54 +3A2F54:lI99|H3A2FC4 +3A2FC4:lI97|H3A302C +3A302C:lI116|H3A3094 +3A3094:lI105|H3A30F4 +3A30F4:lI111|H3A314C +3A314C:lI110|H3A319C +3A319C:lI47|H3A31E4 +3A31E4:lI109|H3A322C +3A322C:lI97|H3A3274 +3A3274:lI99|H3A32BC +3A32BC:lI45|H3A3304 +3A3304:lI99|H3A333C +3A333C:lI111|H3A336C +3A336C:lI109|H3A3394 +3A3394:lI112|H3A33B4 +3A33B4:lI97|H3A33CC +3A33CC:lI99|H3A33DC +3A33DC:lI116|H3A33EC +3A33EC:lI112|H3A33FC +3A33FC:lI114|H3A340C +3A340C:lI111|N +3A2C58:lI99|H3A2D0C +3A2D0C:lI112|H3A2DB4 +3A2DB4:lI116|N +3A2BA8:lH3A2C68|N +3A2C68:t2:H3A2D1C,H3A2D24 +3A2D24:lI97|H3A2DCC +3A2DCC:lI112|H3A2E64 +3A2E64:lI112|H3A2EE4 +3A2EE4:lI108|H3A2F5C +3A2F5C:lI105|H3A2FCC +3A2FCC:lI99|H3A3034 +3A3034:lI97|H3A309C +3A309C:lI116|H3A30FC +3A30FC:lI105|H3A3154 +3A3154:lI111|H3A31A4 +3A31A4:lI110|H3A31EC +3A31EC:lI47|H3A3234 +3A3234:lI109|H3A327C +3A327C:lI97|H3A32C4 +3A32C4:lI99|H3A330C +3A330C:lI45|H3A3344 +3A3344:lI98|H3A3374 +3A3374:lI105|H3A339C +3A339C:lI110|H3A33BC +3A33BC:lI104|H3A33D4 +3A33D4:lI101|H3A33E4 +3A33E4:lI120|H3A33F4 +3A33F4:lI52|H3A3404 +3A3404:lI48|N +3A2D1C:lI104|H3A2DC4 +3A2DC4:lI113|H3A2E5C +3A2E5C:lI120|N +39DC28:lH39DC68|H39DC74 +39DC68:t2:A4:port,I8888 +39DC74:lH39DCA8|H39DCB4 +39DCA8:t2:AC:bind_address,H39DCF8 +39DCF8:t4:I127,I0,I0,I1 +39DCB4:lH39DD0C|H39DD18 +39DD0C:t2:AB:server_name,H39DD6C +39DD6C:lI108|H39DDE4 +39DDE4:lI111|H39DE5C +39DE5C:lI99|H39DEE4 +39DEE4:lI97|H39DF6C +39DF6C:lI108|H39E00C +39E00C:lI104|H39E0B4 +39E0B4:lI111|H39E16C +39E16C:lI115|H39E238 +39E238:lI116|N +39DD18:lH39DD74|H39DD80 +39DD74:t2:AE:max_header_siz,I1024 +39DD80:lH39DDEC|H39DDF8 +39DDEC:t2:A11:max_header_action,A8:reply414 +39DDF8:lH39DE64|H39DE70 +39DE64:t2:A8:com_type,A7:ip_comm +39DE70:lH39DEEC|H39DEF8 +39DEEC:t2:A7:modules,H39DF74 +39DF74:lA9:mod_alias|H39E014 +39E014:lA8:mod_auth|H39E0BC +39E0BC:lA7:mod_esi|H39E174 +39E174:lAB:mod_actions|H39E240 +39E240:lA7:mod_cgi|H39E324 +39E324:lAB:mod_include|H39E418 +39E418:lA7:mod_dir|H39E51C +39E51C:lA7:mod_get|H39E634 +39E634:lA8:mod_head|H39E748 +39E748:lA7:mod_log|H39E85C +39E85C:lAC:mod_disk_log|N +39DEF8:lH39DF7C|H39DF88 +39DF7C:t2:AF:directory_index,H39E01C +39E01C:lH39E0C4|N +39E0C4:lI105|H39E17C +39E17C:lI110|H39E248 +39E248:lI100|H39E32C +39E32C:lI101|H39E420 +39E420:lI120|H39E524 +39E524:lI46|H39E63C +39E63C:lI104|H39E750 +39E750:lI116|H39E864 +39E864:lI109|H39E978 +39E978:lI108|N +39DF88:lH39E024|H39E030 +39E024:t2:AC:default_type,H39E0CC +39E0CC:lI116|H39E184 +39E184:lI101|H39E250 +39E250:lI120|H39E334 +39E334:lI116|H39E428 +39E428:lI47|H39E52C +39E52C:lI112|H39E644 +39E644:lI108|H39E758 +39E758:lI97|H39E86C +39E86C:lI105|H39E980 +39E980:lI110|N +39E030:lH39E0D4|H39E0E0 +39E0D4:t2:A10:erl_script_alias,H39E18C +39E18C:t2:H39E258,H39E260 +39E260:lH39E344|N +39E344:lI119|H39E438 +39E438:lI101|H39E53C +39E53C:lI98|H39E654 +39E654:lI116|H39E768 +39E768:lI111|H39E87C +39E87C:lI111|H39E990 +39E990:lI108|N +39E258:lI47|H39E33C +39E33C:lI119|H39E430 +39E430:lI101|H39E534 +39E534:lI98|H39E64C +39E64C:lI116|H39E760 +39E760:lI111|H39E874 +39E874:lI111|H39E988 +39E988:lI108|N +39E0E0:lH39E198|H39E1A4 +39E198:t2:A5:alias,H39E268 +39E268:t2:H39E34C,H39E354 +39E354:lI47|H39E448 +39E448:lI99|H39E54C +39E54C:lI108|H39E664 +39E664:lI101|H39E778 +39E778:lI97|H39E88C +39E88C:lI114|H39E9A0 +39E9A0:lI99|H39EA94 +39EA94:lI97|H39EB88 +39EB88:lI115|H39EC7C +39EC7C:lI101|H39ED70 +39ED70:lI47|H39EE4C +39EE4C:lI111|H39EF20 +39EF20:lI116|H39EFFC +39EFFC:lI112|H39F0E0 +39F0E0:lI47|H39F1B4 +39F1B4:lI101|H39F288 +39F288:lI114|H39F344 +39F344:lI116|H39F408 +39F408:lI115|H39F4D4 +39F4D4:lI47|H39F5A8 +39F5A8:lI108|H39F67C +39F67C:lI105|H39F750 +39F750:lI98|H39F824 +39F824:lI47|H39F908 +39F908:lI111|H39F9E4 +39F9E4:lI98|H39FAC0 +39FAC0:lI115|H39FB9C +39FB9C:lI101|H39FC68 +39FC68:lI114|H39FD2C +39FD2C:lI118|H39FDF8 +39FDF8:lI101|H39FEB4 +39FEB4:lI114|H39FF70 +39FF70:lI47|H3A0024 +3A0024:lI112|H3A00D8 +3A00D8:lI114|H3A0184 +3A0184:lI105|H3A0238 +3A0238:lI118|H3A02F4 +3A02F4:lI47|H3A03A8 +3A03A8:lI99|H3A0444 +3A0444:lI114|H3A04E8 +3A04E8:lI97|H3A058C +3A058C:lI115|H3A0638 +3A0638:lI104|H3A06EC +3A06EC:lI100|H3A0798 +3A0798:lI117|H3A083C +3A083C:lI109|H3A08C8 +3A08C8:lI112|H3A095C +3A095C:lI95|H3A09F0 +3A09F0:lI118|H3A0A8C +3A0A8C:lI105|H3A0B38 +3A0B38:lI101|H3A0BE4 +3A0BE4:lI119|H3A0CA0 +3A0CA0:lI101|H3A0D5C +3A0D5C:lI114|N +39E34C:lI47|H39E440 +39E440:lI99|H39E544 +39E544:lI114|H39E65C +39E65C:lI97|H39E770 +39E770:lI115|H39E884 +39E884:lI104|H39E998 +39E998:lI100|H39EA8C +39EA8C:lI117|H39EB80 +39EB80:lI109|H39EC74 +39EC74:lI112|H39ED68 +39ED68:lI95|H39EE44 +39EE44:lI118|H39EF18 +39EF18:lI105|H39EFF4 +39EFF4:lI101|H39F0D8 +39F0D8:lI119|H39F1AC +39F1AC:lI101|H39F280 +39F280:lI114|N +39E1A4:lH39E274|H39E280 +39E274:t2:A5:alias,H39E35C +39E35C:t2:H39E450,H39E458 +39E458:lI47|H39E55C +39E55C:lI99|H39E674 +39E674:lI108|H39E788 +39E788:lI101|H39E89C +39E89C:lI97|H39E9B0 +39E9B0:lI114|H39EAA4 +39EAA4:lI99|H39EB98 +39EB98:lI97|H39EC8C +39EC8C:lI115|H39ED80 +39ED80:lI101|H39EE5C +39EE5C:lI47|H39EF30 +39EF30:lI111|H39F00C +39F00C:lI116|H39F0F0 +39F0F0:lI112|H39F1C4 +39F1C4:lI47|H39F298 +39F298:lI101|H39F354 +39F354:lI114|H39F418 +39F418:lI116|H39F4E4 +39F4E4:lI115|H39F5B0 +39F5B0:lI47|H39F684 +39F684:lI101|H39F758 +39F758:lI114|H39F82C +39F82C:lI116|H39F910 +39F910:lI115|H39F9EC +39F9EC:lI47|H39FAC8 +39FAC8:lI100|H39FBA4 +39FBA4:lI111|H39FC70 +39FC70:lI99|H39FD34 +39FD34:lI47|H39FE00 +39FE00:lI104|H39FEBC +39FEBC:lI116|H39FF78 +39FF78:lI109|H3A002C +3A002C:lI108|N +39E450:lI47|H39E554 +39E554:lI99|H39E66C +39E66C:lI114|H39E780 +39E780:lI97|H39E894 +39E894:lI115|H39E9A8 +39E9A8:lI104|H39EA9C +39EA9C:lI100|H39EB90 +39EB90:lI117|H39EC84 +39EC84:lI109|H39ED78 +39ED78:lI112|H39EE54 +39EE54:lI95|H39EF28 +39EF28:lI101|H39F004 +39F004:lI114|H39F0E8 +39F0E8:lI116|H39F1BC +39F1BC:lI115|H39F290 +39F290:lI95|H39F34C +39F34C:lI100|H39F410 +39F410:lI111|H39F4DC +39F4DC:lI99|N +39E280:lH39E368|H39E374 +39E368:t2:A5:alias,H39E460 +39E460:t2:H39E564,H39E56C +39E56C:lI47|H39E684 +39E684:lI99|H39E798 +39E798:lI108|H39E8AC +39E8AC:lI101|H39E9C0 +39E9C0:lI97|H39EAB4 +39EAB4:lI114|H39EBA8 +39EBA8:lI99|H39EC9C +39EC9C:lI97|H39ED90 +39ED90:lI115|H39EE6C +39EE6C:lI101|H39EF40 +39EF40:lI47|H39F01C +39F01C:lI111|H39F100 +39F100:lI116|H39F1D4 +39F1D4:lI112|H39F2A0 +39F2A0:lI47|H39F35C +39F35C:lI101|H39F420 +39F420:lI114|H39F4EC +39F4EC:lI116|H39F5B8 +39F5B8:lI115|H39F68C +39F68C:lI47|H39F760 +39F760:lI108|H39F834 +39F834:lI105|H39F918 +39F918:lI98|H39F9F4 +39F9F4:lI47|H39FAD0 +39FAD0:lI111|H39FBAC +39FBAC:lI98|H39FC78 +39FC78:lI115|H39FD3C +39FD3C:lI101|H39FE08 +39FE08:lI114|H39FEC4 +39FEC4:lI118|H39FF80 +39FF80:lI101|H3A0034 +3A0034:lI114|H3A00E0 +3A00E0:lI47|H3A018C +3A018C:lI100|H3A0240 +3A0240:lI111|H3A02FC +3A02FC:lI99|H3A03B0 +3A03B0:lI47|H3A044C +3A044C:lI104|H3A04F0 +3A04F0:lI116|H3A0594 +3A0594:lI109|H3A0640 +3A0640:lI108|N +39E564:lI47|H39E67C +39E67C:lI99|H39E790 +39E790:lI114|H39E8A4 +39E8A4:lI97|H39E9B8 +39E9B8:lI115|H39EAAC +39EAAC:lI104|H39EBA0 +39EBA0:lI100|H39EC94 +39EC94:lI117|H39ED88 +39ED88:lI109|H39EE64 +39EE64:lI112|H39EF38 +39EF38:lI95|H39F014 +39F014:lI100|H39F0F8 +39F0F8:lI111|H39F1CC +39F1CC:lI99|N +39E374:lH39E46C|N +39E46C:t2:A10:erl_script_alias,H39E574 +39E574:t2:H39E68C,H39E694 +39E694:lH39E7A8|N +39E7A8:lI99|H39E8BC +39E8BC:lI114|H39E9D0 +39E9D0:lI97|H39EAC4 +39EAC4:lI115|H39EBB8 +39EBB8:lI104|H39ECAC +39ECAC:lI100|H39EDA0 +39EDA0:lI117|H39EE74 +39EE74:lI109|H39EF48 +39EF48:lI112|H39F024 +39F024:lI95|H39F108 +39F108:lI118|H39F1DC +39F1DC:lI105|H39F2A8 +39F2A8:lI101|H39F364 +39F364:lI119|H39F428 +39F428:lI101|H39F4F4 +39F4F4:lI114|N +39E68C:lI47|H39E7A0 +39E7A0:lI99|H39E8B4 +39E8B4:lI100|H39E9C8 +39E9C8:lI118|H39EABC +39EABC:lI95|H39EBB0 +39EBB0:lI101|H39ECA4 +39ECA4:lI114|H39ED98 +39ED98:lI108|N +39DB58:lN|H39DB9C +39DB9C:lH39D9FC|H39DBEC +39D9FC:t4:I127,I0,I0,I1 +39DBEC:lI8888|N +3A3E20:lH3A3DFC|H3A3704 +3A3DFC:t8:A5:child,P<0.46.0>,H39DAC8,H39DAD8,A9:permanent,I2000,A6:worker,H39DAE8 +39DAE8:lAD:httpd_manager|H39DB38 +39DB38:lAA:gen_server|N +39DAD8:t3:AD:httpd_manager,AA:start_link,H39DB30 +39DB30:lA9:undefined|H39DB78 +39DB78:lH39DB50|H39DBC0 +39DBC0:lN|N +39DAC8:t3:AD:httpd_manager,H39D9FC,I8888 +3A3704:lH3A36E0|H39D998 +3A36E0:t8:A5:child,P<0.45.0>,H39DA18,H39DA28,A9:permanent,I2000,AA:supervisor,H39DA38 +39DA38:lAE:httpd_misc_sup|H39DAC0 +39DAC0:lAA:supervisor|N +39DA28:t3:AE:httpd_misc_sup,A5:start,H39D958 +39D958:lH39D9FC|H39DA10 +39DA10:lI8888|H39DAB8 +39DAB8:lA7:silence|N +39DA18:t3:AE:httpd_misc_sup,H39D9FC,I8888 +39D998:lH39DA64|N +39DA64:t8:A5:child,P<0.44.0>,H39DAF0,H39DB00,A9:permanent,I2000,AA:supervisor,H39DB10 +39DB10:lA12:httpd_acceptor_sup|H39DB48 +39DB48:lAA:supervisor|N +39DB00:t3:A12:httpd_acceptor_sup,A5:start,H39DB40 +39DB40:lH39D9FC|H39DB80 +39DB80:lI8888|H39DBC8 +39DBC8:lA7:silence|N +39DAF0:t3:A12:httpd_acceptor_sup,H39D9FC,I8888 +39D960:t2:A5:local,A1A:httpd_sup__127_0_0_1__8888 +39D9CC:lAA:gen_server|H39DA90 +39DA90:lP<0.33.0>|H39DB20 +39DB20:lP<0.33.0>|H39DB60 +39DB60:lH39DBA4|H39DBB0 +39DBA4:t2:A5:local,A1A:httpd_sup__127_0_0_1__8888 +39DBB0:lAA:supervisor|H39DBF4 +39DBF4:lH39DC30|H39DC40 +39DC30:t3:H39D960,A9:httpd_sup,H39DA88 +39DC40:lN|N +39D940:t2:AD:$initial_call,H39D9E4 +39D9E4:t3:A3:gen,A7:init_it,H39D9CC +39D94C:t2:AA:$ancestors,H39D9F4 +39D9F4:lA8:web_tool|H39DAB0 +39DAB0:lP<0.27.0>|N +=proc_dictionary:<0.44.0> +H3756A8 +H3756B4 +H3756C0 +H3756CC +=proc_stack:<0.44.0> +36c194:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AA:supervisor +y3:H36C030 +y4:A1E:httpd_acc_sup__127_0_0_1__8888 +y5:P<0.43.0> +36c1b0:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H375710 +=proc_heap:<0.44.0> +36C030:tA:A5:state,H3756D8,AB:one_for_one,H36C028,N,I500,I100,N,A12:httpd_acceptor_sup,H375730 +375730:lA7:silence|N +36C028:lH36C004|N +36C004:t8:A5:child,P<0.47.0>,H36BE80,H36BE90,A9:permanent,I1000,A6:worker,H36BEA0 +36BEA0:lAE:httpd_acceptor|N +36BE90:t3:AE:httpd_acceptor,AA:start_link,H36BEE8 +36BEE8:lP<0.46.0>|H36BEF0 +36BEF0:lA7:ip_comm|H36BEF8 +36BEF8:lH36BF00|H36BF14 +36BF00:t4:I127,I0,I0,I1 +36BF14:lI8888|H36BF1C +36BF1C:lA1B:httpd_conf__127_0_0_1__8888|H36BF24 +36BF24:lA7:silence|N +36BE80:t3:AE:httpd_acceptor,H36BED4,I8888 +36BED4:t4:I127,I0,I0,I1 +3756D8:t2:A5:local,A1E:httpd_acc_sup__127_0_0_1__8888 +375710:lAA:gen_server|H375738 +375738:lP<0.43.0>|H375748 +375748:lP<0.43.0>|H375758 +375758:lH375760|H37576C +375760:t2:A5:local,A1E:httpd_acc_sup__127_0_0_1__8888 +37576C:lAA:supervisor|H375774 +375774:lH37577C|H37578C +37577C:t3:H3756D8,A12:httpd_acceptor_sup,H375730 +37578C:lN|N +3756A8:t2:AD:$initial_call,H375718 +375718:t3:A3:gen,A7:init_it,H375710 +3756B4:t2:A9:verbosity,A7:silence +3756C0:t2:AA:$ancestors,H375728 +375728:lA1A:httpd_sup__127_0_0_1__8888|H375740 +375740:lA8:web_tool|H375750 +375750:lP<0.27.0>|N +3756CC:t2:A5:sname,A7:acc_sup +=proc_dictionary:<0.45.0> +H36F484 +H36F4F4 +H36F468 +H36F500 +=proc_stack:<0.45.0> +36f734:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AA:supervisor +y3:H36F5D0 +y4:A1F:httpd_misc_sup__127_0_0_1__8888 +y5:P<0.43.0> +36f750:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H36F430 +=proc_heap:<0.45.0> +36F5D0:tA:A5:state,H36F3FC,AB:one_for_one,N,N,I0,I1,N,AE:httpd_misc_sup,H36F408 +36F408:lA7:silence|N +36F3FC:t2:A5:local,A1F:httpd_misc_sup__127_0_0_1__8888 +36F430:lAA:gen_server|H36F428 +36F428:lP<0.43.0>|H36F420 +36F420:lP<0.43.0>|H36F3D0 +36F3D0:lH36F3E0|H36F418 +36F3E0:t2:A5:local,A1F:httpd_misc_sup__127_0_0_1__8888 +36F418:lAA:supervisor|H36F3D8 +36F3D8:lH36F3EC|H36F410 +36F3EC:t3:H36F3FC,AE:httpd_misc_sup,H36F408 +36F410:lN|N +36F484:t2:AD:$initial_call,H36F474 +36F474:t3:A3:gen,A7:init_it,H36F430 +36F4F4:t2:A9:verbosity,A7:silence +36F468:t2:AA:$ancestors,H36F460 +36F460:lA1A:httpd_sup__127_0_0_1__8888|H36F440 +36F440:lA8:web_tool|H36F438 +36F438:lP<0.27.0>|N +36F500:t2:A5:sname,A8:misc_sup +=proc_dictionary:<0.46.0> +H3BDA50 +H3BDA5C +H3BDAC8 +H3BDB28 +H3BDB9C +H3BDC00 +H3BDADC +H3BDB3C +=proc_stack:<0.46.0> +39d8f4:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AD:httpd_manager +y3:H39D5A4 +y4:A16:httpd__127_0_0_1__8888 +y5:P<0.43.0> +39d910:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H3BDAB0 +=proc_heap:<0.46.0> +39D5A4:t9:A5:state,A7:ip_comm,A9:undefined,A1B:httpd_conf__127_0_0_1__8888,N,A9:unblocked,A9:undefined,A9:undefined,H39D430 +39D430:lH39BF40|H39D428 +39BF40:t2:A8:max_conn,I1 +39D428:lH39BC80|H39D420 +39BC80:t2:AF:last_heavy_load,A5:never +39D420:lH39D414|N +39D414:t2:AF:last_connection,H39D408 +39D408:t2:H39D3E8,H39D3F8 +39D3F8:t3:I11,I22,I34 +39D3E8:t3:I2004,I4,I21 +3BDAB0:lAA:gen_server|H3BDB20 +3BDB20:lP<0.43.0>|H3BDB94 +3BDB94:lP<0.43.0>|H3BDBF8 +3BDBF8:lH3BDC48|H3BDC54 +3BDC48:t2:A5:local,A16:httpd__127_0_0_1__8888 +3BDC54:lAD:httpd_manager|H3BDCAC +3BDCAC:lH3BDD14|H3BDD1C +3BDD14:lA9:undefined|H3BDD9C +3BDD9C:lH3BDA84|H3BDE2C +3BDA84:lH3BDAF0|H3BDAFC +3BDAF0:t2:AB:server_root,H3BDB48 +3BDB48:lI47|H3BDBB0 +3BDBB0:lI99|H3BDC0C +3BDC0C:lI108|H3BDC64 +3BDC64:lI101|H3BDCBC +3BDCBC:lI97|H3BDD2C +3BDD2C:lI114|H3BDDA4 +3BDDA4:lI99|H3BDE34 +3BDE34:lI97|H3BDED4 +3BDED4:lI115|H3BDF90 +3BDF90:lI101|H3BE054 +3BE054:lI47|H3BE128 +3BE128:lI111|H3BE204 +3BE204:lI116|H3BE2EC +3BE2EC:lI112|H3BE3E0 +3BE3E0:lI47|H3BE4E4 +3BE4E4:lI101|H3BE5E8 +3BE5E8:lI114|H3BE6EC +3BE6EC:lI116|H3BE7E0 +3BE7E0:lI115|H3BE8CC +3BE8CC:lI47|H3BE9B8 +3BE9B8:lI108|H3BEAAC +3BEAAC:lI105|H3BEB98 +3BEB98:lI98|H3BEC84 +3BEC84:lI47|H3BED70 +3BED70:lI119|H3BEE5C +3BEE5C:lI101|H3BEF30 +3BEF30:lI98|H3BEFFC +3BEFFC:lI116|H3BF0C8 +3BF0C8:lI111|H3BF19C +3BF19C:lI111|H3BF260 +3BF260:lI108|H3BF314 +3BF314:lI47|H3BF3C0 +3BF3C0:lI112|H3BF474 +3BF474:lI114|H3BF530 +3BF530:lI105|H3BF5F4 +3BF5F4:lI118|H3BF6C8 +3BF6C8:lI47|H3BF79C +3BF79C:lI114|H3BF870 +3BF870:lI111|H3BF954 +3BF954:lI111|H3BFA30 +3BFA30:lI116|N +3BDAFC:lH3BDB50|H3BDB5C +3BDB50:t2:AD:document_root,H3BDBB8 +3BDBB8:lI47|H3BDC14 +3BDC14:lI99|H3BDC6C +3BDC6C:lI108|H3BDCC4 +3BDCC4:lI101|H3BDD34 +3BDD34:lI97|H3BDDAC +3BDDAC:lI114|H3BDE3C +3BDE3C:lI99|H3BDEDC +3BDEDC:lI97|H3BDF98 +3BDF98:lI115|H3BE05C +3BE05C:lI101|H3BE130 +3BE130:lI47|H3BE20C +3BE20C:lI111|H3BE2F4 +3BE2F4:lI116|H3BE3E8 +3BE3E8:lI112|H3BE4EC +3BE4EC:lI47|H3BE5F0 +3BE5F0:lI101|H3BE6F4 +3BE6F4:lI114|H3BE7E8 +3BE7E8:lI116|H3BE8D4 +3BE8D4:lI115|H3BE9C0 +3BE9C0:lI47|H3BEAB4 +3BEAB4:lI108|H3BEBA0 +3BEBA0:lI105|H3BEC8C +3BEC8C:lI98|H3BED78 +3BED78:lI47|H3BEE64 +3BEE64:lI119|H3BEF38 +3BEF38:lI101|H3BF004 +3BF004:lI98|H3BF0D0 +3BF0D0:lI116|H3BF1A4 +3BF1A4:lI111|H3BF268 +3BF268:lI111|H3BF31C +3BF31C:lI108|H3BF3C8 +3BF3C8:lI47|H3BF47C +3BF47C:lI112|H3BF538 +3BF538:lI114|H3BF5FC +3BF5FC:lI105|H3BF6D0 +3BF6D0:lI118|H3BF7A4 +3BF7A4:lI47|H3BF878 +3BF878:lI114|H3BF95C +3BF95C:lI111|H3BFA38 +3BFA38:lI111|H3BFB0C +3BFB0C:lI116|H3BFBE8 +3BFBE8:lI47|H3BFCB4 +3BFCB4:lI100|H3BFD78 +3BFD78:lI111|H3BFE3C +3BFE3C:lI99|N +3BDB5C:lH3BDBC0|H3BDBCC +3BDBC0:t2:AA:mime_types,H3BDC1C +3BDC1C:lH3BDC74|H3BDC80 +3BDC74:t2:H3BDCCC,H3BDCD4 +3BDCD4:lI120|H3BDD44 +3BDD44:lI45|H3BDDBC +3BDDBC:lI119|H3BDE44 +3BDE44:lI111|H3BDEE4 +3BDEE4:lI114|H3BDFA0 +3BDFA0:lI108|H3BE064 +3BE064:lI100|H3BE138 +3BE138:lI47|H3BE214 +3BE214:lI120|H3BE2FC +3BE2FC:lI45|H3BE3F0 +3BE3F0:lI118|H3BE4F4 +3BE4F4:lI114|H3BE5F8 +3BE5F8:lI109|H3BE6FC +3BE6FC:lI108|N +3BDCCC:lI119|H3BDD3C +3BDD3C:lI114|H3BDDB4 +3BDDB4:lI108|N +3BDC80:lH3BDCDC|H3BDCE8 +3BDCDC:t2:H3BDD4C,H3BDD54 +3BDD54:lI120|H3BDDCC +3BDDCC:lI45|H3BDE54 +3BDE54:lI119|H3BDEF4 +3BDEF4:lI111|H3BDFA8 +3BDFA8:lI114|H3BE06C +3BE06C:lI108|H3BE140 +3BE140:lI100|H3BE21C +3BE21C:lI47|H3BE304 +3BE304:lI120|H3BE3F8 +3BE3F8:lI45|H3BE4FC +3BE4FC:lI118|H3BE600 +3BE600:lI114|H3BE704 +3BE704:lI109|H3BE7F0 +3BE7F0:lI108|N +3BDD4C:lI118|H3BDDC4 +3BDDC4:lI114|H3BDE4C +3BDE4C:lI109|H3BDEEC +3BDEEC:lI108|N +3BDCE8:lH3BDD5C|H3BDD68 +3BDD5C:t2:H3BDDD4,H3BDDDC +3BDDDC:lI120|H3BDE64 +3BDE64:lI45|H3BDF04 +3BDF04:lI99|H3BDFB0 +3BDFB0:lI111|H3BE074 +3BE074:lI110|H3BE148 +3BE148:lI102|H3BE224 +3BE224:lI101|H3BE30C +3BE30C:lI114|H3BE400 +3BE400:lI101|H3BE504 +3BE504:lI110|H3BE608 +3BE608:lI99|H3BE70C +3BE70C:lI101|H3BE7F8 +3BE7F8:lI47|H3BE8DC +3BE8DC:lI120|H3BE9C8 +3BE9C8:lI45|H3BEABC +3BEABC:lI99|H3BEBA8 +3BEBA8:lI111|H3BEC94 +3BEC94:lI111|H3BED80 +3BED80:lI108|H3BEE6C +3BEE6C:lI116|H3BEF40 +3BEF40:lI97|H3BF00C +3BF00C:lI108|H3BF0D8 +3BF0D8:lI107|N +3BDDD4:lI105|H3BDE5C +3BDE5C:lI99|H3BDEFC +3BDEFC:lI101|N +3BDD68:lH3BDDE4|H3BDDF0 +3BDDE4:t2:H3BDE6C,H3BDE74 +3BDE74:lI118|H3BDF14 +3BDF14:lI105|H3BDFC0 +3BDFC0:lI100|H3BE084 +3BE084:lI101|H3BE158 +3BE158:lI111|H3BE22C +3BE22C:lI47|H3BE314 +3BE314:lI120|H3BE408 +3BE408:lI45|H3BE50C +3BE50C:lI115|H3BE610 +3BE610:lI103|H3BE714 +3BE714:lI105|H3BE800 +3BE800:lI45|H3BE8E4 +3BE8E4:lI109|H3BE9D0 +3BE9D0:lI111|H3BEAC4 +3BEAC4:lI118|H3BEBB0 +3BEBB0:lI105|H3BEC9C +3BEC9C:lI101|N +3BDE6C:lI109|H3BDF0C +3BDF0C:lI111|H3BDFB8 +3BDFB8:lI118|H3BE07C +3BE07C:lI105|H3BE150 +3BE150:lI101|N +3BDDF0:lH3BDE7C|H3BDE88 +3BDE7C:t2:H3BDF1C,H3BDF24 +3BDF24:lI118|H3BDFD0 +3BDFD0:lI105|H3BE094 +3BE094:lI100|H3BE160 +3BE160:lI101|H3BE234 +3BE234:lI111|H3BE31C +3BE31C:lI47|H3BE410 +3BE410:lI120|H3BE514 +3BE514:lI45|H3BE618 +3BE618:lI109|H3BE71C +3BE71C:lI115|H3BE808 +3BE808:lI118|H3BE8EC +3BE8EC:lI105|H3BE9D8 +3BE9D8:lI100|H3BEACC +3BEACC:lI101|H3BEBB8 +3BEBB8:lI111|N +3BDF1C:lI97|H3BDFC8 +3BDFC8:lI118|H3BE08C +3BE08C:lI105|N +3BDE88:lH3BDF2C|H3BDF38 +3BDF2C:t2:H3BDFD8,H3BDFE0 +3BDFE0:lI118|H3BE0A4 +3BE0A4:lI105|H3BE168 +3BE168:lI100|H3BE23C +3BE23C:lI101|H3BE324 +3BE324:lI111|H3BE418 +3BE418:lI47|H3BE51C +3BE51C:lI113|H3BE620 +3BE620:lI117|H3BE724 +3BE724:lI105|H3BE810 +3BE810:lI99|H3BE8F4 +3BE8F4:lI107|H3BE9E0 +3BE9E0:lI116|H3BEAD4 +3BEAD4:lI105|H3BEBC0 +3BEBC0:lI109|H3BECA4 +3BECA4:lI101|N +3BDFD8:lI113|H3BE09C +3BE09C:lI116|N +3BDF38:lH3BDFE8|H3BDFF4 +3BDFE8:t2:H3BE0AC,H3BE0B4 +3BE0B4:lI118|H3BE178 +3BE178:lI105|H3BE24C +3BE24C:lI100|H3BE32C +3BE32C:lI101|H3BE420 +3BE420:lI111|H3BE524 +3BE524:lI47|H3BE628 +3BE628:lI113|H3BE72C +3BE72C:lI117|H3BE818 +3BE818:lI105|H3BE8FC +3BE8FC:lI99|H3BE9E8 +3BE9E8:lI107|H3BEADC +3BEADC:lI116|H3BEBC8 +3BEBC8:lI105|H3BECAC +3BECAC:lI109|H3BED88 +3BED88:lI101|N +3BE0AC:lI109|H3BE170 +3BE170:lI111|H3BE244 +3BE244:lI118|N +3BDFF4:lH3BE0BC|H3BE0C8 +3BE0BC:t2:H3BE180,H3BE188 +3BE188:lI118|H3BE25C +3BE25C:lI105|H3BE33C +3BE33C:lI100|H3BE430 +3BE430:lI101|H3BE52C +3BE52C:lI111|H3BE630 +3BE630:lI47|H3BE734 +3BE734:lI109|H3BE820 +3BE820:lI112|H3BE904 +3BE904:lI101|H3BE9F0 +3BE9F0:lI103|N +3BE180:lI109|H3BE254 +3BE254:lI112|H3BE334 +3BE334:lI101|H3BE428 +3BE428:lI103|N +3BE0C8:lH3BE190|H3BE19C +3BE190:t2:H3BE264,H3BE26C +3BE26C:lI118|H3BE34C +3BE34C:lI105|H3BE440 +3BE440:lI100|H3BE534 +3BE534:lI101|H3BE638 +3BE638:lI111|H3BE73C +3BE73C:lI47|H3BE828 +3BE828:lI109|H3BE90C +3BE90C:lI112|H3BE9F8 +3BE9F8:lI101|H3BEAE4 +3BEAE4:lI103|N +3BE264:lI109|H3BE344 +3BE344:lI112|H3BE438 +3BE438:lI103|N +3BE19C:lH3BE274|H3BE280 +3BE274:t2:H3BE354,H3BE35C +3BE35C:lI118|H3BE450 +3BE450:lI105|H3BE544 +3BE544:lI100|H3BE640 +3BE640:lI101|H3BE744 +3BE744:lI111|H3BE830 +3BE830:lI47|H3BE914 +3BE914:lI109|H3BEA00 +3BEA00:lI112|H3BEAEC +3BEAEC:lI101|H3BEBD0 +3BEBD0:lI103|N +3BE354:lI109|H3BE448 +3BE448:lI112|H3BE53C +3BE53C:lI101|N +3BE280:lH3BE364|H3BE370 +3BE364:t2:H3BE458,H3BE460 +3BE460:lI116|H3BE554 +3BE554:lI101|H3BE650 +3BE650:lI120|H3BE754 +3BE754:lI116|H3BE838 +3BE838:lI47|H3BE91C +3BE91C:lI120|H3BEA08 +3BEA08:lI45|H3BEAF4 +3BEAF4:lI115|H3BEBD8 +3BEBD8:lI103|H3BECB4 +3BECB4:lI109|H3BED90 +3BED90:lI108|N +3BE458:lI115|H3BE54C +3BE54C:lI103|H3BE648 +3BE648:lI109|H3BE74C +3BE74C:lI108|N +3BE370:lH3BE468|H3BE474 +3BE468:t2:H3BE55C,H3BE564 +3BE564:lI116|H3BE660 +3BE660:lI101|H3BE764 +3BE764:lI120|H3BE840 +3BE840:lI116|H3BE924 +3BE924:lI47|H3BEA10 +3BEA10:lI120|H3BEAFC +3BEAFC:lI45|H3BEBE0 +3BEBE0:lI115|H3BECBC +3BECBC:lI103|H3BED98 +3BED98:lI109|H3BEE74 +3BEE74:lI108|N +3BE55C:lI115|H3BE658 +3BE658:lI103|H3BE75C +3BE75C:lI109|N +3BE474:lH3BE56C|H3BE578 +3BE56C:t2:H3BE668,H3BE670 +3BE670:lI116|H3BE774 +3BE774:lI101|H3BE850 +3BE850:lI120|H3BE92C +3BE92C:lI116|H3BEA18 +3BEA18:lI47|H3BEB04 +3BEB04:lI120|H3BEBE8 +3BEBE8:lI45|H3BECC4 +3BECC4:lI115|H3BEDA0 +3BEDA0:lI101|H3BEE7C +3BEE7C:lI116|H3BEF48 +3BEF48:lI101|H3BF014 +3BF014:lI120|H3BF0E0 +3BF0E0:lI116|N +3BE668:lI101|H3BE76C +3BE76C:lI116|H3BE848 +3BE848:lI120|N +3BE578:lH3BE678|H3BE684 +3BE678:t2:H3BE77C,H3BE784 +3BE784:lI116|H3BE860 +3BE860:lI101|H3BE93C +3BE93C:lI120|H3BEA20 +3BEA20:lI116|H3BEB0C +3BEB0C:lI47|H3BEBF0 +3BEBF0:lI116|H3BECCC +3BECCC:lI97|H3BEDA8 +3BEDA8:lI98|H3BEE84 +3BEE84:lI45|H3BEF50 +3BEF50:lI115|H3BF01C +3BF01C:lI101|H3BF0E8 +3BF0E8:lI112|H3BF1AC +3BF1AC:lI97|H3BF270 +3BF270:lI114|H3BF324 +3BF324:lI97|H3BF3D0 +3BF3D0:lI116|H3BF484 +3BF484:lI101|H3BF540 +3BF540:lI100|H3BF604 +3BF604:lI45|H3BF6D8 +3BF6D8:lI118|H3BF7AC +3BF7AC:lI97|H3BF880 +3BF880:lI108|H3BF964 +3BF964:lI117|H3BFA40 +3BFA40:lI101|H3BFB14 +3BFB14:lI115|N +3BE77C:lI116|H3BE858 +3BE858:lI115|H3BE934 +3BE934:lI118|N +3BE684:lH3BE78C|H3BE798 +3BE78C:t2:H3BE868,H3BE870 +3BE870:lI116|H3BE94C +3BE94C:lI101|H3BEA30 +3BEA30:lI120|H3BEB14 +3BEB14:lI116|H3BEBF8 +3BEBF8:lI47|H3BECD4 +3BECD4:lI114|H3BEDB0 +3BEDB0:lI105|H3BEE8C +3BEE8C:lI99|H3BEF58 +3BEF58:lI104|H3BF024 +3BF024:lI116|H3BF0F0 +3BF0F0:lI101|H3BF1B4 +3BF1B4:lI120|H3BF278 +3BF278:lI116|N +3BE868:lI114|H3BE944 +3BE944:lI116|H3BEA28 +3BEA28:lI120|N +3BE798:lH3BE878|H3BE884 +3BE878:t2:H3BE954,H3BE95C +3BE95C:lI116|H3BEA40 +3BEA40:lI101|H3BEB24 +3BEB24:lI120|H3BEC00 +3BEC00:lI116|H3BECDC +3BECDC:lI47|H3BEDB8 +3BEDB8:lI112|H3BEE94 +3BEE94:lI108|H3BEF60 +3BEF60:lI97|H3BF02C +3BF02C:lI105|H3BF0F8 +3BF0F8:lI110|N +3BE954:lI116|H3BEA38 +3BEA38:lI120|H3BEB1C +3BEB1C:lI116|N +3BE884:lH3BE964|H3BE970 +3BE964:t2:H3BEA48,H3BEA50 +3BEA50:lI116|H3BEB34 +3BEB34:lI101|H3BEC10 +3BEC10:lI120|H3BECEC +3BECEC:lI116|H3BEDC8 +3BEDC8:lI47|H3BEE9C +3BEE9C:lI120|H3BEF68 +3BEF68:lI45|H3BF034 +3BF034:lI115|H3BF100 +3BF100:lI101|H3BF1BC +3BF1BC:lI114|H3BF280 +3BF280:lI118|H3BF32C +3BF32C:lI101|H3BF3D8 +3BF3D8:lI114|H3BF48C +3BF48C:lI45|H3BF548 +3BF548:lI112|H3BF60C +3BF60C:lI97|H3BF6E0 +3BF6E0:lI114|H3BF7B4 +3BF7B4:lI115|H3BF888 +3BF888:lI101|H3BF96C +3BF96C:lI100|H3BFA48 +3BFA48:lI45|H3BFB1C +3BFB1C:lI104|H3BFBF0 +3BFBF0:lI116|H3BFCBC +3BFCBC:lI109|H3BFD80 +3BFD80:lI108|N +3BEA48:lI115|H3BEB2C +3BEB2C:lI104|H3BEC08 +3BEC08:lI116|H3BECE4 +3BECE4:lI109|H3BEDC0 +3BEDC0:lI108|N +3BE970:lH3BEA58|H3BEA64 +3BEA58:t2:H3BEB3C,H3BEB44 +3BEB44:lI116|H3BEC20 +3BEC20:lI101|H3BECFC +3BECFC:lI120|H3BEDD8 +3BEDD8:lI116|H3BEEA4 +3BEEA4:lI47|H3BEF70 +3BEF70:lI104|H3BF03C +3BF03C:lI116|H3BF108 +3BF108:lI109|H3BF1C4 +3BF1C4:lI108|N +3BEB3C:lI104|H3BEC18 +3BEC18:lI116|H3BECF4 +3BECF4:lI109|H3BEDD0 +3BEDD0:lI108|N +3BEA64:lH3BEB4C|H3BEB58 +3BEB4C:t2:H3BEC28,H3BEC30 +3BEC30:lI116|H3BED0C +3BED0C:lI101|H3BEDE8 +3BEDE8:lI120|H3BEEAC +3BEEAC:lI116|H3BEF78 +3BEF78:lI47|H3BF044 +3BF044:lI104|H3BF110 +3BF110:lI116|H3BF1CC +3BF1CC:lI109|H3BF288 +3BF288:lI108|N +3BEC28:lI104|H3BED04 +3BED04:lI116|H3BEDE0 +3BEDE0:lI109|N +3BEB58:lH3BEC38|H3BEC44 +3BEC38:t2:H3BED14,H3BED1C +3BED1C:lI105|H3BEDF8 +3BEDF8:lI109|H3BEEBC +3BEEBC:lI97|H3BEF80 +3BEF80:lI103|H3BF04C +3BF04C:lI101|H3BF118 +3BF118:lI47|H3BF1D4 +3BF1D4:lI120|H3BF290 +3BF290:lI45|H3BF334 +3BF334:lI120|H3BF3E0 +3BF3E0:lI119|H3BF494 +3BF494:lI105|H3BF550 +3BF550:lI110|H3BF614 +3BF614:lI100|H3BF6E8 +3BF6E8:lI111|H3BF7BC +3BF7BC:lI119|H3BF890 +3BF890:lI100|H3BF974 +3BF974:lI117|H3BFA50 +3BFA50:lI109|H3BFB24 +3BFB24:lI112|N +3BED14:lI120|H3BEDF0 +3BEDF0:lI119|H3BEEB4 +3BEEB4:lI100|N +3BEC44:lH3BED24|H3BED30 +3BED24:t2:H3BEE00,H3BEE08 +3BEE08:lI105|H3BEECC +3BEECC:lI109|H3BEF90 +3BEF90:lI97|H3BF054 +3BF054:lI103|H3BF120 +3BF120:lI101|H3BF1DC +3BF1DC:lI47|H3BF298 +3BF298:lI120|H3BF33C +3BF33C:lI45|H3BF3E8 +3BF3E8:lI120|H3BF49C +3BF49C:lI112|H3BF558 +3BF558:lI105|H3BF61C +3BF61C:lI120|H3BF6F0 +3BF6F0:lI109|H3BF7C4 +3BF7C4:lI97|H3BF898 +3BF898:lI112|N +3BEE00:lI120|H3BEEC4 +3BEEC4:lI112|H3BEF88 +3BEF88:lI109|N +3BED30:lH3BEE10|H3BEE1C +3BEE10:t2:H3BEED4,H3BEEDC +3BEEDC:lI105|H3BEFA0 +3BEFA0:lI109|H3BF064 +3BF064:lI97|H3BF128 +3BF128:lI103|H3BF1E4 +3BF1E4:lI101|H3BF2A0 +3BF2A0:lI47|H3BF344 +3BF344:lI120|H3BF3F0 +3BF3F0:lI45|H3BF4A4 +3BF4A4:lI120|H3BF560 +3BF560:lI98|H3BF624 +3BF624:lI105|H3BF6F8 +3BF6F8:lI116|H3BF7CC +3BF7CC:lI109|H3BF8A0 +3BF8A0:lI97|H3BF97C +3BF97C:lI112|N +3BEED4:lI120|H3BEF98 +3BEF98:lI98|H3BF05C +3BF05C:lI109|N +3BEE1C:lH3BEEE4|H3BEEF0 +3BEEE4:t2:H3BEFA8,H3BEFB0 +3BEFB0:lI105|H3BF074 +3BF074:lI109|H3BF138 +3BF138:lI97|H3BF1EC +3BF1EC:lI103|H3BF2A8 +3BF2A8:lI101|H3BF34C +3BF34C:lI47|H3BF3F8 +3BF3F8:lI120|H3BF4AC +3BF4AC:lI45|H3BF568 +3BF568:lI114|H3BF62C +3BF62C:lI103|H3BF700 +3BF700:lI98|N +3BEFA8:lI114|H3BF06C +3BF06C:lI103|H3BF130 +3BF130:lI98|N +3BEEF0:lH3BEFB8|H3BEFC4 +3BEFB8:t2:H3BF07C,H3BF084 +3BF084:lI105|H3BF148 +3BF148:lI109|H3BF1FC +3BF1FC:lI97|H3BF2B0 +3BF2B0:lI103|H3BF354 +3BF354:lI101|H3BF400 +3BF400:lI47|H3BF4B4 +3BF4B4:lI120|H3BF570 +3BF570:lI45|H3BF634 +3BF634:lI112|H3BF708 +3BF708:lI111|H3BF7D4 +3BF7D4:lI114|H3BF8A8 +3BF8A8:lI116|H3BF984 +3BF984:lI97|H3BFA58 +3BFA58:lI98|H3BFB2C +3BFB2C:lI108|H3BFBF8 +3BFBF8:lI101|H3BFCC4 +3BFCC4:lI45|H3BFD88 +3BFD88:lI112|H3BFE44 +3BFE44:lI105|H3BFEF0 +3BFEF0:lI120|H3BFFA4 +3BFFA4:lI109|H3C0050 +3C0050:lI97|H3C00FC +3C00FC:lI112|N +3BF07C:lI112|H3BF140 +3BF140:lI112|H3BF1F4 +3BF1F4:lI109|N +3BEFC4:lH3BF08C|H3BF098 +3BF08C:t2:H3BF150,H3BF158 +3BF158:lI105|H3BF20C +3BF20C:lI109|H3BF2C0 +3BF2C0:lI97|H3BF35C +3BF35C:lI103|H3BF408 +3BF408:lI101|H3BF4BC +3BF4BC:lI47|H3BF578 +3BF578:lI120|H3BF63C +3BF63C:lI45|H3BF710 +3BF710:lI112|H3BF7DC +3BF7DC:lI111|H3BF8B0 +3BF8B0:lI114|H3BF98C +3BF98C:lI116|H3BFA60 +3BFA60:lI97|H3BFB34 +3BFB34:lI98|H3BFC00 +3BFC00:lI108|H3BFCCC +3BFCCC:lI101|H3BFD90 +3BFD90:lI45|H3BFE4C +3BFE4C:lI103|H3BFEF8 +3BFEF8:lI114|H3BFFAC +3BFFAC:lI97|H3C0058 +3C0058:lI121|H3C0104 +3C0104:lI109|H3C01A8 +3C01A8:lI97|H3C025C +3C025C:lI112|N +3BF150:lI112|H3BF204 +3BF204:lI103|H3BF2B8 +3BF2B8:lI109|N +3BF098:lH3BF160|H3BF16C +3BF160:t2:H3BF214,H3BF21C +3BF21C:lI105|H3BF2D0 +3BF2D0:lI109|H3BF36C +3BF36C:lI97|H3BF410 +3BF410:lI103|H3BF4C4 +3BF4C4:lI101|H3BF580 +3BF580:lI47|H3BF644 +3BF644:lI120|H3BF718 +3BF718:lI45|H3BF7E4 +3BF7E4:lI112|H3BF8B8 +3BF8B8:lI111|H3BF994 +3BF994:lI114|H3BFA68 +3BFA68:lI116|H3BFB3C +3BFB3C:lI97|H3BFC08 +3BFC08:lI98|H3BFCD4 +3BFCD4:lI108|H3BFD98 +3BFD98:lI101|H3BFE54 +3BFE54:lI45|H3BFF00 +3BFF00:lI98|H3BFFB4 +3BFFB4:lI105|H3C0060 +3C0060:lI116|H3C010C +3C010C:lI109|H3C01B0 +3C01B0:lI97|H3C0264 +3C0264:lI112|N +3BF214:lI112|H3BF2C8 +3BF2C8:lI98|H3BF364 +3BF364:lI109|N +3BF16C:lH3BF224|H3BF230 +3BF224:t2:H3BF2D8,H3BF2E0 +3BF2E0:lI105|H3BF37C +3BF37C:lI109|H3BF420 +3BF420:lI97|H3BF4CC +3BF4CC:lI103|H3BF588 +3BF588:lI101|H3BF64C +3BF64C:lI47|H3BF720 +3BF720:lI120|H3BF7EC +3BF7EC:lI45|H3BF8C0 +3BF8C0:lI112|H3BF99C +3BF99C:lI111|H3BFA70 +3BFA70:lI114|H3BFB44 +3BFB44:lI116|H3BFC10 +3BFC10:lI97|H3BFCDC +3BFCDC:lI98|H3BFDA0 +3BFDA0:lI108|H3BFE5C +3BFE5C:lI101|H3BFF08 +3BFF08:lI45|H3BFFBC +3BFFBC:lI97|H3C0068 +3C0068:lI110|H3C0114 +3C0114:lI121|H3C01B8 +3C01B8:lI109|H3C026C +3C026C:lI97|H3C0318 +3C0318:lI112|N +3BF2D8:lI112|H3BF374 +3BF374:lI110|H3BF418 +3BF418:lI109|N +3BF230:lH3BF2E8|H3BF2F4 +3BF2E8:t2:H3BF384,H3BF38C +3BF38C:lI105|H3BF430 +3BF430:lI109|H3BF4DC +3BF4DC:lI97|H3BF590 +3BF590:lI103|H3BF654 +3BF654:lI101|H3BF728 +3BF728:lI47|H3BF7F4 +3BF7F4:lI120|H3BF8C8 +3BF8C8:lI45|H3BF9A4 +3BF9A4:lI99|H3BFA78 +3BFA78:lI109|H3BFB4C +3BFB4C:lI117|H3BFC18 +3BFC18:lI45|H3BFCE4 +3BFCE4:lI114|H3BFDA8 +3BFDA8:lI97|H3BFE64 +3BFE64:lI115|H3BFF10 +3BFF10:lI116|H3BFFC4 +3BFFC4:lI101|H3C0070 +3C0070:lI114|N +3BF384:lI114|H3BF428 +3BF428:lI97|H3BF4D4 +3BF4D4:lI115|N +3BF2F4:lH3BF394|H3BF3A0 +3BF394:t2:H3BF438,H3BF440 +3BF440:lI105|H3BF4EC +3BF4EC:lI109|H3BF5A0 +3BF5A0:lI97|H3BF664 +3BF664:lI103|H3BF730 +3BF730:lI101|H3BF7FC +3BF7FC:lI47|H3BF8D0 +3BF8D0:lI116|H3BF9AC +3BF9AC:lI105|H3BFA80 +3BFA80:lI102|H3BFB54 +3BFB54:lI102|N +3BF438:lI116|H3BF4E4 +3BF4E4:lI105|H3BF598 +3BF598:lI102|H3BF65C +3BF65C:lI102|N +3BF3A0:lH3BF448|H3BF454 +3BF448:t2:H3BF4F4,H3BF4FC +3BF4FC:lI105|H3BF5B0 +3BF5B0:lI109|H3BF674 +3BF674:lI97|H3BF738 +3BF738:lI103|H3BF804 +3BF804:lI101|H3BF8D8 +3BF8D8:lI47|H3BF9B4 +3BF9B4:lI116|H3BFA88 +3BFA88:lI105|H3BFB5C +3BFB5C:lI102|H3BFC20 +3BFC20:lI102|N +3BF4F4:lI116|H3BF5A8 +3BF5A8:lI105|H3BF66C +3BF66C:lI102|N +3BF454:lH3BF504|H3BF510 +3BF504:t2:H3BF5B8,H3BF5C0 +3BF5C0:lI105|H3BF684 +3BF684:lI109|H3BF748 +3BF748:lI97|H3BF80C +3BF80C:lI103|H3BF8E0 +3BF8E0:lI101|H3BF9BC +3BF9BC:lI47|H3BFA90 +3BFA90:lI112|H3BFB64 +3BFB64:lI110|H3BFC28 +3BFC28:lI103|N +3BF5B8:lI112|H3BF67C +3BF67C:lI110|H3BF740 +3BF740:lI103|N +3BF510:lH3BF5C8|H3BF5D4 +3BF5C8:t2:H3BF68C,H3BF694 +3BF694:lI105|H3BF758 +3BF758:lI109|H3BF81C +3BF81C:lI97|H3BF8F0 +3BF8F0:lI103|H3BF9C4 +3BF9C4:lI101|H3BFA98 +3BFA98:lI47|H3BFB6C +3BFB6C:lI106|H3BFC30 +3BFC30:lI112|H3BFCEC +3BFCEC:lI101|H3BFDB0 +3BFDB0:lI103|N +3BF68C:lI106|H3BF750 +3BF750:lI112|H3BF814 +3BF814:lI101|H3BF8E8 +3BF8E8:lI103|N +3BF5D4:lH3BF69C|H3BF6A8 +3BF69C:t2:H3BF760,H3BF768 +3BF768:lI105|H3BF82C +3BF82C:lI109|H3BF900 +3BF900:lI97|H3BF9CC +3BF9CC:lI103|H3BFAA0 +3BFAA0:lI101|H3BFB74 +3BFB74:lI47|H3BFC38 +3BFC38:lI106|H3BFCF4 +3BFCF4:lI112|H3BFDB8 +3BFDB8:lI101|H3BFE6C +3BFE6C:lI103|N +3BF760:lI106|H3BF824 +3BF824:lI112|H3BF8F8 +3BF8F8:lI103|N +3BF6A8:lH3BF770|H3BF77C +3BF770:t2:H3BF834,H3BF83C +3BF83C:lI105|H3BF910 +3BF910:lI109|H3BF9DC +3BF9DC:lI97|H3BFAA8 +3BFAA8:lI103|H3BFB7C +3BFB7C:lI101|H3BFC40 +3BFC40:lI47|H3BFCFC +3BFCFC:lI106|H3BFDC0 +3BFDC0:lI112|H3BFE74 +3BFE74:lI101|H3BFF18 +3BFF18:lI103|N +3BF834:lI106|H3BF908 +3BF908:lI112|H3BF9D4 +3BF9D4:lI101|N +3BF77C:lH3BF844|H3BF850 +3BF844:t2:H3BF918,H3BF920 +3BF920:lI105|H3BF9EC +3BF9EC:lI109|H3BFAB8 +3BFAB8:lI97|H3BFB84 +3BFB84:lI103|H3BFC48 +3BFC48:lI101|H3BFD04 +3BFD04:lI47|H3BFDC8 +3BFDC8:lI105|H3BFE7C +3BFE7C:lI101|H3BFF20 +3BFF20:lI102|N +3BF918:lI105|H3BF9E4 +3BF9E4:lI101|H3BFAB0 +3BFAB0:lI102|N +3BF850:lH3BF928|H3BF934 +3BF928:t2:H3BF9F4,H3BF9FC +3BF9FC:lI105|H3BFAC8 +3BFAC8:lI109|H3BFB94 +3BFB94:lI97|H3BFC50 +3BFC50:lI103|H3BFD0C +3BFD0C:lI101|H3BFDD0 +3BFDD0:lI47|H3BFE84 +3BFE84:lI103|H3BFF28 +3BFF28:lI105|H3BFFCC +3BFFCC:lI102|N +3BF9F4:lI103|H3BFAC0 +3BFAC0:lI105|H3BFB8C +3BFB8C:lI102|N +3BF934:lH3BFA04|H3BFA10 +3BFA04:t2:H3BFAD0,H3BFAD8 +3BFAD8:lI99|H3BFBA4 +3BFBA4:lI104|H3BFC60 +3BFC60:lI101|H3BFD14 +3BFD14:lI109|H3BFDD8 +3BFDD8:lI105|H3BFE8C +3BFE8C:lI99|H3BFF30 +3BFF30:lI97|H3BFFD4 +3BFFD4:lI108|H3C0078 +3C0078:lI47|H3C011C +3C011C:lI120|H3C01C0 +3C01C0:lI45|H3C0274 +3C0274:lI112|H3C0320 +3C0320:lI100|H3C03CC +3C03CC:lI98|N +3BFAD0:lI112|H3BFB9C +3BFB9C:lI100|H3BFC58 +3BFC58:lI98|N +3BFA10:lH3BFAE0|H3BFAEC +3BFAE0:t2:H3BFBAC,H3BFBB4 +3BFBB4:lI99|H3BFC70 +3BFC70:lI104|H3BFD24 +3BFD24:lI101|H3BFDE0 +3BFDE0:lI109|H3BFE94 +3BFE94:lI105|H3BFF38 +3BFF38:lI99|H3BFFDC +3BFFDC:lI97|H3C0080 +3C0080:lI108|H3C0124 +3C0124:lI47|H3C01C8 +3C01C8:lI120|H3C027C +3C027C:lI45|H3C0328 +3C0328:lI112|H3C03D4 +3C03D4:lI100|H3C0460 +3C0460:lI98|N +3BFBAC:lI120|H3BFC68 +3BFC68:lI121|H3BFD1C +3BFD1C:lI122|N +3BFAEC:lH3BFBBC|H3BFBC8 +3BFBBC:t2:H3BFC78,H3BFC80 +3BFC80:lI97|H3BFD34 +3BFD34:lI117|H3BFDF0 +3BFDF0:lI100|H3BFE9C +3BFE9C:lI105|H3BFF40 +3BFF40:lI111|H3BFFE4 +3BFFE4:lI47|H3C0088 +3C0088:lI120|H3C012C +3C012C:lI45|H3C01D0 +3C01D0:lI119|H3C0284 +3C0284:lI97|H3C0330 +3C0330:lI118|N +3BFC78:lI119|H3BFD2C +3BFD2C:lI97|H3BFDE8 +3BFDE8:lI118|N +3BFBC8:lH3BFC88|H3BFC94 +3BFC88:t2:H3BFD3C,H3BFD44 +3BFD44:lI97|H3BFE00 +3BFE00:lI117|H3BFEA4 +3BFEA4:lI100|H3BFF48 +3BFF48:lI105|H3BFFEC +3BFFEC:lI111|H3C0090 +3C0090:lI47|H3C0134 +3C0134:lI120|H3C01D8 +3C01D8:lI45|H3C028C +3C028C:lI114|H3C0338 +3C0338:lI101|H3C03DC +3C03DC:lI97|H3C0468 +3C0468:lI108|H3C04FC +3C04FC:lI97|H3C0598 +3C0598:lI117|H3C063C +3C063C:lI100|H3C06E8 +3C06E8:lI105|H3C0794 +3C0794:lI111|N +3BFD3C:lI114|H3BFDF8 +3BFDF8:lI97|N +3BFC94:lH3BFD4C|H3BFD58 +3BFD4C:t2:H3BFE08,H3BFE10 +3BFE10:lI97|H3BFEB4 +3BFEB4:lI117|H3BFF58 +3BFF58:lI100|H3BFFF4 +3BFFF4:lI105|H3C0098 +3C0098:lI111|H3C013C +3C013C:lI47|H3C01E0 +3C01E0:lI120|H3C0294 +3C0294:lI45|H3C0340 +3C0340:lI112|H3C03E4 +3C03E4:lI110|H3C0470 +3C0470:lI45|H3C0504 +3C0504:lI114|H3C05A0 +3C05A0:lI101|H3C0644 +3C0644:lI97|H3C06F0 +3C06F0:lI108|H3C079C +3C079C:lI97|H3C0838 +3C0838:lI117|H3C08C4 +3C08C4:lI100|H3C0958 +3C0958:lI105|H3C09EC +3C09EC:lI111|H3C0A88 +3C0A88:lI45|H3C0B2C +3C0B2C:lI112|H3C0BD0 +3C0BD0:lI108|H3C0C84 +3C0C84:lI117|H3C0D38 +3C0D38:lI103|H3C0DEC +3C0DEC:lI105|H3C0EA0 +3C0EA0:lI110|N +3BFE08:lI114|H3BFEAC +3BFEAC:lI112|H3BFF50 +3BFF50:lI109|N +3BFD58:lH3BFE18|H3BFE24 +3BFE18:t2:H3BFEBC,H3BFEC4 +3BFEC4:lI97|H3BFF68 +3BFF68:lI117|H3C0004 +3C0004:lI100|H3C00A0 +3C00A0:lI105|H3C0144 +3C0144:lI111|H3C01E8 +3C01E8:lI47|H3C029C +3C029C:lI120|H3C0348 +3C0348:lI45|H3C03EC +3C03EC:lI112|H3C0478 +3C0478:lI110|H3C050C +3C050C:lI45|H3C05A8 +3C05A8:lI114|H3C064C +3C064C:lI101|H3C06F8 +3C06F8:lI97|H3C07A4 +3C07A4:lI108|H3C0840 +3C0840:lI97|H3C08CC +3C08CC:lI117|H3C0960 +3C0960:lI100|H3C09F4 +3C09F4:lI105|H3C0A90 +3C0A90:lI111|N +3BFEBC:lI114|H3BFF60 +3BFF60:lI97|H3BFFFC +3BFFFC:lI109|N +3BFE24:lH3BFECC|H3BFED8 +3BFECC:t2:H3BFF70,H3BFF78 +3BFF78:lI97|H3C0014 +3C0014:lI117|H3C00B0 +3C00B0:lI100|H3C014C +3C014C:lI105|H3C01F0 +3C01F0:lI111|H3C02A4 +3C02A4:lI47|H3C0350 +3C0350:lI120|H3C03F4 +3C03F4:lI45|H3C0480 +3C0480:lI97|H3C0514 +3C0514:lI105|H3C05B0 +3C05B0:lI102|H3C0654 +3C0654:lI102|N +3BFF70:lI97|H3C000C +3C000C:lI105|H3C00A8 +3C00A8:lI102|N +3BFED8:lH3BFF80|H3BFF8C +3BFF80:t2:H3C001C,H3C0024 +3C0024:lI97|H3C00C0 +3C00C0:lI117|H3C015C +3C015C:lI100|H3C0200 +3C0200:lI105|H3C02AC +3C02AC:lI111|H3C0358 +3C0358:lI47|H3C03FC +3C03FC:lI120|H3C0488 +3C0488:lI45|H3C051C +3C051C:lI97|H3C05B8 +3C05B8:lI105|H3C065C +3C065C:lI102|H3C0700 +3C0700:lI102|N +3C001C:lI97|H3C00B8 +3C00B8:lI105|H3C0154 +3C0154:lI102|H3C01F8 +3C01F8:lI102|N +3BFF8C:lH3C002C|H3C0038 +3C002C:t2:H3C00C8,H3C00D0 +3C00D0:lI97|H3C016C +3C016C:lI117|H3C0210 +3C0210:lI100|H3C02BC +3C02BC:lI105|H3C0360 +3C0360:lI111|H3C0404 +3C0404:lI47|H3C0490 +3C0490:lI120|H3C0524 +3C0524:lI45|H3C05C0 +3C05C0:lI97|H3C0664 +3C0664:lI105|H3C0708 +3C0708:lI102|H3C07AC +3C07AC:lI102|N +3C00C8:lI97|H3C0164 +3C0164:lI105|H3C0208 +3C0208:lI102|H3C02B4 +3C02B4:lI99|N +3C0038:lH3C00D8|H3C00E4 +3C00D8:t2:H3C0174,H3C017C +3C017C:lI97|H3C0220 +3C0220:lI117|H3C02CC +3C02CC:lI100|H3C0370 +3C0370:lI105|H3C040C +3C040C:lI111|H3C0498 +3C0498:lI47|H3C052C +3C052C:lI109|H3C05C8 +3C05C8:lI112|H3C066C +3C066C:lI101|H3C0710 +3C0710:lI103|N +3C0174:lI109|H3C0218 +3C0218:lI112|H3C02C4 +3C02C4:lI103|H3C0368 +3C0368:lI97|N +3C00E4:lH3C0184|H3C0190 +3C0184:t2:H3C0228,H3C0230 +3C0230:lI97|H3C02DC +3C02DC:lI117|H3C0380 +3C0380:lI100|H3C0414 +3C0414:lI105|H3C04A0 +3C04A0:lI111|H3C0534 +3C0534:lI47|H3C05D0 +3C05D0:lI109|H3C0674 +3C0674:lI112|H3C0718 +3C0718:lI101|H3C07B4 +3C07B4:lI103|N +3C0228:lI109|H3C02D4 +3C02D4:lI112|H3C0378 +3C0378:lI50|N +3C0190:lH3C0238|H3C0244 +3C0238:t2:H3C02E4,H3C02EC +3C02EC:lI97|H3C0390 +3C0390:lI117|H3C041C +3C041C:lI100|H3C04A8 +3C04A8:lI105|H3C053C +3C053C:lI111|H3C05D8 +3C05D8:lI47|H3C067C +3C067C:lI98|H3C0720 +3C0720:lI97|H3C07BC +3C07BC:lI115|H3C0848 +3C0848:lI105|H3C08D4 +3C08D4:lI99|N +3C02E4:lI97|H3C0388 +3C0388:lI117|N +3C0244:lH3C02F4|H3C0300 +3C02F4:t2:H3C0398,H3C03A0 +3C03A0:lI97|H3C042C +3C042C:lI117|H3C04B8 +3C04B8:lI100|H3C0544 +3C0544:lI105|H3C05E0 +3C05E0:lI111|H3C0684 +3C0684:lI47|H3C0728 +3C0728:lI98|H3C07C4 +3C07C4:lI97|H3C0850 +3C0850:lI115|H3C08DC +3C08DC:lI105|H3C0968 +3C0968:lI99|N +3C0398:lI115|H3C0424 +3C0424:lI110|H3C04B0 +3C04B0:lI100|N +3C0300:lH3C03A8|H3C03B4 +3C03A8:t2:H3C0434,H3C043C +3C043C:lI97|H3C04C8 +3C04C8:lI112|H3C0554 +3C0554:lI112|H3C05E8 +3C05E8:lI108|H3C068C +3C068C:lI105|H3C0730 +3C0730:lI99|H3C07CC +3C07CC:lI97|H3C0858 +3C0858:lI116|H3C08E4 +3C08E4:lI105|H3C0970 +3C0970:lI111|H3C09FC +3C09FC:lI110|H3C0A98 +3C0A98:lI47|H3C0B34 +3C0B34:lI122|H3C0BD8 +3C0BD8:lI105|H3C0C8C +3C0C8C:lI112|N +3C0434:lI122|H3C04C0 +3C04C0:lI105|H3C054C +3C054C:lI112|N +3C03B4:lH3C0444|H3C0450 +3C0444:t2:H3C04D0,H3C04D8 +3C04D8:lI97|H3C0564 +3C0564:lI112|H3C05F8 +3C05F8:lI112|H3C0694 +3C0694:lI108|H3C0738 +3C0738:lI105|H3C07D4 +3C07D4:lI99|H3C0860 +3C0860:lI97|H3C08EC +3C08EC:lI116|H3C0978 +3C0978:lI105|H3C0A04 +3C0A04:lI111|H3C0AA0 +3C0AA0:lI110|H3C0B3C +3C0B3C:lI47|H3C0BE0 +3C0BE0:lI120|H3C0C94 +3C0C94:lI45|H3C0D40 +3C0D40:lI119|H3C0DF4 +3C0DF4:lI97|H3C0EA8 +3C0EA8:lI105|H3C0F64 +3C0F64:lI115|H3C1030 +3C1030:lI45|H3C1104 +3C1104:lI115|H3C11D8 +3C11D8:lI111|H3C12A4 +3C12A4:lI117|H3C1378 +3C1378:lI114|H3C1454 +3C1454:lI99|H3C1538 +3C1538:lI101|N +3C04D0:lI115|H3C055C +3C055C:lI114|H3C05F0 +3C05F0:lI99|N +3C0450:lH3C04E0|H3C04EC +3C04E0:t2:H3C056C,H3C0574 +3C0574:lI97|H3C0608 +3C0608:lI112|H3C06A4 +3C06A4:lI112|H3C0748 +3C0748:lI108|H3C07E4 +3C07E4:lI105|H3C0868 +3C0868:lI99|H3C08F4 +3C08F4:lI97|H3C0980 +3C0980:lI116|H3C0A0C +3C0A0C:lI105|H3C0AA8 +3C0AA8:lI111|H3C0B44 +3C0B44:lI110|H3C0BE8 +3C0BE8:lI47|H3C0C9C +3C0C9C:lI120|H3C0D48 +3C0D48:lI45|H3C0DFC +3C0DFC:lI117|H3C0EB0 +3C0EB0:lI115|H3C0F6C +3C0F6C:lI116|H3C1038 +3C1038:lI97|H3C110C +3C110C:lI114|N +3C056C:lI117|H3C0600 +3C0600:lI115|H3C069C +3C069C:lI116|H3C0740 +3C0740:lI97|H3C07DC +3C07DC:lI114|N +3C04EC:lH3C057C|H3C0588 +3C057C:t2:H3C0610,H3C0618 +3C0618:lI97|H3C06B4 +3C06B4:lI112|H3C0750 +3C0750:lI112|H3C07EC +3C07EC:lI108|H3C0870 +3C0870:lI105|H3C08FC +3C08FC:lI99|H3C0988 +3C0988:lI97|H3C0A14 +3C0A14:lI116|H3C0AB0 +3C0AB0:lI105|H3C0B4C +3C0B4C:lI111|H3C0BF0 +3C0BF0:lI110|H3C0CA4 +3C0CA4:lI47|H3C0D50 +3C0D50:lI120|H3C0E04 +3C0E04:lI45|H3C0EB8 +3C0EB8:lI116|H3C0F74 +3C0F74:lI114|H3C1040 +3C1040:lI111|H3C1114 +3C1114:lI102|H3C11E0 +3C11E0:lI102|H3C12AC +3C12AC:lI45|H3C1380 +3C1380:lI109|H3C145C +3C145C:lI115|N +3C0610:lI109|H3C06AC +3C06AC:lI115|N +3C0588:lH3C0620|H3C062C +3C0620:t2:H3C06BC,H3C06C4 +3C06C4:lI97|H3C0760 +3C0760:lI112|H3C07F4 +3C07F4:lI112|H3C0878 +3C0878:lI108|H3C0904 +3C0904:lI105|H3C0990 +3C0990:lI99|H3C0A1C +3C0A1C:lI97|H3C0AB8 +3C0AB8:lI116|H3C0B54 +3C0B54:lI105|H3C0BF8 +3C0BF8:lI111|H3C0CAC +3C0CAC:lI110|H3C0D58 +3C0D58:lI47|H3C0E0C +3C0E0C:lI120|H3C0EC0 +3C0EC0:lI45|H3C0F7C +3C0F7C:lI116|H3C1048 +3C1048:lI114|H3C111C +3C111C:lI111|H3C11E8 +3C11E8:lI102|H3C12B4 +3C12B4:lI102|H3C1388 +3C1388:lI45|H3C1464 +3C1464:lI109|H3C1540 +3C1540:lI101|N +3C06BC:lI109|H3C0758 +3C0758:lI101|N +3C062C:lH3C06CC|H3C06D8 +3C06CC:t2:H3C0768,H3C0770 +3C0770:lI97|H3C0804 +3C0804:lI112|H3C0888 +3C0888:lI112|H3C090C +3C090C:lI108|H3C0998 +3C0998:lI105|H3C0A24 +3C0A24:lI99|H3C0AC0 +3C0AC0:lI97|H3C0B5C +3C0B5C:lI116|H3C0C00 +3C0C00:lI105|H3C0CB4 +3C0CB4:lI111|H3C0D60 +3C0D60:lI110|H3C0E14 +3C0E14:lI47|H3C0EC8 +3C0EC8:lI120|H3C0F84 +3C0F84:lI45|H3C1050 +3C1050:lI116|H3C1124 +3C1124:lI114|H3C11F0 +3C11F0:lI111|H3C12BC +3C12BC:lI102|H3C1390 +3C1390:lI102|H3C146C +3C146C:lI45|H3C1548 +3C1548:lI109|H3C161C +3C161C:lI97|H3C16F0 +3C16F0:lI110|N +3C0768:lI109|H3C07FC +3C07FC:lI97|H3C0880 +3C0880:lI110|N +3C06D8:lH3C0778|H3C0784 +3C0778:t2:H3C080C,H3C0814 +3C0814:lI97|H3C0890 +3C0890:lI112|H3C0914 +3C0914:lI112|H3C09A0 +3C09A0:lI108|H3C0A2C +3C0A2C:lI105|H3C0AC8 +3C0AC8:lI99|H3C0B64 +3C0B64:lI97|H3C0C08 +3C0C08:lI116|H3C0CBC +3C0CBC:lI105|H3C0D68 +3C0D68:lI111|H3C0E1C +3C0E1C:lI110|H3C0ED0 +3C0ED0:lI47|H3C0F8C +3C0F8C:lI120|H3C1058 +3C1058:lI45|H3C112C +3C112C:lI116|H3C11F8 +3C11F8:lI114|H3C12C4 +3C12C4:lI111|H3C1398 +3C1398:lI102|H3C1474 +3C1474:lI102|N +3C080C:lI116|N +3C0784:lH3C081C|H3C0828 +3C081C:t2:H3C0898,H3C08A0 +3C08A0:lI97|H3C0924 +3C0924:lI112|H3C09A8 +3C09A8:lI112|H3C0A34 +3C0A34:lI108|H3C0AD0 +3C0AD0:lI105|H3C0B6C +3C0B6C:lI99|H3C0C10 +3C0C10:lI97|H3C0CC4 +3C0CC4:lI116|H3C0D70 +3C0D70:lI105|H3C0E24 +3C0E24:lI111|H3C0ED8 +3C0ED8:lI110|H3C0F94 +3C0F94:lI47|H3C1060 +3C1060:lI120|H3C1134 +3C1134:lI45|H3C1200 +3C1200:lI116|H3C12CC +3C12CC:lI114|H3C13A0 +3C13A0:lI111|H3C147C +3C147C:lI102|H3C1550 +3C1550:lI102|N +3C0898:lI116|H3C091C +3C091C:lI114|N +3C0828:lH3C08A8|H3C08B4 +3C08A8:t2:H3C092C,H3C0934 +3C0934:lI97|H3C09B8 +3C09B8:lI112|H3C0A44 +3C0A44:lI112|H3C0AE0 +3C0AE0:lI108|H3C0B74 +3C0B74:lI105|H3C0C18 +3C0C18:lI99|H3C0CCC +3C0CCC:lI97|H3C0D78 +3C0D78:lI116|H3C0E2C +3C0E2C:lI105|H3C0EE0 +3C0EE0:lI111|H3C0F9C +3C0F9C:lI110|H3C1068 +3C1068:lI47|H3C113C +3C113C:lI120|H3C1208 +3C1208:lI45|H3C12D4 +3C12D4:lI116|H3C13A8 +3C13A8:lI114|H3C1484 +3C1484:lI111|H3C1558 +3C1558:lI102|H3C1624 +3C1624:lI102|N +3C092C:lI114|H3C09B0 +3C09B0:lI111|H3C0A3C +3C0A3C:lI102|H3C0AD8 +3C0AD8:lI102|N +3C08B4:lH3C093C|H3C0948 +3C093C:t2:H3C09C0,H3C09C8 +3C09C8:lI97|H3C0A54 +3C0A54:lI112|H3C0AF0 +3C0AF0:lI112|H3C0B84 +3C0B84:lI108|H3C0C28 +3C0C28:lI105|H3C0CDC +3C0CDC:lI99|H3C0D88 +3C0D88:lI97|H3C0E34 +3C0E34:lI116|H3C0EE8 +3C0EE8:lI105|H3C0FA4 +3C0FA4:lI111|H3C1070 +3C1070:lI110|H3C1144 +3C1144:lI47|H3C1210 +3C1210:lI120|H3C12DC +3C12DC:lI45|H3C13B0 +3C13B0:lI116|H3C148C +3C148C:lI101|H3C1560 +3C1560:lI120|H3C162C +3C162C:lI105|H3C16F8 +3C16F8:lI110|H3C17BC +3C17BC:lI102|H3C1880 +3C1880:lI111|N +3C09C0:lI116|H3C0A4C +3C0A4C:lI101|H3C0AE8 +3C0AE8:lI120|H3C0B7C +3C0B7C:lI105|H3C0C20 +3C0C20:lI110|H3C0CD4 +3C0CD4:lI102|H3C0D80 +3C0D80:lI111|N +3C0948:lH3C09D0|H3C09DC +3C09D0:t2:H3C0A5C,H3C0A64 +3C0A64:lI97|H3C0B00 +3C0B00:lI112|H3C0B94 +3C0B94:lI112|H3C0C38 +3C0C38:lI108|H3C0CE4 +3C0CE4:lI105|H3C0D90 +3C0D90:lI99|H3C0E3C +3C0E3C:lI97|H3C0EF0 +3C0EF0:lI116|H3C0FAC +3C0FAC:lI105|H3C1078 +3C1078:lI111|H3C114C +3C114C:lI110|H3C1218 +3C1218:lI47|H3C12E4 +3C12E4:lI120|H3C13B8 +3C13B8:lI45|H3C1494 +3C1494:lI116|H3C1568 +3C1568:lI101|H3C1634 +3C1634:lI120|H3C1700 +3C1700:lI105|H3C17C4 +3C17C4:lI110|H3C1888 +3C1888:lI102|H3C1944 +3C1944:lI111|N +3C0A5C:lI116|H3C0AF8 +3C0AF8:lI101|H3C0B8C +3C0B8C:lI120|H3C0C30 +3C0C30:lI105|N +3C09DC:lH3C0A6C|H3C0A78 +3C0A6C:t2:H3C0B08,H3C0B10 +3C0B10:lI97|H3C0BA4 +3C0BA4:lI112|H3C0C48 +3C0C48:lI112|H3C0CEC +3C0CEC:lI108|H3C0D98 +3C0D98:lI105|H3C0E44 +3C0E44:lI99|H3C0EF8 +3C0EF8:lI97|H3C0FB4 +3C0FB4:lI116|H3C1080 +3C1080:lI105|H3C1154 +3C1154:lI111|H3C1220 +3C1220:lI110|H3C12EC +3C12EC:lI47|H3C13C0 +3C13C0:lI120|H3C149C +3C149C:lI45|H3C1570 +3C1570:lI116|H3C163C +3C163C:lI101|H3C1708 +3C1708:lI120|N +3C0B08:lI116|H3C0B9C +3C0B9C:lI101|H3C0C40 +3C0C40:lI120|N +3C0A78:lH3C0B18|H3C0B24 +3C0B18:t2:H3C0BAC,H3C0BB4 +3C0BB4:lI97|H3C0C58 +3C0C58:lI112|H3C0CFC +3C0CFC:lI112|H3C0DA0 +3C0DA0:lI108|H3C0E4C +3C0E4C:lI105|H3C0F00 +3C0F00:lI99|H3C0FBC +3C0FBC:lI97|H3C1088 +3C1088:lI116|H3C115C +3C115C:lI105|H3C1228 +3C1228:lI111|H3C12F4 +3C12F4:lI110|H3C13C8 +3C13C8:lI47|H3C14A4 +3C14A4:lI120|H3C1578 +3C1578:lI45|H3C1644 +3C1644:lI116|H3C1710 +3C1710:lI99|H3C17CC +3C17CC:lI108|N +3C0BAC:lI116|H3C0C50 +3C0C50:lI99|H3C0CF4 +3C0CF4:lI108|N +3C0B24:lH3C0BBC|H3C0BC8 +3C0BBC:t2:H3C0C60,H3C0C68 +3C0C68:lI97|H3C0D0C +3C0D0C:lI112|H3C0DB0 +3C0DB0:lI112|H3C0E54 +3C0E54:lI108|H3C0F08 +3C0F08:lI105|H3C0FC4 +3C0FC4:lI99|H3C1090 +3C1090:lI97|H3C1164 +3C1164:lI116|H3C1230 +3C1230:lI105|H3C12FC +3C12FC:lI111|H3C13D0 +3C13D0:lI110|H3C14AC +3C14AC:lI47|H3C1580 +3C1580:lI120|H3C164C +3C164C:lI45|H3C1718 +3C1718:lI116|H3C17D4 +3C17D4:lI97|H3C1890 +3C1890:lI114|N +3C0C60:lI116|H3C0D04 +3C0D04:lI97|H3C0DA8 +3C0DA8:lI114|N +3C0BC8:lH3C0C70|H3C0C7C +3C0C70:t2:H3C0D14,H3C0D1C +3C0D1C:lI97|H3C0DC0 +3C0DC0:lI112|H3C0E64 +3C0E64:lI112|H3C0F18 +3C0F18:lI108|H3C0FD4 +3C0FD4:lI105|H3C10A0 +3C10A0:lI99|H3C116C +3C116C:lI97|H3C1238 +3C1238:lI116|H3C1304 +3C1304:lI105|H3C13D8 +3C13D8:lI111|H3C14B4 +3C14B4:lI110|H3C1588 +3C1588:lI47|H3C1654 +3C1654:lI120|H3C1720 +3C1720:lI45|H3C17DC +3C17DC:lI115|H3C1898 +3C1898:lI118|H3C194C +3C194C:lI52|H3C1A00 +3C1A00:lI99|H3C1AB4 +3C1AB4:lI114|H3C1B78 +3C1B78:lI99|N +3C0D14:lI115|H3C0DB8 +3C0DB8:lI118|H3C0E5C +3C0E5C:lI52|H3C0F10 +3C0F10:lI99|H3C0FCC +3C0FCC:lI114|H3C1098 +3C1098:lI99|N +3C0C7C:lH3C0D24|H3C0D30 +3C0D24:t2:H3C0DC8,H3C0DD0 +3C0DD0:lI97|H3C0E74 +3C0E74:lI112|H3C0F28 +3C0F28:lI112|H3C0FE4 +3C0FE4:lI108|H3C10B0 +3C10B0:lI105|H3C117C +3C117C:lI99|H3C1248 +3C1248:lI97|H3C130C +3C130C:lI116|H3C13E0 +3C13E0:lI105|H3C14BC +3C14BC:lI111|H3C1590 +3C1590:lI110|H3C165C +3C165C:lI47|H3C1728 +3C1728:lI120|H3C17E4 +3C17E4:lI45|H3C18A0 +3C18A0:lI115|H3C1954 +3C1954:lI118|H3C1A08 +3C1A08:lI52|H3C1ABC +3C1ABC:lI99|H3C1B80 +3C1B80:lI112|H3C1C4C +3C1C4C:lI105|H3C1D10 +3C1D10:lI111|N +3C0DC8:lI115|H3C0E6C +3C0E6C:lI118|H3C0F20 +3C0F20:lI52|H3C0FDC +3C0FDC:lI99|H3C10A8 +3C10A8:lI112|H3C1174 +3C1174:lI105|H3C1240 +3C1240:lI111|N +3C0D30:lH3C0DD8|H3C0DE4 +3C0DD8:t2:H3C0E7C,H3C0E84 +3C0E84:lI97|H3C0F38 +3C0F38:lI112|H3C0FF4 +3C0FF4:lI112|H3C10B8 +3C10B8:lI108|H3C1184 +3C1184:lI105|H3C1250 +3C1250:lI99|H3C1314 +3C1314:lI97|H3C13E8 +3C13E8:lI116|H3C14C4 +3C14C4:lI105|H3C1598 +3C1598:lI111|H3C1664 +3C1664:lI110|H3C1730 +3C1730:lI47|H3C17EC +3C17EC:lI120|H3C18A8 +3C18A8:lI45|H3C195C +3C195C:lI115|H3C1A10 +3C1A10:lI116|H3C1AC4 +3C1AC4:lI117|H3C1B88 +3C1B88:lI102|H3C1C54 +3C1C54:lI102|H3C1D18 +3C1D18:lI105|H3C1DD4 +3C1DD4:lI116|N +3C0E7C:lI115|H3C0F30 +3C0F30:lI105|H3C0FEC +3C0FEC:lI116|N +3C0DE4:lH3C0E8C|H3C0E98 +3C0E8C:t2:H3C0F40,H3C0F48 +3C0F48:lI97|H3C1004 +3C1004:lI112|H3C10C8 +3C10C8:lI112|H3C1194 +3C1194:lI108|H3C1258 +3C1258:lI105|H3C131C +3C131C:lI99|H3C13F0 +3C13F0:lI97|H3C14CC +3C14CC:lI116|H3C15A0 +3C15A0:lI105|H3C166C +3C166C:lI111|H3C1738 +3C1738:lI110|H3C17F4 +3C17F4:lI47|H3C18B0 +3C18B0:lI120|H3C1964 +3C1964:lI45|H3C1A18 +3C1A18:lI115|H3C1ACC +3C1ACC:lI104|H3C1B90 +3C1B90:lI97|H3C1C5C +3C1C5C:lI114|N +3C0F40:lI115|H3C0FFC +3C0FFC:lI104|H3C10C0 +3C10C0:lI97|H3C118C +3C118C:lI114|N +3C0E98:lH3C0F50|H3C0F5C +3C0F50:t2:H3C100C,H3C1014 +3C1014:lI97|H3C10D8 +3C10D8:lI112|H3C119C +3C119C:lI112|H3C1260 +3C1260:lI108|H3C1324 +3C1324:lI105|H3C13F8 +3C13F8:lI99|H3C14D4 +3C14D4:lI97|H3C15A8 +3C15A8:lI116|H3C1674 +3C1674:lI105|H3C1740 +3C1740:lI111|H3C17FC +3C17FC:lI110|H3C18B8 +3C18B8:lI47|H3C196C +3C196C:lI120|H3C1A20 +3C1A20:lI45|H3C1AD4 +3C1AD4:lI115|H3C1B98 +3C1B98:lI104|N +3C100C:lI115|H3C10D0 +3C10D0:lI104|N +3C0F5C:lH3C101C|H3C1028 +3C101C:t2:H3C10E0,H3C10E8 +3C10E8:lI97|H3C11AC +3C11AC:lI112|H3C1268 +3C1268:lI112|H3C132C +3C132C:lI108|H3C1400 +3C1400:lI105|H3C14DC +3C14DC:lI99|H3C15B0 +3C15B0:lI97|H3C167C +3C167C:lI116|H3C1748 +3C1748:lI105|H3C1804 +3C1804:lI111|H3C18C0 +3C18C0:lI110|H3C1974 +3C1974:lI47|H3C1A28 +3C1A28:lI120|H3C1ADC +3C1ADC:lI45|H3C1BA0 +3C1BA0:lI110|H3C1C64 +3C1C64:lI101|H3C1D20 +3C1D20:lI116|H3C1DDC +3C1DDC:lI99|H3C1E98 +3C1E98:lI100|H3C1F5C +3C1F5C:lI102|N +3C10E0:lI110|H3C11A4 +3C11A4:lI99|N +3C1028:lH3C10F0|H3C10FC +3C10F0:t2:H3C11B4,H3C11BC +3C11BC:lI97|H3C1278 +3C1278:lI112|H3C133C +3C133C:lI112|H3C1408 +3C1408:lI108|H3C14E4 +3C14E4:lI105|H3C15B8 +3C15B8:lI99|H3C1684 +3C1684:lI97|H3C1750 +3C1750:lI116|H3C180C +3C180C:lI105|H3C18C8 +3C18C8:lI111|H3C197C +3C197C:lI110|H3C1A30 +3C1A30:lI47|H3C1AE4 +3C1AE4:lI120|H3C1BA8 +3C1BA8:lI45|H3C1C6C +3C1C6C:lI110|H3C1D28 +3C1D28:lI101|H3C1DE4 +3C1DE4:lI116|H3C1EA0 +3C1EA0:lI99|H3C1F64 +3C1F64:lI100|H3C2018 +3C2018:lI102|N +3C11B4:lI99|H3C1270 +3C1270:lI100|H3C1334 +3C1334:lI102|N +3C10FC:lH3C11C4|H3C11D0 +3C11C4:t2:H3C1280,H3C1288 +3C1288:lI97|H3C134C +3C134C:lI112|H3C1418 +3C1418:lI112|H3C14EC +3C14EC:lI108|H3C15C0 +3C15C0:lI105|H3C168C +3C168C:lI99|H3C1758 +3C1758:lI97|H3C1814 +3C1814:lI116|H3C18D0 +3C18D0:lI105|H3C1984 +3C1984:lI111|H3C1A38 +3C1A38:lI110|H3C1AEC +3C1AEC:lI47|H3C1BB0 +3C1BB0:lI120|H3C1C74 +3C1C74:lI45|H3C1D30 +3C1D30:lI109|H3C1DEC +3C1DEC:lI105|H3C1EA8 +3C1EA8:lI102|N +3C1280:lI109|H3C1344 +3C1344:lI105|H3C1410 +3C1410:lI102|N +3C11D0:lH3C1290|H3C129C +3C1290:t2:H3C1354,H3C135C +3C135C:lI97|H3C1428 +3C1428:lI112|H3C14FC +3C14FC:lI112|H3C15D0 +3C15D0:lI108|H3C169C +3C169C:lI105|H3C1760 +3C1760:lI99|H3C181C +3C181C:lI97|H3C18D8 +3C18D8:lI116|H3C198C +3C198C:lI105|H3C1A40 +3C1A40:lI111|H3C1AF4 +3C1AF4:lI110|H3C1BB8 +3C1BB8:lI47|H3C1C7C +3C1C7C:lI120|H3C1D38 +3C1D38:lI45|H3C1DF4 +3C1DF4:lI108|H3C1EB0 +3C1EB0:lI97|H3C1F6C +3C1F6C:lI116|H3C2020 +3C2020:lI101|H3C20DC +3C20DC:lI120|N +3C1354:lI108|H3C1420 +3C1420:lI97|H3C14F4 +3C14F4:lI116|H3C15C8 +3C15C8:lI101|H3C1694 +3C1694:lI120|N +3C129C:lH3C1364|H3C1370 +3C1364:t2:H3C1430,H3C1438 +3C1438:lI97|H3C150C +3C150C:lI112|H3C15E0 +3C15E0:lI112|H3C16A4 +3C16A4:lI108|H3C1768 +3C1768:lI105|H3C1824 +3C1824:lI99|H3C18E0 +3C18E0:lI97|H3C1994 +3C1994:lI116|H3C1A48 +3C1A48:lI105|H3C1AFC +3C1AFC:lI111|H3C1BC0 +3C1BC0:lI110|H3C1C84 +3C1C84:lI47|H3C1D40 +3C1D40:lI120|H3C1DFC +3C1DFC:lI45|H3C1EB8 +3C1EB8:lI107|H3C1F74 +3C1F74:lI111|H3C2028 +3C2028:lI97|H3C20E4 +3C20E4:lI110|N +3C1430:lI115|H3C1504 +3C1504:lI107|H3C15D8 +3C15D8:lI112|N +3C1370:lH3C1440|H3C144C +3C1440:t2:H3C1514,H3C151C +3C151C:lI97|H3C15F0 +3C15F0:lI112|H3C16B4 +3C16B4:lI112|H3C1770 +3C1770:lI108|H3C182C +3C182C:lI105|H3C18E8 +3C18E8:lI99|H3C199C +3C199C:lI97|H3C1A50 +3C1A50:lI116|H3C1B04 +3C1B04:lI105|H3C1BC8 +3C1BC8:lI111|H3C1C8C +3C1C8C:lI110|H3C1D48 +3C1D48:lI47|H3C1E04 +3C1E04:lI120|H3C1EC0 +3C1EC0:lI45|H3C1F7C +3C1F7C:lI107|H3C2030 +3C2030:lI111|H3C20EC +3C20EC:lI97|H3C21A0 +3C21A0:lI110|N +3C1514:lI115|H3C15E8 +3C15E8:lI107|H3C16AC +3C16AC:lI100|N +3C144C:lH3C1524|H3C1530 +3C1524:t2:H3C15F8,H3C1600 +3C1600:lI97|H3C16C4 +3C16C4:lI112|H3C1780 +3C1780:lI112|H3C1834 +3C1834:lI108|H3C18F0 +3C18F0:lI105|H3C19A4 +3C19A4:lI99|H3C1A58 +3C1A58:lI97|H3C1B0C +3C1B0C:lI116|H3C1BD0 +3C1BD0:lI105|H3C1C94 +3C1C94:lI111|H3C1D50 +3C1D50:lI110|H3C1E0C +3C1E0C:lI47|H3C1EC8 +3C1EC8:lI120|H3C1F84 +3C1F84:lI45|H3C2038 +3C2038:lI107|H3C20F4 +3C20F4:lI111|H3C21A8 +3C21A8:lI97|H3C225C +3C225C:lI110|N +3C15F8:lI115|H3C16BC +3C16BC:lI107|H3C1778 +3C1778:lI116|N +3C1530:lH3C1608|H3C1614 +3C1608:t2:H3C16CC,H3C16D4 +3C16D4:lI97|H3C1790 +3C1790:lI112|H3C1844 +3C1844:lI112|H3C18F8 +3C18F8:lI108|H3C19AC +3C19AC:lI105|H3C1A60 +3C1A60:lI99|H3C1B14 +3C1B14:lI97|H3C1BD8 +3C1BD8:lI116|H3C1C9C +3C1C9C:lI105|H3C1D58 +3C1D58:lI111|H3C1E14 +3C1E14:lI110|H3C1ED0 +3C1ED0:lI47|H3C1F8C +3C1F8C:lI120|H3C2040 +3C2040:lI45|H3C20FC +3C20FC:lI107|H3C21B0 +3C21B0:lI111|H3C2264 +3C2264:lI97|H3C2320 +3C2320:lI110|N +3C16CC:lI115|H3C1788 +3C1788:lI107|H3C183C +3C183C:lI109|N +3C1614:lH3C16DC|H3C16E8 +3C16DC:t2:H3C1798,H3C17A0 +3C17A0:lI97|H3C1854 +3C1854:lI112|H3C1908 +3C1908:lI112|H3C19B4 +3C19B4:lI108|H3C1A68 +3C1A68:lI105|H3C1B1C +3C1B1C:lI99|H3C1BE0 +3C1BE0:lI97|H3C1CA4 +3C1CA4:lI116|H3C1D60 +3C1D60:lI105|H3C1E1C +3C1E1C:lI111|H3C1ED8 +3C1ED8:lI110|H3C1F94 +3C1F94:lI47|H3C2048 +3C2048:lI120|H3C2104 +3C2104:lI45|H3C21B8 +3C21B8:lI104|H3C226C +3C226C:lI116|H3C2328 +3C2328:lI116|H3C23E4 +3C23E4:lI112|H3C2498 +3C2498:lI100|H3C2554 +3C2554:lI45|H3C2610 +3C2610:lI99|H3C26D4 +3C26D4:lI103|H3C2790 +3C2790:lI105|N +3C1798:lI99|H3C184C +3C184C:lI103|H3C1900 +3C1900:lI105|N +3C16E8:lH3C17A8|H3C17B4 +3C17A8:t2:H3C185C,H3C1864 +3C1864:lI97|H3C1918 +3C1918:lI112|H3C19C4 +3C19C4:lI112|H3C1A70 +3C1A70:lI108|H3C1B24 +3C1B24:lI105|H3C1BE8 +3C1BE8:lI99|H3C1CAC +3C1CAC:lI97|H3C1D68 +3C1D68:lI116|H3C1E24 +3C1E24:lI105|H3C1EE0 +3C1EE0:lI111|H3C1F9C +3C1F9C:lI110|H3C2050 +3C2050:lI47|H3C210C +3C210C:lI120|H3C21C0 +3C21C0:lI45|H3C2274 +3C2274:lI104|H3C2330 +3C2330:lI100|H3C23EC +3C23EC:lI102|N +3C185C:lI104|H3C1910 +3C1910:lI100|H3C19BC +3C19BC:lI102|N +3C17B4:lH3C186C|H3C1878 +3C186C:t2:H3C1920,H3C1928 +3C1928:lI97|H3C19D4 +3C19D4:lI112|H3C1A78 +3C1A78:lI112|H3C1B2C +3C1B2C:lI108|H3C1BF0 +3C1BF0:lI105|H3C1CB4 +3C1CB4:lI99|H3C1D70 +3C1D70:lI97|H3C1E2C +3C1E2C:lI116|H3C1EE8 +3C1EE8:lI105|H3C1FA4 +3C1FA4:lI111|H3C2058 +3C2058:lI110|H3C2114 +3C2114:lI47|H3C21C8 +3C21C8:lI120|H3C227C +3C227C:lI45|H3C2338 +3C2338:lI103|H3C23F4 +3C23F4:lI122|H3C24A0 +3C24A0:lI105|H3C255C +3C255C:lI112|N +3C1920:lI103|H3C19CC +3C19CC:lI122|N +3C1878:lH3C1930|H3C193C +3C1930:t2:H3C19DC,H3C19E4 +3C19E4:lI97|H3C1A88 +3C1A88:lI112|H3C1B3C +3C1B3C:lI112|H3C1C00 +3C1C00:lI108|H3C1CBC +3C1CBC:lI105|H3C1D78 +3C1D78:lI99|H3C1E34 +3C1E34:lI97|H3C1EF0 +3C1EF0:lI116|H3C1FAC +3C1FAC:lI105|H3C2060 +3C2060:lI111|H3C211C +3C211C:lI110|H3C21D0 +3C21D0:lI47|H3C2284 +3C2284:lI120|H3C2340 +3C2340:lI45|H3C23FC +3C23FC:lI103|H3C24A8 +3C24A8:lI116|H3C2564 +3C2564:lI97|H3C2618 +3C2618:lI114|N +3C19DC:lI103|H3C1A80 +3C1A80:lI116|H3C1B34 +3C1B34:lI97|H3C1BF8 +3C1BF8:lI114|N +3C193C:lH3C19EC|H3C19F8 +3C19EC:t2:H3C1A90,H3C1A98 +3C1A98:lI97|H3C1B4C +3C1B4C:lI112|H3C1C10 +3C1C10:lI112|H3C1CC4 +3C1CC4:lI108|H3C1D80 +3C1D80:lI105|H3C1E3C +3C1E3C:lI99|H3C1EF8 +3C1EF8:lI97|H3C1FB4 +3C1FB4:lI116|H3C2068 +3C2068:lI105|H3C2124 +3C2124:lI111|H3C21D8 +3C21D8:lI110|H3C228C +3C228C:lI47|H3C2348 +3C2348:lI120|H3C2404 +3C2404:lI45|H3C24B0 +3C24B0:lI100|H3C256C +3C256C:lI118|H3C2620 +3C2620:lI105|N +3C1A90:lI100|H3C1B44 +3C1B44:lI118|H3C1C08 +3C1C08:lI105|N +3C19F8:lH3C1AA0|H3C1AAC +3C1AA0:t2:H3C1B54,H3C1B5C +3C1B5C:lI97|H3C1C20 +3C1C20:lI112|H3C1CD4 +3C1CD4:lI112|H3C1D88 +3C1D88:lI108|H3C1E44 +3C1E44:lI105|H3C1F00 +3C1F00:lI99|H3C1FBC +3C1FBC:lI97|H3C2070 +3C2070:lI116|H3C212C +3C212C:lI105|H3C21E0 +3C21E0:lI111|H3C2294 +3C2294:lI110|H3C2350 +3C2350:lI47|H3C240C +3C240C:lI120|H3C24B8 +3C24B8:lI45|H3C2574 +3C2574:lI100|H3C2628 +3C2628:lI105|H3C26DC +3C26DC:lI114|H3C2798 +3C2798:lI101|H3C2854 +3C2854:lI99|H3C2918 +3C2918:lI116|H3C29E4 +3C29E4:lI111|H3C2AB0 +3C2AB0:lI114|N +3C1B54:lI100|H3C1C18 +3C1C18:lI99|H3C1CCC +3C1CCC:lI114|N +3C1AAC:lH3C1B64|H3C1B70 +3C1B64:t2:H3C1C28,H3C1C30 +3C1C30:lI97|H3C1CE4 +3C1CE4:lI112|H3C1D98 +3C1D98:lI112|H3C1E4C +3C1E4C:lI108|H3C1F08 +3C1F08:lI105|H3C1FC4 +3C1FC4:lI99|H3C2078 +3C2078:lI97|H3C2134 +3C2134:lI116|H3C21E8 +3C21E8:lI105|H3C229C +3C229C:lI111|H3C2358 +3C2358:lI110|H3C2414 +3C2414:lI47|H3C24C0 +3C24C0:lI120|H3C257C +3C257C:lI45|H3C2630 +3C2630:lI100|H3C26E4 +3C26E4:lI105|H3C27A0 +3C27A0:lI114|H3C285C +3C285C:lI101|H3C2920 +3C2920:lI99|H3C29EC +3C29EC:lI116|H3C2AB8 +3C2AB8:lI111|H3C2B84 +3C2B84:lI114|N +3C1C28:lI100|H3C1CDC +3C1CDC:lI105|H3C1D90 +3C1D90:lI114|N +3C1B70:lH3C1C38|H3C1C44 +3C1C38:t2:H3C1CEC,H3C1CF4 +3C1CF4:lI97|H3C1DA8 +3C1DA8:lI112|H3C1E5C +3C1E5C:lI112|H3C1F10 +3C1F10:lI108|H3C1FCC +3C1FCC:lI105|H3C2080 +3C2080:lI99|H3C213C +3C213C:lI97|H3C21F0 +3C21F0:lI116|H3C22A4 +3C22A4:lI105|H3C2360 +3C2360:lI111|H3C241C +3C241C:lI110|H3C24C8 +3C24C8:lI47|H3C2584 +3C2584:lI120|H3C2638 +3C2638:lI45|H3C26EC +3C26EC:lI100|H3C27A8 +3C27A8:lI105|H3C2864 +3C2864:lI114|H3C2928 +3C2928:lI101|H3C29F4 +3C29F4:lI99|H3C2AC0 +3C2AC0:lI116|H3C2B8C +3C2B8C:lI111|H3C2C48 +3C2C48:lI114|N +3C1CEC:lI100|H3C1DA0 +3C1DA0:lI120|H3C1E54 +3C1E54:lI114|N +3C1C44:lH3C1CFC|H3C1D08 +3C1CFC:t2:H3C1DB0,H3C1DB8 +3C1DB8:lI97|H3C1E6C +3C1E6C:lI112|H3C1F20 +3C1F20:lI112|H3C1FD4 +3C1FD4:lI108|H3C2088 +3C2088:lI105|H3C2144 +3C2144:lI99|H3C21F8 +3C21F8:lI97|H3C22AC +3C22AC:lI116|H3C2368 +3C2368:lI105|H3C2424 +3C2424:lI111|H3C24D0 +3C24D0:lI110|H3C258C +3C258C:lI47|H3C2640 +3C2640:lI120|H3C26F4 +3C26F4:lI45|H3C27B0 +3C27B0:lI99|H3C286C +3C286C:lI115|H3C2930 +3C2930:lI104|N +3C1DB0:lI99|H3C1E64 +3C1E64:lI115|H3C1F18 +3C1F18:lI104|N +3C1D08:lH3C1DC0|H3C1DCC +3C1DC0:t2:H3C1E74,H3C1E7C +3C1E7C:lI97|H3C1F30 +3C1F30:lI112|H3C1FE4 +3C1FE4:lI112|H3C2098 +3C2098:lI108|H3C214C +3C214C:lI105|H3C2200 +3C2200:lI99|H3C22B4 +3C22B4:lI97|H3C2370 +3C2370:lI116|H3C242C +3C242C:lI105|H3C24D8 +3C24D8:lI111|H3C2594 +3C2594:lI110|H3C2648 +3C2648:lI47|H3C26FC +3C26FC:lI120|H3C27B8 +3C27B8:lI45|H3C2874 +3C2874:lI99|H3C2938 +3C2938:lI112|H3C29FC +3C29FC:lI105|H3C2AC8 +3C2AC8:lI111|N +3C1E74:lI99|H3C1F28 +3C1F28:lI112|H3C1FDC +3C1FDC:lI105|H3C2090 +3C2090:lI111|N +3C1DCC:lH3C1E84|H3C1E90 +3C1E84:t2:H3C1F38,H3C1F40 +3C1F40:lI97|H3C1FEC +3C1FEC:lI112|H3C20A0 +3C20A0:lI112|H3C2154 +3C2154:lI108|H3C2208 +3C2208:lI105|H3C22BC +3C22BC:lI99|H3C2378 +3C2378:lI97|H3C2434 +3C2434:lI116|H3C24E0 +3C24E0:lI105|H3C259C +3C259C:lI111|H3C2650 +3C2650:lI110|H3C2704 +3C2704:lI47|H3C27C0 +3C27C0:lI120|H3C287C +3C287C:lI45|H3C2940 +3C2940:lI99|H3C2A04 +3C2A04:lI111|H3C2AD0 +3C2AD0:lI109|H3C2B94 +3C2B94:lI112|H3C2C50 +3C2C50:lI114|H3C2D00 +3C2D00:lI101|H3C2DA8 +3C2DA8:lI115|H3C2E40 +3C2E40:lI115|N +3C1F38:lI90|N +3C1E90:lH3C1F48|H3C1F54 +3C1F48:t2:H3C1FF4,H3C1FFC +3C1FFC:lI97|H3C20B0 +3C20B0:lI112|H3C2164 +3C2164:lI112|H3C2210 +3C2210:lI108|H3C22C4 +3C22C4:lI105|H3C2380 +3C2380:lI99|H3C243C +3C243C:lI97|H3C24E8 +3C24E8:lI116|H3C25A4 +3C25A4:lI105|H3C2658 +3C2658:lI111|H3C270C +3C270C:lI110|H3C27C8 +3C27C8:lI47|H3C2884 +3C2884:lI120|H3C2948 +3C2948:lI45|H3C2A0C +3C2A0C:lI99|H3C2AD8 +3C2AD8:lI100|H3C2B9C +3C2B9C:lI108|H3C2C58 +3C2C58:lI105|H3C2D08 +3C2D08:lI110|H3C2DB0 +3C2DB0:lI107|N +3C1FF4:lI118|H3C20A8 +3C20A8:lI99|H3C215C +3C215C:lI100|N +3C1F54:lH3C2004|H3C2010 +3C2004:t2:H3C20B8,H3C20C0 +3C20C0:lI97|H3C2174 +3C2174:lI112|H3C2220 +3C2220:lI112|H3C22D4 +3C22D4:lI108|H3C2390 +3C2390:lI105|H3C2444 +3C2444:lI99|H3C24F0 +3C24F0:lI97|H3C25AC +3C25AC:lI116|H3C2660 +3C2660:lI105|H3C2714 +3C2714:lI111|H3C27D0 +3C27D0:lI110|H3C288C +3C288C:lI47|H3C2950 +3C2950:lI120|H3C2A14 +3C2A14:lI45|H3C2AE0 +3C2AE0:lI98|H3C2BA4 +3C2BA4:lI99|H3C2C60 +3C2C60:lI112|H3C2D10 +3C2D10:lI105|H3C2DB8 +3C2DB8:lI111|N +3C20B8:lI98|H3C216C +3C216C:lI99|H3C2218 +3C2218:lI112|H3C22CC +3C22CC:lI105|H3C2388 +3C2388:lI111|N +3C2010:lH3C20C8|H3C20D4 +3C20C8:t2:H3C217C,H3C2184 +3C2184:lI97|H3C2230 +3C2230:lI112|H3C22E4 +3C22E4:lI112|H3C2398 +3C2398:lI108|H3C244C +3C244C:lI105|H3C24F8 +3C24F8:lI99|H3C25B4 +3C25B4:lI97|H3C2668 +3C2668:lI116|H3C271C +3C271C:lI105|H3C27D8 +3C27D8:lI111|H3C2894 +3C2894:lI110|H3C2958 +3C2958:lI47|H3C2A1C +3C2A1C:lI114|H3C2AE8 +3C2AE8:lI116|H3C2BAC +3C2BAC:lI102|N +3C217C:lI114|H3C2228 +3C2228:lI116|H3C22DC +3C22DC:lI102|N +3C20D4:lH3C218C|H3C2198 +3C218C:t2:H3C2238,H3C2240 +3C2240:lI97|H3C22F4 +3C22F4:lI112|H3C23A8 +3C23A8:lI112|H3C2454 +3C2454:lI108|H3C2500 +3C2500:lI105|H3C25BC +3C25BC:lI99|H3C2670 +3C2670:lI97|H3C2724 +3C2724:lI116|H3C27E0 +3C27E0:lI105|H3C289C +3C289C:lI111|H3C2960 +3C2960:lI110|H3C2A24 +3C2A24:lI47|H3C2AF0 +3C2AF0:lI112|H3C2BB4 +3C2BB4:lI111|H3C2C68 +3C2C68:lI119|H3C2D18 +3C2D18:lI101|H3C2DC0 +3C2DC0:lI114|H3C2E48 +3C2E48:lI112|H3C2EC0 +3C2EC0:lI111|H3C2F38 +3C2F38:lI105|H3C2FA8 +3C2FA8:lI110|H3C3010 +3C3010:lI116|N +3C2238:lI112|H3C22EC +3C22EC:lI112|H3C23A0 +3C23A0:lI116|N +3C2198:lH3C2248|H3C2254 +3C2248:t2:H3C22FC,H3C2304 +3C2304:lI97|H3C23B8 +3C23B8:lI112|H3C245C +3C245C:lI112|H3C2508 +3C2508:lI108|H3C25C4 +3C25C4:lI105|H3C2678 +3C2678:lI99|H3C272C +3C272C:lI97|H3C27E8 +3C27E8:lI116|H3C28A4 +3C28A4:lI105|H3C2968 +3C2968:lI111|H3C2A2C +3C2A2C:lI110|H3C2AF8 +3C2AF8:lI47|H3C2BBC +3C2BBC:lI112|H3C2C70 +3C2C70:lI111|H3C2D20 +3C2D20:lI115|H3C2DC8 +3C2DC8:lI116|H3C2E50 +3C2E50:lI115|H3C2EC8 +3C2EC8:lI99|H3C2F40 +3C2F40:lI114|H3C2FB0 +3C2FB0:lI105|H3C3018 +3C3018:lI112|H3C3078 +3C3078:lI116|N +3C22FC:lI97|H3C23B0 +3C23B0:lI105|N +3C2254:lH3C230C|H3C2318 +3C230C:t2:H3C23C0,H3C23C8 +3C23C8:lI97|H3C246C +3C246C:lI112|H3C2518 +3C2518:lI112|H3C25CC +3C25CC:lI108|H3C2680 +3C2680:lI105|H3C2734 +3C2734:lI99|H3C27F0 +3C27F0:lI97|H3C28AC +3C28AC:lI116|H3C2970 +3C2970:lI105|H3C2A34 +3C2A34:lI111|H3C2B00 +3C2B00:lI110|H3C2BC4 +3C2BC4:lI47|H3C2C78 +3C2C78:lI112|H3C2D28 +3C2D28:lI111|H3C2DD0 +3C2DD0:lI115|H3C2E58 +3C2E58:lI116|H3C2ED0 +3C2ED0:lI115|H3C2F48 +3C2F48:lI99|H3C2FB8 +3C2FB8:lI114|H3C3020 +3C3020:lI105|H3C3080 +3C3080:lI112|H3C30D8 +3C30D8:lI116|N +3C23C0:lI101|H3C2464 +3C2464:lI112|H3C2510 +3C2510:lI115|N +3C2318:lH3C23D0|H3C23DC +3C23D0:t2:H3C2474,H3C247C +3C247C:lI97|H3C2528 +3C2528:lI112|H3C25D4 +3C25D4:lI112|H3C2688 +3C2688:lI108|H3C273C +3C273C:lI105|H3C27F8 +3C27F8:lI99|H3C28B4 +3C28B4:lI97|H3C2978 +3C2978:lI116|H3C2A3C +3C2A3C:lI105|H3C2B08 +3C2B08:lI111|H3C2BCC +3C2BCC:lI110|H3C2C80 +3C2C80:lI47|H3C2D30 +3C2D30:lI112|H3C2DD8 +3C2DD8:lI111|H3C2E60 +3C2E60:lI115|H3C2ED8 +3C2ED8:lI116|H3C2F50 +3C2F50:lI115|H3C2FC0 +3C2FC0:lI99|H3C3028 +3C3028:lI114|H3C3088 +3C3088:lI105|H3C30E0 +3C30E0:lI112|H3C3130 +3C3130:lI116|N +3C2474:lI112|H3C2520 +3C2520:lI115|N +3C23DC:lH3C2484|H3C2490 +3C2484:t2:H3C2530,H3C2538 +3C2538:lI97|H3C25E4 +3C25E4:lI112|H3C2698 +3C2698:lI112|H3C2744 +3C2744:lI108|H3C2800 +3C2800:lI105|H3C28BC +3C28BC:lI99|H3C2980 +3C2980:lI97|H3C2A44 +3C2A44:lI116|H3C2B10 +3C2B10:lI105|H3C2BD4 +3C2BD4:lI111|H3C2C88 +3C2C88:lI110|H3C2D38 +3C2D38:lI47|H3C2DE0 +3C2DE0:lI112|H3C2E68 +3C2E68:lI100|H3C2EE0 +3C2EE0:lI102|N +3C2530:lI112|H3C25DC +3C25DC:lI100|H3C2690 +3C2690:lI102|N +3C2490:lH3C2540|H3C254C +3C2540:t2:H3C25EC,H3C25F4 +3C25F4:lI97|H3C26A8 +3C26A8:lI112|H3C2754 +3C2754:lI112|H3C2808 +3C2808:lI108|H3C28C4 +3C28C4:lI105|H3C2988 +3C2988:lI99|H3C2A4C +3C2A4C:lI97|H3C2B18 +3C2B18:lI116|H3C2BDC +3C2BDC:lI105|H3C2C90 +3C2C90:lI111|H3C2D40 +3C2D40:lI110|H3C2DE8 +3C2DE8:lI47|H3C2E70 +3C2E70:lI111|H3C2EE8 +3C2EE8:lI100|H3C2F58 +3C2F58:lI97|N +3C25EC:lI111|H3C26A0 +3C26A0:lI100|H3C274C +3C274C:lI97|N +3C254C:lH3C25FC|H3C2608 +3C25FC:t2:H3C26B0,H3C26B8 +3C26B8:lI97|H3C2764 +3C2764:lI112|H3C2818 +3C2818:lI112|H3C28CC +3C28CC:lI108|H3C2990 +3C2990:lI105|H3C2A54 +3C2A54:lI99|H3C2B20 +3C2B20:lI97|H3C2BE4 +3C2BE4:lI116|H3C2C98 +3C2C98:lI105|H3C2D48 +3C2D48:lI111|H3C2DF0 +3C2DF0:lI110|H3C2E78 +3C2E78:lI47|H3C2EF0 +3C2EF0:lI111|H3C2F60 +3C2F60:lI99|H3C2FC8 +3C2FC8:lI116|H3C3030 +3C3030:lI101|H3C3090 +3C3090:lI116|H3C30E8 +3C30E8:lI45|H3C3138 +3C3138:lI115|H3C3180 +3C3180:lI116|H3C31C8 +3C31C8:lI114|H3C3210 +3C3210:lI101|H3C3258 +3C3258:lI97|H3C32A0 +3C32A0:lI109|N +3C26B0:lI98|H3C275C +3C275C:lI105|H3C2810 +3C2810:lI110|N +3C2608:lH3C26C0|H3C26CC +3C26C0:t2:H3C276C,H3C2774 +3C2774:lI97|H3C2828 +3C2828:lI112|H3C28DC +3C28DC:lI112|H3C2998 +3C2998:lI108|H3C2A5C +3C2A5C:lI105|H3C2B28 +3C2B28:lI99|H3C2BEC +3C2BEC:lI97|H3C2CA0 +3C2CA0:lI116|H3C2D50 +3C2D50:lI105|H3C2DF8 +3C2DF8:lI111|H3C2E80 +3C2E80:lI110|H3C2EF8 +3C2EF8:lI47|H3C2F68 +3C2F68:lI111|H3C2FD0 +3C2FD0:lI99|H3C3038 +3C3038:lI116|H3C3098 +3C3098:lI101|H3C30F0 +3C30F0:lI116|H3C3140 +3C3140:lI45|H3C3188 +3C3188:lI115|H3C31D0 +3C31D0:lI116|H3C3218 +3C3218:lI114|H3C3260 +3C3260:lI101|H3C32A8 +3C32A8:lI97|H3C32E8 +3C32E8:lI109|N +3C276C:lI100|H3C2820 +3C2820:lI109|H3C28D4 +3C28D4:lI115|N +3C26CC:lH3C277C|H3C2788 +3C277C:t2:H3C2830,H3C2838 +3C2838:lI97|H3C28EC +3C28EC:lI112|H3C29A8 +3C29A8:lI112|H3C2A64 +3C2A64:lI108|H3C2B30 +3C2B30:lI105|H3C2BF4 +3C2BF4:lI99|H3C2CA8 +3C2CA8:lI97|H3C2D58 +3C2D58:lI116|H3C2E00 +3C2E00:lI105|H3C2E88 +3C2E88:lI111|H3C2F00 +3C2F00:lI110|H3C2F70 +3C2F70:lI47|H3C2FD8 +3C2FD8:lI111|H3C3040 +3C3040:lI99|H3C30A0 +3C30A0:lI116|H3C30F8 +3C30F8:lI101|H3C3148 +3C3148:lI116|H3C3190 +3C3190:lI45|H3C31D8 +3C31D8:lI115|H3C3220 +3C3220:lI116|H3C3268 +3C3268:lI114|H3C32B0 +3C32B0:lI101|H3C32F0 +3C32F0:lI97|H3C3320 +3C3320:lI109|N +3C2830:lI108|H3C28E4 +3C28E4:lI104|H3C29A0 +3C29A0:lI97|N +3C2788:lH3C2840|H3C284C +3C2840:t2:H3C28F4,H3C28FC +3C28FC:lI97|H3C29B8 +3C29B8:lI112|H3C2A74 +3C2A74:lI112|H3C2B38 +3C2B38:lI108|H3C2BFC +3C2BFC:lI105|H3C2CB0 +3C2CB0:lI99|H3C2D60 +3C2D60:lI97|H3C2E08 +3C2E08:lI116|H3C2E90 +3C2E90:lI105|H3C2F08 +3C2F08:lI111|H3C2F78 +3C2F78:lI110|H3C2FE0 +3C2FE0:lI47|H3C3048 +3C3048:lI111|H3C30A8 +3C30A8:lI99|H3C3100 +3C3100:lI116|H3C3150 +3C3150:lI101|H3C3198 +3C3198:lI116|H3C31E0 +3C31E0:lI45|H3C3228 +3C3228:lI115|H3C3270 +3C3270:lI116|H3C32B8 +3C32B8:lI114|H3C32F8 +3C32F8:lI101|H3C3328 +3C3328:lI97|H3C3350 +3C3350:lI109|N +3C28F4:lI108|H3C29B0 +3C29B0:lI122|H3C2A6C +3C2A6C:lI104|N +3C284C:lH3C2904|H3C2910 +3C2904:t2:H3C29C0,H3C29C8 +3C29C8:lI97|H3C2A84 +3C2A84:lI112|H3C2B48 +3C2B48:lI112|H3C2C04 +3C2C04:lI108|H3C2CB8 +3C2CB8:lI105|H3C2D68 +3C2D68:lI99|H3C2E10 +3C2E10:lI97|H3C2E98 +3C2E98:lI116|H3C2F10 +3C2F10:lI105|H3C2F80 +3C2F80:lI111|H3C2FE8 +3C2FE8:lI110|H3C3050 +3C3050:lI47|H3C30B0 +3C30B0:lI111|H3C3108 +3C3108:lI99|H3C3158 +3C3158:lI116|H3C31A0 +3C31A0:lI101|H3C31E8 +3C31E8:lI116|H3C3230 +3C3230:lI45|H3C3278 +3C3278:lI115|H3C32C0 +3C32C0:lI116|H3C3300 +3C3300:lI114|H3C3330 +3C3330:lI101|H3C3358 +3C3358:lI97|H3C3378 +3C3378:lI109|N +3C29C0:lI101|H3C2A7C +3C2A7C:lI120|H3C2B40 +3C2B40:lI101|N +3C2910:lH3C29D0|H3C29DC +3C29D0:t2:H3C2A8C,H3C2A94 +3C2A94:lI97|H3C2B58 +3C2B58:lI112|H3C2C14 +3C2C14:lI112|H3C2CC8 +3C2CC8:lI108|H3C2D78 +3C2D78:lI105|H3C2E18 +3C2E18:lI99|H3C2EA0 +3C2EA0:lI97|H3C2F18 +3C2F18:lI116|H3C2F88 +3C2F88:lI105|H3C2FF0 +3C2FF0:lI111|H3C3058 +3C3058:lI110|H3C30B8 +3C30B8:lI47|H3C3110 +3C3110:lI111|H3C3160 +3C3160:lI99|H3C31A8 +3C31A8:lI116|H3C31F0 +3C31F0:lI101|H3C3238 +3C3238:lI116|H3C3280 +3C3280:lI45|H3C32C8 +3C32C8:lI115|H3C3308 +3C3308:lI116|H3C3338 +3C3338:lI114|H3C3360 +3C3360:lI101|H3C3380 +3C3380:lI97|H3C3398 +3C3398:lI109|N +3C2A8C:lI99|H3C2B50 +3C2B50:lI108|H3C2C0C +3C2C0C:lI97|H3C2CC0 +3C2CC0:lI115|H3C2D70 +3C2D70:lI115|N +3C29DC:lH3C2A9C|H3C2AA8 +3C2A9C:t2:H3C2B60,H3C2B68 +3C2B68:lI97|H3C2C24 +3C2C24:lI112|H3C2CD8 +3C2CD8:lI112|H3C2D80 +3C2D80:lI108|H3C2E20 +3C2E20:lI105|H3C2EA8 +3C2EA8:lI99|H3C2F20 +3C2F20:lI97|H3C2F90 +3C2F90:lI116|H3C2FF8 +3C2FF8:lI105|H3C3060 +3C3060:lI111|H3C30C0 +3C30C0:lI110|H3C3118 +3C3118:lI47|H3C3168 +3C3168:lI109|H3C31B0 +3C31B0:lI115|H3C31F8 +3C31F8:lI119|H3C3240 +3C3240:lI111|H3C3288 +3C3288:lI114|H3C32D0 +3C32D0:lI100|N +3C2B60:lI100|H3C2C1C +3C2C1C:lI111|H3C2CD0 +3C2CD0:lI99|N +3C2AA8:lH3C2B70|H3C2B7C +3C2B70:t2:H3C2C2C,H3C2C34 +3C2C34:lI97|H3C2CE8 +3C2CE8:lI112|H3C2D90 +3C2D90:lI112|H3C2E28 +3C2E28:lI108|H3C2EB0 +3C2EB0:lI105|H3C2F28 +3C2F28:lI99|H3C2F98 +3C2F98:lI97|H3C3000 +3C3000:lI116|H3C3068 +3C3068:lI105|H3C30C8 +3C30C8:lI111|H3C3120 +3C3120:lI110|H3C3170 +3C3170:lI47|H3C31B8 +3C31B8:lI109|H3C3200 +3C3200:lI97|H3C3248 +3C3248:lI99|H3C3290 +3C3290:lI45|H3C32D8 +3C32D8:lI99|H3C3310 +3C3310:lI111|H3C3340 +3C3340:lI109|H3C3368 +3C3368:lI112|H3C3388 +3C3388:lI97|H3C33A0 +3C33A0:lI99|H3C33B0 +3C33B0:lI116|H3C33C0 +3C33C0:lI112|H3C33D0 +3C33D0:lI114|H3C33E0 +3C33E0:lI111|N +3C2C2C:lI99|H3C2CE0 +3C2CE0:lI112|H3C2D88 +3C2D88:lI116|N +3C2B7C:lH3C2C3C|N +3C2C3C:t2:H3C2CF0,H3C2CF8 +3C2CF8:lI97|H3C2DA0 +3C2DA0:lI112|H3C2E38 +3C2E38:lI112|H3C2EB8 +3C2EB8:lI108|H3C2F30 +3C2F30:lI105|H3C2FA0 +3C2FA0:lI99|H3C3008 +3C3008:lI97|H3C3070 +3C3070:lI116|H3C30D0 +3C30D0:lI105|H3C3128 +3C3128:lI111|H3C3178 +3C3178:lI110|H3C31C0 +3C31C0:lI47|H3C3208 +3C3208:lI109|H3C3250 +3C3250:lI97|H3C3298 +3C3298:lI99|H3C32E0 +3C32E0:lI45|H3C3318 +3C3318:lI98|H3C3348 +3C3348:lI105|H3C3370 +3C3370:lI110|H3C3390 +3C3390:lI104|H3C33A8 +3C33A8:lI101|H3C33B8 +3C33B8:lI120|H3C33C8 +3C33C8:lI52|H3C33D8 +3C33D8:lI48|N +3C2CF0:lI104|H3C2D98 +3C2D98:lI113|H3C2E30 +3C2E30:lI120|N +3BDBCC:lH3BDA78|H3BDA8C +3BDA78:t2:A4:port,I8888 +3BDA8C:lH3BDB04|H3BDB10 +3BDB04:t2:AC:bind_address,H3BDB64 +3BDB64:t4:I127,I0,I0,I1 +3BDB10:lH3BDB78|H3BDB84 +3BDB78:t2:AB:server_name,H3BDBD4 +3BDBD4:lI108|H3BDC24 +3BDC24:lI111|H3BDC88 +3BDC88:lI99|H3BDCF0 +3BDCF0:lI97|H3BDD70 +3BDD70:lI108|H3BDDF8 +3BDDF8:lI104|H3BDE90 +3BDE90:lI111|H3BDF40 +3BDF40:lI115|H3BDFFC +3BDFFC:lI116|N +3BDB84:lH3BDBDC|H3BDBE8 +3BDBDC:t2:AE:max_header_siz,I1024 +3BDBE8:lH3BDC2C|H3BDC38 +3BDC2C:t2:A11:max_header_action,A8:reply414 +3BDC38:lH3BDC90|H3BDC9C +3BDC90:t2:A8:com_type,A7:ip_comm +3BDC9C:lH3BDCF8|H3BDD04 +3BDCF8:t2:A7:modules,H3BDD78 +3BDD78:lA9:mod_alias|H3BDE00 +3BDE00:lA8:mod_auth|H3BDE98 +3BDE98:lA7:mod_esi|H3BDF48 +3BDF48:lAB:mod_actions|H3BE004 +3BE004:lA7:mod_cgi|H3BE0D0 +3BE0D0:lAB:mod_include|H3BE1A4 +3BE1A4:lA7:mod_dir|H3BE288 +3BE288:lA7:mod_get|H3BE378 +3BE378:lA8:mod_head|H3BE47C +3BE47C:lA7:mod_log|H3BE580 +3BE580:lAC:mod_disk_log|N +3BDD04:lH3BDD80|H3BDD8C +3BDD80:t2:AF:directory_index,H3BDE08 +3BDE08:lH3BDEA0|N +3BDEA0:lI105|H3BDF50 +3BDF50:lI110|H3BE00C +3BE00C:lI100|H3BE0D8 +3BE0D8:lI101|H3BE1AC +3BE1AC:lI120|H3BE290 +3BE290:lI46|H3BE380 +3BE380:lI104|H3BE484 +3BE484:lI116|H3BE588 +3BE588:lI109|H3BE68C +3BE68C:lI108|N +3BDD8C:lH3BDE10|H3BDE1C +3BDE10:t2:AC:default_type,H3BDEA8 +3BDEA8:lI116|H3BDF58 +3BDF58:lI101|H3BE014 +3BE014:lI120|H3BE0E0 +3BE0E0:lI116|H3BE1B4 +3BE1B4:lI47|H3BE298 +3BE298:lI112|H3BE388 +3BE388:lI108|H3BE48C +3BE48C:lI97|H3BE590 +3BE590:lI105|H3BE694 +3BE694:lI110|N +3BDE1C:lH3BDEB0|H3BDEBC +3BDEB0:t2:A10:erl_script_alias,H3BDF60 +3BDF60:t2:H3BE01C,H3BE024 +3BE024:lH3BE0F0|N +3BE0F0:lI119|H3BE1C4 +3BE1C4:lI101|H3BE2A8 +3BE2A8:lI98|H3BE398 +3BE398:lI116|H3BE49C +3BE49C:lI111|H3BE5A0 +3BE5A0:lI111|H3BE6A4 +3BE6A4:lI108|N +3BE01C:lI47|H3BE0E8 +3BE0E8:lI119|H3BE1BC +3BE1BC:lI101|H3BE2A0 +3BE2A0:lI98|H3BE390 +3BE390:lI116|H3BE494 +3BE494:lI111|H3BE598 +3BE598:lI111|H3BE69C +3BE69C:lI108|N +3BDEBC:lH3BDF6C|H3BDF78 +3BDF6C:t2:A5:alias,H3BE02C +3BE02C:t2:H3BE0F8,H3BE100 +3BE100:lI47|H3BE1D4 +3BE1D4:lI99|H3BE2B8 +3BE2B8:lI108|H3BE3A8 +3BE3A8:lI101|H3BE4AC +3BE4AC:lI97|H3BE5B0 +3BE5B0:lI114|H3BE6B4 +3BE6B4:lI99|H3BE7A8 +3BE7A8:lI97|H3BE894 +3BE894:lI115|H3BE980 +3BE980:lI101|H3BEA74 +3BEA74:lI47|H3BEB68 +3BEB68:lI111|H3BEC54 +3BEC54:lI116|H3BED40 +3BED40:lI112|H3BEE2C +3BEE2C:lI47|H3BEF00 +3BEF00:lI101|H3BEFD4 +3BEFD4:lI114|H3BF0A0 +3BF0A0:lI116|H3BF174 +3BF174:lI115|H3BF238 +3BF238:lI47|H3BF2FC +3BF2FC:lI108|H3BF3A8 +3BF3A8:lI105|H3BF45C +3BF45C:lI98|H3BF518 +3BF518:lI47|H3BF5DC +3BF5DC:lI111|H3BF6B0 +3BF6B0:lI98|H3BF784 +3BF784:lI115|H3BF858 +3BF858:lI101|H3BF93C +3BF93C:lI114|H3BFA18 +3BFA18:lI118|H3BFAF4 +3BFAF4:lI101|H3BFBD0 +3BFBD0:lI114|H3BFC9C +3BFC9C:lI47|H3BFD60 +3BFD60:lI112|H3BFE2C +3BFE2C:lI114|H3BFEE0 +3BFEE0:lI105|H3BFF94 +3BFF94:lI118|H3C0040 +3C0040:lI47|H3C00EC +3C00EC:lI99|H3C0198 +3C0198:lI114|H3C024C +3C024C:lI97|H3C0308 +3C0308:lI115|H3C03BC +3C03BC:lI104|H3C0458 +3C0458:lI100|H3C04F4 +3C04F4:lI117|H3C0590 +3C0590:lI109|H3C0634 +3C0634:lI112|H3C06E0 +3C06E0:lI95|H3C078C +3C078C:lI118|H3C0830 +3C0830:lI105|H3C08BC +3C08BC:lI101|H3C0950 +3C0950:lI119|H3C09E4 +3C09E4:lI101|H3C0A80 +3C0A80:lI114|N +3BE0F8:lI47|H3BE1CC +3BE1CC:lI99|H3BE2B0 +3BE2B0:lI114|H3BE3A0 +3BE3A0:lI97|H3BE4A4 +3BE4A4:lI115|H3BE5A8 +3BE5A8:lI104|H3BE6AC +3BE6AC:lI100|H3BE7A0 +3BE7A0:lI117|H3BE88C +3BE88C:lI109|H3BE978 +3BE978:lI112|H3BEA6C +3BEA6C:lI95|H3BEB60 +3BEB60:lI118|H3BEC4C +3BEC4C:lI105|H3BED38 +3BED38:lI101|H3BEE24 +3BEE24:lI119|H3BEEF8 +3BEEF8:lI101|H3BEFCC +3BEFCC:lI114|N +3BDF78:lH3BE038|H3BE044 +3BE038:t2:A5:alias,H3BE108 +3BE108:t2:H3BE1DC,H3BE1E4 +3BE1E4:lI47|H3BE2C8 +3BE2C8:lI99|H3BE3B8 +3BE3B8:lI108|H3BE4BC +3BE4BC:lI101|H3BE5C0 +3BE5C0:lI97|H3BE6C4 +3BE6C4:lI114|H3BE7B8 +3BE7B8:lI99|H3BE8A4 +3BE8A4:lI97|H3BE990 +3BE990:lI115|H3BEA84 +3BEA84:lI101|H3BEB78 +3BEB78:lI47|H3BEC64 +3BEC64:lI111|H3BED50 +3BED50:lI116|H3BEE3C +3BEE3C:lI112|H3BEF10 +3BEF10:lI47|H3BEFE4 +3BEFE4:lI101|H3BF0B0 +3BF0B0:lI114|H3BF184 +3BF184:lI116|H3BF248 +3BF248:lI115|H3BF304 +3BF304:lI47|H3BF3B0 +3BF3B0:lI101|H3BF464 +3BF464:lI114|H3BF520 +3BF520:lI116|H3BF5E4 +3BF5E4:lI115|H3BF6B8 +3BF6B8:lI47|H3BF78C +3BF78C:lI100|H3BF860 +3BF860:lI111|H3BF944 +3BF944:lI99|H3BFA20 +3BFA20:lI47|H3BFAFC +3BFAFC:lI104|H3BFBD8 +3BFBD8:lI116|H3BFCA4 +3BFCA4:lI109|H3BFD68 +3BFD68:lI108|N +3BE1DC:lI47|H3BE2C0 +3BE2C0:lI99|H3BE3B0 +3BE3B0:lI114|H3BE4B4 +3BE4B4:lI97|H3BE5B8 +3BE5B8:lI115|H3BE6BC +3BE6BC:lI104|H3BE7B0 +3BE7B0:lI100|H3BE89C +3BE89C:lI117|H3BE988 +3BE988:lI109|H3BEA7C +3BEA7C:lI112|H3BEB70 +3BEB70:lI95|H3BEC5C +3BEC5C:lI101|H3BED48 +3BED48:lI114|H3BEE34 +3BEE34:lI116|H3BEF08 +3BEF08:lI115|H3BEFDC +3BEFDC:lI95|H3BF0A8 +3BF0A8:lI100|H3BF17C +3BF17C:lI111|H3BF240 +3BF240:lI99|N +3BE044:lH3BE114|H3BE120 +3BE114:t2:A5:alias,H3BE1EC +3BE1EC:t2:H3BE2D0,H3BE2D8 +3BE2D8:lI47|H3BE3C8 +3BE3C8:lI99|H3BE4CC +3BE4CC:lI108|H3BE5D0 +3BE5D0:lI101|H3BE6D4 +3BE6D4:lI97|H3BE7C8 +3BE7C8:lI114|H3BE8B4 +3BE8B4:lI99|H3BE9A0 +3BE9A0:lI97|H3BEA94 +3BEA94:lI115|H3BEB88 +3BEB88:lI101|H3BEC74 +3BEC74:lI47|H3BED60 +3BED60:lI111|H3BEE4C +3BEE4C:lI116|H3BEF20 +3BEF20:lI112|H3BEFEC +3BEFEC:lI47|H3BF0B8 +3BF0B8:lI101|H3BF18C +3BF18C:lI114|H3BF250 +3BF250:lI116|H3BF30C +3BF30C:lI115|H3BF3B8 +3BF3B8:lI47|H3BF46C +3BF46C:lI108|H3BF528 +3BF528:lI105|H3BF5EC +3BF5EC:lI98|H3BF6C0 +3BF6C0:lI47|H3BF794 +3BF794:lI111|H3BF868 +3BF868:lI98|H3BF94C +3BF94C:lI115|H3BFA28 +3BFA28:lI101|H3BFB04 +3BFB04:lI114|H3BFBE0 +3BFBE0:lI118|H3BFCAC +3BFCAC:lI101|H3BFD70 +3BFD70:lI114|H3BFE34 +3BFE34:lI47|H3BFEE8 +3BFEE8:lI100|H3BFF9C +3BFF9C:lI111|H3C0048 +3C0048:lI99|H3C00F4 +3C00F4:lI47|H3C01A0 +3C01A0:lI104|H3C0254 +3C0254:lI116|H3C0310 +3C0310:lI109|H3C03C4 +3C03C4:lI108|N +3BE2D0:lI47|H3BE3C0 +3BE3C0:lI99|H3BE4C4 +3BE4C4:lI114|H3BE5C8 +3BE5C8:lI97|H3BE6CC +3BE6CC:lI115|H3BE7C0 +3BE7C0:lI104|H3BE8AC +3BE8AC:lI100|H3BE998 +3BE998:lI117|H3BEA8C +3BEA8C:lI109|H3BEB80 +3BEB80:lI112|H3BEC6C +3BEC6C:lI95|H3BED58 +3BED58:lI100|H3BEE44 +3BEE44:lI111|H3BEF18 +3BEF18:lI99|N +3BE120:lH3BE1F8|N +3BE1F8:t2:A10:erl_script_alias,H3BE2E0 +3BE2E0:t2:H3BE3D0,H3BE3D8 +3BE3D8:lH3BE4DC|N +3BE4DC:lI99|H3BE5E0 +3BE5E0:lI114|H3BE6E4 +3BE6E4:lI97|H3BE7D8 +3BE7D8:lI115|H3BE8C4 +3BE8C4:lI104|H3BE9B0 +3BE9B0:lI100|H3BEAA4 +3BEAA4:lI117|H3BEB90 +3BEB90:lI109|H3BEC7C +3BEC7C:lI112|H3BED68 +3BED68:lI95|H3BEE54 +3BEE54:lI118|H3BEF28 +3BEF28:lI105|H3BEFF4 +3BEFF4:lI101|H3BF0C0 +3BF0C0:lI119|H3BF194 +3BF194:lI101|H3BF258 +3BF258:lI114|N +3BE3D0:lI47|H3BE4D4 +3BE4D4:lI99|H3BE5D8 +3BE5D8:lI100|H3BE6DC +3BE6DC:lI118|H3BE7D0 +3BE7D0:lI95|H3BE8BC +3BE8BC:lI101|H3BE9A8 +3BE9A8:lI114|H3BEA9C +3BEA9C:lI108|N +3BDE2C:lH3BDA9C|H3BDECC +3BDA9C:t4:I127,I0,I0,I1 +3BDECC:lI8888|H3BDF88 +3BDF88:lN|N +3BDD1C:lN|N +3BDA50:t2:AD:$initial_call,H3BDAB8 +3BDAB8:t3:A3:gen,A7:init_it,H3BDAB0 +3BDA5C:t2:A9:verbosity,A7:silence +3BDAC8:t2:AE:auth_verbosity,A7:silence +3BDB28:t2:A12:security_verbosity,A7:silence +3BDB9C:t2:A12:acceptor_verbosity,A7:silence +3BDC00:t2:AA:$ancestors,H3BDC5C +3BDC5C:lA1A:httpd_sup__127_0_0_1__8888|H3BDCB4 +3BDCB4:lA8:web_tool|H3BDD24 +3BDD24:lP<0.27.0>|N +3BDADC:t2:A19:request_handler_verbosity,A7:silence +3BDB3C:t2:A5:sname,A3:man +=proc_dictionary:<0.47.0> +H36E688 +H36E694 +H36E6A0 +H36E6AC +=proc_stack:<0.47.0> +36c520:SReturn addr 0x362C9C (inet_tcp:accept/2 + 20) +y0:I5 +y1:p<0.161> +y2:p<0.141> +36c530:SReturn addr 0x500C5C (httpd_socket:accept/3 + 280) +y0:N +36c538:SReturn addr 0x502BFC (httpd_acceptor:acceptor/4 + 164) +y0:N +36c540:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:SCatch 0x502BFC (httpd_acceptor:acceptor/4 + 164) +y1:P<0.46.0> +y2:A7:ip_comm +y3:p<0.141> +y4:A1B:httpd_conf__127_0_0_1__8888 +36c558:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:AE:httpd_acceptor +y2:A8:acceptor +y3:H36E6C8 +=proc_heap:<0.47.0> +36E6C8:lP<0.44.0>|H36E724 +36E724:lP<0.46.0>|H36E748 +36E748:lA7:ip_comm|H36E760 +36E760:lH36E6D0|H36E778 +36E6D0:t4:I127,I0,I0,I1 +36E778:lI8888|H36E788 +36E788:lA1B:httpd_conf__127_0_0_1__8888|H36E798 +36E798:lA7:silence|N +36E688:t2:AD:$initial_call,H36E6F0 +36E6F0:t3:AE:httpd_acceptor,A8:acceptor,H36E6C8 +36E694:t2:A9:verbosity,A7:silence +36E6A0:t2:AA:$ancestors,H36E700 +36E700:lA1E:httpd_acc_sup__127_0_0_1__8888|H36E72C +36E72C:lA1A:httpd_sup__127_0_0_1__8888|H36E750 +36E750:lA8:web_tool|H36E768 +36E768:lP<0.27.0>|N +36E6AC:t2:A5:sname,A3:acc +=proc_dictionary:<0.48.0> +H385E48 +H385E54 +=proc_stack:<0.48.0> +3ac1bc:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A10:crashdump_viewer +y3:H3AB280 +y4:A17:crashdump_viewer_server +y5:P<0.41.0> +3ac1d8:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H385E90 +=proc_heap:<0.48.0> +3AB280:t8:A5:state,A9:undefined,A9:undefined,A9:undefined,A5:false,I4,A9:undefined,P<0.56.0> +385E90:lAA:gen_server|H385ED8 +385ED8:lP<0.41.0>|H385F10 +385F10:lP<0.41.0>|H385F58 +385F58:lH385FA8|H385FB4 +385FA8:t2:A5:local,A17:crashdump_viewer_server +385FB4:lA10:crashdump_viewer|H386014 +386014:lN|H38606C +38606C:lN|N +385E48:t2:AD:$initial_call,H385EB0 +385EB0:t3:A3:gen,A7:init_it,H385E90 +385E54:t2:AA:$ancestors,H385EC0 +385EC0:lA6:websup|H385F08 +385F08:lA8:web_tool|H385F50 +385F50:lP<0.27.0>|N +=proc_stack:<0.49.0> +36a114:SReturn addr 0x30174C (io:parse_erl_exprs/3 + 92) +y0:H369E10 +y1:P<0.22.0> +36a120:SReturn addr 0x2E5360 (shell:'-get_command/4-fun-0-'/1 + 20) +y0:N +36a128:SReturn addr 0x156F90 (<terminate process normally>) +=proc_heap:<0.49.0> +369E10:E21:8372000364000D6E6F6E6F6465406E6F686F737400000001330000000000000000 +=atoms +http_cache_control +copy_word +drop_line +copy_line +write_rest_of_line +drop_to_empty_line +read_to_empty_line_reverse +set_pos +read_line_backwards +jumped +jump_to_empty_line_or_eof +get_pos +translate_atoms +translate_fun +translate_funs +translate_loaded_modules2 +translate_loaded_modules_totals +translate_loaded_modules +translate_links +get_all_creations +translate_node_info2 +translate_node_info +translate_dist_info2 +translate_dist_info +get_msg +translate_timers +translate_ets +translate_ets_tables +do_translate_sl_alloc_r7_r8 +translate_sl_alloc_r7_r8 +translate_sl_alloc_line +do_translate_sl_alloc +translate_sl_alloc +translate_memory_and_allocated_area_r9b +translate_allocated_areas +translate_internal_table_line +translate_index_table +translate_hash_table +translate_internal_tables +translate_ports +write_last_calls +write_msg_q_stuff +translate_process +translate_processes +erts_vsn +translate_summary +'Send' +erl_crash_dump +internal_tables +mods +zombies +http_content_length +http_content_type +'-procs_summary_body/5-fun-0-' +'-expanded_memory_body/2-fun-0-' +'-expanded_memory_body/2-fun-1-' +'-expanded_memory_body/2-fun-2-' +'-ports_body/3-fun-0-' +'-ets_tables_body/4-fun-0-' +'-internal_ets_tables_table/1-fun-0-' +'-timers_body/3-fun-0-' +'-make_nodes_table/2-fun-0-' +'-loaded_mods_body/5-fun-0-' +'-funs_body/3-fun-0-' +'-memory_body/3-fun-0-' +'-allocated_areas_body/3-fun-0-' +'-allocator_info_body/3-fun-0-' +'-allocator_info_body/3-fun-1-' +'-allocator_info_body/3-fun-2-' +'-hash_tables_body/3-fun-0-' +'-index_tables_body/3-fun-0-' +enter_write_file +replace_insrt +'$insrt' +special +initial +pretty_format +heading +to_gt_noreverse +to_gt +href_proc_port +br +font +h2 +h1 +img +href +pre +em +td +th +tr +frame +frameset +html_header +index_tables_table +index_tables_body +hash_tables_table +hash_tables_body +allocator_info_body
\ No newline at end of file diff --git a/lib/observer/test/crashdump_viewer_SUITE_data/r10b_dump.trunc.250atoms b/lib/observer/test/crashdump_viewer_SUITE_data/r10b_dump.trunc.250atoms new file mode 100644 index 0000000000..ce3e5d8228 --- /dev/null +++ b/lib/observer/test/crashdump_viewer_SUITE_data/r10b_dump.trunc.250atoms @@ -0,0 +1,13285 @@ +=erl_crash_dump:0.1 +Wed Apr 21 13:22:44 2004 +Slogan: eheap_alloc: Cannot allocate 785672 bytes of memory (of type "heap"). +System version: Erlang (BEAM) emulator version 5.4 [source] [hipe] [threads:0] +Compiled: Thu Dec 18 14:07:45 2003 +Atoms: 5614 +=memory +total: 653336887 +processes: 1768396 +processes_used: 1765460 +system: 651568491 +atom: 244837 +atom_used: 237116 +binary: 648618369 +code: 2158413 +ets: 225620 +=hash_table:atom_tab +size: 4813 +used: 3304 +objs: 5614 +depth: 7 +=index_table:atom_tab +size: 5700 +limit: 1048576 +used: 5614 +rate: 100 +=hash_table:module_code +size: 97 +used: 69 +objs: 107 +depth: 5 +=index_table:module_code +size: 110 +limit: 65536 +used: 107 +rate: 10 +=hash_table:export_list +size: 2411 +used: 1674 +objs: 2843 +depth: 6 +=index_table:export_list +size: 2900 +limit: 65536 +used: 2843 +rate: 100 +=hash_table:process_reg +size: 47 +used: 16 +objs: 23 +depth: 3 +=hash_table:fun_table +size: 397 +used: 261 +objs: 400 +depth: 4 +=hash_table:node_table +size: 11 +used: 1 +objs: 1 +depth: 1 +=hash_table:dist_table +size: 11 +used: 1 +objs: 1 +depth: 1 +=allocated_areas +processes: 1765460 1768396 +ets: 225620 +sys_misc: 24634 +static: 295033 +atom_space: 65544 57967 +binary: 648618369 +atom_table: 42141 +module_table: 920 +export_table: 21336 +register_table: 252 +fun_table: 1650 +module_refs: 1024 +loaded_code: 1968915 +dist_table: 159 +node_table: 131 +bits_bufs_size: 19 +bif_timer: 13392 +link_lh: 0 +dist_buf: 0 +proc: 15080 13576 +atom_entry: 137152 137008 +export_entry: 138448 137632 +module_entry: 4872 4352 +reg_proc: 1000 592 +link_nh: 2464 2080 +link_sh: 832 192 +proc_list: 24 24 +fun_entry: 22584 22584 +db_tab: 1632 1632 +=allocator:sys_alloc +option e: true +option m: libc +=allocator:temp_alloc +versions: 0.9 2.1 +option e: true +option sbct: 524288 +option asbcst: 4145152 +option rsbcst: 90 +option rsbcmt: 80 +option mmbcs: 65536 +option mmsbc: 256 +option mmmbc: 10 +option lmbcs: 5242880 +option smbcs: 1048576 +option mbcgs: 10 +option as: af +mbcs blocks: 0 9 9 +mbcs blocks size: 0 35376 35376 +mbcs carriers: 1 1 1 +mbcs mseg carriers: 0 +mbcs sys_alloc carriers: 1 +mbcs carriers size: 65568 65568 65568 +mbcs mseg carriers size: 0 +mbcs sys_alloc carriers size: 65568 +sbcs blocks: 0 0 0 +sbcs blocks size: 0 0 0 +sbcs carriers: 0 0 0 +sbcs mseg carriers: 0 +sbcs sys_alloc carriers: 0 +sbcs carriers size: 0 0 0 +sbcs mseg carriers size: 0 +sbcs sys_alloc carriers size: 0 +temp_alloc calls: 6155 +temp_free calls: 6155 +temp_realloc calls: 29 +mseg_alloc calls: 0 +mseg_dealloc calls: 0 +mseg_realloc calls: 0 +sys_alloc calls: 1 +sys_free calls: 0 +sys_realloc calls: 0 +=allocator:sl_alloc +option e: false +=allocator:std_alloc +option e: false +=allocator:ll_alloc +versions: 0.9 2.1 +option e: true +option sbct: 4294967295 +option asbcst: 0 +option rsbcst: 0 +option rsbcmt: 0 +option mmbcs: 2097152 +option mmsbc: 0 +option mmmbc: 0 +option lmbcs: 5242880 +option smbcs: 1048576 +option mbcgs: 10 +option as: aobf +mbcs blocks: 592 592 592 +mbcs blocks size: 2838520 2863304 2863304 +mbcs carriers: 2 2 2 +mbcs mseg carriers: 0 +mbcs sys_alloc carriers: 2 +mbcs carriers size: 3145760 3145760 3145760 +mbcs mseg carriers size: 0 +mbcs sys_alloc carriers size: 3145760 +sbcs blocks: 0 0 0 +sbcs blocks size: 0 0 0 +sbcs carriers: 0 0 0 +sbcs mseg carriers: 0 +sbcs sys_alloc carriers: 0 +sbcs carriers size: 0 0 0 +sbcs mseg carriers size: 0 +sbcs sys_alloc carriers size: 0 +ll_alloc calls: 592 +ll_free calls: 0 +ll_realloc calls: 235 +mseg_alloc calls: 0 +mseg_dealloc calls: 0 +mseg_realloc calls: 0 +sys_alloc calls: 2 +sys_free calls: 0 +sys_realloc calls: 0 +=allocator:eheap_alloc +versions: 2.1 2.1 +option e: true +option sbct: 524288 +option asbcst: 4145152 +option rsbcst: 50 +option rsbcmt: 80 +option mmbcs: 524288 +option mmsbc: 256 +option mmmbc: 10 +option lmbcs: 5242880 +option smbcs: 1048576 +option mbcgs: 10 +option mbsd: 3 +option as: gf +mbcs blocks: 56 102 102 +mbcs blocks size: 833280 1638920 1638920 +mbcs carriers: 2 3 3 +mbcs mseg carriers: 1 +mbcs sys_alloc carriers: 1 +mbcs carriers size: 1998880 3047456 3047456 +mbcs mseg carriers size: 1474560 +mbcs sys_alloc carriers size: 524320 +sbcs blocks: 0 0 0 +sbcs blocks size: 0 0 0 +sbcs carriers: 0 0 0 +sbcs mseg carriers: 0 +sbcs sys_alloc carriers: 0 +sbcs carriers size: 0 0 0 +sbcs mseg carriers size: 0 +sbcs sys_alloc carriers size: 0 +eheap_alloc calls: 6971 +eheap_free calls: 6914 +eheap_realloc calls: 461 +mseg_alloc calls: 16 +mseg_dealloc calls: 14 +mseg_realloc calls: 0 +sys_alloc calls: 3 +sys_free calls: 0 +sys_realloc calls: 0 +=allocator:binary_alloc +option e: false +=allocator:ets_alloc +option e: false +=allocator:fix_alloc +option e: true +proc: 15080 13576 +atom_entry: 137152 137008 +export_entry: 138448 137632 +module_entry: 4872 4352 +reg_proc: 1000 592 +link_nh: 2464 2080 +link_sh: 832 192 +proc_list: 24 24 +fun_entry: 22584 22584 +db_tab: 1632 1632 +=allocator:mseg_alloc +version: 0.9 +option amcbf: 4194304 +option rmcbf: 20 +option mcs: 5 +option cci: 1000 +cached_segments: 0 +cache_hits: 13 +segments: 2 +segments_watermark: 2 +mseg_alloc calls: 16 +mseg_dealloc calls: 14 +mseg_realloc calls: 0 +mseg_create calls: 4 +mseg_destroy calls: 1 +mseg_clear_cache calls: 6 +mseg_check_cache calls: 2 +=allocator:alloc_util +option mmc: 1024 +option ycs: 1048576 +=allocator:instr +option m: false +option s: false +option t: false +=proc:<0.0.0> +State: Waiting +Name: init +Spawned as: otp_ring0:start/2 +Spawned by: [] +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.5.0>,<0.4.0>,<0.2.0>] +Reductions: 3851 +Stack+heap: 377 +OldHeap: 610 +Heap unused: 53 +OldHeap unused: 610 +Program counter: 0x1f496c (init:loop/1 + 20) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.2.0> +State: Waiting +Name: erl_prim_loader +Spawned as: erlang:apply/2 +Spawned by: <0.1.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.0.0>,#Port<0.2>] +Reductions: 201036 +Stack+heap: 987 +OldHeap: 987 +Heap unused: 923 +OldHeap unused: 987 +Program counter: 0x20cc94 (erl_prim_loader:loop/3 + 52) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.4.0> +State: Waiting +Name: error_logger +Spawned as: proc_lib:init_p/5 +Spawned by: <0.1.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.21.0>,<0.0.0>] +Reductions: 296 +Stack+heap: 6765 +OldHeap: 0 +Heap unused: 851 +OldHeap unused: 0 +Program counter: 0x21f5b8 (gen_event:loop/4 + 40) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.5.0> +State: Waiting +Name: application_controller +Spawned as: proc_lib:init_p/5 +Spawned by: <0.1.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.7.0>,<0.0.0>] +Reductions: 1508 +Stack+heap: 1597 +OldHeap: 0 +Heap unused: 835 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.7.0> +State: Waiting +Spawned as: proc_lib:init_p/5 +Spawned by: <0.6.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.8.0>,<0.5.0>] +Reductions: 23 +Stack+heap: 377 +OldHeap: 0 +Heap unused: 79 +OldHeap unused: 0 +Program counter: 0x248d04 (application_master:main_loop/2 + 28) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.8.0> +State: Waiting +Spawned as: application_master:start_it/4 +Spawned by: <0.7.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.9.0>,<0.7.0>] +Reductions: 91 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 177 +OldHeap unused: 0 +Program counter: 0x24a26c (application_master:loop_it/4 + 40) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.9.0> +State: Waiting +Name: kernel_sup +Spawned as: proc_lib:init_p/5 +Spawned by: <0.8.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.24.0>,<0.23.0>,<0.19.0>,<0.18.0>,<0.17.0>,<0.16.0>,<0.15.0>,<0.14.0>,<0.11.0>,<0.10.0>,<0.8.0>] +Reductions: 7402 +Stack+heap: 610 +OldHeap: 987 +Heap unused: 311 +OldHeap unused: 987 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.10.0> +State: Waiting +Name: rex +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.9.0>] +Reductions: 44 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 144 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.11.0> +State: Waiting +Name: global_name_server +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.13.0>,<0.12.0>,<0.9.0>] +Reductions: 47 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 98 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.12.0> +State: Waiting +Spawned as: global:init_the_locker/1 +Spawned by: <0.11.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.11.0>] +Reductions: 3 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 227 +OldHeap unused: 0 +Program counter: 0x261340 (global:loop_the_locker/2 + 92) +CP: 0x261184 (global:init_the_locker/1 + 112) +arity = 0 +=proc:<0.13.0> +State: Waiting +Spawned as: erlang:apply/2 +Spawned by: <0.11.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.11.0>] +Reductions: 4 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 221 +OldHeap unused: 0 +Program counter: 0x265288 (global:collect_deletions/2 + 76) +CP: 0x2651ac (global:loop_the_deleter/1 + 36) +arity = 0 +=proc:<0.14.0> +State: Waiting +Name: inet_db +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.9.0>] +Reductions: 376 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 30 +OldHeap unused: 233 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.15.0> +State: Waiting +Name: global_group +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.9.0>] +Reductions: 71 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 92 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.16.0> +State: Waiting +Name: file_server_2 +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 1 +Heap fragment data: 119 +Link list: [{from,<0.17.0>,#Ref<0.0.0.22>},#Port<0.4>,<0.9.0>] +Reductions: 83605 +Stack+heap: 4181 +OldHeap: 4181 +Heap unused: 1720 +OldHeap unused: 4181 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.17.0> +State: Waiting +Name: file_server +Spawned as: erlang:apply/2 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [{to,<0.16.0>,#Ref<0.0.0.22>},<0.9.0>] +Reductions: 12 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 207 +OldHeap unused: 0 +Program counter: 0x2a18e8 (old_file_server:relay_loop/3 + 32) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.18.0> +State: Waiting +Name: code_server +Spawned as: erlang:apply/2 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.9.0>] +Reductions: 108900 +Stack+heap: 6765 +OldHeap: 6765 +Heap unused: 4389 +OldHeap unused: 6765 +Program counter: 0x2a6e64 (code_server:loop/1 + 64) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.19.0> +State: Waiting +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.21.0>,<0.9.0>] +Reductions: 74 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 180 +OldHeap unused: 233 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.20.0> +State: Waiting +Spawned as: user_drv:server/2 +Spawned by: <0.19.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.22.0>,<0.21.0>,#Port<0.72>] +Reductions: 596 +Stack+heap: 233 +OldHeap: 377 +Heap unused: 214 +OldHeap unused: 377 +Program counter: 0x2ca4e0 (user_drv:server_loop/5 + 56) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.21.0> +State: Waiting +Name: user +Spawned as: group:server/2 +Spawned by: <0.20.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.4.0>,<0.19.0>,<0.20.0>] +Reductions: 26 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 202 +OldHeap unused: 0 +Program counter: 0x2cd9d8 (group:server_loop/3 + 32) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.22.0> +State: Waiting +Spawned as: group:server/2 +Spawned by: <0.20.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [{from,<0.49.0>,#Ref<0.0.0.307>},<0.25.0>,<0.20.0>] +Reductions: 1244 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 40 +OldHeap unused: 233 +Program counter: 0x2cf238 (group:get_line1/3 + 1652) +CP: 0x2cf230 (group:get_line1/3 + 1644) +arity = 0 +=proc:<0.23.0> +State: Waiting +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.9.0>] +Reductions: 45 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 63 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.24.0> +State: Waiting +Name: kernel_safe_sup +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.31.0>,<0.9.0>] +Reductions: 133 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 198 +OldHeap unused: 233 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.25.0> +State: Waiting +Spawned as: erlang:apply/2 +Spawned by: <0.22.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.49.0>,<0.27.0>,<0.22.0>] +Reductions: 161 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 169 +OldHeap unused: 0 +Program counter: 0x2e0d00 (shell:get_command1/4 + 40) +CP: 0x2e06fc (shell:server_loop/6 + 140) +arity = 0 +=proc:<0.27.0> +State: Waiting +Spawned as: erlang:apply/2 +Spawned by: <0.25.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.25.0>] +Reductions: 506 +Stack+heap: 4181 +OldHeap: 0 +Heap unused: 1131 +OldHeap unused: 0 +Program counter: 0x2e2bbc (shell:eval_loop/2 + 32) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.31.0> +State: Waiting +Name: inet_gethost_native_sup +Spawned as: proc_lib:init_p/5 +Spawned by: <0.24.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.32.0>,<0.24.0>] +Reductions: 49 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 87 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.32.0> +State: Waiting +Name: inet_gethost_native +Spawned as: inet_gethost_native:server_init/2 +Spawned by: <0.31.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 1 +Heap fragment data: 118 +Link list: [#Port<0.105>,<0.31.0>] +Reductions: 65 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 13 +OldHeap unused: 0 +Program counter: 0x4ad840 (inet_gethost_native:main_loop/1 + 20) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.33.0> +State: Waiting +Name: web_tool +Spawned as: proc_lib:init_p/5 +Spawned by: <0.27.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.41.0>] +Reductions: 131773 +Stack+heap: 6765 +OldHeap: 6765 +Heap unused: 2941 +OldHeap unused: 6765 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.41.0> +State: Waiting +Name: websup +Spawned as: proc_lib:init_p/5 +Spawned by: <0.33.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.48.0>,<0.33.0>] +Reductions: 118 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 205 +OldHeap unused: 233 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.43.0> +State: Waiting +Name: httpd_sup__127_0_0_1__8888 +Spawned as: proc_lib:init_p/5 +Spawned by: <0.33.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.46.0>,<0.45.0>,<0.44.0>] +Reductions: 1220 +Stack+heap: 6765 +OldHeap: 0 +Heap unused: 277 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.44.0> +State: Waiting +Name: httpd_acc_sup__127_0_0_1__8888 +Spawned as: proc_lib:init_p/5 +Spawned by: <0.43.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.47.0>,<0.43.0>] +Reductions: 147 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 77 +OldHeap unused: 233 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.45.0> +State: Waiting +Name: httpd_misc_sup__127_0_0_1__8888 +Spawned as: proc_lib:init_p/5 +Spawned by: <0.43.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.43.0>] +Reductions: 52 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 80 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.46.0> +State: Waiting +Name: httpd__127_0_0_1__8888 +Spawned as: proc_lib:init_p/5 +Spawned by: <0.43.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.43.0>] +Reductions: 2905 +Stack+heap: 6765 +OldHeap: 10946 +Heap unused: 138 +OldHeap unused: 10946 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.47.0> +State: Waiting +Spawned as: proc_lib:init_p/5 +Spawned by: <0.44.0> +Started: Wed Apr 21 13:22:18 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [#Port<0.161>,#Port<0.141>,<0.44.0>] +Reductions: 874 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 190 +OldHeap unused: 233 +Program counter: 0x1fe798 (prim_inet:accept0/2 + 96) +CP: 0x1feb04 (prim_inet:async_accept/2 + 380) +arity = 0 +=proc:<0.48.0> +State: Waiting +Name: crashdump_viewer_server +Spawned as: proc_lib:init_p/5 +Spawned by: <0.41.0> +Started: Wed Apr 21 13:22:18 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.56.0>,<0.41.0>] +Reductions: 1913 +Stack+heap: 987 +OldHeap: 987 +Heap unused: 524 +OldHeap unused: 987 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.49.0> +State: Waiting +Spawned as: erlang:apply/2 +Spawned by: <0.25.0> +Started: Wed Apr 21 13:22:18 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [{to,<0.22.0>,#Ref<0.0.0.307>},<0.25.0>] +Reductions: 15 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 190 +OldHeap unused: 0 +Program counter: 0x301d58 (io:wait_io_mon_reply/2 + 28) +CP: 0x30174c (io:parse_erl_exprs/3 + 92) +arity = 0 +=proc:<0.56.0> +State: Garbing +Spawned as: erlang:apply/2 +Last scheduled in for: erlang:garbage_collect/0 +Spawned by: <0.48.0> +Started: Wed Apr 21 13:22:27 2004 +Message queue length: 0 +Number of heap fragments: 1 +Heap fragment data: 121 +Link list: [#Port<0.158>,#Port<0.157>,<0.48.0>] +Reductions: 2420470 +Stack+heap: 121393 +OldHeap: 0 +Heap unused: 22172 +OldHeap unused: 0 +New heap start: FE5768E0 +New heap top: FE5D7734 +Stack top: FE5ED130 +Stack end: FE5ED1A4 +Old heap start: 0 +Old heap top: 0 +Old heap end: 0 +Program counter: 0x1a4980 (unknown function) +CP: 0x20710c (prim_file:read/2 + 436) +=port:#Port<0.1> +Slot: 1 +Connected: #Port<0.0> +Port controls linked-in driver: async +=port:#Port<0.2> +Slot: 2 +Connected: <0.2.0> +Links: <0.2.0> +Port controls linked-in driver: efile +=port:#Port<0.4> +Slot: 4 +Connected: <0.16.0> +Links: <0.16.0> +Port controls linked-in driver: efile +=port:#Port<0.72> +Slot: 72 +Connected: <0.20.0> +Links: <0.20.0> +Port controls linked-in driver: tty_sl -c -e +=port:#Port<0.105> +Slot: 105 +Connected: <0.32.0> +Links: <0.32.0> +Port controls external process: inet_gethost 4 +=port:#Port<0.141> +Slot: 141 +Connected: <0.47.0> +Links: <0.47.0> +Port controls linked-in driver: tcp_inet +=port:#Port<0.157> +Slot: 157 +Connected: <0.56.0> +Links: <0.56.0> +Port controls linked-in driver: efile +=port:#Port<0.158> +Slot: 158 +Connected: <0.56.0> +Links: <0.56.0> +Port controls linked-in driver: efile +=port:#Port<0.161> +Slot: 161 +Connected: <0.47.0> +Links: <0.47.0> +Port controls linked-in driver: tcp_inet +=ets:<0.18.0> +Slot: 9 +Table: 9 +Name: code +Buckets: 256 +Objects: 289 +Words: 14108 +=ets:<0.18.0> +Slot: 10 +Table: 10 +Name: code_names +Buckets: 256 +Objects: 47 +Words: 4334 +=ets:<0.32.0> +Slot: 11 +Table: 11 +Name: ign_requests +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.32.0> +Slot: 12 +Table: 12 +Name: ign_req_index +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.33.0> +Slot: 13 +Table: 13 +Name: app_data +Buckets: 256 +Objects: 7 +Words: 952 +=ets:<0.46.0> +Slot: 15 +Table: 15 +Name: httpd_mime__127_0_0_1__8888 +Buckets: 256 +Objects: 105 +Words: 5742 +=ets:<0.11.0> +Slot: 84 +Table: global_names +Name: global_names +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.11.0> +Slot: 95 +Table: global_locks +Name: global_locks +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.11.0> +Slot: 96 +Table: global_names_ext +Name: global_names_ext +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.14.0> +Slot: 316 +Table: inet_cache +Name: inet_cache +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.48.0> +Slot: 340 +Table: cdv_menu_table +Name: cdv_menu_table +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.48.0> +Slot: 341 +Table: cdv_dump_index_table +Name: cdv_dump_index_table +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.48.0> +Slot: 342 +Table: cdv_decode_heap_table +Name: cdv_decode_heap_table +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.16.0> +Slot: 780 +Table: file_io_servers +Name: file_io_servers +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.46.0> +Slot: 984 +Table: httpd_conf__127_0_0_1__8888 +Name: httpd_conf__127_0_0_1__8888 +Buckets: 256 +Objects: 17 +Words: 1176 +=ets:<0.14.0> +Slot: 1342 +Table: inet_hosts +Name: inet_hosts +Buckets: 256 +Objects: 4 +Words: 421 +=ets:<0.14.0> +Slot: 1362 +Table: inet_db +Name: inet_db +Buckets: 256 +Objects: 20 +Words: 671 +=ets:<0.5.0> +Slot: 1655 +Table: ac_tab +Name: ac_tab +Buckets: 256 +Objects: 6 +Words: 843 +=timer:<0.14.0> +Message: refresh_timeout +Time left: 3565692 ms +=node:'nonode@nohost' +=no_distribution +=loaded_modules +Current code: 1968915 +Old code: 0 +=mod:otp_ring0 +Current size: 489 +=mod:init +Current size: 30110 +=mod:prim_inet +Current size: 35532 +=mod:prim_file +Current size: 24965 +=mod:erl_prim_loader +Current size: 19607 +=mod:erlang +Current size: 11137 +=mod:error_handler +Current size: 2389 +Current attributes: 836C00000001680264000376736E6C000000016E100030769A34345F26EF6D3433254FF2AE576A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613161216802640006736F757263656B00342F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6572726F725F68616E646C65722E65726C6A +=mod:heart +Current size: 6687 +Current attributes: 836C00000001680264000376736E6C000000016E10003094F7BECF345494DDBB4D7186E694186A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261086802640006736F757263656B002C2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F68656172742E65726C6A +=mod:error_logger +Current size: 7051 +Current attributes: 836C00000001680264000376736E6C000000016E10004E3347F841DEAE2EB6A74389E6E127146A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613161246802640006736F757263656B00332F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6572726F725F6C6F676765722E65726C6A +=mod:gen_event +Current size: 18288 +Current attributes: 836C00000001680264000376736E6C000000016E1000336F22DF1EA75E0EA4AE65D3B8C34F946A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61346802640006736F757263656B00302F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F67656E5F6576656E742E65726C6A +=mod:gen +Current size: 7129 +Current attributes: 836C00000001680264000376736E6C000000016E10007BE6AEB66EF48D8B33323C89C9936A526A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61316802640006736F757263656B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F67656E2E65726C6A +=mod:proc_lib +Current size: 11658 +Current attributes: 836C00000001680264000376736E6C000000016E10005C589A8C9BD2E1F2E895E765CAE983406A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E612D6802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F70726F635F6C69622E65726C6A +=mod:application_controller +Current size: 55249 +Current attributes: 836C00000002680264000376736E6C000000016E10003372E1AB0410565065FA086086A721316A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613061246802640006736F757263656B003D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6170706C69636174696F6E5F636F6E74726F6C6C65722E65726C6A +=mod:gen_server +Current size: 18728 +Current attributes: 836C00000001680264000376736E6C000000016E10004C5E93533036DAC7698FC4112F59CF236A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61396802640006736F757263656B00312F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F67656E5F7365727665722E65726C6A +=mod:sys +Current size: 11589 +Current attributes: 836C00000001680264000376736E6C000000016E1000E12B0E8267551204BD5924BAB9629ADF6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612F61176802640006736F757263656B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F7379732E65726C6A +=mod:lists +Current size: 18638 +Current attributes: 836C00000002680264000376736E6C000000016E10001E95B32C30E4CDAF0BDD1ABA58CBB5F36A680264000A646570726563617465646C0000000B68026400066B65796D617061046802640003616C6C61036802640003616E79610368026400036D617061036802640007666C61746D617061036802640005666F6C646C61046802640005666F6C64726104680264000666696C746572610368026400086D6170666F6C646C610468026400086D6170666F6C647261046802640007666F726561636861036A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61116802640006736F757263656B002C2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6C697374732E65726C6A +=mod:application +Current size: 2666 +Current attributes: 836C00000001680264000376736E6C000000016E1000C0C5A7B67B306300FEFF9D91AA50ECB36A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6130611F6802640006736F757263656B00322F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6170706C69636174696F6E2E65726C6A +=mod:application_master +Current size: 10912 +Current attributes: 836C00000001680264000376736E6C000000016E1000360420F5CEB80AD7DD51B3A8A0E2AFA26A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613061266802640006736F757263656B00392F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6170706C69636174696F6E5F6D61737465722E65726C6A +=mod:kernel +Current size: 7639 +Current attributes: 836C00000002680264000376736E6C000000016E10004D418ACCB0F948D4D3CA6B9A81B462746A68026400096265686176696F75726C0000000164000A73757065727669736F726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261336802640006736F757263656B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6B65726E656C2E65726C6A +=mod:supervisor +Current size: 24469 +Current attributes: 836C00000002680264000376736E6C000000016E1000979F65727577135484BE0892A35087CC6A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612F61126802640006736F757263656B00312F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F73757065727669736F722E65726C6A +=mod:rpc +Current size: 14539 +Current attributes: 836C00000002680264000376736E6C000000016E10008C5D6242D36B3201E3B11E82D5E1581E6A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6133610F6802640006736F757263656B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F7270632E65726C6A +=mod:gb_trees +Current size: 8274 +Current attributes: 836C00000001680264000376736E6C000000016E1000094BEFDE7B866EF2CB6FCD895AC2EE056A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D612B6802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F67625F74726565732E65726C6A +=mod:global +Current size: 40753 +Current attributes: 836C00000002680264000376736E6C000000016E10001D02C89BDE6CB2052F099894683C14CA6A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613161386802640006736F757263656B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F676C6F62616C2E65726C6A +=mod:inet_db +Current size: 34555 +Current attributes: 836C00000001680264000376736E6C000000016E1000C1CF6A6F2E83D4EBC23D2CCECBF376226A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6132611A6802640006736F757263656B002E2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F64622E65726C6A +=mod:inet_config +Current size: 13575 +Current attributes: 836C00000001680264000376736E6C000000016E1000650F6571C03BC9C16BB7973A747565066A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261166802640006736F757263656B00322F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F636F6E6669672E65726C6A +=mod:os +Current size: 5997 +Current attributes: 836C00000001680264000376736E6C000000016E100017144CD766A604A9DFBA0B58C8FCA78B6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613361056802640006736F757263656B00292F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6F732E65726C6A +=mod:inet_udp +Current size: 2451 +Current attributes: 836C00000001680264000376736E6C000000016E1000ACB163E87A687A6683B50B331C6E289B6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261306802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F7564702E65726C6A +=mod:inet +Current size: 28288 +Current attributes: 836C00000001680264000376736E6C000000016E10009B9AD400F0BAF6AAF17A4788A4EFF11E6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6132610C6802640006736F757263656B002B2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65742E65726C6A +=mod:inet_parse +Current size: 21928 +Current attributes: 836C00000001680264000376736E6C000000016E1000E0E65454C096847749930EDC1C53C80B6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261266802640006736F757263656B00312F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F70617273652E65726C6A +=mod:filename +Current size: 17411 +Current attributes: 836C00000001680264000376736E6C000000016E100068085214F459D51A3E08819BF8D7698A6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61296802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F66696C656E616D652E65726C6A +=mod:inet_hosts +Current size: 3745 +Current attributes: 836C00000001680264000376736E6C000000016E1000E7430304E86230057150DEE5D279881F6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261226802640006736F757263656B00312F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F686F7374732E65726C6A +=mod:erl_distribution +Current size: 2512 +Current attributes: 836C00000002680264000376736E6C000000016E1000CDE49D63ACA767E0D49679657E99D2046A68026400096265686176696F75726C0000000164000A73757065727669736F726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613161186802640006736F757263656B00372F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F65726C5F646973747269627574696F6E2E65726C6A +=mod:global_group +Current size: 30960 +Current attributes: 836C00000002680264000376736E6C000000016E10008ECE759E5920988CA3ACFF34B32F86736A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6131613B6802640006736F757263656B00332F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F676C6F62616C5F67726F75702E65726C6A +=mod:net_kernel +Current size: 37648 +Current attributes: 836C00000002680264000376736E6C000000016E1000967CE7DE41F9B39906CCCF3225E6E5286A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613361026802640006736F757263656B00312F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6E65745F6B65726E656C2E65726C6A +=mod:file_server +Current size: 8372 +Current attributes: 836C00000002680264000376736E6C000000016E1000EF90906EC6204204AC0A77C4A25B65236A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6131612D6802640006736F757263656B00322F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F66696C655F7365727665722E65726C6A +=mod:old_file_server +Current size: 3074 +Current attributes: 836C00000001680264000376736E6C000000016E1000C802085DD76D4EFBA6A8F528FECB94B36A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6131612F6802640006736F757263656B00362F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6F6C645F66696C655F7365727665722E65726C6A +=mod:code +Current size: 7419 +Current attributes: 836C00000001680264000376736E6C000000016E1000AE618E3041C8E3807A3719CD5140DF5E6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6130612E6802640006736F757263656B002B2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F636F64652E65726C6A +=mod:code_server +Current size: 30811 +Current attributes: 836C00000001680264000376736E6C000000016E0F00BFB96248C2CA8601B4CB7F543F52E26A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613061346802640006736F757263656B00322F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F636F64655F7365727665722E65726C6A +=mod:code_aux +Current size: 1736 +Current attributes: 836C00000001680264000376736E6C000000016E10007A90DB53FCCECD52504F20E7A3B6BAE26A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613061316802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F636F64655F6175782E65726C6A +=mod:packages +Current size: 3119 +Current attributes: 836C00000001680264000376736E6C000000016E1000044DC8EEB65F178AE23EF2465E1954496A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613361076802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F7061636B616765732E65726C6A +=mod:hipe_unified_loader +Current size: 37330 +Current attributes: 836C00000001680264000376736E6C000000016E1000DABD57945702E56F4B3AA7B7B19C1D166A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613361326802640006736F757263656B003A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F686970655F756E69666965645F6C6F616465722E65726C6A +=mod:hipe_sparc_loader +Current size: 1821 +Current attributes: 836C00000001680264000376736E6C000000016E1000582BC55E9FADFF879C2C45D25A6CB7E56A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C7564656802640001696B00322F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F2E2E2F686970652F6D61696E6802640001696B00312F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F2E2E2F686970652F72746C6802640001696B00332F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F2E2E2F686970652F737061726364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6133612B6802640006736F757263656B00382F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F686970655F73706172635F6C6F616465722E65726C6A +=mod:ets +Current size: 16577 +Current attributes: 836C00000002680264000376736E6C000000016E100033D982AC91129E5FC35E0AC3337A4EB56A680264000A646570726563617465646C0000000168026400086669787461626C6561026A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D611C6802640006736F757263656B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6574732E65726C6A +=mod:lists_sort +Current size: 38692 +Current attributes: 836C00000001680264000376736E6C000000016E1000E17EC92FA9AA3199DD71701C215044616A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000B68026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736802640006696E6C696E656C0000000468026400096D65726765335F3132610768026400096D65726765335F32316107680264000A726D65726765335F31326107680264000A726D65726765335F323161076A6802640006696E6C696E656C00000004680264000A756D65726765335F31326108680264000A756D65726765335F32316108680264000C72756D65726765335F3132616107680264000C72756D65726765335F31326261086A6802640006696E6C696E656C00000004680264000C6B65796D65726765335F3132610C680264000C6B65796D65726765335F3231610C680264000D726B65796D65726765335F3132610C680264000D726B65796D65726765335F3231610C6A6802640006696E6C696E656C00000006680264000D756B65796D65726765335F3132610D680264000D756B65796D65726765335F3231610D680264000F72756B65796D65726765335F313261610B680264000F72756B65796D65726765335F323161610D680264000F72756B65796D65726765335F313262610D680264000F72756B65796D65726765335F323162610C6A6A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61166802640006736F757263656B00312F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6C697374735F736F72742E65726C6A +=mod:user_sup +Current size: 2355 +Current attributes: 836C00000002680264000376736E6C000000016E100074BA860804CB4D60D6908C705E6544BD6A68026400096265686176696F75726C0000000164001173757065727669736F725F6272696467656A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613361246802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F757365725F7375702E65726C6A +=mod:supervisor_bridge +Current size: 2944 +Current attributes: 836C00000002680264000376736E6C000000016E10001590DDC10CF8A9D09763CDB7479678ED6A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612F61156802640006736F757263656B00382F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F73757065727669736F725F6272696467652E65726C6A +=mod:user_drv +Current size: 14630 +Current attributes: 836C00000001680264000376736E6C000000016E1000F29F3B193A1EB1ADA9975D97E51BF0E86A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613361216802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F757365725F6472762E65726C6A +=mod:group +Current size: 10165 +Current attributes: 836C00000001680264000376736E6C000000016E1000F6427D0DA330BBFAD5D4C19058516FF36A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261066802640006736F757263656B002C2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F67726F75702E65726C6A +=mod:io_lib +Current size: 12601 +Current attributes: 836C00000002680264000376736E6C000000016E10004160DD78F37EE7C72F7C5B6A751DB7F56A680264000A646570726563617465646C0000000468026400047363616E610168026400047363616E610268026400047363616E6103680264000D72657365727665645F776F726461016A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61036802640006736F757263656B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F696F5F6C69622E65726C6A +=mod:edlin +Current size: 18178 +Current attributes: 836C00000001680264000376736E6C000000016E100035D752FCBA8ED7F4D26990EF3E6A1A526A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612C61016802640006736F757263656B002C2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F65646C696E2E65726C6A +=mod:io_lib_format +Current size: 16189 +Current attributes: 836C00000001680264000376736E6C000000016E10004F382F327C456F83F33C3D5EBFBD87906A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61066802640006736F757263656B00342F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F696F5F6C69625F666F726D61742E65726C6A +=mod:kernel_config +Current size: 3295 +Current attributes: 836C00000002680264000376736E6C000000016E100077B8EE6C9E95FBBE5DB0371F6DB235226A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261356802640006736F757263656B00342F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6B65726E656C5F636F6E6669672E65726C6A +=mod:shell +Current size: 22571 +Current attributes: 836C00000001680264000376736E6C000000016E10007D1354325618EB98A5BD4E8F41E6A0226A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612F61016802640006736F757263656B002C2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F7368656C6C2E65726C6A +=mod:error_logger_tty_h +Current size: 7773 +Current attributes: 836C00000002680264000376736E6C000000016E10001502D55D6C1777F07E2E05CDD91D16986A68026400096265686176696F75726C0000000164000967656E5F6576656E746A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61196802640006736F757263656B00392F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6572726F725F6C6F676765725F7474795F682E65726C6A +=mod:erl_eval +Current size: 33481 +Current attributes: 836C00000002680264000376736E6C000000016E1000D06903753C86BBC49A5CBD789CCB09B66A680264000A646570726563617465646C00000004680264000373657161026802640003736571610368026400086172675F6C697374610268026400086172675F6C69737461036A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612C610D6802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F65726C5F6576616C2E65726C6A +=mod:orddict +Current size: 4872 +Current attributes: 836C00000002680264000376736E6C000000016E100078DCF69F3949D79BC54168266A3ABF566A680264000A646570726563617465646C00000002680264000C646963745F746F5F6C6973746101680264000C6C6973745F746F5F6469637461016A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61236802640006736F757263656B002E2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6F7264646963742E65726C6A +=mod:c +Current size: 19555 +Current attributes: 836C00000001680264000376736E6C000000016E10003FACCF5DE16ABBC988ABF0811980C33B6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612B61136802640006736F757263656B00282F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F632E65726C6A +=mod:io +Current size: 7417 +Current attributes: 836C00000002680264000376736E6C000000016E1000E2F2A6094B3C3D945865225D0620E7546A680264000A646570726563617465646C00000007680264000B70617273655F65787072736102680264000C7363616E5F65726C5F7365716101680264000C7363616E5F65726C5F7365716102680264000C7363616E5F65726C5F7365716103680264000D70617273655F65726C5F7365716101680264000D70617273655F65726C5F7365716102680264000D70617273655F65726C5F73657161036A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61006802640006736F757263656B00292F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F696F2E65726C6A +=mod:file +Current size: 20795 +Current attributes: 836C00000002680264000376736E6C000000016E1000D291AF77EE8B08B792B7FE99274504506A680264000A646570726563617465646C00000001680264000966696C655F696E666F61016A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613161276802640006736F757263656B002B2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F66696C652E65726C6A +=mod:file_io_server +Current size: 12071 +Current attributes: 836C00000001680264000376736E6C000000016E1000A5A8C4E2B2646855AD5C617CB216CB966A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6131612A6802640006736F757263656B00352F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F66696C655F696F5F7365727665722E65726C6A +=mod:erl_scan +Current size: 21891 +Current attributes: 836C00000001680264000376736E6C000000016E100094F386F0C378B258E5D9CEADD4F03B6A6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61116802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F65726C5F7363616E2E65726C6A +=mod:erl_parse +Current size: 161233 +Current attributes: 836C00000001680264000376736E6C000000016E10000E8CBC32C293BFC1FBC721CE918062236A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000968026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F76617273640006696E6C696E656802640004686970656C000000016802640008726567616C6C6F6364000B6C696E6561725F7363616E6A6A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61076802640006736F757263656B00302F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F65726C5F70617273652E65726C6A +=mod:erl_lint +Current size: 73159 +Current attributes: 836C00000001680264000376736E6C000000016E1000D1D2A7D6DDFD1195CB180993C76FD2CD6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612C61156802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F65726C5F6C696E742E65726C6A +=mod:ordsets +Current size: 3257 +Current attributes: 836C00000002680264000376736E6C000000016E1000FD39D8FD846511128F5670BA28600F676A680264000A646570726563617465646C0000000468026400076E65775F7365746100680264000B7365745F746F5F6C6973746101680264000B6C6973745F746F5F7365746101680264000673756273657461026A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61256802640006736F757263656B002E2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6F7264736574732E65726C6A +=mod:dict +Current size: 15637 +Current attributes: 836C00000002680264000376736E6C000000016E1000BC846E7EF85045A5D76190CE9B1AE97C6A680264000A646570726563617465646C00000002680264000C646963745F746F5F6C6973746101680264000C6C6973745F746F5F6469637461016A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612B61356802640006736F757263656B002B2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F646963742E65726C6A +=mod:otp_internal +Current size: 7133 +Current attributes: 836C00000001680264000376736E6C000000016E1000DC494F64DE590AFC4919DFEB0EB026B66A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61206802640006736F757263656B00332F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6F74705F696E7465726E616C2E65726C6A +=mod:user_default +Current size: 1261 +Current attributes: 836C00000002680264000376736E6C000000016E1000505078ACD9B84D514FC6DA2BE249E6756A6802640006617574686F726C0000000164001765656973686E6E406565692E6572696373736F6E2E73656A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000368026400036377646B00112F686F6D652F736972692F65726C616E6768026400066F75746469726B00112F686F6D652F736972692F65726C616E676400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D461036116610D612C61126802640006736F757263656B00222F686F6D652F736972692F65726C616E672F757365725F64656661756C742E65726C6A +=mod:tt +Current size: 2959 +Current attributes: 836C00000002680264000376736E6C000000016E10001D71FD5A55D3BCBF06BFEDF2426C3C386A6802640006617574686F726C0000000164001765656973686E6E406565692E6572696373736F6E2E73656A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000368026400036377646B00112F686F6D652F736972692F65726C616E6768026400066F75746469726B00112F686F6D652F736972692F65726C616E676400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D461036116610D612B610C6802640006736F757263656B00182F686F6D652F736972692F65726C616E672F74742E65726C6A +=mod:distel +Current size: 18214 +Current attributes: 836C00000002680264000376736E6C000000016E1000CC9C9EF141459249C1CCA00993B2E29A6A6802640006617574686F726C000000016400116C756B6540626C75657461696C2E636F6D6A6A +Current compilation info: 836C0000000368026400076F7074696F6E736C0000000664000276336400107761726E5F756E757365645F7661727364000A64656275675F696E666F68026400066F75746469726B00046562696E68026400036377646B001C2F6C6469736B2F736972692F746F6F6C732F64697374656C2D332E3164000A6578706F72745F616C6C6A680264000776657273696F6E6B0003342E31680264000474696D65680662000007D2610B6114610B610361336A +=mod:crashdump_viewer +Current size: 125756 +Current attributes: 836C00000001680264000376736E6C000000016E10002DC5D9D96190A2D5F27FAC3FA3D5C7956A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868026400036377646B00212F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F73726368026400066F75746469726B00292F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F6562696E6802640001696B002C2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F696E636C7564656802640001696B00322F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F2E2E2F65742F696E636C7564656802640001696B003F2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F2E2E2F2E2E2F6C69627261726965732F65742F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F76617273680264000F70617273655F7472616E73666F726D64000C6D735F7472616E73666F726D6A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461146108611B61366802640006736F757263656B00362F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F637261736864756D705F7669657765722E65726C6A +=mod:webtool +Current size: 29229 +Current attributes: 836C00000002680264000376736E6C000000016E10008AEEF06B60527A3390CBC2C98083CC0A6A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00202F636C656172636173652F6F74702F746F6F6C732F776562746F6F6C2F73726368026400066F75746469726B00282F636C656172636173652F6F74702F746F6F6C732F776562746F6F6C2F7372632F2E2E2F6562696E64000A64656275675F696E666F6400107761726E5F756E757365645F76617273680264000F70617273655F7472616E73666F726D64000C6D735F7472616E73666F726D6A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104610661086106612D6802640006736F757263656B002C2F636C656172636173652F6F74702F746F6F6C732F776562746F6F6C2F7372632F776562746F6F6C2E65726C6A +=mod:gen_tcp +Current size: 3574 +Current attributes: 836C00000001680264000376736E6C000000016E1000C965E4EAFDAA94D7F21EDCBE30B21E7B6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613161316802640006736F757263656B002E2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F67656E5F7463702E65726C6A +=mod:inet_tcp +Current size: 2743 +Current attributes: 836C00000001680264000376736E6C000000016E1000C4AFE0B49768E4CF78B2C42EA1D3DB7F6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6132612B6802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F7463702E65726C6A +=mod:inet_gethost_native +Current size: 15611 +Current attributes: 836C00000002680264000376736E6C000000016E10005D8CD4277D0BD2425B9C26036AE314506A68026400096265686176696F75726C0000000164001173757065727669736F725F6272696467656A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261206802640006736F757263656B003A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F676574686F73745F6E61746976652E65726C6A +=mod:filelib +Current size: 7202 +Current attributes: 836C00000001680264000376736E6C000000016E10007B42AA23FF99DF2CD9D586635B77556A6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61266802640006736F757263656B002E2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F66696C656C69622E65726C6A +=mod:httpd_util +Current size: 24068 +Current attributes: 836C00000002680264000376736E6C000000016E10008D99E096221B88D542E52CB9C8377F6D6A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104611561066128613B6802640006736F757263656B00312F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F7574696C2E65726C6A +=mod:webtool_sup +Current size: 695 +Current attributes: 836C00000002680264000376736E6C000000016E1000FA5449E12816CF3AD0A3085BB26CDB9B6A68026400096265686176696F75726C0000000164000A73757065727669736F726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000468026400036377646B00202F636C656172636173652F6F74702F746F6F6C732F776562746F6F6C2F73726368026400066F75746469726B00282F636C656172636173652F6F74702F746F6F6C732F776562746F6F6C2F7372632F2E2E2F6562696E64000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461066108610761236802640006736F757263656B00302F636C656172636173652F6F74702F746F6F6C732F776562746F6F6C2F7372632F776562746F6F6C5F7375702E65726C6A +=mod:httpd_conf +Current size: 33659 +Current attributes: 836C00000002680264000376736E6C000000016E1000E3198FBDC73BC48CB7D0C1C762B8F1AB6A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861116802640006736F757263656B00312F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F636F6E662E65726C6A +=mod:regexp +Current size: 13698 +Current attributes: 836C00000001680264000376736E6C000000016E10009DD44F3D02F8328BE3ABF4DDA89E0CAE6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61376802640006736F757263656B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F7265676578702E65726C6A +=mod:string +Current size: 7740 +Current attributes: 836C00000002680264000376736E6C000000016E10005521DDF38903D46D7C53DB864266F7456A680264000A646570726563617465646C00000007680264000C72655F73685F746F5F61776B6101680264000872655F70617273656101680264000872655F6D617463686102680264000672655F7375626103680264000772655F677375626103680264000872655F73706C697461026802640005696E64657861026A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612F610F6802640006736F757263656B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F737472696E672E65726C6A +=mod:httpd +Current size: 7563 +Current attributes: 836C00000002680264000376736E6C000000016E1000BFD190D951EB3CAD2CC72ADEF20886906A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861036802640006736F757263656B002C2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470642E65726C6A +=mod:httpd_sup +Current size: 4068 +Current attributes: 836C00000003680264000376736E6C000000016E10007FA5C790118F18F3D20A2BFAF0229F0A6A68026400076170705F76736E6B000B696E6574732D332E302E3768026400096265686176696F75726C0000000164000A73757065727669736F726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861366802640006736F757263656B00302F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F7375702E65726C6A +=mod:httpd_acceptor_sup +Current size: 2161 +Current attributes: 836C00000003680264000376736E6C000000016E10003E6F9289B64C13F1EC8A1184BACF055F6A68026400076170705F76736E6B000B696E6574732D332E302E3768026400096265686176696F75726C0000000164000A73757065727669736F726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104611561066128610C6802640006736F757263656B00392F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F6163636570746F725F7375702E65726C6A +=mod:httpd_verbosity +Current size: 2672 +Current attributes: 836C00000002680264000376736E6C000000016E100018B6F407D391872421748F87877DAAF36A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612961036802640006736F757263656B00362F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F766572626F736974792E65726C6A +=mod:timer +Current size: 8223 +Current attributes: 836C00000001680264000376736E6C000000016E10001D0D64DB1B923D1B3B9497655C43B4AD6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612F611A6802640006736F757263656B002C2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F74696D65722E65726C6A +=mod:httpd_misc_sup +Current size: 2066 +Current attributes: 836C00000003680264000376736E6C000000016E100092342F38AC16C074DDC21532FBFB52C26A68026400076170705F76736E6B000B696E6574732D332E302E3768026400096265686176696F75726C0000000164000A73757065727669736F726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104611561066128611F6802640006736F757263656B00352F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F6D6973635F7375702E65726C6A +=mod:httpd_manager +Current size: 28916 +Current attributes: 836C00000003680264000376736E6C000000016E100013F7A1E6A4B6407A0A1892A794EE10A36A68026400076170705F76736E6B000B696E6574732D332E302E3768026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104611561066128611B6802640006736F757263656B00342F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F6D616E616765722E65726C6A +=mod:mod_alias +Current size: 6720 +Current attributes: 836C00000002680264000376736E6C000000016E10002F35C36060B4AC45474440381D146AB96A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612961106802640006736F757263656B00302F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F616C6961732E65726C6A +=mod:mod_auth +Current size: 25168 +Current attributes: 836C00000002680264000376736E6C000000016E100083F3CA0C7A3E7B5E19A635A7F916595D6A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612961166802640006736F757263656B002F2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F617574682E65726C6A +=mod:mod_esi +Current size: 22534 +Current attributes: 836C00000002680264000376736E6C000000016E1000513E3FF733E1E6592B86CB55B9C14E086A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612A61026802640006736F757263656B002E2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F6573692E65726C6A +=mod:mod_actions +Current size: 3625 +Current attributes: 836C00000002680264000376736E6C000000016E10008E5437921662830490CA76DFF88548966A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104611561066129610C6802640006736F757263656B00322F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F616374696F6E732E65726C6A +=mod:mod_cgi +Current size: 25891 +Current attributes: 836C00000002680264000376736E6C000000016E1000F91D405488188F1BD25110B4ED9EE8786A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612961306802640006736F757263656B002E2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F6367692E65726C6A +=mod:mod_include +Current size: 34923 +Current attributes: 836C00000002680264000376736E6C000000016E1000B9CCE88D63DD6AC49D5DF533C46B97D56A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612A61176802640006736F757263656B00322F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F696E636C7564652E65726C6A +=mod:mod_dir +Current size: 13488 +Current attributes: 836C00000002680264000376736E6C000000016E1000EF620CB4B5DE5586ED681347496DA1C86A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612961356802640006736F757263656B002E2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F6469722E65726C6A +=mod:mod_get +Current size: 4672 +Current attributes: 836C00000002680264000376736E6C000000016E1000AD2730B6BE6AF875A500AF4857C4D7F86A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612A61076802640006736F757263656B002E2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F6765742E65726C6A +=mod:mod_head +Current size: 3074 +Current attributes: 836C00000002680264000376736E6C000000016E1000CAF803B9FA6A28D4153BC109B00D7DF96A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612A610B6802640006736F757263656B002F2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F686561642E65726C6A +=mod:mod_log +Current size: 8546 +Current attributes: 836C00000002680264000376736E6C000000016E1000F9664B54861260DEA081249379219AF86A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612A611B6802640006736F757263656B002E2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F6C6F672E65726C6A +=mod:mod_disk_log +Current size: 15160 +Current attributes: 836C00000002680264000376736E6C000000016E1000DDA1E88A9C423A2866B56425DF36F5C66A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612961396802640006736F757263656B00332F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F6469736B5F6C6F672E65726C6A +=mod:httpd_socket +Current size: 7426 +Current attributes: 836C00000002680264000376736E6C000000016E1000B831219096661E4D2E200A07C4A9A7776A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861326802640006736F757263656B00332F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F736F636B65742E65726C6A +=mod:httpd_acceptor +Current size: 4472 +Current attributes: 836C00000002680264000376736E6C000000016E1000A501686DF4E4053E7D978E0CA162BEC56A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861076802640006736F757263656B00352F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F6163636570746F722E65726C6A +=mod:io_lib_pretty +Current size: 8171 +Current attributes: 836C00000001680264000376736E6C000000016E1000CD397E11D2D380D02A4BC6EE309B98CB6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E610C6802640006736F757263656B00342F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F696F5F6C69625F7072657474792E65726C6A +=mod:httpd_request_handler +Current size: 26393 +Current attributes: 836C00000002680264000376736E6C000000016E100021C280A5EB5B9CCD00A2C418A341202A6A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861296802640006736F757263656B003C2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F726571756573745F68616E646C65722E65726C6A +=mod:calendar +Current size: 7158 +Current attributes: 836C00000002680264000376736E6C000000016E10008C44498546709037F8D72DA4AF8B7FB76A680264000A646570726563617465646C00000001680264001C6C6F63616C5F74696D655F746F5F756E6976657273616C5F74696D6561016A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612B61166802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F63616C656E6461722E65726C6A +=mod:httpd_parse +Current size: 9977 +Current attributes: 836C00000002680264000376736E6C000000016E1000174653BAA652261FEB44FFDED99E50B76A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861246802640006736F757263656B00322F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F70617273652E65726C6A +=mod:httpd_response +Current size: 13535 +Current attributes: 836C00000002680264000376736E6C000000016E1000785B247D894BA08A40D814EF11F848976A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104611561066128612D6802640006736F757263656B00352F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F726573706F6E73652E65726C6A +=mod:crashdump_viewer_html +Current size: 68343 +Current attributes: 836C00000001680264000376736E6C000000016E1000AE414770FDB0806C5583FF8D6D71DC766A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00212F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F73726368026400066F75746469726B00292F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F6562696E6802640001696B002C2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F696E636C7564656802640001696B00322F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F2E2E2F65742F696E636C7564656802640001696B003F2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F2E2E2F2E2E2F6C69627261726965732F65742F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461146108611C61026802640006736F757263656B003B2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F637261736864756D705F7669657765725F68746D6C2E65726C6A +=mod:crashdump_translate +Current size: 89840 +Current attributes: 836C00000001680264000376736E6C000000016E100038F332287181E933A76CEF4799BDB6416A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000668026400036377646B00212F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F73726368026400066F75746469726B00292F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F6562696E6802640001696B002C2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F696E636C7564656802640001696B00322F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F2E2E2F65742F696E636C7564656802640001696B003F2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F2E2E2F2E2E2F6C69627261726965732F65742F696E636C75646564000A64656275675F696E666F6A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D461046115610B611661106802640006736F757263656B00392F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F637261736864756D705F7472616E736C6174652E65726C6A +=fun +Module: crashdump_viewer_html +Uniq: 9122590 +Index: 0 +Address: 526308 +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 77168418 +Index: 14 +Address: 26541c +Native_address: bcf04 +Refc: 1 +=fun +Module: inet_parse +Uniq: 88083515 +Index: 9 +Address: 284c30 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 36747896 +Index: 4 +Address: 26df84 +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 80395734 +Index: 8 +Address: 265838 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 103184573 +Index: 5 +Address: 2fa59c +Native_address: bce80 +Refc: 1 +=fun +Module: erl_lint +Uniq: 88265811 +Index: 24 +Address: 34f6a0 +Native_address: bcefc +Refc: 1 +=fun +Module: global_group +Uniq: 9644262 +Index: 2 +Address: 292cec +Native_address: bcef4 +Refc: 1 +=fun +Module: net_kernel +Uniq: 100885585 +Index: 0 +Address: 29eb2c +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 128335479 +Index: 6 +Address: 26de84 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_prim_loader +Uniq: 42988083 +Index: 1 +Address: 210c14 +Native_address: bcf04 +Refc: 1 +=fun +Module: dict +Uniq: 7105125 +Index: 7 +Address: 354f84 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 29030584 +Index: 8 +Address: 234978 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 29214351 +Index: 2 +Address: 285660 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_config +Uniq: 5158633 +Index: 4 +Address: 274034 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 74624950 +Index: 25 +Address: 34f63c +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 6477018 +Index: 3 +Address: 2adb6c +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 117885138 +Index: 7 +Address: 2ffff8 +Native_address: bcefc +Refc: 1 +=fun +Module: dict +Uniq: 47566924 +Index: 6 +Address: 354fb8 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 114637756 +Index: 12 +Address: 313c60 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 121316204 +Index: 31 +Address: 313a68 +Native_address: bced4 +Refc: 1 +=fun +Module: code_server +Uniq: 61363639 +Index: 12 +Address: 2ad6a4 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_config +Uniq: 116208699 +Index: 3 +Address: 274094 +Native_address: bcefc +Refc: 1 +=fun +Module: global_group +Uniq: 113750737 +Index: 0 +Address: 292d54 +Native_address: bcefc +Refc: 1 +=fun +Module: gen_event +Uniq: 12853672 +Index: 0 +Address: 222e74 +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 108046357 +Index: 12 +Address: 4ab0b0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 111569299 +Index: 47 +Address: 34e80c +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 20108653 +Index: 15 +Address: 2f9f94 +Native_address: bcea4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 45252965 +Index: 15 +Address: 313c0c +Native_address: bced4 +Refc: 1 +=fun +Module: webtool +Uniq: 12437425 +Index: 9 +Address: 4ab3e0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 30942993 +Index: 22 +Address: 34f6ec +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_parse +Uniq: 93430337 +Index: 3 +Address: 33b100 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_parse +Uniq: 6604883 +Index: 2 +Address: 33b16c +Native_address: bcefc +Refc: 1 +=fun +Module: rpc +Uniq: 36867745 +Index: 5 +Address: 255e28 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 90563105 +Index: 1 +Address: 285708 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 18519297 +Index: 7 +Address: 26ddfc +Native_address: bcef4 +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 8058975 +Index: 16 +Address: 4a36b4 +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 30694569 +Index: 7 +Address: 27d018 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_config +Uniq: 76933943 +Index: 0 +Address: 2741b4 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 9033258 +Index: 6 +Address: 4a4690 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 74851752 +Index: 5 +Address: 4a4798 +Native_address: bcef4 +Refc: 1 +=fun +Module: global +Uniq: 50855382 +Index: 4 +Address: 2659a8 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 39211582 +Index: 52 +Address: 34e504 +Native_address: bceec +Refc: 1 +=fun +Module: file_server +Uniq: 77665472 +Index: 0 +Address: 2a0dec +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_eval +Uniq: 57487277 +Index: 8 +Address: 2fa3c4 +Native_address: bce94 +Refc: 1 +=fun +Module: webtool +Uniq: 87386575 +Index: 11 +Address: 4ab1c8 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 58991950 +Index: 8 +Address: 4a4338 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 118859163 +Index: 17 +Address: 4a34d4 +Native_address: bcefc +Refc: 1 +=fun +Module: dict +Uniq: 38265609 +Index: 12 +Address: 354dec +Native_address: bcefc +Refc: 1 +=fun +Module: supervisor +Uniq: 56903339 +Index: 1 +Address: 2527c4 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_hosts +Uniq: 129504763 +Index: 0 +Address: 28aae8 +Native_address: bcefc +Refc: 1 +=fun +Module: dict +Uniq: 44817307 +Index: 10 +Address: 354e3c +Native_address: bceec +Refc: 1 +=fun +Module: erl_lint +Uniq: 52856894 +Index: 41 +Address: 34eb70 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 22623360 +Index: 23 +Address: 34f5d4 +Native_address: bceec +Refc: 1 +=fun +Module: orddict +Uniq: 34963136 +Index: 0 +Address: 2fbbbc +Native_address: bcef4 +Refc: 1 +=fun +Module: erlang +Uniq: 24496633 +Index: 0 +Address: 213744 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 99313855 +Index: 27 +Address: 2f9914 +Native_address: bcef4 +Refc: 1 +=fun +Module: httpd_util +Uniq: 99137703 +Index: 3 +Address: 4b5dfc +Native_address: bcefc +Refc: 1 +=fun +Module: gen_event +Uniq: 124043500 +Index: 3 +Address: 222b84 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 102650878 +Index: 22 +Address: 313b48 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 13333720 +Index: 12 +Address: 34fb2c +Native_address: bcef4 +Refc: 1 +=fun +Module: global_group +Uniq: 133457 +Index: 5 +Address: 292a80 +Native_address: bcefc +Refc: 1 +=fun +Module: net_kernel +Uniq: 64640983 +Index: 4 +Address: 29e944 +Native_address: bcefc +Refc: 1 +=fun +Module: rpc +Uniq: 7580218 +Index: 2 +Address: 255f08 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_lint +Uniq: 131850870 +Index: 59 +Address: 34e6b8 +Native_address: bcef4 +Refc: 1 +=fun +Module: inet_parse +Uniq: 56617403 +Index: 10 +Address: 284b40 +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 108680306 +Index: 4 +Address: 4ab5e0 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 90880071 +Index: 2 +Address: 26e150 +Native_address: bcefc +Refc: 1 +=fun +Module: file_io_server +Uniq: 23980778 +Index: 0 +Address: 30ac30 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_eval +Uniq: 12006418 +Index: 19 +Address: 2f9d54 +Native_address: bce80 +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 81701030 +Index: 8 +Address: 526228 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 71013875 +Index: 1 +Address: 4a4ddc +Native_address: bcf04 +Refc: 1 +=fun +Module: distel +Uniq: 87740845 +Index: 2 +Address: 35c0e0 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_eval +Uniq: 90782401 +Index: 17 +Address: 2f9e8c +Native_address: bced4 +Refc: 1 +=fun +Module: shell +Uniq: 133882676 +Index: 6 +Address: 2e52ac +Native_address: bcef4 +Refc: 1 +=fun +Module: inet_parse +Uniq: 105698088 +Index: 3 +Address: 2855b4 +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 58370899 +Index: 0 +Address: 27d370 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 15274536 +Index: 25 +Address: 2f9a94 +Native_address: bcef4 +Refc: 1 +=fun +Module: supervisor +Uniq: 94349557 +Index: 0 +Address: 252844 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_parse +Uniq: 33328185 +Index: 1 +Address: 33b1d8 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 86971387 +Index: 16 +Address: 313db0 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 53364473 +Index: 38 +Address: 34ee84 +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 128145687 +Index: 0 +Address: 4ab944 +Native_address: bcee4 +Refc: 1 +=fun +Module: c +Uniq: 98651404 +Index: 10 +Address: 2fff20 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 78224618 +Index: 0 +Address: 313dcc +Native_address: bced4 +Refc: 1 +=fun +Module: shell +Uniq: 40779085 +Index: 11 +Address: 2e50c8 +Native_address: bcef4 +Refc: 1 +=fun +Module: c +Uniq: 93517350 +Index: 4 +Address: 300090 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 58551291 +Index: 0 +Address: 234f14 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 10055518 +Index: 17 +Address: 526170 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 15795706 +Index: 19 +Address: 313bd4 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 31129467 +Index: 13 +Address: 313c44 +Native_address: bced4 +Refc: 1 +=fun +Module: old_file_server +Uniq: 115635393 +Index: 0 +Address: 2a1a4c +Native_address: bcf04 +Refc: 2 +=fun +Module: erl_eval +Uniq: 65839696 +Index: 22 +Address: 2f9c00 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 69275064 +Index: 28 +Address: 313aa0 +Native_address: bced4 +Refc: 1 +=fun +Module: dict +Uniq: 55938066 +Index: 11 +Address: 354d6c +Native_address: bceec +Refc: 1 +=fun +Module: supervisor +Uniq: 22323433 +Index: 3 +Address: 252688 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 129726129 +Index: 29 +Address: 313abc +Native_address: bced4 +Refc: 1 +=fun +Module: dict +Uniq: 84346832 +Index: 0 +Address: 3550fc +Native_address: bceec +Refc: 1 +=fun +Module: shell +Uniq: 102096820 +Index: 7 +Address: 2e5290 +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 70385762 +Index: 11 +Address: 27cf44 +Native_address: bcefc +Refc: 1 +=fun +Module: mod_cgi +Uniq: 1483038 +Index: 0 +Address: 4ec2e8 +Native_address: bcefc +Refc: 1 +=fun +Module: dict +Uniq: 3664813 +Index: 1 +Address: 3550b4 +Native_address: bcef4 +Refc: 1 +=fun +Module: inet +Uniq: 131143671 +Index: 6 +Address: 27d08c +Native_address: bcef4 +Refc: 1 +=fun +Module: inet_config +Uniq: 46286977 +Index: 2 +Address: 2740b0 +Native_address: bcefc +Refc: 1 +=fun +Module: mod_esi +Uniq: 49099432 +Index: 0 +Address: 4e522c +Native_address: bcefc +Refc: 1 +=fun +Module: application_master +Uniq: 95764905 +Index: 2 +Address: 24aaa8 +Native_address: bcefc +Refc: 1 +=fun +Module: packages +Uniq: 62890926 +Index: 0 +Address: 2ae814 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 41564771 +Index: 35 +Address: 3139f8 +Native_address: bced4 +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 95490768 +Index: 0 +Address: 4a4dc0 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_scan +Uniq: 121559432 +Index: 3 +Address: 313d78 +Native_address: bced4 +Refc: 1 +=fun +Module: httpd_conf +Uniq: 21152662 +Index: 0 +Address: 4be5a0 +Native_address: bcefc +Refc: 1 +=fun +Module: net_kernel +Uniq: 41630916 +Index: 5 +Address: 29e914 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 19747201 +Index: 5 +Address: 313d24 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 100584837 +Index: 36 +Address: 34f0f4 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 64635712 +Index: 15 +Address: 34f94c +Native_address: bcef4 +Refc: 1 +=fun +Module: net_kernel +Uniq: 46398361 +Index: 3 +Address: 29e9a4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 86699817 +Index: 27 +Address: 313b2c +Native_address: bced4 +Refc: 1 +=fun +Module: distel +Uniq: 40869731 +Index: 0 +Address: 35c12c +Native_address: bcf04 +Refc: 1 +=fun +Module: inet +Uniq: 83701641 +Index: 1 +Address: 27d33c +Native_address: bcefc +Refc: 1 +=fun +Module: mod_auth +Uniq: 85845790 +Index: 0 +Address: 4dfd84 +Native_address: bcefc +Refc: 1 +=fun +Module: shell +Uniq: 101292714 +Index: 9 +Address: 2e519c +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 134173702 +Index: 1 +Address: 265b68 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 92433687 +Index: 6 +Address: 2ad9f4 +Native_address: bcef4 +Refc: 1 +=fun +Module: dict +Uniq: 62315241 +Index: 8 +Address: 354f38 +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 11615541 +Index: 12 +Address: 265530 +Native_address: bcefc +Refc: 1 +=fun +Module: hipe_unified_loader +Uniq: 11160090 +Index: 2 +Address: 2b6bb4 +Native_address: bcef4 +Refc: 1 +=fun +Module: application_controller +Uniq: 12116524 +Index: 15 +Address: 2342c4 +Native_address: bcef4 +Refc: 1 +=fun +Module: mod_log +Uniq: 61620901 +Index: 2 +Address: 4fc670 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 23665189 +Index: 12 +Address: 4a3b94 +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 43844413 +Index: 0 +Address: 300100 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 100514258 +Index: 6 +Address: 313d08 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 54271286 +Index: 17 +Address: 34f8a0 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 47017252 +Index: 3 +Address: 26dfa0 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 1228304 +Index: 7 +Address: 4a45a4 +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 127131470 +Index: 10 +Address: 2655a0 +Native_address: bcefc +Refc: 1 +=fun +Module: file_server +Uniq: 22638227 +Index: 1 +Address: 2a0e20 +Native_address: bcf04 +Refc: 1 +=fun +Module: code_server +Uniq: 112704920 +Index: 15 +Address: 2ad488 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 88302875 +Index: 2 +Address: 2fa76c +Native_address: bceb4 +Refc: 1 +=fun +Module: inet_hosts +Uniq: 85808984 +Index: 1 +Address: 28ab18 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_parse +Uniq: 106391799 +Index: 0 +Address: 33b22c +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 25830519 +Index: 5 +Address: 27d0c0 +Native_address: bcefc +Refc: 1 +=fun +Module: shell +Uniq: 110491036 +Index: 1 +Address: 2e5398 +Native_address: bcef4 +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 13128736 +Index: 5 +Address: 52627c +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 84644982 +Index: 21 +Address: 313b9c +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 120577486 +Index: 3 +Address: 34fffc +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 4504456 +Index: 44 +Address: 34e938 +Native_address: bceec +Refc: 1 +=fun +Module: mod_disk_log +Uniq: 28754183 +Index: 0 +Address: 500140 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 88043334 +Index: 14 +Address: 313c28 +Native_address: bced4 +Refc: 1 +=fun +Module: code_server +Uniq: 61592373 +Index: 0 +Address: 2adc28 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_scan +Uniq: 74468346 +Index: 26 +Address: 313ad8 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 69896253 +Index: 21 +Address: 2f9c40 +Native_address: bce80 +Refc: 1 +=fun +Module: global_group +Uniq: 59656873 +Index: 4 +Address: 292ac0 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 103891261 +Index: 2 +Address: 4a4d70 +Native_address: bcefc +Refc: 1 +=fun +Module: httpd_util +Uniq: 89619733 +Index: 0 +Address: 4b5e64 +Native_address: bcefc +Refc: 1 +=fun +Module: shell +Uniq: 133201466 +Index: 10 +Address: 2e5180 +Native_address: bceec +Refc: 1 +=fun +Module: webtool +Uniq: 32159369 +Index: 2 +Address: 4ab820 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 76861396 +Index: 2 +Address: 2adbb0 +Native_address: bcefc +Refc: 1 +=fun +Module: mod_log +Uniq: 48206487 +Index: 0 +Address: 4fc6f0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 118996551 +Index: 28 +Address: 34f384 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 12593774 +Index: 50 +Address: 34e60c +Native_address: bcef4 +Refc: 1 +=fun +Module: httpd_request_handler +Uniq: 48542841 +Index: 1 +Address: 50e88c +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 56178490 +Index: 9 +Address: 4a420c +Native_address: bcefc +Refc: 1 +=fun +Module: distel +Uniq: 88212576 +Index: 4 +Address: 35bf44 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 79562132 +Index: 29 +Address: 34f368 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 129524917 +Index: 32 +Address: 34f2c0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 54029891 +Index: 23 +Address: 2f9af0 +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 108872092 +Index: 4 +Address: 27d0f0 +Native_address: bcef4 +Refc: 1 +=fun +Module: application_controller +Uniq: 40905124 +Index: 6 +Address: 234ac0 +Native_address: bcef4 +Refc: 1 +=fun +Module: code_server +Uniq: 50124876 +Index: 10 +Address: 2ad760 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 791358 +Index: 48 +Address: 34e7b0 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 18404828 +Index: 24 +Address: 313af4 +Native_address: bced4 +Refc: 1 +=fun +Module: httpd_util +Uniq: 13278653 +Index: 1 +Address: 4b5e48 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 110307423 +Index: 13 +Address: 284a7c +Native_address: bcefc +Refc: 1 +=fun +Module: rpc +Uniq: 99592247 +Index: 0 +Address: 256118 +Native_address: bcf04 +Refc: 1 +=fun +Module: global +Uniq: 99918211 +Index: 2 +Address: 265af4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 71442319 +Index: 27 +Address: 34f510 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 7612785 +Index: 13 +Address: 2fa0fc +Native_address: bce80 +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 56095795 +Index: 15 +Address: 4a38a0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 23626796 +Index: 25 +Address: 313b10 +Native_address: bced4 +Refc: 1 +=fun +Module: file_server +Uniq: 126074974 +Index: 2 +Address: 2a0cac +Native_address: bcef4 +Refc: 1 +=fun +Module: inet_config +Uniq: 104278122 +Index: 1 +Address: 274154 +Native_address: bcefc +Refc: 1 +=fun +Module: sys +Uniq: 90854051 +Index: 0 +Address: 240344 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 113334594 +Index: 2 +Address: 313d5c +Native_address: bced4 +Refc: 1 +=fun +Module: inet_parse +Uniq: 8832142 +Index: 7 +Address: 284e30 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 9159706 +Index: 42 +Address: 34eb54 +Native_address: bceec +Refc: 1 +=fun +Module: inet_db +Uniq: 123946665 +Index: 8 +Address: 26e494 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 3149789 +Index: 1 +Address: 5262d0 +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 48288621 +Index: 11 +Address: 2ffed8 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 8953292 +Index: 20 +Address: 4a4d54 +Native_address: bcee4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 9632158 +Index: 4 +Address: 34ff88 +Native_address: bcefc +Refc: 1 +=fun +Module: net_kernel +Uniq: 31111567 +Index: 7 +Address: 29e8c8 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 85307443 +Index: 10 +Address: 2fa29c +Native_address: bcec4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 104417191 +Index: 7 +Address: 313cd0 +Native_address: bced4 +Refc: 1 +=fun +Module: dict +Uniq: 43625777 +Index: 5 +Address: 354fec +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 92698798 +Index: 3 +Address: 4ab780 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 39074546 +Index: 6 +Address: 2fa54c +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 71451126 +Index: 5 +Address: 234b98 +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 122084387 +Index: 6 +Address: 300038 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 9625924 +Index: 14 +Address: 284a60 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 128777368 +Index: 11 +Address: 313c7c +Native_address: bced4 +Refc: 1 +=fun +Module: webtool +Uniq: 10203723 +Index: 7 +Address: 4ab4f8 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 35032400 +Index: 10 +Address: 313c98 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 17252586 +Index: 34 +Address: 313a14 +Native_address: bced4 +Refc: 1 +=fun +Module: code_server +Uniq: 7177165 +Index: 11 +Address: 2ad734 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 115778175 +Index: 3 +Address: 4a4930 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 96440880 +Index: 51 +Address: 34e590 +Native_address: bcefc +Refc: 1 +=fun +Module: hipe_unified_loader +Uniq: 68275407 +Index: 0 +Address: 2b7340 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 88854488 +Index: 16 +Address: 2f9f04 +Native_address: bcebc +Refc: 1 +=fun +Module: global +Uniq: 26353848 +Index: 13 +Address: 2654e8 +Native_address: bcf04 +Refc: 3 +=fun +Module: global +Uniq: 93414722 +Index: 11 +Address: 265568 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 11194189 +Index: 60 +Address: 34fe0c +Native_address: bcef4 +Refc: 1 +=fun +Module: c +Uniq: 125189992 +Index: 8 +Address: 2fffdc +Native_address: bcefc +Refc: 1 +=fun +Module: dict +Uniq: 112472016 +Index: 2 +Address: 355088 +Native_address: bceec +Refc: 1 +=fun +Module: shell +Uniq: 104426442 +Index: 5 +Address: 2e52e0 +Native_address: bceec +Refc: 1 +=fun +Module: global +Uniq: 17426458 +Index: 0 +Address: 265bc4 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 81191039 +Index: 5 +Address: 2ada48 +Native_address: bcef4 +Refc: 1 +=fun +Module: inet_parse +Uniq: 71765042 +Index: 5 +Address: 284f74 +Native_address: bcefc +Refc: 1 +=fun +Module: init +Uniq: 85855821 +Index: 2 +Address: 1fa298 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 70586122 +Index: 10 +Address: 4a3fe4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 87067911 +Index: 49 +Address: 34e708 +Native_address: bcef4 +Refc: 1 +=fun +Module: distel +Uniq: 63126735 +Index: 1 +Address: 35c0fc +Native_address: bcf04 +Refc: 1 +=fun +Module: c +Uniq: 58270309 +Index: 1 +Address: 3000e4 +Native_address: bcefc +Refc: 1 +=fun +Module: ets +Uniq: 80538457 +Index: 1 +Address: 2bc1a0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 69827241 +Index: 9 +Address: 34fd70 +Native_address: bcef4 +Refc: 1 +=fun +Module: dict +Uniq: 103968752 +Index: 3 +Address: 355054 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 117175573 +Index: 21 +Address: 34f728 +Native_address: bcef4 +Refc: 1 +=fun +Module: shell +Uniq: 57865450 +Index: 2 +Address: 2e537c +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 14705965 +Index: 20 +Address: 313b80 +Native_address: bced4 +Refc: 1 +=fun +Module: webtool +Uniq: 85360931 +Index: 6 +Address: 4ab56c +Native_address: bcefc +Refc: 1 +=fun +Module: kernel_config +Uniq: 41755598 +Index: 0 +Address: 2d9e20 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 7110547 +Index: 37 +Address: 34ef14 +Native_address: bcef4 +Refc: 1 +=fun +Module: application_controller +Uniq: 28091577 +Index: 16 +Address: 234244 +Native_address: bcef4 +Refc: 2 +=fun +Module: code_server +Uniq: 96448152 +Index: 14 +Address: 2ad4e4 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 40177568 +Index: 13 +Address: 4a39a4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 31948320 +Index: 58 +Address: 34dfdc +Native_address: bcef4 +Refc: 1 +=fun +Module: global +Uniq: 54153760 +Index: 7 +Address: 265854 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 60156260 +Index: 3 +Address: 5262b4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 1010616 +Index: 2 +Address: 350064 +Native_address: bcef4 +Refc: 1 +=fun +Module: init +Uniq: 96784459 +Index: 1 +Address: 1fa2b4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 48691771 +Index: 18 +Address: 313bb8 +Native_address: bced4 +Refc: 1 +=fun +Module: global +Uniq: 26895060 +Index: 9 +Address: 265710 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 109625093 +Index: 7 +Address: 2ad8fc +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 59436171 +Index: 1 +Address: 3500dc +Native_address: bcef4 +Refc: 1 +=fun +Module: dict +Uniq: 92768306 +Index: 9 +Address: 354f04 +Native_address: bcefc +Refc: 1 +=fun +Module: global_group +Uniq: 106430008 +Index: 3 +Address: 292b38 +Native_address: bcefc +Refc: 1 +=fun +Module: init +Uniq: 79749196 +Index: 6 +Address: 1fa01c +Native_address: bceec +Refc: 1 +=fun +Module: erl_eval +Uniq: 6014929 +Index: 9 +Address: 2fa324 +Native_address: bceac +Refc: 1 +=fun +Module: application_controller +Uniq: 57051922 +Index: 7 +Address: 234a28 +Native_address: bcef4 +Refc: 1 +=fun +Module: net_kernel +Uniq: 77043468 +Index: 6 +Address: 29e8e4 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 36176045 +Index: 9 +Address: 52620c +Native_address: bcefc +Refc: 1 +=fun +Module: rpc +Uniq: 35862809 +Index: 3 +Address: 255edc +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 113649451 +Index: 4 +Address: 2850a0 +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 67943969 +Index: 5 +Address: 2658f4 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 109003032 +Index: 16 +Address: 5260d0 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 104711447 +Index: 13 +Address: 525f5c +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 107666872 +Index: 9 +Address: 27cfb0 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 89410000 +Index: 10 +Address: 5261f0 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 47356870 +Index: 11 +Address: 284ab4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 17873449 +Index: 56 +Address: 34e1e8 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 8839441 +Index: 33 +Address: 34f25c +Native_address: bcefc +Refc: 1 +=fun +Module: gen_event +Uniq: 82513204 +Index: 2 +Address: 222c18 +Native_address: bcefc +Refc: 1 +=fun +Module: application_master +Uniq: 5973059 +Index: 0 +Address: 24ab7c +Native_address: bcefc +Refc: 1 +=fun +Module: inet_gethost_native +Uniq: 127832132 +Index: 0 +Address: 4b065c +Native_address: bcefc +Refc: 2 +=fun +Module: crashdump_viewer_html +Uniq: 39322658 +Index: 14 +Address: 525f40 +Native_address: bcefc +Refc: 1 +=fun +Module: gen_server +Uniq: 100284021 +Index: 0 +Address: 23d288 +Native_address: bcf04 +Refc: 1 +=fun +Module: inet_parse +Uniq: 17430070 +Index: 12 +Address: 284a98 +Native_address: bcefc +Refc: 1 +=fun +Module: init +Uniq: 97509773 +Index: 3 +Address: 1fa27c +Native_address: bcefc +Refc: 1 +=fun +Module: distel +Uniq: 32364818 +Index: 3 +Address: 35c050 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 58576084 +Index: 32 +Address: 313a4c +Native_address: bced4 +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 38384851 +Index: 14 +Address: 4a3988 +Native_address: bceec +Refc: 1 +=fun +Module: application_controller +Uniq: 14139883 +Index: 4 +Address: 234d78 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 122590256 +Index: 0 +Address: 2fa8b4 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 14705629 +Index: 11 +Address: 2fa22c +Native_address: bcedc +Refc: 1 +=fun +Module: erl_eval +Uniq: 9273769 +Index: 4 +Address: 2fa684 +Native_address: bcee4 +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 87950142 +Index: 11 +Address: 5261d4 +Native_address: bcefc +Refc: 1 +=fun +Module: mod_log +Uniq: 54913678 +Index: 1 +Address: 4fc6b0 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 28370334 +Index: 0 +Address: 26e4b0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 24927227 +Index: 40 +Address: 34ed4c +Native_address: bceec +Refc: 1 +=fun +Module: erl_scan +Uniq: 105437500 +Index: 33 +Address: 313a30 +Native_address: bced4 +Refc: 1 +=fun +Module: application_controller +Uniq: 10921695 +Index: 1 +Address: 234eac +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 112431564 +Index: 55 +Address: 34e22c +Native_address: bceec +Refc: 1 +=fun +Module: webtool +Uniq: 129460863 +Index: 5 +Address: 4ab5c4 +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 89001648 +Index: 3 +Address: 27d2ec +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 36199507 +Index: 8 +Address: 27cfe4 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 35620771 +Index: 2 +Address: 5262ec +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 83214871 +Index: 18 +Address: 2f9e34 +Native_address: bceec +Refc: 1 +=fun +Module: code_server +Uniq: 122455383 +Index: 1 +Address: 2adc0c +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_lint +Uniq: 22389488 +Index: 31 +Address: 34f1b8 +Native_address: bceec +Refc: 1 +=fun +Module: erl_eval +Uniq: 41869059 +Index: 12 +Address: 2fa1d4 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 18130505 +Index: 45 +Address: 34e904 +Native_address: bcefc +Refc: 1 +=fun +Module: hipe_unified_loader +Uniq: 107414126 +Index: 1 +Address: 2b706c +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 116638945 +Index: 28 +Address: 2f98f8 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 48465762 +Index: 9 +Address: 2348c8 +Native_address: bcefc +Refc: 1 +=fun +Module: httpd_request_handler +Uniq: 87633852 +Index: 0 +Address: 50e97c +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 28213098 +Index: 8 +Address: 4ab42c +Native_address: bcefc +Refc: 1 +=fun +Module: gen_event +Uniq: 123630574 +Index: 4 +Address: 222b58 +Native_address: bcefc +Refc: 1 +=fun +Module: dict +Uniq: 127425508 +Index: 13 +Address: 354eb4 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 95048118 +Index: 16 +Address: 2ad46c +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 108661978 +Index: 19 +Address: 34f75c +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 21272619 +Index: 13 +Address: 34fad8 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 29943747 +Index: 17 +Address: 313bf0 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 120240397 +Index: 4 +Address: 313d94 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 124060676 +Index: 0 +Address: 350124 +Native_address: bcef4 +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 100975346 +Index: 6 +Address: 526260 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 61421476 +Index: 4 +Address: 2ada9c +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 45197232 +Index: 7 +Address: 34fe5c +Native_address: bcef4 +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 3151900 +Index: 15 +Address: 525f24 +Native_address: bcefc +Refc: 1 +=fun +Module: httpd_util +Uniq: 77509245 +Index: 2 +Address: 4b5e2c +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 94110229 +Index: 8 +Address: 2ad7e4 +Native_address: bcef4 +Refc: 3 +=fun +Module: rpc +Uniq: 101217130 +Index: 1 +Address: 2560c4 +Native_address: bcf04 +Refc: 1 +=fun +Module: lists +Uniq: 103647452 +Index: 0 +Address: 244b7c +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 37841211 +Index: 9 +Address: 2ad77c +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 40109251 +Index: 54 +Address: 34e2b4 +Native_address: bcef4 +Refc: 1 +=fun +Module: init +Uniq: 98012300 +Index: 0 +Address: 1fa2d0 +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 73604759 +Index: 10 +Address: 4ab270 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 12042434 +Index: 1 +Address: 313d40 +Native_address: bced4 +Refc: 1 +=fun +Module: shell +Uniq: 127137775 +Index: 4 +Address: 2e531c +Native_address: bcf04 +Refc: 1 +=fun +Module: inet +Uniq: 45498037 +Index: 12 +Address: 27cec0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 122441107 +Index: 34 +Address: 34f1d4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 70933889 +Index: 46 +Address: 34e8d0 +Native_address: bcef4 +Refc: 1 +=fun +Module: inet +Uniq: 69850797 +Index: 2 +Address: 27d308 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 103965539 +Index: 13 +Address: 234684 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 29979659 +Index: 30 +Address: 313a84 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 17148721 +Index: 20 +Address: 34f778 +Native_address: bcefc +Refc: 1 +=fun +Module: httpd_response +Uniq: 100673049 +Index: 0 +Address: 5165dc +Native_address: bcefc +Refc: 1 +=fun +Module: inet_gethost_native +Uniq: 10508176 +Index: 1 +Address: 4b04dc +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 32476064 +Index: 57 +Address: 34e1c4 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 74835078 +Index: 9 +Address: 313cec +Native_address: bced4 +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 60689814 +Index: 19 +Address: 4a3b78 +Native_address: bceec +Refc: 1 +=fun +Module: erl_lint +Uniq: 39269715 +Index: 5 +Address: 34ff14 +Native_address: bcef4 +Refc: 1 +=fun +Module: shell +Uniq: 112923172 +Index: 0 +Address: 2e5404 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_eval +Uniq: 43010824 +Index: 14 +Address: 2fa03c +Native_address: bce8c +Refc: 1 +=fun +Module: global +Uniq: 82495254 +Index: 3 +Address: 265ac8 +Native_address: bcefc +Refc: 1 +=fun +Module: shell +Uniq: 48568081 +Index: 8 +Address: 2e5220 +Native_address: bcefc +Refc: 1 +=fun +Module: init +Uniq: 77236637 +Index: 7 +Address: 1fa000 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_eval +Uniq: 109386574 +Index: 1 +Address: 2fa804 +Native_address: bce9c +Refc: 1 +=fun +Module: erl_lint +Uniq: 42613220 +Index: 14 +Address: 34f980 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 67093144 +Index: 23 +Address: 313b64 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 86833790 +Index: 11 +Address: 34fbe8 +Native_address: bcefc +Refc: 1 +=fun +Module: net_kernel +Uniq: 6344855 +Index: 1 +Address: 29eabc +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 5149749 +Index: 35 +Address: 34f220 +Native_address: bcefc +Refc: 1 +=fun +Module: init +Uniq: 93451769 +Index: 5 +Address: 1fa120 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 117428568 +Index: 11 +Address: 234758 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 15225890 +Index: 4 +Address: 526298 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 120760477 +Index: 2 +Address: 234cdc +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 88561919 +Index: 3 +Address: 3000ac +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 108931174 +Index: 8 +Address: 313cb4 +Native_address: bced4 +Refc: 1 +=fun +Module: rpc +Uniq: 122901192 +Index: 4 +Address: 255e44 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_lint +Uniq: 32985930 +Index: 10 +Address: 34fc40 +Native_address: bcef4 +Refc: 1 +=fun +Module: global_group +Uniq: 97968498 +Index: 1 +Address: 292b7c +Native_address: bcef4 +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 45671671 +Index: 18 +Address: 4a32d0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 117968056 +Index: 3 +Address: 2fa6ec +Native_address: bcecc +Refc: 1 +=fun +Module: init +Uniq: 108717591 +Index: 4 +Address: 1fa194 +Native_address: bcf04 +Refc: 1 +=fun +Module: supervisor +Uniq: 15091954 +Index: 2 +Address: 2526dc +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 65707495 +Index: 6 +Address: 2658a4 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 34473969 +Index: 17 +Address: 2ad450 +Native_address: bcef4 +Refc: 2 +=fun +Module: crashdump_viewer_html +Uniq: 124296602 +Index: 7 +Address: 526244 +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 23074707 +Index: 15 +Address: 265460 +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 25972856 +Index: 10 +Address: 27cf74 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 43110452 +Index: 24 +Address: 2f9ad4 +Native_address: bceec +Refc: 1 +=fun +Module: code_server +Uniq: 106445918 +Index: 13 +Address: 2ad660 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 116071286 +Index: 12 +Address: 5261b8 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 130814477 +Index: 8 +Address: 284cfc +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 121017037 +Index: 39 +Address: 34ed80 +Native_address: bcef4 +Refc: 1 +=fun +Module: ets +Uniq: 104895267 +Index: 0 +Address: 2bc1bc +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 104682437 +Index: 11 +Address: 4a3de0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 70248777 +Index: 30 +Address: 34f30c +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 13274975 +Index: 5 +Address: 300074 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 98442771 +Index: 53 +Address: 34e2d0 +Native_address: bceec +Refc: 1 +=fun +Module: erl_eval +Uniq: 69829006 +Index: 7 +Address: 2fa47c +Native_address: bce80 +Refc: 1 +=fun +Module: old_file_server +Uniq: 36444943 +Index: 1 +Address: 2a1a80 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_lint +Uniq: 58719455 +Index: 26 +Address: 34f5f0 +Native_address: bcefc +Refc: 1 +=fun +Module: timer +Uniq: 42505885 +Index: 0 +Address: 4cd62c +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 54682479 +Index: 20 +Address: 2f9d08 +Native_address: bcf04 +Refc: 1 +=fun +Module: gen_event +Uniq: 86070332 +Index: 1 +Address: 222d7c +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 54728136 +Index: 9 +Address: 2fff68 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 16474219 +Index: 3 +Address: 234c60 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 108831556 +Index: 10 +Address: 234810 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 72053761 +Index: 16 +Address: 34f8ec +Native_address: bcef4 +Refc: 1 +=fun +Module: net_kernel +Uniq: 65127616 +Index: 2 +Address: 29ea04 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 126167637 +Index: 14 +Address: 234640 +Native_address: bcef4 +Refc: 1 +=fun +Module: inet_parse +Uniq: 113704917 +Index: 0 +Address: 285788 +Native_address: bcefc +Refc: 1 +=fun +Module: mod_disk_log +Uniq: 75279647 +Index: 1 +Address: 500100 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 119218247 +Index: 5 +Address: 26df68 +Native_address: bcef4 +Refc: 1 +=fun +Module: httpd_util +Uniq: 85690044 +Index: 4 +Address: 4b5d6c +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 53075592 +Index: 1 +Address: 26e16c +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 39490182 +Index: 2 +Address: 3000c8 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 75189006 +Index: 12 +Address: 234714 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 14980808 +Index: 43 +Address: 34eb38 +Native_address: bceec +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 16463468 +Index: 4 +Address: 4a4914 +Native_address: bcee4 +Refc: 1 +=fun +Module: dict +Uniq: 99965326 +Index: 4 +Address: 355020 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 36900786 +Index: 6 +Address: 284f3c +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 45447147 +Index: 18 +Address: 34f794 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 32353825 +Index: 6 +Address: 34fe78 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 134052338 +Index: 8 +Address: 34fdc0 +Native_address: bceec +Refc: 1 +=fun +Module: application_master +Uniq: 23840924 +Index: 1 +Address: 24aae0 +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 108282500 +Index: 1 +Address: 4ab918 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_prim_loader +Uniq: 31081110 +Index: 0 +Address: 210c68 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_eval +Uniq: 54275742 +Index: 26 +Address: 2f9a4c +Native_address: bcef4 +Refc: 1 +=fun +Module: shell +Uniq: 45083091 +Index: 3 +Address: 2e5350 +Native_address: bcf04 +Refc: 3 +=proc_stack:<0.0.0> +3a48bc:SReturn addr 0x156F90 (<terminate process normally>) +y0:H371264 +=proc_heap:<0.0.0> +371264:t9:A5:state,H3710D8,N,N,H3710F4,P<0.1.0>,H37128C,H3710FC,N +3710FC:t2:H371138,H371140 +371140:lI80|H371194 +371194:lI49|H3711E0 +3711E0:lI48|H371204 +371204:lI66|N +371138:lI79|H37118C +37118C:lI84|H3711D8 +3711D8:lI80|H3711FC +3711FC:lI32|H37120C +37120C:lI32|H371214 +371214:lI65|H37121C +37121C:lI80|H371224 +371224:lI78|H37122C +37122C:lI32|H371234 +371234:lI49|H37123C +37123C:lI56|H371244 +371244:lI49|H37124C +37124C:lI32|H371254 +371254:lI48|H37125C +37125C:lI49|N +37128C:t2:A7:started,A7:started +3710F4:lH371124|H371130 +371124:t2:A16:application_controller,P<0.5.0> +371130:lH371178|H371184 +371178:t2:AC:error_logger,P<0.4.0> +371184:lH3711CC|N +3711CC:t2:AF:erl_prim_loader,P<0.2.0> +3710D8:lH3710E0|H3710EC +3710E0:t2:A5:-root,H371108 +371108:lH371148|N +371148:Yh13:2F636C656172636173652F6F74702F65727473 +3710EC:lH371110|H37111C +371110:t2:A9:-progname,H371164 +371164:lH37119C|N +37119C:Yh1D:2F636C656172636173652F6F74702F657274732F62696E2F6365726C20 +37111C:lH37116C|N +37116C:t2:A5:-home,H3711C4 +3711C4:lH3711E8|N +3711E8:YhA:2F686F6D652F73697269 +=proc_stack:<0.2.0> +38eca8:SReturn addr 0x156F90 (<terminate process normally>) +y0:H367D20 +y1:P<0.1.0> +y2:H367D28 +y3:A8:infinity +=proc_heap:<0.2.0> +367D20:lH367D48|H367D50 +367D48:lI47|H367D58 +367D58:lI99|H367D68 +367D68:lI108|H367D78 +367D78:lI101|H367D88 +367D88:lI97|H367D98 +367D98:lI114|H367DA8 +367DA8:lI99|H367DB8 +367DB8:lI97|H367DC8 +367DC8:lI115|H367DD8 +367DD8:lI101|H367DE8 +367DE8:lI47|H367DF8 +367DF8:lI111|H367E08 +367E08:lI116|H367E18 +367E18:lI112|H367E28 +367E28:lI47|H367E38 +367E38:lI101|H367E48 +367E48:lI114|H367E58 +367E58:lI116|H367E68 +367E68:lI115|H367E78 +367E78:lI47|H367E88 +367E88:lI108|H367E98 +367E98:lI105|H367EA8 +367EA8:lI98|H367EB8 +367EB8:lI47|H367EC8 +367EC8:lI107|H367ED8 +367ED8:lI101|H367EE8 +367EE8:lI114|H367EF8 +367EF8:lI110|H367F08 +367F08:lI101|H367F18 +367F18:lI108|H367F28 +367F28:lI47|H367F38 +367F38:lI101|H367F48 +367F48:lI98|H367F58 +367F58:lI105|H367F68 +367F68:lI110|N +367D50:lH367D60|N +367D60:lI47|H367D70 +367D70:lI99|H367D80 +367D80:lI108|H367D90 +367D90:lI101|H367DA0 +367DA0:lI97|H367DB0 +367DB0:lI114|H367DC0 +367DC0:lI99|H367DD0 +367DD0:lI97|H367DE0 +367DE0:lI115|H367DF0 +367DF0:lI101|H367E00 +367E00:lI47|H367E10 +367E10:lI111|H367E20 +367E20:lI116|H367E30 +367E30:lI112|H367E40 +367E40:lI47|H367E50 +367E50:lI101|H367E60 +367E60:lI114|H367E70 +367E70:lI116|H367E80 +367E80:lI115|H367E90 +367E90:lI47|H367EA0 +367EA0:lI108|H367EB0 +367EB0:lI105|H367EC0 +367EC0:lI98|H367ED0 +367ED0:lI47|H367EE0 +367EE0:lI115|H367EF0 +367EF0:lI116|H367F00 +367F00:lI100|H367F10 +367F10:lI108|H367F20 +367F20:lI105|H367F30 +367F30:lI98|H367F40 +367F40:lI47|H367F50 +367F50:lI101|H367F60 +367F60:lI98|H367F70 +367F70:lI105|H367F78 +367F78:lI110|N +367D28:t7:A5:state,A5:efile,N,A4:none,p<0.2>,A8:infinity,A5:false +=proc_dictionary:<0.4.0> +H3AC588 +H3AC594 +=proc_stack:<0.4.0> +3b2f14:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:H3B21E8 +y2:AC:error_logger +y3:P<0.1.0> +3b2f28:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H3AC5A8 +=proc_heap:<0.4.0> +3B21E8:lH3B2144|H3B21E0 +3B2144:t5:A7:handler,AC:error_logger,A5:false,N,A5:false +3B21E0:lH3B21BC|N +3B21BC:t5:A7:handler,A12:error_logger_tty_h,A5:false,H3AC610,A5:false +3AC610:t2:P<0.21.0>,AC:error_logger +3AC5A8:lA9:gen_event|H3AC5E8 +3AC5E8:lP<0.1.0>|H3AC608 +3AC608:lP<0.1.0>|H3AC61C +3AC61C:lH3AC624|H3AC630 +3AC624:t2:A5:local,AC:error_logger +3AC630:lN|H3AC638 +3AC638:lN|H3AC640 +3AC640:lN|N +3AC588:t2:AD:$initial_call,H3AC5B0 +3AC5B0:t3:A3:gen,A7:init_it,H3AC5A8 +3AC594:t2:AA:$ancestors,H3AC5C0 +3AC5C0:lP<0.1.0>|N +=proc_dictionary:<0.5.0> +H372E4C +H372E58 +=proc_stack:<0.5.0> +374704:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A16:application_controller +y3:H3739F4 +y4:A16:application_controller +y5:P<0.1.0> +374720:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H372ED0 +=proc_heap:<0.5.0> +3739F4:t9:A5:state,N,N,N,H373914,N,H373928,N,N +373928:lH37391C|H372F54 +37391C:t2:A6:stdlib,A9:permanent +372F54:lH372F90|N +372F90:t2:A6:kernel,A9:permanent +373914:lH373908|H372F4C +373908:t2:A6:stdlib,A9:undefined +372F4C:lH372F84|N +372F84:t2:A6:kernel,P<0.7.0> +372ED0:lAA:gen_server|H372F5C +372F5C:lP<0.1.0>|H372F9C +372F9C:lP<0.1.0>|H372FC4 +372FC4:lH372FEC|H372FF8 +372FEC:t2:A5:local,A16:application_controller +372FF8:lA16:application_controller|H373018 +373018:lH373038|H373048 +373038:t3:AB:application,A6:kernel,H373060 +373060:lH373078|H373084 +373078:t2:AB:description,H37309C +37309C:lI69|H3730C8 +3730C8:lI82|H3730FC +3730FC:lI84|H373130 +373130:lI83|H37316C +37316C:lI32|H3731A8 +3731A8:lI32|H3731E4 +3731E4:lI67|H373220 +373220:lI88|H37325C +37325C:lI67|H37329C +37329C:lI32|H3732D0 +3732D0:lI49|H3732FC +3732FC:lI51|H373328 +373328:lI56|H373348 +373348:lI32|H373368 +373368:lI49|H373388 +373388:lI48|N +373084:lH3730A4|H3730B0 +3730A4:t2:A3:vsn,H3730D0 +3730D0:lI50|H373104 +373104:lI46|H373138 +373138:lI57|N +3730B0:lH3730D8|H3730E4 +3730D8:t2:A2:id,N +3730E4:lH37310C|H373118 +37310C:t2:A7:modules,H373140 +373140:lAB:application|H373174 +373174:lA16:application_controller|H3731B0 +3731B0:lA12:application_master|H3731EC +3731EC:lA13:application_starter|H373228 +373228:lA4:auth|H373264 +373264:lA4:code|H3732A4 +3732A4:lA8:code_aux|H3732D8 +3732D8:lA8:packages|H373304 +373304:lAB:code_server|H373330 +373330:lA9:dist_util|H373350 +373350:lAF:erl_boot_server|H373370 +373370:lA10:erl_distribution|H373390 +373390:lAF:erl_prim_loader|H3733A8 +3733A8:lA9:erl_reply|H3733C0 +3733C0:lA6:erlang|H3733D8 +3733D8:lAD:error_handler|H3733F0 +3733F0:lAC:error_logger|H373408 +373408:lA4:file|H373420 +373420:lAB:file_server|H373438 +373438:lAF:old_file_server|H373450 +373450:lAE:file_io_server|H373468 +373468:lA9:prim_file|H373480 +373480:lA6:global|H373498 +373498:lAC:global_group|H3734B0 +3734B0:lAD:global_search|H3734C8 +3734C8:lA5:group|H3734E0 +3734E0:lA5:heart|H3734F8 +3734F8:lA13:hipe_unified_loader|H373510 +373510:lA11:hipe_sparc_loader|H373520 +373520:lAF:hipe_x86_loader|H373530 +373530:lA9:inet6_tcp|H373540 +373540:lAE:inet6_tcp_dist|H373550 +373550:lA9:inet6_udp|H373560 +373560:lAB:inet_config|H373570 +373570:lAA:inet_hosts|H373580 +373580:lA13:inet_gethost_native|H373590 +373590:lAD:inet_tcp_dist|H3735A0 +3735A0:lA4:init|H3735B0 +3735B0:lA6:kernel|H3735C0 +3735C0:lAD:kernel_config|H3735D0 +3735D0:lA3:net|H3735E0 +3735E0:lA7:net_adm|H3735F0 +3735F0:lAA:net_kernel|H373600 +373600:lA2:os|H373610 +373610:lA8:ram_file|H373620 +373620:lA3:rpc|H373630 +373630:lA4:user|H373640 +373640:lA8:user_drv|H373650 +373650:lA8:user_sup|H373660 +373660:lA8:disk_log|H373670 +373670:lAA:disk_log_1|H373680 +373680:lAF:disk_log_server|H373690 +373690:lAC:disk_log_sup|H3736A0 +3736A0:lA7:dist_ac|H3736B0 +3736B0:lA8:erl_ddll|H3736C0 +3736C0:lA8:erl_epmd|H3736D0 +3736D0:lAA:erts_debug|H3736E0 +3736E0:lA7:gen_tcp|H3736F0 +3736F0:lA7:gen_udp|H373700 +373700:lA9:prim_inet|H373708 +373708:lA4:inet|H373710 +373710:lA7:inet_db|H373718 +373718:lA8:inet_dns|H373720 +373720:lAA:inet_parse|H373728 +373728:lA8:inet_res|H373730 +373730:lA8:inet_tcp|H373738 +373738:lA8:inet_udp|H373740 +373740:lA3:pg2|H373748 +373748:lA9:seq_trace|H373750 +373750:lA6:socks5|H373758 +373758:lAB:socks5_auth|H373760 +373760:lAA:socks5_tcp|H373768 +373768:lAA:socks5_udp|H373770 +373770:lAF:wrap_log_reader|H373778 +373778:lA4:zlib|H373780 +373780:lA9:otp_ring0|N +373118:lH373148|H373154 +373148:t2:AA:registered,H37317C +37317C:lA16:application_controller|H3731B8 +3731B8:lA9:erl_reply|H3731F4 +3731F4:lA4:auth|H373230 +373230:lAB:boot_server|H37326C +37326C:lAB:code_server|H3732AC +3732AC:lAF:disk_log_server|H3732E0 +3732E0:lAC:disk_log_sup|H37330C +37330C:lAF:erl_prim_loader|H373338 +373338:lAC:error_logger|H373358 +373358:lAB:file_server|H373378 +373378:lAD:file_server_2|H373398 +373398:lAF:fixtable_server|H3733B0 +3733B0:lAC:global_group|H3733C8 +3733C8:lA12:global_name_server|H3733E0 +3733E0:lA5:heart|H3733F8 +3733F8:lA4:init|H373410 +373410:lAD:kernel_config|H373428 +373428:lAA:kernel_sup|H373440 +373440:lAA:net_kernel|H373458 +373458:lA7:net_sup|H373470 +373470:lA3:rex|H373488 +373488:lA4:user|H3734A0 +3734A0:lA9:os_server|H3734B8 +3734B8:lAB:ddll_server|H3734D0 +3734D0:lA8:erl_epmd|H3734E8 +3734E8:lA7:inet_db|H373500 +373500:lA3:pg2|N +373154:lH373184|H373190 +373184:t2:AC:applications,N +373190:lH3731C0|H3731CC +3731C0:t2:A15:included_applications,N +3731CC:lH3731FC|H373208 +3731FC:t2:A3:env,H373238 +373238:lH373274|N +373274:t2:AC:error_logger,A3:tty +373208:lH373240|H37324C +373240:t2:AC:start_phases,A9:undefined +37324C:lH373280|H37328C +373280:t2:A4:maxT,A8:infinity +37328C:lH3732B4|H3732C0 +3732B4:t2:A4:maxP,A8:infinity +3732C0:lH3732E8|N +3732E8:t2:A3:mod,H373314 +373314:t2:A6:kernel,N +373048:lN|N +372E4C:t2:AD:$initial_call,H372EE4 +372EE4:t3:A3:gen,A7:init_it,H372ED0 +372E58:t2:AA:$ancestors,H372EF4 +372EF4:lP<0.1.0>|N +=proc_dictionary:<0.7.0> +H369B78 +H369B5C +=proc_stack:<0.7.0> +369d64:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:H369C2C +y1:P<0.5.0> +369d70:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A12:application_master +y2:A4:init +y3:H369B2C +=proc_heap:<0.7.0> +369C2C:t6:A5:state,P<0.8.0>,H3697B0,N,I0,P<0.0.0> +3697B0:t9:A9:appl_data,A6:kernel,H369B14,A9:undefined,H3697D8,H369A3C,N,A8:infinity,A8:infinity +369A3C:lAB:application|H369A34 +369A34:lA16:application_controller|H369A2C +369A2C:lA12:application_master|H369A24 +369A24:lA13:application_starter|H369A1C +369A1C:lA4:auth|H369A14 +369A14:lA4:code|H369A0C +369A0C:lA8:code_aux|H369A04 +369A04:lA8:packages|H3699FC +3699FC:lAB:code_server|H3699F4 +3699F4:lA9:dist_util|H3699EC +3699EC:lAF:erl_boot_server|H3699E4 +3699E4:lA10:erl_distribution|H3699DC +3699DC:lAF:erl_prim_loader|H3699D4 +3699D4:lA9:erl_reply|H3699CC +3699CC:lA6:erlang|H3699C4 +3699C4:lAD:error_handler|H3699BC +3699BC:lAC:error_logger|H3699B4 +3699B4:lA4:file|H3699AC +3699AC:lAB:file_server|H3699A4 +3699A4:lAF:old_file_server|H36999C +36999C:lAE:file_io_server|H369994 +369994:lA9:prim_file|H36998C +36998C:lA6:global|H369984 +369984:lAC:global_group|H36997C +36997C:lAD:global_search|H369974 +369974:lA5:group|H36996C +36996C:lA5:heart|H369964 +369964:lA13:hipe_unified_loader|H36995C +36995C:lA11:hipe_sparc_loader|H369954 +369954:lAF:hipe_x86_loader|H36994C +36994C:lA9:inet6_tcp|H369944 +369944:lAE:inet6_tcp_dist|H36993C +36993C:lA9:inet6_udp|H369934 +369934:lAB:inet_config|H36992C +36992C:lAA:inet_hosts|H369924 +369924:lA13:inet_gethost_native|H36991C +36991C:lAD:inet_tcp_dist|H369914 +369914:lA4:init|H36990C +36990C:lA6:kernel|H369904 +369904:lAD:kernel_config|H3698FC +3698FC:lA3:net|H3698F4 +3698F4:lA7:net_adm|H3698EC +3698EC:lAA:net_kernel|H3698E4 +3698E4:lA2:os|H3698DC +3698DC:lA8:ram_file|H3698D4 +3698D4:lA3:rpc|H3698CC +3698CC:lA4:user|H3698C4 +3698C4:lA8:user_drv|H3698BC +3698BC:lA8:user_sup|H3698B4 +3698B4:lA8:disk_log|H3698AC +3698AC:lAA:disk_log_1|H3698A4 +3698A4:lAF:disk_log_server|H36989C +36989C:lAC:disk_log_sup|H369894 +369894:lA7:dist_ac|H36988C +36988C:lA8:erl_ddll|H369884 +369884:lA8:erl_epmd|H36987C +36987C:lAA:erts_debug|H369874 +369874:lA7:gen_tcp|H36986C +36986C:lA7:gen_udp|H369864 +369864:lA9:prim_inet|H36985C +36985C:lA4:inet|H369854 +369854:lA7:inet_db|H36984C +36984C:lA8:inet_dns|H369844 +369844:lAA:inet_parse|H36983C +36983C:lA8:inet_res|H369834 +369834:lA8:inet_tcp|H36982C +36982C:lA8:inet_udp|H369824 +369824:lA3:pg2|H36981C +36981C:lA9:seq_trace|H369814 +369814:lA6:socks5|H36980C +36980C:lAB:socks5_auth|H369804 +369804:lAA:socks5_tcp|H3697FC +3697FC:lAA:socks5_udp|H3697F4 +3697F4:lAF:wrap_log_reader|H3697EC +3697EC:lA4:zlib|H3697E4 +3697E4:lA9:otp_ring0|N +3697D8:t2:A6:kernel,N +369B14:lA16:application_controller|H369B0C +369B0C:lA9:erl_reply|H369B04 +369B04:lA4:auth|H369AFC +369AFC:lAB:boot_server|H369AF4 +369AF4:lAB:code_server|H369AEC +369AEC:lAF:disk_log_server|H369AE4 +369AE4:lAC:disk_log_sup|H369ADC +369ADC:lAF:erl_prim_loader|H369AD4 +369AD4:lAC:error_logger|H369ACC +369ACC:lAB:file_server|H369AC4 +369AC4:lAD:file_server_2|H369ABC +369ABC:lAF:fixtable_server|H369AB4 +369AB4:lAC:global_group|H369AAC +369AAC:lA12:global_name_server|H369AA4 +369AA4:lA5:heart|H369A9C +369A9C:lA4:init|H369A94 +369A94:lAD:kernel_config|H369A8C +369A8C:lAA:kernel_sup|H369A84 +369A84:lAA:net_kernel|H369A7C +369A7C:lA7:net_sup|H369A74 +369A74:lA3:rex|H369A6C +369A6C:lA4:user|H369A64 +369A64:lA9:os_server|H369A5C +369A5C:lAB:ddll_server|H369A54 +369A54:lA8:erl_epmd|H369A4C +369A4C:lA7:inet_db|H369A44 +369A44:lA3:pg2|N +369B2C:lP<0.5.0>|H369B24 +369B24:lP<0.6.0>|H3697A8 +3697A8:lH3697B0|H369B1C +369B1C:lA6:normal|N +369B78:t2:AD:$initial_call,H369B68 +369B68:t3:A12:application_master,A4:init,H369B2C +369B5C:t2:AA:$ancestors,H369B54 +369B54:lP<0.6.0>|N +=proc_stack:<0.8.0> +384ec0:SReturn addr 0x156F90 (<terminate process normally>) +y0:H384BDC +y1:A6:kernel +y2:P<0.9.0> +y3:P<0.7.0> +=proc_heap:<0.8.0> +384BDC:t2:A5:state,A3:tty +=proc_dictionary:<0.9.0> +H376850 +H37685C +=proc_stack:<0.9.0> +36bde8:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AA:supervisor +y3:H36B8E8 +y4:AA:kernel_sup +y5:P<0.8.0> +36be04:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H3768D4 +=proc_heap:<0.9.0> +36B8E8:tA:A5:state,H376868,AB:one_for_all,H36B8D4,N,I0,I1,N,A6:kernel,N +36B8D4:lH36B8B0|H36B6E8 +36B8B0:t8:A5:child,P<0.24.0>,AF:kernel_safe_sup,H376BF0,A9:permanent,A8:infinity,AA:supervisor,H376C00 +376C00:lA6:kernel|N +376BF0:t3:AA:supervisor,AA:start_link,H376C08 +376C08:lH376C10|H376C1C +376C10:t2:A5:local,AF:kernel_safe_sup +376C1C:lA6:kernel|H376C24 +376C24:lA4:safe|N +36B6E8:lH36B6C4|H36B490 +36B6C4:t8:A5:child,P<0.23.0>,AD:kernel_config,H376BB4,A9:permanent,I2000,A6:worker,H376BC4 +376BC4:lAD:kernel_config|N +376BB4:t3:AD:kernel_config,AA:start_link,N +36B490:lH36B498|H36B4BC +36B498:t8:A5:child,P<0.19.0>,A4:user,H376B70,A9:temporary,I2000,AA:supervisor,H376B80 +376B80:lA8:user_sup|N +376B70:t3:A8:user_sup,A5:start,N +36B4BC:lH36B4C4|H376CB0 +36B4C4:t8:A5:child,P<0.18.0>,AB:code_server,H376B0C,A9:permanent,I2000,A6:worker,H376B1C +376B1C:lA4:code|N +376B0C:t3:A4:code,AA:start_link,N +376CB0:lH376CB8|H376CDC +376CB8:t8:A5:child,P<0.17.0>,AB:file_server,H376AB8,A9:permanent,I2000,A6:worker,H376AC8 +376AC8:lAF:old_file_server|N +376AB8:t3:AF:old_file_server,AA:start_link,N +376CDC:lH376CE4|H376C2C +376CE4:t8:A5:child,P<0.16.0>,AD:file_server_2,H376A58,A9:permanent,I2000,A6:worker,H376A68 +376A68:lA4:file|H376AB0 +376AB0:lAB:file_server|H376B04 +376B04:lAE:file_io_server|H376B68 +376B68:lA9:prim_file|N +376A58:t3:AB:file_server,AA:start_link,N +376C2C:lH376C34|H376C58 +376C34:t8:A5:child,P<0.15.0>,AC:global_group,H3769F4,A9:permanent,I2000,A6:worker,H376A04 +376A04:lAC:global_group|N +3769F4:t3:AC:global_group,AA:start_link,N +376C58:lH376C60|H376C84 +376C60:t8:A5:child,A9:undefined,A7:net_sup,H37696C,A9:permanent,A8:infinity,AA:supervisor,H37697C +37697C:lA10:erl_distribution|N +37696C:t3:A10:erl_distribution,AA:start_link,N +376C84:lH376C8C|H3768A0 +376C8C:t8:A5:child,P<0.14.0>,A7:inet_db,H3768F4,A9:permanent,I2000,A6:worker,H376904 +376904:lA7:inet_db|N +3768F4:t3:A7:inet_db,AA:start_link,N +3768A0:lH376938|H37695C +376938:t8:A5:child,P<0.11.0>,A12:global_name_server,H3769B0,A9:permanent,I2000,A6:worker,H3769C0 +3769C0:lA6:global|N +3769B0:t3:A6:global,AA:start_link,N +37695C:lH3769C8|N +3769C8:t8:A5:child,P<0.10.0>,A3:rex,H376A38,A9:permanent,I2000,A6:worker,H376A48 +376A48:lA3:rpc|N +376A38:t3:A3:rpc,AA:start_link,N +376868:t2:A5:local,AA:kernel_sup +3768D4:lAA:gen_server|H376964 +376964:lP<0.8.0>|H3769EC +3769EC:lP<0.8.0>|H376A50 +376A50:lH376A9C|H376AA8 +376A9C:t2:A5:local,AA:kernel_sup +376AA8:lAA:supervisor|H376AFC +376AFC:lH376B50|H376B60 +376B50:t3:H376868,A6:kernel,N +376B60:lN|N +376850:t2:AD:$initial_call,H3768DC +3768DC:t3:A3:gen,A7:init_it,H3768D4 +37685C:t2:AA:$ancestors,H3768EC +3768EC:lP<0.8.0>|N +=proc_dictionary:<0.10.0> +H367A10 +H3679F4 +=proc_stack:<0.10.0> +367cec:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A3:rpc +y3:H367AA8 +y4:A3:rex +y5:P<0.9.0> +367d08:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H3679C4 +=proc_heap:<0.10.0> +367AA8:t2:I0,A3:nil +3679C4:lAA:gen_server|H3679BC +3679BC:lP<0.9.0>|H3679B4 +3679B4:lP<0.9.0>|H367988 +367988:lH367990|H3679AC +367990:t2:A5:local,A3:rex +3679AC:lA3:rpc|H3679A4 +3679A4:lN|H36799C +36799C:lN|N +367A10:t2:AD:$initial_call,H367A00 +367A00:t3:A3:gen,A7:init_it,H3679C4 +3679F4:t2:AA:$ancestors,H3679EC +3679EC:lAA:kernel_sup|H3679CC +3679CC:lP<0.8.0>|N +=proc_dictionary:<0.11.0> +H36ADD8 +H36ADBC +=proc_stack:<0.11.0> +36b0b4:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A6:global +y3:H36AF0C +y4:A12:global_name_server +y5:P<0.9.0> +36b0d0:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H36AD8C +=proc_heap:<0.11.0> +36AF0C:t9:A5:state,A4:true,N,N,N,N,AD:nonode@nohost,P<0.12.0>,P<0.13.0> +36AD8C:lAA:gen_server|H36AD84 +36AD84:lP<0.9.0>|H36AD7C +36AD7C:lP<0.9.0>|H36AD50 +36AD50:lH36AD58|H36AD74 +36AD58:t2:A5:local,A12:global_name_server +36AD74:lA6:global|H36AD6C +36AD6C:lN|H36AD64 +36AD64:lN|N +36ADD8:t2:AD:$initial_call,H36ADC8 +36ADC8:t3:A3:gen,A7:init_it,H36AD8C +36ADBC:t2:AA:$ancestors,H36ADB4 +36ADB4:lAA:kernel_sup|H36AD94 +36AD94:lP<0.8.0>|N +=proc_stack:<0.12.0> +36921c:SReturn addr 0x261184 (global:init_the_locker/1 + 112) +y0:N +y1:N +y2:N +y3:N +y4:N +y5:N +y6:A8:infinity +y7:H368EB0 +y8:P<0.11.0> +369244:SReturn addr 0x156F90 (<terminate process normally>) +y0:N +=proc_heap:<0.12.0> +368EB0:t3:A5:multi,A9:undefined,N +=proc_stack:<0.13.0> +3695d0:SReturn addr 0x2651AC (global:loop_the_deleter/1 + 36) +y0:A8:infinity +y1:N +y2:P<0.11.0> +3695e0:SReturn addr 0x2654F8 (global:'-start_the_deleter/1-fun-0-'/1 + 20) +y0:N +y1:N +y2:P<0.11.0> +3695f0:SReturn addr 0x156F90 (<terminate process normally>) +=proc_heap:<0.13.0> +=proc_dictionary:<0.14.0> +H36A998 +H36A9A4 +=proc_stack:<0.14.0> +372e0c:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A7:inet_db +y3:H36A9B0 +y4:A7:inet_db +y5:P<0.9.0> +372e28:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H36A9C8 +=proc_heap:<0.14.0> +36A9B0:t5:A5:state,A7:inet_db,AA:inet_cache,AA:inet_hosts,H36A9E8 +36A9E8:E21:8372000364000D6E6F6E6F6465406E6F686F737400000000060000000000000000 +36A9C8:lAA:gen_server|H36A9F8 +36A9F8:lP<0.9.0>|H36AA08 +36AA08:lP<0.9.0>|H36AA10 +36AA10:lH36AA18|H36AA24 +36AA18:t2:A5:local,A7:inet_db +36AA24:lA7:inet_db|H36AA2C +36AA2C:lN|H36AA34 +36AA34:lN|N +36A998:t2:AD:$initial_call,H36A9D0 +36A9D0:t3:A3:gen,A7:init_it,H36A9C8 +36A9A4:t2:AA:$ancestors,H36A9E0 +36A9E0:lAA:kernel_sup|H36AA00 +36AA00:lP<0.8.0>|N +=proc_dictionary:<0.15.0> +H372788 +H3727F8 +H37276C +H37280C +H372820 +=proc_stack:<0.15.0> +372a64:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AC:global_group +y3:H3728C8 +y4:AC:global_group +y5:P<0.9.0> +372a80:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H37273C +=proc_heap:<0.15.0> +3728C8:tC:A5:state,A7:no_conf,A4:true,N,N,N,N,N,AD:nonode@nohost,N,A6:normal,A6:normal +37273C:lAA:gen_server|H372734 +372734:lP<0.9.0>|H37272C +37272C:lP<0.9.0>|H372700 +372700:lH372708|H372724 +372708:t2:A5:local,AC:global_group +372724:lAC:global_group|H37271C +37271C:lN|H372714 +372714:lN|N +372788:t2:AD:$initial_call,H372778 +372778:t3:A3:gen,A7:init_it,H37273C +3727F8:t2:A10:registered_names,H3727F0 +3727F0:lA9:undefined|N +37276C:t2:AA:$ancestors,H372764 +372764:lAA:kernel_sup|H372744 +372744:lP<0.8.0>|N +37280C:t2:A4:send,H372804 +372804:lA9:undefined|N +372820:t2:AC:whereis_name,H372818 +372818:lA9:undefined|N +=proc_dictionary:<0.16.0> +H37B918 +H37B924 +=proc_stack:<0.16.0> +3d303c:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AB:file_server +y3:p<0.4> +y4:AD:file_server_2 +y5:P<0.9.0> +3d3058:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H37B930 +=proc_heap:<0.16.0> +37B930:lAA:gen_server|H37B950 +37B950:lP<0.9.0>|H37B960 +37B960:lP<0.9.0>|H37B968 +37B968:lH37B970|H37B97C +37B970:t2:A5:local,AD:file_server_2 +37B97C:lAB:file_server|H37B984 +37B984:lN|H37B98C +37B98C:lN|N +37B918:t2:AD:$initial_call,H37B938 +37B938:t3:A3:gen,A7:init_it,H37B930 +37B924:t2:AA:$ancestors,H37B948 +37B948:lAA:kernel_sup|H37B958 +37B958:lP<0.8.0>|N +=proc_stack:<0.17.0> +3763cc:SReturn addr 0x156F90 (<terminate process normally>) +y0:H376084 +y1:P<0.16.0> +y2:P<0.9.0> +=proc_heap:<0.17.0> +376084:E21:8372000364000D6E6F6E6F6465406E6F686F737400000000160000000000000000 +=proc_stack:<0.18.0> +3b98e8:SReturn addr 0x156F90 (<terminate process normally>) +y0:H38AE84 +y1:P<0.9.0> +=proc_heap:<0.18.0> +38AE84:t8:A5:state,P<0.9.0>,H3873BC,H38AEB8,I9,I10,A8:no_cache,AB:interactive +38AEB8:lH3873D4|H38AEE0 +3873D4:lI46|N +38AEE0:lH3873EC|H38AF10 +3873EC:lI47|H387404 +387404:lI99|H387424 +387424:lI108|H38744C +38744C:lI101|H38747C +38747C:lI97|H3874B4 +3874B4:lI114|H3874F4 +3874F4:lI99|H38753C +38753C:lI97|H38758C +38758C:lI115|H3875E4 +3875E4:lI101|H387644 +387644:lI47|H3876AC +3876AC:lI111|H38771C +38771C:lI116|H387794 +387794:lI112|H387814 +387814:lI47|H38789C +38789C:lI101|H38792C +38792C:lI114|H3879BC +3879BC:lI116|H387A54 +387A54:lI115|H387AF4 +387AF4:lI47|H387B9C +387B9C:lI108|H387C4C +387C4C:lI105|H387D04 +387D04:lI98|H387DC4 +387DC4:lI47|H387E8C +387E8C:lI107|H387F5C +387F5C:lI101|H388034 +388034:lI114|H388114 +388114:lI110|H3881FC +3881FC:lI101|H3882EC +3882EC:lI108|H3883E4 +3883E4:lI47|H3884E4 +3884E4:lI101|H3885EC +3885EC:lI98|H3886FC +3886FC:lI105|H388814 +388814:lI110|N +38AF10:lH38740C|H38AF48 +38740C:lI47|H38742C +38742C:lI99|H387454 +387454:lI108|H387484 +387484:lI101|H3874BC +3874BC:lI97|H3874FC +3874FC:lI114|H387544 +387544:lI99|H387594 +387594:lI97|H3875EC +3875EC:lI115|H38764C +38764C:lI101|H3876B4 +3876B4:lI47|H387724 +387724:lI111|H38779C +38779C:lI116|H38781C +38781C:lI112|H3878A4 +3878A4:lI47|H387934 +387934:lI101|H3879C4 +3879C4:lI114|H387A5C +387A5C:lI116|H387AFC +387AFC:lI115|H387BA4 +387BA4:lI47|H387C54 +387C54:lI108|H387D0C +387D0C:lI105|H387DCC +387DCC:lI98|H387E94 +387E94:lI47|H387F64 +387F64:lI115|H38803C +38803C:lI116|H38811C +38811C:lI100|H388204 +388204:lI108|H3882F4 +3882F4:lI105|H3883EC +3883EC:lI98|H3884EC +3884EC:lI47|H3885F4 +3885F4:lI101|H388704 +388704:lI98|H38881C +38881C:lI105|H38892C +38892C:lI110|N +38AF48:lH387434|H38AF70 +387434:lI47|H38745C +38745C:lI99|H38748C +38748C:lI108|H3874C4 +3874C4:lI101|H387504 +387504:lI97|H38754C +38754C:lI114|H38759C +38759C:lI99|H3875F4 +3875F4:lI97|H387654 +387654:lI115|H3876BC +3876BC:lI101|H38772C +38772C:lI47|H3877A4 +3877A4:lI111|H387824 +387824:lI116|H3878AC +3878AC:lI112|H38793C +38793C:lI47|H3879CC +3879CC:lI101|H387A64 +387A64:lI114|H387B04 +387B04:lI116|H387BAC +387BAC:lI115|H387C5C +387C5C:lI47|H387D14 +387D14:lI108|H387DD4 +387DD4:lI105|H387E9C +387E9C:lI98|H387F6C +387F6C:lI47|H388044 +388044:lI119|H388124 +388124:lI101|H38820C +38820C:lI98|H3882FC +3882FC:lI116|H3883F4 +3883F4:lI111|H3884F4 +3884F4:lI111|H3885FC +3885FC:lI108|H38870C +38870C:lI47|H388824 +388824:lI101|H388934 +388934:lI98|H388A44 +388A44:lI105|H388B54 +388B54:lI110|N +38AF70:lH387464|H38AF98 +387464:lI47|H387494 +387494:lI99|H3874CC +3874CC:lI108|H38750C +38750C:lI101|H387554 +387554:lI97|H3875A4 +3875A4:lI114|H3875FC +3875FC:lI99|H38765C +38765C:lI97|H3876C4 +3876C4:lI115|H387734 +387734:lI101|H3877AC +3877AC:lI47|H38782C +38782C:lI111|H3878B4 +3878B4:lI116|H387944 +387944:lI112|H3879D4 +3879D4:lI47|H387A6C +387A6C:lI101|H387B0C +387B0C:lI114|H387BB4 +387BB4:lI116|H387C64 +387C64:lI115|H387D1C +387D1C:lI47|H387DDC +387DDC:lI108|H387EA4 +387EA4:lI105|H387F74 +387F74:lI98|H38804C +38804C:lI47|H38812C +38812C:lI116|H388214 +388214:lI118|H388304 +388304:lI47|H3883FC +3883FC:lI101|H3884FC +3884FC:lI98|H388604 +388604:lI105|H388714 +388714:lI110|N +38AF98:lH38749C|H38AFC0 +38749C:lI47|H3874D4 +3874D4:lI99|H387514 +387514:lI108|H38755C +38755C:lI101|H3875AC +3875AC:lI97|H387604 +387604:lI114|H387664 +387664:lI99|H3876CC +3876CC:lI97|H38773C +38773C:lI115|H3877B4 +3877B4:lI101|H387834 +387834:lI47|H3878BC +3878BC:lI111|H38794C +38794C:lI116|H3879DC +3879DC:lI112|H387A74 +387A74:lI47|H387B14 +387B14:lI101|H387BBC +387BBC:lI114|H387C6C +387C6C:lI116|H387D24 +387D24:lI115|H387DE4 +387DE4:lI47|H387EAC +387EAC:lI108|H387F7C +387F7C:lI105|H388054 +388054:lI98|H388134 +388134:lI47|H38821C +38821C:lI116|H38830C +38830C:lI115|H388404 +388404:lI112|H388504 +388504:lI47|H38860C +38860C:lI101|H38871C +38871C:lI98|H38882C +38882C:lI105|H38893C +38893C:lI110|N +38AFC0:lH3874DC|H38AFE8 +3874DC:lI47|H38751C +38751C:lI99|H387564 +387564:lI108|H3875B4 +3875B4:lI101|H38760C +38760C:lI97|H38766C +38766C:lI114|H3876D4 +3876D4:lI99|H387744 +387744:lI97|H3877BC +3877BC:lI115|H38783C +38783C:lI101|H3878C4 +3878C4:lI47|H387954 +387954:lI111|H3879E4 +3879E4:lI116|H387A7C +387A7C:lI112|H387B1C +387B1C:lI47|H387BC4 +387BC4:lI101|H387C74 +387C74:lI114|H387D2C +387D2C:lI116|H387DEC +387DEC:lI115|H387EB4 +387EB4:lI47|H387F84 +387F84:lI108|H38805C +38805C:lI105|H38813C +38813C:lI98|H388224 +388224:lI47|H388314 +388314:lI116|H38840C +38840C:lI111|H38850C +38850C:lI111|H388614 +388614:lI108|H388724 +388724:lI115|H388834 +388834:lI47|H388944 +388944:lI101|H388A4C +388A4C:lI98|H388B5C +388B5C:lI105|H388C6C +388C6C:lI110|N +38AFE8:lH387524|H38B008 +387524:lI47|H38756C +38756C:lI99|H3875BC +3875BC:lI108|H387614 +387614:lI101|H387674 +387674:lI97|H3876DC +3876DC:lI114|H38774C +38774C:lI99|H3877C4 +3877C4:lI97|H387844 +387844:lI115|H3878CC +3878CC:lI101|H38795C +38795C:lI47|H3879EC +3879EC:lI111|H387A84 +387A84:lI116|H387B24 +387B24:lI112|H387BCC +387BCC:lI47|H387C7C +387C7C:lI101|H387D34 +387D34:lI114|H387DF4 +387DF4:lI116|H387EBC +387EBC:lI115|H387F8C +387F8C:lI47|H388064 +388064:lI108|H388144 +388144:lI105|H38822C +38822C:lI98|H38831C +38831C:lI47|H388414 +388414:lI116|H388514 +388514:lI111|H38861C +38861C:lI111|H38872C +38872C:lI108|H38883C +38883C:lI98|H38894C +38894C:lI97|H388A54 +388A54:lI114|H388B64 +388B64:lI47|H388C74 +388C74:lI101|H388D84 +388D84:lI98|H388E9C +388E9C:lI105|H388FB4 +388FB4:lI110|N +38B008:lH387574|H38B018 +387574:lI47|H3875C4 +3875C4:lI99|H38761C +38761C:lI108|H38767C +38767C:lI101|H3876E4 +3876E4:lI97|H387754 +387754:lI114|H3877CC +3877CC:lI99|H38784C +38784C:lI97|H3878D4 +3878D4:lI115|H387964 +387964:lI101|H3879F4 +3879F4:lI47|H387A8C +387A8C:lI111|H387B2C +387B2C:lI116|H387BD4 +387BD4:lI112|H387C84 +387C84:lI47|H387D3C +387D3C:lI101|H387DFC +387DFC:lI114|H387EC4 +387EC4:lI116|H387F94 +387F94:lI115|H38806C +38806C:lI47|H38814C +38814C:lI108|H388234 +388234:lI105|H388324 +388324:lI98|H38841C +38841C:lI47|H38851C +38851C:lI116|H388624 +388624:lI101|H388734 +388734:lI115|H388844 +388844:lI116|H388954 +388954:lI95|H388A5C +388A5C:lI115|H388B6C +388B6C:lI101|H388C7C +388C7C:lI114|H388D8C +388D8C:lI118|H388EA4 +388EA4:lI101|H388FBC +388FBC:lI114|H3890D4 +3890D4:lI47|H3891EC +3891EC:lI101|H3892FC +3892FC:lI98|H38940C +38940C:lI105|H38951C +38951C:lI110|N +38B018:lH3875CC|H38AE7C +3875CC:lI47|H387624 +387624:lI99|H387684 +387684:lI108|H3876EC +3876EC:lI101|H38775C +38775C:lI97|H3877D4 +3877D4:lI114|H387854 +387854:lI99|H3878DC +3878DC:lI97|H38796C +38796C:lI115|H3879FC +3879FC:lI101|H387A94 +387A94:lI47|H387B34 +387B34:lI111|H387BDC +387BDC:lI116|H387C8C +387C8C:lI112|H387D44 +387D44:lI47|H387E04 +387E04:lI101|H387ECC +387ECC:lI114|H387F9C +387F9C:lI116|H388074 +388074:lI115|H388154 +388154:lI47|H38823C +38823C:lI108|H38832C +38832C:lI105|H388424 +388424:lI98|H388524 +388524:lI47|H38862C +38862C:lI115|H38873C +38873C:lI115|H38884C +38884C:lI108|H38895C +38895C:lI47|H388A64 +388A64:lI101|H388B74 +388B74:lI98|H388C84 +388C84:lI105|H388D94 +388D94:lI110|N +38AE7C:lH38762C|H38AEB0 +38762C:lI47|H38768C +38768C:lI99|H3876F4 +3876F4:lI108|H387764 +387764:lI101|H3877DC +3877DC:lI97|H38785C +38785C:lI114|H3878E4 +3878E4:lI99|H387974 +387974:lI97|H387A04 +387A04:lI115|H387A9C +387A9C:lI101|H387B3C +387B3C:lI47|H387BE4 +387BE4:lI111|H387C94 +387C94:lI116|H387D4C +387D4C:lI112|H387E0C +387E0C:lI47|H387ED4 +387ED4:lI101|H387FA4 +387FA4:lI114|H38807C +38807C:lI116|H38815C +38815C:lI115|H388244 +388244:lI47|H388334 +388334:lI108|H38842C +38842C:lI105|H38852C +38852C:lI98|H388634 +388634:lI47|H388744 +388744:lI115|H388854 +388854:lI110|H388964 +388964:lI109|H388A6C +388A6C:lI112|H388B7C +388B7C:lI47|H388C8C +388C8C:lI101|H388D9C +388D9C:lI98|H388EAC +388EAC:lI105|H388FC4 +388FC4:lI110|N +38AEB0:lH387694|H38AED8 +387694:lI47|H3876FC +3876FC:lI99|H38776C +38776C:lI108|H3877E4 +3877E4:lI101|H387864 +387864:lI97|H3878EC +3878EC:lI114|H38797C +38797C:lI99|H387A0C +387A0C:lI97|H387AA4 +387AA4:lI115|H387B44 +387B44:lI101|H387BEC +387BEC:lI47|H387C9C +387C9C:lI111|H387D54 +387D54:lI116|H387E14 +387E14:lI112|H387EDC +387EDC:lI47|H387FAC +387FAC:lI101|H388084 +388084:lI114|H388164 +388164:lI116|H38824C +38824C:lI115|H38833C +38833C:lI47|H388434 +388434:lI108|H388534 +388534:lI105|H38863C +38863C:lI98|H38874C +38874C:lI47|H38885C +38885C:lI115|H38896C +38896C:lI97|H388A74 +388A74:lI115|H388B84 +388B84:lI108|H388C94 +388C94:lI47|H388DA4 +388DA4:lI101|H388EB4 +388EB4:lI98|H388FCC +388FCC:lI105|H3890DC +3890DC:lI110|N +38AED8:lH387704|H38AF08 +387704:lI47|H387774 +387774:lI99|H3877EC +3877EC:lI108|H38786C +38786C:lI101|H3878F4 +3878F4:lI97|H387984 +387984:lI114|H387A14 +387A14:lI99|H387AAC +387AAC:lI97|H387B4C +387B4C:lI115|H387BF4 +387BF4:lI101|H387CA4 +387CA4:lI47|H387D5C +387D5C:lI111|H387E1C +387E1C:lI116|H387EE4 +387EE4:lI112|H387FB4 +387FB4:lI47|H38808C +38808C:lI101|H38816C +38816C:lI114|H388254 +388254:lI116|H388344 +388344:lI115|H38843C +38843C:lI47|H38853C +38853C:lI108|H388644 +388644:lI105|H388754 +388754:lI98|H388864 +388864:lI47|H388974 +388974:lI114|H388A7C +388A7C:lI117|H388B8C +388B8C:lI110|H388C9C +388C9C:lI116|H388DAC +388DAC:lI105|H388EBC +388EBC:lI109|H388FD4 +388FD4:lI101|H3890E4 +3890E4:lI95|H3891F4 +3891F4:lI116|H389304 +389304:lI111|H389414 +389414:lI111|H389524 +389524:lI108|H389624 +389624:lI115|H38971C +38971C:lI47|H389814 +389814:lI101|H38990C +38990C:lI98|H389A04 +389A04:lI105|H389AE4 +389AE4:lI110|N +38AF08:lH38777C|H38AF40 +38777C:lI47|H3877F4 +3877F4:lI99|H387874 +387874:lI108|H3878FC +3878FC:lI101|H38798C +38798C:lI97|H387A1C +387A1C:lI114|H387AB4 +387AB4:lI99|H387B54 +387B54:lI97|H387BFC +387BFC:lI115|H387CAC +387CAC:lI101|H387D64 +387D64:lI47|H387E24 +387E24:lI111|H387EEC +387EEC:lI116|H387FBC +387FBC:lI112|H388094 +388094:lI47|H388174 +388174:lI101|H38825C +38825C:lI114|H38834C +38834C:lI116|H388444 +388444:lI115|H388544 +388544:lI47|H38864C +38864C:lI108|H38875C +38875C:lI105|H38886C +38886C:lI98|H38897C +38897C:lI47|H388A84 +388A84:lI114|H388B94 +388B94:lI115|H388CA4 +388CA4:lI104|H388DB4 +388DB4:lI101|H388EC4 +388EC4:lI108|H388FDC +388FDC:lI108|H3890EC +3890EC:lI47|H3891FC +3891FC:lI101|H38930C +38930C:lI98|H38941C +38941C:lI105|H38952C +38952C:lI110|N +38AF40:lH3877FC|H38AF68 +3877FC:lI47|H38787C +38787C:lI99|H387904 +387904:lI108|H387994 +387994:lI101|H387A24 +387A24:lI97|H387ABC +387ABC:lI114|H387B5C +387B5C:lI99|H387C04 +387C04:lI97|H387CB4 +387CB4:lI115|H387D6C +387D6C:lI101|H387E2C +387E2C:lI47|H387EF4 +387EF4:lI111|H387FC4 +387FC4:lI116|H38809C +38809C:lI112|H38817C +38817C:lI47|H388264 +388264:lI101|H388354 +388354:lI114|H38844C +38844C:lI116|H38854C +38854C:lI115|H388654 +388654:lI47|H388764 +388764:lI108|H388874 +388874:lI105|H388984 +388984:lI98|H388A8C +388A8C:lI47|H388B9C +388B9C:lI112|H388CAC +388CAC:lI109|H388DBC +388DBC:lI97|H388ECC +388ECC:lI110|H388FE4 +388FE4:lI47|H3890F4 +3890F4:lI101|H389204 +389204:lI98|H389314 +389314:lI105|H389424 +389424:lI110|N +38AF68:lH387884|H38AF90 +387884:lI47|H38790C +38790C:lI99|H38799C +38799C:lI108|H387A2C +387A2C:lI101|H387AC4 +387AC4:lI97|H387B64 +387B64:lI114|H387C0C +387C0C:lI99|H387CBC +387CBC:lI97|H387D74 +387D74:lI115|H387E34 +387E34:lI101|H387EFC +387EFC:lI47|H387FCC +387FCC:lI111|H3880A4 +3880A4:lI116|H388184 +388184:lI112|H38826C +38826C:lI47|H38835C +38835C:lI101|H388454 +388454:lI114|H388554 +388554:lI116|H38865C +38865C:lI115|H38876C +38876C:lI47|H38887C +38887C:lI108|H38898C +38898C:lI105|H388A94 +388A94:lI98|H388BA4 +388BA4:lI47|H388CB4 +388CB4:lI112|H388DC4 +388DC4:lI97|H388ED4 +388ED4:lI114|H388FEC +388FEC:lI115|H3890FC +3890FC:lI101|H38920C +38920C:lI116|H38931C +38931C:lI111|H38942C +38942C:lI111|H389534 +389534:lI108|H38962C +38962C:lI115|H389724 +389724:lI47|H38981C +38981C:lI101|H389914 +389914:lI98|H389A0C +389A0C:lI105|H389AEC +389AEC:lI110|N +38AF90:lH387914|H38AFB8 +387914:lI47|H3879A4 +3879A4:lI99|H387A34 +387A34:lI108|H387ACC +387ACC:lI101|H387B6C +387B6C:lI97|H387C14 +387C14:lI114|H387CC4 +387CC4:lI99|H387D7C +387D7C:lI97|H387E3C +387E3C:lI115|H387F04 +387F04:lI101|H387FD4 +387FD4:lI47|H3880AC +3880AC:lI111|H38818C +38818C:lI116|H388274 +388274:lI112|H388364 +388364:lI47|H38845C +38845C:lI101|H38855C +38855C:lI114|H388664 +388664:lI116|H388774 +388774:lI115|H388884 +388884:lI47|H388994 +388994:lI108|H388A9C +388A9C:lI105|H388BAC +388BAC:lI98|H388CBC +388CBC:lI47|H388DCC +388DCC:lI111|H388EDC +388EDC:lI116|H388FF4 +388FF4:lI112|H389104 +389104:lI95|H389214 +389214:lI109|H389324 +389324:lI105|H389434 +389434:lI98|H38953C +38953C:lI115|H389634 +389634:lI47|H38972C +38972C:lI101|H389824 +389824:lI98|H38991C +38991C:lI105|H389A14 +389A14:lI110|N +38AFB8:lH3879AC|H38AFE0 +3879AC:lI47|H387A3C +387A3C:lI99|H387AD4 +387AD4:lI108|H387B74 +387B74:lI101|H387C1C +387C1C:lI97|H387CCC +387CCC:lI114|H387D84 +387D84:lI99|H387E44 +387E44:lI97|H387F0C +387F0C:lI115|H387FDC +387FDC:lI101|H3880B4 +3880B4:lI47|H388194 +388194:lI111|H38827C +38827C:lI116|H38836C +38836C:lI112|H388464 +388464:lI47|H388564 +388564:lI101|H38866C +38866C:lI114|H38877C +38877C:lI116|H38888C +38888C:lI115|H38899C +38899C:lI47|H388AA4 +388AA4:lI108|H388BB4 +388BB4:lI105|H388CC4 +388CC4:lI98|H388DD4 +388DD4:lI47|H388EE4 +388EE4:lI111|H388FFC +388FFC:lI115|H38910C +38910C:lI95|H38921C +38921C:lI109|H38932C +38932C:lI111|H38943C +38943C:lI110|H389544 +389544:lI47|H38963C +38963C:lI101|H389734 +389734:lI98|H38982C +38982C:lI105|H389924 +389924:lI110|N +38AFE0:lH387A44|H38B000 +387A44:lI47|H387ADC +387ADC:lI99|H387B7C +387B7C:lI108|H387C24 +387C24:lI101|H387CD4 +387CD4:lI97|H387D8C +387D8C:lI114|H387E4C +387E4C:lI99|H387F14 +387F14:lI97|H387FE4 +387FE4:lI115|H3880BC +3880BC:lI101|H38819C +38819C:lI47|H388284 +388284:lI111|H388374 +388374:lI116|H38846C +38846C:lI112|H38856C +38856C:lI47|H388674 +388674:lI101|H388784 +388784:lI114|H388894 +388894:lI116|H3889A4 +3889A4:lI115|H388AAC +388AAC:lI47|H388BBC +388BBC:lI108|H388CCC +388CCC:lI105|H388DDC +388DDC:lI98|H388EEC +388EEC:lI47|H389004 +389004:lI111|H389114 +389114:lI114|H389224 +389224:lI98|H389334 +389334:lI101|H389444 +389444:lI114|H38954C +38954C:lI47|H389644 +389644:lI101|H38973C +38973C:lI98|H389834 +389834:lI105|H38992C +38992C:lI110|N +38B000:lH387AE4|H38B010 +387AE4:lI47|H387B84 +387B84:lI99|H387C2C +387C2C:lI108|H387CDC +387CDC:lI101|H387D94 +387D94:lI97|H387E54 +387E54:lI114|H387F1C +387F1C:lI99|H387FEC +387FEC:lI97|H3880C4 +3880C4:lI115|H3881A4 +3881A4:lI101|H38828C +38828C:lI47|H38837C +38837C:lI111|H388474 +388474:lI116|H388574 +388574:lI112|H38867C +38867C:lI47|H38878C +38878C:lI101|H38889C +38889C:lI114|H3889AC +3889AC:lI116|H388AB4 +388AB4:lI115|H388BC4 +388BC4:lI47|H388CD4 +388CD4:lI108|H388DE4 +388DE4:lI105|H388EF4 +388EF4:lI98|H38900C +38900C:lI47|H38911C +38911C:lI111|H38922C +38922C:lI100|H38933C +38933C:lI98|H38944C +38944C:lI99|H389554 +389554:lI47|H38964C +38964C:lI101|H389744 +389744:lI98|H38983C +38983C:lI105|H389934 +389934:lI110|N +38B010:lH387B8C|H38B020 +387B8C:lI47|H387C34 +387C34:lI99|H387CE4 +387CE4:lI108|H387D9C +387D9C:lI101|H387E5C +387E5C:lI97|H387F24 +387F24:lI114|H387FF4 +387FF4:lI99|H3880CC +3880CC:lI97|H3881AC +3881AC:lI115|H388294 +388294:lI101|H388384 +388384:lI47|H38847C +38847C:lI111|H38857C +38857C:lI116|H388684 +388684:lI112|H388794 +388794:lI47|H3888A4 +3888A4:lI101|H3889B4 +3889B4:lI114|H388ABC +388ABC:lI116|H388BCC +388BCC:lI115|H388CDC +388CDC:lI47|H388DEC +388DEC:lI108|H388EFC +388EFC:lI105|H389014 +389014:lI98|H389124 +389124:lI47|H389234 +389234:lI111|H389344 +389344:lI98|H389454 +389454:lI115|H38955C +38955C:lI101|H389654 +389654:lI114|H38974C +38974C:lI118|H389844 +389844:lI101|H38993C +38993C:lI114|H389A1C +389A1C:lI47|H389AF4 +389AF4:lI101|H389BBC +389BBC:lI98|H389C84 +389C84:lI105|H389D4C +389D4C:lI110|N +38B020:lH387C3C|H38B028 +387C3C:lI47|H387CEC +387CEC:lI99|H387DA4 +387DA4:lI108|H387E64 +387E64:lI101|H387F2C +387F2C:lI97|H387FFC +387FFC:lI114|H3880D4 +3880D4:lI99|H3881B4 +3881B4:lI97|H38829C +38829C:lI115|H38838C +38838C:lI101|H388484 +388484:lI47|H388584 +388584:lI111|H38868C +38868C:lI116|H38879C +38879C:lI112|H3888AC +3888AC:lI47|H3889BC +3889BC:lI101|H388AC4 +388AC4:lI114|H388BD4 +388BD4:lI116|H388CE4 +388CE4:lI115|H388DF4 +388DF4:lI47|H388F04 +388F04:lI108|H38901C +38901C:lI105|H38912C +38912C:lI98|H38923C +38923C:lI47|H38934C +38934C:lI109|H38945C +38945C:lI110|H389564 +389564:lI101|H38965C +38965C:lI115|H389754 +389754:lI105|H38984C +38984C:lI97|H389944 +389944:lI95|H389A24 +389A24:lI115|H389AFC +389AFC:lI101|H389BC4 +389BC4:lI115|H389C8C +389C8C:lI115|H389D54 +389D54:lI105|H389E14 +389E14:lI111|H389ECC +389ECC:lI110|H389F7C +389F7C:lI47|H38A01C +38A01C:lI101|H38A0AC +38A0AC:lI98|H38A12C +38A12C:lI105|H38A19C +38A19C:lI110|N +38B028:lH387CF4|H38B030 +387CF4:lI47|H387DAC +387DAC:lI99|H387E6C +387E6C:lI108|H387F34 +387F34:lI101|H388004 +388004:lI97|H3880DC +3880DC:lI114|H3881BC +3881BC:lI99|H3882A4 +3882A4:lI97|H388394 +388394:lI115|H38848C +38848C:lI101|H38858C +38858C:lI47|H388694 +388694:lI111|H3887A4 +3887A4:lI116|H3888B4 +3888B4:lI112|H3889C4 +3889C4:lI47|H388ACC +388ACC:lI101|H388BDC +388BDC:lI114|H388CEC +388CEC:lI116|H388DFC +388DFC:lI115|H388F0C +388F0C:lI47|H389024 +389024:lI108|H389134 +389134:lI105|H389244 +389244:lI98|H389354 +389354:lI47|H389464 +389464:lI109|H38956C +38956C:lI110|H389664 +389664:lI101|H38975C +38975C:lI115|H389854 +389854:lI105|H38994C +38994C:lI97|H389A2C +389A2C:lI47|H389B04 +389B04:lI101|H389BCC +389BCC:lI98|H389C94 +389C94:lI105|H389D5C +389D5C:lI110|N +38B030:lH387DB4|H38B038 +387DB4:lI47|H387E74 +387E74:lI99|H387F3C +387F3C:lI108|H38800C +38800C:lI101|H3880E4 +3880E4:lI97|H3881C4 +3881C4:lI114|H3882AC +3882AC:lI99|H38839C +38839C:lI97|H388494 +388494:lI115|H388594 +388594:lI101|H38869C +38869C:lI47|H3887AC +3887AC:lI111|H3888BC +3888BC:lI116|H3889CC +3889CC:lI112|H388AD4 +388AD4:lI47|H388BE4 +388BE4:lI101|H388CF4 +388CF4:lI114|H388E04 +388E04:lI116|H388F14 +388F14:lI115|H38902C +38902C:lI47|H38913C +38913C:lI108|H38924C +38924C:lI105|H38935C +38935C:lI98|H38946C +38946C:lI47|H389574 +389574:lI109|H38966C +38966C:lI110|H389764 +389764:lI101|H38985C +38985C:lI109|H389954 +389954:lI111|H389A34 +389A34:lI115|H389B0C +389B0C:lI121|H389BD4 +389BD4:lI110|H389C9C +389C9C:lI101|H389D64 +389D64:lI47|H389E1C +389E1C:lI101|H389ED4 +389ED4:lI98|H389F84 +389F84:lI105|H38A024 +38A024:lI110|N +38B038:lH387E7C|H38B040 +387E7C:lI47|H387F44 +387F44:lI99|H388014 +388014:lI108|H3880EC +3880EC:lI101|H3881CC +3881CC:lI97|H3882B4 +3882B4:lI114|H3883A4 +3883A4:lI99|H38849C +38849C:lI97|H38859C +38859C:lI115|H3886A4 +3886A4:lI101|H3887B4 +3887B4:lI47|H3888C4 +3888C4:lI111|H3889D4 +3889D4:lI116|H388ADC +388ADC:lI112|H388BEC +388BEC:lI47|H388CFC +388CFC:lI101|H388E0C +388E0C:lI114|H388F1C +388F1C:lI116|H389034 +389034:lI115|H389144 +389144:lI47|H389254 +389254:lI108|H389364 +389364:lI105|H389474 +389474:lI98|H38957C +38957C:lI47|H389674 +389674:lI109|H38976C +38976C:lI101|H389864 +389864:lI103|H38995C +38995C:lI97|H389A3C +389A3C:lI99|H389B14 +389B14:lI111|H389BDC +389BDC:lI47|H389CA4 +389CA4:lI101|H389D6C +389D6C:lI98|H389E24 +389E24:lI105|H389EDC +389EDC:lI110|N +38B040:lH387F4C|H38B048 +387F4C:lI47|H38801C +38801C:lI99|H3880F4 +3880F4:lI108|H3881D4 +3881D4:lI101|H3882BC +3882BC:lI97|H3883AC +3883AC:lI114|H3884A4 +3884A4:lI99|H3885A4 +3885A4:lI97|H3886AC +3886AC:lI115|H3887BC +3887BC:lI101|H3888CC +3888CC:lI47|H3889DC +3889DC:lI111|H388AE4 +388AE4:lI116|H388BF4 +388BF4:lI112|H388D04 +388D04:lI47|H388E14 +388E14:lI101|H388F24 +388F24:lI114|H38903C +38903C:lI116|H38914C +38914C:lI115|H38925C +38925C:lI47|H38936C +38936C:lI108|H38947C +38947C:lI105|H389584 +389584:lI98|H38967C +38967C:lI47|H389774 +389774:lI106|H38986C +38986C:lI105|H389964 +389964:lI110|H389A44 +389A44:lI116|H389B1C +389B1C:lI101|H389BE4 +389BE4:lI114|H389CAC +389CAC:lI102|H389D74 +389D74:lI97|H389E2C +389E2C:lI99|H389EE4 +389EE4:lI101|N +38B048:lH388024|H38B050 +388024:lI47|H3880FC +3880FC:lI99|H3881DC +3881DC:lI108|H3882C4 +3882C4:lI101|H3883B4 +3883B4:lI97|H3884AC +3884AC:lI114|H3885AC +3885AC:lI99|H3886B4 +3886B4:lI97|H3887C4 +3887C4:lI115|H3888D4 +3888D4:lI101|H3889E4 +3889E4:lI47|H388AEC +388AEC:lI111|H388BFC +388BFC:lI116|H388D0C +388D0C:lI112|H388E1C +388E1C:lI47|H388F2C +388F2C:lI101|H389044 +389044:lI114|H389154 +389154:lI116|H389264 +389264:lI115|H389374 +389374:lI47|H389484 +389484:lI108|H38958C +38958C:lI105|H389684 +389684:lI98|H38977C +38977C:lI47|H389874 +389874:lI105|H38996C +38996C:lI110|H389A4C +389A4C:lI101|H389B24 +389B24:lI116|H389BEC +389BEC:lI115|H389CB4 +389CB4:lI47|H389D7C +389D7C:lI101|H389E34 +389E34:lI98|H389EEC +389EEC:lI105|H389F8C +389F8C:lI110|N +38B050:lH388104|H38B058 +388104:lI47|H3881E4 +3881E4:lI99|H3882CC +3882CC:lI108|H3883BC +3883BC:lI101|H3884B4 +3884B4:lI97|H3885B4 +3885B4:lI114|H3886BC +3886BC:lI99|H3887CC +3887CC:lI97|H3888DC +3888DC:lI115|H3889EC +3889EC:lI101|H388AF4 +388AF4:lI47|H388C04 +388C04:lI111|H388D14 +388D14:lI116|H388E24 +388E24:lI112|H388F34 +388F34:lI47|H38904C +38904C:lI101|H38915C +38915C:lI114|H38926C +38926C:lI116|H38937C +38937C:lI115|H38948C +38948C:lI47|H389594 +389594:lI108|H38968C +38968C:lI105|H389784 +389784:lI98|H38987C +38987C:lI47|H389974 +389974:lI105|H389A54 +389A54:lI99|H389B2C +389B2C:lI47|H389BF4 +389BF4:lI101|H389CBC +389CBC:lI98|H389D84 +389D84:lI105|H389E3C +389E3C:lI110|N +38B058:lH3881EC|H38B060 +3881EC:lI47|H3882D4 +3882D4:lI99|H3883C4 +3883C4:lI108|H3884BC +3884BC:lI101|H3885BC +3885BC:lI97|H3886C4 +3886C4:lI114|H3887D4 +3887D4:lI99|H3888E4 +3888E4:lI97|H3889F4 +3889F4:lI115|H388AFC +388AFC:lI101|H388C0C +388C0C:lI47|H388D1C +388D1C:lI111|H388E2C +388E2C:lI116|H388F3C +388F3C:lI112|H389054 +389054:lI47|H389164 +389164:lI101|H389274 +389274:lI114|H389384 +389384:lI116|H389494 +389494:lI115|H38959C +38959C:lI47|H389694 +389694:lI108|H38978C +38978C:lI105|H389884 +389884:lI98|H38997C +38997C:lI47|H389A5C +389A5C:lI104|H389B34 +389B34:lI105|H389BFC +389BFC:lI112|H389CC4 +389CC4:lI101|H389D8C +389D8C:lI47|H389E44 +389E44:lI101|H389EF4 +389EF4:lI98|H389F94 +389F94:lI105|H38A02C +38A02C:lI110|N +38B060:lH3882DC|H38B068 +3882DC:lI47|H3883CC +3883CC:lI99|H3884C4 +3884C4:lI108|H3885C4 +3885C4:lI101|H3886CC +3886CC:lI97|H3887DC +3887DC:lI114|H3888EC +3888EC:lI99|H3889FC +3889FC:lI97|H388B04 +388B04:lI115|H388C14 +388C14:lI101|H388D24 +388D24:lI47|H388E34 +388E34:lI111|H388F44 +388F44:lI116|H38905C +38905C:lI112|H38916C +38916C:lI47|H38927C +38927C:lI101|H38938C +38938C:lI114|H38949C +38949C:lI116|H3895A4 +3895A4:lI115|H38969C +38969C:lI47|H389794 +389794:lI108|H38988C +38988C:lI105|H389984 +389984:lI98|H389A64 +389A64:lI47|H389B3C +389B3C:lI103|H389C04 +389C04:lI115|H389CCC +389CCC:lI47|H389D94 +389D94:lI101|H389E4C +389E4C:lI98|H389EFC +389EFC:lI105|H389F9C +389F9C:lI110|N +38B068:lH3883D4|H38B070 +3883D4:lI47|H3884CC +3884CC:lI99|H3885CC +3885CC:lI108|H3886D4 +3886D4:lI101|H3887E4 +3887E4:lI97|H3888F4 +3888F4:lI114|H388A04 +388A04:lI99|H388B0C +388B0C:lI97|H388C1C +388C1C:lI115|H388D2C +388D2C:lI101|H388E3C +388E3C:lI47|H388F4C +388F4C:lI111|H389064 +389064:lI116|H389174 +389174:lI112|H389284 +389284:lI47|H389394 +389394:lI101|H3894A4 +3894A4:lI114|H3895AC +3895AC:lI116|H3896A4 +3896A4:lI115|H38979C +38979C:lI47|H389894 +389894:lI108|H38998C +38998C:lI105|H389A6C +389A6C:lI98|H389B44 +389B44:lI47|H389C0C +389C0C:lI101|H389CD4 +389CD4:lI118|H389D9C +389D9C:lI97|H389E54 +389E54:lI47|H389F04 +389F04:lI101|H389FA4 +389FA4:lI98|H38A034 +38A034:lI105|H38A0B4 +38A0B4:lI110|N +38B070:lH3884D4|H38B078 +3884D4:lI47|H3885D4 +3885D4:lI99|H3886DC +3886DC:lI108|H3887EC +3887EC:lI101|H3888FC +3888FC:lI97|H388A0C +388A0C:lI114|H388B14 +388B14:lI99|H388C24 +388C24:lI97|H388D34 +388D34:lI115|H388E44 +388E44:lI101|H388F54 +388F54:lI47|H38906C +38906C:lI111|H38917C +38917C:lI116|H38928C +38928C:lI112|H38939C +38939C:lI47|H3894AC +3894AC:lI101|H3895B4 +3895B4:lI114|H3896AC +3896AC:lI116|H3897A4 +3897A4:lI115|H38989C +38989C:lI47|H389994 +389994:lI108|H389A74 +389A74:lI105|H389B4C +389B4C:lI98|H389C14 +389C14:lI47|H389CDC +389CDC:lI101|H389DA4 +389DA4:lI116|H389E5C +389E5C:lI47|H389F0C +389F0C:lI101|H389FAC +389FAC:lI98|H38A03C +38A03C:lI105|H38A0BC +38A0BC:lI110|N +38B078:lH3885DC|H38B080 +3885DC:lI47|H3886E4 +3886E4:lI99|H3887F4 +3887F4:lI108|H388904 +388904:lI101|H388A14 +388A14:lI97|H388B1C +388B1C:lI114|H388C2C +388C2C:lI99|H388D3C +388D3C:lI97|H388E4C +388E4C:lI115|H388F5C +388F5C:lI101|H389074 +389074:lI47|H389184 +389184:lI111|H389294 +389294:lI116|H3893A4 +3893A4:lI112|H3894B4 +3894B4:lI47|H3895BC +3895BC:lI101|H3896B4 +3896B4:lI114|H3897AC +3897AC:lI116|H3898A4 +3898A4:lI115|H38999C +38999C:lI47|H389A7C +389A7C:lI108|H389B54 +389B54:lI105|H389C1C +389C1C:lI98|H389CE4 +389CE4:lI47|H389DAC +389DAC:lI101|H389E64 +389E64:lI114|H389F14 +389F14:lI108|H389FB4 +389FB4:lI95|H38A044 +38A044:lI105|H38A0C4 +38A0C4:lI110|H38A134 +38A134:lI116|H38A1A4 +38A1A4:lI101|H38A20C +38A20C:lI114|H38A274 +38A274:lI102|H38A2DC +38A2DC:lI97|H38A344 +38A344:lI99|H38A3AC +38A3AC:lI101|N +38B080:lH3886EC|H38B088 +3886EC:lI47|H3887FC +3887FC:lI99|H38890C +38890C:lI108|H388A1C +388A1C:lI101|H388B24 +388B24:lI97|H388C34 +388C34:lI114|H388D44 +388D44:lI99|H388E54 +388E54:lI97|H388F64 +388F64:lI115|H38907C +38907C:lI101|H38918C +38918C:lI47|H38929C +38929C:lI111|H3893AC +3893AC:lI116|H3894BC +3894BC:lI112|H3895C4 +3895C4:lI47|H3896BC +3896BC:lI101|H3897B4 +3897B4:lI114|H3898AC +3898AC:lI116|H3899A4 +3899A4:lI115|H389A84 +389A84:lI47|H389B5C +389B5C:lI108|H389C24 +389C24:lI105|H389CEC +389CEC:lI98|H389DB4 +389DB4:lI47|H389E6C +389E6C:lI100|H389F1C +389F1C:lI101|H389FBC +389FBC:lI98|H38A04C +38A04C:lI117|H38A0CC +38A0CC:lI103|H38A13C +38A13C:lI103|H38A1AC +38A1AC:lI101|H38A214 +38A214:lI114|H38A27C +38A27C:lI47|H38A2E4 +38A2E4:lI101|H38A34C +38A34C:lI98|H38A3B4 +38A3B4:lI105|H38A414 +38A414:lI110|N +38B088:lH388804|H38B090 +388804:lI47|H388914 +388914:lI99|H388A24 +388A24:lI108|H388B2C +388B2C:lI101|H388C3C +388C3C:lI97|H388D4C +388D4C:lI114|H388E5C +388E5C:lI99|H388F6C +388F6C:lI97|H389084 +389084:lI115|H389194 +389194:lI101|H3892A4 +3892A4:lI47|H3893B4 +3893B4:lI111|H3894C4 +3894C4:lI116|H3895CC +3895CC:lI112|H3896C4 +3896C4:lI47|H3897BC +3897BC:lI101|H3898B4 +3898B4:lI114|H3899AC +3899AC:lI116|H389A8C +389A8C:lI115|H389B64 +389B64:lI47|H389C2C +389C2C:lI108|H389CF4 +389CF4:lI105|H389DBC +389DBC:lI98|H389E74 +389E74:lI47|H389F24 +389F24:lI99|H389FC4 +389FC4:lI114|H38A054 +38A054:lI121|H38A0D4 +38A0D4:lI112|H38A144 +38A144:lI116|H38A1B4 +38A1B4:lI111|H38A21C +38A21C:lI47|H38A284 +38A284:lI101|H38A2EC +38A2EC:lI98|H38A354 +38A354:lI105|H38A3BC +38A3BC:lI110|N +38B090:lH38891C|H38B098 +38891C:lI47|H388A2C +388A2C:lI99|H388B34 +388B34:lI108|H388C44 +388C44:lI101|H388D54 +388D54:lI97|H388E64 +388E64:lI114|H388F74 +388F74:lI99|H38908C +38908C:lI97|H38919C +38919C:lI115|H3892AC +3892AC:lI101|H3893BC +3893BC:lI47|H3894CC +3894CC:lI111|H3895D4 +3895D4:lI116|H3896CC +3896CC:lI112|H3897C4 +3897C4:lI47|H3898BC +3898BC:lI101|H3899B4 +3899B4:lI114|H389A94 +389A94:lI116|H389B6C +389B6C:lI115|H389C34 +389C34:lI47|H389CFC +389CFC:lI108|H389DC4 +389DC4:lI105|H389E7C +389E7C:lI98|H389F2C +389F2C:lI47|H389FCC +389FCC:lI99|H38A05C +38A05C:lI111|H38A0DC +38A0DC:lI115|H38A14C +38A14C:lI84|H38A1BC +38A1BC:lI114|H38A224 +38A224:lI97|H38A28C +38A28C:lI110|H38A2F4 +38A2F4:lI115|H38A35C +38A35C:lI97|H38A3C4 +38A3C4:lI99|H38A41C +38A41C:lI116|H38A46C +38A46C:lI105|H38A4BC +38A4BC:lI111|H38A50C +38A50C:lI110|H38A554 +38A554:lI115|H38A59C +38A59C:lI47|H38A5E4 +38A5E4:lI101|H38A62C +38A62C:lI98|H38A66C +38A66C:lI105|H38A6A4 +38A6A4:lI110|N +38B098:lH388A34|H38B0A0 +388A34:lI47|H388B3C +388B3C:lI99|H388C4C +388C4C:lI108|H388D5C +388D5C:lI101|H388E6C +388E6C:lI97|H388F7C +388F7C:lI114|H389094 +389094:lI99|H3891A4 +3891A4:lI97|H3892B4 +3892B4:lI115|H3893C4 +3893C4:lI101|H3894D4 +3894D4:lI47|H3895DC +3895DC:lI111|H3896D4 +3896D4:lI116|H3897CC +3897CC:lI112|H3898C4 +3898C4:lI47|H3899BC +3899BC:lI101|H389A9C +389A9C:lI114|H389B74 +389B74:lI116|H389C3C +389C3C:lI115|H389D04 +389D04:lI47|H389DCC +389DCC:lI108|H389E84 +389E84:lI105|H389F34 +389F34:lI98|H389FD4 +389FD4:lI47|H38A064 +38A064:lI99|H38A0E4 +38A0E4:lI111|H38A154 +38A154:lI115|H38A1C4 +38A1C4:lI84|H38A22C +38A22C:lI105|H38A294 +38A294:lI109|H38A2FC +38A2FC:lI101|H38A364 +38A364:lI47|H38A3CC +38A3CC:lI101|H38A424 +38A424:lI98|H38A474 +38A474:lI105|H38A4C4 +38A4C4:lI110|N +38B0A0:lH388B44|H38B0A8 +388B44:lI47|H388C54 +388C54:lI99|H388D64 +388D64:lI108|H388E74 +388E74:lI101|H388F84 +388F84:lI97|H38909C +38909C:lI114|H3891AC +3891AC:lI99|H3892BC +3892BC:lI97|H3893CC +3893CC:lI115|H3894DC +3894DC:lI101|H3895E4 +3895E4:lI47|H3896DC +3896DC:lI111|H3897D4 +3897D4:lI116|H3898CC +3898CC:lI112|H3899C4 +3899C4:lI47|H389AA4 +389AA4:lI101|H389B7C +389B7C:lI114|H389C44 +389C44:lI116|H389D0C +389D0C:lI115|H389DD4 +389DD4:lI47|H389E8C +389E8C:lI108|H389F3C +389F3C:lI105|H389FDC +389FDC:lI98|H38A06C +38A06C:lI47|H38A0EC +38A0EC:lI99|H38A15C +38A15C:lI111|H38A1CC +38A1CC:lI115|H38A234 +38A234:lI80|H38A29C +38A29C:lI114|H38A304 +38A304:lI111|H38A36C +38A36C:lI112|H38A3D4 +38A3D4:lI101|H38A42C +38A42C:lI114|H38A47C +38A47C:lI116|H38A4CC +38A4CC:lI121|H38A514 +38A514:lI47|H38A55C +38A55C:lI101|H38A5A4 +38A5A4:lI98|H38A5EC +38A5EC:lI105|H38A634 +38A634:lI110|N +38B0A8:lH388C5C|H38B0B0 +388C5C:lI47|H388D6C +388D6C:lI99|H388E7C +388E7C:lI108|H388F8C +388F8C:lI101|H3890A4 +3890A4:lI97|H3891B4 +3891B4:lI114|H3892C4 +3892C4:lI99|H3893D4 +3893D4:lI97|H3894E4 +3894E4:lI115|H3895EC +3895EC:lI101|H3896E4 +3896E4:lI47|H3897DC +3897DC:lI111|H3898D4 +3898D4:lI116|H3899CC +3899CC:lI112|H389AAC +389AAC:lI47|H389B84 +389B84:lI101|H389C4C +389C4C:lI114|H389D14 +389D14:lI116|H389DDC +389DDC:lI115|H389E94 +389E94:lI47|H389F44 +389F44:lI108|H389FE4 +389FE4:lI105|H38A074 +38A074:lI98|H38A0F4 +38A0F4:lI47|H38A164 +38A164:lI99|H38A1D4 +38A1D4:lI111|H38A23C +38A23C:lI115|H38A2A4 +38A2A4:lI78|H38A30C +38A30C:lI111|H38A374 +38A374:lI116|H38A3DC +38A3DC:lI105|H38A434 +38A434:lI102|H38A484 +38A484:lI105|H38A4D4 +38A4D4:lI99|H38A51C +38A51C:lI97|H38A564 +38A564:lI116|H38A5AC +38A5AC:lI105|H38A5F4 +38A5F4:lI111|H38A63C +38A63C:lI110|H38A674 +38A674:lI47|H38A6AC +38A6AC:lI101|H38A6D4 +38A6D4:lI98|H38A6EC +38A6EC:lI105|H38A704 +38A704:lI110|N +38B0B0:lH388D74|H38B0B8 +388D74:lI47|H388E84 +388E84:lI99|H388F94 +388F94:lI108|H3890AC +3890AC:lI101|H3891BC +3891BC:lI97|H3892CC +3892CC:lI114|H3893DC +3893DC:lI99|H3894EC +3894EC:lI97|H3895F4 +3895F4:lI115|H3896EC +3896EC:lI101|H3897E4 +3897E4:lI47|H3898DC +3898DC:lI111|H3899D4 +3899D4:lI116|H389AB4 +389AB4:lI112|H389B8C +389B8C:lI47|H389C54 +389C54:lI101|H389D1C +389D1C:lI114|H389DE4 +389DE4:lI116|H389E9C +389E9C:lI115|H389F4C +389F4C:lI47|H389FEC +389FEC:lI108|H38A07C +38A07C:lI105|H38A0FC +38A0FC:lI98|H38A16C +38A16C:lI47|H38A1DC +38A1DC:lI99|H38A244 +38A244:lI111|H38A2AC +38A2AC:lI115|H38A314 +38A314:lI70|H38A37C +38A37C:lI105|H38A3E4 +38A3E4:lI108|H38A43C +38A43C:lI101|H38A48C +38A48C:lI84|H38A4DC +38A4DC:lI114|H38A524 +38A524:lI97|H38A56C +38A56C:lI110|H38A5B4 +38A5B4:lI115|H38A5FC +38A5FC:lI102|H38A644 +38A644:lI101|H38A67C +38A67C:lI114|H38A6B4 +38A6B4:lI47|H38A6DC +38A6DC:lI101|H38A6F4 +38A6F4:lI98|H38A70C +38A70C:lI105|H38A71C +38A71C:lI110|N +38B0B8:lH388E8C|H38B0C0 +388E8C:lI47|H388F9C +388F9C:lI99|H3890B4 +3890B4:lI108|H3891C4 +3891C4:lI101|H3892D4 +3892D4:lI97|H3893E4 +3893E4:lI114|H3894F4 +3894F4:lI99|H3895FC +3895FC:lI97|H3896F4 +3896F4:lI115|H3897EC +3897EC:lI101|H3898E4 +3898E4:lI47|H3899DC +3899DC:lI111|H389ABC +389ABC:lI116|H389B94 +389B94:lI112|H389C5C +389C5C:lI47|H389D24 +389D24:lI101|H389DEC +389DEC:lI114|H389EA4 +389EA4:lI116|H389F54 +389F54:lI115|H389FF4 +389FF4:lI47|H38A084 +38A084:lI108|H38A104 +38A104:lI105|H38A174 +38A174:lI98|H38A1E4 +38A1E4:lI47|H38A24C +38A24C:lI99|H38A2B4 +38A2B4:lI111|H38A31C +38A31C:lI115|H38A384 +38A384:lI69|H38A3EC +38A3EC:lI118|H38A444 +38A444:lI101|H38A494 +38A494:lI110|H38A4E4 +38A4E4:lI116|H38A52C +38A52C:lI68|H38A574 +38A574:lI111|H38A5BC +38A5BC:lI109|H38A604 +38A604:lI97|H38A64C +38A64C:lI105|H38A684 +38A684:lI110|H38A6BC +38A6BC:lI47|H38A6E4 +38A6E4:lI101|H38A6FC +38A6FC:lI98|H38A714 +38A714:lI105|H38A724 +38A724:lI110|N +38B0C0:lH388FA4|H38B0C8 +388FA4:lI47|H3890BC +3890BC:lI99|H3891CC +3891CC:lI108|H3892DC +3892DC:lI101|H3893EC +3893EC:lI97|H3894FC +3894FC:lI114|H389604 +389604:lI99|H3896FC +3896FC:lI97|H3897F4 +3897F4:lI115|H3898EC +3898EC:lI101|H3899E4 +3899E4:lI47|H389AC4 +389AC4:lI111|H389B9C +389B9C:lI116|H389C64 +389C64:lI112|H389D2C +389D2C:lI47|H389DF4 +389DF4:lI101|H389EAC +389EAC:lI114|H389F5C +389F5C:lI116|H389FFC +389FFC:lI115|H38A08C +38A08C:lI47|H38A10C +38A10C:lI108|H38A17C +38A17C:lI105|H38A1EC +38A1EC:lI98|H38A254 +38A254:lI47|H38A2BC +38A2BC:lI99|H38A324 +38A324:lI111|H38A38C +38A38C:lI115|H38A3F4 +38A3F4:lI69|H38A44C +38A44C:lI118|H38A49C +38A49C:lI101|H38A4EC +38A4EC:lI110|H38A534 +38A534:lI116|H38A57C +38A57C:lI47|H38A5C4 +38A5C4:lI101|H38A60C +38A60C:lI98|H38A654 +38A654:lI105|H38A68C +38A68C:lI110|N +38B0C8:lH3890C4|H38B0D0 +3890C4:lI47|H3891D4 +3891D4:lI99|H3892E4 +3892E4:lI108|H3893F4 +3893F4:lI101|H389504 +389504:lI97|H38960C +38960C:lI114|H389704 +389704:lI99|H3897FC +3897FC:lI97|H3898F4 +3898F4:lI115|H3899EC +3899EC:lI101|H389ACC +389ACC:lI47|H389BA4 +389BA4:lI111|H389C6C +389C6C:lI116|H389D34 +389D34:lI112|H389DFC +389DFC:lI47|H389EB4 +389EB4:lI101|H389F64 +389F64:lI114|H38A004 +38A004:lI116|H38A094 +38A094:lI115|H38A114 +38A114:lI47|H38A184 +38A184:lI108|H38A1F4 +38A1F4:lI105|H38A25C +38A25C:lI98|H38A2C4 +38A2C4:lI47|H38A32C +38A32C:lI99|H38A394 +38A394:lI111|H38A3FC +38A3FC:lI109|H38A454 +38A454:lI112|H38A4A4 +38A4A4:lI105|H38A4F4 +38A4F4:lI108|H38A53C +38A53C:lI101|H38A584 +38A584:lI114|H38A5CC +38A5CC:lI47|H38A614 +38A614:lI101|H38A65C +38A65C:lI98|H38A694 +38A694:lI105|H38A6C4 +38A6C4:lI110|N +38B0D0:lH3891DC|H38B0D8 +3891DC:lI47|H3892EC +3892EC:lI99|H3893FC +3893FC:lI108|H38950C +38950C:lI101|H389614 +389614:lI97|H38970C +38970C:lI114|H389804 +389804:lI99|H3898FC +3898FC:lI97|H3899F4 +3899F4:lI115|H389AD4 +389AD4:lI101|H389BAC +389BAC:lI47|H389C74 +389C74:lI111|H389D3C +389D3C:lI116|H389E04 +389E04:lI112|H389EBC +389EBC:lI47|H389F6C +389F6C:lI101|H38A00C +38A00C:lI114|H38A09C +38A09C:lI116|H38A11C +38A11C:lI115|H38A18C +38A18C:lI47|H38A1FC +38A1FC:lI108|H38A264 +38A264:lI105|H38A2CC +38A2CC:lI98|H38A334 +38A334:lI47|H38A39C +38A39C:lI97|H38A404 +38A404:lI115|H38A45C +38A45C:lI110|H38A4AC +38A4AC:lI49|H38A4FC +38A4FC:lI47|H38A544 +38A544:lI101|H38A58C +38A58C:lI98|H38A5D4 +38A5D4:lI105|H38A61C +38A61C:lI110|N +38B0D8:lH3892F4|H38B0E0 +3892F4:lI47|H389404 +389404:lI99|H389514 +389514:lI108|H38961C +38961C:lI101|H389714 +389714:lI97|H38980C +38980C:lI114|H389904 +389904:lI99|H3899FC +3899FC:lI97|H389ADC +389ADC:lI115|H389BB4 +389BB4:lI101|H389C7C +389C7C:lI47|H389D44 +389D44:lI111|H389E0C +389E0C:lI116|H389EC4 +389EC4:lI112|H389F74 +389F74:lI47|H38A014 +38A014:lI101|H38A0A4 +38A0A4:lI114|H38A124 +38A124:lI116|H38A194 +38A194:lI115|H38A204 +38A204:lI47|H38A26C +38A26C:lI108|H38A2D4 +38A2D4:lI105|H38A33C +38A33C:lI98|H38A3A4 +38A3A4:lI47|H38A40C +38A40C:lI97|H38A464 +38A464:lI112|H38A4B4 +38A4B4:lI112|H38A504 +38A504:lI109|H38A54C +38A54C:lI111|H38A594 +38A594:lI110|H38A5DC +38A5DC:lI47|H38A624 +38A624:lI101|H38A664 +38A664:lI98|H38A69C +38A69C:lI105|H38A6CC +38A6CC:lI110|N +38B0E0:lH38AA88|H38B0E8 +38AA88:lI47|H38AA90 +38AA90:lI104|H38AA98 +38AA98:lI111|H38AAA0 +38AAA0:lI109|H38AAA8 +38AAA8:lI101|H38AAB0 +38AAB0:lI47|H38AAB8 +38AAB8:lI115|H38AAC0 +38AAC0:lI105|H38AAC8 +38AAC8:lI114|H38AAD0 +38AAD0:lI105|H38AAD8 +38AAD8:lI47|H38AAE0 +38AAE0:lI101|H38AAE8 +38AAE8:lI114|H38AAF0 +38AAF0:lI108|H38AAF8 +38AAF8:lI97|H38AB00 +38AB00:lI110|H38AB08 +38AB08:lI103|N +38B0E8:lH38AB1C|H38B0F0 +38AB1C:lI47|H38AB2C +38AB2C:lI104|H38AB4C +38AB4C:lI111|H38AB74 +38AB74:lI109|H38ABA4 +38ABA4:lI101|H38ABC4 +38ABC4:lI47|H38ABE4 +38ABE4:lI115|H38AC04 +38AC04:lI105|H38AC24 +38AC24:lI114|H38AC3C +38AC3C:lI105|H38AC44 +38AC44:lI47|H38AC4C +38AC4C:lI116|H38AC54 +38AC54:lI111|H38AC5C +38AC5C:lI111|H38AC64 +38AC64:lI108|H38AC6C +38AC6C:lI115|H38AC74 +38AC74:lI47|H38AC7C +38AC7C:lI100|H38AC84 +38AC84:lI105|H38AC8C +38AC8C:lI115|H38AC94 +38AC94:lI116|H38AC9C +38AC9C:lI101|H38ACA4 +38ACA4:lI108|H38ACAC +38ACAC:lI47|H38ACB4 +38ACB4:lI101|H38ACBC +38ACBC:lI98|H38ACC4 +38ACC4:lI105|H38ACCC +38ACCC:lI110|N +38B0F0:lH38B0F8|N +38B0F8:lI47|H38B100 +38B100:lI104|H38B108 +38B108:lI111|H38B110 +38B110:lI109|H38B118 +38B118:lI101|H38B120 +38B120:lI47|H38B128 +38B128:lI115|H38B130 +38B130:lI105|H38B138 +38B138:lI114|H38B140 +38B140:lI105|H38B148 +38B148:lI47|H38B150 +38B150:lI79|H38B158 +38B158:lI84|H38B160 +38B160:lI80|H38B168 +38B168:lI47|H38B170 +38B170:lI103|H38B178 +38B178:lI112|H38B180 +38B180:lI114|H38B188 +38B188:lI115|H38B190 +38B190:lI95|H38B198 +38B198:lI116|H38B1A0 +38B1A0:lI114|H38B1A8 +38B1A8:lI97|H38B1B0 +38B1B0:lI99|H38B1B8 +38B1B8:lI101|H38B1C0 +38B1C0:lI47|H38B1C8 +38B1C8:lI106|H38B1D0 +38B1D0:lI97|H38B1D8 +38B1D8:lI110|N +3873BC:lI47|H3873CC +3873CC:lI99|H3873E4 +3873E4:lI108|H3873FC +3873FC:lI101|H38741C +38741C:lI97|H387444 +387444:lI114|H387474 +387474:lI99|H3874AC +3874AC:lI97|H3874EC +3874EC:lI115|H387534 +387534:lI101|H387584 +387584:lI47|H3875DC +3875DC:lI111|H38763C +38763C:lI116|H3876A4 +3876A4:lI112|H387714 +387714:lI47|H38778C +38778C:lI101|H38780C +38780C:lI114|H387894 +387894:lI116|H387924 +387924:lI115|N +=proc_dictionary:<0.19.0> +H370244 +H370250 +=proc_stack:<0.19.0> +36b45c:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A11:supervisor_bridge +y3:H36B17C +y4:P<0.19.0> +y5:P<0.9.0> +36b478:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H37025C +=proc_heap:<0.19.0> +36B17C:t5:A5:state,A8:user_sup,P<0.21.0>,P<0.21.0>,H370238 +370238:t2:P<0.19.0>,A8:user_sup +37025C:lAA:gen_server|H37027C +37027C:lP<0.9.0>|H37028C +37028C:lP<0.9.0>|H370294 +370294:lA11:supervisor_bridge|H37029C +37029C:lH3702A4|H3702AC +3702A4:lA8:user_sup|H3702B4 +3702B4:lN|H3702BC +3702BC:lA4:self|N +3702AC:lN|N +370244:t2:AD:$initial_call,H370264 +370264:t3:A3:gen,A7:init_it,H37025C +370250:t2:AA:$ancestors,H370274 +370274:lAA:kernel_sup|H370284 +370284:lP<0.8.0>|N +=proc_dictionary:<0.20.0> +H36F8A8 +=proc_stack:<0.20.0> +36a714:SReturn addr 0x156F90 (<terminate process normally>) +y0:N +y1:N +y2:H36F8C4 +y3:P<0.21.0> +y4:P<0.22.0> +y5:p<0.72> +y6:p<0.72> +=proc_heap:<0.20.0> +36F8C4:t4:I3,I2,P<0.22.0>,H36F8F0 +36F8F0:lH36F900|H36F910 +36F900:t3:I1,P<0.21.0>,H36F920 +36F920:t0: +36F910:lH36F924|N +36F924:t3:I2,P<0.22.0>,H36F93C +36F93C:t3:A5:shell,A5:start,N +36F8A8:t2:A3:eof,A5:false +=proc_dictionary:<0.21.0> +H3709DC +H3709D0 +H3709F8 +=proc_stack:<0.21.0> +370d1c:SReturn addr 0x156F90 (<terminate process normally>) +y0:N +y1:A9:undefined +y2:P<0.20.0> +=proc_heap:<0.21.0> +3709DC:t2:AB:line_buffer,N +3709D0:t2:AB:kill_buffer,N +3709F8:t2:A9:read_mode,A4:list +=proc_dictionary:<0.22.0> +H370D44 +H370D60 +H370D7C +H370D38 +=proc_stack:<0.22.0> +374a88:SReturn addr 0x2CE718 (group:get_chars_loop/7 + 80) +y0:N +y1:N +y2:A8:infinity +y3:H374A00 +y4:P<0.20.0> +y5:H374A28 +374aa4:SReturn addr 0x2CDC18 (group:io_request/5 + 48) +y0:H37499C +y1:A6:io_lib +y2:A9:get_until +y3:H3748B8 +y4:P<0.20.0> +y5:A5:start +374ac0:SReturn addr 0x2CDB2C (group:server_loop/3 + 372) +y0:P<0.49.0> +y1:P<0.22.0> +374acc:SReturn addr 0x156F90 (<terminate process normally>) +y0:N +y1:P<0.25.0> +y2:P<0.20.0> +=proc_heap:<0.22.0> +374A00:t4:A4:line,H37499C,H3749A4,A4:none +3749A4:t2:N,N +37499C:lI50|H374994 +374994:lI62|H37498C +37498C:lI32|N +374A28:t4:A5:stack,H370D58,H374A24,N +374A24:t0: +370D58:lH370D74|N +370D74:lI99|H370D88 +370D88:lI114|H370D90 +370D90:lI97|H370D98 +370D98:lI115|H370DA0 +370DA0:lI104|H370DA8 +370DA8:lI100|H370DB0 +370DB0:lI117|H370DB8 +370DB8:lI109|H370DC0 +370DC0:lI112|H370DC8 +370DC8:lI95|H370DD0 +370DD0:lI118|H370DD8 +370DD8:lI105|H370DE0 +370DE0:lI101|H370DE8 +370DE8:lI119|H370DF0 +370DF0:lI101|H370DF8 +370DF8:lI114|H370E00 +370E00:lI58|H370E08 +370E08:lI115|H370E10 +370E10:lI116|H370E18 +370E18:lI97|H370E20 +370E20:lI114|H370E28 +370E28:lI116|H370E30 +370E30:lI40|H370E38 +370E38:lI41|H370E40 +370E40:lI46|H370E48 +370E48:lI10|N +3748B8:t3:A8:erl_scan,A6:tokens,H3748B0 +3748B0:lI1|N +370D44:t2:AB:line_buffer,H370D58 +370D60:t2:A5:shell,P<0.25.0> +370D7C:t2:AB:kill_buffer,N +370D38:t2:A9:read_mode,A4:list +=proc_dictionary:<0.23.0> +H376464 +H376448 +=proc_stack:<0.23.0> +376754:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AD:kernel_config +y3:N +y4:P<0.23.0> +y5:P<0.9.0> +376770:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H376418 +=proc_heap:<0.23.0> +376418:lAA:gen_server|H376410 +376410:lP<0.9.0>|H376408 +376408:lP<0.9.0>|H376400 +376400:lAD:kernel_config|H3763F8 +3763F8:lN|H3763F0 +3763F0:lN|N +376464:t2:AD:$initial_call,H376454 +376454:t3:A3:gen,A7:init_it,H376418 +376448:t2:AA:$ancestors,H376440 +376440:lAA:kernel_sup|H376420 +376420:lP<0.8.0>|N +=proc_dictionary:<0.24.0> +H3705E0 +H3705EC +=proc_stack:<0.24.0> +36f38c:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AA:supervisor +y3:H36F018 +y4:AF:kernel_safe_sup +y5:P<0.9.0> +36f3a8:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H37063C +=proc_heap:<0.24.0> +36F018:tA:A5:state,H370644,AB:one_for_one,H36F044,N,I4,I3600,N,A6:kernel,A4:safe +36F044:lH36F04C|N +36F04C:t8:A5:child,P<0.31.0>,A17:inet_gethost_native_sup,H370650,A9:temporary,I1000,A6:worker,H370660 +370660:lA13:inet_gethost_native|N +370650:t3:A13:inet_gethost_native,AA:start_link,N +370644:t2:A5:local,AF:kernel_safe_sup +37063C:lAA:gen_server|H3706AC +3706AC:lP<0.9.0>|H3706BC +3706BC:lP<0.9.0>|H3706C4 +3706C4:lH3706CC|H3706D8 +3706CC:t2:A5:local,AF:kernel_safe_sup +3706D8:lAA:supervisor|H3706E0 +3706E0:lH3706E8|H3706F8 +3706E8:t3:H370644,A6:kernel,A4:safe +3706F8:lN|N +3705E0:t2:AD:$initial_call,H370668 +370668:t3:A3:gen,A7:init_it,H37063C +3705EC:t2:AA:$ancestors,H370678 +370678:lAA:kernel_sup|H3706B4 +3706B4:lP<0.8.0>|N +=proc_dictionary:<0.25.0> +H36E304 +H36E31C +=proc_stack:<0.25.0> +36e610:SReturn addr 0x2E06FC (shell:server_loop/6 + 140) +y0:N +y1:N +y2:P<0.27.0> +y3:P<0.49.0> +36e624:SReturn addr 0x156F90 (<terminate process normally>) +y0:N +y1:N +y2:I2 +y3:I1 +y4:N +y5:N +y6:N +y7:I20 +y8:I20 +=proc_heap:<0.25.0> +36E304:t2:H36E2F8,H36E2A8 +36E2A8:lH36E2B0|N +36E2B0:t4:A4:call,I1,H36E2C4,N +36E2C4:t4:A6:remote,I1,H36E2D8,H36E2E8 +36E2E8:t3:A4:atom,I1,A5:start +36E2D8:t3:A4:atom,I1,A10:crashdump_viewer +36E2F8:t2:A7:command,I1 +36E31C:t2:H36E310,A2:ok +36E310:t2:A6:result,I1 +=proc_stack:<0.27.0> +3bda3c:SReturn addr 0x156F90 (<terminate process normally>) +y0:N +y1:N +y2:P<0.25.0> +=proc_heap:<0.27.0> +=proc_dictionary:<0.31.0> +H36DA24 +H36DA08 +=proc_stack:<0.31.0> +36dcd4:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A11:supervisor_bridge +y3:H36DB68 +y4:A17:inet_gethost_native_sup +y5:P<0.24.0> +36dcf0:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H36D9D0 +=proc_heap:<0.31.0> +36DB68:t5:A5:state,A13:inet_gethost_native,P<0.32.0>,P<0.32.0>,H36D994 +36D994:t2:A5:local,A17:inet_gethost_native_sup +36D9D0:lAA:gen_server|H36D9C8 +36D9C8:lP<0.24.0>|H36D9C0 +36D9C0:lP<0.24.0>|H36D970 +36D970:lH36D980|H36D9B8 +36D980:t2:A5:local,A17:inet_gethost_native_sup +36D9B8:lA11:supervisor_bridge|H36D978 +36D978:lH36D9A8|H36D9B0 +36D9A8:lA13:inet_gethost_native|H36D9A0 +36D9A0:lN|H36D98C +36D98C:lH36D994|N +36D9B0:lN|N +36DA24:t2:AD:$initial_call,H36DA14 +36DA14:t3:A3:gen,A7:init_it,H36D9D0 +36DA08:t2:AA:$ancestors,H36DA00 +36DA00:lAF:kernel_safe_sup|H36D9E0 +36D9E0:lAA:kernel_sup|H36D9D8 +36D9D8:lP<0.8.0>|N +=proc_dictionary:<0.32.0> +H36CFD4 +H36D0BC +=proc_stack:<0.32.0> +36d12c:SReturn addr 0x156F90 (<terminate process normally>) +y0:H36CF18 +=proc_heap:<0.32.0> +36CF18:t8:A5:state,p<0.105>,I8000,I11,I12,P<0.31.0>,I4,H36CEF0 +36CEF0:t9:AA:statistics,I0,I0,I0,I0,I0,I0,I0,I0 +36CFD4:t2:A3:rid,I1 +36D0BC:t2:AC:num_requests,I0 +=proc_dictionary:<0.33.0> +H3905C4 +H3905D0 +=proc_stack:<0.33.0> +3ceee4:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A7:webtool +y3:H3C8570 +y4:A8:web_tool +y5:P<0.33.0> +3cef00:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H3905FC +=proc_heap:<0.33.0> +3C8570:t6:A5:state,H3905EC,I13,P<0.41.0>,H3905F4,H3C85D4 +3C85D4:lA10:crashdump_viewer|N +3905F4:lH390650|H39065C +390650:t2:A4:port,I8888 +39065C:lH3906C8|H3906D4 +3906C8:t2:AC:bind_address,H390760 +390760:t4:I127,I0,I0,I1 +3906D4:lH390774|H390780 +390774:t2:AB:server_name,H39082C +39082C:lI108|H390908 +390908:lI111|H3909DC +3909DC:lI99|H390AC0 +390AC0:lI97|H390B98 +390B98:lI108|H390C78 +390C78:lI104|H390D58 +390D58:lI111|H390E2C +390E2C:lI115|H390F10 +390F10:lI116|N +390780:lH390834|H390840 +390834:t2:AE:max_header_siz,I1024 +390840:lH390910|H39091C +390910:t2:A11:max_header_action,A8:reply414 +39091C:lH3909E4|H3909F0 +3909E4:t2:A8:com_type,A7:ip_comm +3909F0:lH390AC8|H390AD4 +390AC8:t2:A7:modules,H390BA0 +390BA0:lA9:mod_alias|H390C80 +390C80:lA8:mod_auth|H390D60 +390D60:lA7:mod_esi|H390E34 +390E34:lAB:mod_actions|H390F18 +390F18:lA7:mod_cgi|H390FF4 +390FF4:lAB:mod_include|H3910D8 +3910D8:lA7:mod_dir|H3911B4 +3911B4:lA7:mod_get|H3912A0 +3912A0:lA8:mod_head|H39139C +39139C:lA7:mod_log|H3914A0 +3914A0:lAC:mod_disk_log|N +390AD4:lH390BA8|H390BB4 +390BA8:t2:AF:directory_index,H390C88 +390C88:lH390D68|N +390D68:lI105|H390E3C +390E3C:lI110|H390F20 +390F20:lI100|H390FFC +390FFC:lI101|H3910E0 +3910E0:lI120|H3911BC +3911BC:lI46|H3912A8 +3912A8:lI104|H3913A4 +3913A4:lI116|H3914A8 +3914A8:lI109|H39159C +39159C:lI108|N +390BB4:lH390C90|N +390C90:t2:AC:default_type,H390D70 +390D70:lI116|H390E44 +390E44:lI101|H390F28 +390F28:lI120|H391004 +391004:lI116|H3910E8 +3910E8:lI47|H3911C4 +3911C4:lI112|H3912B0 +3912B0:lI108|H3913AC +3913AC:lI97|H3914B0 +3914B0:lI105|H3915A4 +3915A4:lI110|N +3905EC:lI47|H390648 +390648:lI99|H3906C0 +3906C0:lI108|H390758 +390758:lI101|H390824 +390824:lI97|H390900 +390900:lI114|H3909D4 +3909D4:lI99|H390AB8 +390AB8:lI97|H390B90 +390B90:lI115|H390C70 +390C70:lI101|H390D50 +390D50:lI47|H390E24 +390E24:lI111|H390F08 +390F08:lI116|H390FEC +390FEC:lI112|H3910D0 +3910D0:lI47|H3911AC +3911AC:lI101|H391298 +391298:lI114|H391394 +391394:lI116|H391498 +391498:lI115|H391594 +391594:lI47|H391680 +391680:lI108|H39175C +39175C:lI105|H391840 +391840:lI98|H391924 +391924:lI47|H3919F8 +3919F8:lI119|H391AC4 +391AC4:lI101|H391B90 +391B90:lI98|H391C54 +391C54:lI116|H391D18 +391D18:lI111|H391DD4 +391DD4:lI111|H391E90 +391E90:lI108|H391F5C +391F5C:lI47|H392030 +392030:lI112|H3920EC +3920EC:lI114|H3921A8 +3921A8:lI105|H392264 +392264:lI118|N +3905FC:lAA:gen_server|H390664 +390664:lP<0.27.0>|H3906DC +3906DC:lA4:self|H390788 +390788:lH390848|H390854 +390848:t2:A5:local,A8:web_tool +390854:lA7:webtool|H390924 +390924:lH3909F8|H390A04 +3909F8:t2:H3905EC,H3905F4 +390A04:lN|N +3905C4:t2:AD:$initial_call,H390614 +390614:t3:A3:gen,A7:init_it,H3905FC +3905D0:t2:AA:$ancestors,H390624 +390624:lP<0.27.0>|N +=proc_dictionary:<0.41.0> +H36DF0C +H36DF18 +=proc_stack:<0.41.0> +36eda4:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AA:supervisor +y3:H36EA3C +y4:A6:websup +y5:P<0.33.0> +36edc0:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H36DF24 +=proc_heap:<0.41.0> +36EA3C:tA:A5:state,H36DF2C,AB:one_for_one,H36EA68,N,I100,I10,N,AB:webtool_sup,N +36EA68:lH36EA70|N +36EA70:t8:A5:child,P<0.48.0>,H36DF38,H36DF44,A9:permanent,I100,A6:worker,H36DF54 +36DF54:lA10:crashdump_viewer|N +36DF44:t3:A10:crashdump_viewer,AA:start_link,N +36DF38:t2:A5:local,A17:crashdump_viewer_server +36DF2C:t2:A5:local,A6:websup +36DF24:lAA:gen_server|H36DF84 +36DF84:lP<0.33.0>|H36DF94 +36DF94:lP<0.33.0>|H36DF9C +36DF9C:lH36DFA4|H36DFB0 +36DFA4:t2:A5:local,A6:websup +36DFB0:lAA:supervisor|H36DFB8 +36DFB8:lH36DFC0|H36DFD0 +36DFC0:t3:H36DF2C,AB:webtool_sup,N +36DFD0:lN|N +36DF0C:t2:AD:$initial_call,H36DF6C +36DF6C:t3:A3:gen,A7:init_it,H36DF24 +36DF18:t2:AA:$ancestors,H36DF7C +36DF7C:lA8:web_tool|H36DF8C +36DF8C:lP<0.27.0>|N +=proc_dictionary:<0.43.0> +H39D940 +H39D94C +=proc_stack:<0.43.0> +3a42ac:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AA:supervisor +y3:H3A3E34 +y4:A1A:httpd_sup__127_0_0_1__8888 +y5:P<0.33.0> +3a42c8:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H39D9CC +=proc_heap:<0.43.0> +3A3E34:tA:A5:state,H39D960,AB:one_for_one,H3A3E20,N,I0,I1,N,A9:httpd_sup,H39DA88 +39DA88:lA9:undefined|H39DB18 +39DB18:lH39DB50|H39DB58 +39DB50:lH39DB88|H39DB94 +39DB88:t2:AB:server_root,H39DBD0 +39DBD0:lI47|H39DC0C +39DC0C:lI99|H39DC50 +39DC50:lI108|H39DC84 +39DC84:lI101|H39DCC4 +39DCC4:lI97|H39DD28 +39DD28:lI114|H39DD90 +39DD90:lI99|H39DE00 +39DE00:lI97|H39DE78 +39DE78:lI115|H39DF00 +39DF00:lI101|H39DF90 +39DF90:lI47|H39E038 +39E038:lI111|H39E0E8 +39E0E8:lI116|H39E1AC +39E1AC:lI112|H39E288 +39E288:lI47|H39E37C +39E37C:lI101|H39E478 +39E478:lI114|H39E580 +39E580:lI116|H39E69C +39E69C:lI115|H39E7B0 +39E7B0:lI47|H39E8C4 +39E8C4:lI108|H39E9D8 +39E9D8:lI105|H39EACC +39EACC:lI98|H39EBC0 +39EBC0:lI47|H39ECB4 +39ECB4:lI119|H39EDA8 +39EDA8:lI101|H39EE7C +39EE7C:lI98|H39EF50 +39EF50:lI116|H39F02C +39F02C:lI111|H39F110 +39F110:lI111|H39F1E4 +39F1E4:lI108|H39F2B0 +39F2B0:lI47|H39F36C +39F36C:lI112|H39F430 +39F430:lI114|H39F4FC +39F4FC:lI105|H39F5C0 +39F5C0:lI118|H39F694 +39F694:lI47|H39F768 +39F768:lI114|H39F83C +39F83C:lI111|H39F920 +39F920:lI111|H39F9FC +39F9FC:lI116|N +39DB94:lH39DBD8|H39DBE4 +39DBD8:t2:AD:document_root,H39DC14 +39DC14:lI47|H39DC58 +39DC58:lI99|H39DC8C +39DC8C:lI108|H39DCCC +39DCCC:lI101|H39DD30 +39DD30:lI97|H39DD98 +39DD98:lI114|H39DE08 +39DE08:lI99|H39DE80 +39DE80:lI97|H39DF08 +39DF08:lI115|H39DF98 +39DF98:lI101|H39E040 +39E040:lI47|H39E0F0 +39E0F0:lI111|H39E1B4 +39E1B4:lI116|H39E290 +39E290:lI112|H39E384 +39E384:lI47|H39E480 +39E480:lI101|H39E588 +39E588:lI114|H39E6A4 +39E6A4:lI116|H39E7B8 +39E7B8:lI115|H39E8CC +39E8CC:lI47|H39E9E0 +39E9E0:lI108|H39EAD4 +39EAD4:lI105|H39EBC8 +39EBC8:lI98|H39ECBC +39ECBC:lI47|H39EDB0 +39EDB0:lI119|H39EE84 +39EE84:lI101|H39EF58 +39EF58:lI98|H39F034 +39F034:lI116|H39F118 +39F118:lI111|H39F1EC +39F1EC:lI111|H39F2B8 +39F2B8:lI108|H39F374 +39F374:lI47|H39F438 +39F438:lI112|H39F504 +39F504:lI114|H39F5C8 +39F5C8:lI105|H39F69C +39F69C:lI118|H39F770 +39F770:lI47|H39F844 +39F844:lI114|H39F928 +39F928:lI111|H39FA04 +39FA04:lI111|H39FAD8 +39FAD8:lI116|H39FBB4 +39FBB4:lI47|H39FC80 +39FC80:lI100|H39FD44 +39FD44:lI111|H39FE10 +39FE10:lI99|N +39DBE4:lH39DC1C|H39DC28 +39DC1C:t2:AA:mime_types,H39DC60 +39DC60:lH39DC94|H39DCA0 +39DC94:t2:H39DCD4,H39DCDC +39DCDC:lI120|H39DD40 +39DD40:lI45|H39DDA8 +39DDA8:lI119|H39DE10 +39DE10:lI111|H39DE88 +39DE88:lI114|H39DF10 +39DF10:lI108|H39DFA0 +39DFA0:lI100|H39E048 +39E048:lI47|H39E0F8 +39E0F8:lI120|H39E1BC +39E1BC:lI45|H39E298 +39E298:lI118|H39E38C +39E38C:lI114|H39E488 +39E488:lI109|H39E590 +39E590:lI108|N +39DCD4:lI119|H39DD38 +39DD38:lI114|H39DDA0 +39DDA0:lI108|N +39DCA0:lH39DCE4|H39DCF0 +39DCE4:t2:H39DD48,H39DD50 +39DD50:lI120|H39DDB8 +39DDB8:lI45|H39DE20 +39DE20:lI119|H39DE98 +39DE98:lI111|H39DF18 +39DF18:lI114|H39DFA8 +39DFA8:lI108|H39E050 +39E050:lI100|H39E100 +39E100:lI47|H39E1C4 +39E1C4:lI120|H39E2A0 +39E2A0:lI45|H39E394 +39E394:lI118|H39E490 +39E490:lI114|H39E598 +39E598:lI109|H39E6AC +39E6AC:lI108|N +39DD48:lI118|H39DDB0 +39DDB0:lI114|H39DE18 +39DE18:lI109|H39DE90 +39DE90:lI108|N +39DCF0:lH39DD58|H39DD64 +39DD58:t2:H39DDC0,H39DDC8 +39DDC8:lI120|H39DE30 +39DE30:lI45|H39DEA8 +39DEA8:lI99|H39DF20 +39DF20:lI111|H39DFB0 +39DFB0:lI110|H39E058 +39E058:lI102|H39E108 +39E108:lI101|H39E1CC +39E1CC:lI114|H39E2A8 +39E2A8:lI101|H39E39C +39E39C:lI110|H39E498 +39E498:lI99|H39E5A0 +39E5A0:lI101|H39E6B4 +39E6B4:lI47|H39E7C0 +39E7C0:lI120|H39E8D4 +39E8D4:lI45|H39E9E8 +39E9E8:lI99|H39EADC +39EADC:lI111|H39EBD0 +39EBD0:lI111|H39ECC4 +39ECC4:lI108|H39EDB8 +39EDB8:lI116|H39EE8C +39EE8C:lI97|H39EF60 +39EF60:lI108|H39F03C +39F03C:lI107|N +39DDC0:lI105|H39DE28 +39DE28:lI99|H39DEA0 +39DEA0:lI101|N +39DD64:lH39DDD0|H39DDDC +39DDD0:t2:H39DE38,H39DE40 +39DE40:lI118|H39DEB8 +39DEB8:lI105|H39DF30 +39DF30:lI100|H39DFC0 +39DFC0:lI101|H39E068 +39E068:lI111|H39E110 +39E110:lI47|H39E1D4 +39E1D4:lI120|H39E2B0 +39E2B0:lI45|H39E3A4 +39E3A4:lI115|H39E4A0 +39E4A0:lI103|H39E5A8 +39E5A8:lI105|H39E6BC +39E6BC:lI45|H39E7C8 +39E7C8:lI109|H39E8DC +39E8DC:lI111|H39E9F0 +39E9F0:lI118|H39EAE4 +39EAE4:lI105|H39EBD8 +39EBD8:lI101|N +39DE38:lI109|H39DEB0 +39DEB0:lI111|H39DF28 +39DF28:lI118|H39DFB8 +39DFB8:lI105|H39E060 +39E060:lI101|N +39DDDC:lH39DE48|H39DE54 +39DE48:t2:H39DEC0,H39DEC8 +39DEC8:lI118|H39DF40 +39DF40:lI105|H39DFD0 +39DFD0:lI100|H39E070 +39E070:lI101|H39E118 +39E118:lI111|H39E1DC +39E1DC:lI47|H39E2B8 +39E2B8:lI120|H39E3AC +39E3AC:lI45|H39E4A8 +39E4A8:lI109|H39E5B0 +39E5B0:lI115|H39E6C4 +39E6C4:lI118|H39E7D0 +39E7D0:lI105|H39E8E4 +39E8E4:lI100|H39E9F8 +39E9F8:lI101|H39EAEC +39EAEC:lI111|N +39DEC0:lI97|H39DF38 +39DF38:lI118|H39DFC8 +39DFC8:lI105|N +39DE54:lH39DED0|H39DEDC +39DED0:t2:H39DF48,H39DF50 +39DF50:lI118|H39DFE0 +39DFE0:lI105|H39E078 +39E078:lI100|H39E120 +39E120:lI101|H39E1E4 +39E1E4:lI111|H39E2C0 +39E2C0:lI47|H39E3B4 +39E3B4:lI113|H39E4B0 +39E4B0:lI117|H39E5B8 +39E5B8:lI105|H39E6CC +39E6CC:lI99|H39E7D8 +39E7D8:lI107|H39E8EC +39E8EC:lI116|H39EA00 +39EA00:lI105|H39EAF4 +39EAF4:lI109|H39EBE0 +39EBE0:lI101|N +39DF48:lI113|H39DFD8 +39DFD8:lI116|N +39DEDC:lH39DF58|H39DF64 +39DF58:t2:H39DFE8,H39DFF0 +39DFF0:lI118|H39E088 +39E088:lI105|H39E130 +39E130:lI100|H39E1EC +39E1EC:lI101|H39E2C8 +39E2C8:lI111|H39E3BC +39E3BC:lI47|H39E4B8 +39E4B8:lI113|H39E5C0 +39E5C0:lI117|H39E6D4 +39E6D4:lI105|H39E7E0 +39E7E0:lI99|H39E8F4 +39E8F4:lI107|H39EA08 +39EA08:lI116|H39EAFC +39EAFC:lI105|H39EBE8 +39EBE8:lI109|H39ECCC +39ECCC:lI101|N +39DFE8:lI109|H39E080 +39E080:lI111|H39E128 +39E128:lI118|N +39DF64:lH39DFF8|H39E004 +39DFF8:t2:H39E090,H39E098 +39E098:lI118|H39E140 +39E140:lI105|H39E1FC +39E1FC:lI100|H39E2D8 +39E2D8:lI101|H39E3C4 +39E3C4:lI111|H39E4C0 +39E4C0:lI47|H39E5C8 +39E5C8:lI109|H39E6DC +39E6DC:lI112|H39E7E8 +39E7E8:lI101|H39E8FC +39E8FC:lI103|N +39E090:lI109|H39E138 +39E138:lI112|H39E1F4 +39E1F4:lI101|H39E2D0 +39E2D0:lI103|N +39E004:lH39E0A0|H39E0AC +39E0A0:t2:H39E148,H39E150 +39E150:lI118|H39E20C +39E20C:lI105|H39E2E8 +39E2E8:lI100|H39E3CC +39E3CC:lI101|H39E4C8 +39E4C8:lI111|H39E5D0 +39E5D0:lI47|H39E6E4 +39E6E4:lI109|H39E7F0 +39E7F0:lI112|H39E904 +39E904:lI101|H39EA10 +39EA10:lI103|N +39E148:lI109|H39E204 +39E204:lI112|H39E2E0 +39E2E0:lI103|N +39E0AC:lH39E158|H39E164 +39E158:t2:H39E214,H39E21C +39E21C:lI118|H39E2F8 +39E2F8:lI105|H39E3DC +39E3DC:lI100|H39E4D0 +39E4D0:lI101|H39E5D8 +39E5D8:lI111|H39E6EC +39E6EC:lI47|H39E7F8 +39E7F8:lI109|H39E90C +39E90C:lI112|H39EA18 +39EA18:lI101|H39EB04 +39EB04:lI103|N +39E214:lI109|H39E2F0 +39E2F0:lI112|H39E3D4 +39E3D4:lI101|N +39E164:lH39E224|H39E230 +39E224:t2:H39E300,H39E308 +39E308:lI116|H39E3EC +39E3EC:lI101|H39E4E0 +39E4E0:lI120|H39E5E8 +39E5E8:lI116|H39E6F4 +39E6F4:lI47|H39E800 +39E800:lI120|H39E914 +39E914:lI45|H39EA20 +39EA20:lI115|H39EB0C +39EB0C:lI103|H39EBF0 +39EBF0:lI109|H39ECD4 +39ECD4:lI108|N +39E300:lI115|H39E3E4 +39E3E4:lI103|H39E4D8 +39E4D8:lI109|H39E5E0 +39E5E0:lI108|N +39E230:lH39E310|H39E31C +39E310:t2:H39E3F4,H39E3FC +39E3FC:lI116|H39E4F0 +39E4F0:lI101|H39E5F8 +39E5F8:lI120|H39E6FC +39E6FC:lI116|H39E808 +39E808:lI47|H39E91C +39E91C:lI120|H39EA28 +39EA28:lI45|H39EB14 +39EB14:lI115|H39EBF8 +39EBF8:lI103|H39ECDC +39ECDC:lI109|H39EDC0 +39EDC0:lI108|N +39E3F4:lI115|H39E4E8 +39E4E8:lI103|H39E5F0 +39E5F0:lI109|N +39E31C:lH39E404|H39E410 +39E404:t2:H39E4F8,H39E500 +39E500:lI116|H39E608 +39E608:lI101|H39E70C +39E70C:lI120|H39E810 +39E810:lI116|H39E924 +39E924:lI47|H39EA30 +39EA30:lI120|H39EB1C +39EB1C:lI45|H39EC00 +39EC00:lI115|H39ECE4 +39ECE4:lI101|H39EDC8 +39EDC8:lI116|H39EE94 +39EE94:lI101|H39EF68 +39EF68:lI120|H39F044 +39F044:lI116|N +39E4F8:lI101|H39E600 +39E600:lI116|H39E704 +39E704:lI120|N +39E410:lH39E508|H39E514 +39E508:t2:H39E610,H39E618 +39E618:lI116|H39E71C +39E71C:lI101|H39E820 +39E820:lI120|H39E92C +39E92C:lI116|H39EA38 +39EA38:lI47|H39EB24 +39EB24:lI116|H39EC08 +39EC08:lI97|H39ECEC +39ECEC:lI98|H39EDD0 +39EDD0:lI45|H39EE9C +39EE9C:lI115|H39EF70 +39EF70:lI101|H39F04C +39F04C:lI112|H39F120 +39F120:lI97|H39F1F4 +39F1F4:lI114|H39F2C0 +39F2C0:lI97|H39F37C +39F37C:lI116|H39F440 +39F440:lI101|H39F50C +39F50C:lI100|H39F5D0 +39F5D0:lI45|H39F6A4 +39F6A4:lI118|H39F778 +39F778:lI97|H39F84C +39F84C:lI108|H39F930 +39F930:lI117|H39FA0C +39FA0C:lI101|H39FAE0 +39FAE0:lI115|N +39E610:lI116|H39E714 +39E714:lI115|H39E818 +39E818:lI118|N +39E514:lH39E620|H39E62C +39E620:t2:H39E724,H39E72C +39E72C:lI116|H39E830 +39E830:lI101|H39E93C +39E93C:lI120|H39EA40 +39EA40:lI116|H39EB2C +39EB2C:lI47|H39EC10 +39EC10:lI114|H39ECF4 +39ECF4:lI105|H39EDD8 +39EDD8:lI99|H39EEA4 +39EEA4:lI104|H39EF78 +39EF78:lI116|H39F054 +39F054:lI101|H39F128 +39F128:lI120|H39F1FC +39F1FC:lI116|N +39E724:lI114|H39E828 +39E828:lI116|H39E934 +39E934:lI120|N +39E62C:lH39E734|H39E740 +39E734:t2:H39E838,H39E840 +39E840:lI116|H39E94C +39E94C:lI101|H39EA50 +39EA50:lI120|H39EB34 +39EB34:lI116|H39EC18 +39EC18:lI47|H39ECFC +39ECFC:lI112|H39EDE0 +39EDE0:lI108|H39EEAC +39EEAC:lI97|H39EF80 +39EF80:lI105|H39F05C +39F05C:lI110|N +39E838:lI116|H39E944 +39E944:lI120|H39EA48 +39EA48:lI116|N +39E740:lH39E848|H39E854 +39E848:t2:H39E954,H39E95C +39E95C:lI116|H39EA60 +39EA60:lI101|H39EB44 +39EB44:lI120|H39EC28 +39EC28:lI116|H39ED0C +39ED0C:lI47|H39EDE8 +39EDE8:lI120|H39EEB4 +39EEB4:lI45|H39EF88 +39EF88:lI115|H39F064 +39F064:lI101|H39F130 +39F130:lI114|H39F204 +39F204:lI118|H39F2C8 +39F2C8:lI101|H39F384 +39F384:lI114|H39F448 +39F448:lI45|H39F514 +39F514:lI112|H39F5D8 +39F5D8:lI97|H39F6AC +39F6AC:lI114|H39F780 +39F780:lI115|H39F854 +39F854:lI101|H39F938 +39F938:lI100|H39FA14 +39FA14:lI45|H39FAE8 +39FAE8:lI104|H39FBBC +39FBBC:lI116|H39FC88 +39FC88:lI109|H39FD4C +39FD4C:lI108|N +39E954:lI115|H39EA58 +39EA58:lI104|H39EB3C +39EB3C:lI116|H39EC20 +39EC20:lI109|H39ED04 +39ED04:lI108|N +39E854:lH39E964|H39E970 +39E964:t2:H39EA68,H39EA70 +39EA70:lI116|H39EB54 +39EB54:lI101|H39EC38 +39EC38:lI120|H39ED1C +39ED1C:lI116|H39EDF0 +39EDF0:lI47|H39EEBC +39EEBC:lI104|H39EF90 +39EF90:lI116|H39F06C +39F06C:lI109|H39F138 +39F138:lI108|N +39EA68:lI104|H39EB4C +39EB4C:lI116|H39EC30 +39EC30:lI109|H39ED14 +39ED14:lI108|N +39E970:lH39EA78|H39EA84 +39EA78:t2:H39EB5C,H39EB64 +39EB64:lI116|H39EC48 +39EC48:lI101|H39ED2C +39ED2C:lI120|H39EDF8 +39EDF8:lI116|H39EEC4 +39EEC4:lI47|H39EF98 +39EF98:lI104|H39F074 +39F074:lI116|H39F140 +39F140:lI109|H39F20C +39F20C:lI108|N +39EB5C:lI104|H39EC40 +39EC40:lI116|H39ED24 +39ED24:lI109|N +39EA84:lH39EB6C|H39EB78 +39EB6C:t2:H39EC50,H39EC58 +39EC58:lI105|H39ED3C +39ED3C:lI109|H39EE08 +39EE08:lI97|H39EECC +39EECC:lI103|H39EFA0 +39EFA0:lI101|H39F07C +39F07C:lI47|H39F148 +39F148:lI120|H39F214 +39F214:lI45|H39F2D0 +39F2D0:lI120|H39F38C +39F38C:lI119|H39F450 +39F450:lI105|H39F51C +39F51C:lI110|H39F5E0 +39F5E0:lI100|H39F6B4 +39F6B4:lI111|H39F788 +39F788:lI119|H39F85C +39F85C:lI100|H39F940 +39F940:lI117|H39FA1C +39FA1C:lI109|H39FAF0 +39FAF0:lI112|N +39EC50:lI120|H39ED34 +39ED34:lI119|H39EE00 +39EE00:lI100|N +39EB78:lH39EC60|H39EC6C +39EC60:t2:H39ED44,H39ED4C +39ED4C:lI105|H39EE18 +39EE18:lI109|H39EEDC +39EEDC:lI97|H39EFA8 +39EFA8:lI103|H39F084 +39F084:lI101|H39F150 +39F150:lI47|H39F21C +39F21C:lI120|H39F2D8 +39F2D8:lI45|H39F394 +39F394:lI120|H39F458 +39F458:lI112|H39F524 +39F524:lI105|H39F5E8 +39F5E8:lI120|H39F6BC +39F6BC:lI109|H39F790 +39F790:lI97|H39F864 +39F864:lI112|N +39ED44:lI120|H39EE10 +39EE10:lI112|H39EED4 +39EED4:lI109|N +39EC6C:lH39ED54|H39ED60 +39ED54:t2:H39EE20,H39EE28 +39EE28:lI105|H39EEEC +39EEEC:lI109|H39EFB8 +39EFB8:lI97|H39F08C +39F08C:lI103|H39F158 +39F158:lI101|H39F224 +39F224:lI47|H39F2E0 +39F2E0:lI120|H39F39C +39F39C:lI45|H39F460 +39F460:lI120|H39F52C +39F52C:lI98|H39F5F0 +39F5F0:lI105|H39F6C4 +39F6C4:lI116|H39F798 +39F798:lI109|H39F86C +39F86C:lI97|H39F948 +39F948:lI112|N +39EE20:lI120|H39EEE4 +39EEE4:lI98|H39EFB0 +39EFB0:lI109|N +39ED60:lH39EE30|H39EE3C +39EE30:t2:H39EEF4,H39EEFC +39EEFC:lI105|H39EFC8 +39EFC8:lI109|H39F09C +39F09C:lI97|H39F160 +39F160:lI103|H39F22C +39F22C:lI101|H39F2E8 +39F2E8:lI47|H39F3A4 +39F3A4:lI120|H39F468 +39F468:lI45|H39F534 +39F534:lI114|H39F5F8 +39F5F8:lI103|H39F6CC +39F6CC:lI98|N +39EEF4:lI114|H39EFC0 +39EFC0:lI103|H39F094 +39F094:lI98|N +39EE3C:lH39EF04|H39EF10 +39EF04:t2:H39EFD0,H39EFD8 +39EFD8:lI105|H39F0AC +39F0AC:lI109|H39F170 +39F170:lI97|H39F234 +39F234:lI103|H39F2F0 +39F2F0:lI101|H39F3AC +39F3AC:lI47|H39F470 +39F470:lI120|H39F53C +39F53C:lI45|H39F600 +39F600:lI112|H39F6D4 +39F6D4:lI111|H39F7A0 +39F7A0:lI114|H39F874 +39F874:lI116|H39F950 +39F950:lI97|H39FA24 +39FA24:lI98|H39FAF8 +39FAF8:lI108|H39FBC4 +39FBC4:lI101|H39FC90 +39FC90:lI45|H39FD54 +39FD54:lI112|H39FE18 +39FE18:lI105|H39FECC +39FECC:lI120|H39FF88 +39FF88:lI109|H3A003C +3A003C:lI97|H3A00E8 +3A00E8:lI112|N +39EFD0:lI112|H39F0A4 +39F0A4:lI112|H39F168 +39F168:lI109|N +39EF10:lH39EFE0|H39EFEC +39EFE0:t2:H39F0B4,H39F0BC +39F0BC:lI105|H39F180 +39F180:lI109|H39F244 +39F244:lI97|H39F2F8 +39F2F8:lI103|H39F3B4 +39F3B4:lI101|H39F478 +39F478:lI47|H39F544 +39F544:lI120|H39F608 +39F608:lI45|H39F6DC +39F6DC:lI112|H39F7A8 +39F7A8:lI111|H39F87C +39F87C:lI114|H39F958 +39F958:lI116|H39FA2C +39FA2C:lI97|H39FB00 +39FB00:lI98|H39FBCC +39FBCC:lI108|H39FC98 +39FC98:lI101|H39FD5C +39FD5C:lI45|H39FE20 +39FE20:lI103|H39FED4 +39FED4:lI114|H39FF90 +39FF90:lI97|H3A0044 +3A0044:lI121|H3A00F0 +3A00F0:lI109|H3A0194 +3A0194:lI97|H3A0248 +3A0248:lI112|N +39F0B4:lI112|H39F178 +39F178:lI103|H39F23C +39F23C:lI109|N +39EFEC:lH39F0C4|H39F0D0 +39F0C4:t2:H39F188,H39F190 +39F190:lI105|H39F254 +39F254:lI109|H39F308 +39F308:lI97|H39F3BC +39F3BC:lI103|H39F480 +39F480:lI101|H39F54C +39F54C:lI47|H39F610 +39F610:lI120|H39F6E4 +39F6E4:lI45|H39F7B0 +39F7B0:lI112|H39F884 +39F884:lI111|H39F960 +39F960:lI114|H39FA34 +39FA34:lI116|H39FB08 +39FB08:lI97|H39FBD4 +39FBD4:lI98|H39FCA0 +39FCA0:lI108|H39FD64 +39FD64:lI101|H39FE28 +39FE28:lI45|H39FEDC +39FEDC:lI98|H39FF98 +39FF98:lI105|H3A004C +3A004C:lI116|H3A00F8 +3A00F8:lI109|H3A019C +3A019C:lI97|H3A0250 +3A0250:lI112|N +39F188:lI112|H39F24C +39F24C:lI98|H39F300 +39F300:lI109|N +39F0D0:lH39F198|H39F1A4 +39F198:t2:H39F25C,H39F264 +39F264:lI105|H39F318 +39F318:lI109|H39F3CC +39F3CC:lI97|H39F488 +39F488:lI103|H39F554 +39F554:lI101|H39F618 +39F618:lI47|H39F6EC +39F6EC:lI120|H39F7B8 +39F7B8:lI45|H39F88C +39F88C:lI112|H39F968 +39F968:lI111|H39FA3C +39FA3C:lI114|H39FB10 +39FB10:lI116|H39FBDC +39FBDC:lI97|H39FCA8 +39FCA8:lI98|H39FD6C +39FD6C:lI108|H39FE30 +39FE30:lI101|H39FEE4 +39FEE4:lI45|H39FFA0 +39FFA0:lI97|H3A0054 +3A0054:lI110|H3A0100 +3A0100:lI121|H3A01A4 +3A01A4:lI109|H3A0258 +3A0258:lI97|H3A0304 +3A0304:lI112|N +39F25C:lI112|H39F310 +39F310:lI110|H39F3C4 +39F3C4:lI109|N +39F1A4:lH39F26C|H39F278 +39F26C:t2:H39F320,H39F328 +39F328:lI105|H39F3DC +39F3DC:lI109|H39F498 +39F498:lI97|H39F55C +39F55C:lI103|H39F620 +39F620:lI101|H39F6F4 +39F6F4:lI47|H39F7C0 +39F7C0:lI120|H39F894 +39F894:lI45|H39F970 +39F970:lI99|H39FA44 +39FA44:lI109|H39FB18 +39FB18:lI117|H39FBE4 +39FBE4:lI45|H39FCB0 +39FCB0:lI114|H39FD74 +39FD74:lI97|H39FE38 +39FE38:lI115|H39FEEC +39FEEC:lI116|H39FFA8 +39FFA8:lI101|H3A005C +3A005C:lI114|N +39F320:lI114|H39F3D4 +39F3D4:lI97|H39F490 +39F490:lI115|N +39F278:lH39F330|H39F33C +39F330:t2:H39F3E4,H39F3EC +39F3EC:lI105|H39F4A8 +39F4A8:lI109|H39F56C +39F56C:lI97|H39F630 +39F630:lI103|H39F6FC +39F6FC:lI101|H39F7C8 +39F7C8:lI47|H39F89C +39F89C:lI116|H39F978 +39F978:lI105|H39FA4C +39FA4C:lI102|H39FB20 +39FB20:lI102|N +39F3E4:lI116|H39F4A0 +39F4A0:lI105|H39F564 +39F564:lI102|H39F628 +39F628:lI102|N +39F33C:lH39F3F4|H39F400 +39F3F4:t2:H39F4B0,H39F4B8 +39F4B8:lI105|H39F57C +39F57C:lI109|H39F640 +39F640:lI97|H39F704 +39F704:lI103|H39F7D0 +39F7D0:lI101|H39F8A4 +39F8A4:lI47|H39F980 +39F980:lI116|H39FA54 +39FA54:lI105|H39FB28 +39FB28:lI102|H39FBEC +39FBEC:lI102|N +39F4B0:lI116|H39F574 +39F574:lI105|H39F638 +39F638:lI102|N +39F400:lH39F4C0|H39F4CC +39F4C0:t2:H39F584,H39F58C +39F58C:lI105|H39F650 +39F650:lI109|H39F714 +39F714:lI97|H39F7D8 +39F7D8:lI103|H39F8AC +39F8AC:lI101|H39F988 +39F988:lI47|H39FA5C +39FA5C:lI112|H39FB30 +39FB30:lI110|H39FBF4 +39FBF4:lI103|N +39F584:lI112|H39F648 +39F648:lI110|H39F70C +39F70C:lI103|N +39F4CC:lH39F594|H39F5A0 +39F594:t2:H39F658,H39F660 +39F660:lI105|H39F724 +39F724:lI109|H39F7E8 +39F7E8:lI97|H39F8BC +39F8BC:lI103|H39F990 +39F990:lI101|H39FA64 +39FA64:lI47|H39FB38 +39FB38:lI106|H39FBFC +39FBFC:lI112|H39FCB8 +39FCB8:lI101|H39FD7C +39FD7C:lI103|N +39F658:lI106|H39F71C +39F71C:lI112|H39F7E0 +39F7E0:lI101|H39F8B4 +39F8B4:lI103|N +39F5A0:lH39F668|H39F674 +39F668:t2:H39F72C,H39F734 +39F734:lI105|H39F7F8 +39F7F8:lI109|H39F8CC +39F8CC:lI97|H39F998 +39F998:lI103|H39FA6C +39FA6C:lI101|H39FB40 +39FB40:lI47|H39FC04 +39FC04:lI106|H39FCC0 +39FCC0:lI112|H39FD84 +39FD84:lI101|H39FE40 +39FE40:lI103|N +39F72C:lI106|H39F7F0 +39F7F0:lI112|H39F8C4 +39F8C4:lI103|N +39F674:lH39F73C|H39F748 +39F73C:t2:H39F800,H39F808 +39F808:lI105|H39F8DC +39F8DC:lI109|H39F9A8 +39F9A8:lI97|H39FA74 +39FA74:lI103|H39FB48 +39FB48:lI101|H39FC0C +39FC0C:lI47|H39FCC8 +39FCC8:lI106|H39FD8C +39FD8C:lI112|H39FE48 +39FE48:lI101|H39FEF4 +39FEF4:lI103|N +39F800:lI106|H39F8D4 +39F8D4:lI112|H39F9A0 +39F9A0:lI101|N +39F748:lH39F810|H39F81C +39F810:t2:H39F8E4,H39F8EC +39F8EC:lI105|H39F9B8 +39F9B8:lI109|H39FA84 +39FA84:lI97|H39FB50 +39FB50:lI103|H39FC14 +39FC14:lI101|H39FCD0 +39FCD0:lI47|H39FD94 +39FD94:lI105|H39FE50 +39FE50:lI101|H39FEFC +39FEFC:lI102|N +39F8E4:lI105|H39F9B0 +39F9B0:lI101|H39FA7C +39FA7C:lI102|N +39F81C:lH39F8F4|H39F900 +39F8F4:t2:H39F9C0,H39F9C8 +39F9C8:lI105|H39FA94 +39FA94:lI109|H39FB60 +39FB60:lI97|H39FC1C +39FC1C:lI103|H39FCD8 +39FCD8:lI101|H39FD9C +39FD9C:lI47|H39FE58 +39FE58:lI103|H39FF04 +39FF04:lI105|H39FFB0 +39FFB0:lI102|N +39F9C0:lI103|H39FA8C +39FA8C:lI105|H39FB58 +39FB58:lI102|N +39F900:lH39F9D0|H39F9DC +39F9D0:t2:H39FA9C,H39FAA4 +39FAA4:lI99|H39FB70 +39FB70:lI104|H39FC2C +39FC2C:lI101|H39FCE0 +39FCE0:lI109|H39FDA4 +39FDA4:lI105|H39FE60 +39FE60:lI99|H39FF0C +39FF0C:lI97|H39FFB8 +39FFB8:lI108|H3A0064 +3A0064:lI47|H3A0108 +3A0108:lI120|H3A01AC +3A01AC:lI45|H3A0260 +3A0260:lI112|H3A030C +3A030C:lI100|H3A03B8 +3A03B8:lI98|N +39FA9C:lI112|H39FB68 +39FB68:lI100|H39FC24 +39FC24:lI98|N +39F9DC:lH39FAAC|H39FAB8 +39FAAC:t2:H39FB78,H39FB80 +39FB80:lI99|H39FC3C +39FC3C:lI104|H39FCF0 +39FCF0:lI101|H39FDAC +39FDAC:lI109|H39FE68 +39FE68:lI105|H39FF14 +39FF14:lI99|H39FFC0 +39FFC0:lI97|H3A006C +3A006C:lI108|H3A0110 +3A0110:lI47|H3A01B4 +3A01B4:lI120|H3A0268 +3A0268:lI45|H3A0314 +3A0314:lI112|H3A03C0 +3A03C0:lI100|H3A0454 +3A0454:lI98|N +39FB78:lI120|H39FC34 +39FC34:lI121|H39FCE8 +39FCE8:lI122|N +39FAB8:lH39FB88|H39FB94 +39FB88:t2:H39FC44,H39FC4C +39FC4C:lI97|H39FD00 +39FD00:lI117|H39FDBC +39FDBC:lI100|H39FE70 +39FE70:lI105|H39FF1C +39FF1C:lI111|H39FFC8 +39FFC8:lI47|H3A0074 +3A0074:lI120|H3A0118 +3A0118:lI45|H3A01BC +3A01BC:lI119|H3A0270 +3A0270:lI97|H3A031C +3A031C:lI118|N +39FC44:lI119|H39FCF8 +39FCF8:lI97|H39FDB4 +39FDB4:lI118|N +39FB94:lH39FC54|H39FC60 +39FC54:t2:H39FD08,H39FD10 +39FD10:lI97|H39FDCC +39FDCC:lI117|H39FE78 +39FE78:lI100|H39FF24 +39FF24:lI105|H39FFD0 +39FFD0:lI111|H3A007C +3A007C:lI47|H3A0120 +3A0120:lI120|H3A01C4 +3A01C4:lI45|H3A0278 +3A0278:lI114|H3A0324 +3A0324:lI101|H3A03C8 +3A03C8:lI97|H3A045C +3A045C:lI108|H3A04F8 +3A04F8:lI97|H3A059C +3A059C:lI117|H3A0648 +3A0648:lI100|H3A06F4 +3A06F4:lI105|H3A07A0 +3A07A0:lI111|N +39FD08:lI114|H39FDC4 +39FDC4:lI97|N +39FC60:lH39FD18|H39FD24 +39FD18:t2:H39FDD4,H39FDDC +39FDDC:lI97|H39FE88 +39FE88:lI117|H39FF34 +39FF34:lI100|H39FFD8 +39FFD8:lI105|H3A0084 +3A0084:lI111|H3A0128 +3A0128:lI47|H3A01CC +3A01CC:lI120|H3A0280 +3A0280:lI45|H3A032C +3A032C:lI112|H3A03D0 +3A03D0:lI110|H3A0464 +3A0464:lI45|H3A0500 +3A0500:lI114|H3A05A4 +3A05A4:lI101|H3A0650 +3A0650:lI97|H3A06FC +3A06FC:lI108|H3A07A8 +3A07A8:lI97|H3A0844 +3A0844:lI117|H3A08D0 +3A08D0:lI100|H3A0964 +3A0964:lI105|H3A09F8 +3A09F8:lI111|H3A0A94 +3A0A94:lI45|H3A0B40 +3A0B40:lI112|H3A0BEC +3A0BEC:lI108|H3A0CA8 +3A0CA8:lI117|H3A0D64 +3A0D64:lI103|H3A0E18 +3A0E18:lI105|H3A0ECC +3A0ECC:lI110|N +39FDD4:lI114|H39FE80 +39FE80:lI112|H39FF2C +39FF2C:lI109|N +39FD24:lH39FDE4|H39FDF0 +39FDE4:t2:H39FE90,H39FE98 +39FE98:lI97|H39FF44 +39FF44:lI117|H39FFE8 +39FFE8:lI100|H3A008C +3A008C:lI105|H3A0130 +3A0130:lI111|H3A01D4 +3A01D4:lI47|H3A0288 +3A0288:lI120|H3A0334 +3A0334:lI45|H3A03D8 +3A03D8:lI112|H3A046C +3A046C:lI110|H3A0508 +3A0508:lI45|H3A05AC +3A05AC:lI114|H3A0658 +3A0658:lI101|H3A0704 +3A0704:lI97|H3A07B0 +3A07B0:lI108|H3A084C +3A084C:lI97|H3A08D8 +3A08D8:lI117|H3A096C +3A096C:lI100|H3A0A00 +3A0A00:lI105|H3A0A9C +3A0A9C:lI111|N +39FE90:lI114|H39FF3C +39FF3C:lI97|H39FFE0 +39FFE0:lI109|N +39FDF0:lH39FEA0|H39FEAC +39FEA0:t2:H39FF4C,H39FF54 +39FF54:lI97|H39FFF8 +39FFF8:lI117|H3A009C +3A009C:lI100|H3A0138 +3A0138:lI105|H3A01DC +3A01DC:lI111|H3A0290 +3A0290:lI47|H3A033C +3A033C:lI120|H3A03E0 +3A03E0:lI45|H3A0474 +3A0474:lI97|H3A0510 +3A0510:lI105|H3A05B4 +3A05B4:lI102|H3A0660 +3A0660:lI102|N +39FF4C:lI97|H39FFF0 +39FFF0:lI105|H3A0094 +3A0094:lI102|N +39FEAC:lH39FF5C|H39FF68 +39FF5C:t2:H3A0000,H3A0008 +3A0008:lI97|H3A00AC +3A00AC:lI117|H3A0148 +3A0148:lI100|H3A01EC +3A01EC:lI105|H3A0298 +3A0298:lI111|H3A0344 +3A0344:lI47|H3A03E8 +3A03E8:lI120|H3A047C +3A047C:lI45|H3A0518 +3A0518:lI97|H3A05BC +3A05BC:lI105|H3A0668 +3A0668:lI102|H3A070C +3A070C:lI102|N +3A0000:lI97|H3A00A4 +3A00A4:lI105|H3A0140 +3A0140:lI102|H3A01E4 +3A01E4:lI102|N +39FF68:lH3A0010|H3A001C +3A0010:t2:H3A00B4,H3A00BC +3A00BC:lI97|H3A0158 +3A0158:lI117|H3A01FC +3A01FC:lI100|H3A02A8 +3A02A8:lI105|H3A034C +3A034C:lI111|H3A03F0 +3A03F0:lI47|H3A0484 +3A0484:lI120|H3A0520 +3A0520:lI45|H3A05C4 +3A05C4:lI97|H3A0670 +3A0670:lI105|H3A0714 +3A0714:lI102|H3A07B8 +3A07B8:lI102|N +3A00B4:lI97|H3A0150 +3A0150:lI105|H3A01F4 +3A01F4:lI102|H3A02A0 +3A02A0:lI99|N +3A001C:lH3A00C4|H3A00D0 +3A00C4:t2:H3A0160,H3A0168 +3A0168:lI97|H3A020C +3A020C:lI117|H3A02B8 +3A02B8:lI100|H3A035C +3A035C:lI105|H3A03F8 +3A03F8:lI111|H3A048C +3A048C:lI47|H3A0528 +3A0528:lI109|H3A05CC +3A05CC:lI112|H3A0678 +3A0678:lI101|H3A071C +3A071C:lI103|N +3A0160:lI109|H3A0204 +3A0204:lI112|H3A02B0 +3A02B0:lI103|H3A0354 +3A0354:lI97|N +3A00D0:lH3A0170|H3A017C +3A0170:t2:H3A0214,H3A021C +3A021C:lI97|H3A02C8 +3A02C8:lI117|H3A036C +3A036C:lI100|H3A0400 +3A0400:lI105|H3A0494 +3A0494:lI111|H3A0530 +3A0530:lI47|H3A05D4 +3A05D4:lI109|H3A0680 +3A0680:lI112|H3A0724 +3A0724:lI101|H3A07C0 +3A07C0:lI103|N +3A0214:lI109|H3A02C0 +3A02C0:lI112|H3A0364 +3A0364:lI50|N +3A017C:lH3A0224|H3A0230 +3A0224:t2:H3A02D0,H3A02D8 +3A02D8:lI97|H3A037C +3A037C:lI117|H3A0408 +3A0408:lI100|H3A049C +3A049C:lI105|H3A0538 +3A0538:lI111|H3A05DC +3A05DC:lI47|H3A0688 +3A0688:lI98|H3A072C +3A072C:lI97|H3A07C8 +3A07C8:lI115|H3A0854 +3A0854:lI105|H3A08E0 +3A08E0:lI99|N +3A02D0:lI97|H3A0374 +3A0374:lI117|N +3A0230:lH3A02E0|H3A02EC +3A02E0:t2:H3A0384,H3A038C +3A038C:lI97|H3A0418 +3A0418:lI117|H3A04AC +3A04AC:lI100|H3A0540 +3A0540:lI105|H3A05E4 +3A05E4:lI111|H3A0690 +3A0690:lI47|H3A0734 +3A0734:lI98|H3A07D0 +3A07D0:lI97|H3A085C +3A085C:lI115|H3A08E8 +3A08E8:lI105|H3A0974 +3A0974:lI99|N +3A0384:lI115|H3A0410 +3A0410:lI110|H3A04A4 +3A04A4:lI100|N +3A02EC:lH3A0394|H3A03A0 +3A0394:t2:H3A0420,H3A0428 +3A0428:lI97|H3A04BC +3A04BC:lI112|H3A0550 +3A0550:lI112|H3A05EC +3A05EC:lI108|H3A0698 +3A0698:lI105|H3A073C +3A073C:lI99|H3A07D8 +3A07D8:lI97|H3A0864 +3A0864:lI116|H3A08F0 +3A08F0:lI105|H3A097C +3A097C:lI111|H3A0A08 +3A0A08:lI110|H3A0AA4 +3A0AA4:lI47|H3A0B48 +3A0B48:lI122|H3A0BF4 +3A0BF4:lI105|H3A0CB0 +3A0CB0:lI112|N +3A0420:lI122|H3A04B4 +3A04B4:lI105|H3A0548 +3A0548:lI112|N +3A03A0:lH3A0430|H3A043C +3A0430:t2:H3A04C4,H3A04CC +3A04CC:lI97|H3A0560 +3A0560:lI112|H3A05FC +3A05FC:lI112|H3A06A0 +3A06A0:lI108|H3A0744 +3A0744:lI105|H3A07E0 +3A07E0:lI99|H3A086C +3A086C:lI97|H3A08F8 +3A08F8:lI116|H3A0984 +3A0984:lI105|H3A0A10 +3A0A10:lI111|H3A0AAC +3A0AAC:lI110|H3A0B50 +3A0B50:lI47|H3A0BFC +3A0BFC:lI120|H3A0CB8 +3A0CB8:lI45|H3A0D6C +3A0D6C:lI119|H3A0E20 +3A0E20:lI97|H3A0ED4 +3A0ED4:lI105|H3A0F90 +3A0F90:lI115|H3A105C +3A105C:lI45|H3A1130 +3A1130:lI115|H3A1204 +3A1204:lI111|H3A12D0 +3A12D0:lI117|H3A13A4 +3A13A4:lI114|H3A1480 +3A1480:lI99|H3A1564 +3A1564:lI101|N +3A04C4:lI115|H3A0558 +3A0558:lI114|H3A05F4 +3A05F4:lI99|N +3A043C:lH3A04D4|H3A04E0 +3A04D4:t2:H3A0568,H3A0570 +3A0570:lI97|H3A060C +3A060C:lI112|H3A06B0 +3A06B0:lI112|H3A0754 +3A0754:lI108|H3A07F0 +3A07F0:lI105|H3A0874 +3A0874:lI99|H3A0900 +3A0900:lI97|H3A098C +3A098C:lI116|H3A0A18 +3A0A18:lI105|H3A0AB4 +3A0AB4:lI111|H3A0B58 +3A0B58:lI110|H3A0C04 +3A0C04:lI47|H3A0CC0 +3A0CC0:lI120|H3A0D74 +3A0D74:lI45|H3A0E28 +3A0E28:lI117|H3A0EDC +3A0EDC:lI115|H3A0F98 +3A0F98:lI116|H3A1064 +3A1064:lI97|H3A1138 +3A1138:lI114|N +3A0568:lI117|H3A0604 +3A0604:lI115|H3A06A8 +3A06A8:lI116|H3A074C +3A074C:lI97|H3A07E8 +3A07E8:lI114|N +3A04E0:lH3A0578|H3A0584 +3A0578:t2:H3A0614,H3A061C +3A061C:lI97|H3A06C0 +3A06C0:lI112|H3A075C +3A075C:lI112|H3A07F8 +3A07F8:lI108|H3A087C +3A087C:lI105|H3A0908 +3A0908:lI99|H3A0994 +3A0994:lI97|H3A0A20 +3A0A20:lI116|H3A0ABC +3A0ABC:lI105|H3A0B60 +3A0B60:lI111|H3A0C0C +3A0C0C:lI110|H3A0CC8 +3A0CC8:lI47|H3A0D7C +3A0D7C:lI120|H3A0E30 +3A0E30:lI45|H3A0EE4 +3A0EE4:lI116|H3A0FA0 +3A0FA0:lI114|H3A106C +3A106C:lI111|H3A1140 +3A1140:lI102|H3A120C +3A120C:lI102|H3A12D8 +3A12D8:lI45|H3A13AC +3A13AC:lI109|H3A1488 +3A1488:lI115|N +3A0614:lI109|H3A06B8 +3A06B8:lI115|N +3A0584:lH3A0624|H3A0630 +3A0624:t2:H3A06C8,H3A06D0 +3A06D0:lI97|H3A076C +3A076C:lI112|H3A0800 +3A0800:lI112|H3A0884 +3A0884:lI108|H3A0910 +3A0910:lI105|H3A099C +3A099C:lI99|H3A0A28 +3A0A28:lI97|H3A0AC4 +3A0AC4:lI116|H3A0B68 +3A0B68:lI105|H3A0C14 +3A0C14:lI111|H3A0CD0 +3A0CD0:lI110|H3A0D84 +3A0D84:lI47|H3A0E38 +3A0E38:lI120|H3A0EEC +3A0EEC:lI45|H3A0FA8 +3A0FA8:lI116|H3A1074 +3A1074:lI114|H3A1148 +3A1148:lI111|H3A1214 +3A1214:lI102|H3A12E0 +3A12E0:lI102|H3A13B4 +3A13B4:lI45|H3A1490 +3A1490:lI109|H3A156C +3A156C:lI101|N +3A06C8:lI109|H3A0764 +3A0764:lI101|N +3A0630:lH3A06D8|H3A06E4 +3A06D8:t2:H3A0774,H3A077C +3A077C:lI97|H3A0810 +3A0810:lI112|H3A0894 +3A0894:lI112|H3A0918 +3A0918:lI108|H3A09A4 +3A09A4:lI105|H3A0A30 +3A0A30:lI99|H3A0ACC +3A0ACC:lI97|H3A0B70 +3A0B70:lI116|H3A0C1C +3A0C1C:lI105|H3A0CD8 +3A0CD8:lI111|H3A0D8C +3A0D8C:lI110|H3A0E40 +3A0E40:lI47|H3A0EF4 +3A0EF4:lI120|H3A0FB0 +3A0FB0:lI45|H3A107C +3A107C:lI116|H3A1150 +3A1150:lI114|H3A121C +3A121C:lI111|H3A12E8 +3A12E8:lI102|H3A13BC +3A13BC:lI102|H3A1498 +3A1498:lI45|H3A1574 +3A1574:lI109|H3A1648 +3A1648:lI97|H3A171C +3A171C:lI110|N +3A0774:lI109|H3A0808 +3A0808:lI97|H3A088C +3A088C:lI110|N +3A06E4:lH3A0784|H3A0790 +3A0784:t2:H3A0818,H3A0820 +3A0820:lI97|H3A089C +3A089C:lI112|H3A0920 +3A0920:lI112|H3A09AC +3A09AC:lI108|H3A0A38 +3A0A38:lI105|H3A0AD4 +3A0AD4:lI99|H3A0B78 +3A0B78:lI97|H3A0C24 +3A0C24:lI116|H3A0CE0 +3A0CE0:lI105|H3A0D94 +3A0D94:lI111|H3A0E48 +3A0E48:lI110|H3A0EFC +3A0EFC:lI47|H3A0FB8 +3A0FB8:lI120|H3A1084 +3A1084:lI45|H3A1158 +3A1158:lI116|H3A1224 +3A1224:lI114|H3A12F0 +3A12F0:lI111|H3A13C4 +3A13C4:lI102|H3A14A0 +3A14A0:lI102|N +3A0818:lI116|N +3A0790:lH3A0828|H3A0834 +3A0828:t2:H3A08A4,H3A08AC +3A08AC:lI97|H3A0930 +3A0930:lI112|H3A09B4 +3A09B4:lI112|H3A0A40 +3A0A40:lI108|H3A0ADC +3A0ADC:lI105|H3A0B80 +3A0B80:lI99|H3A0C2C +3A0C2C:lI97|H3A0CE8 +3A0CE8:lI116|H3A0D9C +3A0D9C:lI105|H3A0E50 +3A0E50:lI111|H3A0F04 +3A0F04:lI110|H3A0FC0 +3A0FC0:lI47|H3A108C +3A108C:lI120|H3A1160 +3A1160:lI45|H3A122C +3A122C:lI116|H3A12F8 +3A12F8:lI114|H3A13CC +3A13CC:lI111|H3A14A8 +3A14A8:lI102|H3A157C +3A157C:lI102|N +3A08A4:lI116|H3A0928 +3A0928:lI114|N +3A0834:lH3A08B4|H3A08C0 +3A08B4:t2:H3A0938,H3A0940 +3A0940:lI97|H3A09C4 +3A09C4:lI112|H3A0A50 +3A0A50:lI112|H3A0AEC +3A0AEC:lI108|H3A0B88 +3A0B88:lI105|H3A0C34 +3A0C34:lI99|H3A0CF0 +3A0CF0:lI97|H3A0DA4 +3A0DA4:lI116|H3A0E58 +3A0E58:lI105|H3A0F0C +3A0F0C:lI111|H3A0FC8 +3A0FC8:lI110|H3A1094 +3A1094:lI47|H3A1168 +3A1168:lI120|H3A1234 +3A1234:lI45|H3A1300 +3A1300:lI116|H3A13D4 +3A13D4:lI114|H3A14B0 +3A14B0:lI111|H3A1584 +3A1584:lI102|H3A1650 +3A1650:lI102|N +3A0938:lI114|H3A09BC +3A09BC:lI111|H3A0A48 +3A0A48:lI102|H3A0AE4 +3A0AE4:lI102|N +3A08C0:lH3A0948|H3A0954 +3A0948:t2:H3A09CC,H3A09D4 +3A09D4:lI97|H3A0A60 +3A0A60:lI112|H3A0AFC +3A0AFC:lI112|H3A0B98 +3A0B98:lI108|H3A0C44 +3A0C44:lI105|H3A0D00 +3A0D00:lI99|H3A0DB4 +3A0DB4:lI97|H3A0E60 +3A0E60:lI116|H3A0F14 +3A0F14:lI105|H3A0FD0 +3A0FD0:lI111|H3A109C +3A109C:lI110|H3A1170 +3A1170:lI47|H3A123C +3A123C:lI120|H3A1308 +3A1308:lI45|H3A13DC +3A13DC:lI116|H3A14B8 +3A14B8:lI101|H3A158C +3A158C:lI120|H3A1658 +3A1658:lI105|H3A1724 +3A1724:lI110|H3A17E8 +3A17E8:lI102|H3A18AC +3A18AC:lI111|N +3A09CC:lI116|H3A0A58 +3A0A58:lI101|H3A0AF4 +3A0AF4:lI120|H3A0B90 +3A0B90:lI105|H3A0C3C +3A0C3C:lI110|H3A0CF8 +3A0CF8:lI102|H3A0DAC +3A0DAC:lI111|N +3A0954:lH3A09DC|H3A09E8 +3A09DC:t2:H3A0A68,H3A0A70 +3A0A70:lI97|H3A0B0C +3A0B0C:lI112|H3A0BA8 +3A0BA8:lI112|H3A0C54 +3A0C54:lI108|H3A0D08 +3A0D08:lI105|H3A0DBC +3A0DBC:lI99|H3A0E68 +3A0E68:lI97|H3A0F1C +3A0F1C:lI116|H3A0FD8 +3A0FD8:lI105|H3A10A4 +3A10A4:lI111|H3A1178 +3A1178:lI110|H3A1244 +3A1244:lI47|H3A1310 +3A1310:lI120|H3A13E4 +3A13E4:lI45|H3A14C0 +3A14C0:lI116|H3A1594 +3A1594:lI101|H3A1660 +3A1660:lI120|H3A172C +3A172C:lI105|H3A17F0 +3A17F0:lI110|H3A18B4 +3A18B4:lI102|H3A1970 +3A1970:lI111|N +3A0A68:lI116|H3A0B04 +3A0B04:lI101|H3A0BA0 +3A0BA0:lI120|H3A0C4C +3A0C4C:lI105|N +3A09E8:lH3A0A78|H3A0A84 +3A0A78:t2:H3A0B14,H3A0B1C +3A0B1C:lI97|H3A0BB8 +3A0BB8:lI112|H3A0C64 +3A0C64:lI112|H3A0D10 +3A0D10:lI108|H3A0DC4 +3A0DC4:lI105|H3A0E70 +3A0E70:lI99|H3A0F24 +3A0F24:lI97|H3A0FE0 +3A0FE0:lI116|H3A10AC +3A10AC:lI105|H3A1180 +3A1180:lI111|H3A124C +3A124C:lI110|H3A1318 +3A1318:lI47|H3A13EC +3A13EC:lI120|H3A14C8 +3A14C8:lI45|H3A159C +3A159C:lI116|H3A1668 +3A1668:lI101|H3A1734 +3A1734:lI120|N +3A0B14:lI116|H3A0BB0 +3A0BB0:lI101|H3A0C5C +3A0C5C:lI120|N +3A0A84:lH3A0B24|H3A0B30 +3A0B24:t2:H3A0BC0,H3A0BC8 +3A0BC8:lI97|H3A0C74 +3A0C74:lI112|H3A0D20 +3A0D20:lI112|H3A0DCC +3A0DCC:lI108|H3A0E78 +3A0E78:lI105|H3A0F2C +3A0F2C:lI99|H3A0FE8 +3A0FE8:lI97|H3A10B4 +3A10B4:lI116|H3A1188 +3A1188:lI105|H3A1254 +3A1254:lI111|H3A1320 +3A1320:lI110|H3A13F4 +3A13F4:lI47|H3A14D0 +3A14D0:lI120|H3A15A4 +3A15A4:lI45|H3A1670 +3A1670:lI116|H3A173C +3A173C:lI99|H3A17F8 +3A17F8:lI108|N +3A0BC0:lI116|H3A0C6C +3A0C6C:lI99|H3A0D18 +3A0D18:lI108|N +3A0B30:lH3A0BD0|H3A0BDC +3A0BD0:t2:H3A0C7C,H3A0C84 +3A0C84:lI97|H3A0D30 +3A0D30:lI112|H3A0DDC +3A0DDC:lI112|H3A0E80 +3A0E80:lI108|H3A0F34 +3A0F34:lI105|H3A0FF0 +3A0FF0:lI99|H3A10BC +3A10BC:lI97|H3A1190 +3A1190:lI116|H3A125C +3A125C:lI105|H3A1328 +3A1328:lI111|H3A13FC +3A13FC:lI110|H3A14D8 +3A14D8:lI47|H3A15AC +3A15AC:lI120|H3A1678 +3A1678:lI45|H3A1744 +3A1744:lI116|H3A1800 +3A1800:lI97|H3A18BC +3A18BC:lI114|N +3A0C7C:lI116|H3A0D28 +3A0D28:lI97|H3A0DD4 +3A0DD4:lI114|N +3A0BDC:lH3A0C8C|H3A0C98 +3A0C8C:t2:H3A0D38,H3A0D40 +3A0D40:lI97|H3A0DEC +3A0DEC:lI112|H3A0E90 +3A0E90:lI112|H3A0F44 +3A0F44:lI108|H3A1000 +3A1000:lI105|H3A10CC +3A10CC:lI99|H3A1198 +3A1198:lI97|H3A1264 +3A1264:lI116|H3A1330 +3A1330:lI105|H3A1404 +3A1404:lI111|H3A14E0 +3A14E0:lI110|H3A15B4 +3A15B4:lI47|H3A1680 +3A1680:lI120|H3A174C +3A174C:lI45|H3A1808 +3A1808:lI115|H3A18C4 +3A18C4:lI118|H3A1978 +3A1978:lI52|H3A1A2C +3A1A2C:lI99|H3A1AE0 +3A1AE0:lI114|H3A1BA4 +3A1BA4:lI99|N +3A0D38:lI115|H3A0DE4 +3A0DE4:lI118|H3A0E88 +3A0E88:lI52|H3A0F3C +3A0F3C:lI99|H3A0FF8 +3A0FF8:lI114|H3A10C4 +3A10C4:lI99|N +3A0C98:lH3A0D48|H3A0D54 +3A0D48:t2:H3A0DF4,H3A0DFC +3A0DFC:lI97|H3A0EA0 +3A0EA0:lI112|H3A0F54 +3A0F54:lI112|H3A1010 +3A1010:lI108|H3A10DC +3A10DC:lI105|H3A11A8 +3A11A8:lI99|H3A1274 +3A1274:lI97|H3A1338 +3A1338:lI116|H3A140C +3A140C:lI105|H3A14E8 +3A14E8:lI111|H3A15BC +3A15BC:lI110|H3A1688 +3A1688:lI47|H3A1754 +3A1754:lI120|H3A1810 +3A1810:lI45|H3A18CC +3A18CC:lI115|H3A1980 +3A1980:lI118|H3A1A34 +3A1A34:lI52|H3A1AE8 +3A1AE8:lI99|H3A1BAC +3A1BAC:lI112|H3A1C78 +3A1C78:lI105|H3A1D3C +3A1D3C:lI111|N +3A0DF4:lI115|H3A0E98 +3A0E98:lI118|H3A0F4C +3A0F4C:lI52|H3A1008 +3A1008:lI99|H3A10D4 +3A10D4:lI112|H3A11A0 +3A11A0:lI105|H3A126C +3A126C:lI111|N +3A0D54:lH3A0E04|H3A0E10 +3A0E04:t2:H3A0EA8,H3A0EB0 +3A0EB0:lI97|H3A0F64 +3A0F64:lI112|H3A1020 +3A1020:lI112|H3A10E4 +3A10E4:lI108|H3A11B0 +3A11B0:lI105|H3A127C +3A127C:lI99|H3A1340 +3A1340:lI97|H3A1414 +3A1414:lI116|H3A14F0 +3A14F0:lI105|H3A15C4 +3A15C4:lI111|H3A1690 +3A1690:lI110|H3A175C +3A175C:lI47|H3A1818 +3A1818:lI120|H3A18D4 +3A18D4:lI45|H3A1988 +3A1988:lI115|H3A1A3C +3A1A3C:lI116|H3A1AF0 +3A1AF0:lI117|H3A1BB4 +3A1BB4:lI102|H3A1C80 +3A1C80:lI102|H3A1D44 +3A1D44:lI105|H3A1E00 +3A1E00:lI116|N +3A0EA8:lI115|H3A0F5C +3A0F5C:lI105|H3A1018 +3A1018:lI116|N +3A0E10:lH3A0EB8|H3A0EC4 +3A0EB8:t2:H3A0F6C,H3A0F74 +3A0F74:lI97|H3A1030 +3A1030:lI112|H3A10F4 +3A10F4:lI112|H3A11C0 +3A11C0:lI108|H3A1284 +3A1284:lI105|H3A1348 +3A1348:lI99|H3A141C +3A141C:lI97|H3A14F8 +3A14F8:lI116|H3A15CC +3A15CC:lI105|H3A1698 +3A1698:lI111|H3A1764 +3A1764:lI110|H3A1820 +3A1820:lI47|H3A18DC +3A18DC:lI120|H3A1990 +3A1990:lI45|H3A1A44 +3A1A44:lI115|H3A1AF8 +3A1AF8:lI104|H3A1BBC +3A1BBC:lI97|H3A1C88 +3A1C88:lI114|N +3A0F6C:lI115|H3A1028 +3A1028:lI104|H3A10EC +3A10EC:lI97|H3A11B8 +3A11B8:lI114|N +3A0EC4:lH3A0F7C|H3A0F88 +3A0F7C:t2:H3A1038,H3A1040 +3A1040:lI97|H3A1104 +3A1104:lI112|H3A11C8 +3A11C8:lI112|H3A128C +3A128C:lI108|H3A1350 +3A1350:lI105|H3A1424 +3A1424:lI99|H3A1500 +3A1500:lI97|H3A15D4 +3A15D4:lI116|H3A16A0 +3A16A0:lI105|H3A176C +3A176C:lI111|H3A1828 +3A1828:lI110|H3A18E4 +3A18E4:lI47|H3A1998 +3A1998:lI120|H3A1A4C +3A1A4C:lI45|H3A1B00 +3A1B00:lI115|H3A1BC4 +3A1BC4:lI104|N +3A1038:lI115|H3A10FC +3A10FC:lI104|N +3A0F88:lH3A1048|H3A1054 +3A1048:t2:H3A110C,H3A1114 +3A1114:lI97|H3A11D8 +3A11D8:lI112|H3A1294 +3A1294:lI112|H3A1358 +3A1358:lI108|H3A142C +3A142C:lI105|H3A1508 +3A1508:lI99|H3A15DC +3A15DC:lI97|H3A16A8 +3A16A8:lI116|H3A1774 +3A1774:lI105|H3A1830 +3A1830:lI111|H3A18EC +3A18EC:lI110|H3A19A0 +3A19A0:lI47|H3A1A54 +3A1A54:lI120|H3A1B08 +3A1B08:lI45|H3A1BCC +3A1BCC:lI110|H3A1C90 +3A1C90:lI101|H3A1D4C +3A1D4C:lI116|H3A1E08 +3A1E08:lI99|H3A1EC4 +3A1EC4:lI100|H3A1F88 +3A1F88:lI102|N +3A110C:lI110|H3A11D0 +3A11D0:lI99|N +3A1054:lH3A111C|H3A1128 +3A111C:t2:H3A11E0,H3A11E8 +3A11E8:lI97|H3A12A4 +3A12A4:lI112|H3A1368 +3A1368:lI112|H3A1434 +3A1434:lI108|H3A1510 +3A1510:lI105|H3A15E4 +3A15E4:lI99|H3A16B0 +3A16B0:lI97|H3A177C +3A177C:lI116|H3A1838 +3A1838:lI105|H3A18F4 +3A18F4:lI111|H3A19A8 +3A19A8:lI110|H3A1A5C +3A1A5C:lI47|H3A1B10 +3A1B10:lI120|H3A1BD4 +3A1BD4:lI45|H3A1C98 +3A1C98:lI110|H3A1D54 +3A1D54:lI101|H3A1E10 +3A1E10:lI116|H3A1ECC +3A1ECC:lI99|H3A1F90 +3A1F90:lI100|H3A2044 +3A2044:lI102|N +3A11E0:lI99|H3A129C +3A129C:lI100|H3A1360 +3A1360:lI102|N +3A1128:lH3A11F0|H3A11FC +3A11F0:t2:H3A12AC,H3A12B4 +3A12B4:lI97|H3A1378 +3A1378:lI112|H3A1444 +3A1444:lI112|H3A1518 +3A1518:lI108|H3A15EC +3A15EC:lI105|H3A16B8 +3A16B8:lI99|H3A1784 +3A1784:lI97|H3A1840 +3A1840:lI116|H3A18FC +3A18FC:lI105|H3A19B0 +3A19B0:lI111|H3A1A64 +3A1A64:lI110|H3A1B18 +3A1B18:lI47|H3A1BDC +3A1BDC:lI120|H3A1CA0 +3A1CA0:lI45|H3A1D5C +3A1D5C:lI109|H3A1E18 +3A1E18:lI105|H3A1ED4 +3A1ED4:lI102|N +3A12AC:lI109|H3A1370 +3A1370:lI105|H3A143C +3A143C:lI102|N +3A11FC:lH3A12BC|H3A12C8 +3A12BC:t2:H3A1380,H3A1388 +3A1388:lI97|H3A1454 +3A1454:lI112|H3A1528 +3A1528:lI112|H3A15FC +3A15FC:lI108|H3A16C8 +3A16C8:lI105|H3A178C +3A178C:lI99|H3A1848 +3A1848:lI97|H3A1904 +3A1904:lI116|H3A19B8 +3A19B8:lI105|H3A1A6C +3A1A6C:lI111|H3A1B20 +3A1B20:lI110|H3A1BE4 +3A1BE4:lI47|H3A1CA8 +3A1CA8:lI120|H3A1D64 +3A1D64:lI45|H3A1E20 +3A1E20:lI108|H3A1EDC +3A1EDC:lI97|H3A1F98 +3A1F98:lI116|H3A204C +3A204C:lI101|H3A2108 +3A2108:lI120|N +3A1380:lI108|H3A144C +3A144C:lI97|H3A1520 +3A1520:lI116|H3A15F4 +3A15F4:lI101|H3A16C0 +3A16C0:lI120|N +3A12C8:lH3A1390|H3A139C +3A1390:t2:H3A145C,H3A1464 +3A1464:lI97|H3A1538 +3A1538:lI112|H3A160C +3A160C:lI112|H3A16D0 +3A16D0:lI108|H3A1794 +3A1794:lI105|H3A1850 +3A1850:lI99|H3A190C +3A190C:lI97|H3A19C0 +3A19C0:lI116|H3A1A74 +3A1A74:lI105|H3A1B28 +3A1B28:lI111|H3A1BEC +3A1BEC:lI110|H3A1CB0 +3A1CB0:lI47|H3A1D6C +3A1D6C:lI120|H3A1E28 +3A1E28:lI45|H3A1EE4 +3A1EE4:lI107|H3A1FA0 +3A1FA0:lI111|H3A2054 +3A2054:lI97|H3A2110 +3A2110:lI110|N +3A145C:lI115|H3A1530 +3A1530:lI107|H3A1604 +3A1604:lI112|N +3A139C:lH3A146C|H3A1478 +3A146C:t2:H3A1540,H3A1548 +3A1548:lI97|H3A161C +3A161C:lI112|H3A16E0 +3A16E0:lI112|H3A179C +3A179C:lI108|H3A1858 +3A1858:lI105|H3A1914 +3A1914:lI99|H3A19C8 +3A19C8:lI97|H3A1A7C +3A1A7C:lI116|H3A1B30 +3A1B30:lI105|H3A1BF4 +3A1BF4:lI111|H3A1CB8 +3A1CB8:lI110|H3A1D74 +3A1D74:lI47|H3A1E30 +3A1E30:lI120|H3A1EEC +3A1EEC:lI45|H3A1FA8 +3A1FA8:lI107|H3A205C +3A205C:lI111|H3A2118 +3A2118:lI97|H3A21CC +3A21CC:lI110|N +3A1540:lI115|H3A1614 +3A1614:lI107|H3A16D8 +3A16D8:lI100|N +3A1478:lH3A1550|H3A155C +3A1550:t2:H3A1624,H3A162C +3A162C:lI97|H3A16F0 +3A16F0:lI112|H3A17AC +3A17AC:lI112|H3A1860 +3A1860:lI108|H3A191C +3A191C:lI105|H3A19D0 +3A19D0:lI99|H3A1A84 +3A1A84:lI97|H3A1B38 +3A1B38:lI116|H3A1BFC +3A1BFC:lI105|H3A1CC0 +3A1CC0:lI111|H3A1D7C +3A1D7C:lI110|H3A1E38 +3A1E38:lI47|H3A1EF4 +3A1EF4:lI120|H3A1FB0 +3A1FB0:lI45|H3A2064 +3A2064:lI107|H3A2120 +3A2120:lI111|H3A21D4 +3A21D4:lI97|H3A2288 +3A2288:lI110|N +3A1624:lI115|H3A16E8 +3A16E8:lI107|H3A17A4 +3A17A4:lI116|N +3A155C:lH3A1634|H3A1640 +3A1634:t2:H3A16F8,H3A1700 +3A1700:lI97|H3A17BC +3A17BC:lI112|H3A1870 +3A1870:lI112|H3A1924 +3A1924:lI108|H3A19D8 +3A19D8:lI105|H3A1A8C +3A1A8C:lI99|H3A1B40 +3A1B40:lI97|H3A1C04 +3A1C04:lI116|H3A1CC8 +3A1CC8:lI105|H3A1D84 +3A1D84:lI111|H3A1E40 +3A1E40:lI110|H3A1EFC +3A1EFC:lI47|H3A1FB8 +3A1FB8:lI120|H3A206C +3A206C:lI45|H3A2128 +3A2128:lI107|H3A21DC +3A21DC:lI111|H3A2290 +3A2290:lI97|H3A234C +3A234C:lI110|N +3A16F8:lI115|H3A17B4 +3A17B4:lI107|H3A1868 +3A1868:lI109|N +3A1640:lH3A1708|H3A1714 +3A1708:t2:H3A17C4,H3A17CC +3A17CC:lI97|H3A1880 +3A1880:lI112|H3A1934 +3A1934:lI112|H3A19E0 +3A19E0:lI108|H3A1A94 +3A1A94:lI105|H3A1B48 +3A1B48:lI99|H3A1C0C +3A1C0C:lI97|H3A1CD0 +3A1CD0:lI116|H3A1D8C +3A1D8C:lI105|H3A1E48 +3A1E48:lI111|H3A1F04 +3A1F04:lI110|H3A1FC0 +3A1FC0:lI47|H3A2074 +3A2074:lI120|H3A2130 +3A2130:lI45|H3A21E4 +3A21E4:lI104|H3A2298 +3A2298:lI116|H3A2354 +3A2354:lI116|H3A2410 +3A2410:lI112|H3A24C4 +3A24C4:lI100|H3A2580 +3A2580:lI45|H3A263C +3A263C:lI99|H3A2700 +3A2700:lI103|H3A27BC +3A27BC:lI105|N +3A17C4:lI99|H3A1878 +3A1878:lI103|H3A192C +3A192C:lI105|N +3A1714:lH3A17D4|H3A17E0 +3A17D4:t2:H3A1888,H3A1890 +3A1890:lI97|H3A1944 +3A1944:lI112|H3A19F0 +3A19F0:lI112|H3A1A9C +3A1A9C:lI108|H3A1B50 +3A1B50:lI105|H3A1C14 +3A1C14:lI99|H3A1CD8 +3A1CD8:lI97|H3A1D94 +3A1D94:lI116|H3A1E50 +3A1E50:lI105|H3A1F0C +3A1F0C:lI111|H3A1FC8 +3A1FC8:lI110|H3A207C +3A207C:lI47|H3A2138 +3A2138:lI120|H3A21EC +3A21EC:lI45|H3A22A0 +3A22A0:lI104|H3A235C +3A235C:lI100|H3A2418 +3A2418:lI102|N +3A1888:lI104|H3A193C +3A193C:lI100|H3A19E8 +3A19E8:lI102|N +3A17E0:lH3A1898|H3A18A4 +3A1898:t2:H3A194C,H3A1954 +3A1954:lI97|H3A1A00 +3A1A00:lI112|H3A1AA4 +3A1AA4:lI112|H3A1B58 +3A1B58:lI108|H3A1C1C +3A1C1C:lI105|H3A1CE0 +3A1CE0:lI99|H3A1D9C +3A1D9C:lI97|H3A1E58 +3A1E58:lI116|H3A1F14 +3A1F14:lI105|H3A1FD0 +3A1FD0:lI111|H3A2084 +3A2084:lI110|H3A2140 +3A2140:lI47|H3A21F4 +3A21F4:lI120|H3A22A8 +3A22A8:lI45|H3A2364 +3A2364:lI103|H3A2420 +3A2420:lI122|H3A24CC +3A24CC:lI105|H3A2588 +3A2588:lI112|N +3A194C:lI103|H3A19F8 +3A19F8:lI122|N +3A18A4:lH3A195C|H3A1968 +3A195C:t2:H3A1A08,H3A1A10 +3A1A10:lI97|H3A1AB4 +3A1AB4:lI112|H3A1B68 +3A1B68:lI112|H3A1C2C +3A1C2C:lI108|H3A1CE8 +3A1CE8:lI105|H3A1DA4 +3A1DA4:lI99|H3A1E60 +3A1E60:lI97|H3A1F1C +3A1F1C:lI116|H3A1FD8 +3A1FD8:lI105|H3A208C +3A208C:lI111|H3A2148 +3A2148:lI110|H3A21FC +3A21FC:lI47|H3A22B0 +3A22B0:lI120|H3A236C +3A236C:lI45|H3A2428 +3A2428:lI103|H3A24D4 +3A24D4:lI116|H3A2590 +3A2590:lI97|H3A2644 +3A2644:lI114|N +3A1A08:lI103|H3A1AAC +3A1AAC:lI116|H3A1B60 +3A1B60:lI97|H3A1C24 +3A1C24:lI114|N +3A1968:lH3A1A18|H3A1A24 +3A1A18:t2:H3A1ABC,H3A1AC4 +3A1AC4:lI97|H3A1B78 +3A1B78:lI112|H3A1C3C +3A1C3C:lI112|H3A1CF0 +3A1CF0:lI108|H3A1DAC +3A1DAC:lI105|H3A1E68 +3A1E68:lI99|H3A1F24 +3A1F24:lI97|H3A1FE0 +3A1FE0:lI116|H3A2094 +3A2094:lI105|H3A2150 +3A2150:lI111|H3A2204 +3A2204:lI110|H3A22B8 +3A22B8:lI47|H3A2374 +3A2374:lI120|H3A2430 +3A2430:lI45|H3A24DC +3A24DC:lI100|H3A2598 +3A2598:lI118|H3A264C +3A264C:lI105|N +3A1ABC:lI100|H3A1B70 +3A1B70:lI118|H3A1C34 +3A1C34:lI105|N +3A1A24:lH3A1ACC|H3A1AD8 +3A1ACC:t2:H3A1B80,H3A1B88 +3A1B88:lI97|H3A1C4C +3A1C4C:lI112|H3A1D00 +3A1D00:lI112|H3A1DB4 +3A1DB4:lI108|H3A1E70 +3A1E70:lI105|H3A1F2C +3A1F2C:lI99|H3A1FE8 +3A1FE8:lI97|H3A209C +3A209C:lI116|H3A2158 +3A2158:lI105|H3A220C +3A220C:lI111|H3A22C0 +3A22C0:lI110|H3A237C +3A237C:lI47|H3A2438 +3A2438:lI120|H3A24E4 +3A24E4:lI45|H3A25A0 +3A25A0:lI100|H3A2654 +3A2654:lI105|H3A2708 +3A2708:lI114|H3A27C4 +3A27C4:lI101|H3A2880 +3A2880:lI99|H3A2944 +3A2944:lI116|H3A2A10 +3A2A10:lI111|H3A2ADC +3A2ADC:lI114|N +3A1B80:lI100|H3A1C44 +3A1C44:lI99|H3A1CF8 +3A1CF8:lI114|N +3A1AD8:lH3A1B90|H3A1B9C +3A1B90:t2:H3A1C54,H3A1C5C +3A1C5C:lI97|H3A1D10 +3A1D10:lI112|H3A1DC4 +3A1DC4:lI112|H3A1E78 +3A1E78:lI108|H3A1F34 +3A1F34:lI105|H3A1FF0 +3A1FF0:lI99|H3A20A4 +3A20A4:lI97|H3A2160 +3A2160:lI116|H3A2214 +3A2214:lI105|H3A22C8 +3A22C8:lI111|H3A2384 +3A2384:lI110|H3A2440 +3A2440:lI47|H3A24EC +3A24EC:lI120|H3A25A8 +3A25A8:lI45|H3A265C +3A265C:lI100|H3A2710 +3A2710:lI105|H3A27CC +3A27CC:lI114|H3A2888 +3A2888:lI101|H3A294C +3A294C:lI99|H3A2A18 +3A2A18:lI116|H3A2AE4 +3A2AE4:lI111|H3A2BB0 +3A2BB0:lI114|N +3A1C54:lI100|H3A1D08 +3A1D08:lI105|H3A1DBC +3A1DBC:lI114|N +3A1B9C:lH3A1C64|H3A1C70 +3A1C64:t2:H3A1D18,H3A1D20 +3A1D20:lI97|H3A1DD4 +3A1DD4:lI112|H3A1E88 +3A1E88:lI112|H3A1F3C +3A1F3C:lI108|H3A1FF8 +3A1FF8:lI105|H3A20AC +3A20AC:lI99|H3A2168 +3A2168:lI97|H3A221C +3A221C:lI116|H3A22D0 +3A22D0:lI105|H3A238C +3A238C:lI111|H3A2448 +3A2448:lI110|H3A24F4 +3A24F4:lI47|H3A25B0 +3A25B0:lI120|H3A2664 +3A2664:lI45|H3A2718 +3A2718:lI100|H3A27D4 +3A27D4:lI105|H3A2890 +3A2890:lI114|H3A2954 +3A2954:lI101|H3A2A20 +3A2A20:lI99|H3A2AEC +3A2AEC:lI116|H3A2BB8 +3A2BB8:lI111|H3A2C74 +3A2C74:lI114|N +3A1D18:lI100|H3A1DCC +3A1DCC:lI120|H3A1E80 +3A1E80:lI114|N +3A1C70:lH3A1D28|H3A1D34 +3A1D28:t2:H3A1DDC,H3A1DE4 +3A1DE4:lI97|H3A1E98 +3A1E98:lI112|H3A1F4C +3A1F4C:lI112|H3A2000 +3A2000:lI108|H3A20B4 +3A20B4:lI105|H3A2170 +3A2170:lI99|H3A2224 +3A2224:lI97|H3A22D8 +3A22D8:lI116|H3A2394 +3A2394:lI105|H3A2450 +3A2450:lI111|H3A24FC +3A24FC:lI110|H3A25B8 +3A25B8:lI47|H3A266C +3A266C:lI120|H3A2720 +3A2720:lI45|H3A27DC +3A27DC:lI99|H3A2898 +3A2898:lI115|H3A295C +3A295C:lI104|N +3A1DDC:lI99|H3A1E90 +3A1E90:lI115|H3A1F44 +3A1F44:lI104|N +3A1D34:lH3A1DEC|H3A1DF8 +3A1DEC:t2:H3A1EA0,H3A1EA8 +3A1EA8:lI97|H3A1F5C +3A1F5C:lI112|H3A2010 +3A2010:lI112|H3A20C4 +3A20C4:lI108|H3A2178 +3A2178:lI105|H3A222C +3A222C:lI99|H3A22E0 +3A22E0:lI97|H3A239C +3A239C:lI116|H3A2458 +3A2458:lI105|H3A2504 +3A2504:lI111|H3A25C0 +3A25C0:lI110|H3A2674 +3A2674:lI47|H3A2728 +3A2728:lI120|H3A27E4 +3A27E4:lI45|H3A28A0 +3A28A0:lI99|H3A2964 +3A2964:lI112|H3A2A28 +3A2A28:lI105|H3A2AF4 +3A2AF4:lI111|N +3A1EA0:lI99|H3A1F54 +3A1F54:lI112|H3A2008 +3A2008:lI105|H3A20BC +3A20BC:lI111|N +3A1DF8:lH3A1EB0|H3A1EBC +3A1EB0:t2:H3A1F64,H3A1F6C +3A1F6C:lI97|H3A2018 +3A2018:lI112|H3A20CC +3A20CC:lI112|H3A2180 +3A2180:lI108|H3A2234 +3A2234:lI105|H3A22E8 +3A22E8:lI99|H3A23A4 +3A23A4:lI97|H3A2460 +3A2460:lI116|H3A250C +3A250C:lI105|H3A25C8 +3A25C8:lI111|H3A267C +3A267C:lI110|H3A2730 +3A2730:lI47|H3A27EC +3A27EC:lI120|H3A28A8 +3A28A8:lI45|H3A296C +3A296C:lI99|H3A2A30 +3A2A30:lI111|H3A2AFC +3A2AFC:lI109|H3A2BC0 +3A2BC0:lI112|H3A2C7C +3A2C7C:lI114|H3A2D2C +3A2D2C:lI101|H3A2DD4 +3A2DD4:lI115|H3A2E6C +3A2E6C:lI115|N +3A1F64:lI90|N +3A1EBC:lH3A1F74|H3A1F80 +3A1F74:t2:H3A2020,H3A2028 +3A2028:lI97|H3A20DC +3A20DC:lI112|H3A2190 +3A2190:lI112|H3A223C +3A223C:lI108|H3A22F0 +3A22F0:lI105|H3A23AC +3A23AC:lI99|H3A2468 +3A2468:lI97|H3A2514 +3A2514:lI116|H3A25D0 +3A25D0:lI105|H3A2684 +3A2684:lI111|H3A2738 +3A2738:lI110|H3A27F4 +3A27F4:lI47|H3A28B0 +3A28B0:lI120|H3A2974 +3A2974:lI45|H3A2A38 +3A2A38:lI99|H3A2B04 +3A2B04:lI100|H3A2BC8 +3A2BC8:lI108|H3A2C84 +3A2C84:lI105|H3A2D34 +3A2D34:lI110|H3A2DDC +3A2DDC:lI107|N +3A2020:lI118|H3A20D4 +3A20D4:lI99|H3A2188 +3A2188:lI100|N +3A1F80:lH3A2030|H3A203C +3A2030:t2:H3A20E4,H3A20EC +3A20EC:lI97|H3A21A0 +3A21A0:lI112|H3A224C +3A224C:lI112|H3A2300 +3A2300:lI108|H3A23BC +3A23BC:lI105|H3A2470 +3A2470:lI99|H3A251C +3A251C:lI97|H3A25D8 +3A25D8:lI116|H3A268C +3A268C:lI105|H3A2740 +3A2740:lI111|H3A27FC +3A27FC:lI110|H3A28B8 +3A28B8:lI47|H3A297C +3A297C:lI120|H3A2A40 +3A2A40:lI45|H3A2B0C +3A2B0C:lI98|H3A2BD0 +3A2BD0:lI99|H3A2C8C +3A2C8C:lI112|H3A2D3C +3A2D3C:lI105|H3A2DE4 +3A2DE4:lI111|N +3A20E4:lI98|H3A2198 +3A2198:lI99|H3A2244 +3A2244:lI112|H3A22F8 +3A22F8:lI105|H3A23B4 +3A23B4:lI111|N +3A203C:lH3A20F4|H3A2100 +3A20F4:t2:H3A21A8,H3A21B0 +3A21B0:lI97|H3A225C +3A225C:lI112|H3A2310 +3A2310:lI112|H3A23C4 +3A23C4:lI108|H3A2478 +3A2478:lI105|H3A2524 +3A2524:lI99|H3A25E0 +3A25E0:lI97|H3A2694 +3A2694:lI116|H3A2748 +3A2748:lI105|H3A2804 +3A2804:lI111|H3A28C0 +3A28C0:lI110|H3A2984 +3A2984:lI47|H3A2A48 +3A2A48:lI114|H3A2B14 +3A2B14:lI116|H3A2BD8 +3A2BD8:lI102|N +3A21A8:lI114|H3A2254 +3A2254:lI116|H3A2308 +3A2308:lI102|N +3A2100:lH3A21B8|H3A21C4 +3A21B8:t2:H3A2264,H3A226C +3A226C:lI97|H3A2320 +3A2320:lI112|H3A23D4 +3A23D4:lI112|H3A2480 +3A2480:lI108|H3A252C +3A252C:lI105|H3A25E8 +3A25E8:lI99|H3A269C +3A269C:lI97|H3A2750 +3A2750:lI116|H3A280C +3A280C:lI105|H3A28C8 +3A28C8:lI111|H3A298C +3A298C:lI110|H3A2A50 +3A2A50:lI47|H3A2B1C +3A2B1C:lI112|H3A2BE0 +3A2BE0:lI111|H3A2C94 +3A2C94:lI119|H3A2D44 +3A2D44:lI101|H3A2DEC +3A2DEC:lI114|H3A2E74 +3A2E74:lI112|H3A2EEC +3A2EEC:lI111|H3A2F64 +3A2F64:lI105|H3A2FD4 +3A2FD4:lI110|H3A303C +3A303C:lI116|N +3A2264:lI112|H3A2318 +3A2318:lI112|H3A23CC +3A23CC:lI116|N +3A21C4:lH3A2274|H3A2280 +3A2274:t2:H3A2328,H3A2330 +3A2330:lI97|H3A23E4 +3A23E4:lI112|H3A2488 +3A2488:lI112|H3A2534 +3A2534:lI108|H3A25F0 +3A25F0:lI105|H3A26A4 +3A26A4:lI99|H3A2758 +3A2758:lI97|H3A2814 +3A2814:lI116|H3A28D0 +3A28D0:lI105|H3A2994 +3A2994:lI111|H3A2A58 +3A2A58:lI110|H3A2B24 +3A2B24:lI47|H3A2BE8 +3A2BE8:lI112|H3A2C9C +3A2C9C:lI111|H3A2D4C +3A2D4C:lI115|H3A2DF4 +3A2DF4:lI116|H3A2E7C +3A2E7C:lI115|H3A2EF4 +3A2EF4:lI99|H3A2F6C +3A2F6C:lI114|H3A2FDC +3A2FDC:lI105|H3A3044 +3A3044:lI112|H3A30A4 +3A30A4:lI116|N +3A2328:lI97|H3A23DC +3A23DC:lI105|N +3A2280:lH3A2338|H3A2344 +3A2338:t2:H3A23EC,H3A23F4 +3A23F4:lI97|H3A2498 +3A2498:lI112|H3A2544 +3A2544:lI112|H3A25F8 +3A25F8:lI108|H3A26AC +3A26AC:lI105|H3A2760 +3A2760:lI99|H3A281C +3A281C:lI97|H3A28D8 +3A28D8:lI116|H3A299C +3A299C:lI105|H3A2A60 +3A2A60:lI111|H3A2B2C +3A2B2C:lI110|H3A2BF0 +3A2BF0:lI47|H3A2CA4 +3A2CA4:lI112|H3A2D54 +3A2D54:lI111|H3A2DFC +3A2DFC:lI115|H3A2E84 +3A2E84:lI116|H3A2EFC +3A2EFC:lI115|H3A2F74 +3A2F74:lI99|H3A2FE4 +3A2FE4:lI114|H3A304C +3A304C:lI105|H3A30AC +3A30AC:lI112|H3A3104 +3A3104:lI116|N +3A23EC:lI101|H3A2490 +3A2490:lI112|H3A253C +3A253C:lI115|N +3A2344:lH3A23FC|H3A2408 +3A23FC:t2:H3A24A0,H3A24A8 +3A24A8:lI97|H3A2554 +3A2554:lI112|H3A2600 +3A2600:lI112|H3A26B4 +3A26B4:lI108|H3A2768 +3A2768:lI105|H3A2824 +3A2824:lI99|H3A28E0 +3A28E0:lI97|H3A29A4 +3A29A4:lI116|H3A2A68 +3A2A68:lI105|H3A2B34 +3A2B34:lI111|H3A2BF8 +3A2BF8:lI110|H3A2CAC +3A2CAC:lI47|H3A2D5C +3A2D5C:lI112|H3A2E04 +3A2E04:lI111|H3A2E8C +3A2E8C:lI115|H3A2F04 +3A2F04:lI116|H3A2F7C +3A2F7C:lI115|H3A2FEC +3A2FEC:lI99|H3A3054 +3A3054:lI114|H3A30B4 +3A30B4:lI105|H3A310C +3A310C:lI112|H3A315C +3A315C:lI116|N +3A24A0:lI112|H3A254C +3A254C:lI115|N +3A2408:lH3A24B0|H3A24BC +3A24B0:t2:H3A255C,H3A2564 +3A2564:lI97|H3A2610 +3A2610:lI112|H3A26C4 +3A26C4:lI112|H3A2770 +3A2770:lI108|H3A282C +3A282C:lI105|H3A28E8 +3A28E8:lI99|H3A29AC +3A29AC:lI97|H3A2A70 +3A2A70:lI116|H3A2B3C +3A2B3C:lI105|H3A2C00 +3A2C00:lI111|H3A2CB4 +3A2CB4:lI110|H3A2D64 +3A2D64:lI47|H3A2E0C +3A2E0C:lI112|H3A2E94 +3A2E94:lI100|H3A2F0C +3A2F0C:lI102|N +3A255C:lI112|H3A2608 +3A2608:lI100|H3A26BC +3A26BC:lI102|N +3A24BC:lH3A256C|H3A2578 +3A256C:t2:H3A2618,H3A2620 +3A2620:lI97|H3A26D4 +3A26D4:lI112|H3A2780 +3A2780:lI112|H3A2834 +3A2834:lI108|H3A28F0 +3A28F0:lI105|H3A29B4 +3A29B4:lI99|H3A2A78 +3A2A78:lI97|H3A2B44 +3A2B44:lI116|H3A2C08 +3A2C08:lI105|H3A2CBC +3A2CBC:lI111|H3A2D6C +3A2D6C:lI110|H3A2E14 +3A2E14:lI47|H3A2E9C +3A2E9C:lI111|H3A2F14 +3A2F14:lI100|H3A2F84 +3A2F84:lI97|N +3A2618:lI111|H3A26CC +3A26CC:lI100|H3A2778 +3A2778:lI97|N +3A2578:lH3A2628|H3A2634 +3A2628:t2:H3A26DC,H3A26E4 +3A26E4:lI97|H3A2790 +3A2790:lI112|H3A2844 +3A2844:lI112|H3A28F8 +3A28F8:lI108|H3A29BC +3A29BC:lI105|H3A2A80 +3A2A80:lI99|H3A2B4C +3A2B4C:lI97|H3A2C10 +3A2C10:lI116|H3A2CC4 +3A2CC4:lI105|H3A2D74 +3A2D74:lI111|H3A2E1C +3A2E1C:lI110|H3A2EA4 +3A2EA4:lI47|H3A2F1C +3A2F1C:lI111|H3A2F8C +3A2F8C:lI99|H3A2FF4 +3A2FF4:lI116|H3A305C +3A305C:lI101|H3A30BC +3A30BC:lI116|H3A3114 +3A3114:lI45|H3A3164 +3A3164:lI115|H3A31AC +3A31AC:lI116|H3A31F4 +3A31F4:lI114|H3A323C +3A323C:lI101|H3A3284 +3A3284:lI97|H3A32CC +3A32CC:lI109|N +3A26DC:lI98|H3A2788 +3A2788:lI105|H3A283C +3A283C:lI110|N +3A2634:lH3A26EC|H3A26F8 +3A26EC:t2:H3A2798,H3A27A0 +3A27A0:lI97|H3A2854 +3A2854:lI112|H3A2908 +3A2908:lI112|H3A29C4 +3A29C4:lI108|H3A2A88 +3A2A88:lI105|H3A2B54 +3A2B54:lI99|H3A2C18 +3A2C18:lI97|H3A2CCC +3A2CCC:lI116|H3A2D7C +3A2D7C:lI105|H3A2E24 +3A2E24:lI111|H3A2EAC +3A2EAC:lI110|H3A2F24 +3A2F24:lI47|H3A2F94 +3A2F94:lI111|H3A2FFC +3A2FFC:lI99|H3A3064 +3A3064:lI116|H3A30C4 +3A30C4:lI101|H3A311C +3A311C:lI116|H3A316C +3A316C:lI45|H3A31B4 +3A31B4:lI115|H3A31FC +3A31FC:lI116|H3A3244 +3A3244:lI114|H3A328C +3A328C:lI101|H3A32D4 +3A32D4:lI97|H3A3314 +3A3314:lI109|N +3A2798:lI100|H3A284C +3A284C:lI109|H3A2900 +3A2900:lI115|N +3A26F8:lH3A27A8|H3A27B4 +3A27A8:t2:H3A285C,H3A2864 +3A2864:lI97|H3A2918 +3A2918:lI112|H3A29D4 +3A29D4:lI112|H3A2A90 +3A2A90:lI108|H3A2B5C +3A2B5C:lI105|H3A2C20 +3A2C20:lI99|H3A2CD4 +3A2CD4:lI97|H3A2D84 +3A2D84:lI116|H3A2E2C +3A2E2C:lI105|H3A2EB4 +3A2EB4:lI111|H3A2F2C +3A2F2C:lI110|H3A2F9C +3A2F9C:lI47|H3A3004 +3A3004:lI111|H3A306C +3A306C:lI99|H3A30CC +3A30CC:lI116|H3A3124 +3A3124:lI101|H3A3174 +3A3174:lI116|H3A31BC +3A31BC:lI45|H3A3204 +3A3204:lI115|H3A324C +3A324C:lI116|H3A3294 +3A3294:lI114|H3A32DC +3A32DC:lI101|H3A331C +3A331C:lI97|H3A334C +3A334C:lI109|N +3A285C:lI108|H3A2910 +3A2910:lI104|H3A29CC +3A29CC:lI97|N +3A27B4:lH3A286C|H3A2878 +3A286C:t2:H3A2920,H3A2928 +3A2928:lI97|H3A29E4 +3A29E4:lI112|H3A2AA0 +3A2AA0:lI112|H3A2B64 +3A2B64:lI108|H3A2C28 +3A2C28:lI105|H3A2CDC +3A2CDC:lI99|H3A2D8C +3A2D8C:lI97|H3A2E34 +3A2E34:lI116|H3A2EBC +3A2EBC:lI105|H3A2F34 +3A2F34:lI111|H3A2FA4 +3A2FA4:lI110|H3A300C +3A300C:lI47|H3A3074 +3A3074:lI111|H3A30D4 +3A30D4:lI99|H3A312C +3A312C:lI116|H3A317C +3A317C:lI101|H3A31C4 +3A31C4:lI116|H3A320C +3A320C:lI45|H3A3254 +3A3254:lI115|H3A329C +3A329C:lI116|H3A32E4 +3A32E4:lI114|H3A3324 +3A3324:lI101|H3A3354 +3A3354:lI97|H3A337C +3A337C:lI109|N +3A2920:lI108|H3A29DC +3A29DC:lI122|H3A2A98 +3A2A98:lI104|N +3A2878:lH3A2930|H3A293C +3A2930:t2:H3A29EC,H3A29F4 +3A29F4:lI97|H3A2AB0 +3A2AB0:lI112|H3A2B74 +3A2B74:lI112|H3A2C30 +3A2C30:lI108|H3A2CE4 +3A2CE4:lI105|H3A2D94 +3A2D94:lI99|H3A2E3C +3A2E3C:lI97|H3A2EC4 +3A2EC4:lI116|H3A2F3C +3A2F3C:lI105|H3A2FAC +3A2FAC:lI111|H3A3014 +3A3014:lI110|H3A307C +3A307C:lI47|H3A30DC +3A30DC:lI111|H3A3134 +3A3134:lI99|H3A3184 +3A3184:lI116|H3A31CC +3A31CC:lI101|H3A3214 +3A3214:lI116|H3A325C +3A325C:lI45|H3A32A4 +3A32A4:lI115|H3A32EC +3A32EC:lI116|H3A332C +3A332C:lI114|H3A335C +3A335C:lI101|H3A3384 +3A3384:lI97|H3A33A4 +3A33A4:lI109|N +3A29EC:lI101|H3A2AA8 +3A2AA8:lI120|H3A2B6C +3A2B6C:lI101|N +3A293C:lH3A29FC|H3A2A08 +3A29FC:t2:H3A2AB8,H3A2AC0 +3A2AC0:lI97|H3A2B84 +3A2B84:lI112|H3A2C40 +3A2C40:lI112|H3A2CF4 +3A2CF4:lI108|H3A2DA4 +3A2DA4:lI105|H3A2E44 +3A2E44:lI99|H3A2ECC +3A2ECC:lI97|H3A2F44 +3A2F44:lI116|H3A2FB4 +3A2FB4:lI105|H3A301C +3A301C:lI111|H3A3084 +3A3084:lI110|H3A30E4 +3A30E4:lI47|H3A313C +3A313C:lI111|H3A318C +3A318C:lI99|H3A31D4 +3A31D4:lI116|H3A321C +3A321C:lI101|H3A3264 +3A3264:lI116|H3A32AC +3A32AC:lI45|H3A32F4 +3A32F4:lI115|H3A3334 +3A3334:lI116|H3A3364 +3A3364:lI114|H3A338C +3A338C:lI101|H3A33AC +3A33AC:lI97|H3A33C4 +3A33C4:lI109|N +3A2AB8:lI99|H3A2B7C +3A2B7C:lI108|H3A2C38 +3A2C38:lI97|H3A2CEC +3A2CEC:lI115|H3A2D9C +3A2D9C:lI115|N +3A2A08:lH3A2AC8|H3A2AD4 +3A2AC8:t2:H3A2B8C,H3A2B94 +3A2B94:lI97|H3A2C50 +3A2C50:lI112|H3A2D04 +3A2D04:lI112|H3A2DAC +3A2DAC:lI108|H3A2E4C +3A2E4C:lI105|H3A2ED4 +3A2ED4:lI99|H3A2F4C +3A2F4C:lI97|H3A2FBC +3A2FBC:lI116|H3A3024 +3A3024:lI105|H3A308C +3A308C:lI111|H3A30EC +3A30EC:lI110|H3A3144 +3A3144:lI47|H3A3194 +3A3194:lI109|H3A31DC +3A31DC:lI115|H3A3224 +3A3224:lI119|H3A326C +3A326C:lI111|H3A32B4 +3A32B4:lI114|H3A32FC +3A32FC:lI100|N +3A2B8C:lI100|H3A2C48 +3A2C48:lI111|H3A2CFC +3A2CFC:lI99|N +3A2AD4:lH3A2B9C|H3A2BA8 +3A2B9C:t2:H3A2C58,H3A2C60 +3A2C60:lI97|H3A2D14 +3A2D14:lI112|H3A2DBC +3A2DBC:lI112|H3A2E54 +3A2E54:lI108|H3A2EDC +3A2EDC:lI105|H3A2F54 +3A2F54:lI99|H3A2FC4 +3A2FC4:lI97|H3A302C +3A302C:lI116|H3A3094 +3A3094:lI105|H3A30F4 +3A30F4:lI111|H3A314C +3A314C:lI110|H3A319C +3A319C:lI47|H3A31E4 +3A31E4:lI109|H3A322C +3A322C:lI97|H3A3274 +3A3274:lI99|H3A32BC +3A32BC:lI45|H3A3304 +3A3304:lI99|H3A333C +3A333C:lI111|H3A336C +3A336C:lI109|H3A3394 +3A3394:lI112|H3A33B4 +3A33B4:lI97|H3A33CC +3A33CC:lI99|H3A33DC +3A33DC:lI116|H3A33EC +3A33EC:lI112|H3A33FC +3A33FC:lI114|H3A340C +3A340C:lI111|N +3A2C58:lI99|H3A2D0C +3A2D0C:lI112|H3A2DB4 +3A2DB4:lI116|N +3A2BA8:lH3A2C68|N +3A2C68:t2:H3A2D1C,H3A2D24 +3A2D24:lI97|H3A2DCC +3A2DCC:lI112|H3A2E64 +3A2E64:lI112|H3A2EE4 +3A2EE4:lI108|H3A2F5C +3A2F5C:lI105|H3A2FCC +3A2FCC:lI99|H3A3034 +3A3034:lI97|H3A309C +3A309C:lI116|H3A30FC +3A30FC:lI105|H3A3154 +3A3154:lI111|H3A31A4 +3A31A4:lI110|H3A31EC +3A31EC:lI47|H3A3234 +3A3234:lI109|H3A327C +3A327C:lI97|H3A32C4 +3A32C4:lI99|H3A330C +3A330C:lI45|H3A3344 +3A3344:lI98|H3A3374 +3A3374:lI105|H3A339C +3A339C:lI110|H3A33BC +3A33BC:lI104|H3A33D4 +3A33D4:lI101|H3A33E4 +3A33E4:lI120|H3A33F4 +3A33F4:lI52|H3A3404 +3A3404:lI48|N +3A2D1C:lI104|H3A2DC4 +3A2DC4:lI113|H3A2E5C +3A2E5C:lI120|N +39DC28:lH39DC68|H39DC74 +39DC68:t2:A4:port,I8888 +39DC74:lH39DCA8|H39DCB4 +39DCA8:t2:AC:bind_address,H39DCF8 +39DCF8:t4:I127,I0,I0,I1 +39DCB4:lH39DD0C|H39DD18 +39DD0C:t2:AB:server_name,H39DD6C +39DD6C:lI108|H39DDE4 +39DDE4:lI111|H39DE5C +39DE5C:lI99|H39DEE4 +39DEE4:lI97|H39DF6C +39DF6C:lI108|H39E00C +39E00C:lI104|H39E0B4 +39E0B4:lI111|H39E16C +39E16C:lI115|H39E238 +39E238:lI116|N +39DD18:lH39DD74|H39DD80 +39DD74:t2:AE:max_header_siz,I1024 +39DD80:lH39DDEC|H39DDF8 +39DDEC:t2:A11:max_header_action,A8:reply414 +39DDF8:lH39DE64|H39DE70 +39DE64:t2:A8:com_type,A7:ip_comm +39DE70:lH39DEEC|H39DEF8 +39DEEC:t2:A7:modules,H39DF74 +39DF74:lA9:mod_alias|H39E014 +39E014:lA8:mod_auth|H39E0BC +39E0BC:lA7:mod_esi|H39E174 +39E174:lAB:mod_actions|H39E240 +39E240:lA7:mod_cgi|H39E324 +39E324:lAB:mod_include|H39E418 +39E418:lA7:mod_dir|H39E51C +39E51C:lA7:mod_get|H39E634 +39E634:lA8:mod_head|H39E748 +39E748:lA7:mod_log|H39E85C +39E85C:lAC:mod_disk_log|N +39DEF8:lH39DF7C|H39DF88 +39DF7C:t2:AF:directory_index,H39E01C +39E01C:lH39E0C4|N +39E0C4:lI105|H39E17C +39E17C:lI110|H39E248 +39E248:lI100|H39E32C +39E32C:lI101|H39E420 +39E420:lI120|H39E524 +39E524:lI46|H39E63C +39E63C:lI104|H39E750 +39E750:lI116|H39E864 +39E864:lI109|H39E978 +39E978:lI108|N +39DF88:lH39E024|H39E030 +39E024:t2:AC:default_type,H39E0CC +39E0CC:lI116|H39E184 +39E184:lI101|H39E250 +39E250:lI120|H39E334 +39E334:lI116|H39E428 +39E428:lI47|H39E52C +39E52C:lI112|H39E644 +39E644:lI108|H39E758 +39E758:lI97|H39E86C +39E86C:lI105|H39E980 +39E980:lI110|N +39E030:lH39E0D4|H39E0E0 +39E0D4:t2:A10:erl_script_alias,H39E18C +39E18C:t2:H39E258,H39E260 +39E260:lH39E344|N +39E344:lI119|H39E438 +39E438:lI101|H39E53C +39E53C:lI98|H39E654 +39E654:lI116|H39E768 +39E768:lI111|H39E87C +39E87C:lI111|H39E990 +39E990:lI108|N +39E258:lI47|H39E33C +39E33C:lI119|H39E430 +39E430:lI101|H39E534 +39E534:lI98|H39E64C +39E64C:lI116|H39E760 +39E760:lI111|H39E874 +39E874:lI111|H39E988 +39E988:lI108|N +39E0E0:lH39E198|H39E1A4 +39E198:t2:A5:alias,H39E268 +39E268:t2:H39E34C,H39E354 +39E354:lI47|H39E448 +39E448:lI99|H39E54C +39E54C:lI108|H39E664 +39E664:lI101|H39E778 +39E778:lI97|H39E88C +39E88C:lI114|H39E9A0 +39E9A0:lI99|H39EA94 +39EA94:lI97|H39EB88 +39EB88:lI115|H39EC7C +39EC7C:lI101|H39ED70 +39ED70:lI47|H39EE4C +39EE4C:lI111|H39EF20 +39EF20:lI116|H39EFFC +39EFFC:lI112|H39F0E0 +39F0E0:lI47|H39F1B4 +39F1B4:lI101|H39F288 +39F288:lI114|H39F344 +39F344:lI116|H39F408 +39F408:lI115|H39F4D4 +39F4D4:lI47|H39F5A8 +39F5A8:lI108|H39F67C +39F67C:lI105|H39F750 +39F750:lI98|H39F824 +39F824:lI47|H39F908 +39F908:lI111|H39F9E4 +39F9E4:lI98|H39FAC0 +39FAC0:lI115|H39FB9C +39FB9C:lI101|H39FC68 +39FC68:lI114|H39FD2C +39FD2C:lI118|H39FDF8 +39FDF8:lI101|H39FEB4 +39FEB4:lI114|H39FF70 +39FF70:lI47|H3A0024 +3A0024:lI112|H3A00D8 +3A00D8:lI114|H3A0184 +3A0184:lI105|H3A0238 +3A0238:lI118|H3A02F4 +3A02F4:lI47|H3A03A8 +3A03A8:lI99|H3A0444 +3A0444:lI114|H3A04E8 +3A04E8:lI97|H3A058C +3A058C:lI115|H3A0638 +3A0638:lI104|H3A06EC +3A06EC:lI100|H3A0798 +3A0798:lI117|H3A083C +3A083C:lI109|H3A08C8 +3A08C8:lI112|H3A095C +3A095C:lI95|H3A09F0 +3A09F0:lI118|H3A0A8C +3A0A8C:lI105|H3A0B38 +3A0B38:lI101|H3A0BE4 +3A0BE4:lI119|H3A0CA0 +3A0CA0:lI101|H3A0D5C +3A0D5C:lI114|N +39E34C:lI47|H39E440 +39E440:lI99|H39E544 +39E544:lI114|H39E65C +39E65C:lI97|H39E770 +39E770:lI115|H39E884 +39E884:lI104|H39E998 +39E998:lI100|H39EA8C +39EA8C:lI117|H39EB80 +39EB80:lI109|H39EC74 +39EC74:lI112|H39ED68 +39ED68:lI95|H39EE44 +39EE44:lI118|H39EF18 +39EF18:lI105|H39EFF4 +39EFF4:lI101|H39F0D8 +39F0D8:lI119|H39F1AC +39F1AC:lI101|H39F280 +39F280:lI114|N +39E1A4:lH39E274|H39E280 +39E274:t2:A5:alias,H39E35C +39E35C:t2:H39E450,H39E458 +39E458:lI47|H39E55C +39E55C:lI99|H39E674 +39E674:lI108|H39E788 +39E788:lI101|H39E89C +39E89C:lI97|H39E9B0 +39E9B0:lI114|H39EAA4 +39EAA4:lI99|H39EB98 +39EB98:lI97|H39EC8C +39EC8C:lI115|H39ED80 +39ED80:lI101|H39EE5C +39EE5C:lI47|H39EF30 +39EF30:lI111|H39F00C +39F00C:lI116|H39F0F0 +39F0F0:lI112|H39F1C4 +39F1C4:lI47|H39F298 +39F298:lI101|H39F354 +39F354:lI114|H39F418 +39F418:lI116|H39F4E4 +39F4E4:lI115|H39F5B0 +39F5B0:lI47|H39F684 +39F684:lI101|H39F758 +39F758:lI114|H39F82C +39F82C:lI116|H39F910 +39F910:lI115|H39F9EC +39F9EC:lI47|H39FAC8 +39FAC8:lI100|H39FBA4 +39FBA4:lI111|H39FC70 +39FC70:lI99|H39FD34 +39FD34:lI47|H39FE00 +39FE00:lI104|H39FEBC +39FEBC:lI116|H39FF78 +39FF78:lI109|H3A002C +3A002C:lI108|N +39E450:lI47|H39E554 +39E554:lI99|H39E66C +39E66C:lI114|H39E780 +39E780:lI97|H39E894 +39E894:lI115|H39E9A8 +39E9A8:lI104|H39EA9C +39EA9C:lI100|H39EB90 +39EB90:lI117|H39EC84 +39EC84:lI109|H39ED78 +39ED78:lI112|H39EE54 +39EE54:lI95|H39EF28 +39EF28:lI101|H39F004 +39F004:lI114|H39F0E8 +39F0E8:lI116|H39F1BC +39F1BC:lI115|H39F290 +39F290:lI95|H39F34C +39F34C:lI100|H39F410 +39F410:lI111|H39F4DC +39F4DC:lI99|N +39E280:lH39E368|H39E374 +39E368:t2:A5:alias,H39E460 +39E460:t2:H39E564,H39E56C +39E56C:lI47|H39E684 +39E684:lI99|H39E798 +39E798:lI108|H39E8AC +39E8AC:lI101|H39E9C0 +39E9C0:lI97|H39EAB4 +39EAB4:lI114|H39EBA8 +39EBA8:lI99|H39EC9C +39EC9C:lI97|H39ED90 +39ED90:lI115|H39EE6C +39EE6C:lI101|H39EF40 +39EF40:lI47|H39F01C +39F01C:lI111|H39F100 +39F100:lI116|H39F1D4 +39F1D4:lI112|H39F2A0 +39F2A0:lI47|H39F35C +39F35C:lI101|H39F420 +39F420:lI114|H39F4EC +39F4EC:lI116|H39F5B8 +39F5B8:lI115|H39F68C +39F68C:lI47|H39F760 +39F760:lI108|H39F834 +39F834:lI105|H39F918 +39F918:lI98|H39F9F4 +39F9F4:lI47|H39FAD0 +39FAD0:lI111|H39FBAC +39FBAC:lI98|H39FC78 +39FC78:lI115|H39FD3C +39FD3C:lI101|H39FE08 +39FE08:lI114|H39FEC4 +39FEC4:lI118|H39FF80 +39FF80:lI101|H3A0034 +3A0034:lI114|H3A00E0 +3A00E0:lI47|H3A018C +3A018C:lI100|H3A0240 +3A0240:lI111|H3A02FC +3A02FC:lI99|H3A03B0 +3A03B0:lI47|H3A044C +3A044C:lI104|H3A04F0 +3A04F0:lI116|H3A0594 +3A0594:lI109|H3A0640 +3A0640:lI108|N +39E564:lI47|H39E67C +39E67C:lI99|H39E790 +39E790:lI114|H39E8A4 +39E8A4:lI97|H39E9B8 +39E9B8:lI115|H39EAAC +39EAAC:lI104|H39EBA0 +39EBA0:lI100|H39EC94 +39EC94:lI117|H39ED88 +39ED88:lI109|H39EE64 +39EE64:lI112|H39EF38 +39EF38:lI95|H39F014 +39F014:lI100|H39F0F8 +39F0F8:lI111|H39F1CC +39F1CC:lI99|N +39E374:lH39E46C|N +39E46C:t2:A10:erl_script_alias,H39E574 +39E574:t2:H39E68C,H39E694 +39E694:lH39E7A8|N +39E7A8:lI99|H39E8BC +39E8BC:lI114|H39E9D0 +39E9D0:lI97|H39EAC4 +39EAC4:lI115|H39EBB8 +39EBB8:lI104|H39ECAC +39ECAC:lI100|H39EDA0 +39EDA0:lI117|H39EE74 +39EE74:lI109|H39EF48 +39EF48:lI112|H39F024 +39F024:lI95|H39F108 +39F108:lI118|H39F1DC +39F1DC:lI105|H39F2A8 +39F2A8:lI101|H39F364 +39F364:lI119|H39F428 +39F428:lI101|H39F4F4 +39F4F4:lI114|N +39E68C:lI47|H39E7A0 +39E7A0:lI99|H39E8B4 +39E8B4:lI100|H39E9C8 +39E9C8:lI118|H39EABC +39EABC:lI95|H39EBB0 +39EBB0:lI101|H39ECA4 +39ECA4:lI114|H39ED98 +39ED98:lI108|N +39DB58:lN|H39DB9C +39DB9C:lH39D9FC|H39DBEC +39D9FC:t4:I127,I0,I0,I1 +39DBEC:lI8888|N +3A3E20:lH3A3DFC|H3A3704 +3A3DFC:t8:A5:child,P<0.46.0>,H39DAC8,H39DAD8,A9:permanent,I2000,A6:worker,H39DAE8 +39DAE8:lAD:httpd_manager|H39DB38 +39DB38:lAA:gen_server|N +39DAD8:t3:AD:httpd_manager,AA:start_link,H39DB30 +39DB30:lA9:undefined|H39DB78 +39DB78:lH39DB50|H39DBC0 +39DBC0:lN|N +39DAC8:t3:AD:httpd_manager,H39D9FC,I8888 +3A3704:lH3A36E0|H39D998 +3A36E0:t8:A5:child,P<0.45.0>,H39DA18,H39DA28,A9:permanent,I2000,AA:supervisor,H39DA38 +39DA38:lAE:httpd_misc_sup|H39DAC0 +39DAC0:lAA:supervisor|N +39DA28:t3:AE:httpd_misc_sup,A5:start,H39D958 +39D958:lH39D9FC|H39DA10 +39DA10:lI8888|H39DAB8 +39DAB8:lA7:silence|N +39DA18:t3:AE:httpd_misc_sup,H39D9FC,I8888 +39D998:lH39DA64|N +39DA64:t8:A5:child,P<0.44.0>,H39DAF0,H39DB00,A9:permanent,I2000,AA:supervisor,H39DB10 +39DB10:lA12:httpd_acceptor_sup|H39DB48 +39DB48:lAA:supervisor|N +39DB00:t3:A12:httpd_acceptor_sup,A5:start,H39DB40 +39DB40:lH39D9FC|H39DB80 +39DB80:lI8888|H39DBC8 +39DBC8:lA7:silence|N +39DAF0:t3:A12:httpd_acceptor_sup,H39D9FC,I8888 +39D960:t2:A5:local,A1A:httpd_sup__127_0_0_1__8888 +39D9CC:lAA:gen_server|H39DA90 +39DA90:lP<0.33.0>|H39DB20 +39DB20:lP<0.33.0>|H39DB60 +39DB60:lH39DBA4|H39DBB0 +39DBA4:t2:A5:local,A1A:httpd_sup__127_0_0_1__8888 +39DBB0:lAA:supervisor|H39DBF4 +39DBF4:lH39DC30|H39DC40 +39DC30:t3:H39D960,A9:httpd_sup,H39DA88 +39DC40:lN|N +39D940:t2:AD:$initial_call,H39D9E4 +39D9E4:t3:A3:gen,A7:init_it,H39D9CC +39D94C:t2:AA:$ancestors,H39D9F4 +39D9F4:lA8:web_tool|H39DAB0 +39DAB0:lP<0.27.0>|N +=proc_dictionary:<0.44.0> +H3756A8 +H3756B4 +H3756C0 +H3756CC +=proc_stack:<0.44.0> +36c194:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AA:supervisor +y3:H36C030 +y4:A1E:httpd_acc_sup__127_0_0_1__8888 +y5:P<0.43.0> +36c1b0:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H375710 +=proc_heap:<0.44.0> +36C030:tA:A5:state,H3756D8,AB:one_for_one,H36C028,N,I500,I100,N,A12:httpd_acceptor_sup,H375730 +375730:lA7:silence|N +36C028:lH36C004|N +36C004:t8:A5:child,P<0.47.0>,H36BE80,H36BE90,A9:permanent,I1000,A6:worker,H36BEA0 +36BEA0:lAE:httpd_acceptor|N +36BE90:t3:AE:httpd_acceptor,AA:start_link,H36BEE8 +36BEE8:lP<0.46.0>|H36BEF0 +36BEF0:lA7:ip_comm|H36BEF8 +36BEF8:lH36BF00|H36BF14 +36BF00:t4:I127,I0,I0,I1 +36BF14:lI8888|H36BF1C +36BF1C:lA1B:httpd_conf__127_0_0_1__8888|H36BF24 +36BF24:lA7:silence|N +36BE80:t3:AE:httpd_acceptor,H36BED4,I8888 +36BED4:t4:I127,I0,I0,I1 +3756D8:t2:A5:local,A1E:httpd_acc_sup__127_0_0_1__8888 +375710:lAA:gen_server|H375738 +375738:lP<0.43.0>|H375748 +375748:lP<0.43.0>|H375758 +375758:lH375760|H37576C +375760:t2:A5:local,A1E:httpd_acc_sup__127_0_0_1__8888 +37576C:lAA:supervisor|H375774 +375774:lH37577C|H37578C +37577C:t3:H3756D8,A12:httpd_acceptor_sup,H375730 +37578C:lN|N +3756A8:t2:AD:$initial_call,H375718 +375718:t3:A3:gen,A7:init_it,H375710 +3756B4:t2:A9:verbosity,A7:silence +3756C0:t2:AA:$ancestors,H375728 +375728:lA1A:httpd_sup__127_0_0_1__8888|H375740 +375740:lA8:web_tool|H375750 +375750:lP<0.27.0>|N +3756CC:t2:A5:sname,A7:acc_sup +=proc_dictionary:<0.45.0> +H36F484 +H36F4F4 +H36F468 +H36F500 +=proc_stack:<0.45.0> +36f734:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AA:supervisor +y3:H36F5D0 +y4:A1F:httpd_misc_sup__127_0_0_1__8888 +y5:P<0.43.0> +36f750:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H36F430 +=proc_heap:<0.45.0> +36F5D0:tA:A5:state,H36F3FC,AB:one_for_one,N,N,I0,I1,N,AE:httpd_misc_sup,H36F408 +36F408:lA7:silence|N +36F3FC:t2:A5:local,A1F:httpd_misc_sup__127_0_0_1__8888 +36F430:lAA:gen_server|H36F428 +36F428:lP<0.43.0>|H36F420 +36F420:lP<0.43.0>|H36F3D0 +36F3D0:lH36F3E0|H36F418 +36F3E0:t2:A5:local,A1F:httpd_misc_sup__127_0_0_1__8888 +36F418:lAA:supervisor|H36F3D8 +36F3D8:lH36F3EC|H36F410 +36F3EC:t3:H36F3FC,AE:httpd_misc_sup,H36F408 +36F410:lN|N +36F484:t2:AD:$initial_call,H36F474 +36F474:t3:A3:gen,A7:init_it,H36F430 +36F4F4:t2:A9:verbosity,A7:silence +36F468:t2:AA:$ancestors,H36F460 +36F460:lA1A:httpd_sup__127_0_0_1__8888|H36F440 +36F440:lA8:web_tool|H36F438 +36F438:lP<0.27.0>|N +36F500:t2:A5:sname,A8:misc_sup +=proc_dictionary:<0.46.0> +H3BDA50 +H3BDA5C +H3BDAC8 +H3BDB28 +H3BDB9C +H3BDC00 +H3BDADC +H3BDB3C +=proc_stack:<0.46.0> +39d8f4:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AD:httpd_manager +y3:H39D5A4 +y4:A16:httpd__127_0_0_1__8888 +y5:P<0.43.0> +39d910:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H3BDAB0 +=proc_heap:<0.46.0> +39D5A4:t9:A5:state,A7:ip_comm,A9:undefined,A1B:httpd_conf__127_0_0_1__8888,N,A9:unblocked,A9:undefined,A9:undefined,H39D430 +39D430:lH39BF40|H39D428 +39BF40:t2:A8:max_conn,I1 +39D428:lH39BC80|H39D420 +39BC80:t2:AF:last_heavy_load,A5:never +39D420:lH39D414|N +39D414:t2:AF:last_connection,H39D408 +39D408:t2:H39D3E8,H39D3F8 +39D3F8:t3:I11,I22,I34 +39D3E8:t3:I2004,I4,I21 +3BDAB0:lAA:gen_server|H3BDB20 +3BDB20:lP<0.43.0>|H3BDB94 +3BDB94:lP<0.43.0>|H3BDBF8 +3BDBF8:lH3BDC48|H3BDC54 +3BDC48:t2:A5:local,A16:httpd__127_0_0_1__8888 +3BDC54:lAD:httpd_manager|H3BDCAC +3BDCAC:lH3BDD14|H3BDD1C +3BDD14:lA9:undefined|H3BDD9C +3BDD9C:lH3BDA84|H3BDE2C +3BDA84:lH3BDAF0|H3BDAFC +3BDAF0:t2:AB:server_root,H3BDB48 +3BDB48:lI47|H3BDBB0 +3BDBB0:lI99|H3BDC0C +3BDC0C:lI108|H3BDC64 +3BDC64:lI101|H3BDCBC +3BDCBC:lI97|H3BDD2C +3BDD2C:lI114|H3BDDA4 +3BDDA4:lI99|H3BDE34 +3BDE34:lI97|H3BDED4 +3BDED4:lI115|H3BDF90 +3BDF90:lI101|H3BE054 +3BE054:lI47|H3BE128 +3BE128:lI111|H3BE204 +3BE204:lI116|H3BE2EC +3BE2EC:lI112|H3BE3E0 +3BE3E0:lI47|H3BE4E4 +3BE4E4:lI101|H3BE5E8 +3BE5E8:lI114|H3BE6EC +3BE6EC:lI116|H3BE7E0 +3BE7E0:lI115|H3BE8CC +3BE8CC:lI47|H3BE9B8 +3BE9B8:lI108|H3BEAAC +3BEAAC:lI105|H3BEB98 +3BEB98:lI98|H3BEC84 +3BEC84:lI47|H3BED70 +3BED70:lI119|H3BEE5C +3BEE5C:lI101|H3BEF30 +3BEF30:lI98|H3BEFFC +3BEFFC:lI116|H3BF0C8 +3BF0C8:lI111|H3BF19C +3BF19C:lI111|H3BF260 +3BF260:lI108|H3BF314 +3BF314:lI47|H3BF3C0 +3BF3C0:lI112|H3BF474 +3BF474:lI114|H3BF530 +3BF530:lI105|H3BF5F4 +3BF5F4:lI118|H3BF6C8 +3BF6C8:lI47|H3BF79C +3BF79C:lI114|H3BF870 +3BF870:lI111|H3BF954 +3BF954:lI111|H3BFA30 +3BFA30:lI116|N +3BDAFC:lH3BDB50|H3BDB5C +3BDB50:t2:AD:document_root,H3BDBB8 +3BDBB8:lI47|H3BDC14 +3BDC14:lI99|H3BDC6C +3BDC6C:lI108|H3BDCC4 +3BDCC4:lI101|H3BDD34 +3BDD34:lI97|H3BDDAC +3BDDAC:lI114|H3BDE3C +3BDE3C:lI99|H3BDEDC +3BDEDC:lI97|H3BDF98 +3BDF98:lI115|H3BE05C +3BE05C:lI101|H3BE130 +3BE130:lI47|H3BE20C +3BE20C:lI111|H3BE2F4 +3BE2F4:lI116|H3BE3E8 +3BE3E8:lI112|H3BE4EC +3BE4EC:lI47|H3BE5F0 +3BE5F0:lI101|H3BE6F4 +3BE6F4:lI114|H3BE7E8 +3BE7E8:lI116|H3BE8D4 +3BE8D4:lI115|H3BE9C0 +3BE9C0:lI47|H3BEAB4 +3BEAB4:lI108|H3BEBA0 +3BEBA0:lI105|H3BEC8C +3BEC8C:lI98|H3BED78 +3BED78:lI47|H3BEE64 +3BEE64:lI119|H3BEF38 +3BEF38:lI101|H3BF004 +3BF004:lI98|H3BF0D0 +3BF0D0:lI116|H3BF1A4 +3BF1A4:lI111|H3BF268 +3BF268:lI111|H3BF31C +3BF31C:lI108|H3BF3C8 +3BF3C8:lI47|H3BF47C +3BF47C:lI112|H3BF538 +3BF538:lI114|H3BF5FC +3BF5FC:lI105|H3BF6D0 +3BF6D0:lI118|H3BF7A4 +3BF7A4:lI47|H3BF878 +3BF878:lI114|H3BF95C +3BF95C:lI111|H3BFA38 +3BFA38:lI111|H3BFB0C +3BFB0C:lI116|H3BFBE8 +3BFBE8:lI47|H3BFCB4 +3BFCB4:lI100|H3BFD78 +3BFD78:lI111|H3BFE3C +3BFE3C:lI99|N +3BDB5C:lH3BDBC0|H3BDBCC +3BDBC0:t2:AA:mime_types,H3BDC1C +3BDC1C:lH3BDC74|H3BDC80 +3BDC74:t2:H3BDCCC,H3BDCD4 +3BDCD4:lI120|H3BDD44 +3BDD44:lI45|H3BDDBC +3BDDBC:lI119|H3BDE44 +3BDE44:lI111|H3BDEE4 +3BDEE4:lI114|H3BDFA0 +3BDFA0:lI108|H3BE064 +3BE064:lI100|H3BE138 +3BE138:lI47|H3BE214 +3BE214:lI120|H3BE2FC +3BE2FC:lI45|H3BE3F0 +3BE3F0:lI118|H3BE4F4 +3BE4F4:lI114|H3BE5F8 +3BE5F8:lI109|H3BE6FC +3BE6FC:lI108|N +3BDCCC:lI119|H3BDD3C +3BDD3C:lI114|H3BDDB4 +3BDDB4:lI108|N +3BDC80:lH3BDCDC|H3BDCE8 +3BDCDC:t2:H3BDD4C,H3BDD54 +3BDD54:lI120|H3BDDCC +3BDDCC:lI45|H3BDE54 +3BDE54:lI119|H3BDEF4 +3BDEF4:lI111|H3BDFA8 +3BDFA8:lI114|H3BE06C +3BE06C:lI108|H3BE140 +3BE140:lI100|H3BE21C +3BE21C:lI47|H3BE304 +3BE304:lI120|H3BE3F8 +3BE3F8:lI45|H3BE4FC +3BE4FC:lI118|H3BE600 +3BE600:lI114|H3BE704 +3BE704:lI109|H3BE7F0 +3BE7F0:lI108|N +3BDD4C:lI118|H3BDDC4 +3BDDC4:lI114|H3BDE4C +3BDE4C:lI109|H3BDEEC +3BDEEC:lI108|N +3BDCE8:lH3BDD5C|H3BDD68 +3BDD5C:t2:H3BDDD4,H3BDDDC +3BDDDC:lI120|H3BDE64 +3BDE64:lI45|H3BDF04 +3BDF04:lI99|H3BDFB0 +3BDFB0:lI111|H3BE074 +3BE074:lI110|H3BE148 +3BE148:lI102|H3BE224 +3BE224:lI101|H3BE30C +3BE30C:lI114|H3BE400 +3BE400:lI101|H3BE504 +3BE504:lI110|H3BE608 +3BE608:lI99|H3BE70C +3BE70C:lI101|H3BE7F8 +3BE7F8:lI47|H3BE8DC +3BE8DC:lI120|H3BE9C8 +3BE9C8:lI45|H3BEABC +3BEABC:lI99|H3BEBA8 +3BEBA8:lI111|H3BEC94 +3BEC94:lI111|H3BED80 +3BED80:lI108|H3BEE6C +3BEE6C:lI116|H3BEF40 +3BEF40:lI97|H3BF00C +3BF00C:lI108|H3BF0D8 +3BF0D8:lI107|N +3BDDD4:lI105|H3BDE5C +3BDE5C:lI99|H3BDEFC +3BDEFC:lI101|N +3BDD68:lH3BDDE4|H3BDDF0 +3BDDE4:t2:H3BDE6C,H3BDE74 +3BDE74:lI118|H3BDF14 +3BDF14:lI105|H3BDFC0 +3BDFC0:lI100|H3BE084 +3BE084:lI101|H3BE158 +3BE158:lI111|H3BE22C +3BE22C:lI47|H3BE314 +3BE314:lI120|H3BE408 +3BE408:lI45|H3BE50C +3BE50C:lI115|H3BE610 +3BE610:lI103|H3BE714 +3BE714:lI105|H3BE800 +3BE800:lI45|H3BE8E4 +3BE8E4:lI109|H3BE9D0 +3BE9D0:lI111|H3BEAC4 +3BEAC4:lI118|H3BEBB0 +3BEBB0:lI105|H3BEC9C +3BEC9C:lI101|N +3BDE6C:lI109|H3BDF0C +3BDF0C:lI111|H3BDFB8 +3BDFB8:lI118|H3BE07C +3BE07C:lI105|H3BE150 +3BE150:lI101|N +3BDDF0:lH3BDE7C|H3BDE88 +3BDE7C:t2:H3BDF1C,H3BDF24 +3BDF24:lI118|H3BDFD0 +3BDFD0:lI105|H3BE094 +3BE094:lI100|H3BE160 +3BE160:lI101|H3BE234 +3BE234:lI111|H3BE31C +3BE31C:lI47|H3BE410 +3BE410:lI120|H3BE514 +3BE514:lI45|H3BE618 +3BE618:lI109|H3BE71C +3BE71C:lI115|H3BE808 +3BE808:lI118|H3BE8EC +3BE8EC:lI105|H3BE9D8 +3BE9D8:lI100|H3BEACC +3BEACC:lI101|H3BEBB8 +3BEBB8:lI111|N +3BDF1C:lI97|H3BDFC8 +3BDFC8:lI118|H3BE08C +3BE08C:lI105|N +3BDE88:lH3BDF2C|H3BDF38 +3BDF2C:t2:H3BDFD8,H3BDFE0 +3BDFE0:lI118|H3BE0A4 +3BE0A4:lI105|H3BE168 +3BE168:lI100|H3BE23C +3BE23C:lI101|H3BE324 +3BE324:lI111|H3BE418 +3BE418:lI47|H3BE51C +3BE51C:lI113|H3BE620 +3BE620:lI117|H3BE724 +3BE724:lI105|H3BE810 +3BE810:lI99|H3BE8F4 +3BE8F4:lI107|H3BE9E0 +3BE9E0:lI116|H3BEAD4 +3BEAD4:lI105|H3BEBC0 +3BEBC0:lI109|H3BECA4 +3BECA4:lI101|N +3BDFD8:lI113|H3BE09C +3BE09C:lI116|N +3BDF38:lH3BDFE8|H3BDFF4 +3BDFE8:t2:H3BE0AC,H3BE0B4 +3BE0B4:lI118|H3BE178 +3BE178:lI105|H3BE24C +3BE24C:lI100|H3BE32C +3BE32C:lI101|H3BE420 +3BE420:lI111|H3BE524 +3BE524:lI47|H3BE628 +3BE628:lI113|H3BE72C +3BE72C:lI117|H3BE818 +3BE818:lI105|H3BE8FC +3BE8FC:lI99|H3BE9E8 +3BE9E8:lI107|H3BEADC +3BEADC:lI116|H3BEBC8 +3BEBC8:lI105|H3BECAC +3BECAC:lI109|H3BED88 +3BED88:lI101|N +3BE0AC:lI109|H3BE170 +3BE170:lI111|H3BE244 +3BE244:lI118|N +3BDFF4:lH3BE0BC|H3BE0C8 +3BE0BC:t2:H3BE180,H3BE188 +3BE188:lI118|H3BE25C +3BE25C:lI105|H3BE33C +3BE33C:lI100|H3BE430 +3BE430:lI101|H3BE52C +3BE52C:lI111|H3BE630 +3BE630:lI47|H3BE734 +3BE734:lI109|H3BE820 +3BE820:lI112|H3BE904 +3BE904:lI101|H3BE9F0 +3BE9F0:lI103|N +3BE180:lI109|H3BE254 +3BE254:lI112|H3BE334 +3BE334:lI101|H3BE428 +3BE428:lI103|N +3BE0C8:lH3BE190|H3BE19C +3BE190:t2:H3BE264,H3BE26C +3BE26C:lI118|H3BE34C +3BE34C:lI105|H3BE440 +3BE440:lI100|H3BE534 +3BE534:lI101|H3BE638 +3BE638:lI111|H3BE73C +3BE73C:lI47|H3BE828 +3BE828:lI109|H3BE90C +3BE90C:lI112|H3BE9F8 +3BE9F8:lI101|H3BEAE4 +3BEAE4:lI103|N +3BE264:lI109|H3BE344 +3BE344:lI112|H3BE438 +3BE438:lI103|N +3BE19C:lH3BE274|H3BE280 +3BE274:t2:H3BE354,H3BE35C +3BE35C:lI118|H3BE450 +3BE450:lI105|H3BE544 +3BE544:lI100|H3BE640 +3BE640:lI101|H3BE744 +3BE744:lI111|H3BE830 +3BE830:lI47|H3BE914 +3BE914:lI109|H3BEA00 +3BEA00:lI112|H3BEAEC +3BEAEC:lI101|H3BEBD0 +3BEBD0:lI103|N +3BE354:lI109|H3BE448 +3BE448:lI112|H3BE53C +3BE53C:lI101|N +3BE280:lH3BE364|H3BE370 +3BE364:t2:H3BE458,H3BE460 +3BE460:lI116|H3BE554 +3BE554:lI101|H3BE650 +3BE650:lI120|H3BE754 +3BE754:lI116|H3BE838 +3BE838:lI47|H3BE91C +3BE91C:lI120|H3BEA08 +3BEA08:lI45|H3BEAF4 +3BEAF4:lI115|H3BEBD8 +3BEBD8:lI103|H3BECB4 +3BECB4:lI109|H3BED90 +3BED90:lI108|N +3BE458:lI115|H3BE54C +3BE54C:lI103|H3BE648 +3BE648:lI109|H3BE74C +3BE74C:lI108|N +3BE370:lH3BE468|H3BE474 +3BE468:t2:H3BE55C,H3BE564 +3BE564:lI116|H3BE660 +3BE660:lI101|H3BE764 +3BE764:lI120|H3BE840 +3BE840:lI116|H3BE924 +3BE924:lI47|H3BEA10 +3BEA10:lI120|H3BEAFC +3BEAFC:lI45|H3BEBE0 +3BEBE0:lI115|H3BECBC +3BECBC:lI103|H3BED98 +3BED98:lI109|H3BEE74 +3BEE74:lI108|N +3BE55C:lI115|H3BE658 +3BE658:lI103|H3BE75C +3BE75C:lI109|N +3BE474:lH3BE56C|H3BE578 +3BE56C:t2:H3BE668,H3BE670 +3BE670:lI116|H3BE774 +3BE774:lI101|H3BE850 +3BE850:lI120|H3BE92C +3BE92C:lI116|H3BEA18 +3BEA18:lI47|H3BEB04 +3BEB04:lI120|H3BEBE8 +3BEBE8:lI45|H3BECC4 +3BECC4:lI115|H3BEDA0 +3BEDA0:lI101|H3BEE7C +3BEE7C:lI116|H3BEF48 +3BEF48:lI101|H3BF014 +3BF014:lI120|H3BF0E0 +3BF0E0:lI116|N +3BE668:lI101|H3BE76C +3BE76C:lI116|H3BE848 +3BE848:lI120|N +3BE578:lH3BE678|H3BE684 +3BE678:t2:H3BE77C,H3BE784 +3BE784:lI116|H3BE860 +3BE860:lI101|H3BE93C +3BE93C:lI120|H3BEA20 +3BEA20:lI116|H3BEB0C +3BEB0C:lI47|H3BEBF0 +3BEBF0:lI116|H3BECCC +3BECCC:lI97|H3BEDA8 +3BEDA8:lI98|H3BEE84 +3BEE84:lI45|H3BEF50 +3BEF50:lI115|H3BF01C +3BF01C:lI101|H3BF0E8 +3BF0E8:lI112|H3BF1AC +3BF1AC:lI97|H3BF270 +3BF270:lI114|H3BF324 +3BF324:lI97|H3BF3D0 +3BF3D0:lI116|H3BF484 +3BF484:lI101|H3BF540 +3BF540:lI100|H3BF604 +3BF604:lI45|H3BF6D8 +3BF6D8:lI118|H3BF7AC +3BF7AC:lI97|H3BF880 +3BF880:lI108|H3BF964 +3BF964:lI117|H3BFA40 +3BFA40:lI101|H3BFB14 +3BFB14:lI115|N +3BE77C:lI116|H3BE858 +3BE858:lI115|H3BE934 +3BE934:lI118|N +3BE684:lH3BE78C|H3BE798 +3BE78C:t2:H3BE868,H3BE870 +3BE870:lI116|H3BE94C +3BE94C:lI101|H3BEA30 +3BEA30:lI120|H3BEB14 +3BEB14:lI116|H3BEBF8 +3BEBF8:lI47|H3BECD4 +3BECD4:lI114|H3BEDB0 +3BEDB0:lI105|H3BEE8C +3BEE8C:lI99|H3BEF58 +3BEF58:lI104|H3BF024 +3BF024:lI116|H3BF0F0 +3BF0F0:lI101|H3BF1B4 +3BF1B4:lI120|H3BF278 +3BF278:lI116|N +3BE868:lI114|H3BE944 +3BE944:lI116|H3BEA28 +3BEA28:lI120|N +3BE798:lH3BE878|H3BE884 +3BE878:t2:H3BE954,H3BE95C +3BE95C:lI116|H3BEA40 +3BEA40:lI101|H3BEB24 +3BEB24:lI120|H3BEC00 +3BEC00:lI116|H3BECDC +3BECDC:lI47|H3BEDB8 +3BEDB8:lI112|H3BEE94 +3BEE94:lI108|H3BEF60 +3BEF60:lI97|H3BF02C +3BF02C:lI105|H3BF0F8 +3BF0F8:lI110|N +3BE954:lI116|H3BEA38 +3BEA38:lI120|H3BEB1C +3BEB1C:lI116|N +3BE884:lH3BE964|H3BE970 +3BE964:t2:H3BEA48,H3BEA50 +3BEA50:lI116|H3BEB34 +3BEB34:lI101|H3BEC10 +3BEC10:lI120|H3BECEC +3BECEC:lI116|H3BEDC8 +3BEDC8:lI47|H3BEE9C +3BEE9C:lI120|H3BEF68 +3BEF68:lI45|H3BF034 +3BF034:lI115|H3BF100 +3BF100:lI101|H3BF1BC +3BF1BC:lI114|H3BF280 +3BF280:lI118|H3BF32C +3BF32C:lI101|H3BF3D8 +3BF3D8:lI114|H3BF48C +3BF48C:lI45|H3BF548 +3BF548:lI112|H3BF60C +3BF60C:lI97|H3BF6E0 +3BF6E0:lI114|H3BF7B4 +3BF7B4:lI115|H3BF888 +3BF888:lI101|H3BF96C +3BF96C:lI100|H3BFA48 +3BFA48:lI45|H3BFB1C +3BFB1C:lI104|H3BFBF0 +3BFBF0:lI116|H3BFCBC +3BFCBC:lI109|H3BFD80 +3BFD80:lI108|N +3BEA48:lI115|H3BEB2C +3BEB2C:lI104|H3BEC08 +3BEC08:lI116|H3BECE4 +3BECE4:lI109|H3BEDC0 +3BEDC0:lI108|N +3BE970:lH3BEA58|H3BEA64 +3BEA58:t2:H3BEB3C,H3BEB44 +3BEB44:lI116|H3BEC20 +3BEC20:lI101|H3BECFC +3BECFC:lI120|H3BEDD8 +3BEDD8:lI116|H3BEEA4 +3BEEA4:lI47|H3BEF70 +3BEF70:lI104|H3BF03C +3BF03C:lI116|H3BF108 +3BF108:lI109|H3BF1C4 +3BF1C4:lI108|N +3BEB3C:lI104|H3BEC18 +3BEC18:lI116|H3BECF4 +3BECF4:lI109|H3BEDD0 +3BEDD0:lI108|N +3BEA64:lH3BEB4C|H3BEB58 +3BEB4C:t2:H3BEC28,H3BEC30 +3BEC30:lI116|H3BED0C +3BED0C:lI101|H3BEDE8 +3BEDE8:lI120|H3BEEAC +3BEEAC:lI116|H3BEF78 +3BEF78:lI47|H3BF044 +3BF044:lI104|H3BF110 +3BF110:lI116|H3BF1CC +3BF1CC:lI109|H3BF288 +3BF288:lI108|N +3BEC28:lI104|H3BED04 +3BED04:lI116|H3BEDE0 +3BEDE0:lI109|N +3BEB58:lH3BEC38|H3BEC44 +3BEC38:t2:H3BED14,H3BED1C +3BED1C:lI105|H3BEDF8 +3BEDF8:lI109|H3BEEBC +3BEEBC:lI97|H3BEF80 +3BEF80:lI103|H3BF04C +3BF04C:lI101|H3BF118 +3BF118:lI47|H3BF1D4 +3BF1D4:lI120|H3BF290 +3BF290:lI45|H3BF334 +3BF334:lI120|H3BF3E0 +3BF3E0:lI119|H3BF494 +3BF494:lI105|H3BF550 +3BF550:lI110|H3BF614 +3BF614:lI100|H3BF6E8 +3BF6E8:lI111|H3BF7BC +3BF7BC:lI119|H3BF890 +3BF890:lI100|H3BF974 +3BF974:lI117|H3BFA50 +3BFA50:lI109|H3BFB24 +3BFB24:lI112|N +3BED14:lI120|H3BEDF0 +3BEDF0:lI119|H3BEEB4 +3BEEB4:lI100|N +3BEC44:lH3BED24|H3BED30 +3BED24:t2:H3BEE00,H3BEE08 +3BEE08:lI105|H3BEECC +3BEECC:lI109|H3BEF90 +3BEF90:lI97|H3BF054 +3BF054:lI103|H3BF120 +3BF120:lI101|H3BF1DC +3BF1DC:lI47|H3BF298 +3BF298:lI120|H3BF33C +3BF33C:lI45|H3BF3E8 +3BF3E8:lI120|H3BF49C +3BF49C:lI112|H3BF558 +3BF558:lI105|H3BF61C +3BF61C:lI120|H3BF6F0 +3BF6F0:lI109|H3BF7C4 +3BF7C4:lI97|H3BF898 +3BF898:lI112|N +3BEE00:lI120|H3BEEC4 +3BEEC4:lI112|H3BEF88 +3BEF88:lI109|N +3BED30:lH3BEE10|H3BEE1C +3BEE10:t2:H3BEED4,H3BEEDC +3BEEDC:lI105|H3BEFA0 +3BEFA0:lI109|H3BF064 +3BF064:lI97|H3BF128 +3BF128:lI103|H3BF1E4 +3BF1E4:lI101|H3BF2A0 +3BF2A0:lI47|H3BF344 +3BF344:lI120|H3BF3F0 +3BF3F0:lI45|H3BF4A4 +3BF4A4:lI120|H3BF560 +3BF560:lI98|H3BF624 +3BF624:lI105|H3BF6F8 +3BF6F8:lI116|H3BF7CC +3BF7CC:lI109|H3BF8A0 +3BF8A0:lI97|H3BF97C +3BF97C:lI112|N +3BEED4:lI120|H3BEF98 +3BEF98:lI98|H3BF05C +3BF05C:lI109|N +3BEE1C:lH3BEEE4|H3BEEF0 +3BEEE4:t2:H3BEFA8,H3BEFB0 +3BEFB0:lI105|H3BF074 +3BF074:lI109|H3BF138 +3BF138:lI97|H3BF1EC +3BF1EC:lI103|H3BF2A8 +3BF2A8:lI101|H3BF34C +3BF34C:lI47|H3BF3F8 +3BF3F8:lI120|H3BF4AC +3BF4AC:lI45|H3BF568 +3BF568:lI114|H3BF62C +3BF62C:lI103|H3BF700 +3BF700:lI98|N +3BEFA8:lI114|H3BF06C +3BF06C:lI103|H3BF130 +3BF130:lI98|N +3BEEF0:lH3BEFB8|H3BEFC4 +3BEFB8:t2:H3BF07C,H3BF084 +3BF084:lI105|H3BF148 +3BF148:lI109|H3BF1FC +3BF1FC:lI97|H3BF2B0 +3BF2B0:lI103|H3BF354 +3BF354:lI101|H3BF400 +3BF400:lI47|H3BF4B4 +3BF4B4:lI120|H3BF570 +3BF570:lI45|H3BF634 +3BF634:lI112|H3BF708 +3BF708:lI111|H3BF7D4 +3BF7D4:lI114|H3BF8A8 +3BF8A8:lI116|H3BF984 +3BF984:lI97|H3BFA58 +3BFA58:lI98|H3BFB2C +3BFB2C:lI108|H3BFBF8 +3BFBF8:lI101|H3BFCC4 +3BFCC4:lI45|H3BFD88 +3BFD88:lI112|H3BFE44 +3BFE44:lI105|H3BFEF0 +3BFEF0:lI120|H3BFFA4 +3BFFA4:lI109|H3C0050 +3C0050:lI97|H3C00FC +3C00FC:lI112|N +3BF07C:lI112|H3BF140 +3BF140:lI112|H3BF1F4 +3BF1F4:lI109|N +3BEFC4:lH3BF08C|H3BF098 +3BF08C:t2:H3BF150,H3BF158 +3BF158:lI105|H3BF20C +3BF20C:lI109|H3BF2C0 +3BF2C0:lI97|H3BF35C +3BF35C:lI103|H3BF408 +3BF408:lI101|H3BF4BC +3BF4BC:lI47|H3BF578 +3BF578:lI120|H3BF63C +3BF63C:lI45|H3BF710 +3BF710:lI112|H3BF7DC +3BF7DC:lI111|H3BF8B0 +3BF8B0:lI114|H3BF98C +3BF98C:lI116|H3BFA60 +3BFA60:lI97|H3BFB34 +3BFB34:lI98|H3BFC00 +3BFC00:lI108|H3BFCCC +3BFCCC:lI101|H3BFD90 +3BFD90:lI45|H3BFE4C +3BFE4C:lI103|H3BFEF8 +3BFEF8:lI114|H3BFFAC +3BFFAC:lI97|H3C0058 +3C0058:lI121|H3C0104 +3C0104:lI109|H3C01A8 +3C01A8:lI97|H3C025C +3C025C:lI112|N +3BF150:lI112|H3BF204 +3BF204:lI103|H3BF2B8 +3BF2B8:lI109|N +3BF098:lH3BF160|H3BF16C +3BF160:t2:H3BF214,H3BF21C +3BF21C:lI105|H3BF2D0 +3BF2D0:lI109|H3BF36C +3BF36C:lI97|H3BF410 +3BF410:lI103|H3BF4C4 +3BF4C4:lI101|H3BF580 +3BF580:lI47|H3BF644 +3BF644:lI120|H3BF718 +3BF718:lI45|H3BF7E4 +3BF7E4:lI112|H3BF8B8 +3BF8B8:lI111|H3BF994 +3BF994:lI114|H3BFA68 +3BFA68:lI116|H3BFB3C +3BFB3C:lI97|H3BFC08 +3BFC08:lI98|H3BFCD4 +3BFCD4:lI108|H3BFD98 +3BFD98:lI101|H3BFE54 +3BFE54:lI45|H3BFF00 +3BFF00:lI98|H3BFFB4 +3BFFB4:lI105|H3C0060 +3C0060:lI116|H3C010C +3C010C:lI109|H3C01B0 +3C01B0:lI97|H3C0264 +3C0264:lI112|N +3BF214:lI112|H3BF2C8 +3BF2C8:lI98|H3BF364 +3BF364:lI109|N +3BF16C:lH3BF224|H3BF230 +3BF224:t2:H3BF2D8,H3BF2E0 +3BF2E0:lI105|H3BF37C +3BF37C:lI109|H3BF420 +3BF420:lI97|H3BF4CC +3BF4CC:lI103|H3BF588 +3BF588:lI101|H3BF64C +3BF64C:lI47|H3BF720 +3BF720:lI120|H3BF7EC +3BF7EC:lI45|H3BF8C0 +3BF8C0:lI112|H3BF99C +3BF99C:lI111|H3BFA70 +3BFA70:lI114|H3BFB44 +3BFB44:lI116|H3BFC10 +3BFC10:lI97|H3BFCDC +3BFCDC:lI98|H3BFDA0 +3BFDA0:lI108|H3BFE5C +3BFE5C:lI101|H3BFF08 +3BFF08:lI45|H3BFFBC +3BFFBC:lI97|H3C0068 +3C0068:lI110|H3C0114 +3C0114:lI121|H3C01B8 +3C01B8:lI109|H3C026C +3C026C:lI97|H3C0318 +3C0318:lI112|N +3BF2D8:lI112|H3BF374 +3BF374:lI110|H3BF418 +3BF418:lI109|N +3BF230:lH3BF2E8|H3BF2F4 +3BF2E8:t2:H3BF384,H3BF38C +3BF38C:lI105|H3BF430 +3BF430:lI109|H3BF4DC +3BF4DC:lI97|H3BF590 +3BF590:lI103|H3BF654 +3BF654:lI101|H3BF728 +3BF728:lI47|H3BF7F4 +3BF7F4:lI120|H3BF8C8 +3BF8C8:lI45|H3BF9A4 +3BF9A4:lI99|H3BFA78 +3BFA78:lI109|H3BFB4C +3BFB4C:lI117|H3BFC18 +3BFC18:lI45|H3BFCE4 +3BFCE4:lI114|H3BFDA8 +3BFDA8:lI97|H3BFE64 +3BFE64:lI115|H3BFF10 +3BFF10:lI116|H3BFFC4 +3BFFC4:lI101|H3C0070 +3C0070:lI114|N +3BF384:lI114|H3BF428 +3BF428:lI97|H3BF4D4 +3BF4D4:lI115|N +3BF2F4:lH3BF394|H3BF3A0 +3BF394:t2:H3BF438,H3BF440 +3BF440:lI105|H3BF4EC +3BF4EC:lI109|H3BF5A0 +3BF5A0:lI97|H3BF664 +3BF664:lI103|H3BF730 +3BF730:lI101|H3BF7FC +3BF7FC:lI47|H3BF8D0 +3BF8D0:lI116|H3BF9AC +3BF9AC:lI105|H3BFA80 +3BFA80:lI102|H3BFB54 +3BFB54:lI102|N +3BF438:lI116|H3BF4E4 +3BF4E4:lI105|H3BF598 +3BF598:lI102|H3BF65C +3BF65C:lI102|N +3BF3A0:lH3BF448|H3BF454 +3BF448:t2:H3BF4F4,H3BF4FC +3BF4FC:lI105|H3BF5B0 +3BF5B0:lI109|H3BF674 +3BF674:lI97|H3BF738 +3BF738:lI103|H3BF804 +3BF804:lI101|H3BF8D8 +3BF8D8:lI47|H3BF9B4 +3BF9B4:lI116|H3BFA88 +3BFA88:lI105|H3BFB5C +3BFB5C:lI102|H3BFC20 +3BFC20:lI102|N +3BF4F4:lI116|H3BF5A8 +3BF5A8:lI105|H3BF66C +3BF66C:lI102|N +3BF454:lH3BF504|H3BF510 +3BF504:t2:H3BF5B8,H3BF5C0 +3BF5C0:lI105|H3BF684 +3BF684:lI109|H3BF748 +3BF748:lI97|H3BF80C +3BF80C:lI103|H3BF8E0 +3BF8E0:lI101|H3BF9BC +3BF9BC:lI47|H3BFA90 +3BFA90:lI112|H3BFB64 +3BFB64:lI110|H3BFC28 +3BFC28:lI103|N +3BF5B8:lI112|H3BF67C +3BF67C:lI110|H3BF740 +3BF740:lI103|N +3BF510:lH3BF5C8|H3BF5D4 +3BF5C8:t2:H3BF68C,H3BF694 +3BF694:lI105|H3BF758 +3BF758:lI109|H3BF81C +3BF81C:lI97|H3BF8F0 +3BF8F0:lI103|H3BF9C4 +3BF9C4:lI101|H3BFA98 +3BFA98:lI47|H3BFB6C +3BFB6C:lI106|H3BFC30 +3BFC30:lI112|H3BFCEC +3BFCEC:lI101|H3BFDB0 +3BFDB0:lI103|N +3BF68C:lI106|H3BF750 +3BF750:lI112|H3BF814 +3BF814:lI101|H3BF8E8 +3BF8E8:lI103|N +3BF5D4:lH3BF69C|H3BF6A8 +3BF69C:t2:H3BF760,H3BF768 +3BF768:lI105|H3BF82C +3BF82C:lI109|H3BF900 +3BF900:lI97|H3BF9CC +3BF9CC:lI103|H3BFAA0 +3BFAA0:lI101|H3BFB74 +3BFB74:lI47|H3BFC38 +3BFC38:lI106|H3BFCF4 +3BFCF4:lI112|H3BFDB8 +3BFDB8:lI101|H3BFE6C +3BFE6C:lI103|N +3BF760:lI106|H3BF824 +3BF824:lI112|H3BF8F8 +3BF8F8:lI103|N +3BF6A8:lH3BF770|H3BF77C +3BF770:t2:H3BF834,H3BF83C +3BF83C:lI105|H3BF910 +3BF910:lI109|H3BF9DC +3BF9DC:lI97|H3BFAA8 +3BFAA8:lI103|H3BFB7C +3BFB7C:lI101|H3BFC40 +3BFC40:lI47|H3BFCFC +3BFCFC:lI106|H3BFDC0 +3BFDC0:lI112|H3BFE74 +3BFE74:lI101|H3BFF18 +3BFF18:lI103|N +3BF834:lI106|H3BF908 +3BF908:lI112|H3BF9D4 +3BF9D4:lI101|N +3BF77C:lH3BF844|H3BF850 +3BF844:t2:H3BF918,H3BF920 +3BF920:lI105|H3BF9EC +3BF9EC:lI109|H3BFAB8 +3BFAB8:lI97|H3BFB84 +3BFB84:lI103|H3BFC48 +3BFC48:lI101|H3BFD04 +3BFD04:lI47|H3BFDC8 +3BFDC8:lI105|H3BFE7C +3BFE7C:lI101|H3BFF20 +3BFF20:lI102|N +3BF918:lI105|H3BF9E4 +3BF9E4:lI101|H3BFAB0 +3BFAB0:lI102|N +3BF850:lH3BF928|H3BF934 +3BF928:t2:H3BF9F4,H3BF9FC +3BF9FC:lI105|H3BFAC8 +3BFAC8:lI109|H3BFB94 +3BFB94:lI97|H3BFC50 +3BFC50:lI103|H3BFD0C +3BFD0C:lI101|H3BFDD0 +3BFDD0:lI47|H3BFE84 +3BFE84:lI103|H3BFF28 +3BFF28:lI105|H3BFFCC +3BFFCC:lI102|N +3BF9F4:lI103|H3BFAC0 +3BFAC0:lI105|H3BFB8C +3BFB8C:lI102|N +3BF934:lH3BFA04|H3BFA10 +3BFA04:t2:H3BFAD0,H3BFAD8 +3BFAD8:lI99|H3BFBA4 +3BFBA4:lI104|H3BFC60 +3BFC60:lI101|H3BFD14 +3BFD14:lI109|H3BFDD8 +3BFDD8:lI105|H3BFE8C +3BFE8C:lI99|H3BFF30 +3BFF30:lI97|H3BFFD4 +3BFFD4:lI108|H3C0078 +3C0078:lI47|H3C011C +3C011C:lI120|H3C01C0 +3C01C0:lI45|H3C0274 +3C0274:lI112|H3C0320 +3C0320:lI100|H3C03CC +3C03CC:lI98|N +3BFAD0:lI112|H3BFB9C +3BFB9C:lI100|H3BFC58 +3BFC58:lI98|N +3BFA10:lH3BFAE0|H3BFAEC +3BFAE0:t2:H3BFBAC,H3BFBB4 +3BFBB4:lI99|H3BFC70 +3BFC70:lI104|H3BFD24 +3BFD24:lI101|H3BFDE0 +3BFDE0:lI109|H3BFE94 +3BFE94:lI105|H3BFF38 +3BFF38:lI99|H3BFFDC +3BFFDC:lI97|H3C0080 +3C0080:lI108|H3C0124 +3C0124:lI47|H3C01C8 +3C01C8:lI120|H3C027C +3C027C:lI45|H3C0328 +3C0328:lI112|H3C03D4 +3C03D4:lI100|H3C0460 +3C0460:lI98|N +3BFBAC:lI120|H3BFC68 +3BFC68:lI121|H3BFD1C +3BFD1C:lI122|N +3BFAEC:lH3BFBBC|H3BFBC8 +3BFBBC:t2:H3BFC78,H3BFC80 +3BFC80:lI97|H3BFD34 +3BFD34:lI117|H3BFDF0 +3BFDF0:lI100|H3BFE9C +3BFE9C:lI105|H3BFF40 +3BFF40:lI111|H3BFFE4 +3BFFE4:lI47|H3C0088 +3C0088:lI120|H3C012C +3C012C:lI45|H3C01D0 +3C01D0:lI119|H3C0284 +3C0284:lI97|H3C0330 +3C0330:lI118|N +3BFC78:lI119|H3BFD2C +3BFD2C:lI97|H3BFDE8 +3BFDE8:lI118|N +3BFBC8:lH3BFC88|H3BFC94 +3BFC88:t2:H3BFD3C,H3BFD44 +3BFD44:lI97|H3BFE00 +3BFE00:lI117|H3BFEA4 +3BFEA4:lI100|H3BFF48 +3BFF48:lI105|H3BFFEC +3BFFEC:lI111|H3C0090 +3C0090:lI47|H3C0134 +3C0134:lI120|H3C01D8 +3C01D8:lI45|H3C028C +3C028C:lI114|H3C0338 +3C0338:lI101|H3C03DC +3C03DC:lI97|H3C0468 +3C0468:lI108|H3C04FC +3C04FC:lI97|H3C0598 +3C0598:lI117|H3C063C +3C063C:lI100|H3C06E8 +3C06E8:lI105|H3C0794 +3C0794:lI111|N +3BFD3C:lI114|H3BFDF8 +3BFDF8:lI97|N +3BFC94:lH3BFD4C|H3BFD58 +3BFD4C:t2:H3BFE08,H3BFE10 +3BFE10:lI97|H3BFEB4 +3BFEB4:lI117|H3BFF58 +3BFF58:lI100|H3BFFF4 +3BFFF4:lI105|H3C0098 +3C0098:lI111|H3C013C +3C013C:lI47|H3C01E0 +3C01E0:lI120|H3C0294 +3C0294:lI45|H3C0340 +3C0340:lI112|H3C03E4 +3C03E4:lI110|H3C0470 +3C0470:lI45|H3C0504 +3C0504:lI114|H3C05A0 +3C05A0:lI101|H3C0644 +3C0644:lI97|H3C06F0 +3C06F0:lI108|H3C079C +3C079C:lI97|H3C0838 +3C0838:lI117|H3C08C4 +3C08C4:lI100|H3C0958 +3C0958:lI105|H3C09EC +3C09EC:lI111|H3C0A88 +3C0A88:lI45|H3C0B2C +3C0B2C:lI112|H3C0BD0 +3C0BD0:lI108|H3C0C84 +3C0C84:lI117|H3C0D38 +3C0D38:lI103|H3C0DEC +3C0DEC:lI105|H3C0EA0 +3C0EA0:lI110|N +3BFE08:lI114|H3BFEAC +3BFEAC:lI112|H3BFF50 +3BFF50:lI109|N +3BFD58:lH3BFE18|H3BFE24 +3BFE18:t2:H3BFEBC,H3BFEC4 +3BFEC4:lI97|H3BFF68 +3BFF68:lI117|H3C0004 +3C0004:lI100|H3C00A0 +3C00A0:lI105|H3C0144 +3C0144:lI111|H3C01E8 +3C01E8:lI47|H3C029C +3C029C:lI120|H3C0348 +3C0348:lI45|H3C03EC +3C03EC:lI112|H3C0478 +3C0478:lI110|H3C050C +3C050C:lI45|H3C05A8 +3C05A8:lI114|H3C064C +3C064C:lI101|H3C06F8 +3C06F8:lI97|H3C07A4 +3C07A4:lI108|H3C0840 +3C0840:lI97|H3C08CC +3C08CC:lI117|H3C0960 +3C0960:lI100|H3C09F4 +3C09F4:lI105|H3C0A90 +3C0A90:lI111|N +3BFEBC:lI114|H3BFF60 +3BFF60:lI97|H3BFFFC +3BFFFC:lI109|N +3BFE24:lH3BFECC|H3BFED8 +3BFECC:t2:H3BFF70,H3BFF78 +3BFF78:lI97|H3C0014 +3C0014:lI117|H3C00B0 +3C00B0:lI100|H3C014C +3C014C:lI105|H3C01F0 +3C01F0:lI111|H3C02A4 +3C02A4:lI47|H3C0350 +3C0350:lI120|H3C03F4 +3C03F4:lI45|H3C0480 +3C0480:lI97|H3C0514 +3C0514:lI105|H3C05B0 +3C05B0:lI102|H3C0654 +3C0654:lI102|N +3BFF70:lI97|H3C000C +3C000C:lI105|H3C00A8 +3C00A8:lI102|N +3BFED8:lH3BFF80|H3BFF8C +3BFF80:t2:H3C001C,H3C0024 +3C0024:lI97|H3C00C0 +3C00C0:lI117|H3C015C +3C015C:lI100|H3C0200 +3C0200:lI105|H3C02AC +3C02AC:lI111|H3C0358 +3C0358:lI47|H3C03FC +3C03FC:lI120|H3C0488 +3C0488:lI45|H3C051C +3C051C:lI97|H3C05B8 +3C05B8:lI105|H3C065C +3C065C:lI102|H3C0700 +3C0700:lI102|N +3C001C:lI97|H3C00B8 +3C00B8:lI105|H3C0154 +3C0154:lI102|H3C01F8 +3C01F8:lI102|N +3BFF8C:lH3C002C|H3C0038 +3C002C:t2:H3C00C8,H3C00D0 +3C00D0:lI97|H3C016C +3C016C:lI117|H3C0210 +3C0210:lI100|H3C02BC +3C02BC:lI105|H3C0360 +3C0360:lI111|H3C0404 +3C0404:lI47|H3C0490 +3C0490:lI120|H3C0524 +3C0524:lI45|H3C05C0 +3C05C0:lI97|H3C0664 +3C0664:lI105|H3C0708 +3C0708:lI102|H3C07AC +3C07AC:lI102|N +3C00C8:lI97|H3C0164 +3C0164:lI105|H3C0208 +3C0208:lI102|H3C02B4 +3C02B4:lI99|N +3C0038:lH3C00D8|H3C00E4 +3C00D8:t2:H3C0174,H3C017C +3C017C:lI97|H3C0220 +3C0220:lI117|H3C02CC +3C02CC:lI100|H3C0370 +3C0370:lI105|H3C040C +3C040C:lI111|H3C0498 +3C0498:lI47|H3C052C +3C052C:lI109|H3C05C8 +3C05C8:lI112|H3C066C +3C066C:lI101|H3C0710 +3C0710:lI103|N +3C0174:lI109|H3C0218 +3C0218:lI112|H3C02C4 +3C02C4:lI103|H3C0368 +3C0368:lI97|N +3C00E4:lH3C0184|H3C0190 +3C0184:t2:H3C0228,H3C0230 +3C0230:lI97|H3C02DC +3C02DC:lI117|H3C0380 +3C0380:lI100|H3C0414 +3C0414:lI105|H3C04A0 +3C04A0:lI111|H3C0534 +3C0534:lI47|H3C05D0 +3C05D0:lI109|H3C0674 +3C0674:lI112|H3C0718 +3C0718:lI101|H3C07B4 +3C07B4:lI103|N +3C0228:lI109|H3C02D4 +3C02D4:lI112|H3C0378 +3C0378:lI50|N +3C0190:lH3C0238|H3C0244 +3C0238:t2:H3C02E4,H3C02EC +3C02EC:lI97|H3C0390 +3C0390:lI117|H3C041C +3C041C:lI100|H3C04A8 +3C04A8:lI105|H3C053C +3C053C:lI111|H3C05D8 +3C05D8:lI47|H3C067C +3C067C:lI98|H3C0720 +3C0720:lI97|H3C07BC +3C07BC:lI115|H3C0848 +3C0848:lI105|H3C08D4 +3C08D4:lI99|N +3C02E4:lI97|H3C0388 +3C0388:lI117|N +3C0244:lH3C02F4|H3C0300 +3C02F4:t2:H3C0398,H3C03A0 +3C03A0:lI97|H3C042C +3C042C:lI117|H3C04B8 +3C04B8:lI100|H3C0544 +3C0544:lI105|H3C05E0 +3C05E0:lI111|H3C0684 +3C0684:lI47|H3C0728 +3C0728:lI98|H3C07C4 +3C07C4:lI97|H3C0850 +3C0850:lI115|H3C08DC +3C08DC:lI105|H3C0968 +3C0968:lI99|N +3C0398:lI115|H3C0424 +3C0424:lI110|H3C04B0 +3C04B0:lI100|N +3C0300:lH3C03A8|H3C03B4 +3C03A8:t2:H3C0434,H3C043C +3C043C:lI97|H3C04C8 +3C04C8:lI112|H3C0554 +3C0554:lI112|H3C05E8 +3C05E8:lI108|H3C068C +3C068C:lI105|H3C0730 +3C0730:lI99|H3C07CC +3C07CC:lI97|H3C0858 +3C0858:lI116|H3C08E4 +3C08E4:lI105|H3C0970 +3C0970:lI111|H3C09FC +3C09FC:lI110|H3C0A98 +3C0A98:lI47|H3C0B34 +3C0B34:lI122|H3C0BD8 +3C0BD8:lI105|H3C0C8C +3C0C8C:lI112|N +3C0434:lI122|H3C04C0 +3C04C0:lI105|H3C054C +3C054C:lI112|N +3C03B4:lH3C0444|H3C0450 +3C0444:t2:H3C04D0,H3C04D8 +3C04D8:lI97|H3C0564 +3C0564:lI112|H3C05F8 +3C05F8:lI112|H3C0694 +3C0694:lI108|H3C0738 +3C0738:lI105|H3C07D4 +3C07D4:lI99|H3C0860 +3C0860:lI97|H3C08EC +3C08EC:lI116|H3C0978 +3C0978:lI105|H3C0A04 +3C0A04:lI111|H3C0AA0 +3C0AA0:lI110|H3C0B3C +3C0B3C:lI47|H3C0BE0 +3C0BE0:lI120|H3C0C94 +3C0C94:lI45|H3C0D40 +3C0D40:lI119|H3C0DF4 +3C0DF4:lI97|H3C0EA8 +3C0EA8:lI105|H3C0F64 +3C0F64:lI115|H3C1030 +3C1030:lI45|H3C1104 +3C1104:lI115|H3C11D8 +3C11D8:lI111|H3C12A4 +3C12A4:lI117|H3C1378 +3C1378:lI114|H3C1454 +3C1454:lI99|H3C1538 +3C1538:lI101|N +3C04D0:lI115|H3C055C +3C055C:lI114|H3C05F0 +3C05F0:lI99|N +3C0450:lH3C04E0|H3C04EC +3C04E0:t2:H3C056C,H3C0574 +3C0574:lI97|H3C0608 +3C0608:lI112|H3C06A4 +3C06A4:lI112|H3C0748 +3C0748:lI108|H3C07E4 +3C07E4:lI105|H3C0868 +3C0868:lI99|H3C08F4 +3C08F4:lI97|H3C0980 +3C0980:lI116|H3C0A0C +3C0A0C:lI105|H3C0AA8 +3C0AA8:lI111|H3C0B44 +3C0B44:lI110|H3C0BE8 +3C0BE8:lI47|H3C0C9C +3C0C9C:lI120|H3C0D48 +3C0D48:lI45|H3C0DFC +3C0DFC:lI117|H3C0EB0 +3C0EB0:lI115|H3C0F6C +3C0F6C:lI116|H3C1038 +3C1038:lI97|H3C110C +3C110C:lI114|N +3C056C:lI117|H3C0600 +3C0600:lI115|H3C069C +3C069C:lI116|H3C0740 +3C0740:lI97|H3C07DC +3C07DC:lI114|N +3C04EC:lH3C057C|H3C0588 +3C057C:t2:H3C0610,H3C0618 +3C0618:lI97|H3C06B4 +3C06B4:lI112|H3C0750 +3C0750:lI112|H3C07EC +3C07EC:lI108|H3C0870 +3C0870:lI105|H3C08FC +3C08FC:lI99|H3C0988 +3C0988:lI97|H3C0A14 +3C0A14:lI116|H3C0AB0 +3C0AB0:lI105|H3C0B4C +3C0B4C:lI111|H3C0BF0 +3C0BF0:lI110|H3C0CA4 +3C0CA4:lI47|H3C0D50 +3C0D50:lI120|H3C0E04 +3C0E04:lI45|H3C0EB8 +3C0EB8:lI116|H3C0F74 +3C0F74:lI114|H3C1040 +3C1040:lI111|H3C1114 +3C1114:lI102|H3C11E0 +3C11E0:lI102|H3C12AC +3C12AC:lI45|H3C1380 +3C1380:lI109|H3C145C +3C145C:lI115|N +3C0610:lI109|H3C06AC +3C06AC:lI115|N +3C0588:lH3C0620|H3C062C +3C0620:t2:H3C06BC,H3C06C4 +3C06C4:lI97|H3C0760 +3C0760:lI112|H3C07F4 +3C07F4:lI112|H3C0878 +3C0878:lI108|H3C0904 +3C0904:lI105|H3C0990 +3C0990:lI99|H3C0A1C +3C0A1C:lI97|H3C0AB8 +3C0AB8:lI116|H3C0B54 +3C0B54:lI105|H3C0BF8 +3C0BF8:lI111|H3C0CAC +3C0CAC:lI110|H3C0D58 +3C0D58:lI47|H3C0E0C +3C0E0C:lI120|H3C0EC0 +3C0EC0:lI45|H3C0F7C +3C0F7C:lI116|H3C1048 +3C1048:lI114|H3C111C +3C111C:lI111|H3C11E8 +3C11E8:lI102|H3C12B4 +3C12B4:lI102|H3C1388 +3C1388:lI45|H3C1464 +3C1464:lI109|H3C1540 +3C1540:lI101|N +3C06BC:lI109|H3C0758 +3C0758:lI101|N +3C062C:lH3C06CC|H3C06D8 +3C06CC:t2:H3C0768,H3C0770 +3C0770:lI97|H3C0804 +3C0804:lI112|H3C0888 +3C0888:lI112|H3C090C +3C090C:lI108|H3C0998 +3C0998:lI105|H3C0A24 +3C0A24:lI99|H3C0AC0 +3C0AC0:lI97|H3C0B5C +3C0B5C:lI116|H3C0C00 +3C0C00:lI105|H3C0CB4 +3C0CB4:lI111|H3C0D60 +3C0D60:lI110|H3C0E14 +3C0E14:lI47|H3C0EC8 +3C0EC8:lI120|H3C0F84 +3C0F84:lI45|H3C1050 +3C1050:lI116|H3C1124 +3C1124:lI114|H3C11F0 +3C11F0:lI111|H3C12BC +3C12BC:lI102|H3C1390 +3C1390:lI102|H3C146C +3C146C:lI45|H3C1548 +3C1548:lI109|H3C161C +3C161C:lI97|H3C16F0 +3C16F0:lI110|N +3C0768:lI109|H3C07FC +3C07FC:lI97|H3C0880 +3C0880:lI110|N +3C06D8:lH3C0778|H3C0784 +3C0778:t2:H3C080C,H3C0814 +3C0814:lI97|H3C0890 +3C0890:lI112|H3C0914 +3C0914:lI112|H3C09A0 +3C09A0:lI108|H3C0A2C +3C0A2C:lI105|H3C0AC8 +3C0AC8:lI99|H3C0B64 +3C0B64:lI97|H3C0C08 +3C0C08:lI116|H3C0CBC +3C0CBC:lI105|H3C0D68 +3C0D68:lI111|H3C0E1C +3C0E1C:lI110|H3C0ED0 +3C0ED0:lI47|H3C0F8C +3C0F8C:lI120|H3C1058 +3C1058:lI45|H3C112C +3C112C:lI116|H3C11F8 +3C11F8:lI114|H3C12C4 +3C12C4:lI111|H3C1398 +3C1398:lI102|H3C1474 +3C1474:lI102|N +3C080C:lI116|N +3C0784:lH3C081C|H3C0828 +3C081C:t2:H3C0898,H3C08A0 +3C08A0:lI97|H3C0924 +3C0924:lI112|H3C09A8 +3C09A8:lI112|H3C0A34 +3C0A34:lI108|H3C0AD0 +3C0AD0:lI105|H3C0B6C +3C0B6C:lI99|H3C0C10 +3C0C10:lI97|H3C0CC4 +3C0CC4:lI116|H3C0D70 +3C0D70:lI105|H3C0E24 +3C0E24:lI111|H3C0ED8 +3C0ED8:lI110|H3C0F94 +3C0F94:lI47|H3C1060 +3C1060:lI120|H3C1134 +3C1134:lI45|H3C1200 +3C1200:lI116|H3C12CC +3C12CC:lI114|H3C13A0 +3C13A0:lI111|H3C147C +3C147C:lI102|H3C1550 +3C1550:lI102|N +3C0898:lI116|H3C091C +3C091C:lI114|N +3C0828:lH3C08A8|H3C08B4 +3C08A8:t2:H3C092C,H3C0934 +3C0934:lI97|H3C09B8 +3C09B8:lI112|H3C0A44 +3C0A44:lI112|H3C0AE0 +3C0AE0:lI108|H3C0B74 +3C0B74:lI105|H3C0C18 +3C0C18:lI99|H3C0CCC +3C0CCC:lI97|H3C0D78 +3C0D78:lI116|H3C0E2C +3C0E2C:lI105|H3C0EE0 +3C0EE0:lI111|H3C0F9C +3C0F9C:lI110|H3C1068 +3C1068:lI47|H3C113C +3C113C:lI120|H3C1208 +3C1208:lI45|H3C12D4 +3C12D4:lI116|H3C13A8 +3C13A8:lI114|H3C1484 +3C1484:lI111|H3C1558 +3C1558:lI102|H3C1624 +3C1624:lI102|N +3C092C:lI114|H3C09B0 +3C09B0:lI111|H3C0A3C +3C0A3C:lI102|H3C0AD8 +3C0AD8:lI102|N +3C08B4:lH3C093C|H3C0948 +3C093C:t2:H3C09C0,H3C09C8 +3C09C8:lI97|H3C0A54 +3C0A54:lI112|H3C0AF0 +3C0AF0:lI112|H3C0B84 +3C0B84:lI108|H3C0C28 +3C0C28:lI105|H3C0CDC +3C0CDC:lI99|H3C0D88 +3C0D88:lI97|H3C0E34 +3C0E34:lI116|H3C0EE8 +3C0EE8:lI105|H3C0FA4 +3C0FA4:lI111|H3C1070 +3C1070:lI110|H3C1144 +3C1144:lI47|H3C1210 +3C1210:lI120|H3C12DC +3C12DC:lI45|H3C13B0 +3C13B0:lI116|H3C148C +3C148C:lI101|H3C1560 +3C1560:lI120|H3C162C +3C162C:lI105|H3C16F8 +3C16F8:lI110|H3C17BC +3C17BC:lI102|H3C1880 +3C1880:lI111|N +3C09C0:lI116|H3C0A4C +3C0A4C:lI101|H3C0AE8 +3C0AE8:lI120|H3C0B7C +3C0B7C:lI105|H3C0C20 +3C0C20:lI110|H3C0CD4 +3C0CD4:lI102|H3C0D80 +3C0D80:lI111|N +3C0948:lH3C09D0|H3C09DC +3C09D0:t2:H3C0A5C,H3C0A64 +3C0A64:lI97|H3C0B00 +3C0B00:lI112|H3C0B94 +3C0B94:lI112|H3C0C38 +3C0C38:lI108|H3C0CE4 +3C0CE4:lI105|H3C0D90 +3C0D90:lI99|H3C0E3C +3C0E3C:lI97|H3C0EF0 +3C0EF0:lI116|H3C0FAC +3C0FAC:lI105|H3C1078 +3C1078:lI111|H3C114C +3C114C:lI110|H3C1218 +3C1218:lI47|H3C12E4 +3C12E4:lI120|H3C13B8 +3C13B8:lI45|H3C1494 +3C1494:lI116|H3C1568 +3C1568:lI101|H3C1634 +3C1634:lI120|H3C1700 +3C1700:lI105|H3C17C4 +3C17C4:lI110|H3C1888 +3C1888:lI102|H3C1944 +3C1944:lI111|N +3C0A5C:lI116|H3C0AF8 +3C0AF8:lI101|H3C0B8C +3C0B8C:lI120|H3C0C30 +3C0C30:lI105|N +3C09DC:lH3C0A6C|H3C0A78 +3C0A6C:t2:H3C0B08,H3C0B10 +3C0B10:lI97|H3C0BA4 +3C0BA4:lI112|H3C0C48 +3C0C48:lI112|H3C0CEC +3C0CEC:lI108|H3C0D98 +3C0D98:lI105|H3C0E44 +3C0E44:lI99|H3C0EF8 +3C0EF8:lI97|H3C0FB4 +3C0FB4:lI116|H3C1080 +3C1080:lI105|H3C1154 +3C1154:lI111|H3C1220 +3C1220:lI110|H3C12EC +3C12EC:lI47|H3C13C0 +3C13C0:lI120|H3C149C +3C149C:lI45|H3C1570 +3C1570:lI116|H3C163C +3C163C:lI101|H3C1708 +3C1708:lI120|N +3C0B08:lI116|H3C0B9C +3C0B9C:lI101|H3C0C40 +3C0C40:lI120|N +3C0A78:lH3C0B18|H3C0B24 +3C0B18:t2:H3C0BAC,H3C0BB4 +3C0BB4:lI97|H3C0C58 +3C0C58:lI112|H3C0CFC +3C0CFC:lI112|H3C0DA0 +3C0DA0:lI108|H3C0E4C +3C0E4C:lI105|H3C0F00 +3C0F00:lI99|H3C0FBC +3C0FBC:lI97|H3C1088 +3C1088:lI116|H3C115C +3C115C:lI105|H3C1228 +3C1228:lI111|H3C12F4 +3C12F4:lI110|H3C13C8 +3C13C8:lI47|H3C14A4 +3C14A4:lI120|H3C1578 +3C1578:lI45|H3C1644 +3C1644:lI116|H3C1710 +3C1710:lI99|H3C17CC +3C17CC:lI108|N +3C0BAC:lI116|H3C0C50 +3C0C50:lI99|H3C0CF4 +3C0CF4:lI108|N +3C0B24:lH3C0BBC|H3C0BC8 +3C0BBC:t2:H3C0C60,H3C0C68 +3C0C68:lI97|H3C0D0C +3C0D0C:lI112|H3C0DB0 +3C0DB0:lI112|H3C0E54 +3C0E54:lI108|H3C0F08 +3C0F08:lI105|H3C0FC4 +3C0FC4:lI99|H3C1090 +3C1090:lI97|H3C1164 +3C1164:lI116|H3C1230 +3C1230:lI105|H3C12FC +3C12FC:lI111|H3C13D0 +3C13D0:lI110|H3C14AC +3C14AC:lI47|H3C1580 +3C1580:lI120|H3C164C +3C164C:lI45|H3C1718 +3C1718:lI116|H3C17D4 +3C17D4:lI97|H3C1890 +3C1890:lI114|N +3C0C60:lI116|H3C0D04 +3C0D04:lI97|H3C0DA8 +3C0DA8:lI114|N +3C0BC8:lH3C0C70|H3C0C7C +3C0C70:t2:H3C0D14,H3C0D1C +3C0D1C:lI97|H3C0DC0 +3C0DC0:lI112|H3C0E64 +3C0E64:lI112|H3C0F18 +3C0F18:lI108|H3C0FD4 +3C0FD4:lI105|H3C10A0 +3C10A0:lI99|H3C116C +3C116C:lI97|H3C1238 +3C1238:lI116|H3C1304 +3C1304:lI105|H3C13D8 +3C13D8:lI111|H3C14B4 +3C14B4:lI110|H3C1588 +3C1588:lI47|H3C1654 +3C1654:lI120|H3C1720 +3C1720:lI45|H3C17DC +3C17DC:lI115|H3C1898 +3C1898:lI118|H3C194C +3C194C:lI52|H3C1A00 +3C1A00:lI99|H3C1AB4 +3C1AB4:lI114|H3C1B78 +3C1B78:lI99|N +3C0D14:lI115|H3C0DB8 +3C0DB8:lI118|H3C0E5C +3C0E5C:lI52|H3C0F10 +3C0F10:lI99|H3C0FCC +3C0FCC:lI114|H3C1098 +3C1098:lI99|N +3C0C7C:lH3C0D24|H3C0D30 +3C0D24:t2:H3C0DC8,H3C0DD0 +3C0DD0:lI97|H3C0E74 +3C0E74:lI112|H3C0F28 +3C0F28:lI112|H3C0FE4 +3C0FE4:lI108|H3C10B0 +3C10B0:lI105|H3C117C +3C117C:lI99|H3C1248 +3C1248:lI97|H3C130C +3C130C:lI116|H3C13E0 +3C13E0:lI105|H3C14BC +3C14BC:lI111|H3C1590 +3C1590:lI110|H3C165C +3C165C:lI47|H3C1728 +3C1728:lI120|H3C17E4 +3C17E4:lI45|H3C18A0 +3C18A0:lI115|H3C1954 +3C1954:lI118|H3C1A08 +3C1A08:lI52|H3C1ABC +3C1ABC:lI99|H3C1B80 +3C1B80:lI112|H3C1C4C +3C1C4C:lI105|H3C1D10 +3C1D10:lI111|N +3C0DC8:lI115|H3C0E6C +3C0E6C:lI118|H3C0F20 +3C0F20:lI52|H3C0FDC +3C0FDC:lI99|H3C10A8 +3C10A8:lI112|H3C1174 +3C1174:lI105|H3C1240 +3C1240:lI111|N +3C0D30:lH3C0DD8|H3C0DE4 +3C0DD8:t2:H3C0E7C,H3C0E84 +3C0E84:lI97|H3C0F38 +3C0F38:lI112|H3C0FF4 +3C0FF4:lI112|H3C10B8 +3C10B8:lI108|H3C1184 +3C1184:lI105|H3C1250 +3C1250:lI99|H3C1314 +3C1314:lI97|H3C13E8 +3C13E8:lI116|H3C14C4 +3C14C4:lI105|H3C1598 +3C1598:lI111|H3C1664 +3C1664:lI110|H3C1730 +3C1730:lI47|H3C17EC +3C17EC:lI120|H3C18A8 +3C18A8:lI45|H3C195C +3C195C:lI115|H3C1A10 +3C1A10:lI116|H3C1AC4 +3C1AC4:lI117|H3C1B88 +3C1B88:lI102|H3C1C54 +3C1C54:lI102|H3C1D18 +3C1D18:lI105|H3C1DD4 +3C1DD4:lI116|N +3C0E7C:lI115|H3C0F30 +3C0F30:lI105|H3C0FEC +3C0FEC:lI116|N +3C0DE4:lH3C0E8C|H3C0E98 +3C0E8C:t2:H3C0F40,H3C0F48 +3C0F48:lI97|H3C1004 +3C1004:lI112|H3C10C8 +3C10C8:lI112|H3C1194 +3C1194:lI108|H3C1258 +3C1258:lI105|H3C131C +3C131C:lI99|H3C13F0 +3C13F0:lI97|H3C14CC +3C14CC:lI116|H3C15A0 +3C15A0:lI105|H3C166C +3C166C:lI111|H3C1738 +3C1738:lI110|H3C17F4 +3C17F4:lI47|H3C18B0 +3C18B0:lI120|H3C1964 +3C1964:lI45|H3C1A18 +3C1A18:lI115|H3C1ACC +3C1ACC:lI104|H3C1B90 +3C1B90:lI97|H3C1C5C +3C1C5C:lI114|N +3C0F40:lI115|H3C0FFC +3C0FFC:lI104|H3C10C0 +3C10C0:lI97|H3C118C +3C118C:lI114|N +3C0E98:lH3C0F50|H3C0F5C +3C0F50:t2:H3C100C,H3C1014 +3C1014:lI97|H3C10D8 +3C10D8:lI112|H3C119C +3C119C:lI112|H3C1260 +3C1260:lI108|H3C1324 +3C1324:lI105|H3C13F8 +3C13F8:lI99|H3C14D4 +3C14D4:lI97|H3C15A8 +3C15A8:lI116|H3C1674 +3C1674:lI105|H3C1740 +3C1740:lI111|H3C17FC +3C17FC:lI110|H3C18B8 +3C18B8:lI47|H3C196C +3C196C:lI120|H3C1A20 +3C1A20:lI45|H3C1AD4 +3C1AD4:lI115|H3C1B98 +3C1B98:lI104|N +3C100C:lI115|H3C10D0 +3C10D0:lI104|N +3C0F5C:lH3C101C|H3C1028 +3C101C:t2:H3C10E0,H3C10E8 +3C10E8:lI97|H3C11AC +3C11AC:lI112|H3C1268 +3C1268:lI112|H3C132C +3C132C:lI108|H3C1400 +3C1400:lI105|H3C14DC +3C14DC:lI99|H3C15B0 +3C15B0:lI97|H3C167C +3C167C:lI116|H3C1748 +3C1748:lI105|H3C1804 +3C1804:lI111|H3C18C0 +3C18C0:lI110|H3C1974 +3C1974:lI47|H3C1A28 +3C1A28:lI120|H3C1ADC +3C1ADC:lI45|H3C1BA0 +3C1BA0:lI110|H3C1C64 +3C1C64:lI101|H3C1D20 +3C1D20:lI116|H3C1DDC +3C1DDC:lI99|H3C1E98 +3C1E98:lI100|H3C1F5C +3C1F5C:lI102|N +3C10E0:lI110|H3C11A4 +3C11A4:lI99|N +3C1028:lH3C10F0|H3C10FC +3C10F0:t2:H3C11B4,H3C11BC +3C11BC:lI97|H3C1278 +3C1278:lI112|H3C133C +3C133C:lI112|H3C1408 +3C1408:lI108|H3C14E4 +3C14E4:lI105|H3C15B8 +3C15B8:lI99|H3C1684 +3C1684:lI97|H3C1750 +3C1750:lI116|H3C180C +3C180C:lI105|H3C18C8 +3C18C8:lI111|H3C197C +3C197C:lI110|H3C1A30 +3C1A30:lI47|H3C1AE4 +3C1AE4:lI120|H3C1BA8 +3C1BA8:lI45|H3C1C6C +3C1C6C:lI110|H3C1D28 +3C1D28:lI101|H3C1DE4 +3C1DE4:lI116|H3C1EA0 +3C1EA0:lI99|H3C1F64 +3C1F64:lI100|H3C2018 +3C2018:lI102|N +3C11B4:lI99|H3C1270 +3C1270:lI100|H3C1334 +3C1334:lI102|N +3C10FC:lH3C11C4|H3C11D0 +3C11C4:t2:H3C1280,H3C1288 +3C1288:lI97|H3C134C +3C134C:lI112|H3C1418 +3C1418:lI112|H3C14EC +3C14EC:lI108|H3C15C0 +3C15C0:lI105|H3C168C +3C168C:lI99|H3C1758 +3C1758:lI97|H3C1814 +3C1814:lI116|H3C18D0 +3C18D0:lI105|H3C1984 +3C1984:lI111|H3C1A38 +3C1A38:lI110|H3C1AEC +3C1AEC:lI47|H3C1BB0 +3C1BB0:lI120|H3C1C74 +3C1C74:lI45|H3C1D30 +3C1D30:lI109|H3C1DEC +3C1DEC:lI105|H3C1EA8 +3C1EA8:lI102|N +3C1280:lI109|H3C1344 +3C1344:lI105|H3C1410 +3C1410:lI102|N +3C11D0:lH3C1290|H3C129C +3C1290:t2:H3C1354,H3C135C +3C135C:lI97|H3C1428 +3C1428:lI112|H3C14FC +3C14FC:lI112|H3C15D0 +3C15D0:lI108|H3C169C +3C169C:lI105|H3C1760 +3C1760:lI99|H3C181C +3C181C:lI97|H3C18D8 +3C18D8:lI116|H3C198C +3C198C:lI105|H3C1A40 +3C1A40:lI111|H3C1AF4 +3C1AF4:lI110|H3C1BB8 +3C1BB8:lI47|H3C1C7C +3C1C7C:lI120|H3C1D38 +3C1D38:lI45|H3C1DF4 +3C1DF4:lI108|H3C1EB0 +3C1EB0:lI97|H3C1F6C +3C1F6C:lI116|H3C2020 +3C2020:lI101|H3C20DC +3C20DC:lI120|N +3C1354:lI108|H3C1420 +3C1420:lI97|H3C14F4 +3C14F4:lI116|H3C15C8 +3C15C8:lI101|H3C1694 +3C1694:lI120|N +3C129C:lH3C1364|H3C1370 +3C1364:t2:H3C1430,H3C1438 +3C1438:lI97|H3C150C +3C150C:lI112|H3C15E0 +3C15E0:lI112|H3C16A4 +3C16A4:lI108|H3C1768 +3C1768:lI105|H3C1824 +3C1824:lI99|H3C18E0 +3C18E0:lI97|H3C1994 +3C1994:lI116|H3C1A48 +3C1A48:lI105|H3C1AFC +3C1AFC:lI111|H3C1BC0 +3C1BC0:lI110|H3C1C84 +3C1C84:lI47|H3C1D40 +3C1D40:lI120|H3C1DFC +3C1DFC:lI45|H3C1EB8 +3C1EB8:lI107|H3C1F74 +3C1F74:lI111|H3C2028 +3C2028:lI97|H3C20E4 +3C20E4:lI110|N +3C1430:lI115|H3C1504 +3C1504:lI107|H3C15D8 +3C15D8:lI112|N +3C1370:lH3C1440|H3C144C +3C1440:t2:H3C1514,H3C151C +3C151C:lI97|H3C15F0 +3C15F0:lI112|H3C16B4 +3C16B4:lI112|H3C1770 +3C1770:lI108|H3C182C +3C182C:lI105|H3C18E8 +3C18E8:lI99|H3C199C +3C199C:lI97|H3C1A50 +3C1A50:lI116|H3C1B04 +3C1B04:lI105|H3C1BC8 +3C1BC8:lI111|H3C1C8C +3C1C8C:lI110|H3C1D48 +3C1D48:lI47|H3C1E04 +3C1E04:lI120|H3C1EC0 +3C1EC0:lI45|H3C1F7C +3C1F7C:lI107|H3C2030 +3C2030:lI111|H3C20EC +3C20EC:lI97|H3C21A0 +3C21A0:lI110|N +3C1514:lI115|H3C15E8 +3C15E8:lI107|H3C16AC +3C16AC:lI100|N +3C144C:lH3C1524|H3C1530 +3C1524:t2:H3C15F8,H3C1600 +3C1600:lI97|H3C16C4 +3C16C4:lI112|H3C1780 +3C1780:lI112|H3C1834 +3C1834:lI108|H3C18F0 +3C18F0:lI105|H3C19A4 +3C19A4:lI99|H3C1A58 +3C1A58:lI97|H3C1B0C +3C1B0C:lI116|H3C1BD0 +3C1BD0:lI105|H3C1C94 +3C1C94:lI111|H3C1D50 +3C1D50:lI110|H3C1E0C +3C1E0C:lI47|H3C1EC8 +3C1EC8:lI120|H3C1F84 +3C1F84:lI45|H3C2038 +3C2038:lI107|H3C20F4 +3C20F4:lI111|H3C21A8 +3C21A8:lI97|H3C225C +3C225C:lI110|N +3C15F8:lI115|H3C16BC +3C16BC:lI107|H3C1778 +3C1778:lI116|N +3C1530:lH3C1608|H3C1614 +3C1608:t2:H3C16CC,H3C16D4 +3C16D4:lI97|H3C1790 +3C1790:lI112|H3C1844 +3C1844:lI112|H3C18F8 +3C18F8:lI108|H3C19AC +3C19AC:lI105|H3C1A60 +3C1A60:lI99|H3C1B14 +3C1B14:lI97|H3C1BD8 +3C1BD8:lI116|H3C1C9C +3C1C9C:lI105|H3C1D58 +3C1D58:lI111|H3C1E14 +3C1E14:lI110|H3C1ED0 +3C1ED0:lI47|H3C1F8C +3C1F8C:lI120|H3C2040 +3C2040:lI45|H3C20FC +3C20FC:lI107|H3C21B0 +3C21B0:lI111|H3C2264 +3C2264:lI97|H3C2320 +3C2320:lI110|N +3C16CC:lI115|H3C1788 +3C1788:lI107|H3C183C +3C183C:lI109|N +3C1614:lH3C16DC|H3C16E8 +3C16DC:t2:H3C1798,H3C17A0 +3C17A0:lI97|H3C1854 +3C1854:lI112|H3C1908 +3C1908:lI112|H3C19B4 +3C19B4:lI108|H3C1A68 +3C1A68:lI105|H3C1B1C +3C1B1C:lI99|H3C1BE0 +3C1BE0:lI97|H3C1CA4 +3C1CA4:lI116|H3C1D60 +3C1D60:lI105|H3C1E1C +3C1E1C:lI111|H3C1ED8 +3C1ED8:lI110|H3C1F94 +3C1F94:lI47|H3C2048 +3C2048:lI120|H3C2104 +3C2104:lI45|H3C21B8 +3C21B8:lI104|H3C226C +3C226C:lI116|H3C2328 +3C2328:lI116|H3C23E4 +3C23E4:lI112|H3C2498 +3C2498:lI100|H3C2554 +3C2554:lI45|H3C2610 +3C2610:lI99|H3C26D4 +3C26D4:lI103|H3C2790 +3C2790:lI105|N +3C1798:lI99|H3C184C +3C184C:lI103|H3C1900 +3C1900:lI105|N +3C16E8:lH3C17A8|H3C17B4 +3C17A8:t2:H3C185C,H3C1864 +3C1864:lI97|H3C1918 +3C1918:lI112|H3C19C4 +3C19C4:lI112|H3C1A70 +3C1A70:lI108|H3C1B24 +3C1B24:lI105|H3C1BE8 +3C1BE8:lI99|H3C1CAC +3C1CAC:lI97|H3C1D68 +3C1D68:lI116|H3C1E24 +3C1E24:lI105|H3C1EE0 +3C1EE0:lI111|H3C1F9C +3C1F9C:lI110|H3C2050 +3C2050:lI47|H3C210C +3C210C:lI120|H3C21C0 +3C21C0:lI45|H3C2274 +3C2274:lI104|H3C2330 +3C2330:lI100|H3C23EC +3C23EC:lI102|N +3C185C:lI104|H3C1910 +3C1910:lI100|H3C19BC +3C19BC:lI102|N +3C17B4:lH3C186C|H3C1878 +3C186C:t2:H3C1920,H3C1928 +3C1928:lI97|H3C19D4 +3C19D4:lI112|H3C1A78 +3C1A78:lI112|H3C1B2C +3C1B2C:lI108|H3C1BF0 +3C1BF0:lI105|H3C1CB4 +3C1CB4:lI99|H3C1D70 +3C1D70:lI97|H3C1E2C +3C1E2C:lI116|H3C1EE8 +3C1EE8:lI105|H3C1FA4 +3C1FA4:lI111|H3C2058 +3C2058:lI110|H3C2114 +3C2114:lI47|H3C21C8 +3C21C8:lI120|H3C227C +3C227C:lI45|H3C2338 +3C2338:lI103|H3C23F4 +3C23F4:lI122|H3C24A0 +3C24A0:lI105|H3C255C +3C255C:lI112|N +3C1920:lI103|H3C19CC +3C19CC:lI122|N +3C1878:lH3C1930|H3C193C +3C1930:t2:H3C19DC,H3C19E4 +3C19E4:lI97|H3C1A88 +3C1A88:lI112|H3C1B3C +3C1B3C:lI112|H3C1C00 +3C1C00:lI108|H3C1CBC +3C1CBC:lI105|H3C1D78 +3C1D78:lI99|H3C1E34 +3C1E34:lI97|H3C1EF0 +3C1EF0:lI116|H3C1FAC +3C1FAC:lI105|H3C2060 +3C2060:lI111|H3C211C +3C211C:lI110|H3C21D0 +3C21D0:lI47|H3C2284 +3C2284:lI120|H3C2340 +3C2340:lI45|H3C23FC +3C23FC:lI103|H3C24A8 +3C24A8:lI116|H3C2564 +3C2564:lI97|H3C2618 +3C2618:lI114|N +3C19DC:lI103|H3C1A80 +3C1A80:lI116|H3C1B34 +3C1B34:lI97|H3C1BF8 +3C1BF8:lI114|N +3C193C:lH3C19EC|H3C19F8 +3C19EC:t2:H3C1A90,H3C1A98 +3C1A98:lI97|H3C1B4C +3C1B4C:lI112|H3C1C10 +3C1C10:lI112|H3C1CC4 +3C1CC4:lI108|H3C1D80 +3C1D80:lI105|H3C1E3C +3C1E3C:lI99|H3C1EF8 +3C1EF8:lI97|H3C1FB4 +3C1FB4:lI116|H3C2068 +3C2068:lI105|H3C2124 +3C2124:lI111|H3C21D8 +3C21D8:lI110|H3C228C +3C228C:lI47|H3C2348 +3C2348:lI120|H3C2404 +3C2404:lI45|H3C24B0 +3C24B0:lI100|H3C256C +3C256C:lI118|H3C2620 +3C2620:lI105|N +3C1A90:lI100|H3C1B44 +3C1B44:lI118|H3C1C08 +3C1C08:lI105|N +3C19F8:lH3C1AA0|H3C1AAC +3C1AA0:t2:H3C1B54,H3C1B5C +3C1B5C:lI97|H3C1C20 +3C1C20:lI112|H3C1CD4 +3C1CD4:lI112|H3C1D88 +3C1D88:lI108|H3C1E44 +3C1E44:lI105|H3C1F00 +3C1F00:lI99|H3C1FBC +3C1FBC:lI97|H3C2070 +3C2070:lI116|H3C212C +3C212C:lI105|H3C21E0 +3C21E0:lI111|H3C2294 +3C2294:lI110|H3C2350 +3C2350:lI47|H3C240C +3C240C:lI120|H3C24B8 +3C24B8:lI45|H3C2574 +3C2574:lI100|H3C2628 +3C2628:lI105|H3C26DC +3C26DC:lI114|H3C2798 +3C2798:lI101|H3C2854 +3C2854:lI99|H3C2918 +3C2918:lI116|H3C29E4 +3C29E4:lI111|H3C2AB0 +3C2AB0:lI114|N +3C1B54:lI100|H3C1C18 +3C1C18:lI99|H3C1CCC +3C1CCC:lI114|N +3C1AAC:lH3C1B64|H3C1B70 +3C1B64:t2:H3C1C28,H3C1C30 +3C1C30:lI97|H3C1CE4 +3C1CE4:lI112|H3C1D98 +3C1D98:lI112|H3C1E4C +3C1E4C:lI108|H3C1F08 +3C1F08:lI105|H3C1FC4 +3C1FC4:lI99|H3C2078 +3C2078:lI97|H3C2134 +3C2134:lI116|H3C21E8 +3C21E8:lI105|H3C229C +3C229C:lI111|H3C2358 +3C2358:lI110|H3C2414 +3C2414:lI47|H3C24C0 +3C24C0:lI120|H3C257C +3C257C:lI45|H3C2630 +3C2630:lI100|H3C26E4 +3C26E4:lI105|H3C27A0 +3C27A0:lI114|H3C285C +3C285C:lI101|H3C2920 +3C2920:lI99|H3C29EC +3C29EC:lI116|H3C2AB8 +3C2AB8:lI111|H3C2B84 +3C2B84:lI114|N +3C1C28:lI100|H3C1CDC +3C1CDC:lI105|H3C1D90 +3C1D90:lI114|N +3C1B70:lH3C1C38|H3C1C44 +3C1C38:t2:H3C1CEC,H3C1CF4 +3C1CF4:lI97|H3C1DA8 +3C1DA8:lI112|H3C1E5C +3C1E5C:lI112|H3C1F10 +3C1F10:lI108|H3C1FCC +3C1FCC:lI105|H3C2080 +3C2080:lI99|H3C213C +3C213C:lI97|H3C21F0 +3C21F0:lI116|H3C22A4 +3C22A4:lI105|H3C2360 +3C2360:lI111|H3C241C +3C241C:lI110|H3C24C8 +3C24C8:lI47|H3C2584 +3C2584:lI120|H3C2638 +3C2638:lI45|H3C26EC +3C26EC:lI100|H3C27A8 +3C27A8:lI105|H3C2864 +3C2864:lI114|H3C2928 +3C2928:lI101|H3C29F4 +3C29F4:lI99|H3C2AC0 +3C2AC0:lI116|H3C2B8C +3C2B8C:lI111|H3C2C48 +3C2C48:lI114|N +3C1CEC:lI100|H3C1DA0 +3C1DA0:lI120|H3C1E54 +3C1E54:lI114|N +3C1C44:lH3C1CFC|H3C1D08 +3C1CFC:t2:H3C1DB0,H3C1DB8 +3C1DB8:lI97|H3C1E6C +3C1E6C:lI112|H3C1F20 +3C1F20:lI112|H3C1FD4 +3C1FD4:lI108|H3C2088 +3C2088:lI105|H3C2144 +3C2144:lI99|H3C21F8 +3C21F8:lI97|H3C22AC +3C22AC:lI116|H3C2368 +3C2368:lI105|H3C2424 +3C2424:lI111|H3C24D0 +3C24D0:lI110|H3C258C +3C258C:lI47|H3C2640 +3C2640:lI120|H3C26F4 +3C26F4:lI45|H3C27B0 +3C27B0:lI99|H3C286C +3C286C:lI115|H3C2930 +3C2930:lI104|N +3C1DB0:lI99|H3C1E64 +3C1E64:lI115|H3C1F18 +3C1F18:lI104|N +3C1D08:lH3C1DC0|H3C1DCC +3C1DC0:t2:H3C1E74,H3C1E7C +3C1E7C:lI97|H3C1F30 +3C1F30:lI112|H3C1FE4 +3C1FE4:lI112|H3C2098 +3C2098:lI108|H3C214C +3C214C:lI105|H3C2200 +3C2200:lI99|H3C22B4 +3C22B4:lI97|H3C2370 +3C2370:lI116|H3C242C +3C242C:lI105|H3C24D8 +3C24D8:lI111|H3C2594 +3C2594:lI110|H3C2648 +3C2648:lI47|H3C26FC +3C26FC:lI120|H3C27B8 +3C27B8:lI45|H3C2874 +3C2874:lI99|H3C2938 +3C2938:lI112|H3C29FC +3C29FC:lI105|H3C2AC8 +3C2AC8:lI111|N +3C1E74:lI99|H3C1F28 +3C1F28:lI112|H3C1FDC +3C1FDC:lI105|H3C2090 +3C2090:lI111|N +3C1DCC:lH3C1E84|H3C1E90 +3C1E84:t2:H3C1F38,H3C1F40 +3C1F40:lI97|H3C1FEC +3C1FEC:lI112|H3C20A0 +3C20A0:lI112|H3C2154 +3C2154:lI108|H3C2208 +3C2208:lI105|H3C22BC +3C22BC:lI99|H3C2378 +3C2378:lI97|H3C2434 +3C2434:lI116|H3C24E0 +3C24E0:lI105|H3C259C +3C259C:lI111|H3C2650 +3C2650:lI110|H3C2704 +3C2704:lI47|H3C27C0 +3C27C0:lI120|H3C287C +3C287C:lI45|H3C2940 +3C2940:lI99|H3C2A04 +3C2A04:lI111|H3C2AD0 +3C2AD0:lI109|H3C2B94 +3C2B94:lI112|H3C2C50 +3C2C50:lI114|H3C2D00 +3C2D00:lI101|H3C2DA8 +3C2DA8:lI115|H3C2E40 +3C2E40:lI115|N +3C1F38:lI90|N +3C1E90:lH3C1F48|H3C1F54 +3C1F48:t2:H3C1FF4,H3C1FFC +3C1FFC:lI97|H3C20B0 +3C20B0:lI112|H3C2164 +3C2164:lI112|H3C2210 +3C2210:lI108|H3C22C4 +3C22C4:lI105|H3C2380 +3C2380:lI99|H3C243C +3C243C:lI97|H3C24E8 +3C24E8:lI116|H3C25A4 +3C25A4:lI105|H3C2658 +3C2658:lI111|H3C270C +3C270C:lI110|H3C27C8 +3C27C8:lI47|H3C2884 +3C2884:lI120|H3C2948 +3C2948:lI45|H3C2A0C +3C2A0C:lI99|H3C2AD8 +3C2AD8:lI100|H3C2B9C +3C2B9C:lI108|H3C2C58 +3C2C58:lI105|H3C2D08 +3C2D08:lI110|H3C2DB0 +3C2DB0:lI107|N +3C1FF4:lI118|H3C20A8 +3C20A8:lI99|H3C215C +3C215C:lI100|N +3C1F54:lH3C2004|H3C2010 +3C2004:t2:H3C20B8,H3C20C0 +3C20C0:lI97|H3C2174 +3C2174:lI112|H3C2220 +3C2220:lI112|H3C22D4 +3C22D4:lI108|H3C2390 +3C2390:lI105|H3C2444 +3C2444:lI99|H3C24F0 +3C24F0:lI97|H3C25AC +3C25AC:lI116|H3C2660 +3C2660:lI105|H3C2714 +3C2714:lI111|H3C27D0 +3C27D0:lI110|H3C288C +3C288C:lI47|H3C2950 +3C2950:lI120|H3C2A14 +3C2A14:lI45|H3C2AE0 +3C2AE0:lI98|H3C2BA4 +3C2BA4:lI99|H3C2C60 +3C2C60:lI112|H3C2D10 +3C2D10:lI105|H3C2DB8 +3C2DB8:lI111|N +3C20B8:lI98|H3C216C +3C216C:lI99|H3C2218 +3C2218:lI112|H3C22CC +3C22CC:lI105|H3C2388 +3C2388:lI111|N +3C2010:lH3C20C8|H3C20D4 +3C20C8:t2:H3C217C,H3C2184 +3C2184:lI97|H3C2230 +3C2230:lI112|H3C22E4 +3C22E4:lI112|H3C2398 +3C2398:lI108|H3C244C +3C244C:lI105|H3C24F8 +3C24F8:lI99|H3C25B4 +3C25B4:lI97|H3C2668 +3C2668:lI116|H3C271C +3C271C:lI105|H3C27D8 +3C27D8:lI111|H3C2894 +3C2894:lI110|H3C2958 +3C2958:lI47|H3C2A1C +3C2A1C:lI114|H3C2AE8 +3C2AE8:lI116|H3C2BAC +3C2BAC:lI102|N +3C217C:lI114|H3C2228 +3C2228:lI116|H3C22DC +3C22DC:lI102|N +3C20D4:lH3C218C|H3C2198 +3C218C:t2:H3C2238,H3C2240 +3C2240:lI97|H3C22F4 +3C22F4:lI112|H3C23A8 +3C23A8:lI112|H3C2454 +3C2454:lI108|H3C2500 +3C2500:lI105|H3C25BC +3C25BC:lI99|H3C2670 +3C2670:lI97|H3C2724 +3C2724:lI116|H3C27E0 +3C27E0:lI105|H3C289C +3C289C:lI111|H3C2960 +3C2960:lI110|H3C2A24 +3C2A24:lI47|H3C2AF0 +3C2AF0:lI112|H3C2BB4 +3C2BB4:lI111|H3C2C68 +3C2C68:lI119|H3C2D18 +3C2D18:lI101|H3C2DC0 +3C2DC0:lI114|H3C2E48 +3C2E48:lI112|H3C2EC0 +3C2EC0:lI111|H3C2F38 +3C2F38:lI105|H3C2FA8 +3C2FA8:lI110|H3C3010 +3C3010:lI116|N +3C2238:lI112|H3C22EC +3C22EC:lI112|H3C23A0 +3C23A0:lI116|N +3C2198:lH3C2248|H3C2254 +3C2248:t2:H3C22FC,H3C2304 +3C2304:lI97|H3C23B8 +3C23B8:lI112|H3C245C +3C245C:lI112|H3C2508 +3C2508:lI108|H3C25C4 +3C25C4:lI105|H3C2678 +3C2678:lI99|H3C272C +3C272C:lI97|H3C27E8 +3C27E8:lI116|H3C28A4 +3C28A4:lI105|H3C2968 +3C2968:lI111|H3C2A2C +3C2A2C:lI110|H3C2AF8 +3C2AF8:lI47|H3C2BBC +3C2BBC:lI112|H3C2C70 +3C2C70:lI111|H3C2D20 +3C2D20:lI115|H3C2DC8 +3C2DC8:lI116|H3C2E50 +3C2E50:lI115|H3C2EC8 +3C2EC8:lI99|H3C2F40 +3C2F40:lI114|H3C2FB0 +3C2FB0:lI105|H3C3018 +3C3018:lI112|H3C3078 +3C3078:lI116|N +3C22FC:lI97|H3C23B0 +3C23B0:lI105|N +3C2254:lH3C230C|H3C2318 +3C230C:t2:H3C23C0,H3C23C8 +3C23C8:lI97|H3C246C +3C246C:lI112|H3C2518 +3C2518:lI112|H3C25CC +3C25CC:lI108|H3C2680 +3C2680:lI105|H3C2734 +3C2734:lI99|H3C27F0 +3C27F0:lI97|H3C28AC +3C28AC:lI116|H3C2970 +3C2970:lI105|H3C2A34 +3C2A34:lI111|H3C2B00 +3C2B00:lI110|H3C2BC4 +3C2BC4:lI47|H3C2C78 +3C2C78:lI112|H3C2D28 +3C2D28:lI111|H3C2DD0 +3C2DD0:lI115|H3C2E58 +3C2E58:lI116|H3C2ED0 +3C2ED0:lI115|H3C2F48 +3C2F48:lI99|H3C2FB8 +3C2FB8:lI114|H3C3020 +3C3020:lI105|H3C3080 +3C3080:lI112|H3C30D8 +3C30D8:lI116|N +3C23C0:lI101|H3C2464 +3C2464:lI112|H3C2510 +3C2510:lI115|N +3C2318:lH3C23D0|H3C23DC +3C23D0:t2:H3C2474,H3C247C +3C247C:lI97|H3C2528 +3C2528:lI112|H3C25D4 +3C25D4:lI112|H3C2688 +3C2688:lI108|H3C273C +3C273C:lI105|H3C27F8 +3C27F8:lI99|H3C28B4 +3C28B4:lI97|H3C2978 +3C2978:lI116|H3C2A3C +3C2A3C:lI105|H3C2B08 +3C2B08:lI111|H3C2BCC +3C2BCC:lI110|H3C2C80 +3C2C80:lI47|H3C2D30 +3C2D30:lI112|H3C2DD8 +3C2DD8:lI111|H3C2E60 +3C2E60:lI115|H3C2ED8 +3C2ED8:lI116|H3C2F50 +3C2F50:lI115|H3C2FC0 +3C2FC0:lI99|H3C3028 +3C3028:lI114|H3C3088 +3C3088:lI105|H3C30E0 +3C30E0:lI112|H3C3130 +3C3130:lI116|N +3C2474:lI112|H3C2520 +3C2520:lI115|N +3C23DC:lH3C2484|H3C2490 +3C2484:t2:H3C2530,H3C2538 +3C2538:lI97|H3C25E4 +3C25E4:lI112|H3C2698 +3C2698:lI112|H3C2744 +3C2744:lI108|H3C2800 +3C2800:lI105|H3C28BC +3C28BC:lI99|H3C2980 +3C2980:lI97|H3C2A44 +3C2A44:lI116|H3C2B10 +3C2B10:lI105|H3C2BD4 +3C2BD4:lI111|H3C2C88 +3C2C88:lI110|H3C2D38 +3C2D38:lI47|H3C2DE0 +3C2DE0:lI112|H3C2E68 +3C2E68:lI100|H3C2EE0 +3C2EE0:lI102|N +3C2530:lI112|H3C25DC +3C25DC:lI100|H3C2690 +3C2690:lI102|N +3C2490:lH3C2540|H3C254C +3C2540:t2:H3C25EC,H3C25F4 +3C25F4:lI97|H3C26A8 +3C26A8:lI112|H3C2754 +3C2754:lI112|H3C2808 +3C2808:lI108|H3C28C4 +3C28C4:lI105|H3C2988 +3C2988:lI99|H3C2A4C +3C2A4C:lI97|H3C2B18 +3C2B18:lI116|H3C2BDC +3C2BDC:lI105|H3C2C90 +3C2C90:lI111|H3C2D40 +3C2D40:lI110|H3C2DE8 +3C2DE8:lI47|H3C2E70 +3C2E70:lI111|H3C2EE8 +3C2EE8:lI100|H3C2F58 +3C2F58:lI97|N +3C25EC:lI111|H3C26A0 +3C26A0:lI100|H3C274C +3C274C:lI97|N +3C254C:lH3C25FC|H3C2608 +3C25FC:t2:H3C26B0,H3C26B8 +3C26B8:lI97|H3C2764 +3C2764:lI112|H3C2818 +3C2818:lI112|H3C28CC +3C28CC:lI108|H3C2990 +3C2990:lI105|H3C2A54 +3C2A54:lI99|H3C2B20 +3C2B20:lI97|H3C2BE4 +3C2BE4:lI116|H3C2C98 +3C2C98:lI105|H3C2D48 +3C2D48:lI111|H3C2DF0 +3C2DF0:lI110|H3C2E78 +3C2E78:lI47|H3C2EF0 +3C2EF0:lI111|H3C2F60 +3C2F60:lI99|H3C2FC8 +3C2FC8:lI116|H3C3030 +3C3030:lI101|H3C3090 +3C3090:lI116|H3C30E8 +3C30E8:lI45|H3C3138 +3C3138:lI115|H3C3180 +3C3180:lI116|H3C31C8 +3C31C8:lI114|H3C3210 +3C3210:lI101|H3C3258 +3C3258:lI97|H3C32A0 +3C32A0:lI109|N +3C26B0:lI98|H3C275C +3C275C:lI105|H3C2810 +3C2810:lI110|N +3C2608:lH3C26C0|H3C26CC +3C26C0:t2:H3C276C,H3C2774 +3C2774:lI97|H3C2828 +3C2828:lI112|H3C28DC +3C28DC:lI112|H3C2998 +3C2998:lI108|H3C2A5C +3C2A5C:lI105|H3C2B28 +3C2B28:lI99|H3C2BEC +3C2BEC:lI97|H3C2CA0 +3C2CA0:lI116|H3C2D50 +3C2D50:lI105|H3C2DF8 +3C2DF8:lI111|H3C2E80 +3C2E80:lI110|H3C2EF8 +3C2EF8:lI47|H3C2F68 +3C2F68:lI111|H3C2FD0 +3C2FD0:lI99|H3C3038 +3C3038:lI116|H3C3098 +3C3098:lI101|H3C30F0 +3C30F0:lI116|H3C3140 +3C3140:lI45|H3C3188 +3C3188:lI115|H3C31D0 +3C31D0:lI116|H3C3218 +3C3218:lI114|H3C3260 +3C3260:lI101|H3C32A8 +3C32A8:lI97|H3C32E8 +3C32E8:lI109|N +3C276C:lI100|H3C2820 +3C2820:lI109|H3C28D4 +3C28D4:lI115|N +3C26CC:lH3C277C|H3C2788 +3C277C:t2:H3C2830,H3C2838 +3C2838:lI97|H3C28EC +3C28EC:lI112|H3C29A8 +3C29A8:lI112|H3C2A64 +3C2A64:lI108|H3C2B30 +3C2B30:lI105|H3C2BF4 +3C2BF4:lI99|H3C2CA8 +3C2CA8:lI97|H3C2D58 +3C2D58:lI116|H3C2E00 +3C2E00:lI105|H3C2E88 +3C2E88:lI111|H3C2F00 +3C2F00:lI110|H3C2F70 +3C2F70:lI47|H3C2FD8 +3C2FD8:lI111|H3C3040 +3C3040:lI99|H3C30A0 +3C30A0:lI116|H3C30F8 +3C30F8:lI101|H3C3148 +3C3148:lI116|H3C3190 +3C3190:lI45|H3C31D8 +3C31D8:lI115|H3C3220 +3C3220:lI116|H3C3268 +3C3268:lI114|H3C32B0 +3C32B0:lI101|H3C32F0 +3C32F0:lI97|H3C3320 +3C3320:lI109|N +3C2830:lI108|H3C28E4 +3C28E4:lI104|H3C29A0 +3C29A0:lI97|N +3C2788:lH3C2840|H3C284C +3C2840:t2:H3C28F4,H3C28FC +3C28FC:lI97|H3C29B8 +3C29B8:lI112|H3C2A74 +3C2A74:lI112|H3C2B38 +3C2B38:lI108|H3C2BFC +3C2BFC:lI105|H3C2CB0 +3C2CB0:lI99|H3C2D60 +3C2D60:lI97|H3C2E08 +3C2E08:lI116|H3C2E90 +3C2E90:lI105|H3C2F08 +3C2F08:lI111|H3C2F78 +3C2F78:lI110|H3C2FE0 +3C2FE0:lI47|H3C3048 +3C3048:lI111|H3C30A8 +3C30A8:lI99|H3C3100 +3C3100:lI116|H3C3150 +3C3150:lI101|H3C3198 +3C3198:lI116|H3C31E0 +3C31E0:lI45|H3C3228 +3C3228:lI115|H3C3270 +3C3270:lI116|H3C32B8 +3C32B8:lI114|H3C32F8 +3C32F8:lI101|H3C3328 +3C3328:lI97|H3C3350 +3C3350:lI109|N +3C28F4:lI108|H3C29B0 +3C29B0:lI122|H3C2A6C +3C2A6C:lI104|N +3C284C:lH3C2904|H3C2910 +3C2904:t2:H3C29C0,H3C29C8 +3C29C8:lI97|H3C2A84 +3C2A84:lI112|H3C2B48 +3C2B48:lI112|H3C2C04 +3C2C04:lI108|H3C2CB8 +3C2CB8:lI105|H3C2D68 +3C2D68:lI99|H3C2E10 +3C2E10:lI97|H3C2E98 +3C2E98:lI116|H3C2F10 +3C2F10:lI105|H3C2F80 +3C2F80:lI111|H3C2FE8 +3C2FE8:lI110|H3C3050 +3C3050:lI47|H3C30B0 +3C30B0:lI111|H3C3108 +3C3108:lI99|H3C3158 +3C3158:lI116|H3C31A0 +3C31A0:lI101|H3C31E8 +3C31E8:lI116|H3C3230 +3C3230:lI45|H3C3278 +3C3278:lI115|H3C32C0 +3C32C0:lI116|H3C3300 +3C3300:lI114|H3C3330 +3C3330:lI101|H3C3358 +3C3358:lI97|H3C3378 +3C3378:lI109|N +3C29C0:lI101|H3C2A7C +3C2A7C:lI120|H3C2B40 +3C2B40:lI101|N +3C2910:lH3C29D0|H3C29DC +3C29D0:t2:H3C2A8C,H3C2A94 +3C2A94:lI97|H3C2B58 +3C2B58:lI112|H3C2C14 +3C2C14:lI112|H3C2CC8 +3C2CC8:lI108|H3C2D78 +3C2D78:lI105|H3C2E18 +3C2E18:lI99|H3C2EA0 +3C2EA0:lI97|H3C2F18 +3C2F18:lI116|H3C2F88 +3C2F88:lI105|H3C2FF0 +3C2FF0:lI111|H3C3058 +3C3058:lI110|H3C30B8 +3C30B8:lI47|H3C3110 +3C3110:lI111|H3C3160 +3C3160:lI99|H3C31A8 +3C31A8:lI116|H3C31F0 +3C31F0:lI101|H3C3238 +3C3238:lI116|H3C3280 +3C3280:lI45|H3C32C8 +3C32C8:lI115|H3C3308 +3C3308:lI116|H3C3338 +3C3338:lI114|H3C3360 +3C3360:lI101|H3C3380 +3C3380:lI97|H3C3398 +3C3398:lI109|N +3C2A8C:lI99|H3C2B50 +3C2B50:lI108|H3C2C0C +3C2C0C:lI97|H3C2CC0 +3C2CC0:lI115|H3C2D70 +3C2D70:lI115|N +3C29DC:lH3C2A9C|H3C2AA8 +3C2A9C:t2:H3C2B60,H3C2B68 +3C2B68:lI97|H3C2C24 +3C2C24:lI112|H3C2CD8 +3C2CD8:lI112|H3C2D80 +3C2D80:lI108|H3C2E20 +3C2E20:lI105|H3C2EA8 +3C2EA8:lI99|H3C2F20 +3C2F20:lI97|H3C2F90 +3C2F90:lI116|H3C2FF8 +3C2FF8:lI105|H3C3060 +3C3060:lI111|H3C30C0 +3C30C0:lI110|H3C3118 +3C3118:lI47|H3C3168 +3C3168:lI109|H3C31B0 +3C31B0:lI115|H3C31F8 +3C31F8:lI119|H3C3240 +3C3240:lI111|H3C3288 +3C3288:lI114|H3C32D0 +3C32D0:lI100|N +3C2B60:lI100|H3C2C1C +3C2C1C:lI111|H3C2CD0 +3C2CD0:lI99|N +3C2AA8:lH3C2B70|H3C2B7C +3C2B70:t2:H3C2C2C,H3C2C34 +3C2C34:lI97|H3C2CE8 +3C2CE8:lI112|H3C2D90 +3C2D90:lI112|H3C2E28 +3C2E28:lI108|H3C2EB0 +3C2EB0:lI105|H3C2F28 +3C2F28:lI99|H3C2F98 +3C2F98:lI97|H3C3000 +3C3000:lI116|H3C3068 +3C3068:lI105|H3C30C8 +3C30C8:lI111|H3C3120 +3C3120:lI110|H3C3170 +3C3170:lI47|H3C31B8 +3C31B8:lI109|H3C3200 +3C3200:lI97|H3C3248 +3C3248:lI99|H3C3290 +3C3290:lI45|H3C32D8 +3C32D8:lI99|H3C3310 +3C3310:lI111|H3C3340 +3C3340:lI109|H3C3368 +3C3368:lI112|H3C3388 +3C3388:lI97|H3C33A0 +3C33A0:lI99|H3C33B0 +3C33B0:lI116|H3C33C0 +3C33C0:lI112|H3C33D0 +3C33D0:lI114|H3C33E0 +3C33E0:lI111|N +3C2C2C:lI99|H3C2CE0 +3C2CE0:lI112|H3C2D88 +3C2D88:lI116|N +3C2B7C:lH3C2C3C|N +3C2C3C:t2:H3C2CF0,H3C2CF8 +3C2CF8:lI97|H3C2DA0 +3C2DA0:lI112|H3C2E38 +3C2E38:lI112|H3C2EB8 +3C2EB8:lI108|H3C2F30 +3C2F30:lI105|H3C2FA0 +3C2FA0:lI99|H3C3008 +3C3008:lI97|H3C3070 +3C3070:lI116|H3C30D0 +3C30D0:lI105|H3C3128 +3C3128:lI111|H3C3178 +3C3178:lI110|H3C31C0 +3C31C0:lI47|H3C3208 +3C3208:lI109|H3C3250 +3C3250:lI97|H3C3298 +3C3298:lI99|H3C32E0 +3C32E0:lI45|H3C3318 +3C3318:lI98|H3C3348 +3C3348:lI105|H3C3370 +3C3370:lI110|H3C3390 +3C3390:lI104|H3C33A8 +3C33A8:lI101|H3C33B8 +3C33B8:lI120|H3C33C8 +3C33C8:lI52|H3C33D8 +3C33D8:lI48|N +3C2CF0:lI104|H3C2D98 +3C2D98:lI113|H3C2E30 +3C2E30:lI120|N +3BDBCC:lH3BDA78|H3BDA8C +3BDA78:t2:A4:port,I8888 +3BDA8C:lH3BDB04|H3BDB10 +3BDB04:t2:AC:bind_address,H3BDB64 +3BDB64:t4:I127,I0,I0,I1 +3BDB10:lH3BDB78|H3BDB84 +3BDB78:t2:AB:server_name,H3BDBD4 +3BDBD4:lI108|H3BDC24 +3BDC24:lI111|H3BDC88 +3BDC88:lI99|H3BDCF0 +3BDCF0:lI97|H3BDD70 +3BDD70:lI108|H3BDDF8 +3BDDF8:lI104|H3BDE90 +3BDE90:lI111|H3BDF40 +3BDF40:lI115|H3BDFFC +3BDFFC:lI116|N +3BDB84:lH3BDBDC|H3BDBE8 +3BDBDC:t2:AE:max_header_siz,I1024 +3BDBE8:lH3BDC2C|H3BDC38 +3BDC2C:t2:A11:max_header_action,A8:reply414 +3BDC38:lH3BDC90|H3BDC9C +3BDC90:t2:A8:com_type,A7:ip_comm +3BDC9C:lH3BDCF8|H3BDD04 +3BDCF8:t2:A7:modules,H3BDD78 +3BDD78:lA9:mod_alias|H3BDE00 +3BDE00:lA8:mod_auth|H3BDE98 +3BDE98:lA7:mod_esi|H3BDF48 +3BDF48:lAB:mod_actions|H3BE004 +3BE004:lA7:mod_cgi|H3BE0D0 +3BE0D0:lAB:mod_include|H3BE1A4 +3BE1A4:lA7:mod_dir|H3BE288 +3BE288:lA7:mod_get|H3BE378 +3BE378:lA8:mod_head|H3BE47C +3BE47C:lA7:mod_log|H3BE580 +3BE580:lAC:mod_disk_log|N +3BDD04:lH3BDD80|H3BDD8C +3BDD80:t2:AF:directory_index,H3BDE08 +3BDE08:lH3BDEA0|N +3BDEA0:lI105|H3BDF50 +3BDF50:lI110|H3BE00C +3BE00C:lI100|H3BE0D8 +3BE0D8:lI101|H3BE1AC +3BE1AC:lI120|H3BE290 +3BE290:lI46|H3BE380 +3BE380:lI104|H3BE484 +3BE484:lI116|H3BE588 +3BE588:lI109|H3BE68C +3BE68C:lI108|N +3BDD8C:lH3BDE10|H3BDE1C +3BDE10:t2:AC:default_type,H3BDEA8 +3BDEA8:lI116|H3BDF58 +3BDF58:lI101|H3BE014 +3BE014:lI120|H3BE0E0 +3BE0E0:lI116|H3BE1B4 +3BE1B4:lI47|H3BE298 +3BE298:lI112|H3BE388 +3BE388:lI108|H3BE48C +3BE48C:lI97|H3BE590 +3BE590:lI105|H3BE694 +3BE694:lI110|N +3BDE1C:lH3BDEB0|H3BDEBC +3BDEB0:t2:A10:erl_script_alias,H3BDF60 +3BDF60:t2:H3BE01C,H3BE024 +3BE024:lH3BE0F0|N +3BE0F0:lI119|H3BE1C4 +3BE1C4:lI101|H3BE2A8 +3BE2A8:lI98|H3BE398 +3BE398:lI116|H3BE49C +3BE49C:lI111|H3BE5A0 +3BE5A0:lI111|H3BE6A4 +3BE6A4:lI108|N +3BE01C:lI47|H3BE0E8 +3BE0E8:lI119|H3BE1BC +3BE1BC:lI101|H3BE2A0 +3BE2A0:lI98|H3BE390 +3BE390:lI116|H3BE494 +3BE494:lI111|H3BE598 +3BE598:lI111|H3BE69C +3BE69C:lI108|N +3BDEBC:lH3BDF6C|H3BDF78 +3BDF6C:t2:A5:alias,H3BE02C +3BE02C:t2:H3BE0F8,H3BE100 +3BE100:lI47|H3BE1D4 +3BE1D4:lI99|H3BE2B8 +3BE2B8:lI108|H3BE3A8 +3BE3A8:lI101|H3BE4AC +3BE4AC:lI97|H3BE5B0 +3BE5B0:lI114|H3BE6B4 +3BE6B4:lI99|H3BE7A8 +3BE7A8:lI97|H3BE894 +3BE894:lI115|H3BE980 +3BE980:lI101|H3BEA74 +3BEA74:lI47|H3BEB68 +3BEB68:lI111|H3BEC54 +3BEC54:lI116|H3BED40 +3BED40:lI112|H3BEE2C +3BEE2C:lI47|H3BEF00 +3BEF00:lI101|H3BEFD4 +3BEFD4:lI114|H3BF0A0 +3BF0A0:lI116|H3BF174 +3BF174:lI115|H3BF238 +3BF238:lI47|H3BF2FC +3BF2FC:lI108|H3BF3A8 +3BF3A8:lI105|H3BF45C +3BF45C:lI98|H3BF518 +3BF518:lI47|H3BF5DC +3BF5DC:lI111|H3BF6B0 +3BF6B0:lI98|H3BF784 +3BF784:lI115|H3BF858 +3BF858:lI101|H3BF93C +3BF93C:lI114|H3BFA18 +3BFA18:lI118|H3BFAF4 +3BFAF4:lI101|H3BFBD0 +3BFBD0:lI114|H3BFC9C +3BFC9C:lI47|H3BFD60 +3BFD60:lI112|H3BFE2C +3BFE2C:lI114|H3BFEE0 +3BFEE0:lI105|H3BFF94 +3BFF94:lI118|H3C0040 +3C0040:lI47|H3C00EC +3C00EC:lI99|H3C0198 +3C0198:lI114|H3C024C +3C024C:lI97|H3C0308 +3C0308:lI115|H3C03BC +3C03BC:lI104|H3C0458 +3C0458:lI100|H3C04F4 +3C04F4:lI117|H3C0590 +3C0590:lI109|H3C0634 +3C0634:lI112|H3C06E0 +3C06E0:lI95|H3C078C +3C078C:lI118|H3C0830 +3C0830:lI105|H3C08BC +3C08BC:lI101|H3C0950 +3C0950:lI119|H3C09E4 +3C09E4:lI101|H3C0A80 +3C0A80:lI114|N +3BE0F8:lI47|H3BE1CC +3BE1CC:lI99|H3BE2B0 +3BE2B0:lI114|H3BE3A0 +3BE3A0:lI97|H3BE4A4 +3BE4A4:lI115|H3BE5A8 +3BE5A8:lI104|H3BE6AC +3BE6AC:lI100|H3BE7A0 +3BE7A0:lI117|H3BE88C +3BE88C:lI109|H3BE978 +3BE978:lI112|H3BEA6C +3BEA6C:lI95|H3BEB60 +3BEB60:lI118|H3BEC4C +3BEC4C:lI105|H3BED38 +3BED38:lI101|H3BEE24 +3BEE24:lI119|H3BEEF8 +3BEEF8:lI101|H3BEFCC +3BEFCC:lI114|N +3BDF78:lH3BE038|H3BE044 +3BE038:t2:A5:alias,H3BE108 +3BE108:t2:H3BE1DC,H3BE1E4 +3BE1E4:lI47|H3BE2C8 +3BE2C8:lI99|H3BE3B8 +3BE3B8:lI108|H3BE4BC +3BE4BC:lI101|H3BE5C0 +3BE5C0:lI97|H3BE6C4 +3BE6C4:lI114|H3BE7B8 +3BE7B8:lI99|H3BE8A4 +3BE8A4:lI97|H3BE990 +3BE990:lI115|H3BEA84 +3BEA84:lI101|H3BEB78 +3BEB78:lI47|H3BEC64 +3BEC64:lI111|H3BED50 +3BED50:lI116|H3BEE3C +3BEE3C:lI112|H3BEF10 +3BEF10:lI47|H3BEFE4 +3BEFE4:lI101|H3BF0B0 +3BF0B0:lI114|H3BF184 +3BF184:lI116|H3BF248 +3BF248:lI115|H3BF304 +3BF304:lI47|H3BF3B0 +3BF3B0:lI101|H3BF464 +3BF464:lI114|H3BF520 +3BF520:lI116|H3BF5E4 +3BF5E4:lI115|H3BF6B8 +3BF6B8:lI47|H3BF78C +3BF78C:lI100|H3BF860 +3BF860:lI111|H3BF944 +3BF944:lI99|H3BFA20 +3BFA20:lI47|H3BFAFC +3BFAFC:lI104|H3BFBD8 +3BFBD8:lI116|H3BFCA4 +3BFCA4:lI109|H3BFD68 +3BFD68:lI108|N +3BE1DC:lI47|H3BE2C0 +3BE2C0:lI99|H3BE3B0 +3BE3B0:lI114|H3BE4B4 +3BE4B4:lI97|H3BE5B8 +3BE5B8:lI115|H3BE6BC +3BE6BC:lI104|H3BE7B0 +3BE7B0:lI100|H3BE89C +3BE89C:lI117|H3BE988 +3BE988:lI109|H3BEA7C +3BEA7C:lI112|H3BEB70 +3BEB70:lI95|H3BEC5C +3BEC5C:lI101|H3BED48 +3BED48:lI114|H3BEE34 +3BEE34:lI116|H3BEF08 +3BEF08:lI115|H3BEFDC +3BEFDC:lI95|H3BF0A8 +3BF0A8:lI100|H3BF17C +3BF17C:lI111|H3BF240 +3BF240:lI99|N +3BE044:lH3BE114|H3BE120 +3BE114:t2:A5:alias,H3BE1EC +3BE1EC:t2:H3BE2D0,H3BE2D8 +3BE2D8:lI47|H3BE3C8 +3BE3C8:lI99|H3BE4CC +3BE4CC:lI108|H3BE5D0 +3BE5D0:lI101|H3BE6D4 +3BE6D4:lI97|H3BE7C8 +3BE7C8:lI114|H3BE8B4 +3BE8B4:lI99|H3BE9A0 +3BE9A0:lI97|H3BEA94 +3BEA94:lI115|H3BEB88 +3BEB88:lI101|H3BEC74 +3BEC74:lI47|H3BED60 +3BED60:lI111|H3BEE4C +3BEE4C:lI116|H3BEF20 +3BEF20:lI112|H3BEFEC +3BEFEC:lI47|H3BF0B8 +3BF0B8:lI101|H3BF18C +3BF18C:lI114|H3BF250 +3BF250:lI116|H3BF30C +3BF30C:lI115|H3BF3B8 +3BF3B8:lI47|H3BF46C +3BF46C:lI108|H3BF528 +3BF528:lI105|H3BF5EC +3BF5EC:lI98|H3BF6C0 +3BF6C0:lI47|H3BF794 +3BF794:lI111|H3BF868 +3BF868:lI98|H3BF94C +3BF94C:lI115|H3BFA28 +3BFA28:lI101|H3BFB04 +3BFB04:lI114|H3BFBE0 +3BFBE0:lI118|H3BFCAC +3BFCAC:lI101|H3BFD70 +3BFD70:lI114|H3BFE34 +3BFE34:lI47|H3BFEE8 +3BFEE8:lI100|H3BFF9C +3BFF9C:lI111|H3C0048 +3C0048:lI99|H3C00F4 +3C00F4:lI47|H3C01A0 +3C01A0:lI104|H3C0254 +3C0254:lI116|H3C0310 +3C0310:lI109|H3C03C4 +3C03C4:lI108|N +3BE2D0:lI47|H3BE3C0 +3BE3C0:lI99|H3BE4C4 +3BE4C4:lI114|H3BE5C8 +3BE5C8:lI97|H3BE6CC +3BE6CC:lI115|H3BE7C0 +3BE7C0:lI104|H3BE8AC +3BE8AC:lI100|H3BE998 +3BE998:lI117|H3BEA8C +3BEA8C:lI109|H3BEB80 +3BEB80:lI112|H3BEC6C +3BEC6C:lI95|H3BED58 +3BED58:lI100|H3BEE44 +3BEE44:lI111|H3BEF18 +3BEF18:lI99|N +3BE120:lH3BE1F8|N +3BE1F8:t2:A10:erl_script_alias,H3BE2E0 +3BE2E0:t2:H3BE3D0,H3BE3D8 +3BE3D8:lH3BE4DC|N +3BE4DC:lI99|H3BE5E0 +3BE5E0:lI114|H3BE6E4 +3BE6E4:lI97|H3BE7D8 +3BE7D8:lI115|H3BE8C4 +3BE8C4:lI104|H3BE9B0 +3BE9B0:lI100|H3BEAA4 +3BEAA4:lI117|H3BEB90 +3BEB90:lI109|H3BEC7C +3BEC7C:lI112|H3BED68 +3BED68:lI95|H3BEE54 +3BEE54:lI118|H3BEF28 +3BEF28:lI105|H3BEFF4 +3BEFF4:lI101|H3BF0C0 +3BF0C0:lI119|H3BF194 +3BF194:lI101|H3BF258 +3BF258:lI114|N +3BE3D0:lI47|H3BE4D4 +3BE4D4:lI99|H3BE5D8 +3BE5D8:lI100|H3BE6DC +3BE6DC:lI118|H3BE7D0 +3BE7D0:lI95|H3BE8BC +3BE8BC:lI101|H3BE9A8 +3BE9A8:lI114|H3BEA9C +3BEA9C:lI108|N +3BDE2C:lH3BDA9C|H3BDECC +3BDA9C:t4:I127,I0,I0,I1 +3BDECC:lI8888|H3BDF88 +3BDF88:lN|N +3BDD1C:lN|N +3BDA50:t2:AD:$initial_call,H3BDAB8 +3BDAB8:t3:A3:gen,A7:init_it,H3BDAB0 +3BDA5C:t2:A9:verbosity,A7:silence +3BDAC8:t2:AE:auth_verbosity,A7:silence +3BDB28:t2:A12:security_verbosity,A7:silence +3BDB9C:t2:A12:acceptor_verbosity,A7:silence +3BDC00:t2:AA:$ancestors,H3BDC5C +3BDC5C:lA1A:httpd_sup__127_0_0_1__8888|H3BDCB4 +3BDCB4:lA8:web_tool|H3BDD24 +3BDD24:lP<0.27.0>|N +3BDADC:t2:A19:request_handler_verbosity,A7:silence +3BDB3C:t2:A5:sname,A3:man +=proc_dictionary:<0.47.0> +H36E688 +H36E694 +H36E6A0 +H36E6AC +=proc_stack:<0.47.0> +36c520:SReturn addr 0x362C9C (inet_tcp:accept/2 + 20) +y0:I5 +y1:p<0.161> +y2:p<0.141> +36c530:SReturn addr 0x500C5C (httpd_socket:accept/3 + 280) +y0:N +36c538:SReturn addr 0x502BFC (httpd_acceptor:acceptor/4 + 164) +y0:N +36c540:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:SCatch 0x502BFC (httpd_acceptor:acceptor/4 + 164) +y1:P<0.46.0> +y2:A7:ip_comm +y3:p<0.141> +y4:A1B:httpd_conf__127_0_0_1__8888 +36c558:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:AE:httpd_acceptor +y2:A8:acceptor +y3:H36E6C8 +=proc_heap:<0.47.0> +36E6C8:lP<0.44.0>|H36E724 +36E724:lP<0.46.0>|H36E748 +36E748:lA7:ip_comm|H36E760 +36E760:lH36E6D0|H36E778 +36E6D0:t4:I127,I0,I0,I1 +36E778:lI8888|H36E788 +36E788:lA1B:httpd_conf__127_0_0_1__8888|H36E798 +36E798:lA7:silence|N +36E688:t2:AD:$initial_call,H36E6F0 +36E6F0:t3:AE:httpd_acceptor,A8:acceptor,H36E6C8 +36E694:t2:A9:verbosity,A7:silence +36E6A0:t2:AA:$ancestors,H36E700 +36E700:lA1E:httpd_acc_sup__127_0_0_1__8888|H36E72C +36E72C:lA1A:httpd_sup__127_0_0_1__8888|H36E750 +36E750:lA8:web_tool|H36E768 +36E768:lP<0.27.0>|N +36E6AC:t2:A5:sname,A3:acc +=proc_dictionary:<0.48.0> +H385E48 +H385E54 +=proc_stack:<0.48.0> +3ac1bc:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A10:crashdump_viewer +y3:H3AB280 +y4:A17:crashdump_viewer_server +y5:P<0.41.0> +3ac1d8:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H385E90 +=proc_heap:<0.48.0> +3AB280:t8:A5:state,A9:undefined,A9:undefined,A9:undefined,A5:false,I4,A9:undefined,P<0.56.0> +385E90:lAA:gen_server|H385ED8 +385ED8:lP<0.41.0>|H385F10 +385F10:lP<0.41.0>|H385F58 +385F58:lH385FA8|H385FB4 +385FA8:t2:A5:local,A17:crashdump_viewer_server +385FB4:lA10:crashdump_viewer|H386014 +386014:lN|H38606C +38606C:lN|N +385E48:t2:AD:$initial_call,H385EB0 +385EB0:t3:A3:gen,A7:init_it,H385E90 +385E54:t2:AA:$ancestors,H385EC0 +385EC0:lA6:websup|H385F08 +385F08:lA8:web_tool|H385F50 +385F50:lP<0.27.0>|N +=proc_stack:<0.49.0> +36a114:SReturn addr 0x30174C (io:parse_erl_exprs/3 + 92) +y0:H369E10 +y1:P<0.22.0> +36a120:SReturn addr 0x2E5360 (shell:'-get_command/4-fun-0-'/1 + 20) +y0:N +36a128:SReturn addr 0x156F90 (<terminate process normally>) +=proc_heap:<0.49.0> +369E10:E21:8372000364000D6E6F6E6F6465406E6F686F737400000001330000000000000000 +=atoms +http_cache_control +copy_word +drop_line +copy_line +write_rest_of_line +drop_to_empty_line +read_to_empty_line_reverse +set_pos +read_line_backwards +jumped +jump_to_empty_line_or_eof +get_pos +translate_atoms +translate_fun +translate_funs +translate_loaded_modules2 +translate_loaded_modules_totals +translate_loaded_modules +translate_links +get_all_creations +translate_node_info2 +translate_node_info +translate_dist_info2 +translate_dist_info +get_msg +translate_timers +translate_ets +translate_ets_tables +do_translate_sl_alloc_r7_r8 +translate_sl_alloc_r7_r8 +translate_sl_alloc_line +do_translate_sl_alloc +translate_sl_alloc +translate_memory_and_allocated_area_r9b +translate_allocated_areas +translate_internal_table_line +translate_index_table +translate_hash_table +translate_internal_tables +translate_ports +write_last_calls +write_msg_q_stuff +translate_process +translate_processes +erts_vsn +translate_summary +'Send' +erl_crash_dump +internal_tables +mods +zombies +http_content_length +http_content_type +'-procs_summary_body/5-fun-0-' +'-expanded_memory_body/2-fun-0-' +'-expanded_memory_body/2-fun-1-' +'-expanded_memory_body/2-fun-2-' +'-ports_body/3-fun-0-' +'-ets_tables_body/4-fun-0-' +'-internal_ets_tables_table/1-fun-0-' +'-timers_body/3-fun-0-' +'-make_nodes_table/2-fun-0-' +'-loaded_mods_body/5-fun-0-' +'-funs_body/3-fun-0-' +'-memory_body/3-fun-0-' +'-allocated_areas_body/3-fun-0-' +'-allocator_info_body/3-fun-0-' +'-allocator_info_body/3-fun-1-' +'-allocator_info_body/3-fun-2-' +'-hash_tables_body/3-fun-0-' +'-index_tables_body/3-fun-0-' +enter_write_file +replace_insrt +'$insrt' +special +initial +pretty_format +heading +to_gt_noreverse +to_gt +href_proc_port +br +font +h2 +h1 +img +href +pre +em +td +th +tr +frame +frameset +html_header +index_tables_table +index_tables_body +hash_tables_table +hash_tables_body +allocator_info_body +allocated_areas_table +allocated_areas_body +memory_table +memory_body +atoms_body +funs_table +funs_body +loaded_mod_details_body +loaded_mods_table +loaded_mods_body +format_extra_info +format_links_and_monitors +to_end_par +break_lines_creation +maybe_refcount +nodes_table_row +nodes_table_heading +make_nodes_table +nodes_body +timers_table +timers_body +internal_ets_tables_table1 +internal_ets_tables_table +ets_tables_table +ets_tables_body +ports_table +ports_body +expanded_binary_body +dict_table +stackdump_table +msgq_table +expanded_memory_body +link_to_read_memory +display_or_link_to_expand +proc_details_body +procs_summary_table +summary_table_head +procs_summary_body +pretty_info_body +info_body +error_body +general_info_body +format_title +format_picture +format_item +arentState +format_items +menu_body +filename_body +start_page_frameset +get_translated_filename_frame_body +read_file_frame_body +welcome_body +http_ +http_te +http_connection +http_if_modified_since +http_referer +http_accept_encoding +http_accept +http_host +http_user_agent +'-create_header1/3-fun-0-' +send_response_old +transform +mapfilter +create_header1 +accept_ranges +cache_control +pragma +trailer +etag +retry_after +content_encoding +content_language +content_location +content_MD5 +content_range +expires +transfer_encoding +get_connection +bad_args +send_header +get_body +traverse_modules +formatAbsoluteURI +removeServer +formatRequestUri +tagup_header +verify_request +split_lines +find_content_type +maybe_remove_nl +get_persistens +df +dm +dy +year_day_to_date2 +year_day_to_date +dty +day_to_year +valid_date1 +valid_date +universal_time_to_local_time +time_to_seconds +seconds_to_time +seconds_to_daystime +now_to_local_time +now_to_universal_time +now_to_datetime +last_day_of_the_month1 +last_day_of_the_month +is_leap_year1 +is_leap_year +gregorian_seconds_to_datetime +gregorian_days_to_date +date_to_gregorian_days +'-parse_trailers/1-lc^0/1-0-' +'-read_trailer_end/4-fun-0-' +'-read_trailer_end/4-lc^0/1-0-' +'-remove_newline/1-fun-0-' +remove_newline +close_sleep +unknown_size +send_read_status +handle_read_error +transfer_coding +expect +getTrailerField +read_trailer +get_chunk_size +read_chunked_entity_body +read_chunk_trailer +read_trailer_end +parse_trailers +parse_chunk_trailer +body_to_big +parse_chunked_entity_body +parse_chunk_size +read_chunked_entity +etimedout +body_too_long +unknown_coding +chunked +read_entity_body2 +no_expect_header +http_1_0_expect_header +read_entity_body +header_too_long +hsplit
\ No newline at end of file diff --git a/lib/observer/test/crashdump_viewer_SUITE_data/r10b_dump.trunc.50atoms b/lib/observer/test/crashdump_viewer_SUITE_data/r10b_dump.trunc.50atoms new file mode 100644 index 0000000000..78e301a6c7 --- /dev/null +++ b/lib/observer/test/crashdump_viewer_SUITE_data/r10b_dump.trunc.50atoms @@ -0,0 +1,13085 @@ +=erl_crash_dump:0.1 +Wed Apr 21 13:22:44 2004 +Slogan: eheap_alloc: Cannot allocate 785672 bytes of memory (of type "heap"). +System version: Erlang (BEAM) emulator version 5.4 [source] [hipe] [threads:0] +Compiled: Thu Dec 18 14:07:45 2003 +Atoms: 5614 +=memory +total: 653336887 +processes: 1768396 +processes_used: 1765460 +system: 651568491 +atom: 244837 +atom_used: 237116 +binary: 648618369 +code: 2158413 +ets: 225620 +=hash_table:atom_tab +size: 4813 +used: 3304 +objs: 5614 +depth: 7 +=index_table:atom_tab +size: 5700 +limit: 1048576 +used: 5614 +rate: 100 +=hash_table:module_code +size: 97 +used: 69 +objs: 107 +depth: 5 +=index_table:module_code +size: 110 +limit: 65536 +used: 107 +rate: 10 +=hash_table:export_list +size: 2411 +used: 1674 +objs: 2843 +depth: 6 +=index_table:export_list +size: 2900 +limit: 65536 +used: 2843 +rate: 100 +=hash_table:process_reg +size: 47 +used: 16 +objs: 23 +depth: 3 +=hash_table:fun_table +size: 397 +used: 261 +objs: 400 +depth: 4 +=hash_table:node_table +size: 11 +used: 1 +objs: 1 +depth: 1 +=hash_table:dist_table +size: 11 +used: 1 +objs: 1 +depth: 1 +=allocated_areas +processes: 1765460 1768396 +ets: 225620 +sys_misc: 24634 +static: 295033 +atom_space: 65544 57967 +binary: 648618369 +atom_table: 42141 +module_table: 920 +export_table: 21336 +register_table: 252 +fun_table: 1650 +module_refs: 1024 +loaded_code: 1968915 +dist_table: 159 +node_table: 131 +bits_bufs_size: 19 +bif_timer: 13392 +link_lh: 0 +dist_buf: 0 +proc: 15080 13576 +atom_entry: 137152 137008 +export_entry: 138448 137632 +module_entry: 4872 4352 +reg_proc: 1000 592 +link_nh: 2464 2080 +link_sh: 832 192 +proc_list: 24 24 +fun_entry: 22584 22584 +db_tab: 1632 1632 +=allocator:sys_alloc +option e: true +option m: libc +=allocator:temp_alloc +versions: 0.9 2.1 +option e: true +option sbct: 524288 +option asbcst: 4145152 +option rsbcst: 90 +option rsbcmt: 80 +option mmbcs: 65536 +option mmsbc: 256 +option mmmbc: 10 +option lmbcs: 5242880 +option smbcs: 1048576 +option mbcgs: 10 +option as: af +mbcs blocks: 0 9 9 +mbcs blocks size: 0 35376 35376 +mbcs carriers: 1 1 1 +mbcs mseg carriers: 0 +mbcs sys_alloc carriers: 1 +mbcs carriers size: 65568 65568 65568 +mbcs mseg carriers size: 0 +mbcs sys_alloc carriers size: 65568 +sbcs blocks: 0 0 0 +sbcs blocks size: 0 0 0 +sbcs carriers: 0 0 0 +sbcs mseg carriers: 0 +sbcs sys_alloc carriers: 0 +sbcs carriers size: 0 0 0 +sbcs mseg carriers size: 0 +sbcs sys_alloc carriers size: 0 +temp_alloc calls: 6155 +temp_free calls: 6155 +temp_realloc calls: 29 +mseg_alloc calls: 0 +mseg_dealloc calls: 0 +mseg_realloc calls: 0 +sys_alloc calls: 1 +sys_free calls: 0 +sys_realloc calls: 0 +=allocator:sl_alloc +option e: false +=allocator:std_alloc +option e: false +=allocator:ll_alloc +versions: 0.9 2.1 +option e: true +option sbct: 4294967295 +option asbcst: 0 +option rsbcst: 0 +option rsbcmt: 0 +option mmbcs: 2097152 +option mmsbc: 0 +option mmmbc: 0 +option lmbcs: 5242880 +option smbcs: 1048576 +option mbcgs: 10 +option as: aobf +mbcs blocks: 592 592 592 +mbcs blocks size: 2838520 2863304 2863304 +mbcs carriers: 2 2 2 +mbcs mseg carriers: 0 +mbcs sys_alloc carriers: 2 +mbcs carriers size: 3145760 3145760 3145760 +mbcs mseg carriers size: 0 +mbcs sys_alloc carriers size: 3145760 +sbcs blocks: 0 0 0 +sbcs blocks size: 0 0 0 +sbcs carriers: 0 0 0 +sbcs mseg carriers: 0 +sbcs sys_alloc carriers: 0 +sbcs carriers size: 0 0 0 +sbcs mseg carriers size: 0 +sbcs sys_alloc carriers size: 0 +ll_alloc calls: 592 +ll_free calls: 0 +ll_realloc calls: 235 +mseg_alloc calls: 0 +mseg_dealloc calls: 0 +mseg_realloc calls: 0 +sys_alloc calls: 2 +sys_free calls: 0 +sys_realloc calls: 0 +=allocator:eheap_alloc +versions: 2.1 2.1 +option e: true +option sbct: 524288 +option asbcst: 4145152 +option rsbcst: 50 +option rsbcmt: 80 +option mmbcs: 524288 +option mmsbc: 256 +option mmmbc: 10 +option lmbcs: 5242880 +option smbcs: 1048576 +option mbcgs: 10 +option mbsd: 3 +option as: gf +mbcs blocks: 56 102 102 +mbcs blocks size: 833280 1638920 1638920 +mbcs carriers: 2 3 3 +mbcs mseg carriers: 1 +mbcs sys_alloc carriers: 1 +mbcs carriers size: 1998880 3047456 3047456 +mbcs mseg carriers size: 1474560 +mbcs sys_alloc carriers size: 524320 +sbcs blocks: 0 0 0 +sbcs blocks size: 0 0 0 +sbcs carriers: 0 0 0 +sbcs mseg carriers: 0 +sbcs sys_alloc carriers: 0 +sbcs carriers size: 0 0 0 +sbcs mseg carriers size: 0 +sbcs sys_alloc carriers size: 0 +eheap_alloc calls: 6971 +eheap_free calls: 6914 +eheap_realloc calls: 461 +mseg_alloc calls: 16 +mseg_dealloc calls: 14 +mseg_realloc calls: 0 +sys_alloc calls: 3 +sys_free calls: 0 +sys_realloc calls: 0 +=allocator:binary_alloc +option e: false +=allocator:ets_alloc +option e: false +=allocator:fix_alloc +option e: true +proc: 15080 13576 +atom_entry: 137152 137008 +export_entry: 138448 137632 +module_entry: 4872 4352 +reg_proc: 1000 592 +link_nh: 2464 2080 +link_sh: 832 192 +proc_list: 24 24 +fun_entry: 22584 22584 +db_tab: 1632 1632 +=allocator:mseg_alloc +version: 0.9 +option amcbf: 4194304 +option rmcbf: 20 +option mcs: 5 +option cci: 1000 +cached_segments: 0 +cache_hits: 13 +segments: 2 +segments_watermark: 2 +mseg_alloc calls: 16 +mseg_dealloc calls: 14 +mseg_realloc calls: 0 +mseg_create calls: 4 +mseg_destroy calls: 1 +mseg_clear_cache calls: 6 +mseg_check_cache calls: 2 +=allocator:alloc_util +option mmc: 1024 +option ycs: 1048576 +=allocator:instr +option m: false +option s: false +option t: false +=proc:<0.0.0> +State: Waiting +Name: init +Spawned as: otp_ring0:start/2 +Spawned by: [] +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.5.0>,<0.4.0>,<0.2.0>] +Reductions: 3851 +Stack+heap: 377 +OldHeap: 610 +Heap unused: 53 +OldHeap unused: 610 +Program counter: 0x1f496c (init:loop/1 + 20) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.2.0> +State: Waiting +Name: erl_prim_loader +Spawned as: erlang:apply/2 +Spawned by: <0.1.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.0.0>,#Port<0.2>] +Reductions: 201036 +Stack+heap: 987 +OldHeap: 987 +Heap unused: 923 +OldHeap unused: 987 +Program counter: 0x20cc94 (erl_prim_loader:loop/3 + 52) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.4.0> +State: Waiting +Name: error_logger +Spawned as: proc_lib:init_p/5 +Spawned by: <0.1.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.21.0>,<0.0.0>] +Reductions: 296 +Stack+heap: 6765 +OldHeap: 0 +Heap unused: 851 +OldHeap unused: 0 +Program counter: 0x21f5b8 (gen_event:loop/4 + 40) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.5.0> +State: Waiting +Name: application_controller +Spawned as: proc_lib:init_p/5 +Spawned by: <0.1.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.7.0>,<0.0.0>] +Reductions: 1508 +Stack+heap: 1597 +OldHeap: 0 +Heap unused: 835 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.7.0> +State: Waiting +Spawned as: proc_lib:init_p/5 +Spawned by: <0.6.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.8.0>,<0.5.0>] +Reductions: 23 +Stack+heap: 377 +OldHeap: 0 +Heap unused: 79 +OldHeap unused: 0 +Program counter: 0x248d04 (application_master:main_loop/2 + 28) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.8.0> +State: Waiting +Spawned as: application_master:start_it/4 +Spawned by: <0.7.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.9.0>,<0.7.0>] +Reductions: 91 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 177 +OldHeap unused: 0 +Program counter: 0x24a26c (application_master:loop_it/4 + 40) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.9.0> +State: Waiting +Name: kernel_sup +Spawned as: proc_lib:init_p/5 +Spawned by: <0.8.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.24.0>,<0.23.0>,<0.19.0>,<0.18.0>,<0.17.0>,<0.16.0>,<0.15.0>,<0.14.0>,<0.11.0>,<0.10.0>,<0.8.0>] +Reductions: 7402 +Stack+heap: 610 +OldHeap: 987 +Heap unused: 311 +OldHeap unused: 987 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.10.0> +State: Waiting +Name: rex +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.9.0>] +Reductions: 44 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 144 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.11.0> +State: Waiting +Name: global_name_server +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.13.0>,<0.12.0>,<0.9.0>] +Reductions: 47 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 98 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.12.0> +State: Waiting +Spawned as: global:init_the_locker/1 +Spawned by: <0.11.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.11.0>] +Reductions: 3 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 227 +OldHeap unused: 0 +Program counter: 0x261340 (global:loop_the_locker/2 + 92) +CP: 0x261184 (global:init_the_locker/1 + 112) +arity = 0 +=proc:<0.13.0> +State: Waiting +Spawned as: erlang:apply/2 +Spawned by: <0.11.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.11.0>] +Reductions: 4 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 221 +OldHeap unused: 0 +Program counter: 0x265288 (global:collect_deletions/2 + 76) +CP: 0x2651ac (global:loop_the_deleter/1 + 36) +arity = 0 +=proc:<0.14.0> +State: Waiting +Name: inet_db +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.9.0>] +Reductions: 376 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 30 +OldHeap unused: 233 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.15.0> +State: Waiting +Name: global_group +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.9.0>] +Reductions: 71 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 92 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.16.0> +State: Waiting +Name: file_server_2 +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 1 +Heap fragment data: 119 +Link list: [{from,<0.17.0>,#Ref<0.0.0.22>},#Port<0.4>,<0.9.0>] +Reductions: 83605 +Stack+heap: 4181 +OldHeap: 4181 +Heap unused: 1720 +OldHeap unused: 4181 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.17.0> +State: Waiting +Name: file_server +Spawned as: erlang:apply/2 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [{to,<0.16.0>,#Ref<0.0.0.22>},<0.9.0>] +Reductions: 12 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 207 +OldHeap unused: 0 +Program counter: 0x2a18e8 (old_file_server:relay_loop/3 + 32) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.18.0> +State: Waiting +Name: code_server +Spawned as: erlang:apply/2 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.9.0>] +Reductions: 108900 +Stack+heap: 6765 +OldHeap: 6765 +Heap unused: 4389 +OldHeap unused: 6765 +Program counter: 0x2a6e64 (code_server:loop/1 + 64) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.19.0> +State: Waiting +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.21.0>,<0.9.0>] +Reductions: 74 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 180 +OldHeap unused: 233 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.20.0> +State: Waiting +Spawned as: user_drv:server/2 +Spawned by: <0.19.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.22.0>,<0.21.0>,#Port<0.72>] +Reductions: 596 +Stack+heap: 233 +OldHeap: 377 +Heap unused: 214 +OldHeap unused: 377 +Program counter: 0x2ca4e0 (user_drv:server_loop/5 + 56) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.21.0> +State: Waiting +Name: user +Spawned as: group:server/2 +Spawned by: <0.20.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.4.0>,<0.19.0>,<0.20.0>] +Reductions: 26 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 202 +OldHeap unused: 0 +Program counter: 0x2cd9d8 (group:server_loop/3 + 32) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.22.0> +State: Waiting +Spawned as: group:server/2 +Spawned by: <0.20.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [{from,<0.49.0>,#Ref<0.0.0.307>},<0.25.0>,<0.20.0>] +Reductions: 1244 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 40 +OldHeap unused: 233 +Program counter: 0x2cf238 (group:get_line1/3 + 1652) +CP: 0x2cf230 (group:get_line1/3 + 1644) +arity = 0 +=proc:<0.23.0> +State: Waiting +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.9.0>] +Reductions: 45 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 63 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.24.0> +State: Waiting +Name: kernel_safe_sup +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.31.0>,<0.9.0>] +Reductions: 133 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 198 +OldHeap unused: 233 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.25.0> +State: Waiting +Spawned as: erlang:apply/2 +Spawned by: <0.22.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.49.0>,<0.27.0>,<0.22.0>] +Reductions: 161 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 169 +OldHeap unused: 0 +Program counter: 0x2e0d00 (shell:get_command1/4 + 40) +CP: 0x2e06fc (shell:server_loop/6 + 140) +arity = 0 +=proc:<0.27.0> +State: Waiting +Spawned as: erlang:apply/2 +Spawned by: <0.25.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.25.0>] +Reductions: 506 +Stack+heap: 4181 +OldHeap: 0 +Heap unused: 1131 +OldHeap unused: 0 +Program counter: 0x2e2bbc (shell:eval_loop/2 + 32) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.31.0> +State: Waiting +Name: inet_gethost_native_sup +Spawned as: proc_lib:init_p/5 +Spawned by: <0.24.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.32.0>,<0.24.0>] +Reductions: 49 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 87 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.32.0> +State: Waiting +Name: inet_gethost_native +Spawned as: inet_gethost_native:server_init/2 +Spawned by: <0.31.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 1 +Heap fragment data: 118 +Link list: [#Port<0.105>,<0.31.0>] +Reductions: 65 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 13 +OldHeap unused: 0 +Program counter: 0x4ad840 (inet_gethost_native:main_loop/1 + 20) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.33.0> +State: Waiting +Name: web_tool +Spawned as: proc_lib:init_p/5 +Spawned by: <0.27.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.41.0>] +Reductions: 131773 +Stack+heap: 6765 +OldHeap: 6765 +Heap unused: 2941 +OldHeap unused: 6765 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.41.0> +State: Waiting +Name: websup +Spawned as: proc_lib:init_p/5 +Spawned by: <0.33.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.48.0>,<0.33.0>] +Reductions: 118 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 205 +OldHeap unused: 233 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.43.0> +State: Waiting +Name: httpd_sup__127_0_0_1__8888 +Spawned as: proc_lib:init_p/5 +Spawned by: <0.33.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.46.0>,<0.45.0>,<0.44.0>] +Reductions: 1220 +Stack+heap: 6765 +OldHeap: 0 +Heap unused: 277 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.44.0> +State: Waiting +Name: httpd_acc_sup__127_0_0_1__8888 +Spawned as: proc_lib:init_p/5 +Spawned by: <0.43.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.47.0>,<0.43.0>] +Reductions: 147 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 77 +OldHeap unused: 233 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.45.0> +State: Waiting +Name: httpd_misc_sup__127_0_0_1__8888 +Spawned as: proc_lib:init_p/5 +Spawned by: <0.43.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.43.0>] +Reductions: 52 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 80 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.46.0> +State: Waiting +Name: httpd__127_0_0_1__8888 +Spawned as: proc_lib:init_p/5 +Spawned by: <0.43.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.43.0>] +Reductions: 2905 +Stack+heap: 6765 +OldHeap: 10946 +Heap unused: 138 +OldHeap unused: 10946 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.47.0> +State: Waiting +Spawned as: proc_lib:init_p/5 +Spawned by: <0.44.0> +Started: Wed Apr 21 13:22:18 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [#Port<0.161>,#Port<0.141>,<0.44.0>] +Reductions: 874 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 190 +OldHeap unused: 233 +Program counter: 0x1fe798 (prim_inet:accept0/2 + 96) +CP: 0x1feb04 (prim_inet:async_accept/2 + 380) +arity = 0 +=proc:<0.48.0> +State: Waiting +Name: crashdump_viewer_server +Spawned as: proc_lib:init_p/5 +Spawned by: <0.41.0> +Started: Wed Apr 21 13:22:18 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.56.0>,<0.41.0>] +Reductions: 1913 +Stack+heap: 987 +OldHeap: 987 +Heap unused: 524 +OldHeap unused: 987 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.49.0> +State: Waiting +Spawned as: erlang:apply/2 +Spawned by: <0.25.0> +Started: Wed Apr 21 13:22:18 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [{to,<0.22.0>,#Ref<0.0.0.307>},<0.25.0>] +Reductions: 15 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 190 +OldHeap unused: 0 +Program counter: 0x301d58 (io:wait_io_mon_reply/2 + 28) +CP: 0x30174c (io:parse_erl_exprs/3 + 92) +arity = 0 +=proc:<0.56.0> +State: Garbing +Spawned as: erlang:apply/2 +Last scheduled in for: erlang:garbage_collect/0 +Spawned by: <0.48.0> +Started: Wed Apr 21 13:22:27 2004 +Message queue length: 0 +Number of heap fragments: 1 +Heap fragment data: 121 +Link list: [#Port<0.158>,#Port<0.157>,<0.48.0>] +Reductions: 2420470 +Stack+heap: 121393 +OldHeap: 0 +Heap unused: 22172 +OldHeap unused: 0 +New heap start: FE5768E0 +New heap top: FE5D7734 +Stack top: FE5ED130 +Stack end: FE5ED1A4 +Old heap start: 0 +Old heap top: 0 +Old heap end: 0 +Program counter: 0x1a4980 (unknown function) +CP: 0x20710c (prim_file:read/2 + 436) +=port:#Port<0.1> +Slot: 1 +Connected: #Port<0.0> +Port controls linked-in driver: async +=port:#Port<0.2> +Slot: 2 +Connected: <0.2.0> +Links: <0.2.0> +Port controls linked-in driver: efile +=port:#Port<0.4> +Slot: 4 +Connected: <0.16.0> +Links: <0.16.0> +Port controls linked-in driver: efile +=port:#Port<0.72> +Slot: 72 +Connected: <0.20.0> +Links: <0.20.0> +Port controls linked-in driver: tty_sl -c -e +=port:#Port<0.105> +Slot: 105 +Connected: <0.32.0> +Links: <0.32.0> +Port controls external process: inet_gethost 4 +=port:#Port<0.141> +Slot: 141 +Connected: <0.47.0> +Links: <0.47.0> +Port controls linked-in driver: tcp_inet +=port:#Port<0.157> +Slot: 157 +Connected: <0.56.0> +Links: <0.56.0> +Port controls linked-in driver: efile +=port:#Port<0.158> +Slot: 158 +Connected: <0.56.0> +Links: <0.56.0> +Port controls linked-in driver: efile +=port:#Port<0.161> +Slot: 161 +Connected: <0.47.0> +Links: <0.47.0> +Port controls linked-in driver: tcp_inet +=ets:<0.18.0> +Slot: 9 +Table: 9 +Name: code +Buckets: 256 +Objects: 289 +Words: 14108 +=ets:<0.18.0> +Slot: 10 +Table: 10 +Name: code_names +Buckets: 256 +Objects: 47 +Words: 4334 +=ets:<0.32.0> +Slot: 11 +Table: 11 +Name: ign_requests +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.32.0> +Slot: 12 +Table: 12 +Name: ign_req_index +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.33.0> +Slot: 13 +Table: 13 +Name: app_data +Buckets: 256 +Objects: 7 +Words: 952 +=ets:<0.46.0> +Slot: 15 +Table: 15 +Name: httpd_mime__127_0_0_1__8888 +Buckets: 256 +Objects: 105 +Words: 5742 +=ets:<0.11.0> +Slot: 84 +Table: global_names +Name: global_names +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.11.0> +Slot: 95 +Table: global_locks +Name: global_locks +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.11.0> +Slot: 96 +Table: global_names_ext +Name: global_names_ext +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.14.0> +Slot: 316 +Table: inet_cache +Name: inet_cache +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.48.0> +Slot: 340 +Table: cdv_menu_table +Name: cdv_menu_table +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.48.0> +Slot: 341 +Table: cdv_dump_index_table +Name: cdv_dump_index_table +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.48.0> +Slot: 342 +Table: cdv_decode_heap_table +Name: cdv_decode_heap_table +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.16.0> +Slot: 780 +Table: file_io_servers +Name: file_io_servers +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.46.0> +Slot: 984 +Table: httpd_conf__127_0_0_1__8888 +Name: httpd_conf__127_0_0_1__8888 +Buckets: 256 +Objects: 17 +Words: 1176 +=ets:<0.14.0> +Slot: 1342 +Table: inet_hosts +Name: inet_hosts +Buckets: 256 +Objects: 4 +Words: 421 +=ets:<0.14.0> +Slot: 1362 +Table: inet_db +Name: inet_db +Buckets: 256 +Objects: 20 +Words: 671 +=ets:<0.5.0> +Slot: 1655 +Table: ac_tab +Name: ac_tab +Buckets: 256 +Objects: 6 +Words: 843 +=timer:<0.14.0> +Message: refresh_timeout +Time left: 3565692 ms +=node:'nonode@nohost' +=no_distribution +=loaded_modules +Current code: 1968915 +Old code: 0 +=mod:otp_ring0 +Current size: 489 +=mod:init +Current size: 30110 +=mod:prim_inet +Current size: 35532 +=mod:prim_file +Current size: 24965 +=mod:erl_prim_loader +Current size: 19607 +=mod:erlang +Current size: 11137 +=mod:error_handler +Current size: 2389 +Current attributes: 836C00000001680264000376736E6C000000016E100030769A34345F26EF6D3433254FF2AE576A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613161216802640006736F757263656B00342F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6572726F725F68616E646C65722E65726C6A +=mod:heart +Current size: 6687 +Current attributes: 836C00000001680264000376736E6C000000016E10003094F7BECF345494DDBB4D7186E694186A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261086802640006736F757263656B002C2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F68656172742E65726C6A +=mod:error_logger +Current size: 7051 +Current attributes: 836C00000001680264000376736E6C000000016E10004E3347F841DEAE2EB6A74389E6E127146A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613161246802640006736F757263656B00332F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6572726F725F6C6F676765722E65726C6A +=mod:gen_event +Current size: 18288 +Current attributes: 836C00000001680264000376736E6C000000016E1000336F22DF1EA75E0EA4AE65D3B8C34F946A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61346802640006736F757263656B00302F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F67656E5F6576656E742E65726C6A +=mod:gen +Current size: 7129 +Current attributes: 836C00000001680264000376736E6C000000016E10007BE6AEB66EF48D8B33323C89C9936A526A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61316802640006736F757263656B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F67656E2E65726C6A +=mod:proc_lib +Current size: 11658 +Current attributes: 836C00000001680264000376736E6C000000016E10005C589A8C9BD2E1F2E895E765CAE983406A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E612D6802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F70726F635F6C69622E65726C6A +=mod:application_controller +Current size: 55249 +Current attributes: 836C00000002680264000376736E6C000000016E10003372E1AB0410565065FA086086A721316A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613061246802640006736F757263656B003D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6170706C69636174696F6E5F636F6E74726F6C6C65722E65726C6A +=mod:gen_server +Current size: 18728 +Current attributes: 836C00000001680264000376736E6C000000016E10004C5E93533036DAC7698FC4112F59CF236A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61396802640006736F757263656B00312F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F67656E5F7365727665722E65726C6A +=mod:sys +Current size: 11589 +Current attributes: 836C00000001680264000376736E6C000000016E1000E12B0E8267551204BD5924BAB9629ADF6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612F61176802640006736F757263656B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F7379732E65726C6A +=mod:lists +Current size: 18638 +Current attributes: 836C00000002680264000376736E6C000000016E10001E95B32C30E4CDAF0BDD1ABA58CBB5F36A680264000A646570726563617465646C0000000B68026400066B65796D617061046802640003616C6C61036802640003616E79610368026400036D617061036802640007666C61746D617061036802640005666F6C646C61046802640005666F6C64726104680264000666696C746572610368026400086D6170666F6C646C610468026400086D6170666F6C647261046802640007666F726561636861036A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61116802640006736F757263656B002C2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6C697374732E65726C6A +=mod:application +Current size: 2666 +Current attributes: 836C00000001680264000376736E6C000000016E1000C0C5A7B67B306300FEFF9D91AA50ECB36A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6130611F6802640006736F757263656B00322F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6170706C69636174696F6E2E65726C6A +=mod:application_master +Current size: 10912 +Current attributes: 836C00000001680264000376736E6C000000016E1000360420F5CEB80AD7DD51B3A8A0E2AFA26A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613061266802640006736F757263656B00392F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6170706C69636174696F6E5F6D61737465722E65726C6A +=mod:kernel +Current size: 7639 +Current attributes: 836C00000002680264000376736E6C000000016E10004D418ACCB0F948D4D3CA6B9A81B462746A68026400096265686176696F75726C0000000164000A73757065727669736F726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261336802640006736F757263656B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6B65726E656C2E65726C6A +=mod:supervisor +Current size: 24469 +Current attributes: 836C00000002680264000376736E6C000000016E1000979F65727577135484BE0892A35087CC6A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612F61126802640006736F757263656B00312F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F73757065727669736F722E65726C6A +=mod:rpc +Current size: 14539 +Current attributes: 836C00000002680264000376736E6C000000016E10008C5D6242D36B3201E3B11E82D5E1581E6A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6133610F6802640006736F757263656B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F7270632E65726C6A +=mod:gb_trees +Current size: 8274 +Current attributes: 836C00000001680264000376736E6C000000016E1000094BEFDE7B866EF2CB6FCD895AC2EE056A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D612B6802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F67625F74726565732E65726C6A +=mod:global +Current size: 40753 +Current attributes: 836C00000002680264000376736E6C000000016E10001D02C89BDE6CB2052F099894683C14CA6A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613161386802640006736F757263656B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F676C6F62616C2E65726C6A +=mod:inet_db +Current size: 34555 +Current attributes: 836C00000001680264000376736E6C000000016E1000C1CF6A6F2E83D4EBC23D2CCECBF376226A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6132611A6802640006736F757263656B002E2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F64622E65726C6A +=mod:inet_config +Current size: 13575 +Current attributes: 836C00000001680264000376736E6C000000016E1000650F6571C03BC9C16BB7973A747565066A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261166802640006736F757263656B00322F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F636F6E6669672E65726C6A +=mod:os +Current size: 5997 +Current attributes: 836C00000001680264000376736E6C000000016E100017144CD766A604A9DFBA0B58C8FCA78B6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613361056802640006736F757263656B00292F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6F732E65726C6A +=mod:inet_udp +Current size: 2451 +Current attributes: 836C00000001680264000376736E6C000000016E1000ACB163E87A687A6683B50B331C6E289B6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261306802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F7564702E65726C6A +=mod:inet +Current size: 28288 +Current attributes: 836C00000001680264000376736E6C000000016E10009B9AD400F0BAF6AAF17A4788A4EFF11E6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6132610C6802640006736F757263656B002B2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65742E65726C6A +=mod:inet_parse +Current size: 21928 +Current attributes: 836C00000001680264000376736E6C000000016E1000E0E65454C096847749930EDC1C53C80B6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261266802640006736F757263656B00312F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F70617273652E65726C6A +=mod:filename +Current size: 17411 +Current attributes: 836C00000001680264000376736E6C000000016E100068085214F459D51A3E08819BF8D7698A6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61296802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F66696C656E616D652E65726C6A +=mod:inet_hosts +Current size: 3745 +Current attributes: 836C00000001680264000376736E6C000000016E1000E7430304E86230057150DEE5D279881F6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261226802640006736F757263656B00312F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F686F7374732E65726C6A +=mod:erl_distribution +Current size: 2512 +Current attributes: 836C00000002680264000376736E6C000000016E1000CDE49D63ACA767E0D49679657E99D2046A68026400096265686176696F75726C0000000164000A73757065727669736F726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613161186802640006736F757263656B00372F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F65726C5F646973747269627574696F6E2E65726C6A +=mod:global_group +Current size: 30960 +Current attributes: 836C00000002680264000376736E6C000000016E10008ECE759E5920988CA3ACFF34B32F86736A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6131613B6802640006736F757263656B00332F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F676C6F62616C5F67726F75702E65726C6A +=mod:net_kernel +Current size: 37648 +Current attributes: 836C00000002680264000376736E6C000000016E1000967CE7DE41F9B39906CCCF3225E6E5286A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613361026802640006736F757263656B00312F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6E65745F6B65726E656C2E65726C6A +=mod:file_server +Current size: 8372 +Current attributes: 836C00000002680264000376736E6C000000016E1000EF90906EC6204204AC0A77C4A25B65236A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6131612D6802640006736F757263656B00322F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F66696C655F7365727665722E65726C6A +=mod:old_file_server +Current size: 3074 +Current attributes: 836C00000001680264000376736E6C000000016E1000C802085DD76D4EFBA6A8F528FECB94B36A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6131612F6802640006736F757263656B00362F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6F6C645F66696C655F7365727665722E65726C6A +=mod:code +Current size: 7419 +Current attributes: 836C00000001680264000376736E6C000000016E1000AE618E3041C8E3807A3719CD5140DF5E6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6130612E6802640006736F757263656B002B2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F636F64652E65726C6A +=mod:code_server +Current size: 30811 +Current attributes: 836C00000001680264000376736E6C000000016E0F00BFB96248C2CA8601B4CB7F543F52E26A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613061346802640006736F757263656B00322F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F636F64655F7365727665722E65726C6A +=mod:code_aux +Current size: 1736 +Current attributes: 836C00000001680264000376736E6C000000016E10007A90DB53FCCECD52504F20E7A3B6BAE26A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613061316802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F636F64655F6175782E65726C6A +=mod:packages +Current size: 3119 +Current attributes: 836C00000001680264000376736E6C000000016E1000044DC8EEB65F178AE23EF2465E1954496A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613361076802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F7061636B616765732E65726C6A +=mod:hipe_unified_loader +Current size: 37330 +Current attributes: 836C00000001680264000376736E6C000000016E1000DABD57945702E56F4B3AA7B7B19C1D166A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613361326802640006736F757263656B003A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F686970655F756E69666965645F6C6F616465722E65726C6A +=mod:hipe_sparc_loader +Current size: 1821 +Current attributes: 836C00000001680264000376736E6C000000016E1000582BC55E9FADFF879C2C45D25A6CB7E56A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C7564656802640001696B00322F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F2E2E2F686970652F6D61696E6802640001696B00312F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F2E2E2F686970652F72746C6802640001696B00332F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F2E2E2F686970652F737061726364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6133612B6802640006736F757263656B00382F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F686970655F73706172635F6C6F616465722E65726C6A +=mod:ets +Current size: 16577 +Current attributes: 836C00000002680264000376736E6C000000016E100033D982AC91129E5FC35E0AC3337A4EB56A680264000A646570726563617465646C0000000168026400086669787461626C6561026A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D611C6802640006736F757263656B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6574732E65726C6A +=mod:lists_sort +Current size: 38692 +Current attributes: 836C00000001680264000376736E6C000000016E1000E17EC92FA9AA3199DD71701C215044616A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000B68026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736802640006696E6C696E656C0000000468026400096D65726765335F3132610768026400096D65726765335F32316107680264000A726D65726765335F31326107680264000A726D65726765335F323161076A6802640006696E6C696E656C00000004680264000A756D65726765335F31326108680264000A756D65726765335F32316108680264000C72756D65726765335F3132616107680264000C72756D65726765335F31326261086A6802640006696E6C696E656C00000004680264000C6B65796D65726765335F3132610C680264000C6B65796D65726765335F3231610C680264000D726B65796D65726765335F3132610C680264000D726B65796D65726765335F3231610C6A6802640006696E6C696E656C00000006680264000D756B65796D65726765335F3132610D680264000D756B65796D65726765335F3231610D680264000F72756B65796D65726765335F313261610B680264000F72756B65796D65726765335F323161610D680264000F72756B65796D65726765335F313262610D680264000F72756B65796D65726765335F323162610C6A6A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61166802640006736F757263656B00312F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6C697374735F736F72742E65726C6A +=mod:user_sup +Current size: 2355 +Current attributes: 836C00000002680264000376736E6C000000016E100074BA860804CB4D60D6908C705E6544BD6A68026400096265686176696F75726C0000000164001173757065727669736F725F6272696467656A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613361246802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F757365725F7375702E65726C6A +=mod:supervisor_bridge +Current size: 2944 +Current attributes: 836C00000002680264000376736E6C000000016E10001590DDC10CF8A9D09763CDB7479678ED6A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612F61156802640006736F757263656B00382F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F73757065727669736F725F6272696467652E65726C6A +=mod:user_drv +Current size: 14630 +Current attributes: 836C00000001680264000376736E6C000000016E1000F29F3B193A1EB1ADA9975D97E51BF0E86A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613361216802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F757365725F6472762E65726C6A +=mod:group +Current size: 10165 +Current attributes: 836C00000001680264000376736E6C000000016E1000F6427D0DA330BBFAD5D4C19058516FF36A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261066802640006736F757263656B002C2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F67726F75702E65726C6A +=mod:io_lib +Current size: 12601 +Current attributes: 836C00000002680264000376736E6C000000016E10004160DD78F37EE7C72F7C5B6A751DB7F56A680264000A646570726563617465646C0000000468026400047363616E610168026400047363616E610268026400047363616E6103680264000D72657365727665645F776F726461016A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61036802640006736F757263656B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F696F5F6C69622E65726C6A +=mod:edlin +Current size: 18178 +Current attributes: 836C00000001680264000376736E6C000000016E100035D752FCBA8ED7F4D26990EF3E6A1A526A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612C61016802640006736F757263656B002C2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F65646C696E2E65726C6A +=mod:io_lib_format +Current size: 16189 +Current attributes: 836C00000001680264000376736E6C000000016E10004F382F327C456F83F33C3D5EBFBD87906A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61066802640006736F757263656B00342F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F696F5F6C69625F666F726D61742E65726C6A +=mod:kernel_config +Current size: 3295 +Current attributes: 836C00000002680264000376736E6C000000016E100077B8EE6C9E95FBBE5DB0371F6DB235226A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261356802640006736F757263656B00342F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6B65726E656C5F636F6E6669672E65726C6A +=mod:shell +Current size: 22571 +Current attributes: 836C00000001680264000376736E6C000000016E10007D1354325618EB98A5BD4E8F41E6A0226A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612F61016802640006736F757263656B002C2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F7368656C6C2E65726C6A +=mod:error_logger_tty_h +Current size: 7773 +Current attributes: 836C00000002680264000376736E6C000000016E10001502D55D6C1777F07E2E05CDD91D16986A68026400096265686176696F75726C0000000164000967656E5F6576656E746A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61196802640006736F757263656B00392F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6572726F725F6C6F676765725F7474795F682E65726C6A +=mod:erl_eval +Current size: 33481 +Current attributes: 836C00000002680264000376736E6C000000016E1000D06903753C86BBC49A5CBD789CCB09B66A680264000A646570726563617465646C00000004680264000373657161026802640003736571610368026400086172675F6C697374610268026400086172675F6C69737461036A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612C610D6802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F65726C5F6576616C2E65726C6A +=mod:orddict +Current size: 4872 +Current attributes: 836C00000002680264000376736E6C000000016E100078DCF69F3949D79BC54168266A3ABF566A680264000A646570726563617465646C00000002680264000C646963745F746F5F6C6973746101680264000C6C6973745F746F5F6469637461016A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61236802640006736F757263656B002E2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6F7264646963742E65726C6A +=mod:c +Current size: 19555 +Current attributes: 836C00000001680264000376736E6C000000016E10003FACCF5DE16ABBC988ABF0811980C33B6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612B61136802640006736F757263656B00282F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F632E65726C6A +=mod:io +Current size: 7417 +Current attributes: 836C00000002680264000376736E6C000000016E1000E2F2A6094B3C3D945865225D0620E7546A680264000A646570726563617465646C00000007680264000B70617273655F65787072736102680264000C7363616E5F65726C5F7365716101680264000C7363616E5F65726C5F7365716102680264000C7363616E5F65726C5F7365716103680264000D70617273655F65726C5F7365716101680264000D70617273655F65726C5F7365716102680264000D70617273655F65726C5F73657161036A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61006802640006736F757263656B00292F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F696F2E65726C6A +=mod:file +Current size: 20795 +Current attributes: 836C00000002680264000376736E6C000000016E1000D291AF77EE8B08B792B7FE99274504506A680264000A646570726563617465646C00000001680264000966696C655F696E666F61016A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613161276802640006736F757263656B002B2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F66696C652E65726C6A +=mod:file_io_server +Current size: 12071 +Current attributes: 836C00000001680264000376736E6C000000016E1000A5A8C4E2B2646855AD5C617CB216CB966A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6131612A6802640006736F757263656B00352F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F66696C655F696F5F7365727665722E65726C6A +=mod:erl_scan +Current size: 21891 +Current attributes: 836C00000001680264000376736E6C000000016E100094F386F0C378B258E5D9CEADD4F03B6A6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61116802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F65726C5F7363616E2E65726C6A +=mod:erl_parse +Current size: 161233 +Current attributes: 836C00000001680264000376736E6C000000016E10000E8CBC32C293BFC1FBC721CE918062236A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000968026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F76617273640006696E6C696E656802640004686970656C000000016802640008726567616C6C6F6364000B6C696E6561725F7363616E6A6A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61076802640006736F757263656B00302F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F65726C5F70617273652E65726C6A +=mod:erl_lint +Current size: 73159 +Current attributes: 836C00000001680264000376736E6C000000016E1000D1D2A7D6DDFD1195CB180993C76FD2CD6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612C61156802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F65726C5F6C696E742E65726C6A +=mod:ordsets +Current size: 3257 +Current attributes: 836C00000002680264000376736E6C000000016E1000FD39D8FD846511128F5670BA28600F676A680264000A646570726563617465646C0000000468026400076E65775F7365746100680264000B7365745F746F5F6C6973746101680264000B6C6973745F746F5F7365746101680264000673756273657461026A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61256802640006736F757263656B002E2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6F7264736574732E65726C6A +=mod:dict +Current size: 15637 +Current attributes: 836C00000002680264000376736E6C000000016E1000BC846E7EF85045A5D76190CE9B1AE97C6A680264000A646570726563617465646C00000002680264000C646963745F746F5F6C6973746101680264000C6C6973745F746F5F6469637461016A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612B61356802640006736F757263656B002B2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F646963742E65726C6A +=mod:otp_internal +Current size: 7133 +Current attributes: 836C00000001680264000376736E6C000000016E1000DC494F64DE590AFC4919DFEB0EB026B66A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61206802640006736F757263656B00332F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6F74705F696E7465726E616C2E65726C6A +=mod:user_default +Current size: 1261 +Current attributes: 836C00000002680264000376736E6C000000016E1000505078ACD9B84D514FC6DA2BE249E6756A6802640006617574686F726C0000000164001765656973686E6E406565692E6572696373736F6E2E73656A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000368026400036377646B00112F686F6D652F736972692F65726C616E6768026400066F75746469726B00112F686F6D652F736972692F65726C616E676400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D461036116610D612C61126802640006736F757263656B00222F686F6D652F736972692F65726C616E672F757365725F64656661756C742E65726C6A +=mod:tt +Current size: 2959 +Current attributes: 836C00000002680264000376736E6C000000016E10001D71FD5A55D3BCBF06BFEDF2426C3C386A6802640006617574686F726C0000000164001765656973686E6E406565692E6572696373736F6E2E73656A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000368026400036377646B00112F686F6D652F736972692F65726C616E6768026400066F75746469726B00112F686F6D652F736972692F65726C616E676400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D461036116610D612B610C6802640006736F757263656B00182F686F6D652F736972692F65726C616E672F74742E65726C6A +=mod:distel +Current size: 18214 +Current attributes: 836C00000002680264000376736E6C000000016E1000CC9C9EF141459249C1CCA00993B2E29A6A6802640006617574686F726C000000016400116C756B6540626C75657461696C2E636F6D6A6A +Current compilation info: 836C0000000368026400076F7074696F6E736C0000000664000276336400107761726E5F756E757365645F7661727364000A64656275675F696E666F68026400066F75746469726B00046562696E68026400036377646B001C2F6C6469736B2F736972692F746F6F6C732F64697374656C2D332E3164000A6578706F72745F616C6C6A680264000776657273696F6E6B0003342E31680264000474696D65680662000007D2610B6114610B610361336A +=mod:crashdump_viewer +Current size: 125756 +Current attributes: 836C00000001680264000376736E6C000000016E10002DC5D9D96190A2D5F27FAC3FA3D5C7956A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868026400036377646B00212F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F73726368026400066F75746469726B00292F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F6562696E6802640001696B002C2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F696E636C7564656802640001696B00322F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F2E2E2F65742F696E636C7564656802640001696B003F2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F2E2E2F2E2E2F6C69627261726965732F65742F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F76617273680264000F70617273655F7472616E73666F726D64000C6D735F7472616E73666F726D6A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461146108611B61366802640006736F757263656B00362F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F637261736864756D705F7669657765722E65726C6A +=mod:webtool +Current size: 29229 +Current attributes: 836C00000002680264000376736E6C000000016E10008AEEF06B60527A3390CBC2C98083CC0A6A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00202F636C656172636173652F6F74702F746F6F6C732F776562746F6F6C2F73726368026400066F75746469726B00282F636C656172636173652F6F74702F746F6F6C732F776562746F6F6C2F7372632F2E2E2F6562696E64000A64656275675F696E666F6400107761726E5F756E757365645F76617273680264000F70617273655F7472616E73666F726D64000C6D735F7472616E73666F726D6A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104610661086106612D6802640006736F757263656B002C2F636C656172636173652F6F74702F746F6F6C732F776562746F6F6C2F7372632F776562746F6F6C2E65726C6A +=mod:gen_tcp +Current size: 3574 +Current attributes: 836C00000001680264000376736E6C000000016E1000C965E4EAFDAA94D7F21EDCBE30B21E7B6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613161316802640006736F757263656B002E2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F67656E5F7463702E65726C6A +=mod:inet_tcp +Current size: 2743 +Current attributes: 836C00000001680264000376736E6C000000016E1000C4AFE0B49768E4CF78B2C42EA1D3DB7F6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6132612B6802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F7463702E65726C6A +=mod:inet_gethost_native +Current size: 15611 +Current attributes: 836C00000002680264000376736E6C000000016E10005D8CD4277D0BD2425B9C26036AE314506A68026400096265686176696F75726C0000000164001173757065727669736F725F6272696467656A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261206802640006736F757263656B003A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F676574686F73745F6E61746976652E65726C6A +=mod:filelib +Current size: 7202 +Current attributes: 836C00000001680264000376736E6C000000016E10007B42AA23FF99DF2CD9D586635B77556A6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61266802640006736F757263656B002E2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F66696C656C69622E65726C6A +=mod:httpd_util +Current size: 24068 +Current attributes: 836C00000002680264000376736E6C000000016E10008D99E096221B88D542E52CB9C8377F6D6A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104611561066128613B6802640006736F757263656B00312F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F7574696C2E65726C6A +=mod:webtool_sup +Current size: 695 +Current attributes: 836C00000002680264000376736E6C000000016E1000FA5449E12816CF3AD0A3085BB26CDB9B6A68026400096265686176696F75726C0000000164000A73757065727669736F726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000468026400036377646B00202F636C656172636173652F6F74702F746F6F6C732F776562746F6F6C2F73726368026400066F75746469726B00282F636C656172636173652F6F74702F746F6F6C732F776562746F6F6C2F7372632F2E2E2F6562696E64000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461066108610761236802640006736F757263656B00302F636C656172636173652F6F74702F746F6F6C732F776562746F6F6C2F7372632F776562746F6F6C5F7375702E65726C6A +=mod:httpd_conf +Current size: 33659 +Current attributes: 836C00000002680264000376736E6C000000016E1000E3198FBDC73BC48CB7D0C1C762B8F1AB6A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861116802640006736F757263656B00312F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F636F6E662E65726C6A +=mod:regexp +Current size: 13698 +Current attributes: 836C00000001680264000376736E6C000000016E10009DD44F3D02F8328BE3ABF4DDA89E0CAE6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61376802640006736F757263656B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F7265676578702E65726C6A +=mod:string +Current size: 7740 +Current attributes: 836C00000002680264000376736E6C000000016E10005521DDF38903D46D7C53DB864266F7456A680264000A646570726563617465646C00000007680264000C72655F73685F746F5F61776B6101680264000872655F70617273656101680264000872655F6D617463686102680264000672655F7375626103680264000772655F677375626103680264000872655F73706C697461026802640005696E64657861026A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612F610F6802640006736F757263656B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F737472696E672E65726C6A +=mod:httpd +Current size: 7563 +Current attributes: 836C00000002680264000376736E6C000000016E1000BFD190D951EB3CAD2CC72ADEF20886906A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861036802640006736F757263656B002C2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470642E65726C6A +=mod:httpd_sup +Current size: 4068 +Current attributes: 836C00000003680264000376736E6C000000016E10007FA5C790118F18F3D20A2BFAF0229F0A6A68026400076170705F76736E6B000B696E6574732D332E302E3768026400096265686176696F75726C0000000164000A73757065727669736F726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861366802640006736F757263656B00302F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F7375702E65726C6A +=mod:httpd_acceptor_sup +Current size: 2161 +Current attributes: 836C00000003680264000376736E6C000000016E10003E6F9289B64C13F1EC8A1184BACF055F6A68026400076170705F76736E6B000B696E6574732D332E302E3768026400096265686176696F75726C0000000164000A73757065727669736F726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104611561066128610C6802640006736F757263656B00392F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F6163636570746F725F7375702E65726C6A +=mod:httpd_verbosity +Current size: 2672 +Current attributes: 836C00000002680264000376736E6C000000016E100018B6F407D391872421748F87877DAAF36A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612961036802640006736F757263656B00362F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F766572626F736974792E65726C6A +=mod:timer +Current size: 8223 +Current attributes: 836C00000001680264000376736E6C000000016E10001D0D64DB1B923D1B3B9497655C43B4AD6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612F611A6802640006736F757263656B002C2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F74696D65722E65726C6A +=mod:httpd_misc_sup +Current size: 2066 +Current attributes: 836C00000003680264000376736E6C000000016E100092342F38AC16C074DDC21532FBFB52C26A68026400076170705F76736E6B000B696E6574732D332E302E3768026400096265686176696F75726C0000000164000A73757065727669736F726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104611561066128611F6802640006736F757263656B00352F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F6D6973635F7375702E65726C6A +=mod:httpd_manager +Current size: 28916 +Current attributes: 836C00000003680264000376736E6C000000016E100013F7A1E6A4B6407A0A1892A794EE10A36A68026400076170705F76736E6B000B696E6574732D332E302E3768026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104611561066128611B6802640006736F757263656B00342F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F6D616E616765722E65726C6A +=mod:mod_alias +Current size: 6720 +Current attributes: 836C00000002680264000376736E6C000000016E10002F35C36060B4AC45474440381D146AB96A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612961106802640006736F757263656B00302F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F616C6961732E65726C6A +=mod:mod_auth +Current size: 25168 +Current attributes: 836C00000002680264000376736E6C000000016E100083F3CA0C7A3E7B5E19A635A7F916595D6A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612961166802640006736F757263656B002F2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F617574682E65726C6A +=mod:mod_esi +Current size: 22534 +Current attributes: 836C00000002680264000376736E6C000000016E1000513E3FF733E1E6592B86CB55B9C14E086A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612A61026802640006736F757263656B002E2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F6573692E65726C6A +=mod:mod_actions +Current size: 3625 +Current attributes: 836C00000002680264000376736E6C000000016E10008E5437921662830490CA76DFF88548966A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104611561066129610C6802640006736F757263656B00322F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F616374696F6E732E65726C6A +=mod:mod_cgi +Current size: 25891 +Current attributes: 836C00000002680264000376736E6C000000016E1000F91D405488188F1BD25110B4ED9EE8786A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612961306802640006736F757263656B002E2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F6367692E65726C6A +=mod:mod_include +Current size: 34923 +Current attributes: 836C00000002680264000376736E6C000000016E1000B9CCE88D63DD6AC49D5DF533C46B97D56A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612A61176802640006736F757263656B00322F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F696E636C7564652E65726C6A +=mod:mod_dir +Current size: 13488 +Current attributes: 836C00000002680264000376736E6C000000016E1000EF620CB4B5DE5586ED681347496DA1C86A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612961356802640006736F757263656B002E2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F6469722E65726C6A +=mod:mod_get +Current size: 4672 +Current attributes: 836C00000002680264000376736E6C000000016E1000AD2730B6BE6AF875A500AF4857C4D7F86A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612A61076802640006736F757263656B002E2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F6765742E65726C6A +=mod:mod_head +Current size: 3074 +Current attributes: 836C00000002680264000376736E6C000000016E1000CAF803B9FA6A28D4153BC109B00D7DF96A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612A610B6802640006736F757263656B002F2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F686561642E65726C6A +=mod:mod_log +Current size: 8546 +Current attributes: 836C00000002680264000376736E6C000000016E1000F9664B54861260DEA081249379219AF86A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612A611B6802640006736F757263656B002E2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F6C6F672E65726C6A +=mod:mod_disk_log +Current size: 15160 +Current attributes: 836C00000002680264000376736E6C000000016E1000DDA1E88A9C423A2866B56425DF36F5C66A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612961396802640006736F757263656B00332F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F6469736B5F6C6F672E65726C6A +=mod:httpd_socket +Current size: 7426 +Current attributes: 836C00000002680264000376736E6C000000016E1000B831219096661E4D2E200A07C4A9A7776A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861326802640006736F757263656B00332F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F736F636B65742E65726C6A +=mod:httpd_acceptor +Current size: 4472 +Current attributes: 836C00000002680264000376736E6C000000016E1000A501686DF4E4053E7D978E0CA162BEC56A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861076802640006736F757263656B00352F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F6163636570746F722E65726C6A +=mod:io_lib_pretty +Current size: 8171 +Current attributes: 836C00000001680264000376736E6C000000016E1000CD397E11D2D380D02A4BC6EE309B98CB6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E610C6802640006736F757263656B00342F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F696F5F6C69625F7072657474792E65726C6A +=mod:httpd_request_handler +Current size: 26393 +Current attributes: 836C00000002680264000376736E6C000000016E100021C280A5EB5B9CCD00A2C418A341202A6A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861296802640006736F757263656B003C2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F726571756573745F68616E646C65722E65726C6A +=mod:calendar +Current size: 7158 +Current attributes: 836C00000002680264000376736E6C000000016E10008C44498546709037F8D72DA4AF8B7FB76A680264000A646570726563617465646C00000001680264001C6C6F63616C5F74696D655F746F5F756E6976657273616C5F74696D6561016A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612B61166802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F63616C656E6461722E65726C6A +=mod:httpd_parse +Current size: 9977 +Current attributes: 836C00000002680264000376736E6C000000016E1000174653BAA652261FEB44FFDED99E50B76A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861246802640006736F757263656B00322F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F70617273652E65726C6A +=mod:httpd_response +Current size: 13535 +Current attributes: 836C00000002680264000376736E6C000000016E1000785B247D894BA08A40D814EF11F848976A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104611561066128612D6802640006736F757263656B00352F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F726573706F6E73652E65726C6A +=mod:crashdump_viewer_html +Current size: 68343 +Current attributes: 836C00000001680264000376736E6C000000016E1000AE414770FDB0806C5583FF8D6D71DC766A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00212F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F73726368026400066F75746469726B00292F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F6562696E6802640001696B002C2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F696E636C7564656802640001696B00322F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F2E2E2F65742F696E636C7564656802640001696B003F2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F2E2E2F2E2E2F6C69627261726965732F65742F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461146108611C61026802640006736F757263656B003B2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F637261736864756D705F7669657765725F68746D6C2E65726C6A +=mod:crashdump_translate +Current size: 89840 +Current attributes: 836C00000001680264000376736E6C000000016E100038F332287181E933A76CEF4799BDB6416A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000668026400036377646B00212F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F73726368026400066F75746469726B00292F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F6562696E6802640001696B002C2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F696E636C7564656802640001696B00322F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F2E2E2F65742F696E636C7564656802640001696B003F2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F2E2E2F2E2E2F6C69627261726965732F65742F696E636C75646564000A64656275675F696E666F6A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D461046115610B611661106802640006736F757263656B00392F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F637261736864756D705F7472616E736C6174652E65726C6A +=fun +Module: crashdump_viewer_html +Uniq: 9122590 +Index: 0 +Address: 526308 +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 77168418 +Index: 14 +Address: 26541c +Native_address: bcf04 +Refc: 1 +=fun +Module: inet_parse +Uniq: 88083515 +Index: 9 +Address: 284c30 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 36747896 +Index: 4 +Address: 26df84 +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 80395734 +Index: 8 +Address: 265838 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 103184573 +Index: 5 +Address: 2fa59c +Native_address: bce80 +Refc: 1 +=fun +Module: erl_lint +Uniq: 88265811 +Index: 24 +Address: 34f6a0 +Native_address: bcefc +Refc: 1 +=fun +Module: global_group +Uniq: 9644262 +Index: 2 +Address: 292cec +Native_address: bcef4 +Refc: 1 +=fun +Module: net_kernel +Uniq: 100885585 +Index: 0 +Address: 29eb2c +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 128335479 +Index: 6 +Address: 26de84 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_prim_loader +Uniq: 42988083 +Index: 1 +Address: 210c14 +Native_address: bcf04 +Refc: 1 +=fun +Module: dict +Uniq: 7105125 +Index: 7 +Address: 354f84 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 29030584 +Index: 8 +Address: 234978 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 29214351 +Index: 2 +Address: 285660 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_config +Uniq: 5158633 +Index: 4 +Address: 274034 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 74624950 +Index: 25 +Address: 34f63c +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 6477018 +Index: 3 +Address: 2adb6c +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 117885138 +Index: 7 +Address: 2ffff8 +Native_address: bcefc +Refc: 1 +=fun +Module: dict +Uniq: 47566924 +Index: 6 +Address: 354fb8 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 114637756 +Index: 12 +Address: 313c60 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 121316204 +Index: 31 +Address: 313a68 +Native_address: bced4 +Refc: 1 +=fun +Module: code_server +Uniq: 61363639 +Index: 12 +Address: 2ad6a4 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_config +Uniq: 116208699 +Index: 3 +Address: 274094 +Native_address: bcefc +Refc: 1 +=fun +Module: global_group +Uniq: 113750737 +Index: 0 +Address: 292d54 +Native_address: bcefc +Refc: 1 +=fun +Module: gen_event +Uniq: 12853672 +Index: 0 +Address: 222e74 +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 108046357 +Index: 12 +Address: 4ab0b0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 111569299 +Index: 47 +Address: 34e80c +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 20108653 +Index: 15 +Address: 2f9f94 +Native_address: bcea4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 45252965 +Index: 15 +Address: 313c0c +Native_address: bced4 +Refc: 1 +=fun +Module: webtool +Uniq: 12437425 +Index: 9 +Address: 4ab3e0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 30942993 +Index: 22 +Address: 34f6ec +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_parse +Uniq: 93430337 +Index: 3 +Address: 33b100 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_parse +Uniq: 6604883 +Index: 2 +Address: 33b16c +Native_address: bcefc +Refc: 1 +=fun +Module: rpc +Uniq: 36867745 +Index: 5 +Address: 255e28 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 90563105 +Index: 1 +Address: 285708 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 18519297 +Index: 7 +Address: 26ddfc +Native_address: bcef4 +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 8058975 +Index: 16 +Address: 4a36b4 +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 30694569 +Index: 7 +Address: 27d018 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_config +Uniq: 76933943 +Index: 0 +Address: 2741b4 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 9033258 +Index: 6 +Address: 4a4690 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 74851752 +Index: 5 +Address: 4a4798 +Native_address: bcef4 +Refc: 1 +=fun +Module: global +Uniq: 50855382 +Index: 4 +Address: 2659a8 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 39211582 +Index: 52 +Address: 34e504 +Native_address: bceec +Refc: 1 +=fun +Module: file_server +Uniq: 77665472 +Index: 0 +Address: 2a0dec +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_eval +Uniq: 57487277 +Index: 8 +Address: 2fa3c4 +Native_address: bce94 +Refc: 1 +=fun +Module: webtool +Uniq: 87386575 +Index: 11 +Address: 4ab1c8 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 58991950 +Index: 8 +Address: 4a4338 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 118859163 +Index: 17 +Address: 4a34d4 +Native_address: bcefc +Refc: 1 +=fun +Module: dict +Uniq: 38265609 +Index: 12 +Address: 354dec +Native_address: bcefc +Refc: 1 +=fun +Module: supervisor +Uniq: 56903339 +Index: 1 +Address: 2527c4 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_hosts +Uniq: 129504763 +Index: 0 +Address: 28aae8 +Native_address: bcefc +Refc: 1 +=fun +Module: dict +Uniq: 44817307 +Index: 10 +Address: 354e3c +Native_address: bceec +Refc: 1 +=fun +Module: erl_lint +Uniq: 52856894 +Index: 41 +Address: 34eb70 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 22623360 +Index: 23 +Address: 34f5d4 +Native_address: bceec +Refc: 1 +=fun +Module: orddict +Uniq: 34963136 +Index: 0 +Address: 2fbbbc +Native_address: bcef4 +Refc: 1 +=fun +Module: erlang +Uniq: 24496633 +Index: 0 +Address: 213744 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 99313855 +Index: 27 +Address: 2f9914 +Native_address: bcef4 +Refc: 1 +=fun +Module: httpd_util +Uniq: 99137703 +Index: 3 +Address: 4b5dfc +Native_address: bcefc +Refc: 1 +=fun +Module: gen_event +Uniq: 124043500 +Index: 3 +Address: 222b84 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 102650878 +Index: 22 +Address: 313b48 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 13333720 +Index: 12 +Address: 34fb2c +Native_address: bcef4 +Refc: 1 +=fun +Module: global_group +Uniq: 133457 +Index: 5 +Address: 292a80 +Native_address: bcefc +Refc: 1 +=fun +Module: net_kernel +Uniq: 64640983 +Index: 4 +Address: 29e944 +Native_address: bcefc +Refc: 1 +=fun +Module: rpc +Uniq: 7580218 +Index: 2 +Address: 255f08 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_lint +Uniq: 131850870 +Index: 59 +Address: 34e6b8 +Native_address: bcef4 +Refc: 1 +=fun +Module: inet_parse +Uniq: 56617403 +Index: 10 +Address: 284b40 +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 108680306 +Index: 4 +Address: 4ab5e0 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 90880071 +Index: 2 +Address: 26e150 +Native_address: bcefc +Refc: 1 +=fun +Module: file_io_server +Uniq: 23980778 +Index: 0 +Address: 30ac30 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_eval +Uniq: 12006418 +Index: 19 +Address: 2f9d54 +Native_address: bce80 +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 81701030 +Index: 8 +Address: 526228 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 71013875 +Index: 1 +Address: 4a4ddc +Native_address: bcf04 +Refc: 1 +=fun +Module: distel +Uniq: 87740845 +Index: 2 +Address: 35c0e0 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_eval +Uniq: 90782401 +Index: 17 +Address: 2f9e8c +Native_address: bced4 +Refc: 1 +=fun +Module: shell +Uniq: 133882676 +Index: 6 +Address: 2e52ac +Native_address: bcef4 +Refc: 1 +=fun +Module: inet_parse +Uniq: 105698088 +Index: 3 +Address: 2855b4 +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 58370899 +Index: 0 +Address: 27d370 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 15274536 +Index: 25 +Address: 2f9a94 +Native_address: bcef4 +Refc: 1 +=fun +Module: supervisor +Uniq: 94349557 +Index: 0 +Address: 252844 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_parse +Uniq: 33328185 +Index: 1 +Address: 33b1d8 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 86971387 +Index: 16 +Address: 313db0 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 53364473 +Index: 38 +Address: 34ee84 +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 128145687 +Index: 0 +Address: 4ab944 +Native_address: bcee4 +Refc: 1 +=fun +Module: c +Uniq: 98651404 +Index: 10 +Address: 2fff20 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 78224618 +Index: 0 +Address: 313dcc +Native_address: bced4 +Refc: 1 +=fun +Module: shell +Uniq: 40779085 +Index: 11 +Address: 2e50c8 +Native_address: bcef4 +Refc: 1 +=fun +Module: c +Uniq: 93517350 +Index: 4 +Address: 300090 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 58551291 +Index: 0 +Address: 234f14 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 10055518 +Index: 17 +Address: 526170 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 15795706 +Index: 19 +Address: 313bd4 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 31129467 +Index: 13 +Address: 313c44 +Native_address: bced4 +Refc: 1 +=fun +Module: old_file_server +Uniq: 115635393 +Index: 0 +Address: 2a1a4c +Native_address: bcf04 +Refc: 2 +=fun +Module: erl_eval +Uniq: 65839696 +Index: 22 +Address: 2f9c00 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 69275064 +Index: 28 +Address: 313aa0 +Native_address: bced4 +Refc: 1 +=fun +Module: dict +Uniq: 55938066 +Index: 11 +Address: 354d6c +Native_address: bceec +Refc: 1 +=fun +Module: supervisor +Uniq: 22323433 +Index: 3 +Address: 252688 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 129726129 +Index: 29 +Address: 313abc +Native_address: bced4 +Refc: 1 +=fun +Module: dict +Uniq: 84346832 +Index: 0 +Address: 3550fc +Native_address: bceec +Refc: 1 +=fun +Module: shell +Uniq: 102096820 +Index: 7 +Address: 2e5290 +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 70385762 +Index: 11 +Address: 27cf44 +Native_address: bcefc +Refc: 1 +=fun +Module: mod_cgi +Uniq: 1483038 +Index: 0 +Address: 4ec2e8 +Native_address: bcefc +Refc: 1 +=fun +Module: dict +Uniq: 3664813 +Index: 1 +Address: 3550b4 +Native_address: bcef4 +Refc: 1 +=fun +Module: inet +Uniq: 131143671 +Index: 6 +Address: 27d08c +Native_address: bcef4 +Refc: 1 +=fun +Module: inet_config +Uniq: 46286977 +Index: 2 +Address: 2740b0 +Native_address: bcefc +Refc: 1 +=fun +Module: mod_esi +Uniq: 49099432 +Index: 0 +Address: 4e522c +Native_address: bcefc +Refc: 1 +=fun +Module: application_master +Uniq: 95764905 +Index: 2 +Address: 24aaa8 +Native_address: bcefc +Refc: 1 +=fun +Module: packages +Uniq: 62890926 +Index: 0 +Address: 2ae814 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 41564771 +Index: 35 +Address: 3139f8 +Native_address: bced4 +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 95490768 +Index: 0 +Address: 4a4dc0 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_scan +Uniq: 121559432 +Index: 3 +Address: 313d78 +Native_address: bced4 +Refc: 1 +=fun +Module: httpd_conf +Uniq: 21152662 +Index: 0 +Address: 4be5a0 +Native_address: bcefc +Refc: 1 +=fun +Module: net_kernel +Uniq: 41630916 +Index: 5 +Address: 29e914 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 19747201 +Index: 5 +Address: 313d24 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 100584837 +Index: 36 +Address: 34f0f4 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 64635712 +Index: 15 +Address: 34f94c +Native_address: bcef4 +Refc: 1 +=fun +Module: net_kernel +Uniq: 46398361 +Index: 3 +Address: 29e9a4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 86699817 +Index: 27 +Address: 313b2c +Native_address: bced4 +Refc: 1 +=fun +Module: distel +Uniq: 40869731 +Index: 0 +Address: 35c12c +Native_address: bcf04 +Refc: 1 +=fun +Module: inet +Uniq: 83701641 +Index: 1 +Address: 27d33c +Native_address: bcefc +Refc: 1 +=fun +Module: mod_auth +Uniq: 85845790 +Index: 0 +Address: 4dfd84 +Native_address: bcefc +Refc: 1 +=fun +Module: shell +Uniq: 101292714 +Index: 9 +Address: 2e519c +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 134173702 +Index: 1 +Address: 265b68 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 92433687 +Index: 6 +Address: 2ad9f4 +Native_address: bcef4 +Refc: 1 +=fun +Module: dict +Uniq: 62315241 +Index: 8 +Address: 354f38 +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 11615541 +Index: 12 +Address: 265530 +Native_address: bcefc +Refc: 1 +=fun +Module: hipe_unified_loader +Uniq: 11160090 +Index: 2 +Address: 2b6bb4 +Native_address: bcef4 +Refc: 1 +=fun +Module: application_controller +Uniq: 12116524 +Index: 15 +Address: 2342c4 +Native_address: bcef4 +Refc: 1 +=fun +Module: mod_log +Uniq: 61620901 +Index: 2 +Address: 4fc670 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 23665189 +Index: 12 +Address: 4a3b94 +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 43844413 +Index: 0 +Address: 300100 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 100514258 +Index: 6 +Address: 313d08 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 54271286 +Index: 17 +Address: 34f8a0 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 47017252 +Index: 3 +Address: 26dfa0 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 1228304 +Index: 7 +Address: 4a45a4 +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 127131470 +Index: 10 +Address: 2655a0 +Native_address: bcefc +Refc: 1 +=fun +Module: file_server +Uniq: 22638227 +Index: 1 +Address: 2a0e20 +Native_address: bcf04 +Refc: 1 +=fun +Module: code_server +Uniq: 112704920 +Index: 15 +Address: 2ad488 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 88302875 +Index: 2 +Address: 2fa76c +Native_address: bceb4 +Refc: 1 +=fun +Module: inet_hosts +Uniq: 85808984 +Index: 1 +Address: 28ab18 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_parse +Uniq: 106391799 +Index: 0 +Address: 33b22c +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 25830519 +Index: 5 +Address: 27d0c0 +Native_address: bcefc +Refc: 1 +=fun +Module: shell +Uniq: 110491036 +Index: 1 +Address: 2e5398 +Native_address: bcef4 +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 13128736 +Index: 5 +Address: 52627c +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 84644982 +Index: 21 +Address: 313b9c +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 120577486 +Index: 3 +Address: 34fffc +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 4504456 +Index: 44 +Address: 34e938 +Native_address: bceec +Refc: 1 +=fun +Module: mod_disk_log +Uniq: 28754183 +Index: 0 +Address: 500140 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 88043334 +Index: 14 +Address: 313c28 +Native_address: bced4 +Refc: 1 +=fun +Module: code_server +Uniq: 61592373 +Index: 0 +Address: 2adc28 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_scan +Uniq: 74468346 +Index: 26 +Address: 313ad8 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 69896253 +Index: 21 +Address: 2f9c40 +Native_address: bce80 +Refc: 1 +=fun +Module: global_group +Uniq: 59656873 +Index: 4 +Address: 292ac0 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 103891261 +Index: 2 +Address: 4a4d70 +Native_address: bcefc +Refc: 1 +=fun +Module: httpd_util +Uniq: 89619733 +Index: 0 +Address: 4b5e64 +Native_address: bcefc +Refc: 1 +=fun +Module: shell +Uniq: 133201466 +Index: 10 +Address: 2e5180 +Native_address: bceec +Refc: 1 +=fun +Module: webtool +Uniq: 32159369 +Index: 2 +Address: 4ab820 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 76861396 +Index: 2 +Address: 2adbb0 +Native_address: bcefc +Refc: 1 +=fun +Module: mod_log +Uniq: 48206487 +Index: 0 +Address: 4fc6f0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 118996551 +Index: 28 +Address: 34f384 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 12593774 +Index: 50 +Address: 34e60c +Native_address: bcef4 +Refc: 1 +=fun +Module: httpd_request_handler +Uniq: 48542841 +Index: 1 +Address: 50e88c +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 56178490 +Index: 9 +Address: 4a420c +Native_address: bcefc +Refc: 1 +=fun +Module: distel +Uniq: 88212576 +Index: 4 +Address: 35bf44 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 79562132 +Index: 29 +Address: 34f368 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 129524917 +Index: 32 +Address: 34f2c0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 54029891 +Index: 23 +Address: 2f9af0 +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 108872092 +Index: 4 +Address: 27d0f0 +Native_address: bcef4 +Refc: 1 +=fun +Module: application_controller +Uniq: 40905124 +Index: 6 +Address: 234ac0 +Native_address: bcef4 +Refc: 1 +=fun +Module: code_server +Uniq: 50124876 +Index: 10 +Address: 2ad760 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 791358 +Index: 48 +Address: 34e7b0 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 18404828 +Index: 24 +Address: 313af4 +Native_address: bced4 +Refc: 1 +=fun +Module: httpd_util +Uniq: 13278653 +Index: 1 +Address: 4b5e48 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 110307423 +Index: 13 +Address: 284a7c +Native_address: bcefc +Refc: 1 +=fun +Module: rpc +Uniq: 99592247 +Index: 0 +Address: 256118 +Native_address: bcf04 +Refc: 1 +=fun +Module: global +Uniq: 99918211 +Index: 2 +Address: 265af4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 71442319 +Index: 27 +Address: 34f510 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 7612785 +Index: 13 +Address: 2fa0fc +Native_address: bce80 +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 56095795 +Index: 15 +Address: 4a38a0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 23626796 +Index: 25 +Address: 313b10 +Native_address: bced4 +Refc: 1 +=fun +Module: file_server +Uniq: 126074974 +Index: 2 +Address: 2a0cac +Native_address: bcef4 +Refc: 1 +=fun +Module: inet_config +Uniq: 104278122 +Index: 1 +Address: 274154 +Native_address: bcefc +Refc: 1 +=fun +Module: sys +Uniq: 90854051 +Index: 0 +Address: 240344 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 113334594 +Index: 2 +Address: 313d5c +Native_address: bced4 +Refc: 1 +=fun +Module: inet_parse +Uniq: 8832142 +Index: 7 +Address: 284e30 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 9159706 +Index: 42 +Address: 34eb54 +Native_address: bceec +Refc: 1 +=fun +Module: inet_db +Uniq: 123946665 +Index: 8 +Address: 26e494 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 3149789 +Index: 1 +Address: 5262d0 +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 48288621 +Index: 11 +Address: 2ffed8 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 8953292 +Index: 20 +Address: 4a4d54 +Native_address: bcee4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 9632158 +Index: 4 +Address: 34ff88 +Native_address: bcefc +Refc: 1 +=fun +Module: net_kernel +Uniq: 31111567 +Index: 7 +Address: 29e8c8 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 85307443 +Index: 10 +Address: 2fa29c +Native_address: bcec4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 104417191 +Index: 7 +Address: 313cd0 +Native_address: bced4 +Refc: 1 +=fun +Module: dict +Uniq: 43625777 +Index: 5 +Address: 354fec +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 92698798 +Index: 3 +Address: 4ab780 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 39074546 +Index: 6 +Address: 2fa54c +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 71451126 +Index: 5 +Address: 234b98 +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 122084387 +Index: 6 +Address: 300038 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 9625924 +Index: 14 +Address: 284a60 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 128777368 +Index: 11 +Address: 313c7c +Native_address: bced4 +Refc: 1 +=fun +Module: webtool +Uniq: 10203723 +Index: 7 +Address: 4ab4f8 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 35032400 +Index: 10 +Address: 313c98 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 17252586 +Index: 34 +Address: 313a14 +Native_address: bced4 +Refc: 1 +=fun +Module: code_server +Uniq: 7177165 +Index: 11 +Address: 2ad734 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 115778175 +Index: 3 +Address: 4a4930 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 96440880 +Index: 51 +Address: 34e590 +Native_address: bcefc +Refc: 1 +=fun +Module: hipe_unified_loader +Uniq: 68275407 +Index: 0 +Address: 2b7340 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 88854488 +Index: 16 +Address: 2f9f04 +Native_address: bcebc +Refc: 1 +=fun +Module: global +Uniq: 26353848 +Index: 13 +Address: 2654e8 +Native_address: bcf04 +Refc: 3 +=fun +Module: global +Uniq: 93414722 +Index: 11 +Address: 265568 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 11194189 +Index: 60 +Address: 34fe0c +Native_address: bcef4 +Refc: 1 +=fun +Module: c +Uniq: 125189992 +Index: 8 +Address: 2fffdc +Native_address: bcefc +Refc: 1 +=fun +Module: dict +Uniq: 112472016 +Index: 2 +Address: 355088 +Native_address: bceec +Refc: 1 +=fun +Module: shell +Uniq: 104426442 +Index: 5 +Address: 2e52e0 +Native_address: bceec +Refc: 1 +=fun +Module: global +Uniq: 17426458 +Index: 0 +Address: 265bc4 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 81191039 +Index: 5 +Address: 2ada48 +Native_address: bcef4 +Refc: 1 +=fun +Module: inet_parse +Uniq: 71765042 +Index: 5 +Address: 284f74 +Native_address: bcefc +Refc: 1 +=fun +Module: init +Uniq: 85855821 +Index: 2 +Address: 1fa298 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 70586122 +Index: 10 +Address: 4a3fe4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 87067911 +Index: 49 +Address: 34e708 +Native_address: bcef4 +Refc: 1 +=fun +Module: distel +Uniq: 63126735 +Index: 1 +Address: 35c0fc +Native_address: bcf04 +Refc: 1 +=fun +Module: c +Uniq: 58270309 +Index: 1 +Address: 3000e4 +Native_address: bcefc +Refc: 1 +=fun +Module: ets +Uniq: 80538457 +Index: 1 +Address: 2bc1a0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 69827241 +Index: 9 +Address: 34fd70 +Native_address: bcef4 +Refc: 1 +=fun +Module: dict +Uniq: 103968752 +Index: 3 +Address: 355054 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 117175573 +Index: 21 +Address: 34f728 +Native_address: bcef4 +Refc: 1 +=fun +Module: shell +Uniq: 57865450 +Index: 2 +Address: 2e537c +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 14705965 +Index: 20 +Address: 313b80 +Native_address: bced4 +Refc: 1 +=fun +Module: webtool +Uniq: 85360931 +Index: 6 +Address: 4ab56c +Native_address: bcefc +Refc: 1 +=fun +Module: kernel_config +Uniq: 41755598 +Index: 0 +Address: 2d9e20 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 7110547 +Index: 37 +Address: 34ef14 +Native_address: bcef4 +Refc: 1 +=fun +Module: application_controller +Uniq: 28091577 +Index: 16 +Address: 234244 +Native_address: bcef4 +Refc: 2 +=fun +Module: code_server +Uniq: 96448152 +Index: 14 +Address: 2ad4e4 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 40177568 +Index: 13 +Address: 4a39a4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 31948320 +Index: 58 +Address: 34dfdc +Native_address: bcef4 +Refc: 1 +=fun +Module: global +Uniq: 54153760 +Index: 7 +Address: 265854 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 60156260 +Index: 3 +Address: 5262b4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 1010616 +Index: 2 +Address: 350064 +Native_address: bcef4 +Refc: 1 +=fun +Module: init +Uniq: 96784459 +Index: 1 +Address: 1fa2b4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 48691771 +Index: 18 +Address: 313bb8 +Native_address: bced4 +Refc: 1 +=fun +Module: global +Uniq: 26895060 +Index: 9 +Address: 265710 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 109625093 +Index: 7 +Address: 2ad8fc +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 59436171 +Index: 1 +Address: 3500dc +Native_address: bcef4 +Refc: 1 +=fun +Module: dict +Uniq: 92768306 +Index: 9 +Address: 354f04 +Native_address: bcefc +Refc: 1 +=fun +Module: global_group +Uniq: 106430008 +Index: 3 +Address: 292b38 +Native_address: bcefc +Refc: 1 +=fun +Module: init +Uniq: 79749196 +Index: 6 +Address: 1fa01c +Native_address: bceec +Refc: 1 +=fun +Module: erl_eval +Uniq: 6014929 +Index: 9 +Address: 2fa324 +Native_address: bceac +Refc: 1 +=fun +Module: application_controller +Uniq: 57051922 +Index: 7 +Address: 234a28 +Native_address: bcef4 +Refc: 1 +=fun +Module: net_kernel +Uniq: 77043468 +Index: 6 +Address: 29e8e4 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 36176045 +Index: 9 +Address: 52620c +Native_address: bcefc +Refc: 1 +=fun +Module: rpc +Uniq: 35862809 +Index: 3 +Address: 255edc +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 113649451 +Index: 4 +Address: 2850a0 +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 67943969 +Index: 5 +Address: 2658f4 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 109003032 +Index: 16 +Address: 5260d0 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 104711447 +Index: 13 +Address: 525f5c +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 107666872 +Index: 9 +Address: 27cfb0 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 89410000 +Index: 10 +Address: 5261f0 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 47356870 +Index: 11 +Address: 284ab4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 17873449 +Index: 56 +Address: 34e1e8 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 8839441 +Index: 33 +Address: 34f25c +Native_address: bcefc +Refc: 1 +=fun +Module: gen_event +Uniq: 82513204 +Index: 2 +Address: 222c18 +Native_address: bcefc +Refc: 1 +=fun +Module: application_master +Uniq: 5973059 +Index: 0 +Address: 24ab7c +Native_address: bcefc +Refc: 1 +=fun +Module: inet_gethost_native +Uniq: 127832132 +Index: 0 +Address: 4b065c +Native_address: bcefc +Refc: 2 +=fun +Module: crashdump_viewer_html +Uniq: 39322658 +Index: 14 +Address: 525f40 +Native_address: bcefc +Refc: 1 +=fun +Module: gen_server +Uniq: 100284021 +Index: 0 +Address: 23d288 +Native_address: bcf04 +Refc: 1 +=fun +Module: inet_parse +Uniq: 17430070 +Index: 12 +Address: 284a98 +Native_address: bcefc +Refc: 1 +=fun +Module: init +Uniq: 97509773 +Index: 3 +Address: 1fa27c +Native_address: bcefc +Refc: 1 +=fun +Module: distel +Uniq: 32364818 +Index: 3 +Address: 35c050 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 58576084 +Index: 32 +Address: 313a4c +Native_address: bced4 +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 38384851 +Index: 14 +Address: 4a3988 +Native_address: bceec +Refc: 1 +=fun +Module: application_controller +Uniq: 14139883 +Index: 4 +Address: 234d78 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 122590256 +Index: 0 +Address: 2fa8b4 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 14705629 +Index: 11 +Address: 2fa22c +Native_address: bcedc +Refc: 1 +=fun +Module: erl_eval +Uniq: 9273769 +Index: 4 +Address: 2fa684 +Native_address: bcee4 +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 87950142 +Index: 11 +Address: 5261d4 +Native_address: bcefc +Refc: 1 +=fun +Module: mod_log +Uniq: 54913678 +Index: 1 +Address: 4fc6b0 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 28370334 +Index: 0 +Address: 26e4b0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 24927227 +Index: 40 +Address: 34ed4c +Native_address: bceec +Refc: 1 +=fun +Module: erl_scan +Uniq: 105437500 +Index: 33 +Address: 313a30 +Native_address: bced4 +Refc: 1 +=fun +Module: application_controller +Uniq: 10921695 +Index: 1 +Address: 234eac +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 112431564 +Index: 55 +Address: 34e22c +Native_address: bceec +Refc: 1 +=fun +Module: webtool +Uniq: 129460863 +Index: 5 +Address: 4ab5c4 +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 89001648 +Index: 3 +Address: 27d2ec +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 36199507 +Index: 8 +Address: 27cfe4 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 35620771 +Index: 2 +Address: 5262ec +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 83214871 +Index: 18 +Address: 2f9e34 +Native_address: bceec +Refc: 1 +=fun +Module: code_server +Uniq: 122455383 +Index: 1 +Address: 2adc0c +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_lint +Uniq: 22389488 +Index: 31 +Address: 34f1b8 +Native_address: bceec +Refc: 1 +=fun +Module: erl_eval +Uniq: 41869059 +Index: 12 +Address: 2fa1d4 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 18130505 +Index: 45 +Address: 34e904 +Native_address: bcefc +Refc: 1 +=fun +Module: hipe_unified_loader +Uniq: 107414126 +Index: 1 +Address: 2b706c +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 116638945 +Index: 28 +Address: 2f98f8 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 48465762 +Index: 9 +Address: 2348c8 +Native_address: bcefc +Refc: 1 +=fun +Module: httpd_request_handler +Uniq: 87633852 +Index: 0 +Address: 50e97c +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 28213098 +Index: 8 +Address: 4ab42c +Native_address: bcefc +Refc: 1 +=fun +Module: gen_event +Uniq: 123630574 +Index: 4 +Address: 222b58 +Native_address: bcefc +Refc: 1 +=fun +Module: dict +Uniq: 127425508 +Index: 13 +Address: 354eb4 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 95048118 +Index: 16 +Address: 2ad46c +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 108661978 +Index: 19 +Address: 34f75c +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 21272619 +Index: 13 +Address: 34fad8 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 29943747 +Index: 17 +Address: 313bf0 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 120240397 +Index: 4 +Address: 313d94 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 124060676 +Index: 0 +Address: 350124 +Native_address: bcef4 +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 100975346 +Index: 6 +Address: 526260 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 61421476 +Index: 4 +Address: 2ada9c +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 45197232 +Index: 7 +Address: 34fe5c +Native_address: bcef4 +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 3151900 +Index: 15 +Address: 525f24 +Native_address: bcefc +Refc: 1 +=fun +Module: httpd_util +Uniq: 77509245 +Index: 2 +Address: 4b5e2c +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 94110229 +Index: 8 +Address: 2ad7e4 +Native_address: bcef4 +Refc: 3 +=fun +Module: rpc +Uniq: 101217130 +Index: 1 +Address: 2560c4 +Native_address: bcf04 +Refc: 1 +=fun +Module: lists +Uniq: 103647452 +Index: 0 +Address: 244b7c +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 37841211 +Index: 9 +Address: 2ad77c +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 40109251 +Index: 54 +Address: 34e2b4 +Native_address: bcef4 +Refc: 1 +=fun +Module: init +Uniq: 98012300 +Index: 0 +Address: 1fa2d0 +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 73604759 +Index: 10 +Address: 4ab270 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 12042434 +Index: 1 +Address: 313d40 +Native_address: bced4 +Refc: 1 +=fun +Module: shell +Uniq: 127137775 +Index: 4 +Address: 2e531c +Native_address: bcf04 +Refc: 1 +=fun +Module: inet +Uniq: 45498037 +Index: 12 +Address: 27cec0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 122441107 +Index: 34 +Address: 34f1d4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 70933889 +Index: 46 +Address: 34e8d0 +Native_address: bcef4 +Refc: 1 +=fun +Module: inet +Uniq: 69850797 +Index: 2 +Address: 27d308 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 103965539 +Index: 13 +Address: 234684 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 29979659 +Index: 30 +Address: 313a84 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 17148721 +Index: 20 +Address: 34f778 +Native_address: bcefc +Refc: 1 +=fun +Module: httpd_response +Uniq: 100673049 +Index: 0 +Address: 5165dc +Native_address: bcefc +Refc: 1 +=fun +Module: inet_gethost_native +Uniq: 10508176 +Index: 1 +Address: 4b04dc +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 32476064 +Index: 57 +Address: 34e1c4 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 74835078 +Index: 9 +Address: 313cec +Native_address: bced4 +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 60689814 +Index: 19 +Address: 4a3b78 +Native_address: bceec +Refc: 1 +=fun +Module: erl_lint +Uniq: 39269715 +Index: 5 +Address: 34ff14 +Native_address: bcef4 +Refc: 1 +=fun +Module: shell +Uniq: 112923172 +Index: 0 +Address: 2e5404 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_eval +Uniq: 43010824 +Index: 14 +Address: 2fa03c +Native_address: bce8c +Refc: 1 +=fun +Module: global +Uniq: 82495254 +Index: 3 +Address: 265ac8 +Native_address: bcefc +Refc: 1 +=fun +Module: shell +Uniq: 48568081 +Index: 8 +Address: 2e5220 +Native_address: bcefc +Refc: 1 +=fun +Module: init +Uniq: 77236637 +Index: 7 +Address: 1fa000 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_eval +Uniq: 109386574 +Index: 1 +Address: 2fa804 +Native_address: bce9c +Refc: 1 +=fun +Module: erl_lint +Uniq: 42613220 +Index: 14 +Address: 34f980 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 67093144 +Index: 23 +Address: 313b64 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 86833790 +Index: 11 +Address: 34fbe8 +Native_address: bcefc +Refc: 1 +=fun +Module: net_kernel +Uniq: 6344855 +Index: 1 +Address: 29eabc +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 5149749 +Index: 35 +Address: 34f220 +Native_address: bcefc +Refc: 1 +=fun +Module: init +Uniq: 93451769 +Index: 5 +Address: 1fa120 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 117428568 +Index: 11 +Address: 234758 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 15225890 +Index: 4 +Address: 526298 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 120760477 +Index: 2 +Address: 234cdc +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 88561919 +Index: 3 +Address: 3000ac +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 108931174 +Index: 8 +Address: 313cb4 +Native_address: bced4 +Refc: 1 +=fun +Module: rpc +Uniq: 122901192 +Index: 4 +Address: 255e44 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_lint +Uniq: 32985930 +Index: 10 +Address: 34fc40 +Native_address: bcef4 +Refc: 1 +=fun +Module: global_group +Uniq: 97968498 +Index: 1 +Address: 292b7c +Native_address: bcef4 +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 45671671 +Index: 18 +Address: 4a32d0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 117968056 +Index: 3 +Address: 2fa6ec +Native_address: bcecc +Refc: 1 +=fun +Module: init +Uniq: 108717591 +Index: 4 +Address: 1fa194 +Native_address: bcf04 +Refc: 1 +=fun +Module: supervisor +Uniq: 15091954 +Index: 2 +Address: 2526dc +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 65707495 +Index: 6 +Address: 2658a4 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 34473969 +Index: 17 +Address: 2ad450 +Native_address: bcef4 +Refc: 2 +=fun +Module: crashdump_viewer_html +Uniq: 124296602 +Index: 7 +Address: 526244 +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 23074707 +Index: 15 +Address: 265460 +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 25972856 +Index: 10 +Address: 27cf74 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 43110452 +Index: 24 +Address: 2f9ad4 +Native_address: bceec +Refc: 1 +=fun +Module: code_server +Uniq: 106445918 +Index: 13 +Address: 2ad660 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 116071286 +Index: 12 +Address: 5261b8 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 130814477 +Index: 8 +Address: 284cfc +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 121017037 +Index: 39 +Address: 34ed80 +Native_address: bcef4 +Refc: 1 +=fun +Module: ets +Uniq: 104895267 +Index: 0 +Address: 2bc1bc +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 104682437 +Index: 11 +Address: 4a3de0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 70248777 +Index: 30 +Address: 34f30c +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 13274975 +Index: 5 +Address: 300074 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 98442771 +Index: 53 +Address: 34e2d0 +Native_address: bceec +Refc: 1 +=fun +Module: erl_eval +Uniq: 69829006 +Index: 7 +Address: 2fa47c +Native_address: bce80 +Refc: 1 +=fun +Module: old_file_server +Uniq: 36444943 +Index: 1 +Address: 2a1a80 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_lint +Uniq: 58719455 +Index: 26 +Address: 34f5f0 +Native_address: bcefc +Refc: 1 +=fun +Module: timer +Uniq: 42505885 +Index: 0 +Address: 4cd62c +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 54682479 +Index: 20 +Address: 2f9d08 +Native_address: bcf04 +Refc: 1 +=fun +Module: gen_event +Uniq: 86070332 +Index: 1 +Address: 222d7c +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 54728136 +Index: 9 +Address: 2fff68 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 16474219 +Index: 3 +Address: 234c60 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 108831556 +Index: 10 +Address: 234810 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 72053761 +Index: 16 +Address: 34f8ec +Native_address: bcef4 +Refc: 1 +=fun +Module: net_kernel +Uniq: 65127616 +Index: 2 +Address: 29ea04 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 126167637 +Index: 14 +Address: 234640 +Native_address: bcef4 +Refc: 1 +=fun +Module: inet_parse +Uniq: 113704917 +Index: 0 +Address: 285788 +Native_address: bcefc +Refc: 1 +=fun +Module: mod_disk_log +Uniq: 75279647 +Index: 1 +Address: 500100 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 119218247 +Index: 5 +Address: 26df68 +Native_address: bcef4 +Refc: 1 +=fun +Module: httpd_util +Uniq: 85690044 +Index: 4 +Address: 4b5d6c +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 53075592 +Index: 1 +Address: 26e16c +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 39490182 +Index: 2 +Address: 3000c8 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 75189006 +Index: 12 +Address: 234714 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 14980808 +Index: 43 +Address: 34eb38 +Native_address: bceec +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 16463468 +Index: 4 +Address: 4a4914 +Native_address: bcee4 +Refc: 1 +=fun +Module: dict +Uniq: 99965326 +Index: 4 +Address: 355020 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 36900786 +Index: 6 +Address: 284f3c +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 45447147 +Index: 18 +Address: 34f794 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 32353825 +Index: 6 +Address: 34fe78 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 134052338 +Index: 8 +Address: 34fdc0 +Native_address: bceec +Refc: 1 +=fun +Module: application_master +Uniq: 23840924 +Index: 1 +Address: 24aae0 +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 108282500 +Index: 1 +Address: 4ab918 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_prim_loader +Uniq: 31081110 +Index: 0 +Address: 210c68 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_eval +Uniq: 54275742 +Index: 26 +Address: 2f9a4c +Native_address: bcef4 +Refc: 1 +=fun +Module: shell +Uniq: 45083091 +Index: 3 +Address: 2e5350 +Native_address: bcf04 +Refc: 3 +=proc_stack:<0.0.0> +3a48bc:SReturn addr 0x156F90 (<terminate process normally>) +y0:H371264 +=proc_heap:<0.0.0> +371264:t9:A5:state,H3710D8,N,N,H3710F4,P<0.1.0>,H37128C,H3710FC,N +3710FC:t2:H371138,H371140 +371140:lI80|H371194 +371194:lI49|H3711E0 +3711E0:lI48|H371204 +371204:lI66|N +371138:lI79|H37118C +37118C:lI84|H3711D8 +3711D8:lI80|H3711FC +3711FC:lI32|H37120C +37120C:lI32|H371214 +371214:lI65|H37121C +37121C:lI80|H371224 +371224:lI78|H37122C +37122C:lI32|H371234 +371234:lI49|H37123C +37123C:lI56|H371244 +371244:lI49|H37124C +37124C:lI32|H371254 +371254:lI48|H37125C +37125C:lI49|N +37128C:t2:A7:started,A7:started +3710F4:lH371124|H371130 +371124:t2:A16:application_controller,P<0.5.0> +371130:lH371178|H371184 +371178:t2:AC:error_logger,P<0.4.0> +371184:lH3711CC|N +3711CC:t2:AF:erl_prim_loader,P<0.2.0> +3710D8:lH3710E0|H3710EC +3710E0:t2:A5:-root,H371108 +371108:lH371148|N +371148:Yh13:2F636C656172636173652F6F74702F65727473 +3710EC:lH371110|H37111C +371110:t2:A9:-progname,H371164 +371164:lH37119C|N +37119C:Yh1D:2F636C656172636173652F6F74702F657274732F62696E2F6365726C20 +37111C:lH37116C|N +37116C:t2:A5:-home,H3711C4 +3711C4:lH3711E8|N +3711E8:YhA:2F686F6D652F73697269 +=proc_stack:<0.2.0> +38eca8:SReturn addr 0x156F90 (<terminate process normally>) +y0:H367D20 +y1:P<0.1.0> +y2:H367D28 +y3:A8:infinity +=proc_heap:<0.2.0> +367D20:lH367D48|H367D50 +367D48:lI47|H367D58 +367D58:lI99|H367D68 +367D68:lI108|H367D78 +367D78:lI101|H367D88 +367D88:lI97|H367D98 +367D98:lI114|H367DA8 +367DA8:lI99|H367DB8 +367DB8:lI97|H367DC8 +367DC8:lI115|H367DD8 +367DD8:lI101|H367DE8 +367DE8:lI47|H367DF8 +367DF8:lI111|H367E08 +367E08:lI116|H367E18 +367E18:lI112|H367E28 +367E28:lI47|H367E38 +367E38:lI101|H367E48 +367E48:lI114|H367E58 +367E58:lI116|H367E68 +367E68:lI115|H367E78 +367E78:lI47|H367E88 +367E88:lI108|H367E98 +367E98:lI105|H367EA8 +367EA8:lI98|H367EB8 +367EB8:lI47|H367EC8 +367EC8:lI107|H367ED8 +367ED8:lI101|H367EE8 +367EE8:lI114|H367EF8 +367EF8:lI110|H367F08 +367F08:lI101|H367F18 +367F18:lI108|H367F28 +367F28:lI47|H367F38 +367F38:lI101|H367F48 +367F48:lI98|H367F58 +367F58:lI105|H367F68 +367F68:lI110|N +367D50:lH367D60|N +367D60:lI47|H367D70 +367D70:lI99|H367D80 +367D80:lI108|H367D90 +367D90:lI101|H367DA0 +367DA0:lI97|H367DB0 +367DB0:lI114|H367DC0 +367DC0:lI99|H367DD0 +367DD0:lI97|H367DE0 +367DE0:lI115|H367DF0 +367DF0:lI101|H367E00 +367E00:lI47|H367E10 +367E10:lI111|H367E20 +367E20:lI116|H367E30 +367E30:lI112|H367E40 +367E40:lI47|H367E50 +367E50:lI101|H367E60 +367E60:lI114|H367E70 +367E70:lI116|H367E80 +367E80:lI115|H367E90 +367E90:lI47|H367EA0 +367EA0:lI108|H367EB0 +367EB0:lI105|H367EC0 +367EC0:lI98|H367ED0 +367ED0:lI47|H367EE0 +367EE0:lI115|H367EF0 +367EF0:lI116|H367F00 +367F00:lI100|H367F10 +367F10:lI108|H367F20 +367F20:lI105|H367F30 +367F30:lI98|H367F40 +367F40:lI47|H367F50 +367F50:lI101|H367F60 +367F60:lI98|H367F70 +367F70:lI105|H367F78 +367F78:lI110|N +367D28:t7:A5:state,A5:efile,N,A4:none,p<0.2>,A8:infinity,A5:false +=proc_dictionary:<0.4.0> +H3AC588 +H3AC594 +=proc_stack:<0.4.0> +3b2f14:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:H3B21E8 +y2:AC:error_logger +y3:P<0.1.0> +3b2f28:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H3AC5A8 +=proc_heap:<0.4.0> +3B21E8:lH3B2144|H3B21E0 +3B2144:t5:A7:handler,AC:error_logger,A5:false,N,A5:false +3B21E0:lH3B21BC|N +3B21BC:t5:A7:handler,A12:error_logger_tty_h,A5:false,H3AC610,A5:false +3AC610:t2:P<0.21.0>,AC:error_logger +3AC5A8:lA9:gen_event|H3AC5E8 +3AC5E8:lP<0.1.0>|H3AC608 +3AC608:lP<0.1.0>|H3AC61C +3AC61C:lH3AC624|H3AC630 +3AC624:t2:A5:local,AC:error_logger +3AC630:lN|H3AC638 +3AC638:lN|H3AC640 +3AC640:lN|N +3AC588:t2:AD:$initial_call,H3AC5B0 +3AC5B0:t3:A3:gen,A7:init_it,H3AC5A8 +3AC594:t2:AA:$ancestors,H3AC5C0 +3AC5C0:lP<0.1.0>|N +=proc_dictionary:<0.5.0> +H372E4C +H372E58 +=proc_stack:<0.5.0> +374704:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A16:application_controller +y3:H3739F4 +y4:A16:application_controller +y5:P<0.1.0> +374720:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H372ED0 +=proc_heap:<0.5.0> +3739F4:t9:A5:state,N,N,N,H373914,N,H373928,N,N +373928:lH37391C|H372F54 +37391C:t2:A6:stdlib,A9:permanent +372F54:lH372F90|N +372F90:t2:A6:kernel,A9:permanent +373914:lH373908|H372F4C +373908:t2:A6:stdlib,A9:undefined +372F4C:lH372F84|N +372F84:t2:A6:kernel,P<0.7.0> +372ED0:lAA:gen_server|H372F5C +372F5C:lP<0.1.0>|H372F9C +372F9C:lP<0.1.0>|H372FC4 +372FC4:lH372FEC|H372FF8 +372FEC:t2:A5:local,A16:application_controller +372FF8:lA16:application_controller|H373018 +373018:lH373038|H373048 +373038:t3:AB:application,A6:kernel,H373060 +373060:lH373078|H373084 +373078:t2:AB:description,H37309C +37309C:lI69|H3730C8 +3730C8:lI82|H3730FC +3730FC:lI84|H373130 +373130:lI83|H37316C +37316C:lI32|H3731A8 +3731A8:lI32|H3731E4 +3731E4:lI67|H373220 +373220:lI88|H37325C +37325C:lI67|H37329C +37329C:lI32|H3732D0 +3732D0:lI49|H3732FC +3732FC:lI51|H373328 +373328:lI56|H373348 +373348:lI32|H373368 +373368:lI49|H373388 +373388:lI48|N +373084:lH3730A4|H3730B0 +3730A4:t2:A3:vsn,H3730D0 +3730D0:lI50|H373104 +373104:lI46|H373138 +373138:lI57|N +3730B0:lH3730D8|H3730E4 +3730D8:t2:A2:id,N +3730E4:lH37310C|H373118 +37310C:t2:A7:modules,H373140 +373140:lAB:application|H373174 +373174:lA16:application_controller|H3731B0 +3731B0:lA12:application_master|H3731EC +3731EC:lA13:application_starter|H373228 +373228:lA4:auth|H373264 +373264:lA4:code|H3732A4 +3732A4:lA8:code_aux|H3732D8 +3732D8:lA8:packages|H373304 +373304:lAB:code_server|H373330 +373330:lA9:dist_util|H373350 +373350:lAF:erl_boot_server|H373370 +373370:lA10:erl_distribution|H373390 +373390:lAF:erl_prim_loader|H3733A8 +3733A8:lA9:erl_reply|H3733C0 +3733C0:lA6:erlang|H3733D8 +3733D8:lAD:error_handler|H3733F0 +3733F0:lAC:error_logger|H373408 +373408:lA4:file|H373420 +373420:lAB:file_server|H373438 +373438:lAF:old_file_server|H373450 +373450:lAE:file_io_server|H373468 +373468:lA9:prim_file|H373480 +373480:lA6:global|H373498 +373498:lAC:global_group|H3734B0 +3734B0:lAD:global_search|H3734C8 +3734C8:lA5:group|H3734E0 +3734E0:lA5:heart|H3734F8 +3734F8:lA13:hipe_unified_loader|H373510 +373510:lA11:hipe_sparc_loader|H373520 +373520:lAF:hipe_x86_loader|H373530 +373530:lA9:inet6_tcp|H373540 +373540:lAE:inet6_tcp_dist|H373550 +373550:lA9:inet6_udp|H373560 +373560:lAB:inet_config|H373570 +373570:lAA:inet_hosts|H373580 +373580:lA13:inet_gethost_native|H373590 +373590:lAD:inet_tcp_dist|H3735A0 +3735A0:lA4:init|H3735B0 +3735B0:lA6:kernel|H3735C0 +3735C0:lAD:kernel_config|H3735D0 +3735D0:lA3:net|H3735E0 +3735E0:lA7:net_adm|H3735F0 +3735F0:lAA:net_kernel|H373600 +373600:lA2:os|H373610 +373610:lA8:ram_file|H373620 +373620:lA3:rpc|H373630 +373630:lA4:user|H373640 +373640:lA8:user_drv|H373650 +373650:lA8:user_sup|H373660 +373660:lA8:disk_log|H373670 +373670:lAA:disk_log_1|H373680 +373680:lAF:disk_log_server|H373690 +373690:lAC:disk_log_sup|H3736A0 +3736A0:lA7:dist_ac|H3736B0 +3736B0:lA8:erl_ddll|H3736C0 +3736C0:lA8:erl_epmd|H3736D0 +3736D0:lAA:erts_debug|H3736E0 +3736E0:lA7:gen_tcp|H3736F0 +3736F0:lA7:gen_udp|H373700 +373700:lA9:prim_inet|H373708 +373708:lA4:inet|H373710 +373710:lA7:inet_db|H373718 +373718:lA8:inet_dns|H373720 +373720:lAA:inet_parse|H373728 +373728:lA8:inet_res|H373730 +373730:lA8:inet_tcp|H373738 +373738:lA8:inet_udp|H373740 +373740:lA3:pg2|H373748 +373748:lA9:seq_trace|H373750 +373750:lA6:socks5|H373758 +373758:lAB:socks5_auth|H373760 +373760:lAA:socks5_tcp|H373768 +373768:lAA:socks5_udp|H373770 +373770:lAF:wrap_log_reader|H373778 +373778:lA4:zlib|H373780 +373780:lA9:otp_ring0|N +373118:lH373148|H373154 +373148:t2:AA:registered,H37317C +37317C:lA16:application_controller|H3731B8 +3731B8:lA9:erl_reply|H3731F4 +3731F4:lA4:auth|H373230 +373230:lAB:boot_server|H37326C +37326C:lAB:code_server|H3732AC +3732AC:lAF:disk_log_server|H3732E0 +3732E0:lAC:disk_log_sup|H37330C +37330C:lAF:erl_prim_loader|H373338 +373338:lAC:error_logger|H373358 +373358:lAB:file_server|H373378 +373378:lAD:file_server_2|H373398 +373398:lAF:fixtable_server|H3733B0 +3733B0:lAC:global_group|H3733C8 +3733C8:lA12:global_name_server|H3733E0 +3733E0:lA5:heart|H3733F8 +3733F8:lA4:init|H373410 +373410:lAD:kernel_config|H373428 +373428:lAA:kernel_sup|H373440 +373440:lAA:net_kernel|H373458 +373458:lA7:net_sup|H373470 +373470:lA3:rex|H373488 +373488:lA4:user|H3734A0 +3734A0:lA9:os_server|H3734B8 +3734B8:lAB:ddll_server|H3734D0 +3734D0:lA8:erl_epmd|H3734E8 +3734E8:lA7:inet_db|H373500 +373500:lA3:pg2|N +373154:lH373184|H373190 +373184:t2:AC:applications,N +373190:lH3731C0|H3731CC +3731C0:t2:A15:included_applications,N +3731CC:lH3731FC|H373208 +3731FC:t2:A3:env,H373238 +373238:lH373274|N +373274:t2:AC:error_logger,A3:tty +373208:lH373240|H37324C +373240:t2:AC:start_phases,A9:undefined +37324C:lH373280|H37328C +373280:t2:A4:maxT,A8:infinity +37328C:lH3732B4|H3732C0 +3732B4:t2:A4:maxP,A8:infinity +3732C0:lH3732E8|N +3732E8:t2:A3:mod,H373314 +373314:t2:A6:kernel,N +373048:lN|N +372E4C:t2:AD:$initial_call,H372EE4 +372EE4:t3:A3:gen,A7:init_it,H372ED0 +372E58:t2:AA:$ancestors,H372EF4 +372EF4:lP<0.1.0>|N +=proc_dictionary:<0.7.0> +H369B78 +H369B5C +=proc_stack:<0.7.0> +369d64:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:H369C2C +y1:P<0.5.0> +369d70:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A12:application_master +y2:A4:init +y3:H369B2C +=proc_heap:<0.7.0> +369C2C:t6:A5:state,P<0.8.0>,H3697B0,N,I0,P<0.0.0> +3697B0:t9:A9:appl_data,A6:kernel,H369B14,A9:undefined,H3697D8,H369A3C,N,A8:infinity,A8:infinity +369A3C:lAB:application|H369A34 +369A34:lA16:application_controller|H369A2C +369A2C:lA12:application_master|H369A24 +369A24:lA13:application_starter|H369A1C +369A1C:lA4:auth|H369A14 +369A14:lA4:code|H369A0C +369A0C:lA8:code_aux|H369A04 +369A04:lA8:packages|H3699FC +3699FC:lAB:code_server|H3699F4 +3699F4:lA9:dist_util|H3699EC +3699EC:lAF:erl_boot_server|H3699E4 +3699E4:lA10:erl_distribution|H3699DC +3699DC:lAF:erl_prim_loader|H3699D4 +3699D4:lA9:erl_reply|H3699CC +3699CC:lA6:erlang|H3699C4 +3699C4:lAD:error_handler|H3699BC +3699BC:lAC:error_logger|H3699B4 +3699B4:lA4:file|H3699AC +3699AC:lAB:file_server|H3699A4 +3699A4:lAF:old_file_server|H36999C +36999C:lAE:file_io_server|H369994 +369994:lA9:prim_file|H36998C +36998C:lA6:global|H369984 +369984:lAC:global_group|H36997C +36997C:lAD:global_search|H369974 +369974:lA5:group|H36996C +36996C:lA5:heart|H369964 +369964:lA13:hipe_unified_loader|H36995C +36995C:lA11:hipe_sparc_loader|H369954 +369954:lAF:hipe_x86_loader|H36994C +36994C:lA9:inet6_tcp|H369944 +369944:lAE:inet6_tcp_dist|H36993C +36993C:lA9:inet6_udp|H369934 +369934:lAB:inet_config|H36992C +36992C:lAA:inet_hosts|H369924 +369924:lA13:inet_gethost_native|H36991C +36991C:lAD:inet_tcp_dist|H369914 +369914:lA4:init|H36990C +36990C:lA6:kernel|H369904 +369904:lAD:kernel_config|H3698FC +3698FC:lA3:net|H3698F4 +3698F4:lA7:net_adm|H3698EC +3698EC:lAA:net_kernel|H3698E4 +3698E4:lA2:os|H3698DC +3698DC:lA8:ram_file|H3698D4 +3698D4:lA3:rpc|H3698CC +3698CC:lA4:user|H3698C4 +3698C4:lA8:user_drv|H3698BC +3698BC:lA8:user_sup|H3698B4 +3698B4:lA8:disk_log|H3698AC +3698AC:lAA:disk_log_1|H3698A4 +3698A4:lAF:disk_log_server|H36989C +36989C:lAC:disk_log_sup|H369894 +369894:lA7:dist_ac|H36988C +36988C:lA8:erl_ddll|H369884 +369884:lA8:erl_epmd|H36987C +36987C:lAA:erts_debug|H369874 +369874:lA7:gen_tcp|H36986C +36986C:lA7:gen_udp|H369864 +369864:lA9:prim_inet|H36985C +36985C:lA4:inet|H369854 +369854:lA7:inet_db|H36984C +36984C:lA8:inet_dns|H369844 +369844:lAA:inet_parse|H36983C +36983C:lA8:inet_res|H369834 +369834:lA8:inet_tcp|H36982C +36982C:lA8:inet_udp|H369824 +369824:lA3:pg2|H36981C +36981C:lA9:seq_trace|H369814 +369814:lA6:socks5|H36980C +36980C:lAB:socks5_auth|H369804 +369804:lAA:socks5_tcp|H3697FC +3697FC:lAA:socks5_udp|H3697F4 +3697F4:lAF:wrap_log_reader|H3697EC +3697EC:lA4:zlib|H3697E4 +3697E4:lA9:otp_ring0|N +3697D8:t2:A6:kernel,N +369B14:lA16:application_controller|H369B0C +369B0C:lA9:erl_reply|H369B04 +369B04:lA4:auth|H369AFC +369AFC:lAB:boot_server|H369AF4 +369AF4:lAB:code_server|H369AEC +369AEC:lAF:disk_log_server|H369AE4 +369AE4:lAC:disk_log_sup|H369ADC +369ADC:lAF:erl_prim_loader|H369AD4 +369AD4:lAC:error_logger|H369ACC +369ACC:lAB:file_server|H369AC4 +369AC4:lAD:file_server_2|H369ABC +369ABC:lAF:fixtable_server|H369AB4 +369AB4:lAC:global_group|H369AAC +369AAC:lA12:global_name_server|H369AA4 +369AA4:lA5:heart|H369A9C +369A9C:lA4:init|H369A94 +369A94:lAD:kernel_config|H369A8C +369A8C:lAA:kernel_sup|H369A84 +369A84:lAA:net_kernel|H369A7C +369A7C:lA7:net_sup|H369A74 +369A74:lA3:rex|H369A6C +369A6C:lA4:user|H369A64 +369A64:lA9:os_server|H369A5C +369A5C:lAB:ddll_server|H369A54 +369A54:lA8:erl_epmd|H369A4C +369A4C:lA7:inet_db|H369A44 +369A44:lA3:pg2|N +369B2C:lP<0.5.0>|H369B24 +369B24:lP<0.6.0>|H3697A8 +3697A8:lH3697B0|H369B1C +369B1C:lA6:normal|N +369B78:t2:AD:$initial_call,H369B68 +369B68:t3:A12:application_master,A4:init,H369B2C +369B5C:t2:AA:$ancestors,H369B54 +369B54:lP<0.6.0>|N +=proc_stack:<0.8.0> +384ec0:SReturn addr 0x156F90 (<terminate process normally>) +y0:H384BDC +y1:A6:kernel +y2:P<0.9.0> +y3:P<0.7.0> +=proc_heap:<0.8.0> +384BDC:t2:A5:state,A3:tty +=proc_dictionary:<0.9.0> +H376850 +H37685C +=proc_stack:<0.9.0> +36bde8:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AA:supervisor +y3:H36B8E8 +y4:AA:kernel_sup +y5:P<0.8.0> +36be04:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H3768D4 +=proc_heap:<0.9.0> +36B8E8:tA:A5:state,H376868,AB:one_for_all,H36B8D4,N,I0,I1,N,A6:kernel,N +36B8D4:lH36B8B0|H36B6E8 +36B8B0:t8:A5:child,P<0.24.0>,AF:kernel_safe_sup,H376BF0,A9:permanent,A8:infinity,AA:supervisor,H376C00 +376C00:lA6:kernel|N +376BF0:t3:AA:supervisor,AA:start_link,H376C08 +376C08:lH376C10|H376C1C +376C10:t2:A5:local,AF:kernel_safe_sup +376C1C:lA6:kernel|H376C24 +376C24:lA4:safe|N +36B6E8:lH36B6C4|H36B490 +36B6C4:t8:A5:child,P<0.23.0>,AD:kernel_config,H376BB4,A9:permanent,I2000,A6:worker,H376BC4 +376BC4:lAD:kernel_config|N +376BB4:t3:AD:kernel_config,AA:start_link,N +36B490:lH36B498|H36B4BC +36B498:t8:A5:child,P<0.19.0>,A4:user,H376B70,A9:temporary,I2000,AA:supervisor,H376B80 +376B80:lA8:user_sup|N +376B70:t3:A8:user_sup,A5:start,N +36B4BC:lH36B4C4|H376CB0 +36B4C4:t8:A5:child,P<0.18.0>,AB:code_server,H376B0C,A9:permanent,I2000,A6:worker,H376B1C +376B1C:lA4:code|N +376B0C:t3:A4:code,AA:start_link,N +376CB0:lH376CB8|H376CDC +376CB8:t8:A5:child,P<0.17.0>,AB:file_server,H376AB8,A9:permanent,I2000,A6:worker,H376AC8 +376AC8:lAF:old_file_server|N +376AB8:t3:AF:old_file_server,AA:start_link,N +376CDC:lH376CE4|H376C2C +376CE4:t8:A5:child,P<0.16.0>,AD:file_server_2,H376A58,A9:permanent,I2000,A6:worker,H376A68 +376A68:lA4:file|H376AB0 +376AB0:lAB:file_server|H376B04 +376B04:lAE:file_io_server|H376B68 +376B68:lA9:prim_file|N +376A58:t3:AB:file_server,AA:start_link,N +376C2C:lH376C34|H376C58 +376C34:t8:A5:child,P<0.15.0>,AC:global_group,H3769F4,A9:permanent,I2000,A6:worker,H376A04 +376A04:lAC:global_group|N +3769F4:t3:AC:global_group,AA:start_link,N +376C58:lH376C60|H376C84 +376C60:t8:A5:child,A9:undefined,A7:net_sup,H37696C,A9:permanent,A8:infinity,AA:supervisor,H37697C +37697C:lA10:erl_distribution|N +37696C:t3:A10:erl_distribution,AA:start_link,N +376C84:lH376C8C|H3768A0 +376C8C:t8:A5:child,P<0.14.0>,A7:inet_db,H3768F4,A9:permanent,I2000,A6:worker,H376904 +376904:lA7:inet_db|N +3768F4:t3:A7:inet_db,AA:start_link,N +3768A0:lH376938|H37695C +376938:t8:A5:child,P<0.11.0>,A12:global_name_server,H3769B0,A9:permanent,I2000,A6:worker,H3769C0 +3769C0:lA6:global|N +3769B0:t3:A6:global,AA:start_link,N +37695C:lH3769C8|N +3769C8:t8:A5:child,P<0.10.0>,A3:rex,H376A38,A9:permanent,I2000,A6:worker,H376A48 +376A48:lA3:rpc|N +376A38:t3:A3:rpc,AA:start_link,N +376868:t2:A5:local,AA:kernel_sup +3768D4:lAA:gen_server|H376964 +376964:lP<0.8.0>|H3769EC +3769EC:lP<0.8.0>|H376A50 +376A50:lH376A9C|H376AA8 +376A9C:t2:A5:local,AA:kernel_sup +376AA8:lAA:supervisor|H376AFC +376AFC:lH376B50|H376B60 +376B50:t3:H376868,A6:kernel,N +376B60:lN|N +376850:t2:AD:$initial_call,H3768DC +3768DC:t3:A3:gen,A7:init_it,H3768D4 +37685C:t2:AA:$ancestors,H3768EC +3768EC:lP<0.8.0>|N +=proc_dictionary:<0.10.0> +H367A10 +H3679F4 +=proc_stack:<0.10.0> +367cec:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A3:rpc +y3:H367AA8 +y4:A3:rex +y5:P<0.9.0> +367d08:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H3679C4 +=proc_heap:<0.10.0> +367AA8:t2:I0,A3:nil +3679C4:lAA:gen_server|H3679BC +3679BC:lP<0.9.0>|H3679B4 +3679B4:lP<0.9.0>|H367988 +367988:lH367990|H3679AC +367990:t2:A5:local,A3:rex +3679AC:lA3:rpc|H3679A4 +3679A4:lN|H36799C +36799C:lN|N +367A10:t2:AD:$initial_call,H367A00 +367A00:t3:A3:gen,A7:init_it,H3679C4 +3679F4:t2:AA:$ancestors,H3679EC +3679EC:lAA:kernel_sup|H3679CC +3679CC:lP<0.8.0>|N +=proc_dictionary:<0.11.0> +H36ADD8 +H36ADBC +=proc_stack:<0.11.0> +36b0b4:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A6:global +y3:H36AF0C +y4:A12:global_name_server +y5:P<0.9.0> +36b0d0:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H36AD8C +=proc_heap:<0.11.0> +36AF0C:t9:A5:state,A4:true,N,N,N,N,AD:nonode@nohost,P<0.12.0>,P<0.13.0> +36AD8C:lAA:gen_server|H36AD84 +36AD84:lP<0.9.0>|H36AD7C +36AD7C:lP<0.9.0>|H36AD50 +36AD50:lH36AD58|H36AD74 +36AD58:t2:A5:local,A12:global_name_server +36AD74:lA6:global|H36AD6C +36AD6C:lN|H36AD64 +36AD64:lN|N +36ADD8:t2:AD:$initial_call,H36ADC8 +36ADC8:t3:A3:gen,A7:init_it,H36AD8C +36ADBC:t2:AA:$ancestors,H36ADB4 +36ADB4:lAA:kernel_sup|H36AD94 +36AD94:lP<0.8.0>|N +=proc_stack:<0.12.0> +36921c:SReturn addr 0x261184 (global:init_the_locker/1 + 112) +y0:N +y1:N +y2:N +y3:N +y4:N +y5:N +y6:A8:infinity +y7:H368EB0 +y8:P<0.11.0> +369244:SReturn addr 0x156F90 (<terminate process normally>) +y0:N +=proc_heap:<0.12.0> +368EB0:t3:A5:multi,A9:undefined,N +=proc_stack:<0.13.0> +3695d0:SReturn addr 0x2651AC (global:loop_the_deleter/1 + 36) +y0:A8:infinity +y1:N +y2:P<0.11.0> +3695e0:SReturn addr 0x2654F8 (global:'-start_the_deleter/1-fun-0-'/1 + 20) +y0:N +y1:N +y2:P<0.11.0> +3695f0:SReturn addr 0x156F90 (<terminate process normally>) +=proc_heap:<0.13.0> +=proc_dictionary:<0.14.0> +H36A998 +H36A9A4 +=proc_stack:<0.14.0> +372e0c:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A7:inet_db +y3:H36A9B0 +y4:A7:inet_db +y5:P<0.9.0> +372e28:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H36A9C8 +=proc_heap:<0.14.0> +36A9B0:t5:A5:state,A7:inet_db,AA:inet_cache,AA:inet_hosts,H36A9E8 +36A9E8:E21:8372000364000D6E6F6E6F6465406E6F686F737400000000060000000000000000 +36A9C8:lAA:gen_server|H36A9F8 +36A9F8:lP<0.9.0>|H36AA08 +36AA08:lP<0.9.0>|H36AA10 +36AA10:lH36AA18|H36AA24 +36AA18:t2:A5:local,A7:inet_db +36AA24:lA7:inet_db|H36AA2C +36AA2C:lN|H36AA34 +36AA34:lN|N +36A998:t2:AD:$initial_call,H36A9D0 +36A9D0:t3:A3:gen,A7:init_it,H36A9C8 +36A9A4:t2:AA:$ancestors,H36A9E0 +36A9E0:lAA:kernel_sup|H36AA00 +36AA00:lP<0.8.0>|N +=proc_dictionary:<0.15.0> +H372788 +H3727F8 +H37276C +H37280C +H372820 +=proc_stack:<0.15.0> +372a64:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AC:global_group +y3:H3728C8 +y4:AC:global_group +y5:P<0.9.0> +372a80:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H37273C +=proc_heap:<0.15.0> +3728C8:tC:A5:state,A7:no_conf,A4:true,N,N,N,N,N,AD:nonode@nohost,N,A6:normal,A6:normal +37273C:lAA:gen_server|H372734 +372734:lP<0.9.0>|H37272C +37272C:lP<0.9.0>|H372700 +372700:lH372708|H372724 +372708:t2:A5:local,AC:global_group +372724:lAC:global_group|H37271C +37271C:lN|H372714 +372714:lN|N +372788:t2:AD:$initial_call,H372778 +372778:t3:A3:gen,A7:init_it,H37273C +3727F8:t2:A10:registered_names,H3727F0 +3727F0:lA9:undefined|N +37276C:t2:AA:$ancestors,H372764 +372764:lAA:kernel_sup|H372744 +372744:lP<0.8.0>|N +37280C:t2:A4:send,H372804 +372804:lA9:undefined|N +372820:t2:AC:whereis_name,H372818 +372818:lA9:undefined|N +=proc_dictionary:<0.16.0> +H37B918 +H37B924 +=proc_stack:<0.16.0> +3d303c:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AB:file_server +y3:p<0.4> +y4:AD:file_server_2 +y5:P<0.9.0> +3d3058:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H37B930 +=proc_heap:<0.16.0> +37B930:lAA:gen_server|H37B950 +37B950:lP<0.9.0>|H37B960 +37B960:lP<0.9.0>|H37B968 +37B968:lH37B970|H37B97C +37B970:t2:A5:local,AD:file_server_2 +37B97C:lAB:file_server|H37B984 +37B984:lN|H37B98C +37B98C:lN|N +37B918:t2:AD:$initial_call,H37B938 +37B938:t3:A3:gen,A7:init_it,H37B930 +37B924:t2:AA:$ancestors,H37B948 +37B948:lAA:kernel_sup|H37B958 +37B958:lP<0.8.0>|N +=proc_stack:<0.17.0> +3763cc:SReturn addr 0x156F90 (<terminate process normally>) +y0:H376084 +y1:P<0.16.0> +y2:P<0.9.0> +=proc_heap:<0.17.0> +376084:E21:8372000364000D6E6F6E6F6465406E6F686F737400000000160000000000000000 +=proc_stack:<0.18.0> +3b98e8:SReturn addr 0x156F90 (<terminate process normally>) +y0:H38AE84 +y1:P<0.9.0> +=proc_heap:<0.18.0> +38AE84:t8:A5:state,P<0.9.0>,H3873BC,H38AEB8,I9,I10,A8:no_cache,AB:interactive +38AEB8:lH3873D4|H38AEE0 +3873D4:lI46|N +38AEE0:lH3873EC|H38AF10 +3873EC:lI47|H387404 +387404:lI99|H387424 +387424:lI108|H38744C +38744C:lI101|H38747C +38747C:lI97|H3874B4 +3874B4:lI114|H3874F4 +3874F4:lI99|H38753C +38753C:lI97|H38758C +38758C:lI115|H3875E4 +3875E4:lI101|H387644 +387644:lI47|H3876AC +3876AC:lI111|H38771C +38771C:lI116|H387794 +387794:lI112|H387814 +387814:lI47|H38789C +38789C:lI101|H38792C +38792C:lI114|H3879BC +3879BC:lI116|H387A54 +387A54:lI115|H387AF4 +387AF4:lI47|H387B9C +387B9C:lI108|H387C4C +387C4C:lI105|H387D04 +387D04:lI98|H387DC4 +387DC4:lI47|H387E8C +387E8C:lI107|H387F5C +387F5C:lI101|H388034 +388034:lI114|H388114 +388114:lI110|H3881FC +3881FC:lI101|H3882EC +3882EC:lI108|H3883E4 +3883E4:lI47|H3884E4 +3884E4:lI101|H3885EC +3885EC:lI98|H3886FC +3886FC:lI105|H388814 +388814:lI110|N +38AF10:lH38740C|H38AF48 +38740C:lI47|H38742C +38742C:lI99|H387454 +387454:lI108|H387484 +387484:lI101|H3874BC +3874BC:lI97|H3874FC +3874FC:lI114|H387544 +387544:lI99|H387594 +387594:lI97|H3875EC +3875EC:lI115|H38764C +38764C:lI101|H3876B4 +3876B4:lI47|H387724 +387724:lI111|H38779C +38779C:lI116|H38781C +38781C:lI112|H3878A4 +3878A4:lI47|H387934 +387934:lI101|H3879C4 +3879C4:lI114|H387A5C +387A5C:lI116|H387AFC +387AFC:lI115|H387BA4 +387BA4:lI47|H387C54 +387C54:lI108|H387D0C +387D0C:lI105|H387DCC +387DCC:lI98|H387E94 +387E94:lI47|H387F64 +387F64:lI115|H38803C +38803C:lI116|H38811C +38811C:lI100|H388204 +388204:lI108|H3882F4 +3882F4:lI105|H3883EC +3883EC:lI98|H3884EC +3884EC:lI47|H3885F4 +3885F4:lI101|H388704 +388704:lI98|H38881C +38881C:lI105|H38892C +38892C:lI110|N +38AF48:lH387434|H38AF70 +387434:lI47|H38745C +38745C:lI99|H38748C +38748C:lI108|H3874C4 +3874C4:lI101|H387504 +387504:lI97|H38754C +38754C:lI114|H38759C +38759C:lI99|H3875F4 +3875F4:lI97|H387654 +387654:lI115|H3876BC +3876BC:lI101|H38772C +38772C:lI47|H3877A4 +3877A4:lI111|H387824 +387824:lI116|H3878AC +3878AC:lI112|H38793C +38793C:lI47|H3879CC +3879CC:lI101|H387A64 +387A64:lI114|H387B04 +387B04:lI116|H387BAC +387BAC:lI115|H387C5C +387C5C:lI47|H387D14 +387D14:lI108|H387DD4 +387DD4:lI105|H387E9C +387E9C:lI98|H387F6C +387F6C:lI47|H388044 +388044:lI119|H388124 +388124:lI101|H38820C +38820C:lI98|H3882FC +3882FC:lI116|H3883F4 +3883F4:lI111|H3884F4 +3884F4:lI111|H3885FC +3885FC:lI108|H38870C +38870C:lI47|H388824 +388824:lI101|H388934 +388934:lI98|H388A44 +388A44:lI105|H388B54 +388B54:lI110|N +38AF70:lH387464|H38AF98 +387464:lI47|H387494 +387494:lI99|H3874CC +3874CC:lI108|H38750C +38750C:lI101|H387554 +387554:lI97|H3875A4 +3875A4:lI114|H3875FC +3875FC:lI99|H38765C +38765C:lI97|H3876C4 +3876C4:lI115|H387734 +387734:lI101|H3877AC +3877AC:lI47|H38782C +38782C:lI111|H3878B4 +3878B4:lI116|H387944 +387944:lI112|H3879D4 +3879D4:lI47|H387A6C +387A6C:lI101|H387B0C +387B0C:lI114|H387BB4 +387BB4:lI116|H387C64 +387C64:lI115|H387D1C +387D1C:lI47|H387DDC +387DDC:lI108|H387EA4 +387EA4:lI105|H387F74 +387F74:lI98|H38804C +38804C:lI47|H38812C +38812C:lI116|H388214 +388214:lI118|H388304 +388304:lI47|H3883FC +3883FC:lI101|H3884FC +3884FC:lI98|H388604 +388604:lI105|H388714 +388714:lI110|N +38AF98:lH38749C|H38AFC0 +38749C:lI47|H3874D4 +3874D4:lI99|H387514 +387514:lI108|H38755C +38755C:lI101|H3875AC +3875AC:lI97|H387604 +387604:lI114|H387664 +387664:lI99|H3876CC +3876CC:lI97|H38773C +38773C:lI115|H3877B4 +3877B4:lI101|H387834 +387834:lI47|H3878BC +3878BC:lI111|H38794C +38794C:lI116|H3879DC +3879DC:lI112|H387A74 +387A74:lI47|H387B14 +387B14:lI101|H387BBC +387BBC:lI114|H387C6C +387C6C:lI116|H387D24 +387D24:lI115|H387DE4 +387DE4:lI47|H387EAC +387EAC:lI108|H387F7C +387F7C:lI105|H388054 +388054:lI98|H388134 +388134:lI47|H38821C +38821C:lI116|H38830C +38830C:lI115|H388404 +388404:lI112|H388504 +388504:lI47|H38860C +38860C:lI101|H38871C +38871C:lI98|H38882C +38882C:lI105|H38893C +38893C:lI110|N +38AFC0:lH3874DC|H38AFE8 +3874DC:lI47|H38751C +38751C:lI99|H387564 +387564:lI108|H3875B4 +3875B4:lI101|H38760C +38760C:lI97|H38766C +38766C:lI114|H3876D4 +3876D4:lI99|H387744 +387744:lI97|H3877BC +3877BC:lI115|H38783C +38783C:lI101|H3878C4 +3878C4:lI47|H387954 +387954:lI111|H3879E4 +3879E4:lI116|H387A7C +387A7C:lI112|H387B1C +387B1C:lI47|H387BC4 +387BC4:lI101|H387C74 +387C74:lI114|H387D2C +387D2C:lI116|H387DEC +387DEC:lI115|H387EB4 +387EB4:lI47|H387F84 +387F84:lI108|H38805C +38805C:lI105|H38813C +38813C:lI98|H388224 +388224:lI47|H388314 +388314:lI116|H38840C +38840C:lI111|H38850C +38850C:lI111|H388614 +388614:lI108|H388724 +388724:lI115|H388834 +388834:lI47|H388944 +388944:lI101|H388A4C +388A4C:lI98|H388B5C +388B5C:lI105|H388C6C +388C6C:lI110|N +38AFE8:lH387524|H38B008 +387524:lI47|H38756C +38756C:lI99|H3875BC +3875BC:lI108|H387614 +387614:lI101|H387674 +387674:lI97|H3876DC +3876DC:lI114|H38774C +38774C:lI99|H3877C4 +3877C4:lI97|H387844 +387844:lI115|H3878CC +3878CC:lI101|H38795C +38795C:lI47|H3879EC +3879EC:lI111|H387A84 +387A84:lI116|H387B24 +387B24:lI112|H387BCC +387BCC:lI47|H387C7C +387C7C:lI101|H387D34 +387D34:lI114|H387DF4 +387DF4:lI116|H387EBC +387EBC:lI115|H387F8C +387F8C:lI47|H388064 +388064:lI108|H388144 +388144:lI105|H38822C +38822C:lI98|H38831C +38831C:lI47|H388414 +388414:lI116|H388514 +388514:lI111|H38861C +38861C:lI111|H38872C +38872C:lI108|H38883C +38883C:lI98|H38894C +38894C:lI97|H388A54 +388A54:lI114|H388B64 +388B64:lI47|H388C74 +388C74:lI101|H388D84 +388D84:lI98|H388E9C +388E9C:lI105|H388FB4 +388FB4:lI110|N +38B008:lH387574|H38B018 +387574:lI47|H3875C4 +3875C4:lI99|H38761C +38761C:lI108|H38767C +38767C:lI101|H3876E4 +3876E4:lI97|H387754 +387754:lI114|H3877CC +3877CC:lI99|H38784C +38784C:lI97|H3878D4 +3878D4:lI115|H387964 +387964:lI101|H3879F4 +3879F4:lI47|H387A8C +387A8C:lI111|H387B2C +387B2C:lI116|H387BD4 +387BD4:lI112|H387C84 +387C84:lI47|H387D3C +387D3C:lI101|H387DFC +387DFC:lI114|H387EC4 +387EC4:lI116|H387F94 +387F94:lI115|H38806C +38806C:lI47|H38814C +38814C:lI108|H388234 +388234:lI105|H388324 +388324:lI98|H38841C +38841C:lI47|H38851C +38851C:lI116|H388624 +388624:lI101|H388734 +388734:lI115|H388844 +388844:lI116|H388954 +388954:lI95|H388A5C +388A5C:lI115|H388B6C +388B6C:lI101|H388C7C +388C7C:lI114|H388D8C +388D8C:lI118|H388EA4 +388EA4:lI101|H388FBC +388FBC:lI114|H3890D4 +3890D4:lI47|H3891EC +3891EC:lI101|H3892FC +3892FC:lI98|H38940C +38940C:lI105|H38951C +38951C:lI110|N +38B018:lH3875CC|H38AE7C +3875CC:lI47|H387624 +387624:lI99|H387684 +387684:lI108|H3876EC +3876EC:lI101|H38775C +38775C:lI97|H3877D4 +3877D4:lI114|H387854 +387854:lI99|H3878DC +3878DC:lI97|H38796C +38796C:lI115|H3879FC +3879FC:lI101|H387A94 +387A94:lI47|H387B34 +387B34:lI111|H387BDC +387BDC:lI116|H387C8C +387C8C:lI112|H387D44 +387D44:lI47|H387E04 +387E04:lI101|H387ECC +387ECC:lI114|H387F9C +387F9C:lI116|H388074 +388074:lI115|H388154 +388154:lI47|H38823C +38823C:lI108|H38832C +38832C:lI105|H388424 +388424:lI98|H388524 +388524:lI47|H38862C +38862C:lI115|H38873C +38873C:lI115|H38884C +38884C:lI108|H38895C +38895C:lI47|H388A64 +388A64:lI101|H388B74 +388B74:lI98|H388C84 +388C84:lI105|H388D94 +388D94:lI110|N +38AE7C:lH38762C|H38AEB0 +38762C:lI47|H38768C +38768C:lI99|H3876F4 +3876F4:lI108|H387764 +387764:lI101|H3877DC +3877DC:lI97|H38785C +38785C:lI114|H3878E4 +3878E4:lI99|H387974 +387974:lI97|H387A04 +387A04:lI115|H387A9C +387A9C:lI101|H387B3C +387B3C:lI47|H387BE4 +387BE4:lI111|H387C94 +387C94:lI116|H387D4C +387D4C:lI112|H387E0C +387E0C:lI47|H387ED4 +387ED4:lI101|H387FA4 +387FA4:lI114|H38807C +38807C:lI116|H38815C +38815C:lI115|H388244 +388244:lI47|H388334 +388334:lI108|H38842C +38842C:lI105|H38852C +38852C:lI98|H388634 +388634:lI47|H388744 +388744:lI115|H388854 +388854:lI110|H388964 +388964:lI109|H388A6C +388A6C:lI112|H388B7C +388B7C:lI47|H388C8C +388C8C:lI101|H388D9C +388D9C:lI98|H388EAC +388EAC:lI105|H388FC4 +388FC4:lI110|N +38AEB0:lH387694|H38AED8 +387694:lI47|H3876FC +3876FC:lI99|H38776C +38776C:lI108|H3877E4 +3877E4:lI101|H387864 +387864:lI97|H3878EC +3878EC:lI114|H38797C +38797C:lI99|H387A0C +387A0C:lI97|H387AA4 +387AA4:lI115|H387B44 +387B44:lI101|H387BEC +387BEC:lI47|H387C9C +387C9C:lI111|H387D54 +387D54:lI116|H387E14 +387E14:lI112|H387EDC +387EDC:lI47|H387FAC +387FAC:lI101|H388084 +388084:lI114|H388164 +388164:lI116|H38824C +38824C:lI115|H38833C +38833C:lI47|H388434 +388434:lI108|H388534 +388534:lI105|H38863C +38863C:lI98|H38874C +38874C:lI47|H38885C +38885C:lI115|H38896C +38896C:lI97|H388A74 +388A74:lI115|H388B84 +388B84:lI108|H388C94 +388C94:lI47|H388DA4 +388DA4:lI101|H388EB4 +388EB4:lI98|H388FCC +388FCC:lI105|H3890DC +3890DC:lI110|N +38AED8:lH387704|H38AF08 +387704:lI47|H387774 +387774:lI99|H3877EC +3877EC:lI108|H38786C +38786C:lI101|H3878F4 +3878F4:lI97|H387984 +387984:lI114|H387A14 +387A14:lI99|H387AAC +387AAC:lI97|H387B4C +387B4C:lI115|H387BF4 +387BF4:lI101|H387CA4 +387CA4:lI47|H387D5C +387D5C:lI111|H387E1C +387E1C:lI116|H387EE4 +387EE4:lI112|H387FB4 +387FB4:lI47|H38808C +38808C:lI101|H38816C +38816C:lI114|H388254 +388254:lI116|H388344 +388344:lI115|H38843C +38843C:lI47|H38853C +38853C:lI108|H388644 +388644:lI105|H388754 +388754:lI98|H388864 +388864:lI47|H388974 +388974:lI114|H388A7C +388A7C:lI117|H388B8C +388B8C:lI110|H388C9C +388C9C:lI116|H388DAC +388DAC:lI105|H388EBC +388EBC:lI109|H388FD4 +388FD4:lI101|H3890E4 +3890E4:lI95|H3891F4 +3891F4:lI116|H389304 +389304:lI111|H389414 +389414:lI111|H389524 +389524:lI108|H389624 +389624:lI115|H38971C +38971C:lI47|H389814 +389814:lI101|H38990C +38990C:lI98|H389A04 +389A04:lI105|H389AE4 +389AE4:lI110|N +38AF08:lH38777C|H38AF40 +38777C:lI47|H3877F4 +3877F4:lI99|H387874 +387874:lI108|H3878FC +3878FC:lI101|H38798C +38798C:lI97|H387A1C +387A1C:lI114|H387AB4 +387AB4:lI99|H387B54 +387B54:lI97|H387BFC +387BFC:lI115|H387CAC +387CAC:lI101|H387D64 +387D64:lI47|H387E24 +387E24:lI111|H387EEC +387EEC:lI116|H387FBC +387FBC:lI112|H388094 +388094:lI47|H388174 +388174:lI101|H38825C +38825C:lI114|H38834C +38834C:lI116|H388444 +388444:lI115|H388544 +388544:lI47|H38864C +38864C:lI108|H38875C +38875C:lI105|H38886C +38886C:lI98|H38897C +38897C:lI47|H388A84 +388A84:lI114|H388B94 +388B94:lI115|H388CA4 +388CA4:lI104|H388DB4 +388DB4:lI101|H388EC4 +388EC4:lI108|H388FDC +388FDC:lI108|H3890EC +3890EC:lI47|H3891FC +3891FC:lI101|H38930C +38930C:lI98|H38941C +38941C:lI105|H38952C +38952C:lI110|N +38AF40:lH3877FC|H38AF68 +3877FC:lI47|H38787C +38787C:lI99|H387904 +387904:lI108|H387994 +387994:lI101|H387A24 +387A24:lI97|H387ABC +387ABC:lI114|H387B5C +387B5C:lI99|H387C04 +387C04:lI97|H387CB4 +387CB4:lI115|H387D6C +387D6C:lI101|H387E2C +387E2C:lI47|H387EF4 +387EF4:lI111|H387FC4 +387FC4:lI116|H38809C +38809C:lI112|H38817C +38817C:lI47|H388264 +388264:lI101|H388354 +388354:lI114|H38844C +38844C:lI116|H38854C +38854C:lI115|H388654 +388654:lI47|H388764 +388764:lI108|H388874 +388874:lI105|H388984 +388984:lI98|H388A8C +388A8C:lI47|H388B9C +388B9C:lI112|H388CAC +388CAC:lI109|H388DBC +388DBC:lI97|H388ECC +388ECC:lI110|H388FE4 +388FE4:lI47|H3890F4 +3890F4:lI101|H389204 +389204:lI98|H389314 +389314:lI105|H389424 +389424:lI110|N +38AF68:lH387884|H38AF90 +387884:lI47|H38790C +38790C:lI99|H38799C +38799C:lI108|H387A2C +387A2C:lI101|H387AC4 +387AC4:lI97|H387B64 +387B64:lI114|H387C0C +387C0C:lI99|H387CBC +387CBC:lI97|H387D74 +387D74:lI115|H387E34 +387E34:lI101|H387EFC +387EFC:lI47|H387FCC +387FCC:lI111|H3880A4 +3880A4:lI116|H388184 +388184:lI112|H38826C +38826C:lI47|H38835C +38835C:lI101|H388454 +388454:lI114|H388554 +388554:lI116|H38865C +38865C:lI115|H38876C +38876C:lI47|H38887C +38887C:lI108|H38898C +38898C:lI105|H388A94 +388A94:lI98|H388BA4 +388BA4:lI47|H388CB4 +388CB4:lI112|H388DC4 +388DC4:lI97|H388ED4 +388ED4:lI114|H388FEC +388FEC:lI115|H3890FC +3890FC:lI101|H38920C +38920C:lI116|H38931C +38931C:lI111|H38942C +38942C:lI111|H389534 +389534:lI108|H38962C +38962C:lI115|H389724 +389724:lI47|H38981C +38981C:lI101|H389914 +389914:lI98|H389A0C +389A0C:lI105|H389AEC +389AEC:lI110|N +38AF90:lH387914|H38AFB8 +387914:lI47|H3879A4 +3879A4:lI99|H387A34 +387A34:lI108|H387ACC +387ACC:lI101|H387B6C +387B6C:lI97|H387C14 +387C14:lI114|H387CC4 +387CC4:lI99|H387D7C +387D7C:lI97|H387E3C +387E3C:lI115|H387F04 +387F04:lI101|H387FD4 +387FD4:lI47|H3880AC +3880AC:lI111|H38818C +38818C:lI116|H388274 +388274:lI112|H388364 +388364:lI47|H38845C +38845C:lI101|H38855C +38855C:lI114|H388664 +388664:lI116|H388774 +388774:lI115|H388884 +388884:lI47|H388994 +388994:lI108|H388A9C +388A9C:lI105|H388BAC +388BAC:lI98|H388CBC +388CBC:lI47|H388DCC +388DCC:lI111|H388EDC +388EDC:lI116|H388FF4 +388FF4:lI112|H389104 +389104:lI95|H389214 +389214:lI109|H389324 +389324:lI105|H389434 +389434:lI98|H38953C +38953C:lI115|H389634 +389634:lI47|H38972C +38972C:lI101|H389824 +389824:lI98|H38991C +38991C:lI105|H389A14 +389A14:lI110|N +38AFB8:lH3879AC|H38AFE0 +3879AC:lI47|H387A3C +387A3C:lI99|H387AD4 +387AD4:lI108|H387B74 +387B74:lI101|H387C1C +387C1C:lI97|H387CCC +387CCC:lI114|H387D84 +387D84:lI99|H387E44 +387E44:lI97|H387F0C +387F0C:lI115|H387FDC +387FDC:lI101|H3880B4 +3880B4:lI47|H388194 +388194:lI111|H38827C +38827C:lI116|H38836C +38836C:lI112|H388464 +388464:lI47|H388564 +388564:lI101|H38866C +38866C:lI114|H38877C +38877C:lI116|H38888C +38888C:lI115|H38899C +38899C:lI47|H388AA4 +388AA4:lI108|H388BB4 +388BB4:lI105|H388CC4 +388CC4:lI98|H388DD4 +388DD4:lI47|H388EE4 +388EE4:lI111|H388FFC +388FFC:lI115|H38910C +38910C:lI95|H38921C +38921C:lI109|H38932C +38932C:lI111|H38943C +38943C:lI110|H389544 +389544:lI47|H38963C +38963C:lI101|H389734 +389734:lI98|H38982C +38982C:lI105|H389924 +389924:lI110|N +38AFE0:lH387A44|H38B000 +387A44:lI47|H387ADC +387ADC:lI99|H387B7C +387B7C:lI108|H387C24 +387C24:lI101|H387CD4 +387CD4:lI97|H387D8C +387D8C:lI114|H387E4C +387E4C:lI99|H387F14 +387F14:lI97|H387FE4 +387FE4:lI115|H3880BC +3880BC:lI101|H38819C +38819C:lI47|H388284 +388284:lI111|H388374 +388374:lI116|H38846C +38846C:lI112|H38856C +38856C:lI47|H388674 +388674:lI101|H388784 +388784:lI114|H388894 +388894:lI116|H3889A4 +3889A4:lI115|H388AAC +388AAC:lI47|H388BBC +388BBC:lI108|H388CCC +388CCC:lI105|H388DDC +388DDC:lI98|H388EEC +388EEC:lI47|H389004 +389004:lI111|H389114 +389114:lI114|H389224 +389224:lI98|H389334 +389334:lI101|H389444 +389444:lI114|H38954C +38954C:lI47|H389644 +389644:lI101|H38973C +38973C:lI98|H389834 +389834:lI105|H38992C +38992C:lI110|N +38B000:lH387AE4|H38B010 +387AE4:lI47|H387B84 +387B84:lI99|H387C2C +387C2C:lI108|H387CDC +387CDC:lI101|H387D94 +387D94:lI97|H387E54 +387E54:lI114|H387F1C +387F1C:lI99|H387FEC +387FEC:lI97|H3880C4 +3880C4:lI115|H3881A4 +3881A4:lI101|H38828C +38828C:lI47|H38837C +38837C:lI111|H388474 +388474:lI116|H388574 +388574:lI112|H38867C +38867C:lI47|H38878C +38878C:lI101|H38889C +38889C:lI114|H3889AC +3889AC:lI116|H388AB4 +388AB4:lI115|H388BC4 +388BC4:lI47|H388CD4 +388CD4:lI108|H388DE4 +388DE4:lI105|H388EF4 +388EF4:lI98|H38900C +38900C:lI47|H38911C +38911C:lI111|H38922C +38922C:lI100|H38933C +38933C:lI98|H38944C +38944C:lI99|H389554 +389554:lI47|H38964C +38964C:lI101|H389744 +389744:lI98|H38983C +38983C:lI105|H389934 +389934:lI110|N +38B010:lH387B8C|H38B020 +387B8C:lI47|H387C34 +387C34:lI99|H387CE4 +387CE4:lI108|H387D9C +387D9C:lI101|H387E5C +387E5C:lI97|H387F24 +387F24:lI114|H387FF4 +387FF4:lI99|H3880CC +3880CC:lI97|H3881AC +3881AC:lI115|H388294 +388294:lI101|H388384 +388384:lI47|H38847C +38847C:lI111|H38857C +38857C:lI116|H388684 +388684:lI112|H388794 +388794:lI47|H3888A4 +3888A4:lI101|H3889B4 +3889B4:lI114|H388ABC +388ABC:lI116|H388BCC +388BCC:lI115|H388CDC +388CDC:lI47|H388DEC +388DEC:lI108|H388EFC +388EFC:lI105|H389014 +389014:lI98|H389124 +389124:lI47|H389234 +389234:lI111|H389344 +389344:lI98|H389454 +389454:lI115|H38955C +38955C:lI101|H389654 +389654:lI114|H38974C +38974C:lI118|H389844 +389844:lI101|H38993C +38993C:lI114|H389A1C +389A1C:lI47|H389AF4 +389AF4:lI101|H389BBC +389BBC:lI98|H389C84 +389C84:lI105|H389D4C +389D4C:lI110|N +38B020:lH387C3C|H38B028 +387C3C:lI47|H387CEC +387CEC:lI99|H387DA4 +387DA4:lI108|H387E64 +387E64:lI101|H387F2C +387F2C:lI97|H387FFC +387FFC:lI114|H3880D4 +3880D4:lI99|H3881B4 +3881B4:lI97|H38829C +38829C:lI115|H38838C +38838C:lI101|H388484 +388484:lI47|H388584 +388584:lI111|H38868C +38868C:lI116|H38879C +38879C:lI112|H3888AC +3888AC:lI47|H3889BC +3889BC:lI101|H388AC4 +388AC4:lI114|H388BD4 +388BD4:lI116|H388CE4 +388CE4:lI115|H388DF4 +388DF4:lI47|H388F04 +388F04:lI108|H38901C +38901C:lI105|H38912C +38912C:lI98|H38923C +38923C:lI47|H38934C +38934C:lI109|H38945C +38945C:lI110|H389564 +389564:lI101|H38965C +38965C:lI115|H389754 +389754:lI105|H38984C +38984C:lI97|H389944 +389944:lI95|H389A24 +389A24:lI115|H389AFC +389AFC:lI101|H389BC4 +389BC4:lI115|H389C8C +389C8C:lI115|H389D54 +389D54:lI105|H389E14 +389E14:lI111|H389ECC +389ECC:lI110|H389F7C +389F7C:lI47|H38A01C +38A01C:lI101|H38A0AC +38A0AC:lI98|H38A12C +38A12C:lI105|H38A19C +38A19C:lI110|N +38B028:lH387CF4|H38B030 +387CF4:lI47|H387DAC +387DAC:lI99|H387E6C +387E6C:lI108|H387F34 +387F34:lI101|H388004 +388004:lI97|H3880DC +3880DC:lI114|H3881BC +3881BC:lI99|H3882A4 +3882A4:lI97|H388394 +388394:lI115|H38848C +38848C:lI101|H38858C +38858C:lI47|H388694 +388694:lI111|H3887A4 +3887A4:lI116|H3888B4 +3888B4:lI112|H3889C4 +3889C4:lI47|H388ACC +388ACC:lI101|H388BDC +388BDC:lI114|H388CEC +388CEC:lI116|H388DFC +388DFC:lI115|H388F0C +388F0C:lI47|H389024 +389024:lI108|H389134 +389134:lI105|H389244 +389244:lI98|H389354 +389354:lI47|H389464 +389464:lI109|H38956C +38956C:lI110|H389664 +389664:lI101|H38975C +38975C:lI115|H389854 +389854:lI105|H38994C +38994C:lI97|H389A2C +389A2C:lI47|H389B04 +389B04:lI101|H389BCC +389BCC:lI98|H389C94 +389C94:lI105|H389D5C +389D5C:lI110|N +38B030:lH387DB4|H38B038 +387DB4:lI47|H387E74 +387E74:lI99|H387F3C +387F3C:lI108|H38800C +38800C:lI101|H3880E4 +3880E4:lI97|H3881C4 +3881C4:lI114|H3882AC +3882AC:lI99|H38839C +38839C:lI97|H388494 +388494:lI115|H388594 +388594:lI101|H38869C +38869C:lI47|H3887AC +3887AC:lI111|H3888BC +3888BC:lI116|H3889CC +3889CC:lI112|H388AD4 +388AD4:lI47|H388BE4 +388BE4:lI101|H388CF4 +388CF4:lI114|H388E04 +388E04:lI116|H388F14 +388F14:lI115|H38902C +38902C:lI47|H38913C +38913C:lI108|H38924C +38924C:lI105|H38935C +38935C:lI98|H38946C +38946C:lI47|H389574 +389574:lI109|H38966C +38966C:lI110|H389764 +389764:lI101|H38985C +38985C:lI109|H389954 +389954:lI111|H389A34 +389A34:lI115|H389B0C +389B0C:lI121|H389BD4 +389BD4:lI110|H389C9C +389C9C:lI101|H389D64 +389D64:lI47|H389E1C +389E1C:lI101|H389ED4 +389ED4:lI98|H389F84 +389F84:lI105|H38A024 +38A024:lI110|N +38B038:lH387E7C|H38B040 +387E7C:lI47|H387F44 +387F44:lI99|H388014 +388014:lI108|H3880EC +3880EC:lI101|H3881CC +3881CC:lI97|H3882B4 +3882B4:lI114|H3883A4 +3883A4:lI99|H38849C +38849C:lI97|H38859C +38859C:lI115|H3886A4 +3886A4:lI101|H3887B4 +3887B4:lI47|H3888C4 +3888C4:lI111|H3889D4 +3889D4:lI116|H388ADC +388ADC:lI112|H388BEC +388BEC:lI47|H388CFC +388CFC:lI101|H388E0C +388E0C:lI114|H388F1C +388F1C:lI116|H389034 +389034:lI115|H389144 +389144:lI47|H389254 +389254:lI108|H389364 +389364:lI105|H389474 +389474:lI98|H38957C +38957C:lI47|H389674 +389674:lI109|H38976C +38976C:lI101|H389864 +389864:lI103|H38995C +38995C:lI97|H389A3C +389A3C:lI99|H389B14 +389B14:lI111|H389BDC +389BDC:lI47|H389CA4 +389CA4:lI101|H389D6C +389D6C:lI98|H389E24 +389E24:lI105|H389EDC +389EDC:lI110|N +38B040:lH387F4C|H38B048 +387F4C:lI47|H38801C +38801C:lI99|H3880F4 +3880F4:lI108|H3881D4 +3881D4:lI101|H3882BC +3882BC:lI97|H3883AC +3883AC:lI114|H3884A4 +3884A4:lI99|H3885A4 +3885A4:lI97|H3886AC +3886AC:lI115|H3887BC +3887BC:lI101|H3888CC +3888CC:lI47|H3889DC +3889DC:lI111|H388AE4 +388AE4:lI116|H388BF4 +388BF4:lI112|H388D04 +388D04:lI47|H388E14 +388E14:lI101|H388F24 +388F24:lI114|H38903C +38903C:lI116|H38914C +38914C:lI115|H38925C +38925C:lI47|H38936C +38936C:lI108|H38947C +38947C:lI105|H389584 +389584:lI98|H38967C +38967C:lI47|H389774 +389774:lI106|H38986C +38986C:lI105|H389964 +389964:lI110|H389A44 +389A44:lI116|H389B1C +389B1C:lI101|H389BE4 +389BE4:lI114|H389CAC +389CAC:lI102|H389D74 +389D74:lI97|H389E2C +389E2C:lI99|H389EE4 +389EE4:lI101|N +38B048:lH388024|H38B050 +388024:lI47|H3880FC +3880FC:lI99|H3881DC +3881DC:lI108|H3882C4 +3882C4:lI101|H3883B4 +3883B4:lI97|H3884AC +3884AC:lI114|H3885AC +3885AC:lI99|H3886B4 +3886B4:lI97|H3887C4 +3887C4:lI115|H3888D4 +3888D4:lI101|H3889E4 +3889E4:lI47|H388AEC +388AEC:lI111|H388BFC +388BFC:lI116|H388D0C +388D0C:lI112|H388E1C +388E1C:lI47|H388F2C +388F2C:lI101|H389044 +389044:lI114|H389154 +389154:lI116|H389264 +389264:lI115|H389374 +389374:lI47|H389484 +389484:lI108|H38958C +38958C:lI105|H389684 +389684:lI98|H38977C +38977C:lI47|H389874 +389874:lI105|H38996C +38996C:lI110|H389A4C +389A4C:lI101|H389B24 +389B24:lI116|H389BEC +389BEC:lI115|H389CB4 +389CB4:lI47|H389D7C +389D7C:lI101|H389E34 +389E34:lI98|H389EEC +389EEC:lI105|H389F8C +389F8C:lI110|N +38B050:lH388104|H38B058 +388104:lI47|H3881E4 +3881E4:lI99|H3882CC +3882CC:lI108|H3883BC +3883BC:lI101|H3884B4 +3884B4:lI97|H3885B4 +3885B4:lI114|H3886BC +3886BC:lI99|H3887CC +3887CC:lI97|H3888DC +3888DC:lI115|H3889EC +3889EC:lI101|H388AF4 +388AF4:lI47|H388C04 +388C04:lI111|H388D14 +388D14:lI116|H388E24 +388E24:lI112|H388F34 +388F34:lI47|H38904C +38904C:lI101|H38915C +38915C:lI114|H38926C +38926C:lI116|H38937C +38937C:lI115|H38948C +38948C:lI47|H389594 +389594:lI108|H38968C +38968C:lI105|H389784 +389784:lI98|H38987C +38987C:lI47|H389974 +389974:lI105|H389A54 +389A54:lI99|H389B2C +389B2C:lI47|H389BF4 +389BF4:lI101|H389CBC +389CBC:lI98|H389D84 +389D84:lI105|H389E3C +389E3C:lI110|N +38B058:lH3881EC|H38B060 +3881EC:lI47|H3882D4 +3882D4:lI99|H3883C4 +3883C4:lI108|H3884BC +3884BC:lI101|H3885BC +3885BC:lI97|H3886C4 +3886C4:lI114|H3887D4 +3887D4:lI99|H3888E4 +3888E4:lI97|H3889F4 +3889F4:lI115|H388AFC +388AFC:lI101|H388C0C +388C0C:lI47|H388D1C +388D1C:lI111|H388E2C +388E2C:lI116|H388F3C +388F3C:lI112|H389054 +389054:lI47|H389164 +389164:lI101|H389274 +389274:lI114|H389384 +389384:lI116|H389494 +389494:lI115|H38959C +38959C:lI47|H389694 +389694:lI108|H38978C +38978C:lI105|H389884 +389884:lI98|H38997C +38997C:lI47|H389A5C +389A5C:lI104|H389B34 +389B34:lI105|H389BFC +389BFC:lI112|H389CC4 +389CC4:lI101|H389D8C +389D8C:lI47|H389E44 +389E44:lI101|H389EF4 +389EF4:lI98|H389F94 +389F94:lI105|H38A02C +38A02C:lI110|N +38B060:lH3882DC|H38B068 +3882DC:lI47|H3883CC +3883CC:lI99|H3884C4 +3884C4:lI108|H3885C4 +3885C4:lI101|H3886CC +3886CC:lI97|H3887DC +3887DC:lI114|H3888EC +3888EC:lI99|H3889FC +3889FC:lI97|H388B04 +388B04:lI115|H388C14 +388C14:lI101|H388D24 +388D24:lI47|H388E34 +388E34:lI111|H388F44 +388F44:lI116|H38905C +38905C:lI112|H38916C +38916C:lI47|H38927C +38927C:lI101|H38938C +38938C:lI114|H38949C +38949C:lI116|H3895A4 +3895A4:lI115|H38969C +38969C:lI47|H389794 +389794:lI108|H38988C +38988C:lI105|H389984 +389984:lI98|H389A64 +389A64:lI47|H389B3C +389B3C:lI103|H389C04 +389C04:lI115|H389CCC +389CCC:lI47|H389D94 +389D94:lI101|H389E4C +389E4C:lI98|H389EFC +389EFC:lI105|H389F9C +389F9C:lI110|N +38B068:lH3883D4|H38B070 +3883D4:lI47|H3884CC +3884CC:lI99|H3885CC +3885CC:lI108|H3886D4 +3886D4:lI101|H3887E4 +3887E4:lI97|H3888F4 +3888F4:lI114|H388A04 +388A04:lI99|H388B0C +388B0C:lI97|H388C1C +388C1C:lI115|H388D2C +388D2C:lI101|H388E3C +388E3C:lI47|H388F4C +388F4C:lI111|H389064 +389064:lI116|H389174 +389174:lI112|H389284 +389284:lI47|H389394 +389394:lI101|H3894A4 +3894A4:lI114|H3895AC +3895AC:lI116|H3896A4 +3896A4:lI115|H38979C +38979C:lI47|H389894 +389894:lI108|H38998C +38998C:lI105|H389A6C +389A6C:lI98|H389B44 +389B44:lI47|H389C0C +389C0C:lI101|H389CD4 +389CD4:lI118|H389D9C +389D9C:lI97|H389E54 +389E54:lI47|H389F04 +389F04:lI101|H389FA4 +389FA4:lI98|H38A034 +38A034:lI105|H38A0B4 +38A0B4:lI110|N +38B070:lH3884D4|H38B078 +3884D4:lI47|H3885D4 +3885D4:lI99|H3886DC +3886DC:lI108|H3887EC +3887EC:lI101|H3888FC +3888FC:lI97|H388A0C +388A0C:lI114|H388B14 +388B14:lI99|H388C24 +388C24:lI97|H388D34 +388D34:lI115|H388E44 +388E44:lI101|H388F54 +388F54:lI47|H38906C +38906C:lI111|H38917C +38917C:lI116|H38928C +38928C:lI112|H38939C +38939C:lI47|H3894AC +3894AC:lI101|H3895B4 +3895B4:lI114|H3896AC +3896AC:lI116|H3897A4 +3897A4:lI115|H38989C +38989C:lI47|H389994 +389994:lI108|H389A74 +389A74:lI105|H389B4C +389B4C:lI98|H389C14 +389C14:lI47|H389CDC +389CDC:lI101|H389DA4 +389DA4:lI116|H389E5C +389E5C:lI47|H389F0C +389F0C:lI101|H389FAC +389FAC:lI98|H38A03C +38A03C:lI105|H38A0BC +38A0BC:lI110|N +38B078:lH3885DC|H38B080 +3885DC:lI47|H3886E4 +3886E4:lI99|H3887F4 +3887F4:lI108|H388904 +388904:lI101|H388A14 +388A14:lI97|H388B1C +388B1C:lI114|H388C2C +388C2C:lI99|H388D3C +388D3C:lI97|H388E4C +388E4C:lI115|H388F5C +388F5C:lI101|H389074 +389074:lI47|H389184 +389184:lI111|H389294 +389294:lI116|H3893A4 +3893A4:lI112|H3894B4 +3894B4:lI47|H3895BC +3895BC:lI101|H3896B4 +3896B4:lI114|H3897AC +3897AC:lI116|H3898A4 +3898A4:lI115|H38999C +38999C:lI47|H389A7C +389A7C:lI108|H389B54 +389B54:lI105|H389C1C +389C1C:lI98|H389CE4 +389CE4:lI47|H389DAC +389DAC:lI101|H389E64 +389E64:lI114|H389F14 +389F14:lI108|H389FB4 +389FB4:lI95|H38A044 +38A044:lI105|H38A0C4 +38A0C4:lI110|H38A134 +38A134:lI116|H38A1A4 +38A1A4:lI101|H38A20C +38A20C:lI114|H38A274 +38A274:lI102|H38A2DC +38A2DC:lI97|H38A344 +38A344:lI99|H38A3AC +38A3AC:lI101|N +38B080:lH3886EC|H38B088 +3886EC:lI47|H3887FC +3887FC:lI99|H38890C +38890C:lI108|H388A1C +388A1C:lI101|H388B24 +388B24:lI97|H388C34 +388C34:lI114|H388D44 +388D44:lI99|H388E54 +388E54:lI97|H388F64 +388F64:lI115|H38907C +38907C:lI101|H38918C +38918C:lI47|H38929C +38929C:lI111|H3893AC +3893AC:lI116|H3894BC +3894BC:lI112|H3895C4 +3895C4:lI47|H3896BC +3896BC:lI101|H3897B4 +3897B4:lI114|H3898AC +3898AC:lI116|H3899A4 +3899A4:lI115|H389A84 +389A84:lI47|H389B5C +389B5C:lI108|H389C24 +389C24:lI105|H389CEC +389CEC:lI98|H389DB4 +389DB4:lI47|H389E6C +389E6C:lI100|H389F1C +389F1C:lI101|H389FBC +389FBC:lI98|H38A04C +38A04C:lI117|H38A0CC +38A0CC:lI103|H38A13C +38A13C:lI103|H38A1AC +38A1AC:lI101|H38A214 +38A214:lI114|H38A27C +38A27C:lI47|H38A2E4 +38A2E4:lI101|H38A34C +38A34C:lI98|H38A3B4 +38A3B4:lI105|H38A414 +38A414:lI110|N +38B088:lH388804|H38B090 +388804:lI47|H388914 +388914:lI99|H388A24 +388A24:lI108|H388B2C +388B2C:lI101|H388C3C +388C3C:lI97|H388D4C +388D4C:lI114|H388E5C +388E5C:lI99|H388F6C +388F6C:lI97|H389084 +389084:lI115|H389194 +389194:lI101|H3892A4 +3892A4:lI47|H3893B4 +3893B4:lI111|H3894C4 +3894C4:lI116|H3895CC +3895CC:lI112|H3896C4 +3896C4:lI47|H3897BC +3897BC:lI101|H3898B4 +3898B4:lI114|H3899AC +3899AC:lI116|H389A8C +389A8C:lI115|H389B64 +389B64:lI47|H389C2C +389C2C:lI108|H389CF4 +389CF4:lI105|H389DBC +389DBC:lI98|H389E74 +389E74:lI47|H389F24 +389F24:lI99|H389FC4 +389FC4:lI114|H38A054 +38A054:lI121|H38A0D4 +38A0D4:lI112|H38A144 +38A144:lI116|H38A1B4 +38A1B4:lI111|H38A21C +38A21C:lI47|H38A284 +38A284:lI101|H38A2EC +38A2EC:lI98|H38A354 +38A354:lI105|H38A3BC +38A3BC:lI110|N +38B090:lH38891C|H38B098 +38891C:lI47|H388A2C +388A2C:lI99|H388B34 +388B34:lI108|H388C44 +388C44:lI101|H388D54 +388D54:lI97|H388E64 +388E64:lI114|H388F74 +388F74:lI99|H38908C +38908C:lI97|H38919C +38919C:lI115|H3892AC +3892AC:lI101|H3893BC +3893BC:lI47|H3894CC +3894CC:lI111|H3895D4 +3895D4:lI116|H3896CC +3896CC:lI112|H3897C4 +3897C4:lI47|H3898BC +3898BC:lI101|H3899B4 +3899B4:lI114|H389A94 +389A94:lI116|H389B6C +389B6C:lI115|H389C34 +389C34:lI47|H389CFC +389CFC:lI108|H389DC4 +389DC4:lI105|H389E7C +389E7C:lI98|H389F2C +389F2C:lI47|H389FCC +389FCC:lI99|H38A05C +38A05C:lI111|H38A0DC +38A0DC:lI115|H38A14C +38A14C:lI84|H38A1BC +38A1BC:lI114|H38A224 +38A224:lI97|H38A28C +38A28C:lI110|H38A2F4 +38A2F4:lI115|H38A35C +38A35C:lI97|H38A3C4 +38A3C4:lI99|H38A41C +38A41C:lI116|H38A46C +38A46C:lI105|H38A4BC +38A4BC:lI111|H38A50C +38A50C:lI110|H38A554 +38A554:lI115|H38A59C +38A59C:lI47|H38A5E4 +38A5E4:lI101|H38A62C +38A62C:lI98|H38A66C +38A66C:lI105|H38A6A4 +38A6A4:lI110|N +38B098:lH388A34|H38B0A0 +388A34:lI47|H388B3C +388B3C:lI99|H388C4C +388C4C:lI108|H388D5C +388D5C:lI101|H388E6C +388E6C:lI97|H388F7C +388F7C:lI114|H389094 +389094:lI99|H3891A4 +3891A4:lI97|H3892B4 +3892B4:lI115|H3893C4 +3893C4:lI101|H3894D4 +3894D4:lI47|H3895DC +3895DC:lI111|H3896D4 +3896D4:lI116|H3897CC +3897CC:lI112|H3898C4 +3898C4:lI47|H3899BC +3899BC:lI101|H389A9C +389A9C:lI114|H389B74 +389B74:lI116|H389C3C +389C3C:lI115|H389D04 +389D04:lI47|H389DCC +389DCC:lI108|H389E84 +389E84:lI105|H389F34 +389F34:lI98|H389FD4 +389FD4:lI47|H38A064 +38A064:lI99|H38A0E4 +38A0E4:lI111|H38A154 +38A154:lI115|H38A1C4 +38A1C4:lI84|H38A22C +38A22C:lI105|H38A294 +38A294:lI109|H38A2FC +38A2FC:lI101|H38A364 +38A364:lI47|H38A3CC +38A3CC:lI101|H38A424 +38A424:lI98|H38A474 +38A474:lI105|H38A4C4 +38A4C4:lI110|N +38B0A0:lH388B44|H38B0A8 +388B44:lI47|H388C54 +388C54:lI99|H388D64 +388D64:lI108|H388E74 +388E74:lI101|H388F84 +388F84:lI97|H38909C +38909C:lI114|H3891AC +3891AC:lI99|H3892BC +3892BC:lI97|H3893CC +3893CC:lI115|H3894DC +3894DC:lI101|H3895E4 +3895E4:lI47|H3896DC +3896DC:lI111|H3897D4 +3897D4:lI116|H3898CC +3898CC:lI112|H3899C4 +3899C4:lI47|H389AA4 +389AA4:lI101|H389B7C +389B7C:lI114|H389C44 +389C44:lI116|H389D0C +389D0C:lI115|H389DD4 +389DD4:lI47|H389E8C +389E8C:lI108|H389F3C +389F3C:lI105|H389FDC +389FDC:lI98|H38A06C +38A06C:lI47|H38A0EC +38A0EC:lI99|H38A15C +38A15C:lI111|H38A1CC +38A1CC:lI115|H38A234 +38A234:lI80|H38A29C +38A29C:lI114|H38A304 +38A304:lI111|H38A36C +38A36C:lI112|H38A3D4 +38A3D4:lI101|H38A42C +38A42C:lI114|H38A47C +38A47C:lI116|H38A4CC +38A4CC:lI121|H38A514 +38A514:lI47|H38A55C +38A55C:lI101|H38A5A4 +38A5A4:lI98|H38A5EC +38A5EC:lI105|H38A634 +38A634:lI110|N +38B0A8:lH388C5C|H38B0B0 +388C5C:lI47|H388D6C +388D6C:lI99|H388E7C +388E7C:lI108|H388F8C +388F8C:lI101|H3890A4 +3890A4:lI97|H3891B4 +3891B4:lI114|H3892C4 +3892C4:lI99|H3893D4 +3893D4:lI97|H3894E4 +3894E4:lI115|H3895EC +3895EC:lI101|H3896E4 +3896E4:lI47|H3897DC +3897DC:lI111|H3898D4 +3898D4:lI116|H3899CC +3899CC:lI112|H389AAC +389AAC:lI47|H389B84 +389B84:lI101|H389C4C +389C4C:lI114|H389D14 +389D14:lI116|H389DDC +389DDC:lI115|H389E94 +389E94:lI47|H389F44 +389F44:lI108|H389FE4 +389FE4:lI105|H38A074 +38A074:lI98|H38A0F4 +38A0F4:lI47|H38A164 +38A164:lI99|H38A1D4 +38A1D4:lI111|H38A23C +38A23C:lI115|H38A2A4 +38A2A4:lI78|H38A30C +38A30C:lI111|H38A374 +38A374:lI116|H38A3DC +38A3DC:lI105|H38A434 +38A434:lI102|H38A484 +38A484:lI105|H38A4D4 +38A4D4:lI99|H38A51C +38A51C:lI97|H38A564 +38A564:lI116|H38A5AC +38A5AC:lI105|H38A5F4 +38A5F4:lI111|H38A63C +38A63C:lI110|H38A674 +38A674:lI47|H38A6AC +38A6AC:lI101|H38A6D4 +38A6D4:lI98|H38A6EC +38A6EC:lI105|H38A704 +38A704:lI110|N +38B0B0:lH388D74|H38B0B8 +388D74:lI47|H388E84 +388E84:lI99|H388F94 +388F94:lI108|H3890AC +3890AC:lI101|H3891BC +3891BC:lI97|H3892CC +3892CC:lI114|H3893DC +3893DC:lI99|H3894EC +3894EC:lI97|H3895F4 +3895F4:lI115|H3896EC +3896EC:lI101|H3897E4 +3897E4:lI47|H3898DC +3898DC:lI111|H3899D4 +3899D4:lI116|H389AB4 +389AB4:lI112|H389B8C +389B8C:lI47|H389C54 +389C54:lI101|H389D1C +389D1C:lI114|H389DE4 +389DE4:lI116|H389E9C +389E9C:lI115|H389F4C +389F4C:lI47|H389FEC +389FEC:lI108|H38A07C +38A07C:lI105|H38A0FC +38A0FC:lI98|H38A16C +38A16C:lI47|H38A1DC +38A1DC:lI99|H38A244 +38A244:lI111|H38A2AC +38A2AC:lI115|H38A314 +38A314:lI70|H38A37C +38A37C:lI105|H38A3E4 +38A3E4:lI108|H38A43C +38A43C:lI101|H38A48C +38A48C:lI84|H38A4DC +38A4DC:lI114|H38A524 +38A524:lI97|H38A56C +38A56C:lI110|H38A5B4 +38A5B4:lI115|H38A5FC +38A5FC:lI102|H38A644 +38A644:lI101|H38A67C +38A67C:lI114|H38A6B4 +38A6B4:lI47|H38A6DC +38A6DC:lI101|H38A6F4 +38A6F4:lI98|H38A70C +38A70C:lI105|H38A71C +38A71C:lI110|N +38B0B8:lH388E8C|H38B0C0 +388E8C:lI47|H388F9C +388F9C:lI99|H3890B4 +3890B4:lI108|H3891C4 +3891C4:lI101|H3892D4 +3892D4:lI97|H3893E4 +3893E4:lI114|H3894F4 +3894F4:lI99|H3895FC +3895FC:lI97|H3896F4 +3896F4:lI115|H3897EC +3897EC:lI101|H3898E4 +3898E4:lI47|H3899DC +3899DC:lI111|H389ABC +389ABC:lI116|H389B94 +389B94:lI112|H389C5C +389C5C:lI47|H389D24 +389D24:lI101|H389DEC +389DEC:lI114|H389EA4 +389EA4:lI116|H389F54 +389F54:lI115|H389FF4 +389FF4:lI47|H38A084 +38A084:lI108|H38A104 +38A104:lI105|H38A174 +38A174:lI98|H38A1E4 +38A1E4:lI47|H38A24C +38A24C:lI99|H38A2B4 +38A2B4:lI111|H38A31C +38A31C:lI115|H38A384 +38A384:lI69|H38A3EC +38A3EC:lI118|H38A444 +38A444:lI101|H38A494 +38A494:lI110|H38A4E4 +38A4E4:lI116|H38A52C +38A52C:lI68|H38A574 +38A574:lI111|H38A5BC +38A5BC:lI109|H38A604 +38A604:lI97|H38A64C +38A64C:lI105|H38A684 +38A684:lI110|H38A6BC +38A6BC:lI47|H38A6E4 +38A6E4:lI101|H38A6FC +38A6FC:lI98|H38A714 +38A714:lI105|H38A724 +38A724:lI110|N +38B0C0:lH388FA4|H38B0C8 +388FA4:lI47|H3890BC +3890BC:lI99|H3891CC +3891CC:lI108|H3892DC +3892DC:lI101|H3893EC +3893EC:lI97|H3894FC +3894FC:lI114|H389604 +389604:lI99|H3896FC +3896FC:lI97|H3897F4 +3897F4:lI115|H3898EC +3898EC:lI101|H3899E4 +3899E4:lI47|H389AC4 +389AC4:lI111|H389B9C +389B9C:lI116|H389C64 +389C64:lI112|H389D2C +389D2C:lI47|H389DF4 +389DF4:lI101|H389EAC +389EAC:lI114|H389F5C +389F5C:lI116|H389FFC +389FFC:lI115|H38A08C +38A08C:lI47|H38A10C +38A10C:lI108|H38A17C +38A17C:lI105|H38A1EC +38A1EC:lI98|H38A254 +38A254:lI47|H38A2BC +38A2BC:lI99|H38A324 +38A324:lI111|H38A38C +38A38C:lI115|H38A3F4 +38A3F4:lI69|H38A44C +38A44C:lI118|H38A49C +38A49C:lI101|H38A4EC +38A4EC:lI110|H38A534 +38A534:lI116|H38A57C +38A57C:lI47|H38A5C4 +38A5C4:lI101|H38A60C +38A60C:lI98|H38A654 +38A654:lI105|H38A68C +38A68C:lI110|N +38B0C8:lH3890C4|H38B0D0 +3890C4:lI47|H3891D4 +3891D4:lI99|H3892E4 +3892E4:lI108|H3893F4 +3893F4:lI101|H389504 +389504:lI97|H38960C +38960C:lI114|H389704 +389704:lI99|H3897FC +3897FC:lI97|H3898F4 +3898F4:lI115|H3899EC +3899EC:lI101|H389ACC +389ACC:lI47|H389BA4 +389BA4:lI111|H389C6C +389C6C:lI116|H389D34 +389D34:lI112|H389DFC +389DFC:lI47|H389EB4 +389EB4:lI101|H389F64 +389F64:lI114|H38A004 +38A004:lI116|H38A094 +38A094:lI115|H38A114 +38A114:lI47|H38A184 +38A184:lI108|H38A1F4 +38A1F4:lI105|H38A25C +38A25C:lI98|H38A2C4 +38A2C4:lI47|H38A32C +38A32C:lI99|H38A394 +38A394:lI111|H38A3FC +38A3FC:lI109|H38A454 +38A454:lI112|H38A4A4 +38A4A4:lI105|H38A4F4 +38A4F4:lI108|H38A53C +38A53C:lI101|H38A584 +38A584:lI114|H38A5CC +38A5CC:lI47|H38A614 +38A614:lI101|H38A65C +38A65C:lI98|H38A694 +38A694:lI105|H38A6C4 +38A6C4:lI110|N +38B0D0:lH3891DC|H38B0D8 +3891DC:lI47|H3892EC +3892EC:lI99|H3893FC +3893FC:lI108|H38950C +38950C:lI101|H389614 +389614:lI97|H38970C +38970C:lI114|H389804 +389804:lI99|H3898FC +3898FC:lI97|H3899F4 +3899F4:lI115|H389AD4 +389AD4:lI101|H389BAC +389BAC:lI47|H389C74 +389C74:lI111|H389D3C +389D3C:lI116|H389E04 +389E04:lI112|H389EBC +389EBC:lI47|H389F6C +389F6C:lI101|H38A00C +38A00C:lI114|H38A09C +38A09C:lI116|H38A11C +38A11C:lI115|H38A18C +38A18C:lI47|H38A1FC +38A1FC:lI108|H38A264 +38A264:lI105|H38A2CC +38A2CC:lI98|H38A334 +38A334:lI47|H38A39C +38A39C:lI97|H38A404 +38A404:lI115|H38A45C +38A45C:lI110|H38A4AC +38A4AC:lI49|H38A4FC +38A4FC:lI47|H38A544 +38A544:lI101|H38A58C +38A58C:lI98|H38A5D4 +38A5D4:lI105|H38A61C +38A61C:lI110|N +38B0D8:lH3892F4|H38B0E0 +3892F4:lI47|H389404 +389404:lI99|H389514 +389514:lI108|H38961C +38961C:lI101|H389714 +389714:lI97|H38980C +38980C:lI114|H389904 +389904:lI99|H3899FC +3899FC:lI97|H389ADC +389ADC:lI115|H389BB4 +389BB4:lI101|H389C7C +389C7C:lI47|H389D44 +389D44:lI111|H389E0C +389E0C:lI116|H389EC4 +389EC4:lI112|H389F74 +389F74:lI47|H38A014 +38A014:lI101|H38A0A4 +38A0A4:lI114|H38A124 +38A124:lI116|H38A194 +38A194:lI115|H38A204 +38A204:lI47|H38A26C +38A26C:lI108|H38A2D4 +38A2D4:lI105|H38A33C +38A33C:lI98|H38A3A4 +38A3A4:lI47|H38A40C +38A40C:lI97|H38A464 +38A464:lI112|H38A4B4 +38A4B4:lI112|H38A504 +38A504:lI109|H38A54C +38A54C:lI111|H38A594 +38A594:lI110|H38A5DC +38A5DC:lI47|H38A624 +38A624:lI101|H38A664 +38A664:lI98|H38A69C +38A69C:lI105|H38A6CC +38A6CC:lI110|N +38B0E0:lH38AA88|H38B0E8 +38AA88:lI47|H38AA90 +38AA90:lI104|H38AA98 +38AA98:lI111|H38AAA0 +38AAA0:lI109|H38AAA8 +38AAA8:lI101|H38AAB0 +38AAB0:lI47|H38AAB8 +38AAB8:lI115|H38AAC0 +38AAC0:lI105|H38AAC8 +38AAC8:lI114|H38AAD0 +38AAD0:lI105|H38AAD8 +38AAD8:lI47|H38AAE0 +38AAE0:lI101|H38AAE8 +38AAE8:lI114|H38AAF0 +38AAF0:lI108|H38AAF8 +38AAF8:lI97|H38AB00 +38AB00:lI110|H38AB08 +38AB08:lI103|N +38B0E8:lH38AB1C|H38B0F0 +38AB1C:lI47|H38AB2C +38AB2C:lI104|H38AB4C +38AB4C:lI111|H38AB74 +38AB74:lI109|H38ABA4 +38ABA4:lI101|H38ABC4 +38ABC4:lI47|H38ABE4 +38ABE4:lI115|H38AC04 +38AC04:lI105|H38AC24 +38AC24:lI114|H38AC3C +38AC3C:lI105|H38AC44 +38AC44:lI47|H38AC4C +38AC4C:lI116|H38AC54 +38AC54:lI111|H38AC5C +38AC5C:lI111|H38AC64 +38AC64:lI108|H38AC6C +38AC6C:lI115|H38AC74 +38AC74:lI47|H38AC7C +38AC7C:lI100|H38AC84 +38AC84:lI105|H38AC8C +38AC8C:lI115|H38AC94 +38AC94:lI116|H38AC9C +38AC9C:lI101|H38ACA4 +38ACA4:lI108|H38ACAC +38ACAC:lI47|H38ACB4 +38ACB4:lI101|H38ACBC +38ACBC:lI98|H38ACC4 +38ACC4:lI105|H38ACCC +38ACCC:lI110|N +38B0F0:lH38B0F8|N +38B0F8:lI47|H38B100 +38B100:lI104|H38B108 +38B108:lI111|H38B110 +38B110:lI109|H38B118 +38B118:lI101|H38B120 +38B120:lI47|H38B128 +38B128:lI115|H38B130 +38B130:lI105|H38B138 +38B138:lI114|H38B140 +38B140:lI105|H38B148 +38B148:lI47|H38B150 +38B150:lI79|H38B158 +38B158:lI84|H38B160 +38B160:lI80|H38B168 +38B168:lI47|H38B170 +38B170:lI103|H38B178 +38B178:lI112|H38B180 +38B180:lI114|H38B188 +38B188:lI115|H38B190 +38B190:lI95|H38B198 +38B198:lI116|H38B1A0 +38B1A0:lI114|H38B1A8 +38B1A8:lI97|H38B1B0 +38B1B0:lI99|H38B1B8 +38B1B8:lI101|H38B1C0 +38B1C0:lI47|H38B1C8 +38B1C8:lI106|H38B1D0 +38B1D0:lI97|H38B1D8 +38B1D8:lI110|N +3873BC:lI47|H3873CC +3873CC:lI99|H3873E4 +3873E4:lI108|H3873FC +3873FC:lI101|H38741C +38741C:lI97|H387444 +387444:lI114|H387474 +387474:lI99|H3874AC +3874AC:lI97|H3874EC +3874EC:lI115|H387534 +387534:lI101|H387584 +387584:lI47|H3875DC +3875DC:lI111|H38763C +38763C:lI116|H3876A4 +3876A4:lI112|H387714 +387714:lI47|H38778C +38778C:lI101|H38780C +38780C:lI114|H387894 +387894:lI116|H387924 +387924:lI115|N +=proc_dictionary:<0.19.0> +H370244 +H370250 +=proc_stack:<0.19.0> +36b45c:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A11:supervisor_bridge +y3:H36B17C +y4:P<0.19.0> +y5:P<0.9.0> +36b478:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H37025C +=proc_heap:<0.19.0> +36B17C:t5:A5:state,A8:user_sup,P<0.21.0>,P<0.21.0>,H370238 +370238:t2:P<0.19.0>,A8:user_sup +37025C:lAA:gen_server|H37027C +37027C:lP<0.9.0>|H37028C +37028C:lP<0.9.0>|H370294 +370294:lA11:supervisor_bridge|H37029C +37029C:lH3702A4|H3702AC +3702A4:lA8:user_sup|H3702B4 +3702B4:lN|H3702BC +3702BC:lA4:self|N +3702AC:lN|N +370244:t2:AD:$initial_call,H370264 +370264:t3:A3:gen,A7:init_it,H37025C +370250:t2:AA:$ancestors,H370274 +370274:lAA:kernel_sup|H370284 +370284:lP<0.8.0>|N +=proc_dictionary:<0.20.0> +H36F8A8 +=proc_stack:<0.20.0> +36a714:SReturn addr 0x156F90 (<terminate process normally>) +y0:N +y1:N +y2:H36F8C4 +y3:P<0.21.0> +y4:P<0.22.0> +y5:p<0.72> +y6:p<0.72> +=proc_heap:<0.20.0> +36F8C4:t4:I3,I2,P<0.22.0>,H36F8F0 +36F8F0:lH36F900|H36F910 +36F900:t3:I1,P<0.21.0>,H36F920 +36F920:t0: +36F910:lH36F924|N +36F924:t3:I2,P<0.22.0>,H36F93C +36F93C:t3:A5:shell,A5:start,N +36F8A8:t2:A3:eof,A5:false +=proc_dictionary:<0.21.0> +H3709DC +H3709D0 +H3709F8 +=proc_stack:<0.21.0> +370d1c:SReturn addr 0x156F90 (<terminate process normally>) +y0:N +y1:A9:undefined +y2:P<0.20.0> +=proc_heap:<0.21.0> +3709DC:t2:AB:line_buffer,N +3709D0:t2:AB:kill_buffer,N +3709F8:t2:A9:read_mode,A4:list +=proc_dictionary:<0.22.0> +H370D44 +H370D60 +H370D7C +H370D38 +=proc_stack:<0.22.0> +374a88:SReturn addr 0x2CE718 (group:get_chars_loop/7 + 80) +y0:N +y1:N +y2:A8:infinity +y3:H374A00 +y4:P<0.20.0> +y5:H374A28 +374aa4:SReturn addr 0x2CDC18 (group:io_request/5 + 48) +y0:H37499C +y1:A6:io_lib +y2:A9:get_until +y3:H3748B8 +y4:P<0.20.0> +y5:A5:start +374ac0:SReturn addr 0x2CDB2C (group:server_loop/3 + 372) +y0:P<0.49.0> +y1:P<0.22.0> +374acc:SReturn addr 0x156F90 (<terminate process normally>) +y0:N +y1:P<0.25.0> +y2:P<0.20.0> +=proc_heap:<0.22.0> +374A00:t4:A4:line,H37499C,H3749A4,A4:none +3749A4:t2:N,N +37499C:lI50|H374994 +374994:lI62|H37498C +37498C:lI32|N +374A28:t4:A5:stack,H370D58,H374A24,N +374A24:t0: +370D58:lH370D74|N +370D74:lI99|H370D88 +370D88:lI114|H370D90 +370D90:lI97|H370D98 +370D98:lI115|H370DA0 +370DA0:lI104|H370DA8 +370DA8:lI100|H370DB0 +370DB0:lI117|H370DB8 +370DB8:lI109|H370DC0 +370DC0:lI112|H370DC8 +370DC8:lI95|H370DD0 +370DD0:lI118|H370DD8 +370DD8:lI105|H370DE0 +370DE0:lI101|H370DE8 +370DE8:lI119|H370DF0 +370DF0:lI101|H370DF8 +370DF8:lI114|H370E00 +370E00:lI58|H370E08 +370E08:lI115|H370E10 +370E10:lI116|H370E18 +370E18:lI97|H370E20 +370E20:lI114|H370E28 +370E28:lI116|H370E30 +370E30:lI40|H370E38 +370E38:lI41|H370E40 +370E40:lI46|H370E48 +370E48:lI10|N +3748B8:t3:A8:erl_scan,A6:tokens,H3748B0 +3748B0:lI1|N +370D44:t2:AB:line_buffer,H370D58 +370D60:t2:A5:shell,P<0.25.0> +370D7C:t2:AB:kill_buffer,N +370D38:t2:A9:read_mode,A4:list +=proc_dictionary:<0.23.0> +H376464 +H376448 +=proc_stack:<0.23.0> +376754:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AD:kernel_config +y3:N +y4:P<0.23.0> +y5:P<0.9.0> +376770:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H376418 +=proc_heap:<0.23.0> +376418:lAA:gen_server|H376410 +376410:lP<0.9.0>|H376408 +376408:lP<0.9.0>|H376400 +376400:lAD:kernel_config|H3763F8 +3763F8:lN|H3763F0 +3763F0:lN|N +376464:t2:AD:$initial_call,H376454 +376454:t3:A3:gen,A7:init_it,H376418 +376448:t2:AA:$ancestors,H376440 +376440:lAA:kernel_sup|H376420 +376420:lP<0.8.0>|N +=proc_dictionary:<0.24.0> +H3705E0 +H3705EC +=proc_stack:<0.24.0> +36f38c:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AA:supervisor +y3:H36F018 +y4:AF:kernel_safe_sup +y5:P<0.9.0> +36f3a8:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H37063C +=proc_heap:<0.24.0> +36F018:tA:A5:state,H370644,AB:one_for_one,H36F044,N,I4,I3600,N,A6:kernel,A4:safe +36F044:lH36F04C|N +36F04C:t8:A5:child,P<0.31.0>,A17:inet_gethost_native_sup,H370650,A9:temporary,I1000,A6:worker,H370660 +370660:lA13:inet_gethost_native|N +370650:t3:A13:inet_gethost_native,AA:start_link,N +370644:t2:A5:local,AF:kernel_safe_sup +37063C:lAA:gen_server|H3706AC +3706AC:lP<0.9.0>|H3706BC +3706BC:lP<0.9.0>|H3706C4 +3706C4:lH3706CC|H3706D8 +3706CC:t2:A5:local,AF:kernel_safe_sup +3706D8:lAA:supervisor|H3706E0 +3706E0:lH3706E8|H3706F8 +3706E8:t3:H370644,A6:kernel,A4:safe +3706F8:lN|N +3705E0:t2:AD:$initial_call,H370668 +370668:t3:A3:gen,A7:init_it,H37063C +3705EC:t2:AA:$ancestors,H370678 +370678:lAA:kernel_sup|H3706B4 +3706B4:lP<0.8.0>|N +=proc_dictionary:<0.25.0> +H36E304 +H36E31C +=proc_stack:<0.25.0> +36e610:SReturn addr 0x2E06FC (shell:server_loop/6 + 140) +y0:N +y1:N +y2:P<0.27.0> +y3:P<0.49.0> +36e624:SReturn addr 0x156F90 (<terminate process normally>) +y0:N +y1:N +y2:I2 +y3:I1 +y4:N +y5:N +y6:N +y7:I20 +y8:I20 +=proc_heap:<0.25.0> +36E304:t2:H36E2F8,H36E2A8 +36E2A8:lH36E2B0|N +36E2B0:t4:A4:call,I1,H36E2C4,N +36E2C4:t4:A6:remote,I1,H36E2D8,H36E2E8 +36E2E8:t3:A4:atom,I1,A5:start +36E2D8:t3:A4:atom,I1,A10:crashdump_viewer +36E2F8:t2:A7:command,I1 +36E31C:t2:H36E310,A2:ok +36E310:t2:A6:result,I1 +=proc_stack:<0.27.0> +3bda3c:SReturn addr 0x156F90 (<terminate process normally>) +y0:N +y1:N +y2:P<0.25.0> +=proc_heap:<0.27.0> +=proc_dictionary:<0.31.0> +H36DA24 +H36DA08 +=proc_stack:<0.31.0> +36dcd4:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A11:supervisor_bridge +y3:H36DB68 +y4:A17:inet_gethost_native_sup +y5:P<0.24.0> +36dcf0:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H36D9D0 +=proc_heap:<0.31.0> +36DB68:t5:A5:state,A13:inet_gethost_native,P<0.32.0>,P<0.32.0>,H36D994 +36D994:t2:A5:local,A17:inet_gethost_native_sup +36D9D0:lAA:gen_server|H36D9C8 +36D9C8:lP<0.24.0>|H36D9C0 +36D9C0:lP<0.24.0>|H36D970 +36D970:lH36D980|H36D9B8 +36D980:t2:A5:local,A17:inet_gethost_native_sup +36D9B8:lA11:supervisor_bridge|H36D978 +36D978:lH36D9A8|H36D9B0 +36D9A8:lA13:inet_gethost_native|H36D9A0 +36D9A0:lN|H36D98C +36D98C:lH36D994|N +36D9B0:lN|N +36DA24:t2:AD:$initial_call,H36DA14 +36DA14:t3:A3:gen,A7:init_it,H36D9D0 +36DA08:t2:AA:$ancestors,H36DA00 +36DA00:lAF:kernel_safe_sup|H36D9E0 +36D9E0:lAA:kernel_sup|H36D9D8 +36D9D8:lP<0.8.0>|N +=proc_dictionary:<0.32.0> +H36CFD4 +H36D0BC +=proc_stack:<0.32.0> +36d12c:SReturn addr 0x156F90 (<terminate process normally>) +y0:H36CF18 +=proc_heap:<0.32.0> +36CF18:t8:A5:state,p<0.105>,I8000,I11,I12,P<0.31.0>,I4,H36CEF0 +36CEF0:t9:AA:statistics,I0,I0,I0,I0,I0,I0,I0,I0 +36CFD4:t2:A3:rid,I1 +36D0BC:t2:AC:num_requests,I0 +=proc_dictionary:<0.33.0> +H3905C4 +H3905D0 +=proc_stack:<0.33.0> +3ceee4:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A7:webtool +y3:H3C8570 +y4:A8:web_tool +y5:P<0.33.0> +3cef00:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H3905FC +=proc_heap:<0.33.0> +3C8570:t6:A5:state,H3905EC,I13,P<0.41.0>,H3905F4,H3C85D4 +3C85D4:lA10:crashdump_viewer|N +3905F4:lH390650|H39065C +390650:t2:A4:port,I8888 +39065C:lH3906C8|H3906D4 +3906C8:t2:AC:bind_address,H390760 +390760:t4:I127,I0,I0,I1 +3906D4:lH390774|H390780 +390774:t2:AB:server_name,H39082C +39082C:lI108|H390908 +390908:lI111|H3909DC +3909DC:lI99|H390AC0 +390AC0:lI97|H390B98 +390B98:lI108|H390C78 +390C78:lI104|H390D58 +390D58:lI111|H390E2C +390E2C:lI115|H390F10 +390F10:lI116|N +390780:lH390834|H390840 +390834:t2:AE:max_header_siz,I1024 +390840:lH390910|H39091C +390910:t2:A11:max_header_action,A8:reply414 +39091C:lH3909E4|H3909F0 +3909E4:t2:A8:com_type,A7:ip_comm +3909F0:lH390AC8|H390AD4 +390AC8:t2:A7:modules,H390BA0 +390BA0:lA9:mod_alias|H390C80 +390C80:lA8:mod_auth|H390D60 +390D60:lA7:mod_esi|H390E34 +390E34:lAB:mod_actions|H390F18 +390F18:lA7:mod_cgi|H390FF4 +390FF4:lAB:mod_include|H3910D8 +3910D8:lA7:mod_dir|H3911B4 +3911B4:lA7:mod_get|H3912A0 +3912A0:lA8:mod_head|H39139C +39139C:lA7:mod_log|H3914A0 +3914A0:lAC:mod_disk_log|N +390AD4:lH390BA8|H390BB4 +390BA8:t2:AF:directory_index,H390C88 +390C88:lH390D68|N +390D68:lI105|H390E3C +390E3C:lI110|H390F20 +390F20:lI100|H390FFC +390FFC:lI101|H3910E0 +3910E0:lI120|H3911BC +3911BC:lI46|H3912A8 +3912A8:lI104|H3913A4 +3913A4:lI116|H3914A8 +3914A8:lI109|H39159C +39159C:lI108|N +390BB4:lH390C90|N +390C90:t2:AC:default_type,H390D70 +390D70:lI116|H390E44 +390E44:lI101|H390F28 +390F28:lI120|H391004 +391004:lI116|H3910E8 +3910E8:lI47|H3911C4 +3911C4:lI112|H3912B0 +3912B0:lI108|H3913AC +3913AC:lI97|H3914B0 +3914B0:lI105|H3915A4 +3915A4:lI110|N +3905EC:lI47|H390648 +390648:lI99|H3906C0 +3906C0:lI108|H390758 +390758:lI101|H390824 +390824:lI97|H390900 +390900:lI114|H3909D4 +3909D4:lI99|H390AB8 +390AB8:lI97|H390B90 +390B90:lI115|H390C70 +390C70:lI101|H390D50 +390D50:lI47|H390E24 +390E24:lI111|H390F08 +390F08:lI116|H390FEC +390FEC:lI112|H3910D0 +3910D0:lI47|H3911AC +3911AC:lI101|H391298 +391298:lI114|H391394 +391394:lI116|H391498 +391498:lI115|H391594 +391594:lI47|H391680 +391680:lI108|H39175C +39175C:lI105|H391840 +391840:lI98|H391924 +391924:lI47|H3919F8 +3919F8:lI119|H391AC4 +391AC4:lI101|H391B90 +391B90:lI98|H391C54 +391C54:lI116|H391D18 +391D18:lI111|H391DD4 +391DD4:lI111|H391E90 +391E90:lI108|H391F5C +391F5C:lI47|H392030 +392030:lI112|H3920EC +3920EC:lI114|H3921A8 +3921A8:lI105|H392264 +392264:lI118|N +3905FC:lAA:gen_server|H390664 +390664:lP<0.27.0>|H3906DC +3906DC:lA4:self|H390788 +390788:lH390848|H390854 +390848:t2:A5:local,A8:web_tool +390854:lA7:webtool|H390924 +390924:lH3909F8|H390A04 +3909F8:t2:H3905EC,H3905F4 +390A04:lN|N +3905C4:t2:AD:$initial_call,H390614 +390614:t3:A3:gen,A7:init_it,H3905FC +3905D0:t2:AA:$ancestors,H390624 +390624:lP<0.27.0>|N +=proc_dictionary:<0.41.0> +H36DF0C +H36DF18 +=proc_stack:<0.41.0> +36eda4:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AA:supervisor +y3:H36EA3C +y4:A6:websup +y5:P<0.33.0> +36edc0:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H36DF24 +=proc_heap:<0.41.0> +36EA3C:tA:A5:state,H36DF2C,AB:one_for_one,H36EA68,N,I100,I10,N,AB:webtool_sup,N +36EA68:lH36EA70|N +36EA70:t8:A5:child,P<0.48.0>,H36DF38,H36DF44,A9:permanent,I100,A6:worker,H36DF54 +36DF54:lA10:crashdump_viewer|N +36DF44:t3:A10:crashdump_viewer,AA:start_link,N +36DF38:t2:A5:local,A17:crashdump_viewer_server +36DF2C:t2:A5:local,A6:websup +36DF24:lAA:gen_server|H36DF84 +36DF84:lP<0.33.0>|H36DF94 +36DF94:lP<0.33.0>|H36DF9C +36DF9C:lH36DFA4|H36DFB0 +36DFA4:t2:A5:local,A6:websup +36DFB0:lAA:supervisor|H36DFB8 +36DFB8:lH36DFC0|H36DFD0 +36DFC0:t3:H36DF2C,AB:webtool_sup,N +36DFD0:lN|N +36DF0C:t2:AD:$initial_call,H36DF6C +36DF6C:t3:A3:gen,A7:init_it,H36DF24 +36DF18:t2:AA:$ancestors,H36DF7C +36DF7C:lA8:web_tool|H36DF8C +36DF8C:lP<0.27.0>|N +=proc_dictionary:<0.43.0> +H39D940 +H39D94C +=proc_stack:<0.43.0> +3a42ac:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AA:supervisor +y3:H3A3E34 +y4:A1A:httpd_sup__127_0_0_1__8888 +y5:P<0.33.0> +3a42c8:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H39D9CC +=proc_heap:<0.43.0> +3A3E34:tA:A5:state,H39D960,AB:one_for_one,H3A3E20,N,I0,I1,N,A9:httpd_sup,H39DA88 +39DA88:lA9:undefined|H39DB18 +39DB18:lH39DB50|H39DB58 +39DB50:lH39DB88|H39DB94 +39DB88:t2:AB:server_root,H39DBD0 +39DBD0:lI47|H39DC0C +39DC0C:lI99|H39DC50 +39DC50:lI108|H39DC84 +39DC84:lI101|H39DCC4 +39DCC4:lI97|H39DD28 +39DD28:lI114|H39DD90 +39DD90:lI99|H39DE00 +39DE00:lI97|H39DE78 +39DE78:lI115|H39DF00 +39DF00:lI101|H39DF90 +39DF90:lI47|H39E038 +39E038:lI111|H39E0E8 +39E0E8:lI116|H39E1AC +39E1AC:lI112|H39E288 +39E288:lI47|H39E37C +39E37C:lI101|H39E478 +39E478:lI114|H39E580 +39E580:lI116|H39E69C +39E69C:lI115|H39E7B0 +39E7B0:lI47|H39E8C4 +39E8C4:lI108|H39E9D8 +39E9D8:lI105|H39EACC +39EACC:lI98|H39EBC0 +39EBC0:lI47|H39ECB4 +39ECB4:lI119|H39EDA8 +39EDA8:lI101|H39EE7C +39EE7C:lI98|H39EF50 +39EF50:lI116|H39F02C +39F02C:lI111|H39F110 +39F110:lI111|H39F1E4 +39F1E4:lI108|H39F2B0 +39F2B0:lI47|H39F36C +39F36C:lI112|H39F430 +39F430:lI114|H39F4FC +39F4FC:lI105|H39F5C0 +39F5C0:lI118|H39F694 +39F694:lI47|H39F768 +39F768:lI114|H39F83C +39F83C:lI111|H39F920 +39F920:lI111|H39F9FC +39F9FC:lI116|N +39DB94:lH39DBD8|H39DBE4 +39DBD8:t2:AD:document_root,H39DC14 +39DC14:lI47|H39DC58 +39DC58:lI99|H39DC8C +39DC8C:lI108|H39DCCC +39DCCC:lI101|H39DD30 +39DD30:lI97|H39DD98 +39DD98:lI114|H39DE08 +39DE08:lI99|H39DE80 +39DE80:lI97|H39DF08 +39DF08:lI115|H39DF98 +39DF98:lI101|H39E040 +39E040:lI47|H39E0F0 +39E0F0:lI111|H39E1B4 +39E1B4:lI116|H39E290 +39E290:lI112|H39E384 +39E384:lI47|H39E480 +39E480:lI101|H39E588 +39E588:lI114|H39E6A4 +39E6A4:lI116|H39E7B8 +39E7B8:lI115|H39E8CC +39E8CC:lI47|H39E9E0 +39E9E0:lI108|H39EAD4 +39EAD4:lI105|H39EBC8 +39EBC8:lI98|H39ECBC +39ECBC:lI47|H39EDB0 +39EDB0:lI119|H39EE84 +39EE84:lI101|H39EF58 +39EF58:lI98|H39F034 +39F034:lI116|H39F118 +39F118:lI111|H39F1EC +39F1EC:lI111|H39F2B8 +39F2B8:lI108|H39F374 +39F374:lI47|H39F438 +39F438:lI112|H39F504 +39F504:lI114|H39F5C8 +39F5C8:lI105|H39F69C +39F69C:lI118|H39F770 +39F770:lI47|H39F844 +39F844:lI114|H39F928 +39F928:lI111|H39FA04 +39FA04:lI111|H39FAD8 +39FAD8:lI116|H39FBB4 +39FBB4:lI47|H39FC80 +39FC80:lI100|H39FD44 +39FD44:lI111|H39FE10 +39FE10:lI99|N +39DBE4:lH39DC1C|H39DC28 +39DC1C:t2:AA:mime_types,H39DC60 +39DC60:lH39DC94|H39DCA0 +39DC94:t2:H39DCD4,H39DCDC +39DCDC:lI120|H39DD40 +39DD40:lI45|H39DDA8 +39DDA8:lI119|H39DE10 +39DE10:lI111|H39DE88 +39DE88:lI114|H39DF10 +39DF10:lI108|H39DFA0 +39DFA0:lI100|H39E048 +39E048:lI47|H39E0F8 +39E0F8:lI120|H39E1BC +39E1BC:lI45|H39E298 +39E298:lI118|H39E38C +39E38C:lI114|H39E488 +39E488:lI109|H39E590 +39E590:lI108|N +39DCD4:lI119|H39DD38 +39DD38:lI114|H39DDA0 +39DDA0:lI108|N +39DCA0:lH39DCE4|H39DCF0 +39DCE4:t2:H39DD48,H39DD50 +39DD50:lI120|H39DDB8 +39DDB8:lI45|H39DE20 +39DE20:lI119|H39DE98 +39DE98:lI111|H39DF18 +39DF18:lI114|H39DFA8 +39DFA8:lI108|H39E050 +39E050:lI100|H39E100 +39E100:lI47|H39E1C4 +39E1C4:lI120|H39E2A0 +39E2A0:lI45|H39E394 +39E394:lI118|H39E490 +39E490:lI114|H39E598 +39E598:lI109|H39E6AC +39E6AC:lI108|N +39DD48:lI118|H39DDB0 +39DDB0:lI114|H39DE18 +39DE18:lI109|H39DE90 +39DE90:lI108|N +39DCF0:lH39DD58|H39DD64 +39DD58:t2:H39DDC0,H39DDC8 +39DDC8:lI120|H39DE30 +39DE30:lI45|H39DEA8 +39DEA8:lI99|H39DF20 +39DF20:lI111|H39DFB0 +39DFB0:lI110|H39E058 +39E058:lI102|H39E108 +39E108:lI101|H39E1CC +39E1CC:lI114|H39E2A8 +39E2A8:lI101|H39E39C +39E39C:lI110|H39E498 +39E498:lI99|H39E5A0 +39E5A0:lI101|H39E6B4 +39E6B4:lI47|H39E7C0 +39E7C0:lI120|H39E8D4 +39E8D4:lI45|H39E9E8 +39E9E8:lI99|H39EADC +39EADC:lI111|H39EBD0 +39EBD0:lI111|H39ECC4 +39ECC4:lI108|H39EDB8 +39EDB8:lI116|H39EE8C +39EE8C:lI97|H39EF60 +39EF60:lI108|H39F03C +39F03C:lI107|N +39DDC0:lI105|H39DE28 +39DE28:lI99|H39DEA0 +39DEA0:lI101|N +39DD64:lH39DDD0|H39DDDC +39DDD0:t2:H39DE38,H39DE40 +39DE40:lI118|H39DEB8 +39DEB8:lI105|H39DF30 +39DF30:lI100|H39DFC0 +39DFC0:lI101|H39E068 +39E068:lI111|H39E110 +39E110:lI47|H39E1D4 +39E1D4:lI120|H39E2B0 +39E2B0:lI45|H39E3A4 +39E3A4:lI115|H39E4A0 +39E4A0:lI103|H39E5A8 +39E5A8:lI105|H39E6BC +39E6BC:lI45|H39E7C8 +39E7C8:lI109|H39E8DC +39E8DC:lI111|H39E9F0 +39E9F0:lI118|H39EAE4 +39EAE4:lI105|H39EBD8 +39EBD8:lI101|N +39DE38:lI109|H39DEB0 +39DEB0:lI111|H39DF28 +39DF28:lI118|H39DFB8 +39DFB8:lI105|H39E060 +39E060:lI101|N +39DDDC:lH39DE48|H39DE54 +39DE48:t2:H39DEC0,H39DEC8 +39DEC8:lI118|H39DF40 +39DF40:lI105|H39DFD0 +39DFD0:lI100|H39E070 +39E070:lI101|H39E118 +39E118:lI111|H39E1DC +39E1DC:lI47|H39E2B8 +39E2B8:lI120|H39E3AC +39E3AC:lI45|H39E4A8 +39E4A8:lI109|H39E5B0 +39E5B0:lI115|H39E6C4 +39E6C4:lI118|H39E7D0 +39E7D0:lI105|H39E8E4 +39E8E4:lI100|H39E9F8 +39E9F8:lI101|H39EAEC +39EAEC:lI111|N +39DEC0:lI97|H39DF38 +39DF38:lI118|H39DFC8 +39DFC8:lI105|N +39DE54:lH39DED0|H39DEDC +39DED0:t2:H39DF48,H39DF50 +39DF50:lI118|H39DFE0 +39DFE0:lI105|H39E078 +39E078:lI100|H39E120 +39E120:lI101|H39E1E4 +39E1E4:lI111|H39E2C0 +39E2C0:lI47|H39E3B4 +39E3B4:lI113|H39E4B0 +39E4B0:lI117|H39E5B8 +39E5B8:lI105|H39E6CC +39E6CC:lI99|H39E7D8 +39E7D8:lI107|H39E8EC +39E8EC:lI116|H39EA00 +39EA00:lI105|H39EAF4 +39EAF4:lI109|H39EBE0 +39EBE0:lI101|N +39DF48:lI113|H39DFD8 +39DFD8:lI116|N +39DEDC:lH39DF58|H39DF64 +39DF58:t2:H39DFE8,H39DFF0 +39DFF0:lI118|H39E088 +39E088:lI105|H39E130 +39E130:lI100|H39E1EC +39E1EC:lI101|H39E2C8 +39E2C8:lI111|H39E3BC +39E3BC:lI47|H39E4B8 +39E4B8:lI113|H39E5C0 +39E5C0:lI117|H39E6D4 +39E6D4:lI105|H39E7E0 +39E7E0:lI99|H39E8F4 +39E8F4:lI107|H39EA08 +39EA08:lI116|H39EAFC +39EAFC:lI105|H39EBE8 +39EBE8:lI109|H39ECCC +39ECCC:lI101|N +39DFE8:lI109|H39E080 +39E080:lI111|H39E128 +39E128:lI118|N +39DF64:lH39DFF8|H39E004 +39DFF8:t2:H39E090,H39E098 +39E098:lI118|H39E140 +39E140:lI105|H39E1FC +39E1FC:lI100|H39E2D8 +39E2D8:lI101|H39E3C4 +39E3C4:lI111|H39E4C0 +39E4C0:lI47|H39E5C8 +39E5C8:lI109|H39E6DC +39E6DC:lI112|H39E7E8 +39E7E8:lI101|H39E8FC +39E8FC:lI103|N +39E090:lI109|H39E138 +39E138:lI112|H39E1F4 +39E1F4:lI101|H39E2D0 +39E2D0:lI103|N +39E004:lH39E0A0|H39E0AC +39E0A0:t2:H39E148,H39E150 +39E150:lI118|H39E20C +39E20C:lI105|H39E2E8 +39E2E8:lI100|H39E3CC +39E3CC:lI101|H39E4C8 +39E4C8:lI111|H39E5D0 +39E5D0:lI47|H39E6E4 +39E6E4:lI109|H39E7F0 +39E7F0:lI112|H39E904 +39E904:lI101|H39EA10 +39EA10:lI103|N +39E148:lI109|H39E204 +39E204:lI112|H39E2E0 +39E2E0:lI103|N +39E0AC:lH39E158|H39E164 +39E158:t2:H39E214,H39E21C +39E21C:lI118|H39E2F8 +39E2F8:lI105|H39E3DC +39E3DC:lI100|H39E4D0 +39E4D0:lI101|H39E5D8 +39E5D8:lI111|H39E6EC +39E6EC:lI47|H39E7F8 +39E7F8:lI109|H39E90C +39E90C:lI112|H39EA18 +39EA18:lI101|H39EB04 +39EB04:lI103|N +39E214:lI109|H39E2F0 +39E2F0:lI112|H39E3D4 +39E3D4:lI101|N +39E164:lH39E224|H39E230 +39E224:t2:H39E300,H39E308 +39E308:lI116|H39E3EC +39E3EC:lI101|H39E4E0 +39E4E0:lI120|H39E5E8 +39E5E8:lI116|H39E6F4 +39E6F4:lI47|H39E800 +39E800:lI120|H39E914 +39E914:lI45|H39EA20 +39EA20:lI115|H39EB0C +39EB0C:lI103|H39EBF0 +39EBF0:lI109|H39ECD4 +39ECD4:lI108|N +39E300:lI115|H39E3E4 +39E3E4:lI103|H39E4D8 +39E4D8:lI109|H39E5E0 +39E5E0:lI108|N +39E230:lH39E310|H39E31C +39E310:t2:H39E3F4,H39E3FC +39E3FC:lI116|H39E4F0 +39E4F0:lI101|H39E5F8 +39E5F8:lI120|H39E6FC +39E6FC:lI116|H39E808 +39E808:lI47|H39E91C +39E91C:lI120|H39EA28 +39EA28:lI45|H39EB14 +39EB14:lI115|H39EBF8 +39EBF8:lI103|H39ECDC +39ECDC:lI109|H39EDC0 +39EDC0:lI108|N +39E3F4:lI115|H39E4E8 +39E4E8:lI103|H39E5F0 +39E5F0:lI109|N +39E31C:lH39E404|H39E410 +39E404:t2:H39E4F8,H39E500 +39E500:lI116|H39E608 +39E608:lI101|H39E70C +39E70C:lI120|H39E810 +39E810:lI116|H39E924 +39E924:lI47|H39EA30 +39EA30:lI120|H39EB1C +39EB1C:lI45|H39EC00 +39EC00:lI115|H39ECE4 +39ECE4:lI101|H39EDC8 +39EDC8:lI116|H39EE94 +39EE94:lI101|H39EF68 +39EF68:lI120|H39F044 +39F044:lI116|N +39E4F8:lI101|H39E600 +39E600:lI116|H39E704 +39E704:lI120|N +39E410:lH39E508|H39E514 +39E508:t2:H39E610,H39E618 +39E618:lI116|H39E71C +39E71C:lI101|H39E820 +39E820:lI120|H39E92C +39E92C:lI116|H39EA38 +39EA38:lI47|H39EB24 +39EB24:lI116|H39EC08 +39EC08:lI97|H39ECEC +39ECEC:lI98|H39EDD0 +39EDD0:lI45|H39EE9C +39EE9C:lI115|H39EF70 +39EF70:lI101|H39F04C +39F04C:lI112|H39F120 +39F120:lI97|H39F1F4 +39F1F4:lI114|H39F2C0 +39F2C0:lI97|H39F37C +39F37C:lI116|H39F440 +39F440:lI101|H39F50C +39F50C:lI100|H39F5D0 +39F5D0:lI45|H39F6A4 +39F6A4:lI118|H39F778 +39F778:lI97|H39F84C +39F84C:lI108|H39F930 +39F930:lI117|H39FA0C +39FA0C:lI101|H39FAE0 +39FAE0:lI115|N +39E610:lI116|H39E714 +39E714:lI115|H39E818 +39E818:lI118|N +39E514:lH39E620|H39E62C +39E620:t2:H39E724,H39E72C +39E72C:lI116|H39E830 +39E830:lI101|H39E93C +39E93C:lI120|H39EA40 +39EA40:lI116|H39EB2C +39EB2C:lI47|H39EC10 +39EC10:lI114|H39ECF4 +39ECF4:lI105|H39EDD8 +39EDD8:lI99|H39EEA4 +39EEA4:lI104|H39EF78 +39EF78:lI116|H39F054 +39F054:lI101|H39F128 +39F128:lI120|H39F1FC +39F1FC:lI116|N +39E724:lI114|H39E828 +39E828:lI116|H39E934 +39E934:lI120|N +39E62C:lH39E734|H39E740 +39E734:t2:H39E838,H39E840 +39E840:lI116|H39E94C +39E94C:lI101|H39EA50 +39EA50:lI120|H39EB34 +39EB34:lI116|H39EC18 +39EC18:lI47|H39ECFC +39ECFC:lI112|H39EDE0 +39EDE0:lI108|H39EEAC +39EEAC:lI97|H39EF80 +39EF80:lI105|H39F05C +39F05C:lI110|N +39E838:lI116|H39E944 +39E944:lI120|H39EA48 +39EA48:lI116|N +39E740:lH39E848|H39E854 +39E848:t2:H39E954,H39E95C +39E95C:lI116|H39EA60 +39EA60:lI101|H39EB44 +39EB44:lI120|H39EC28 +39EC28:lI116|H39ED0C +39ED0C:lI47|H39EDE8 +39EDE8:lI120|H39EEB4 +39EEB4:lI45|H39EF88 +39EF88:lI115|H39F064 +39F064:lI101|H39F130 +39F130:lI114|H39F204 +39F204:lI118|H39F2C8 +39F2C8:lI101|H39F384 +39F384:lI114|H39F448 +39F448:lI45|H39F514 +39F514:lI112|H39F5D8 +39F5D8:lI97|H39F6AC +39F6AC:lI114|H39F780 +39F780:lI115|H39F854 +39F854:lI101|H39F938 +39F938:lI100|H39FA14 +39FA14:lI45|H39FAE8 +39FAE8:lI104|H39FBBC +39FBBC:lI116|H39FC88 +39FC88:lI109|H39FD4C +39FD4C:lI108|N +39E954:lI115|H39EA58 +39EA58:lI104|H39EB3C +39EB3C:lI116|H39EC20 +39EC20:lI109|H39ED04 +39ED04:lI108|N +39E854:lH39E964|H39E970 +39E964:t2:H39EA68,H39EA70 +39EA70:lI116|H39EB54 +39EB54:lI101|H39EC38 +39EC38:lI120|H39ED1C +39ED1C:lI116|H39EDF0 +39EDF0:lI47|H39EEBC +39EEBC:lI104|H39EF90 +39EF90:lI116|H39F06C +39F06C:lI109|H39F138 +39F138:lI108|N +39EA68:lI104|H39EB4C +39EB4C:lI116|H39EC30 +39EC30:lI109|H39ED14 +39ED14:lI108|N +39E970:lH39EA78|H39EA84 +39EA78:t2:H39EB5C,H39EB64 +39EB64:lI116|H39EC48 +39EC48:lI101|H39ED2C +39ED2C:lI120|H39EDF8 +39EDF8:lI116|H39EEC4 +39EEC4:lI47|H39EF98 +39EF98:lI104|H39F074 +39F074:lI116|H39F140 +39F140:lI109|H39F20C +39F20C:lI108|N +39EB5C:lI104|H39EC40 +39EC40:lI116|H39ED24 +39ED24:lI109|N +39EA84:lH39EB6C|H39EB78 +39EB6C:t2:H39EC50,H39EC58 +39EC58:lI105|H39ED3C +39ED3C:lI109|H39EE08 +39EE08:lI97|H39EECC +39EECC:lI103|H39EFA0 +39EFA0:lI101|H39F07C +39F07C:lI47|H39F148 +39F148:lI120|H39F214 +39F214:lI45|H39F2D0 +39F2D0:lI120|H39F38C +39F38C:lI119|H39F450 +39F450:lI105|H39F51C +39F51C:lI110|H39F5E0 +39F5E0:lI100|H39F6B4 +39F6B4:lI111|H39F788 +39F788:lI119|H39F85C +39F85C:lI100|H39F940 +39F940:lI117|H39FA1C +39FA1C:lI109|H39FAF0 +39FAF0:lI112|N +39EC50:lI120|H39ED34 +39ED34:lI119|H39EE00 +39EE00:lI100|N +39EB78:lH39EC60|H39EC6C +39EC60:t2:H39ED44,H39ED4C +39ED4C:lI105|H39EE18 +39EE18:lI109|H39EEDC +39EEDC:lI97|H39EFA8 +39EFA8:lI103|H39F084 +39F084:lI101|H39F150 +39F150:lI47|H39F21C +39F21C:lI120|H39F2D8 +39F2D8:lI45|H39F394 +39F394:lI120|H39F458 +39F458:lI112|H39F524 +39F524:lI105|H39F5E8 +39F5E8:lI120|H39F6BC +39F6BC:lI109|H39F790 +39F790:lI97|H39F864 +39F864:lI112|N +39ED44:lI120|H39EE10 +39EE10:lI112|H39EED4 +39EED4:lI109|N +39EC6C:lH39ED54|H39ED60 +39ED54:t2:H39EE20,H39EE28 +39EE28:lI105|H39EEEC +39EEEC:lI109|H39EFB8 +39EFB8:lI97|H39F08C +39F08C:lI103|H39F158 +39F158:lI101|H39F224 +39F224:lI47|H39F2E0 +39F2E0:lI120|H39F39C +39F39C:lI45|H39F460 +39F460:lI120|H39F52C +39F52C:lI98|H39F5F0 +39F5F0:lI105|H39F6C4 +39F6C4:lI116|H39F798 +39F798:lI109|H39F86C +39F86C:lI97|H39F948 +39F948:lI112|N +39EE20:lI120|H39EEE4 +39EEE4:lI98|H39EFB0 +39EFB0:lI109|N +39ED60:lH39EE30|H39EE3C +39EE30:t2:H39EEF4,H39EEFC +39EEFC:lI105|H39EFC8 +39EFC8:lI109|H39F09C +39F09C:lI97|H39F160 +39F160:lI103|H39F22C +39F22C:lI101|H39F2E8 +39F2E8:lI47|H39F3A4 +39F3A4:lI120|H39F468 +39F468:lI45|H39F534 +39F534:lI114|H39F5F8 +39F5F8:lI103|H39F6CC +39F6CC:lI98|N +39EEF4:lI114|H39EFC0 +39EFC0:lI103|H39F094 +39F094:lI98|N +39EE3C:lH39EF04|H39EF10 +39EF04:t2:H39EFD0,H39EFD8 +39EFD8:lI105|H39F0AC +39F0AC:lI109|H39F170 +39F170:lI97|H39F234 +39F234:lI103|H39F2F0 +39F2F0:lI101|H39F3AC +39F3AC:lI47|H39F470 +39F470:lI120|H39F53C +39F53C:lI45|H39F600 +39F600:lI112|H39F6D4 +39F6D4:lI111|H39F7A0 +39F7A0:lI114|H39F874 +39F874:lI116|H39F950 +39F950:lI97|H39FA24 +39FA24:lI98|H39FAF8 +39FAF8:lI108|H39FBC4 +39FBC4:lI101|H39FC90 +39FC90:lI45|H39FD54 +39FD54:lI112|H39FE18 +39FE18:lI105|H39FECC +39FECC:lI120|H39FF88 +39FF88:lI109|H3A003C +3A003C:lI97|H3A00E8 +3A00E8:lI112|N +39EFD0:lI112|H39F0A4 +39F0A4:lI112|H39F168 +39F168:lI109|N +39EF10:lH39EFE0|H39EFEC +39EFE0:t2:H39F0B4,H39F0BC +39F0BC:lI105|H39F180 +39F180:lI109|H39F244 +39F244:lI97|H39F2F8 +39F2F8:lI103|H39F3B4 +39F3B4:lI101|H39F478 +39F478:lI47|H39F544 +39F544:lI120|H39F608 +39F608:lI45|H39F6DC +39F6DC:lI112|H39F7A8 +39F7A8:lI111|H39F87C +39F87C:lI114|H39F958 +39F958:lI116|H39FA2C +39FA2C:lI97|H39FB00 +39FB00:lI98|H39FBCC +39FBCC:lI108|H39FC98 +39FC98:lI101|H39FD5C +39FD5C:lI45|H39FE20 +39FE20:lI103|H39FED4 +39FED4:lI114|H39FF90 +39FF90:lI97|H3A0044 +3A0044:lI121|H3A00F0 +3A00F0:lI109|H3A0194 +3A0194:lI97|H3A0248 +3A0248:lI112|N +39F0B4:lI112|H39F178 +39F178:lI103|H39F23C +39F23C:lI109|N +39EFEC:lH39F0C4|H39F0D0 +39F0C4:t2:H39F188,H39F190 +39F190:lI105|H39F254 +39F254:lI109|H39F308 +39F308:lI97|H39F3BC +39F3BC:lI103|H39F480 +39F480:lI101|H39F54C +39F54C:lI47|H39F610 +39F610:lI120|H39F6E4 +39F6E4:lI45|H39F7B0 +39F7B0:lI112|H39F884 +39F884:lI111|H39F960 +39F960:lI114|H39FA34 +39FA34:lI116|H39FB08 +39FB08:lI97|H39FBD4 +39FBD4:lI98|H39FCA0 +39FCA0:lI108|H39FD64 +39FD64:lI101|H39FE28 +39FE28:lI45|H39FEDC +39FEDC:lI98|H39FF98 +39FF98:lI105|H3A004C +3A004C:lI116|H3A00F8 +3A00F8:lI109|H3A019C +3A019C:lI97|H3A0250 +3A0250:lI112|N +39F188:lI112|H39F24C +39F24C:lI98|H39F300 +39F300:lI109|N +39F0D0:lH39F198|H39F1A4 +39F198:t2:H39F25C,H39F264 +39F264:lI105|H39F318 +39F318:lI109|H39F3CC +39F3CC:lI97|H39F488 +39F488:lI103|H39F554 +39F554:lI101|H39F618 +39F618:lI47|H39F6EC +39F6EC:lI120|H39F7B8 +39F7B8:lI45|H39F88C +39F88C:lI112|H39F968 +39F968:lI111|H39FA3C +39FA3C:lI114|H39FB10 +39FB10:lI116|H39FBDC +39FBDC:lI97|H39FCA8 +39FCA8:lI98|H39FD6C +39FD6C:lI108|H39FE30 +39FE30:lI101|H39FEE4 +39FEE4:lI45|H39FFA0 +39FFA0:lI97|H3A0054 +3A0054:lI110|H3A0100 +3A0100:lI121|H3A01A4 +3A01A4:lI109|H3A0258 +3A0258:lI97|H3A0304 +3A0304:lI112|N +39F25C:lI112|H39F310 +39F310:lI110|H39F3C4 +39F3C4:lI109|N +39F1A4:lH39F26C|H39F278 +39F26C:t2:H39F320,H39F328 +39F328:lI105|H39F3DC +39F3DC:lI109|H39F498 +39F498:lI97|H39F55C +39F55C:lI103|H39F620 +39F620:lI101|H39F6F4 +39F6F4:lI47|H39F7C0 +39F7C0:lI120|H39F894 +39F894:lI45|H39F970 +39F970:lI99|H39FA44 +39FA44:lI109|H39FB18 +39FB18:lI117|H39FBE4 +39FBE4:lI45|H39FCB0 +39FCB0:lI114|H39FD74 +39FD74:lI97|H39FE38 +39FE38:lI115|H39FEEC +39FEEC:lI116|H39FFA8 +39FFA8:lI101|H3A005C +3A005C:lI114|N +39F320:lI114|H39F3D4 +39F3D4:lI97|H39F490 +39F490:lI115|N +39F278:lH39F330|H39F33C +39F330:t2:H39F3E4,H39F3EC +39F3EC:lI105|H39F4A8 +39F4A8:lI109|H39F56C +39F56C:lI97|H39F630 +39F630:lI103|H39F6FC +39F6FC:lI101|H39F7C8 +39F7C8:lI47|H39F89C +39F89C:lI116|H39F978 +39F978:lI105|H39FA4C +39FA4C:lI102|H39FB20 +39FB20:lI102|N +39F3E4:lI116|H39F4A0 +39F4A0:lI105|H39F564 +39F564:lI102|H39F628 +39F628:lI102|N +39F33C:lH39F3F4|H39F400 +39F3F4:t2:H39F4B0,H39F4B8 +39F4B8:lI105|H39F57C +39F57C:lI109|H39F640 +39F640:lI97|H39F704 +39F704:lI103|H39F7D0 +39F7D0:lI101|H39F8A4 +39F8A4:lI47|H39F980 +39F980:lI116|H39FA54 +39FA54:lI105|H39FB28 +39FB28:lI102|H39FBEC +39FBEC:lI102|N +39F4B0:lI116|H39F574 +39F574:lI105|H39F638 +39F638:lI102|N +39F400:lH39F4C0|H39F4CC +39F4C0:t2:H39F584,H39F58C +39F58C:lI105|H39F650 +39F650:lI109|H39F714 +39F714:lI97|H39F7D8 +39F7D8:lI103|H39F8AC +39F8AC:lI101|H39F988 +39F988:lI47|H39FA5C +39FA5C:lI112|H39FB30 +39FB30:lI110|H39FBF4 +39FBF4:lI103|N +39F584:lI112|H39F648 +39F648:lI110|H39F70C +39F70C:lI103|N +39F4CC:lH39F594|H39F5A0 +39F594:t2:H39F658,H39F660 +39F660:lI105|H39F724 +39F724:lI109|H39F7E8 +39F7E8:lI97|H39F8BC +39F8BC:lI103|H39F990 +39F990:lI101|H39FA64 +39FA64:lI47|H39FB38 +39FB38:lI106|H39FBFC +39FBFC:lI112|H39FCB8 +39FCB8:lI101|H39FD7C +39FD7C:lI103|N +39F658:lI106|H39F71C +39F71C:lI112|H39F7E0 +39F7E0:lI101|H39F8B4 +39F8B4:lI103|N +39F5A0:lH39F668|H39F674 +39F668:t2:H39F72C,H39F734 +39F734:lI105|H39F7F8 +39F7F8:lI109|H39F8CC +39F8CC:lI97|H39F998 +39F998:lI103|H39FA6C +39FA6C:lI101|H39FB40 +39FB40:lI47|H39FC04 +39FC04:lI106|H39FCC0 +39FCC0:lI112|H39FD84 +39FD84:lI101|H39FE40 +39FE40:lI103|N +39F72C:lI106|H39F7F0 +39F7F0:lI112|H39F8C4 +39F8C4:lI103|N +39F674:lH39F73C|H39F748 +39F73C:t2:H39F800,H39F808 +39F808:lI105|H39F8DC +39F8DC:lI109|H39F9A8 +39F9A8:lI97|H39FA74 +39FA74:lI103|H39FB48 +39FB48:lI101|H39FC0C +39FC0C:lI47|H39FCC8 +39FCC8:lI106|H39FD8C +39FD8C:lI112|H39FE48 +39FE48:lI101|H39FEF4 +39FEF4:lI103|N +39F800:lI106|H39F8D4 +39F8D4:lI112|H39F9A0 +39F9A0:lI101|N +39F748:lH39F810|H39F81C +39F810:t2:H39F8E4,H39F8EC +39F8EC:lI105|H39F9B8 +39F9B8:lI109|H39FA84 +39FA84:lI97|H39FB50 +39FB50:lI103|H39FC14 +39FC14:lI101|H39FCD0 +39FCD0:lI47|H39FD94 +39FD94:lI105|H39FE50 +39FE50:lI101|H39FEFC +39FEFC:lI102|N +39F8E4:lI105|H39F9B0 +39F9B0:lI101|H39FA7C +39FA7C:lI102|N +39F81C:lH39F8F4|H39F900 +39F8F4:t2:H39F9C0,H39F9C8 +39F9C8:lI105|H39FA94 +39FA94:lI109|H39FB60 +39FB60:lI97|H39FC1C +39FC1C:lI103|H39FCD8 +39FCD8:lI101|H39FD9C +39FD9C:lI47|H39FE58 +39FE58:lI103|H39FF04 +39FF04:lI105|H39FFB0 +39FFB0:lI102|N +39F9C0:lI103|H39FA8C +39FA8C:lI105|H39FB58 +39FB58:lI102|N +39F900:lH39F9D0|H39F9DC +39F9D0:t2:H39FA9C,H39FAA4 +39FAA4:lI99|H39FB70 +39FB70:lI104|H39FC2C +39FC2C:lI101|H39FCE0 +39FCE0:lI109|H39FDA4 +39FDA4:lI105|H39FE60 +39FE60:lI99|H39FF0C +39FF0C:lI97|H39FFB8 +39FFB8:lI108|H3A0064 +3A0064:lI47|H3A0108 +3A0108:lI120|H3A01AC +3A01AC:lI45|H3A0260 +3A0260:lI112|H3A030C +3A030C:lI100|H3A03B8 +3A03B8:lI98|N +39FA9C:lI112|H39FB68 +39FB68:lI100|H39FC24 +39FC24:lI98|N +39F9DC:lH39FAAC|H39FAB8 +39FAAC:t2:H39FB78,H39FB80 +39FB80:lI99|H39FC3C +39FC3C:lI104|H39FCF0 +39FCF0:lI101|H39FDAC +39FDAC:lI109|H39FE68 +39FE68:lI105|H39FF14 +39FF14:lI99|H39FFC0 +39FFC0:lI97|H3A006C +3A006C:lI108|H3A0110 +3A0110:lI47|H3A01B4 +3A01B4:lI120|H3A0268 +3A0268:lI45|H3A0314 +3A0314:lI112|H3A03C0 +3A03C0:lI100|H3A0454 +3A0454:lI98|N +39FB78:lI120|H39FC34 +39FC34:lI121|H39FCE8 +39FCE8:lI122|N +39FAB8:lH39FB88|H39FB94 +39FB88:t2:H39FC44,H39FC4C +39FC4C:lI97|H39FD00 +39FD00:lI117|H39FDBC +39FDBC:lI100|H39FE70 +39FE70:lI105|H39FF1C +39FF1C:lI111|H39FFC8 +39FFC8:lI47|H3A0074 +3A0074:lI120|H3A0118 +3A0118:lI45|H3A01BC +3A01BC:lI119|H3A0270 +3A0270:lI97|H3A031C +3A031C:lI118|N +39FC44:lI119|H39FCF8 +39FCF8:lI97|H39FDB4 +39FDB4:lI118|N +39FB94:lH39FC54|H39FC60 +39FC54:t2:H39FD08,H39FD10 +39FD10:lI97|H39FDCC +39FDCC:lI117|H39FE78 +39FE78:lI100|H39FF24 +39FF24:lI105|H39FFD0 +39FFD0:lI111|H3A007C +3A007C:lI47|H3A0120 +3A0120:lI120|H3A01C4 +3A01C4:lI45|H3A0278 +3A0278:lI114|H3A0324 +3A0324:lI101|H3A03C8 +3A03C8:lI97|H3A045C +3A045C:lI108|H3A04F8 +3A04F8:lI97|H3A059C +3A059C:lI117|H3A0648 +3A0648:lI100|H3A06F4 +3A06F4:lI105|H3A07A0 +3A07A0:lI111|N +39FD08:lI114|H39FDC4 +39FDC4:lI97|N +39FC60:lH39FD18|H39FD24 +39FD18:t2:H39FDD4,H39FDDC +39FDDC:lI97|H39FE88 +39FE88:lI117|H39FF34 +39FF34:lI100|H39FFD8 +39FFD8:lI105|H3A0084 +3A0084:lI111|H3A0128 +3A0128:lI47|H3A01CC +3A01CC:lI120|H3A0280 +3A0280:lI45|H3A032C +3A032C:lI112|H3A03D0 +3A03D0:lI110|H3A0464 +3A0464:lI45|H3A0500 +3A0500:lI114|H3A05A4 +3A05A4:lI101|H3A0650 +3A0650:lI97|H3A06FC +3A06FC:lI108|H3A07A8 +3A07A8:lI97|H3A0844 +3A0844:lI117|H3A08D0 +3A08D0:lI100|H3A0964 +3A0964:lI105|H3A09F8 +3A09F8:lI111|H3A0A94 +3A0A94:lI45|H3A0B40 +3A0B40:lI112|H3A0BEC +3A0BEC:lI108|H3A0CA8 +3A0CA8:lI117|H3A0D64 +3A0D64:lI103|H3A0E18 +3A0E18:lI105|H3A0ECC +3A0ECC:lI110|N +39FDD4:lI114|H39FE80 +39FE80:lI112|H39FF2C +39FF2C:lI109|N +39FD24:lH39FDE4|H39FDF0 +39FDE4:t2:H39FE90,H39FE98 +39FE98:lI97|H39FF44 +39FF44:lI117|H39FFE8 +39FFE8:lI100|H3A008C +3A008C:lI105|H3A0130 +3A0130:lI111|H3A01D4 +3A01D4:lI47|H3A0288 +3A0288:lI120|H3A0334 +3A0334:lI45|H3A03D8 +3A03D8:lI112|H3A046C +3A046C:lI110|H3A0508 +3A0508:lI45|H3A05AC +3A05AC:lI114|H3A0658 +3A0658:lI101|H3A0704 +3A0704:lI97|H3A07B0 +3A07B0:lI108|H3A084C +3A084C:lI97|H3A08D8 +3A08D8:lI117|H3A096C +3A096C:lI100|H3A0A00 +3A0A00:lI105|H3A0A9C +3A0A9C:lI111|N +39FE90:lI114|H39FF3C +39FF3C:lI97|H39FFE0 +39FFE0:lI109|N +39FDF0:lH39FEA0|H39FEAC +39FEA0:t2:H39FF4C,H39FF54 +39FF54:lI97|H39FFF8 +39FFF8:lI117|H3A009C +3A009C:lI100|H3A0138 +3A0138:lI105|H3A01DC +3A01DC:lI111|H3A0290 +3A0290:lI47|H3A033C +3A033C:lI120|H3A03E0 +3A03E0:lI45|H3A0474 +3A0474:lI97|H3A0510 +3A0510:lI105|H3A05B4 +3A05B4:lI102|H3A0660 +3A0660:lI102|N +39FF4C:lI97|H39FFF0 +39FFF0:lI105|H3A0094 +3A0094:lI102|N +39FEAC:lH39FF5C|H39FF68 +39FF5C:t2:H3A0000,H3A0008 +3A0008:lI97|H3A00AC +3A00AC:lI117|H3A0148 +3A0148:lI100|H3A01EC +3A01EC:lI105|H3A0298 +3A0298:lI111|H3A0344 +3A0344:lI47|H3A03E8 +3A03E8:lI120|H3A047C +3A047C:lI45|H3A0518 +3A0518:lI97|H3A05BC +3A05BC:lI105|H3A0668 +3A0668:lI102|H3A070C +3A070C:lI102|N +3A0000:lI97|H3A00A4 +3A00A4:lI105|H3A0140 +3A0140:lI102|H3A01E4 +3A01E4:lI102|N +39FF68:lH3A0010|H3A001C +3A0010:t2:H3A00B4,H3A00BC +3A00BC:lI97|H3A0158 +3A0158:lI117|H3A01FC +3A01FC:lI100|H3A02A8 +3A02A8:lI105|H3A034C +3A034C:lI111|H3A03F0 +3A03F0:lI47|H3A0484 +3A0484:lI120|H3A0520 +3A0520:lI45|H3A05C4 +3A05C4:lI97|H3A0670 +3A0670:lI105|H3A0714 +3A0714:lI102|H3A07B8 +3A07B8:lI102|N +3A00B4:lI97|H3A0150 +3A0150:lI105|H3A01F4 +3A01F4:lI102|H3A02A0 +3A02A0:lI99|N +3A001C:lH3A00C4|H3A00D0 +3A00C4:t2:H3A0160,H3A0168 +3A0168:lI97|H3A020C +3A020C:lI117|H3A02B8 +3A02B8:lI100|H3A035C +3A035C:lI105|H3A03F8 +3A03F8:lI111|H3A048C +3A048C:lI47|H3A0528 +3A0528:lI109|H3A05CC +3A05CC:lI112|H3A0678 +3A0678:lI101|H3A071C +3A071C:lI103|N +3A0160:lI109|H3A0204 +3A0204:lI112|H3A02B0 +3A02B0:lI103|H3A0354 +3A0354:lI97|N +3A00D0:lH3A0170|H3A017C +3A0170:t2:H3A0214,H3A021C +3A021C:lI97|H3A02C8 +3A02C8:lI117|H3A036C +3A036C:lI100|H3A0400 +3A0400:lI105|H3A0494 +3A0494:lI111|H3A0530 +3A0530:lI47|H3A05D4 +3A05D4:lI109|H3A0680 +3A0680:lI112|H3A0724 +3A0724:lI101|H3A07C0 +3A07C0:lI103|N +3A0214:lI109|H3A02C0 +3A02C0:lI112|H3A0364 +3A0364:lI50|N +3A017C:lH3A0224|H3A0230 +3A0224:t2:H3A02D0,H3A02D8 +3A02D8:lI97|H3A037C +3A037C:lI117|H3A0408 +3A0408:lI100|H3A049C +3A049C:lI105|H3A0538 +3A0538:lI111|H3A05DC +3A05DC:lI47|H3A0688 +3A0688:lI98|H3A072C +3A072C:lI97|H3A07C8 +3A07C8:lI115|H3A0854 +3A0854:lI105|H3A08E0 +3A08E0:lI99|N +3A02D0:lI97|H3A0374 +3A0374:lI117|N +3A0230:lH3A02E0|H3A02EC +3A02E0:t2:H3A0384,H3A038C +3A038C:lI97|H3A0418 +3A0418:lI117|H3A04AC +3A04AC:lI100|H3A0540 +3A0540:lI105|H3A05E4 +3A05E4:lI111|H3A0690 +3A0690:lI47|H3A0734 +3A0734:lI98|H3A07D0 +3A07D0:lI97|H3A085C +3A085C:lI115|H3A08E8 +3A08E8:lI105|H3A0974 +3A0974:lI99|N +3A0384:lI115|H3A0410 +3A0410:lI110|H3A04A4 +3A04A4:lI100|N +3A02EC:lH3A0394|H3A03A0 +3A0394:t2:H3A0420,H3A0428 +3A0428:lI97|H3A04BC +3A04BC:lI112|H3A0550 +3A0550:lI112|H3A05EC +3A05EC:lI108|H3A0698 +3A0698:lI105|H3A073C +3A073C:lI99|H3A07D8 +3A07D8:lI97|H3A0864 +3A0864:lI116|H3A08F0 +3A08F0:lI105|H3A097C +3A097C:lI111|H3A0A08 +3A0A08:lI110|H3A0AA4 +3A0AA4:lI47|H3A0B48 +3A0B48:lI122|H3A0BF4 +3A0BF4:lI105|H3A0CB0 +3A0CB0:lI112|N +3A0420:lI122|H3A04B4 +3A04B4:lI105|H3A0548 +3A0548:lI112|N +3A03A0:lH3A0430|H3A043C +3A0430:t2:H3A04C4,H3A04CC +3A04CC:lI97|H3A0560 +3A0560:lI112|H3A05FC +3A05FC:lI112|H3A06A0 +3A06A0:lI108|H3A0744 +3A0744:lI105|H3A07E0 +3A07E0:lI99|H3A086C +3A086C:lI97|H3A08F8 +3A08F8:lI116|H3A0984 +3A0984:lI105|H3A0A10 +3A0A10:lI111|H3A0AAC +3A0AAC:lI110|H3A0B50 +3A0B50:lI47|H3A0BFC +3A0BFC:lI120|H3A0CB8 +3A0CB8:lI45|H3A0D6C +3A0D6C:lI119|H3A0E20 +3A0E20:lI97|H3A0ED4 +3A0ED4:lI105|H3A0F90 +3A0F90:lI115|H3A105C +3A105C:lI45|H3A1130 +3A1130:lI115|H3A1204 +3A1204:lI111|H3A12D0 +3A12D0:lI117|H3A13A4 +3A13A4:lI114|H3A1480 +3A1480:lI99|H3A1564 +3A1564:lI101|N +3A04C4:lI115|H3A0558 +3A0558:lI114|H3A05F4 +3A05F4:lI99|N +3A043C:lH3A04D4|H3A04E0 +3A04D4:t2:H3A0568,H3A0570 +3A0570:lI97|H3A060C +3A060C:lI112|H3A06B0 +3A06B0:lI112|H3A0754 +3A0754:lI108|H3A07F0 +3A07F0:lI105|H3A0874 +3A0874:lI99|H3A0900 +3A0900:lI97|H3A098C +3A098C:lI116|H3A0A18 +3A0A18:lI105|H3A0AB4 +3A0AB4:lI111|H3A0B58 +3A0B58:lI110|H3A0C04 +3A0C04:lI47|H3A0CC0 +3A0CC0:lI120|H3A0D74 +3A0D74:lI45|H3A0E28 +3A0E28:lI117|H3A0EDC +3A0EDC:lI115|H3A0F98 +3A0F98:lI116|H3A1064 +3A1064:lI97|H3A1138 +3A1138:lI114|N +3A0568:lI117|H3A0604 +3A0604:lI115|H3A06A8 +3A06A8:lI116|H3A074C +3A074C:lI97|H3A07E8 +3A07E8:lI114|N +3A04E0:lH3A0578|H3A0584 +3A0578:t2:H3A0614,H3A061C +3A061C:lI97|H3A06C0 +3A06C0:lI112|H3A075C +3A075C:lI112|H3A07F8 +3A07F8:lI108|H3A087C +3A087C:lI105|H3A0908 +3A0908:lI99|H3A0994 +3A0994:lI97|H3A0A20 +3A0A20:lI116|H3A0ABC +3A0ABC:lI105|H3A0B60 +3A0B60:lI111|H3A0C0C +3A0C0C:lI110|H3A0CC8 +3A0CC8:lI47|H3A0D7C +3A0D7C:lI120|H3A0E30 +3A0E30:lI45|H3A0EE4 +3A0EE4:lI116|H3A0FA0 +3A0FA0:lI114|H3A106C +3A106C:lI111|H3A1140 +3A1140:lI102|H3A120C +3A120C:lI102|H3A12D8 +3A12D8:lI45|H3A13AC +3A13AC:lI109|H3A1488 +3A1488:lI115|N +3A0614:lI109|H3A06B8 +3A06B8:lI115|N +3A0584:lH3A0624|H3A0630 +3A0624:t2:H3A06C8,H3A06D0 +3A06D0:lI97|H3A076C +3A076C:lI112|H3A0800 +3A0800:lI112|H3A0884 +3A0884:lI108|H3A0910 +3A0910:lI105|H3A099C +3A099C:lI99|H3A0A28 +3A0A28:lI97|H3A0AC4 +3A0AC4:lI116|H3A0B68 +3A0B68:lI105|H3A0C14 +3A0C14:lI111|H3A0CD0 +3A0CD0:lI110|H3A0D84 +3A0D84:lI47|H3A0E38 +3A0E38:lI120|H3A0EEC +3A0EEC:lI45|H3A0FA8 +3A0FA8:lI116|H3A1074 +3A1074:lI114|H3A1148 +3A1148:lI111|H3A1214 +3A1214:lI102|H3A12E0 +3A12E0:lI102|H3A13B4 +3A13B4:lI45|H3A1490 +3A1490:lI109|H3A156C +3A156C:lI101|N +3A06C8:lI109|H3A0764 +3A0764:lI101|N +3A0630:lH3A06D8|H3A06E4 +3A06D8:t2:H3A0774,H3A077C +3A077C:lI97|H3A0810 +3A0810:lI112|H3A0894 +3A0894:lI112|H3A0918 +3A0918:lI108|H3A09A4 +3A09A4:lI105|H3A0A30 +3A0A30:lI99|H3A0ACC +3A0ACC:lI97|H3A0B70 +3A0B70:lI116|H3A0C1C +3A0C1C:lI105|H3A0CD8 +3A0CD8:lI111|H3A0D8C +3A0D8C:lI110|H3A0E40 +3A0E40:lI47|H3A0EF4 +3A0EF4:lI120|H3A0FB0 +3A0FB0:lI45|H3A107C +3A107C:lI116|H3A1150 +3A1150:lI114|H3A121C +3A121C:lI111|H3A12E8 +3A12E8:lI102|H3A13BC +3A13BC:lI102|H3A1498 +3A1498:lI45|H3A1574 +3A1574:lI109|H3A1648 +3A1648:lI97|H3A171C +3A171C:lI110|N +3A0774:lI109|H3A0808 +3A0808:lI97|H3A088C +3A088C:lI110|N +3A06E4:lH3A0784|H3A0790 +3A0784:t2:H3A0818,H3A0820 +3A0820:lI97|H3A089C +3A089C:lI112|H3A0920 +3A0920:lI112|H3A09AC +3A09AC:lI108|H3A0A38 +3A0A38:lI105|H3A0AD4 +3A0AD4:lI99|H3A0B78 +3A0B78:lI97|H3A0C24 +3A0C24:lI116|H3A0CE0 +3A0CE0:lI105|H3A0D94 +3A0D94:lI111|H3A0E48 +3A0E48:lI110|H3A0EFC +3A0EFC:lI47|H3A0FB8 +3A0FB8:lI120|H3A1084 +3A1084:lI45|H3A1158 +3A1158:lI116|H3A1224 +3A1224:lI114|H3A12F0 +3A12F0:lI111|H3A13C4 +3A13C4:lI102|H3A14A0 +3A14A0:lI102|N +3A0818:lI116|N +3A0790:lH3A0828|H3A0834 +3A0828:t2:H3A08A4,H3A08AC +3A08AC:lI97|H3A0930 +3A0930:lI112|H3A09B4 +3A09B4:lI112|H3A0A40 +3A0A40:lI108|H3A0ADC +3A0ADC:lI105|H3A0B80 +3A0B80:lI99|H3A0C2C +3A0C2C:lI97|H3A0CE8 +3A0CE8:lI116|H3A0D9C +3A0D9C:lI105|H3A0E50 +3A0E50:lI111|H3A0F04 +3A0F04:lI110|H3A0FC0 +3A0FC0:lI47|H3A108C +3A108C:lI120|H3A1160 +3A1160:lI45|H3A122C +3A122C:lI116|H3A12F8 +3A12F8:lI114|H3A13CC +3A13CC:lI111|H3A14A8 +3A14A8:lI102|H3A157C +3A157C:lI102|N +3A08A4:lI116|H3A0928 +3A0928:lI114|N +3A0834:lH3A08B4|H3A08C0 +3A08B4:t2:H3A0938,H3A0940 +3A0940:lI97|H3A09C4 +3A09C4:lI112|H3A0A50 +3A0A50:lI112|H3A0AEC +3A0AEC:lI108|H3A0B88 +3A0B88:lI105|H3A0C34 +3A0C34:lI99|H3A0CF0 +3A0CF0:lI97|H3A0DA4 +3A0DA4:lI116|H3A0E58 +3A0E58:lI105|H3A0F0C +3A0F0C:lI111|H3A0FC8 +3A0FC8:lI110|H3A1094 +3A1094:lI47|H3A1168 +3A1168:lI120|H3A1234 +3A1234:lI45|H3A1300 +3A1300:lI116|H3A13D4 +3A13D4:lI114|H3A14B0 +3A14B0:lI111|H3A1584 +3A1584:lI102|H3A1650 +3A1650:lI102|N +3A0938:lI114|H3A09BC +3A09BC:lI111|H3A0A48 +3A0A48:lI102|H3A0AE4 +3A0AE4:lI102|N +3A08C0:lH3A0948|H3A0954 +3A0948:t2:H3A09CC,H3A09D4 +3A09D4:lI97|H3A0A60 +3A0A60:lI112|H3A0AFC +3A0AFC:lI112|H3A0B98 +3A0B98:lI108|H3A0C44 +3A0C44:lI105|H3A0D00 +3A0D00:lI99|H3A0DB4 +3A0DB4:lI97|H3A0E60 +3A0E60:lI116|H3A0F14 +3A0F14:lI105|H3A0FD0 +3A0FD0:lI111|H3A109C +3A109C:lI110|H3A1170 +3A1170:lI47|H3A123C +3A123C:lI120|H3A1308 +3A1308:lI45|H3A13DC +3A13DC:lI116|H3A14B8 +3A14B8:lI101|H3A158C +3A158C:lI120|H3A1658 +3A1658:lI105|H3A1724 +3A1724:lI110|H3A17E8 +3A17E8:lI102|H3A18AC +3A18AC:lI111|N +3A09CC:lI116|H3A0A58 +3A0A58:lI101|H3A0AF4 +3A0AF4:lI120|H3A0B90 +3A0B90:lI105|H3A0C3C +3A0C3C:lI110|H3A0CF8 +3A0CF8:lI102|H3A0DAC +3A0DAC:lI111|N +3A0954:lH3A09DC|H3A09E8 +3A09DC:t2:H3A0A68,H3A0A70 +3A0A70:lI97|H3A0B0C +3A0B0C:lI112|H3A0BA8 +3A0BA8:lI112|H3A0C54 +3A0C54:lI108|H3A0D08 +3A0D08:lI105|H3A0DBC +3A0DBC:lI99|H3A0E68 +3A0E68:lI97|H3A0F1C +3A0F1C:lI116|H3A0FD8 +3A0FD8:lI105|H3A10A4 +3A10A4:lI111|H3A1178 +3A1178:lI110|H3A1244 +3A1244:lI47|H3A1310 +3A1310:lI120|H3A13E4 +3A13E4:lI45|H3A14C0 +3A14C0:lI116|H3A1594 +3A1594:lI101|H3A1660 +3A1660:lI120|H3A172C +3A172C:lI105|H3A17F0 +3A17F0:lI110|H3A18B4 +3A18B4:lI102|H3A1970 +3A1970:lI111|N +3A0A68:lI116|H3A0B04 +3A0B04:lI101|H3A0BA0 +3A0BA0:lI120|H3A0C4C +3A0C4C:lI105|N +3A09E8:lH3A0A78|H3A0A84 +3A0A78:t2:H3A0B14,H3A0B1C +3A0B1C:lI97|H3A0BB8 +3A0BB8:lI112|H3A0C64 +3A0C64:lI112|H3A0D10 +3A0D10:lI108|H3A0DC4 +3A0DC4:lI105|H3A0E70 +3A0E70:lI99|H3A0F24 +3A0F24:lI97|H3A0FE0 +3A0FE0:lI116|H3A10AC +3A10AC:lI105|H3A1180 +3A1180:lI111|H3A124C +3A124C:lI110|H3A1318 +3A1318:lI47|H3A13EC +3A13EC:lI120|H3A14C8 +3A14C8:lI45|H3A159C +3A159C:lI116|H3A1668 +3A1668:lI101|H3A1734 +3A1734:lI120|N +3A0B14:lI116|H3A0BB0 +3A0BB0:lI101|H3A0C5C +3A0C5C:lI120|N +3A0A84:lH3A0B24|H3A0B30 +3A0B24:t2:H3A0BC0,H3A0BC8 +3A0BC8:lI97|H3A0C74 +3A0C74:lI112|H3A0D20 +3A0D20:lI112|H3A0DCC +3A0DCC:lI108|H3A0E78 +3A0E78:lI105|H3A0F2C +3A0F2C:lI99|H3A0FE8 +3A0FE8:lI97|H3A10B4 +3A10B4:lI116|H3A1188 +3A1188:lI105|H3A1254 +3A1254:lI111|H3A1320 +3A1320:lI110|H3A13F4 +3A13F4:lI47|H3A14D0 +3A14D0:lI120|H3A15A4 +3A15A4:lI45|H3A1670 +3A1670:lI116|H3A173C +3A173C:lI99|H3A17F8 +3A17F8:lI108|N +3A0BC0:lI116|H3A0C6C +3A0C6C:lI99|H3A0D18 +3A0D18:lI108|N +3A0B30:lH3A0BD0|H3A0BDC +3A0BD0:t2:H3A0C7C,H3A0C84 +3A0C84:lI97|H3A0D30 +3A0D30:lI112|H3A0DDC +3A0DDC:lI112|H3A0E80 +3A0E80:lI108|H3A0F34 +3A0F34:lI105|H3A0FF0 +3A0FF0:lI99|H3A10BC +3A10BC:lI97|H3A1190 +3A1190:lI116|H3A125C +3A125C:lI105|H3A1328 +3A1328:lI111|H3A13FC +3A13FC:lI110|H3A14D8 +3A14D8:lI47|H3A15AC +3A15AC:lI120|H3A1678 +3A1678:lI45|H3A1744 +3A1744:lI116|H3A1800 +3A1800:lI97|H3A18BC +3A18BC:lI114|N +3A0C7C:lI116|H3A0D28 +3A0D28:lI97|H3A0DD4 +3A0DD4:lI114|N +3A0BDC:lH3A0C8C|H3A0C98 +3A0C8C:t2:H3A0D38,H3A0D40 +3A0D40:lI97|H3A0DEC +3A0DEC:lI112|H3A0E90 +3A0E90:lI112|H3A0F44 +3A0F44:lI108|H3A1000 +3A1000:lI105|H3A10CC +3A10CC:lI99|H3A1198 +3A1198:lI97|H3A1264 +3A1264:lI116|H3A1330 +3A1330:lI105|H3A1404 +3A1404:lI111|H3A14E0 +3A14E0:lI110|H3A15B4 +3A15B4:lI47|H3A1680 +3A1680:lI120|H3A174C +3A174C:lI45|H3A1808 +3A1808:lI115|H3A18C4 +3A18C4:lI118|H3A1978 +3A1978:lI52|H3A1A2C +3A1A2C:lI99|H3A1AE0 +3A1AE0:lI114|H3A1BA4 +3A1BA4:lI99|N +3A0D38:lI115|H3A0DE4 +3A0DE4:lI118|H3A0E88 +3A0E88:lI52|H3A0F3C +3A0F3C:lI99|H3A0FF8 +3A0FF8:lI114|H3A10C4 +3A10C4:lI99|N +3A0C98:lH3A0D48|H3A0D54 +3A0D48:t2:H3A0DF4,H3A0DFC +3A0DFC:lI97|H3A0EA0 +3A0EA0:lI112|H3A0F54 +3A0F54:lI112|H3A1010 +3A1010:lI108|H3A10DC +3A10DC:lI105|H3A11A8 +3A11A8:lI99|H3A1274 +3A1274:lI97|H3A1338 +3A1338:lI116|H3A140C +3A140C:lI105|H3A14E8 +3A14E8:lI111|H3A15BC +3A15BC:lI110|H3A1688 +3A1688:lI47|H3A1754 +3A1754:lI120|H3A1810 +3A1810:lI45|H3A18CC +3A18CC:lI115|H3A1980 +3A1980:lI118|H3A1A34 +3A1A34:lI52|H3A1AE8 +3A1AE8:lI99|H3A1BAC +3A1BAC:lI112|H3A1C78 +3A1C78:lI105|H3A1D3C +3A1D3C:lI111|N +3A0DF4:lI115|H3A0E98 +3A0E98:lI118|H3A0F4C +3A0F4C:lI52|H3A1008 +3A1008:lI99|H3A10D4 +3A10D4:lI112|H3A11A0 +3A11A0:lI105|H3A126C +3A126C:lI111|N +3A0D54:lH3A0E04|H3A0E10 +3A0E04:t2:H3A0EA8,H3A0EB0 +3A0EB0:lI97|H3A0F64 +3A0F64:lI112|H3A1020 +3A1020:lI112|H3A10E4 +3A10E4:lI108|H3A11B0 +3A11B0:lI105|H3A127C +3A127C:lI99|H3A1340 +3A1340:lI97|H3A1414 +3A1414:lI116|H3A14F0 +3A14F0:lI105|H3A15C4 +3A15C4:lI111|H3A1690 +3A1690:lI110|H3A175C +3A175C:lI47|H3A1818 +3A1818:lI120|H3A18D4 +3A18D4:lI45|H3A1988 +3A1988:lI115|H3A1A3C +3A1A3C:lI116|H3A1AF0 +3A1AF0:lI117|H3A1BB4 +3A1BB4:lI102|H3A1C80 +3A1C80:lI102|H3A1D44 +3A1D44:lI105|H3A1E00 +3A1E00:lI116|N +3A0EA8:lI115|H3A0F5C +3A0F5C:lI105|H3A1018 +3A1018:lI116|N +3A0E10:lH3A0EB8|H3A0EC4 +3A0EB8:t2:H3A0F6C,H3A0F74 +3A0F74:lI97|H3A1030 +3A1030:lI112|H3A10F4 +3A10F4:lI112|H3A11C0 +3A11C0:lI108|H3A1284 +3A1284:lI105|H3A1348 +3A1348:lI99|H3A141C +3A141C:lI97|H3A14F8 +3A14F8:lI116|H3A15CC +3A15CC:lI105|H3A1698 +3A1698:lI111|H3A1764 +3A1764:lI110|H3A1820 +3A1820:lI47|H3A18DC +3A18DC:lI120|H3A1990 +3A1990:lI45|H3A1A44 +3A1A44:lI115|H3A1AF8 +3A1AF8:lI104|H3A1BBC +3A1BBC:lI97|H3A1C88 +3A1C88:lI114|N +3A0F6C:lI115|H3A1028 +3A1028:lI104|H3A10EC +3A10EC:lI97|H3A11B8 +3A11B8:lI114|N +3A0EC4:lH3A0F7C|H3A0F88 +3A0F7C:t2:H3A1038,H3A1040 +3A1040:lI97|H3A1104 +3A1104:lI112|H3A11C8 +3A11C8:lI112|H3A128C +3A128C:lI108|H3A1350 +3A1350:lI105|H3A1424 +3A1424:lI99|H3A1500 +3A1500:lI97|H3A15D4 +3A15D4:lI116|H3A16A0 +3A16A0:lI105|H3A176C +3A176C:lI111|H3A1828 +3A1828:lI110|H3A18E4 +3A18E4:lI47|H3A1998 +3A1998:lI120|H3A1A4C +3A1A4C:lI45|H3A1B00 +3A1B00:lI115|H3A1BC4 +3A1BC4:lI104|N +3A1038:lI115|H3A10FC +3A10FC:lI104|N +3A0F88:lH3A1048|H3A1054 +3A1048:t2:H3A110C,H3A1114 +3A1114:lI97|H3A11D8 +3A11D8:lI112|H3A1294 +3A1294:lI112|H3A1358 +3A1358:lI108|H3A142C +3A142C:lI105|H3A1508 +3A1508:lI99|H3A15DC +3A15DC:lI97|H3A16A8 +3A16A8:lI116|H3A1774 +3A1774:lI105|H3A1830 +3A1830:lI111|H3A18EC +3A18EC:lI110|H3A19A0 +3A19A0:lI47|H3A1A54 +3A1A54:lI120|H3A1B08 +3A1B08:lI45|H3A1BCC +3A1BCC:lI110|H3A1C90 +3A1C90:lI101|H3A1D4C +3A1D4C:lI116|H3A1E08 +3A1E08:lI99|H3A1EC4 +3A1EC4:lI100|H3A1F88 +3A1F88:lI102|N +3A110C:lI110|H3A11D0 +3A11D0:lI99|N +3A1054:lH3A111C|H3A1128 +3A111C:t2:H3A11E0,H3A11E8 +3A11E8:lI97|H3A12A4 +3A12A4:lI112|H3A1368 +3A1368:lI112|H3A1434 +3A1434:lI108|H3A1510 +3A1510:lI105|H3A15E4 +3A15E4:lI99|H3A16B0 +3A16B0:lI97|H3A177C +3A177C:lI116|H3A1838 +3A1838:lI105|H3A18F4 +3A18F4:lI111|H3A19A8 +3A19A8:lI110|H3A1A5C +3A1A5C:lI47|H3A1B10 +3A1B10:lI120|H3A1BD4 +3A1BD4:lI45|H3A1C98 +3A1C98:lI110|H3A1D54 +3A1D54:lI101|H3A1E10 +3A1E10:lI116|H3A1ECC +3A1ECC:lI99|H3A1F90 +3A1F90:lI100|H3A2044 +3A2044:lI102|N +3A11E0:lI99|H3A129C +3A129C:lI100|H3A1360 +3A1360:lI102|N +3A1128:lH3A11F0|H3A11FC +3A11F0:t2:H3A12AC,H3A12B4 +3A12B4:lI97|H3A1378 +3A1378:lI112|H3A1444 +3A1444:lI112|H3A1518 +3A1518:lI108|H3A15EC +3A15EC:lI105|H3A16B8 +3A16B8:lI99|H3A1784 +3A1784:lI97|H3A1840 +3A1840:lI116|H3A18FC +3A18FC:lI105|H3A19B0 +3A19B0:lI111|H3A1A64 +3A1A64:lI110|H3A1B18 +3A1B18:lI47|H3A1BDC +3A1BDC:lI120|H3A1CA0 +3A1CA0:lI45|H3A1D5C +3A1D5C:lI109|H3A1E18 +3A1E18:lI105|H3A1ED4 +3A1ED4:lI102|N +3A12AC:lI109|H3A1370 +3A1370:lI105|H3A143C +3A143C:lI102|N +3A11FC:lH3A12BC|H3A12C8 +3A12BC:t2:H3A1380,H3A1388 +3A1388:lI97|H3A1454 +3A1454:lI112|H3A1528 +3A1528:lI112|H3A15FC +3A15FC:lI108|H3A16C8 +3A16C8:lI105|H3A178C +3A178C:lI99|H3A1848 +3A1848:lI97|H3A1904 +3A1904:lI116|H3A19B8 +3A19B8:lI105|H3A1A6C +3A1A6C:lI111|H3A1B20 +3A1B20:lI110|H3A1BE4 +3A1BE4:lI47|H3A1CA8 +3A1CA8:lI120|H3A1D64 +3A1D64:lI45|H3A1E20 +3A1E20:lI108|H3A1EDC +3A1EDC:lI97|H3A1F98 +3A1F98:lI116|H3A204C +3A204C:lI101|H3A2108 +3A2108:lI120|N +3A1380:lI108|H3A144C +3A144C:lI97|H3A1520 +3A1520:lI116|H3A15F4 +3A15F4:lI101|H3A16C0 +3A16C0:lI120|N +3A12C8:lH3A1390|H3A139C +3A1390:t2:H3A145C,H3A1464 +3A1464:lI97|H3A1538 +3A1538:lI112|H3A160C +3A160C:lI112|H3A16D0 +3A16D0:lI108|H3A1794 +3A1794:lI105|H3A1850 +3A1850:lI99|H3A190C +3A190C:lI97|H3A19C0 +3A19C0:lI116|H3A1A74 +3A1A74:lI105|H3A1B28 +3A1B28:lI111|H3A1BEC +3A1BEC:lI110|H3A1CB0 +3A1CB0:lI47|H3A1D6C +3A1D6C:lI120|H3A1E28 +3A1E28:lI45|H3A1EE4 +3A1EE4:lI107|H3A1FA0 +3A1FA0:lI111|H3A2054 +3A2054:lI97|H3A2110 +3A2110:lI110|N +3A145C:lI115|H3A1530 +3A1530:lI107|H3A1604 +3A1604:lI112|N +3A139C:lH3A146C|H3A1478 +3A146C:t2:H3A1540,H3A1548 +3A1548:lI97|H3A161C +3A161C:lI112|H3A16E0 +3A16E0:lI112|H3A179C +3A179C:lI108|H3A1858 +3A1858:lI105|H3A1914 +3A1914:lI99|H3A19C8 +3A19C8:lI97|H3A1A7C +3A1A7C:lI116|H3A1B30 +3A1B30:lI105|H3A1BF4 +3A1BF4:lI111|H3A1CB8 +3A1CB8:lI110|H3A1D74 +3A1D74:lI47|H3A1E30 +3A1E30:lI120|H3A1EEC +3A1EEC:lI45|H3A1FA8 +3A1FA8:lI107|H3A205C +3A205C:lI111|H3A2118 +3A2118:lI97|H3A21CC +3A21CC:lI110|N +3A1540:lI115|H3A1614 +3A1614:lI107|H3A16D8 +3A16D8:lI100|N +3A1478:lH3A1550|H3A155C +3A1550:t2:H3A1624,H3A162C +3A162C:lI97|H3A16F0 +3A16F0:lI112|H3A17AC +3A17AC:lI112|H3A1860 +3A1860:lI108|H3A191C +3A191C:lI105|H3A19D0 +3A19D0:lI99|H3A1A84 +3A1A84:lI97|H3A1B38 +3A1B38:lI116|H3A1BFC +3A1BFC:lI105|H3A1CC0 +3A1CC0:lI111|H3A1D7C +3A1D7C:lI110|H3A1E38 +3A1E38:lI47|H3A1EF4 +3A1EF4:lI120|H3A1FB0 +3A1FB0:lI45|H3A2064 +3A2064:lI107|H3A2120 +3A2120:lI111|H3A21D4 +3A21D4:lI97|H3A2288 +3A2288:lI110|N +3A1624:lI115|H3A16E8 +3A16E8:lI107|H3A17A4 +3A17A4:lI116|N +3A155C:lH3A1634|H3A1640 +3A1634:t2:H3A16F8,H3A1700 +3A1700:lI97|H3A17BC +3A17BC:lI112|H3A1870 +3A1870:lI112|H3A1924 +3A1924:lI108|H3A19D8 +3A19D8:lI105|H3A1A8C +3A1A8C:lI99|H3A1B40 +3A1B40:lI97|H3A1C04 +3A1C04:lI116|H3A1CC8 +3A1CC8:lI105|H3A1D84 +3A1D84:lI111|H3A1E40 +3A1E40:lI110|H3A1EFC +3A1EFC:lI47|H3A1FB8 +3A1FB8:lI120|H3A206C +3A206C:lI45|H3A2128 +3A2128:lI107|H3A21DC +3A21DC:lI111|H3A2290 +3A2290:lI97|H3A234C +3A234C:lI110|N +3A16F8:lI115|H3A17B4 +3A17B4:lI107|H3A1868 +3A1868:lI109|N +3A1640:lH3A1708|H3A1714 +3A1708:t2:H3A17C4,H3A17CC +3A17CC:lI97|H3A1880 +3A1880:lI112|H3A1934 +3A1934:lI112|H3A19E0 +3A19E0:lI108|H3A1A94 +3A1A94:lI105|H3A1B48 +3A1B48:lI99|H3A1C0C +3A1C0C:lI97|H3A1CD0 +3A1CD0:lI116|H3A1D8C +3A1D8C:lI105|H3A1E48 +3A1E48:lI111|H3A1F04 +3A1F04:lI110|H3A1FC0 +3A1FC0:lI47|H3A2074 +3A2074:lI120|H3A2130 +3A2130:lI45|H3A21E4 +3A21E4:lI104|H3A2298 +3A2298:lI116|H3A2354 +3A2354:lI116|H3A2410 +3A2410:lI112|H3A24C4 +3A24C4:lI100|H3A2580 +3A2580:lI45|H3A263C +3A263C:lI99|H3A2700 +3A2700:lI103|H3A27BC +3A27BC:lI105|N +3A17C4:lI99|H3A1878 +3A1878:lI103|H3A192C +3A192C:lI105|N +3A1714:lH3A17D4|H3A17E0 +3A17D4:t2:H3A1888,H3A1890 +3A1890:lI97|H3A1944 +3A1944:lI112|H3A19F0 +3A19F0:lI112|H3A1A9C +3A1A9C:lI108|H3A1B50 +3A1B50:lI105|H3A1C14 +3A1C14:lI99|H3A1CD8 +3A1CD8:lI97|H3A1D94 +3A1D94:lI116|H3A1E50 +3A1E50:lI105|H3A1F0C +3A1F0C:lI111|H3A1FC8 +3A1FC8:lI110|H3A207C +3A207C:lI47|H3A2138 +3A2138:lI120|H3A21EC +3A21EC:lI45|H3A22A0 +3A22A0:lI104|H3A235C +3A235C:lI100|H3A2418 +3A2418:lI102|N +3A1888:lI104|H3A193C +3A193C:lI100|H3A19E8 +3A19E8:lI102|N +3A17E0:lH3A1898|H3A18A4 +3A1898:t2:H3A194C,H3A1954 +3A1954:lI97|H3A1A00 +3A1A00:lI112|H3A1AA4 +3A1AA4:lI112|H3A1B58 +3A1B58:lI108|H3A1C1C +3A1C1C:lI105|H3A1CE0 +3A1CE0:lI99|H3A1D9C +3A1D9C:lI97|H3A1E58 +3A1E58:lI116|H3A1F14 +3A1F14:lI105|H3A1FD0 +3A1FD0:lI111|H3A2084 +3A2084:lI110|H3A2140 +3A2140:lI47|H3A21F4 +3A21F4:lI120|H3A22A8 +3A22A8:lI45|H3A2364 +3A2364:lI103|H3A2420 +3A2420:lI122|H3A24CC +3A24CC:lI105|H3A2588 +3A2588:lI112|N +3A194C:lI103|H3A19F8 +3A19F8:lI122|N +3A18A4:lH3A195C|H3A1968 +3A195C:t2:H3A1A08,H3A1A10 +3A1A10:lI97|H3A1AB4 +3A1AB4:lI112|H3A1B68 +3A1B68:lI112|H3A1C2C +3A1C2C:lI108|H3A1CE8 +3A1CE8:lI105|H3A1DA4 +3A1DA4:lI99|H3A1E60 +3A1E60:lI97|H3A1F1C +3A1F1C:lI116|H3A1FD8 +3A1FD8:lI105|H3A208C +3A208C:lI111|H3A2148 +3A2148:lI110|H3A21FC +3A21FC:lI47|H3A22B0 +3A22B0:lI120|H3A236C +3A236C:lI45|H3A2428 +3A2428:lI103|H3A24D4 +3A24D4:lI116|H3A2590 +3A2590:lI97|H3A2644 +3A2644:lI114|N +3A1A08:lI103|H3A1AAC +3A1AAC:lI116|H3A1B60 +3A1B60:lI97|H3A1C24 +3A1C24:lI114|N +3A1968:lH3A1A18|H3A1A24 +3A1A18:t2:H3A1ABC,H3A1AC4 +3A1AC4:lI97|H3A1B78 +3A1B78:lI112|H3A1C3C +3A1C3C:lI112|H3A1CF0 +3A1CF0:lI108|H3A1DAC +3A1DAC:lI105|H3A1E68 +3A1E68:lI99|H3A1F24 +3A1F24:lI97|H3A1FE0 +3A1FE0:lI116|H3A2094 +3A2094:lI105|H3A2150 +3A2150:lI111|H3A2204 +3A2204:lI110|H3A22B8 +3A22B8:lI47|H3A2374 +3A2374:lI120|H3A2430 +3A2430:lI45|H3A24DC +3A24DC:lI100|H3A2598 +3A2598:lI118|H3A264C +3A264C:lI105|N +3A1ABC:lI100|H3A1B70 +3A1B70:lI118|H3A1C34 +3A1C34:lI105|N +3A1A24:lH3A1ACC|H3A1AD8 +3A1ACC:t2:H3A1B80,H3A1B88 +3A1B88:lI97|H3A1C4C +3A1C4C:lI112|H3A1D00 +3A1D00:lI112|H3A1DB4 +3A1DB4:lI108|H3A1E70 +3A1E70:lI105|H3A1F2C +3A1F2C:lI99|H3A1FE8 +3A1FE8:lI97|H3A209C +3A209C:lI116|H3A2158 +3A2158:lI105|H3A220C +3A220C:lI111|H3A22C0 +3A22C0:lI110|H3A237C +3A237C:lI47|H3A2438 +3A2438:lI120|H3A24E4 +3A24E4:lI45|H3A25A0 +3A25A0:lI100|H3A2654 +3A2654:lI105|H3A2708 +3A2708:lI114|H3A27C4 +3A27C4:lI101|H3A2880 +3A2880:lI99|H3A2944 +3A2944:lI116|H3A2A10 +3A2A10:lI111|H3A2ADC +3A2ADC:lI114|N +3A1B80:lI100|H3A1C44 +3A1C44:lI99|H3A1CF8 +3A1CF8:lI114|N +3A1AD8:lH3A1B90|H3A1B9C +3A1B90:t2:H3A1C54,H3A1C5C +3A1C5C:lI97|H3A1D10 +3A1D10:lI112|H3A1DC4 +3A1DC4:lI112|H3A1E78 +3A1E78:lI108|H3A1F34 +3A1F34:lI105|H3A1FF0 +3A1FF0:lI99|H3A20A4 +3A20A4:lI97|H3A2160 +3A2160:lI116|H3A2214 +3A2214:lI105|H3A22C8 +3A22C8:lI111|H3A2384 +3A2384:lI110|H3A2440 +3A2440:lI47|H3A24EC +3A24EC:lI120|H3A25A8 +3A25A8:lI45|H3A265C +3A265C:lI100|H3A2710 +3A2710:lI105|H3A27CC +3A27CC:lI114|H3A2888 +3A2888:lI101|H3A294C +3A294C:lI99|H3A2A18 +3A2A18:lI116|H3A2AE4 +3A2AE4:lI111|H3A2BB0 +3A2BB0:lI114|N +3A1C54:lI100|H3A1D08 +3A1D08:lI105|H3A1DBC +3A1DBC:lI114|N +3A1B9C:lH3A1C64|H3A1C70 +3A1C64:t2:H3A1D18,H3A1D20 +3A1D20:lI97|H3A1DD4 +3A1DD4:lI112|H3A1E88 +3A1E88:lI112|H3A1F3C +3A1F3C:lI108|H3A1FF8 +3A1FF8:lI105|H3A20AC +3A20AC:lI99|H3A2168 +3A2168:lI97|H3A221C +3A221C:lI116|H3A22D0 +3A22D0:lI105|H3A238C +3A238C:lI111|H3A2448 +3A2448:lI110|H3A24F4 +3A24F4:lI47|H3A25B0 +3A25B0:lI120|H3A2664 +3A2664:lI45|H3A2718 +3A2718:lI100|H3A27D4 +3A27D4:lI105|H3A2890 +3A2890:lI114|H3A2954 +3A2954:lI101|H3A2A20 +3A2A20:lI99|H3A2AEC +3A2AEC:lI116|H3A2BB8 +3A2BB8:lI111|H3A2C74 +3A2C74:lI114|N +3A1D18:lI100|H3A1DCC +3A1DCC:lI120|H3A1E80 +3A1E80:lI114|N +3A1C70:lH3A1D28|H3A1D34 +3A1D28:t2:H3A1DDC,H3A1DE4 +3A1DE4:lI97|H3A1E98 +3A1E98:lI112|H3A1F4C +3A1F4C:lI112|H3A2000 +3A2000:lI108|H3A20B4 +3A20B4:lI105|H3A2170 +3A2170:lI99|H3A2224 +3A2224:lI97|H3A22D8 +3A22D8:lI116|H3A2394 +3A2394:lI105|H3A2450 +3A2450:lI111|H3A24FC +3A24FC:lI110|H3A25B8 +3A25B8:lI47|H3A266C +3A266C:lI120|H3A2720 +3A2720:lI45|H3A27DC +3A27DC:lI99|H3A2898 +3A2898:lI115|H3A295C +3A295C:lI104|N +3A1DDC:lI99|H3A1E90 +3A1E90:lI115|H3A1F44 +3A1F44:lI104|N +3A1D34:lH3A1DEC|H3A1DF8 +3A1DEC:t2:H3A1EA0,H3A1EA8 +3A1EA8:lI97|H3A1F5C +3A1F5C:lI112|H3A2010 +3A2010:lI112|H3A20C4 +3A20C4:lI108|H3A2178 +3A2178:lI105|H3A222C +3A222C:lI99|H3A22E0 +3A22E0:lI97|H3A239C +3A239C:lI116|H3A2458 +3A2458:lI105|H3A2504 +3A2504:lI111|H3A25C0 +3A25C0:lI110|H3A2674 +3A2674:lI47|H3A2728 +3A2728:lI120|H3A27E4 +3A27E4:lI45|H3A28A0 +3A28A0:lI99|H3A2964 +3A2964:lI112|H3A2A28 +3A2A28:lI105|H3A2AF4 +3A2AF4:lI111|N +3A1EA0:lI99|H3A1F54 +3A1F54:lI112|H3A2008 +3A2008:lI105|H3A20BC +3A20BC:lI111|N +3A1DF8:lH3A1EB0|H3A1EBC +3A1EB0:t2:H3A1F64,H3A1F6C +3A1F6C:lI97|H3A2018 +3A2018:lI112|H3A20CC +3A20CC:lI112|H3A2180 +3A2180:lI108|H3A2234 +3A2234:lI105|H3A22E8 +3A22E8:lI99|H3A23A4 +3A23A4:lI97|H3A2460 +3A2460:lI116|H3A250C +3A250C:lI105|H3A25C8 +3A25C8:lI111|H3A267C +3A267C:lI110|H3A2730 +3A2730:lI47|H3A27EC +3A27EC:lI120|H3A28A8 +3A28A8:lI45|H3A296C +3A296C:lI99|H3A2A30 +3A2A30:lI111|H3A2AFC +3A2AFC:lI109|H3A2BC0 +3A2BC0:lI112|H3A2C7C +3A2C7C:lI114|H3A2D2C +3A2D2C:lI101|H3A2DD4 +3A2DD4:lI115|H3A2E6C +3A2E6C:lI115|N +3A1F64:lI90|N +3A1EBC:lH3A1F74|H3A1F80 +3A1F74:t2:H3A2020,H3A2028 +3A2028:lI97|H3A20DC +3A20DC:lI112|H3A2190 +3A2190:lI112|H3A223C +3A223C:lI108|H3A22F0 +3A22F0:lI105|H3A23AC +3A23AC:lI99|H3A2468 +3A2468:lI97|H3A2514 +3A2514:lI116|H3A25D0 +3A25D0:lI105|H3A2684 +3A2684:lI111|H3A2738 +3A2738:lI110|H3A27F4 +3A27F4:lI47|H3A28B0 +3A28B0:lI120|H3A2974 +3A2974:lI45|H3A2A38 +3A2A38:lI99|H3A2B04 +3A2B04:lI100|H3A2BC8 +3A2BC8:lI108|H3A2C84 +3A2C84:lI105|H3A2D34 +3A2D34:lI110|H3A2DDC +3A2DDC:lI107|N +3A2020:lI118|H3A20D4 +3A20D4:lI99|H3A2188 +3A2188:lI100|N +3A1F80:lH3A2030|H3A203C +3A2030:t2:H3A20E4,H3A20EC +3A20EC:lI97|H3A21A0 +3A21A0:lI112|H3A224C +3A224C:lI112|H3A2300 +3A2300:lI108|H3A23BC +3A23BC:lI105|H3A2470 +3A2470:lI99|H3A251C +3A251C:lI97|H3A25D8 +3A25D8:lI116|H3A268C +3A268C:lI105|H3A2740 +3A2740:lI111|H3A27FC +3A27FC:lI110|H3A28B8 +3A28B8:lI47|H3A297C +3A297C:lI120|H3A2A40 +3A2A40:lI45|H3A2B0C +3A2B0C:lI98|H3A2BD0 +3A2BD0:lI99|H3A2C8C +3A2C8C:lI112|H3A2D3C +3A2D3C:lI105|H3A2DE4 +3A2DE4:lI111|N +3A20E4:lI98|H3A2198 +3A2198:lI99|H3A2244 +3A2244:lI112|H3A22F8 +3A22F8:lI105|H3A23B4 +3A23B4:lI111|N +3A203C:lH3A20F4|H3A2100 +3A20F4:t2:H3A21A8,H3A21B0 +3A21B0:lI97|H3A225C +3A225C:lI112|H3A2310 +3A2310:lI112|H3A23C4 +3A23C4:lI108|H3A2478 +3A2478:lI105|H3A2524 +3A2524:lI99|H3A25E0 +3A25E0:lI97|H3A2694 +3A2694:lI116|H3A2748 +3A2748:lI105|H3A2804 +3A2804:lI111|H3A28C0 +3A28C0:lI110|H3A2984 +3A2984:lI47|H3A2A48 +3A2A48:lI114|H3A2B14 +3A2B14:lI116|H3A2BD8 +3A2BD8:lI102|N +3A21A8:lI114|H3A2254 +3A2254:lI116|H3A2308 +3A2308:lI102|N +3A2100:lH3A21B8|H3A21C4 +3A21B8:t2:H3A2264,H3A226C +3A226C:lI97|H3A2320 +3A2320:lI112|H3A23D4 +3A23D4:lI112|H3A2480 +3A2480:lI108|H3A252C +3A252C:lI105|H3A25E8 +3A25E8:lI99|H3A269C +3A269C:lI97|H3A2750 +3A2750:lI116|H3A280C +3A280C:lI105|H3A28C8 +3A28C8:lI111|H3A298C +3A298C:lI110|H3A2A50 +3A2A50:lI47|H3A2B1C +3A2B1C:lI112|H3A2BE0 +3A2BE0:lI111|H3A2C94 +3A2C94:lI119|H3A2D44 +3A2D44:lI101|H3A2DEC +3A2DEC:lI114|H3A2E74 +3A2E74:lI112|H3A2EEC +3A2EEC:lI111|H3A2F64 +3A2F64:lI105|H3A2FD4 +3A2FD4:lI110|H3A303C +3A303C:lI116|N +3A2264:lI112|H3A2318 +3A2318:lI112|H3A23CC +3A23CC:lI116|N +3A21C4:lH3A2274|H3A2280 +3A2274:t2:H3A2328,H3A2330 +3A2330:lI97|H3A23E4 +3A23E4:lI112|H3A2488 +3A2488:lI112|H3A2534 +3A2534:lI108|H3A25F0 +3A25F0:lI105|H3A26A4 +3A26A4:lI99|H3A2758 +3A2758:lI97|H3A2814 +3A2814:lI116|H3A28D0 +3A28D0:lI105|H3A2994 +3A2994:lI111|H3A2A58 +3A2A58:lI110|H3A2B24 +3A2B24:lI47|H3A2BE8 +3A2BE8:lI112|H3A2C9C +3A2C9C:lI111|H3A2D4C +3A2D4C:lI115|H3A2DF4 +3A2DF4:lI116|H3A2E7C +3A2E7C:lI115|H3A2EF4 +3A2EF4:lI99|H3A2F6C +3A2F6C:lI114|H3A2FDC +3A2FDC:lI105|H3A3044 +3A3044:lI112|H3A30A4 +3A30A4:lI116|N +3A2328:lI97|H3A23DC +3A23DC:lI105|N +3A2280:lH3A2338|H3A2344 +3A2338:t2:H3A23EC,H3A23F4 +3A23F4:lI97|H3A2498 +3A2498:lI112|H3A2544 +3A2544:lI112|H3A25F8 +3A25F8:lI108|H3A26AC +3A26AC:lI105|H3A2760 +3A2760:lI99|H3A281C +3A281C:lI97|H3A28D8 +3A28D8:lI116|H3A299C +3A299C:lI105|H3A2A60 +3A2A60:lI111|H3A2B2C +3A2B2C:lI110|H3A2BF0 +3A2BF0:lI47|H3A2CA4 +3A2CA4:lI112|H3A2D54 +3A2D54:lI111|H3A2DFC +3A2DFC:lI115|H3A2E84 +3A2E84:lI116|H3A2EFC +3A2EFC:lI115|H3A2F74 +3A2F74:lI99|H3A2FE4 +3A2FE4:lI114|H3A304C +3A304C:lI105|H3A30AC +3A30AC:lI112|H3A3104 +3A3104:lI116|N +3A23EC:lI101|H3A2490 +3A2490:lI112|H3A253C +3A253C:lI115|N +3A2344:lH3A23FC|H3A2408 +3A23FC:t2:H3A24A0,H3A24A8 +3A24A8:lI97|H3A2554 +3A2554:lI112|H3A2600 +3A2600:lI112|H3A26B4 +3A26B4:lI108|H3A2768 +3A2768:lI105|H3A2824 +3A2824:lI99|H3A28E0 +3A28E0:lI97|H3A29A4 +3A29A4:lI116|H3A2A68 +3A2A68:lI105|H3A2B34 +3A2B34:lI111|H3A2BF8 +3A2BF8:lI110|H3A2CAC +3A2CAC:lI47|H3A2D5C +3A2D5C:lI112|H3A2E04 +3A2E04:lI111|H3A2E8C +3A2E8C:lI115|H3A2F04 +3A2F04:lI116|H3A2F7C +3A2F7C:lI115|H3A2FEC +3A2FEC:lI99|H3A3054 +3A3054:lI114|H3A30B4 +3A30B4:lI105|H3A310C +3A310C:lI112|H3A315C +3A315C:lI116|N +3A24A0:lI112|H3A254C +3A254C:lI115|N +3A2408:lH3A24B0|H3A24BC +3A24B0:t2:H3A255C,H3A2564 +3A2564:lI97|H3A2610 +3A2610:lI112|H3A26C4 +3A26C4:lI112|H3A2770 +3A2770:lI108|H3A282C +3A282C:lI105|H3A28E8 +3A28E8:lI99|H3A29AC +3A29AC:lI97|H3A2A70 +3A2A70:lI116|H3A2B3C +3A2B3C:lI105|H3A2C00 +3A2C00:lI111|H3A2CB4 +3A2CB4:lI110|H3A2D64 +3A2D64:lI47|H3A2E0C +3A2E0C:lI112|H3A2E94 +3A2E94:lI100|H3A2F0C +3A2F0C:lI102|N +3A255C:lI112|H3A2608 +3A2608:lI100|H3A26BC +3A26BC:lI102|N +3A24BC:lH3A256C|H3A2578 +3A256C:t2:H3A2618,H3A2620 +3A2620:lI97|H3A26D4 +3A26D4:lI112|H3A2780 +3A2780:lI112|H3A2834 +3A2834:lI108|H3A28F0 +3A28F0:lI105|H3A29B4 +3A29B4:lI99|H3A2A78 +3A2A78:lI97|H3A2B44 +3A2B44:lI116|H3A2C08 +3A2C08:lI105|H3A2CBC +3A2CBC:lI111|H3A2D6C +3A2D6C:lI110|H3A2E14 +3A2E14:lI47|H3A2E9C +3A2E9C:lI111|H3A2F14 +3A2F14:lI100|H3A2F84 +3A2F84:lI97|N +3A2618:lI111|H3A26CC +3A26CC:lI100|H3A2778 +3A2778:lI97|N +3A2578:lH3A2628|H3A2634 +3A2628:t2:H3A26DC,H3A26E4 +3A26E4:lI97|H3A2790 +3A2790:lI112|H3A2844 +3A2844:lI112|H3A28F8 +3A28F8:lI108|H3A29BC +3A29BC:lI105|H3A2A80 +3A2A80:lI99|H3A2B4C +3A2B4C:lI97|H3A2C10 +3A2C10:lI116|H3A2CC4 +3A2CC4:lI105|H3A2D74 +3A2D74:lI111|H3A2E1C +3A2E1C:lI110|H3A2EA4 +3A2EA4:lI47|H3A2F1C +3A2F1C:lI111|H3A2F8C +3A2F8C:lI99|H3A2FF4 +3A2FF4:lI116|H3A305C +3A305C:lI101|H3A30BC +3A30BC:lI116|H3A3114 +3A3114:lI45|H3A3164 +3A3164:lI115|H3A31AC +3A31AC:lI116|H3A31F4 +3A31F4:lI114|H3A323C +3A323C:lI101|H3A3284 +3A3284:lI97|H3A32CC +3A32CC:lI109|N +3A26DC:lI98|H3A2788 +3A2788:lI105|H3A283C +3A283C:lI110|N +3A2634:lH3A26EC|H3A26F8 +3A26EC:t2:H3A2798,H3A27A0 +3A27A0:lI97|H3A2854 +3A2854:lI112|H3A2908 +3A2908:lI112|H3A29C4 +3A29C4:lI108|H3A2A88 +3A2A88:lI105|H3A2B54 +3A2B54:lI99|H3A2C18 +3A2C18:lI97|H3A2CCC +3A2CCC:lI116|H3A2D7C +3A2D7C:lI105|H3A2E24 +3A2E24:lI111|H3A2EAC +3A2EAC:lI110|H3A2F24 +3A2F24:lI47|H3A2F94 +3A2F94:lI111|H3A2FFC +3A2FFC:lI99|H3A3064 +3A3064:lI116|H3A30C4 +3A30C4:lI101|H3A311C +3A311C:lI116|H3A316C +3A316C:lI45|H3A31B4 +3A31B4:lI115|H3A31FC +3A31FC:lI116|H3A3244 +3A3244:lI114|H3A328C +3A328C:lI101|H3A32D4 +3A32D4:lI97|H3A3314 +3A3314:lI109|N +3A2798:lI100|H3A284C +3A284C:lI109|H3A2900 +3A2900:lI115|N +3A26F8:lH3A27A8|H3A27B4 +3A27A8:t2:H3A285C,H3A2864 +3A2864:lI97|H3A2918 +3A2918:lI112|H3A29D4 +3A29D4:lI112|H3A2A90 +3A2A90:lI108|H3A2B5C +3A2B5C:lI105|H3A2C20 +3A2C20:lI99|H3A2CD4 +3A2CD4:lI97|H3A2D84 +3A2D84:lI116|H3A2E2C +3A2E2C:lI105|H3A2EB4 +3A2EB4:lI111|H3A2F2C +3A2F2C:lI110|H3A2F9C +3A2F9C:lI47|H3A3004 +3A3004:lI111|H3A306C +3A306C:lI99|H3A30CC +3A30CC:lI116|H3A3124 +3A3124:lI101|H3A3174 +3A3174:lI116|H3A31BC +3A31BC:lI45|H3A3204 +3A3204:lI115|H3A324C +3A324C:lI116|H3A3294 +3A3294:lI114|H3A32DC +3A32DC:lI101|H3A331C +3A331C:lI97|H3A334C +3A334C:lI109|N +3A285C:lI108|H3A2910 +3A2910:lI104|H3A29CC +3A29CC:lI97|N +3A27B4:lH3A286C|H3A2878 +3A286C:t2:H3A2920,H3A2928 +3A2928:lI97|H3A29E4 +3A29E4:lI112|H3A2AA0 +3A2AA0:lI112|H3A2B64 +3A2B64:lI108|H3A2C28 +3A2C28:lI105|H3A2CDC +3A2CDC:lI99|H3A2D8C +3A2D8C:lI97|H3A2E34 +3A2E34:lI116|H3A2EBC +3A2EBC:lI105|H3A2F34 +3A2F34:lI111|H3A2FA4 +3A2FA4:lI110|H3A300C +3A300C:lI47|H3A3074 +3A3074:lI111|H3A30D4 +3A30D4:lI99|H3A312C +3A312C:lI116|H3A317C +3A317C:lI101|H3A31C4 +3A31C4:lI116|H3A320C +3A320C:lI45|H3A3254 +3A3254:lI115|H3A329C +3A329C:lI116|H3A32E4 +3A32E4:lI114|H3A3324 +3A3324:lI101|H3A3354 +3A3354:lI97|H3A337C +3A337C:lI109|N +3A2920:lI108|H3A29DC +3A29DC:lI122|H3A2A98 +3A2A98:lI104|N +3A2878:lH3A2930|H3A293C +3A2930:t2:H3A29EC,H3A29F4 +3A29F4:lI97|H3A2AB0 +3A2AB0:lI112|H3A2B74 +3A2B74:lI112|H3A2C30 +3A2C30:lI108|H3A2CE4 +3A2CE4:lI105|H3A2D94 +3A2D94:lI99|H3A2E3C +3A2E3C:lI97|H3A2EC4 +3A2EC4:lI116|H3A2F3C +3A2F3C:lI105|H3A2FAC +3A2FAC:lI111|H3A3014 +3A3014:lI110|H3A307C +3A307C:lI47|H3A30DC +3A30DC:lI111|H3A3134 +3A3134:lI99|H3A3184 +3A3184:lI116|H3A31CC +3A31CC:lI101|H3A3214 +3A3214:lI116|H3A325C +3A325C:lI45|H3A32A4 +3A32A4:lI115|H3A32EC +3A32EC:lI116|H3A332C +3A332C:lI114|H3A335C +3A335C:lI101|H3A3384 +3A3384:lI97|H3A33A4 +3A33A4:lI109|N +3A29EC:lI101|H3A2AA8 +3A2AA8:lI120|H3A2B6C +3A2B6C:lI101|N +3A293C:lH3A29FC|H3A2A08 +3A29FC:t2:H3A2AB8,H3A2AC0 +3A2AC0:lI97|H3A2B84 +3A2B84:lI112|H3A2C40 +3A2C40:lI112|H3A2CF4 +3A2CF4:lI108|H3A2DA4 +3A2DA4:lI105|H3A2E44 +3A2E44:lI99|H3A2ECC +3A2ECC:lI97|H3A2F44 +3A2F44:lI116|H3A2FB4 +3A2FB4:lI105|H3A301C +3A301C:lI111|H3A3084 +3A3084:lI110|H3A30E4 +3A30E4:lI47|H3A313C +3A313C:lI111|H3A318C +3A318C:lI99|H3A31D4 +3A31D4:lI116|H3A321C +3A321C:lI101|H3A3264 +3A3264:lI116|H3A32AC +3A32AC:lI45|H3A32F4 +3A32F4:lI115|H3A3334 +3A3334:lI116|H3A3364 +3A3364:lI114|H3A338C +3A338C:lI101|H3A33AC +3A33AC:lI97|H3A33C4 +3A33C4:lI109|N +3A2AB8:lI99|H3A2B7C +3A2B7C:lI108|H3A2C38 +3A2C38:lI97|H3A2CEC +3A2CEC:lI115|H3A2D9C +3A2D9C:lI115|N +3A2A08:lH3A2AC8|H3A2AD4 +3A2AC8:t2:H3A2B8C,H3A2B94 +3A2B94:lI97|H3A2C50 +3A2C50:lI112|H3A2D04 +3A2D04:lI112|H3A2DAC +3A2DAC:lI108|H3A2E4C +3A2E4C:lI105|H3A2ED4 +3A2ED4:lI99|H3A2F4C +3A2F4C:lI97|H3A2FBC +3A2FBC:lI116|H3A3024 +3A3024:lI105|H3A308C +3A308C:lI111|H3A30EC +3A30EC:lI110|H3A3144 +3A3144:lI47|H3A3194 +3A3194:lI109|H3A31DC +3A31DC:lI115|H3A3224 +3A3224:lI119|H3A326C +3A326C:lI111|H3A32B4 +3A32B4:lI114|H3A32FC +3A32FC:lI100|N +3A2B8C:lI100|H3A2C48 +3A2C48:lI111|H3A2CFC +3A2CFC:lI99|N +3A2AD4:lH3A2B9C|H3A2BA8 +3A2B9C:t2:H3A2C58,H3A2C60 +3A2C60:lI97|H3A2D14 +3A2D14:lI112|H3A2DBC +3A2DBC:lI112|H3A2E54 +3A2E54:lI108|H3A2EDC +3A2EDC:lI105|H3A2F54 +3A2F54:lI99|H3A2FC4 +3A2FC4:lI97|H3A302C +3A302C:lI116|H3A3094 +3A3094:lI105|H3A30F4 +3A30F4:lI111|H3A314C +3A314C:lI110|H3A319C +3A319C:lI47|H3A31E4 +3A31E4:lI109|H3A322C +3A322C:lI97|H3A3274 +3A3274:lI99|H3A32BC +3A32BC:lI45|H3A3304 +3A3304:lI99|H3A333C +3A333C:lI111|H3A336C +3A336C:lI109|H3A3394 +3A3394:lI112|H3A33B4 +3A33B4:lI97|H3A33CC +3A33CC:lI99|H3A33DC +3A33DC:lI116|H3A33EC +3A33EC:lI112|H3A33FC +3A33FC:lI114|H3A340C +3A340C:lI111|N +3A2C58:lI99|H3A2D0C +3A2D0C:lI112|H3A2DB4 +3A2DB4:lI116|N +3A2BA8:lH3A2C68|N +3A2C68:t2:H3A2D1C,H3A2D24 +3A2D24:lI97|H3A2DCC +3A2DCC:lI112|H3A2E64 +3A2E64:lI112|H3A2EE4 +3A2EE4:lI108|H3A2F5C +3A2F5C:lI105|H3A2FCC +3A2FCC:lI99|H3A3034 +3A3034:lI97|H3A309C +3A309C:lI116|H3A30FC +3A30FC:lI105|H3A3154 +3A3154:lI111|H3A31A4 +3A31A4:lI110|H3A31EC +3A31EC:lI47|H3A3234 +3A3234:lI109|H3A327C +3A327C:lI97|H3A32C4 +3A32C4:lI99|H3A330C +3A330C:lI45|H3A3344 +3A3344:lI98|H3A3374 +3A3374:lI105|H3A339C +3A339C:lI110|H3A33BC +3A33BC:lI104|H3A33D4 +3A33D4:lI101|H3A33E4 +3A33E4:lI120|H3A33F4 +3A33F4:lI52|H3A3404 +3A3404:lI48|N +3A2D1C:lI104|H3A2DC4 +3A2DC4:lI113|H3A2E5C +3A2E5C:lI120|N +39DC28:lH39DC68|H39DC74 +39DC68:t2:A4:port,I8888 +39DC74:lH39DCA8|H39DCB4 +39DCA8:t2:AC:bind_address,H39DCF8 +39DCF8:t4:I127,I0,I0,I1 +39DCB4:lH39DD0C|H39DD18 +39DD0C:t2:AB:server_name,H39DD6C +39DD6C:lI108|H39DDE4 +39DDE4:lI111|H39DE5C +39DE5C:lI99|H39DEE4 +39DEE4:lI97|H39DF6C +39DF6C:lI108|H39E00C +39E00C:lI104|H39E0B4 +39E0B4:lI111|H39E16C +39E16C:lI115|H39E238 +39E238:lI116|N +39DD18:lH39DD74|H39DD80 +39DD74:t2:AE:max_header_siz,I1024 +39DD80:lH39DDEC|H39DDF8 +39DDEC:t2:A11:max_header_action,A8:reply414 +39DDF8:lH39DE64|H39DE70 +39DE64:t2:A8:com_type,A7:ip_comm +39DE70:lH39DEEC|H39DEF8 +39DEEC:t2:A7:modules,H39DF74 +39DF74:lA9:mod_alias|H39E014 +39E014:lA8:mod_auth|H39E0BC +39E0BC:lA7:mod_esi|H39E174 +39E174:lAB:mod_actions|H39E240 +39E240:lA7:mod_cgi|H39E324 +39E324:lAB:mod_include|H39E418 +39E418:lA7:mod_dir|H39E51C +39E51C:lA7:mod_get|H39E634 +39E634:lA8:mod_head|H39E748 +39E748:lA7:mod_log|H39E85C +39E85C:lAC:mod_disk_log|N +39DEF8:lH39DF7C|H39DF88 +39DF7C:t2:AF:directory_index,H39E01C +39E01C:lH39E0C4|N +39E0C4:lI105|H39E17C +39E17C:lI110|H39E248 +39E248:lI100|H39E32C +39E32C:lI101|H39E420 +39E420:lI120|H39E524 +39E524:lI46|H39E63C +39E63C:lI104|H39E750 +39E750:lI116|H39E864 +39E864:lI109|H39E978 +39E978:lI108|N +39DF88:lH39E024|H39E030 +39E024:t2:AC:default_type,H39E0CC +39E0CC:lI116|H39E184 +39E184:lI101|H39E250 +39E250:lI120|H39E334 +39E334:lI116|H39E428 +39E428:lI47|H39E52C +39E52C:lI112|H39E644 +39E644:lI108|H39E758 +39E758:lI97|H39E86C +39E86C:lI105|H39E980 +39E980:lI110|N +39E030:lH39E0D4|H39E0E0 +39E0D4:t2:A10:erl_script_alias,H39E18C +39E18C:t2:H39E258,H39E260 +39E260:lH39E344|N +39E344:lI119|H39E438 +39E438:lI101|H39E53C +39E53C:lI98|H39E654 +39E654:lI116|H39E768 +39E768:lI111|H39E87C +39E87C:lI111|H39E990 +39E990:lI108|N +39E258:lI47|H39E33C +39E33C:lI119|H39E430 +39E430:lI101|H39E534 +39E534:lI98|H39E64C +39E64C:lI116|H39E760 +39E760:lI111|H39E874 +39E874:lI111|H39E988 +39E988:lI108|N +39E0E0:lH39E198|H39E1A4 +39E198:t2:A5:alias,H39E268 +39E268:t2:H39E34C,H39E354 +39E354:lI47|H39E448 +39E448:lI99|H39E54C +39E54C:lI108|H39E664 +39E664:lI101|H39E778 +39E778:lI97|H39E88C +39E88C:lI114|H39E9A0 +39E9A0:lI99|H39EA94 +39EA94:lI97|H39EB88 +39EB88:lI115|H39EC7C +39EC7C:lI101|H39ED70 +39ED70:lI47|H39EE4C +39EE4C:lI111|H39EF20 +39EF20:lI116|H39EFFC +39EFFC:lI112|H39F0E0 +39F0E0:lI47|H39F1B4 +39F1B4:lI101|H39F288 +39F288:lI114|H39F344 +39F344:lI116|H39F408 +39F408:lI115|H39F4D4 +39F4D4:lI47|H39F5A8 +39F5A8:lI108|H39F67C +39F67C:lI105|H39F750 +39F750:lI98|H39F824 +39F824:lI47|H39F908 +39F908:lI111|H39F9E4 +39F9E4:lI98|H39FAC0 +39FAC0:lI115|H39FB9C +39FB9C:lI101|H39FC68 +39FC68:lI114|H39FD2C +39FD2C:lI118|H39FDF8 +39FDF8:lI101|H39FEB4 +39FEB4:lI114|H39FF70 +39FF70:lI47|H3A0024 +3A0024:lI112|H3A00D8 +3A00D8:lI114|H3A0184 +3A0184:lI105|H3A0238 +3A0238:lI118|H3A02F4 +3A02F4:lI47|H3A03A8 +3A03A8:lI99|H3A0444 +3A0444:lI114|H3A04E8 +3A04E8:lI97|H3A058C +3A058C:lI115|H3A0638 +3A0638:lI104|H3A06EC +3A06EC:lI100|H3A0798 +3A0798:lI117|H3A083C +3A083C:lI109|H3A08C8 +3A08C8:lI112|H3A095C +3A095C:lI95|H3A09F0 +3A09F0:lI118|H3A0A8C +3A0A8C:lI105|H3A0B38 +3A0B38:lI101|H3A0BE4 +3A0BE4:lI119|H3A0CA0 +3A0CA0:lI101|H3A0D5C +3A0D5C:lI114|N +39E34C:lI47|H39E440 +39E440:lI99|H39E544 +39E544:lI114|H39E65C +39E65C:lI97|H39E770 +39E770:lI115|H39E884 +39E884:lI104|H39E998 +39E998:lI100|H39EA8C +39EA8C:lI117|H39EB80 +39EB80:lI109|H39EC74 +39EC74:lI112|H39ED68 +39ED68:lI95|H39EE44 +39EE44:lI118|H39EF18 +39EF18:lI105|H39EFF4 +39EFF4:lI101|H39F0D8 +39F0D8:lI119|H39F1AC +39F1AC:lI101|H39F280 +39F280:lI114|N +39E1A4:lH39E274|H39E280 +39E274:t2:A5:alias,H39E35C +39E35C:t2:H39E450,H39E458 +39E458:lI47|H39E55C +39E55C:lI99|H39E674 +39E674:lI108|H39E788 +39E788:lI101|H39E89C +39E89C:lI97|H39E9B0 +39E9B0:lI114|H39EAA4 +39EAA4:lI99|H39EB98 +39EB98:lI97|H39EC8C +39EC8C:lI115|H39ED80 +39ED80:lI101|H39EE5C +39EE5C:lI47|H39EF30 +39EF30:lI111|H39F00C +39F00C:lI116|H39F0F0 +39F0F0:lI112|H39F1C4 +39F1C4:lI47|H39F298 +39F298:lI101|H39F354 +39F354:lI114|H39F418 +39F418:lI116|H39F4E4 +39F4E4:lI115|H39F5B0 +39F5B0:lI47|H39F684 +39F684:lI101|H39F758 +39F758:lI114|H39F82C +39F82C:lI116|H39F910 +39F910:lI115|H39F9EC +39F9EC:lI47|H39FAC8 +39FAC8:lI100|H39FBA4 +39FBA4:lI111|H39FC70 +39FC70:lI99|H39FD34 +39FD34:lI47|H39FE00 +39FE00:lI104|H39FEBC +39FEBC:lI116|H39FF78 +39FF78:lI109|H3A002C +3A002C:lI108|N +39E450:lI47|H39E554 +39E554:lI99|H39E66C +39E66C:lI114|H39E780 +39E780:lI97|H39E894 +39E894:lI115|H39E9A8 +39E9A8:lI104|H39EA9C +39EA9C:lI100|H39EB90 +39EB90:lI117|H39EC84 +39EC84:lI109|H39ED78 +39ED78:lI112|H39EE54 +39EE54:lI95|H39EF28 +39EF28:lI101|H39F004 +39F004:lI114|H39F0E8 +39F0E8:lI116|H39F1BC +39F1BC:lI115|H39F290 +39F290:lI95|H39F34C +39F34C:lI100|H39F410 +39F410:lI111|H39F4DC +39F4DC:lI99|N +39E280:lH39E368|H39E374 +39E368:t2:A5:alias,H39E460 +39E460:t2:H39E564,H39E56C +39E56C:lI47|H39E684 +39E684:lI99|H39E798 +39E798:lI108|H39E8AC +39E8AC:lI101|H39E9C0 +39E9C0:lI97|H39EAB4 +39EAB4:lI114|H39EBA8 +39EBA8:lI99|H39EC9C +39EC9C:lI97|H39ED90 +39ED90:lI115|H39EE6C +39EE6C:lI101|H39EF40 +39EF40:lI47|H39F01C +39F01C:lI111|H39F100 +39F100:lI116|H39F1D4 +39F1D4:lI112|H39F2A0 +39F2A0:lI47|H39F35C +39F35C:lI101|H39F420 +39F420:lI114|H39F4EC +39F4EC:lI116|H39F5B8 +39F5B8:lI115|H39F68C +39F68C:lI47|H39F760 +39F760:lI108|H39F834 +39F834:lI105|H39F918 +39F918:lI98|H39F9F4 +39F9F4:lI47|H39FAD0 +39FAD0:lI111|H39FBAC +39FBAC:lI98|H39FC78 +39FC78:lI115|H39FD3C +39FD3C:lI101|H39FE08 +39FE08:lI114|H39FEC4 +39FEC4:lI118|H39FF80 +39FF80:lI101|H3A0034 +3A0034:lI114|H3A00E0 +3A00E0:lI47|H3A018C +3A018C:lI100|H3A0240 +3A0240:lI111|H3A02FC +3A02FC:lI99|H3A03B0 +3A03B0:lI47|H3A044C +3A044C:lI104|H3A04F0 +3A04F0:lI116|H3A0594 +3A0594:lI109|H3A0640 +3A0640:lI108|N +39E564:lI47|H39E67C +39E67C:lI99|H39E790 +39E790:lI114|H39E8A4 +39E8A4:lI97|H39E9B8 +39E9B8:lI115|H39EAAC +39EAAC:lI104|H39EBA0 +39EBA0:lI100|H39EC94 +39EC94:lI117|H39ED88 +39ED88:lI109|H39EE64 +39EE64:lI112|H39EF38 +39EF38:lI95|H39F014 +39F014:lI100|H39F0F8 +39F0F8:lI111|H39F1CC +39F1CC:lI99|N +39E374:lH39E46C|N +39E46C:t2:A10:erl_script_alias,H39E574 +39E574:t2:H39E68C,H39E694 +39E694:lH39E7A8|N +39E7A8:lI99|H39E8BC +39E8BC:lI114|H39E9D0 +39E9D0:lI97|H39EAC4 +39EAC4:lI115|H39EBB8 +39EBB8:lI104|H39ECAC +39ECAC:lI100|H39EDA0 +39EDA0:lI117|H39EE74 +39EE74:lI109|H39EF48 +39EF48:lI112|H39F024 +39F024:lI95|H39F108 +39F108:lI118|H39F1DC +39F1DC:lI105|H39F2A8 +39F2A8:lI101|H39F364 +39F364:lI119|H39F428 +39F428:lI101|H39F4F4 +39F4F4:lI114|N +39E68C:lI47|H39E7A0 +39E7A0:lI99|H39E8B4 +39E8B4:lI100|H39E9C8 +39E9C8:lI118|H39EABC +39EABC:lI95|H39EBB0 +39EBB0:lI101|H39ECA4 +39ECA4:lI114|H39ED98 +39ED98:lI108|N +39DB58:lN|H39DB9C +39DB9C:lH39D9FC|H39DBEC +39D9FC:t4:I127,I0,I0,I1 +39DBEC:lI8888|N +3A3E20:lH3A3DFC|H3A3704 +3A3DFC:t8:A5:child,P<0.46.0>,H39DAC8,H39DAD8,A9:permanent,I2000,A6:worker,H39DAE8 +39DAE8:lAD:httpd_manager|H39DB38 +39DB38:lAA:gen_server|N +39DAD8:t3:AD:httpd_manager,AA:start_link,H39DB30 +39DB30:lA9:undefined|H39DB78 +39DB78:lH39DB50|H39DBC0 +39DBC0:lN|N +39DAC8:t3:AD:httpd_manager,H39D9FC,I8888 +3A3704:lH3A36E0|H39D998 +3A36E0:t8:A5:child,P<0.45.0>,H39DA18,H39DA28,A9:permanent,I2000,AA:supervisor,H39DA38 +39DA38:lAE:httpd_misc_sup|H39DAC0 +39DAC0:lAA:supervisor|N +39DA28:t3:AE:httpd_misc_sup,A5:start,H39D958 +39D958:lH39D9FC|H39DA10 +39DA10:lI8888|H39DAB8 +39DAB8:lA7:silence|N +39DA18:t3:AE:httpd_misc_sup,H39D9FC,I8888 +39D998:lH39DA64|N +39DA64:t8:A5:child,P<0.44.0>,H39DAF0,H39DB00,A9:permanent,I2000,AA:supervisor,H39DB10 +39DB10:lA12:httpd_acceptor_sup|H39DB48 +39DB48:lAA:supervisor|N +39DB00:t3:A12:httpd_acceptor_sup,A5:start,H39DB40 +39DB40:lH39D9FC|H39DB80 +39DB80:lI8888|H39DBC8 +39DBC8:lA7:silence|N +39DAF0:t3:A12:httpd_acceptor_sup,H39D9FC,I8888 +39D960:t2:A5:local,A1A:httpd_sup__127_0_0_1__8888 +39D9CC:lAA:gen_server|H39DA90 +39DA90:lP<0.33.0>|H39DB20 +39DB20:lP<0.33.0>|H39DB60 +39DB60:lH39DBA4|H39DBB0 +39DBA4:t2:A5:local,A1A:httpd_sup__127_0_0_1__8888 +39DBB0:lAA:supervisor|H39DBF4 +39DBF4:lH39DC30|H39DC40 +39DC30:t3:H39D960,A9:httpd_sup,H39DA88 +39DC40:lN|N +39D940:t2:AD:$initial_call,H39D9E4 +39D9E4:t3:A3:gen,A7:init_it,H39D9CC +39D94C:t2:AA:$ancestors,H39D9F4 +39D9F4:lA8:web_tool|H39DAB0 +39DAB0:lP<0.27.0>|N +=proc_dictionary:<0.44.0> +H3756A8 +H3756B4 +H3756C0 +H3756CC +=proc_stack:<0.44.0> +36c194:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AA:supervisor +y3:H36C030 +y4:A1E:httpd_acc_sup__127_0_0_1__8888 +y5:P<0.43.0> +36c1b0:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H375710 +=proc_heap:<0.44.0> +36C030:tA:A5:state,H3756D8,AB:one_for_one,H36C028,N,I500,I100,N,A12:httpd_acceptor_sup,H375730 +375730:lA7:silence|N +36C028:lH36C004|N +36C004:t8:A5:child,P<0.47.0>,H36BE80,H36BE90,A9:permanent,I1000,A6:worker,H36BEA0 +36BEA0:lAE:httpd_acceptor|N +36BE90:t3:AE:httpd_acceptor,AA:start_link,H36BEE8 +36BEE8:lP<0.46.0>|H36BEF0 +36BEF0:lA7:ip_comm|H36BEF8 +36BEF8:lH36BF00|H36BF14 +36BF00:t4:I127,I0,I0,I1 +36BF14:lI8888|H36BF1C +36BF1C:lA1B:httpd_conf__127_0_0_1__8888|H36BF24 +36BF24:lA7:silence|N +36BE80:t3:AE:httpd_acceptor,H36BED4,I8888 +36BED4:t4:I127,I0,I0,I1 +3756D8:t2:A5:local,A1E:httpd_acc_sup__127_0_0_1__8888 +375710:lAA:gen_server|H375738 +375738:lP<0.43.0>|H375748 +375748:lP<0.43.0>|H375758 +375758:lH375760|H37576C +375760:t2:A5:local,A1E:httpd_acc_sup__127_0_0_1__8888 +37576C:lAA:supervisor|H375774 +375774:lH37577C|H37578C +37577C:t3:H3756D8,A12:httpd_acceptor_sup,H375730 +37578C:lN|N +3756A8:t2:AD:$initial_call,H375718 +375718:t3:A3:gen,A7:init_it,H375710 +3756B4:t2:A9:verbosity,A7:silence +3756C0:t2:AA:$ancestors,H375728 +375728:lA1A:httpd_sup__127_0_0_1__8888|H375740 +375740:lA8:web_tool|H375750 +375750:lP<0.27.0>|N +3756CC:t2:A5:sname,A7:acc_sup +=proc_dictionary:<0.45.0> +H36F484 +H36F4F4 +H36F468 +H36F500 +=proc_stack:<0.45.0> +36f734:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AA:supervisor +y3:H36F5D0 +y4:A1F:httpd_misc_sup__127_0_0_1__8888 +y5:P<0.43.0> +36f750:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H36F430 +=proc_heap:<0.45.0> +36F5D0:tA:A5:state,H36F3FC,AB:one_for_one,N,N,I0,I1,N,AE:httpd_misc_sup,H36F408 +36F408:lA7:silence|N +36F3FC:t2:A5:local,A1F:httpd_misc_sup__127_0_0_1__8888 +36F430:lAA:gen_server|H36F428 +36F428:lP<0.43.0>|H36F420 +36F420:lP<0.43.0>|H36F3D0 +36F3D0:lH36F3E0|H36F418 +36F3E0:t2:A5:local,A1F:httpd_misc_sup__127_0_0_1__8888 +36F418:lAA:supervisor|H36F3D8 +36F3D8:lH36F3EC|H36F410 +36F3EC:t3:H36F3FC,AE:httpd_misc_sup,H36F408 +36F410:lN|N +36F484:t2:AD:$initial_call,H36F474 +36F474:t3:A3:gen,A7:init_it,H36F430 +36F4F4:t2:A9:verbosity,A7:silence +36F468:t2:AA:$ancestors,H36F460 +36F460:lA1A:httpd_sup__127_0_0_1__8888|H36F440 +36F440:lA8:web_tool|H36F438 +36F438:lP<0.27.0>|N +36F500:t2:A5:sname,A8:misc_sup +=proc_dictionary:<0.46.0> +H3BDA50 +H3BDA5C +H3BDAC8 +H3BDB28 +H3BDB9C +H3BDC00 +H3BDADC +H3BDB3C +=proc_stack:<0.46.0> +39d8f4:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AD:httpd_manager +y3:H39D5A4 +y4:A16:httpd__127_0_0_1__8888 +y5:P<0.43.0> +39d910:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H3BDAB0 +=proc_heap:<0.46.0> +39D5A4:t9:A5:state,A7:ip_comm,A9:undefined,A1B:httpd_conf__127_0_0_1__8888,N,A9:unblocked,A9:undefined,A9:undefined,H39D430 +39D430:lH39BF40|H39D428 +39BF40:t2:A8:max_conn,I1 +39D428:lH39BC80|H39D420 +39BC80:t2:AF:last_heavy_load,A5:never +39D420:lH39D414|N +39D414:t2:AF:last_connection,H39D408 +39D408:t2:H39D3E8,H39D3F8 +39D3F8:t3:I11,I22,I34 +39D3E8:t3:I2004,I4,I21 +3BDAB0:lAA:gen_server|H3BDB20 +3BDB20:lP<0.43.0>|H3BDB94 +3BDB94:lP<0.43.0>|H3BDBF8 +3BDBF8:lH3BDC48|H3BDC54 +3BDC48:t2:A5:local,A16:httpd__127_0_0_1__8888 +3BDC54:lAD:httpd_manager|H3BDCAC +3BDCAC:lH3BDD14|H3BDD1C +3BDD14:lA9:undefined|H3BDD9C +3BDD9C:lH3BDA84|H3BDE2C +3BDA84:lH3BDAF0|H3BDAFC +3BDAF0:t2:AB:server_root,H3BDB48 +3BDB48:lI47|H3BDBB0 +3BDBB0:lI99|H3BDC0C +3BDC0C:lI108|H3BDC64 +3BDC64:lI101|H3BDCBC +3BDCBC:lI97|H3BDD2C +3BDD2C:lI114|H3BDDA4 +3BDDA4:lI99|H3BDE34 +3BDE34:lI97|H3BDED4 +3BDED4:lI115|H3BDF90 +3BDF90:lI101|H3BE054 +3BE054:lI47|H3BE128 +3BE128:lI111|H3BE204 +3BE204:lI116|H3BE2EC +3BE2EC:lI112|H3BE3E0 +3BE3E0:lI47|H3BE4E4 +3BE4E4:lI101|H3BE5E8 +3BE5E8:lI114|H3BE6EC +3BE6EC:lI116|H3BE7E0 +3BE7E0:lI115|H3BE8CC +3BE8CC:lI47|H3BE9B8 +3BE9B8:lI108|H3BEAAC +3BEAAC:lI105|H3BEB98 +3BEB98:lI98|H3BEC84 +3BEC84:lI47|H3BED70 +3BED70:lI119|H3BEE5C +3BEE5C:lI101|H3BEF30 +3BEF30:lI98|H3BEFFC +3BEFFC:lI116|H3BF0C8 +3BF0C8:lI111|H3BF19C +3BF19C:lI111|H3BF260 +3BF260:lI108|H3BF314 +3BF314:lI47|H3BF3C0 +3BF3C0:lI112|H3BF474 +3BF474:lI114|H3BF530 +3BF530:lI105|H3BF5F4 +3BF5F4:lI118|H3BF6C8 +3BF6C8:lI47|H3BF79C +3BF79C:lI114|H3BF870 +3BF870:lI111|H3BF954 +3BF954:lI111|H3BFA30 +3BFA30:lI116|N +3BDAFC:lH3BDB50|H3BDB5C +3BDB50:t2:AD:document_root,H3BDBB8 +3BDBB8:lI47|H3BDC14 +3BDC14:lI99|H3BDC6C +3BDC6C:lI108|H3BDCC4 +3BDCC4:lI101|H3BDD34 +3BDD34:lI97|H3BDDAC +3BDDAC:lI114|H3BDE3C +3BDE3C:lI99|H3BDEDC +3BDEDC:lI97|H3BDF98 +3BDF98:lI115|H3BE05C +3BE05C:lI101|H3BE130 +3BE130:lI47|H3BE20C +3BE20C:lI111|H3BE2F4 +3BE2F4:lI116|H3BE3E8 +3BE3E8:lI112|H3BE4EC +3BE4EC:lI47|H3BE5F0 +3BE5F0:lI101|H3BE6F4 +3BE6F4:lI114|H3BE7E8 +3BE7E8:lI116|H3BE8D4 +3BE8D4:lI115|H3BE9C0 +3BE9C0:lI47|H3BEAB4 +3BEAB4:lI108|H3BEBA0 +3BEBA0:lI105|H3BEC8C +3BEC8C:lI98|H3BED78 +3BED78:lI47|H3BEE64 +3BEE64:lI119|H3BEF38 +3BEF38:lI101|H3BF004 +3BF004:lI98|H3BF0D0 +3BF0D0:lI116|H3BF1A4 +3BF1A4:lI111|H3BF268 +3BF268:lI111|H3BF31C +3BF31C:lI108|H3BF3C8 +3BF3C8:lI47|H3BF47C +3BF47C:lI112|H3BF538 +3BF538:lI114|H3BF5FC +3BF5FC:lI105|H3BF6D0 +3BF6D0:lI118|H3BF7A4 +3BF7A4:lI47|H3BF878 +3BF878:lI114|H3BF95C +3BF95C:lI111|H3BFA38 +3BFA38:lI111|H3BFB0C +3BFB0C:lI116|H3BFBE8 +3BFBE8:lI47|H3BFCB4 +3BFCB4:lI100|H3BFD78 +3BFD78:lI111|H3BFE3C +3BFE3C:lI99|N +3BDB5C:lH3BDBC0|H3BDBCC +3BDBC0:t2:AA:mime_types,H3BDC1C +3BDC1C:lH3BDC74|H3BDC80 +3BDC74:t2:H3BDCCC,H3BDCD4 +3BDCD4:lI120|H3BDD44 +3BDD44:lI45|H3BDDBC +3BDDBC:lI119|H3BDE44 +3BDE44:lI111|H3BDEE4 +3BDEE4:lI114|H3BDFA0 +3BDFA0:lI108|H3BE064 +3BE064:lI100|H3BE138 +3BE138:lI47|H3BE214 +3BE214:lI120|H3BE2FC +3BE2FC:lI45|H3BE3F0 +3BE3F0:lI118|H3BE4F4 +3BE4F4:lI114|H3BE5F8 +3BE5F8:lI109|H3BE6FC +3BE6FC:lI108|N +3BDCCC:lI119|H3BDD3C +3BDD3C:lI114|H3BDDB4 +3BDDB4:lI108|N +3BDC80:lH3BDCDC|H3BDCE8 +3BDCDC:t2:H3BDD4C,H3BDD54 +3BDD54:lI120|H3BDDCC +3BDDCC:lI45|H3BDE54 +3BDE54:lI119|H3BDEF4 +3BDEF4:lI111|H3BDFA8 +3BDFA8:lI114|H3BE06C +3BE06C:lI108|H3BE140 +3BE140:lI100|H3BE21C +3BE21C:lI47|H3BE304 +3BE304:lI120|H3BE3F8 +3BE3F8:lI45|H3BE4FC +3BE4FC:lI118|H3BE600 +3BE600:lI114|H3BE704 +3BE704:lI109|H3BE7F0 +3BE7F0:lI108|N +3BDD4C:lI118|H3BDDC4 +3BDDC4:lI114|H3BDE4C +3BDE4C:lI109|H3BDEEC +3BDEEC:lI108|N +3BDCE8:lH3BDD5C|H3BDD68 +3BDD5C:t2:H3BDDD4,H3BDDDC +3BDDDC:lI120|H3BDE64 +3BDE64:lI45|H3BDF04 +3BDF04:lI99|H3BDFB0 +3BDFB0:lI111|H3BE074 +3BE074:lI110|H3BE148 +3BE148:lI102|H3BE224 +3BE224:lI101|H3BE30C +3BE30C:lI114|H3BE400 +3BE400:lI101|H3BE504 +3BE504:lI110|H3BE608 +3BE608:lI99|H3BE70C +3BE70C:lI101|H3BE7F8 +3BE7F8:lI47|H3BE8DC +3BE8DC:lI120|H3BE9C8 +3BE9C8:lI45|H3BEABC +3BEABC:lI99|H3BEBA8 +3BEBA8:lI111|H3BEC94 +3BEC94:lI111|H3BED80 +3BED80:lI108|H3BEE6C +3BEE6C:lI116|H3BEF40 +3BEF40:lI97|H3BF00C +3BF00C:lI108|H3BF0D8 +3BF0D8:lI107|N +3BDDD4:lI105|H3BDE5C +3BDE5C:lI99|H3BDEFC +3BDEFC:lI101|N +3BDD68:lH3BDDE4|H3BDDF0 +3BDDE4:t2:H3BDE6C,H3BDE74 +3BDE74:lI118|H3BDF14 +3BDF14:lI105|H3BDFC0 +3BDFC0:lI100|H3BE084 +3BE084:lI101|H3BE158 +3BE158:lI111|H3BE22C +3BE22C:lI47|H3BE314 +3BE314:lI120|H3BE408 +3BE408:lI45|H3BE50C +3BE50C:lI115|H3BE610 +3BE610:lI103|H3BE714 +3BE714:lI105|H3BE800 +3BE800:lI45|H3BE8E4 +3BE8E4:lI109|H3BE9D0 +3BE9D0:lI111|H3BEAC4 +3BEAC4:lI118|H3BEBB0 +3BEBB0:lI105|H3BEC9C +3BEC9C:lI101|N +3BDE6C:lI109|H3BDF0C +3BDF0C:lI111|H3BDFB8 +3BDFB8:lI118|H3BE07C +3BE07C:lI105|H3BE150 +3BE150:lI101|N +3BDDF0:lH3BDE7C|H3BDE88 +3BDE7C:t2:H3BDF1C,H3BDF24 +3BDF24:lI118|H3BDFD0 +3BDFD0:lI105|H3BE094 +3BE094:lI100|H3BE160 +3BE160:lI101|H3BE234 +3BE234:lI111|H3BE31C +3BE31C:lI47|H3BE410 +3BE410:lI120|H3BE514 +3BE514:lI45|H3BE618 +3BE618:lI109|H3BE71C +3BE71C:lI115|H3BE808 +3BE808:lI118|H3BE8EC +3BE8EC:lI105|H3BE9D8 +3BE9D8:lI100|H3BEACC +3BEACC:lI101|H3BEBB8 +3BEBB8:lI111|N +3BDF1C:lI97|H3BDFC8 +3BDFC8:lI118|H3BE08C +3BE08C:lI105|N +3BDE88:lH3BDF2C|H3BDF38 +3BDF2C:t2:H3BDFD8,H3BDFE0 +3BDFE0:lI118|H3BE0A4 +3BE0A4:lI105|H3BE168 +3BE168:lI100|H3BE23C +3BE23C:lI101|H3BE324 +3BE324:lI111|H3BE418 +3BE418:lI47|H3BE51C +3BE51C:lI113|H3BE620 +3BE620:lI117|H3BE724 +3BE724:lI105|H3BE810 +3BE810:lI99|H3BE8F4 +3BE8F4:lI107|H3BE9E0 +3BE9E0:lI116|H3BEAD4 +3BEAD4:lI105|H3BEBC0 +3BEBC0:lI109|H3BECA4 +3BECA4:lI101|N +3BDFD8:lI113|H3BE09C +3BE09C:lI116|N +3BDF38:lH3BDFE8|H3BDFF4 +3BDFE8:t2:H3BE0AC,H3BE0B4 +3BE0B4:lI118|H3BE178 +3BE178:lI105|H3BE24C +3BE24C:lI100|H3BE32C +3BE32C:lI101|H3BE420 +3BE420:lI111|H3BE524 +3BE524:lI47|H3BE628 +3BE628:lI113|H3BE72C +3BE72C:lI117|H3BE818 +3BE818:lI105|H3BE8FC +3BE8FC:lI99|H3BE9E8 +3BE9E8:lI107|H3BEADC +3BEADC:lI116|H3BEBC8 +3BEBC8:lI105|H3BECAC +3BECAC:lI109|H3BED88 +3BED88:lI101|N +3BE0AC:lI109|H3BE170 +3BE170:lI111|H3BE244 +3BE244:lI118|N +3BDFF4:lH3BE0BC|H3BE0C8 +3BE0BC:t2:H3BE180,H3BE188 +3BE188:lI118|H3BE25C +3BE25C:lI105|H3BE33C +3BE33C:lI100|H3BE430 +3BE430:lI101|H3BE52C +3BE52C:lI111|H3BE630 +3BE630:lI47|H3BE734 +3BE734:lI109|H3BE820 +3BE820:lI112|H3BE904 +3BE904:lI101|H3BE9F0 +3BE9F0:lI103|N +3BE180:lI109|H3BE254 +3BE254:lI112|H3BE334 +3BE334:lI101|H3BE428 +3BE428:lI103|N +3BE0C8:lH3BE190|H3BE19C +3BE190:t2:H3BE264,H3BE26C +3BE26C:lI118|H3BE34C +3BE34C:lI105|H3BE440 +3BE440:lI100|H3BE534 +3BE534:lI101|H3BE638 +3BE638:lI111|H3BE73C +3BE73C:lI47|H3BE828 +3BE828:lI109|H3BE90C +3BE90C:lI112|H3BE9F8 +3BE9F8:lI101|H3BEAE4 +3BEAE4:lI103|N +3BE264:lI109|H3BE344 +3BE344:lI112|H3BE438 +3BE438:lI103|N +3BE19C:lH3BE274|H3BE280 +3BE274:t2:H3BE354,H3BE35C +3BE35C:lI118|H3BE450 +3BE450:lI105|H3BE544 +3BE544:lI100|H3BE640 +3BE640:lI101|H3BE744 +3BE744:lI111|H3BE830 +3BE830:lI47|H3BE914 +3BE914:lI109|H3BEA00 +3BEA00:lI112|H3BEAEC +3BEAEC:lI101|H3BEBD0 +3BEBD0:lI103|N +3BE354:lI109|H3BE448 +3BE448:lI112|H3BE53C +3BE53C:lI101|N +3BE280:lH3BE364|H3BE370 +3BE364:t2:H3BE458,H3BE460 +3BE460:lI116|H3BE554 +3BE554:lI101|H3BE650 +3BE650:lI120|H3BE754 +3BE754:lI116|H3BE838 +3BE838:lI47|H3BE91C +3BE91C:lI120|H3BEA08 +3BEA08:lI45|H3BEAF4 +3BEAF4:lI115|H3BEBD8 +3BEBD8:lI103|H3BECB4 +3BECB4:lI109|H3BED90 +3BED90:lI108|N +3BE458:lI115|H3BE54C +3BE54C:lI103|H3BE648 +3BE648:lI109|H3BE74C +3BE74C:lI108|N +3BE370:lH3BE468|H3BE474 +3BE468:t2:H3BE55C,H3BE564 +3BE564:lI116|H3BE660 +3BE660:lI101|H3BE764 +3BE764:lI120|H3BE840 +3BE840:lI116|H3BE924 +3BE924:lI47|H3BEA10 +3BEA10:lI120|H3BEAFC +3BEAFC:lI45|H3BEBE0 +3BEBE0:lI115|H3BECBC +3BECBC:lI103|H3BED98 +3BED98:lI109|H3BEE74 +3BEE74:lI108|N +3BE55C:lI115|H3BE658 +3BE658:lI103|H3BE75C +3BE75C:lI109|N +3BE474:lH3BE56C|H3BE578 +3BE56C:t2:H3BE668,H3BE670 +3BE670:lI116|H3BE774 +3BE774:lI101|H3BE850 +3BE850:lI120|H3BE92C +3BE92C:lI116|H3BEA18 +3BEA18:lI47|H3BEB04 +3BEB04:lI120|H3BEBE8 +3BEBE8:lI45|H3BECC4 +3BECC4:lI115|H3BEDA0 +3BEDA0:lI101|H3BEE7C +3BEE7C:lI116|H3BEF48 +3BEF48:lI101|H3BF014 +3BF014:lI120|H3BF0E0 +3BF0E0:lI116|N +3BE668:lI101|H3BE76C +3BE76C:lI116|H3BE848 +3BE848:lI120|N +3BE578:lH3BE678|H3BE684 +3BE678:t2:H3BE77C,H3BE784 +3BE784:lI116|H3BE860 +3BE860:lI101|H3BE93C +3BE93C:lI120|H3BEA20 +3BEA20:lI116|H3BEB0C +3BEB0C:lI47|H3BEBF0 +3BEBF0:lI116|H3BECCC +3BECCC:lI97|H3BEDA8 +3BEDA8:lI98|H3BEE84 +3BEE84:lI45|H3BEF50 +3BEF50:lI115|H3BF01C +3BF01C:lI101|H3BF0E8 +3BF0E8:lI112|H3BF1AC +3BF1AC:lI97|H3BF270 +3BF270:lI114|H3BF324 +3BF324:lI97|H3BF3D0 +3BF3D0:lI116|H3BF484 +3BF484:lI101|H3BF540 +3BF540:lI100|H3BF604 +3BF604:lI45|H3BF6D8 +3BF6D8:lI118|H3BF7AC +3BF7AC:lI97|H3BF880 +3BF880:lI108|H3BF964 +3BF964:lI117|H3BFA40 +3BFA40:lI101|H3BFB14 +3BFB14:lI115|N +3BE77C:lI116|H3BE858 +3BE858:lI115|H3BE934 +3BE934:lI118|N +3BE684:lH3BE78C|H3BE798 +3BE78C:t2:H3BE868,H3BE870 +3BE870:lI116|H3BE94C +3BE94C:lI101|H3BEA30 +3BEA30:lI120|H3BEB14 +3BEB14:lI116|H3BEBF8 +3BEBF8:lI47|H3BECD4 +3BECD4:lI114|H3BEDB0 +3BEDB0:lI105|H3BEE8C +3BEE8C:lI99|H3BEF58 +3BEF58:lI104|H3BF024 +3BF024:lI116|H3BF0F0 +3BF0F0:lI101|H3BF1B4 +3BF1B4:lI120|H3BF278 +3BF278:lI116|N +3BE868:lI114|H3BE944 +3BE944:lI116|H3BEA28 +3BEA28:lI120|N +3BE798:lH3BE878|H3BE884 +3BE878:t2:H3BE954,H3BE95C +3BE95C:lI116|H3BEA40 +3BEA40:lI101|H3BEB24 +3BEB24:lI120|H3BEC00 +3BEC00:lI116|H3BECDC +3BECDC:lI47|H3BEDB8 +3BEDB8:lI112|H3BEE94 +3BEE94:lI108|H3BEF60 +3BEF60:lI97|H3BF02C +3BF02C:lI105|H3BF0F8 +3BF0F8:lI110|N +3BE954:lI116|H3BEA38 +3BEA38:lI120|H3BEB1C +3BEB1C:lI116|N +3BE884:lH3BE964|H3BE970 +3BE964:t2:H3BEA48,H3BEA50 +3BEA50:lI116|H3BEB34 +3BEB34:lI101|H3BEC10 +3BEC10:lI120|H3BECEC +3BECEC:lI116|H3BEDC8 +3BEDC8:lI47|H3BEE9C +3BEE9C:lI120|H3BEF68 +3BEF68:lI45|H3BF034 +3BF034:lI115|H3BF100 +3BF100:lI101|H3BF1BC +3BF1BC:lI114|H3BF280 +3BF280:lI118|H3BF32C +3BF32C:lI101|H3BF3D8 +3BF3D8:lI114|H3BF48C +3BF48C:lI45|H3BF548 +3BF548:lI112|H3BF60C +3BF60C:lI97|H3BF6E0 +3BF6E0:lI114|H3BF7B4 +3BF7B4:lI115|H3BF888 +3BF888:lI101|H3BF96C +3BF96C:lI100|H3BFA48 +3BFA48:lI45|H3BFB1C +3BFB1C:lI104|H3BFBF0 +3BFBF0:lI116|H3BFCBC +3BFCBC:lI109|H3BFD80 +3BFD80:lI108|N +3BEA48:lI115|H3BEB2C +3BEB2C:lI104|H3BEC08 +3BEC08:lI116|H3BECE4 +3BECE4:lI109|H3BEDC0 +3BEDC0:lI108|N +3BE970:lH3BEA58|H3BEA64 +3BEA58:t2:H3BEB3C,H3BEB44 +3BEB44:lI116|H3BEC20 +3BEC20:lI101|H3BECFC +3BECFC:lI120|H3BEDD8 +3BEDD8:lI116|H3BEEA4 +3BEEA4:lI47|H3BEF70 +3BEF70:lI104|H3BF03C +3BF03C:lI116|H3BF108 +3BF108:lI109|H3BF1C4 +3BF1C4:lI108|N +3BEB3C:lI104|H3BEC18 +3BEC18:lI116|H3BECF4 +3BECF4:lI109|H3BEDD0 +3BEDD0:lI108|N +3BEA64:lH3BEB4C|H3BEB58 +3BEB4C:t2:H3BEC28,H3BEC30 +3BEC30:lI116|H3BED0C +3BED0C:lI101|H3BEDE8 +3BEDE8:lI120|H3BEEAC +3BEEAC:lI116|H3BEF78 +3BEF78:lI47|H3BF044 +3BF044:lI104|H3BF110 +3BF110:lI116|H3BF1CC +3BF1CC:lI109|H3BF288 +3BF288:lI108|N +3BEC28:lI104|H3BED04 +3BED04:lI116|H3BEDE0 +3BEDE0:lI109|N +3BEB58:lH3BEC38|H3BEC44 +3BEC38:t2:H3BED14,H3BED1C +3BED1C:lI105|H3BEDF8 +3BEDF8:lI109|H3BEEBC +3BEEBC:lI97|H3BEF80 +3BEF80:lI103|H3BF04C +3BF04C:lI101|H3BF118 +3BF118:lI47|H3BF1D4 +3BF1D4:lI120|H3BF290 +3BF290:lI45|H3BF334 +3BF334:lI120|H3BF3E0 +3BF3E0:lI119|H3BF494 +3BF494:lI105|H3BF550 +3BF550:lI110|H3BF614 +3BF614:lI100|H3BF6E8 +3BF6E8:lI111|H3BF7BC +3BF7BC:lI119|H3BF890 +3BF890:lI100|H3BF974 +3BF974:lI117|H3BFA50 +3BFA50:lI109|H3BFB24 +3BFB24:lI112|N +3BED14:lI120|H3BEDF0 +3BEDF0:lI119|H3BEEB4 +3BEEB4:lI100|N +3BEC44:lH3BED24|H3BED30 +3BED24:t2:H3BEE00,H3BEE08 +3BEE08:lI105|H3BEECC +3BEECC:lI109|H3BEF90 +3BEF90:lI97|H3BF054 +3BF054:lI103|H3BF120 +3BF120:lI101|H3BF1DC +3BF1DC:lI47|H3BF298 +3BF298:lI120|H3BF33C +3BF33C:lI45|H3BF3E8 +3BF3E8:lI120|H3BF49C +3BF49C:lI112|H3BF558 +3BF558:lI105|H3BF61C +3BF61C:lI120|H3BF6F0 +3BF6F0:lI109|H3BF7C4 +3BF7C4:lI97|H3BF898 +3BF898:lI112|N +3BEE00:lI120|H3BEEC4 +3BEEC4:lI112|H3BEF88 +3BEF88:lI109|N +3BED30:lH3BEE10|H3BEE1C +3BEE10:t2:H3BEED4,H3BEEDC +3BEEDC:lI105|H3BEFA0 +3BEFA0:lI109|H3BF064 +3BF064:lI97|H3BF128 +3BF128:lI103|H3BF1E4 +3BF1E4:lI101|H3BF2A0 +3BF2A0:lI47|H3BF344 +3BF344:lI120|H3BF3F0 +3BF3F0:lI45|H3BF4A4 +3BF4A4:lI120|H3BF560 +3BF560:lI98|H3BF624 +3BF624:lI105|H3BF6F8 +3BF6F8:lI116|H3BF7CC +3BF7CC:lI109|H3BF8A0 +3BF8A0:lI97|H3BF97C +3BF97C:lI112|N +3BEED4:lI120|H3BEF98 +3BEF98:lI98|H3BF05C +3BF05C:lI109|N +3BEE1C:lH3BEEE4|H3BEEF0 +3BEEE4:t2:H3BEFA8,H3BEFB0 +3BEFB0:lI105|H3BF074 +3BF074:lI109|H3BF138 +3BF138:lI97|H3BF1EC +3BF1EC:lI103|H3BF2A8 +3BF2A8:lI101|H3BF34C +3BF34C:lI47|H3BF3F8 +3BF3F8:lI120|H3BF4AC +3BF4AC:lI45|H3BF568 +3BF568:lI114|H3BF62C +3BF62C:lI103|H3BF700 +3BF700:lI98|N +3BEFA8:lI114|H3BF06C +3BF06C:lI103|H3BF130 +3BF130:lI98|N +3BEEF0:lH3BEFB8|H3BEFC4 +3BEFB8:t2:H3BF07C,H3BF084 +3BF084:lI105|H3BF148 +3BF148:lI109|H3BF1FC +3BF1FC:lI97|H3BF2B0 +3BF2B0:lI103|H3BF354 +3BF354:lI101|H3BF400 +3BF400:lI47|H3BF4B4 +3BF4B4:lI120|H3BF570 +3BF570:lI45|H3BF634 +3BF634:lI112|H3BF708 +3BF708:lI111|H3BF7D4 +3BF7D4:lI114|H3BF8A8 +3BF8A8:lI116|H3BF984 +3BF984:lI97|H3BFA58 +3BFA58:lI98|H3BFB2C +3BFB2C:lI108|H3BFBF8 +3BFBF8:lI101|H3BFCC4 +3BFCC4:lI45|H3BFD88 +3BFD88:lI112|H3BFE44 +3BFE44:lI105|H3BFEF0 +3BFEF0:lI120|H3BFFA4 +3BFFA4:lI109|H3C0050 +3C0050:lI97|H3C00FC +3C00FC:lI112|N +3BF07C:lI112|H3BF140 +3BF140:lI112|H3BF1F4 +3BF1F4:lI109|N +3BEFC4:lH3BF08C|H3BF098 +3BF08C:t2:H3BF150,H3BF158 +3BF158:lI105|H3BF20C +3BF20C:lI109|H3BF2C0 +3BF2C0:lI97|H3BF35C +3BF35C:lI103|H3BF408 +3BF408:lI101|H3BF4BC +3BF4BC:lI47|H3BF578 +3BF578:lI120|H3BF63C +3BF63C:lI45|H3BF710 +3BF710:lI112|H3BF7DC +3BF7DC:lI111|H3BF8B0 +3BF8B0:lI114|H3BF98C +3BF98C:lI116|H3BFA60 +3BFA60:lI97|H3BFB34 +3BFB34:lI98|H3BFC00 +3BFC00:lI108|H3BFCCC +3BFCCC:lI101|H3BFD90 +3BFD90:lI45|H3BFE4C +3BFE4C:lI103|H3BFEF8 +3BFEF8:lI114|H3BFFAC +3BFFAC:lI97|H3C0058 +3C0058:lI121|H3C0104 +3C0104:lI109|H3C01A8 +3C01A8:lI97|H3C025C +3C025C:lI112|N +3BF150:lI112|H3BF204 +3BF204:lI103|H3BF2B8 +3BF2B8:lI109|N +3BF098:lH3BF160|H3BF16C +3BF160:t2:H3BF214,H3BF21C +3BF21C:lI105|H3BF2D0 +3BF2D0:lI109|H3BF36C +3BF36C:lI97|H3BF410 +3BF410:lI103|H3BF4C4 +3BF4C4:lI101|H3BF580 +3BF580:lI47|H3BF644 +3BF644:lI120|H3BF718 +3BF718:lI45|H3BF7E4 +3BF7E4:lI112|H3BF8B8 +3BF8B8:lI111|H3BF994 +3BF994:lI114|H3BFA68 +3BFA68:lI116|H3BFB3C +3BFB3C:lI97|H3BFC08 +3BFC08:lI98|H3BFCD4 +3BFCD4:lI108|H3BFD98 +3BFD98:lI101|H3BFE54 +3BFE54:lI45|H3BFF00 +3BFF00:lI98|H3BFFB4 +3BFFB4:lI105|H3C0060 +3C0060:lI116|H3C010C +3C010C:lI109|H3C01B0 +3C01B0:lI97|H3C0264 +3C0264:lI112|N +3BF214:lI112|H3BF2C8 +3BF2C8:lI98|H3BF364 +3BF364:lI109|N +3BF16C:lH3BF224|H3BF230 +3BF224:t2:H3BF2D8,H3BF2E0 +3BF2E0:lI105|H3BF37C +3BF37C:lI109|H3BF420 +3BF420:lI97|H3BF4CC +3BF4CC:lI103|H3BF588 +3BF588:lI101|H3BF64C +3BF64C:lI47|H3BF720 +3BF720:lI120|H3BF7EC +3BF7EC:lI45|H3BF8C0 +3BF8C0:lI112|H3BF99C +3BF99C:lI111|H3BFA70 +3BFA70:lI114|H3BFB44 +3BFB44:lI116|H3BFC10 +3BFC10:lI97|H3BFCDC +3BFCDC:lI98|H3BFDA0 +3BFDA0:lI108|H3BFE5C +3BFE5C:lI101|H3BFF08 +3BFF08:lI45|H3BFFBC +3BFFBC:lI97|H3C0068 +3C0068:lI110|H3C0114 +3C0114:lI121|H3C01B8 +3C01B8:lI109|H3C026C +3C026C:lI97|H3C0318 +3C0318:lI112|N +3BF2D8:lI112|H3BF374 +3BF374:lI110|H3BF418 +3BF418:lI109|N +3BF230:lH3BF2E8|H3BF2F4 +3BF2E8:t2:H3BF384,H3BF38C +3BF38C:lI105|H3BF430 +3BF430:lI109|H3BF4DC +3BF4DC:lI97|H3BF590 +3BF590:lI103|H3BF654 +3BF654:lI101|H3BF728 +3BF728:lI47|H3BF7F4 +3BF7F4:lI120|H3BF8C8 +3BF8C8:lI45|H3BF9A4 +3BF9A4:lI99|H3BFA78 +3BFA78:lI109|H3BFB4C +3BFB4C:lI117|H3BFC18 +3BFC18:lI45|H3BFCE4 +3BFCE4:lI114|H3BFDA8 +3BFDA8:lI97|H3BFE64 +3BFE64:lI115|H3BFF10 +3BFF10:lI116|H3BFFC4 +3BFFC4:lI101|H3C0070 +3C0070:lI114|N +3BF384:lI114|H3BF428 +3BF428:lI97|H3BF4D4 +3BF4D4:lI115|N +3BF2F4:lH3BF394|H3BF3A0 +3BF394:t2:H3BF438,H3BF440 +3BF440:lI105|H3BF4EC +3BF4EC:lI109|H3BF5A0 +3BF5A0:lI97|H3BF664 +3BF664:lI103|H3BF730 +3BF730:lI101|H3BF7FC +3BF7FC:lI47|H3BF8D0 +3BF8D0:lI116|H3BF9AC +3BF9AC:lI105|H3BFA80 +3BFA80:lI102|H3BFB54 +3BFB54:lI102|N +3BF438:lI116|H3BF4E4 +3BF4E4:lI105|H3BF598 +3BF598:lI102|H3BF65C +3BF65C:lI102|N +3BF3A0:lH3BF448|H3BF454 +3BF448:t2:H3BF4F4,H3BF4FC +3BF4FC:lI105|H3BF5B0 +3BF5B0:lI109|H3BF674 +3BF674:lI97|H3BF738 +3BF738:lI103|H3BF804 +3BF804:lI101|H3BF8D8 +3BF8D8:lI47|H3BF9B4 +3BF9B4:lI116|H3BFA88 +3BFA88:lI105|H3BFB5C +3BFB5C:lI102|H3BFC20 +3BFC20:lI102|N +3BF4F4:lI116|H3BF5A8 +3BF5A8:lI105|H3BF66C +3BF66C:lI102|N +3BF454:lH3BF504|H3BF510 +3BF504:t2:H3BF5B8,H3BF5C0 +3BF5C0:lI105|H3BF684 +3BF684:lI109|H3BF748 +3BF748:lI97|H3BF80C +3BF80C:lI103|H3BF8E0 +3BF8E0:lI101|H3BF9BC +3BF9BC:lI47|H3BFA90 +3BFA90:lI112|H3BFB64 +3BFB64:lI110|H3BFC28 +3BFC28:lI103|N +3BF5B8:lI112|H3BF67C +3BF67C:lI110|H3BF740 +3BF740:lI103|N +3BF510:lH3BF5C8|H3BF5D4 +3BF5C8:t2:H3BF68C,H3BF694 +3BF694:lI105|H3BF758 +3BF758:lI109|H3BF81C +3BF81C:lI97|H3BF8F0 +3BF8F0:lI103|H3BF9C4 +3BF9C4:lI101|H3BFA98 +3BFA98:lI47|H3BFB6C +3BFB6C:lI106|H3BFC30 +3BFC30:lI112|H3BFCEC +3BFCEC:lI101|H3BFDB0 +3BFDB0:lI103|N +3BF68C:lI106|H3BF750 +3BF750:lI112|H3BF814 +3BF814:lI101|H3BF8E8 +3BF8E8:lI103|N +3BF5D4:lH3BF69C|H3BF6A8 +3BF69C:t2:H3BF760,H3BF768 +3BF768:lI105|H3BF82C +3BF82C:lI109|H3BF900 +3BF900:lI97|H3BF9CC +3BF9CC:lI103|H3BFAA0 +3BFAA0:lI101|H3BFB74 +3BFB74:lI47|H3BFC38 +3BFC38:lI106|H3BFCF4 +3BFCF4:lI112|H3BFDB8 +3BFDB8:lI101|H3BFE6C +3BFE6C:lI103|N +3BF760:lI106|H3BF824 +3BF824:lI112|H3BF8F8 +3BF8F8:lI103|N +3BF6A8:lH3BF770|H3BF77C +3BF770:t2:H3BF834,H3BF83C +3BF83C:lI105|H3BF910 +3BF910:lI109|H3BF9DC +3BF9DC:lI97|H3BFAA8 +3BFAA8:lI103|H3BFB7C +3BFB7C:lI101|H3BFC40 +3BFC40:lI47|H3BFCFC +3BFCFC:lI106|H3BFDC0 +3BFDC0:lI112|H3BFE74 +3BFE74:lI101|H3BFF18 +3BFF18:lI103|N +3BF834:lI106|H3BF908 +3BF908:lI112|H3BF9D4 +3BF9D4:lI101|N +3BF77C:lH3BF844|H3BF850 +3BF844:t2:H3BF918,H3BF920 +3BF920:lI105|H3BF9EC +3BF9EC:lI109|H3BFAB8 +3BFAB8:lI97|H3BFB84 +3BFB84:lI103|H3BFC48 +3BFC48:lI101|H3BFD04 +3BFD04:lI47|H3BFDC8 +3BFDC8:lI105|H3BFE7C +3BFE7C:lI101|H3BFF20 +3BFF20:lI102|N +3BF918:lI105|H3BF9E4 +3BF9E4:lI101|H3BFAB0 +3BFAB0:lI102|N +3BF850:lH3BF928|H3BF934 +3BF928:t2:H3BF9F4,H3BF9FC +3BF9FC:lI105|H3BFAC8 +3BFAC8:lI109|H3BFB94 +3BFB94:lI97|H3BFC50 +3BFC50:lI103|H3BFD0C +3BFD0C:lI101|H3BFDD0 +3BFDD0:lI47|H3BFE84 +3BFE84:lI103|H3BFF28 +3BFF28:lI105|H3BFFCC +3BFFCC:lI102|N +3BF9F4:lI103|H3BFAC0 +3BFAC0:lI105|H3BFB8C +3BFB8C:lI102|N +3BF934:lH3BFA04|H3BFA10 +3BFA04:t2:H3BFAD0,H3BFAD8 +3BFAD8:lI99|H3BFBA4 +3BFBA4:lI104|H3BFC60 +3BFC60:lI101|H3BFD14 +3BFD14:lI109|H3BFDD8 +3BFDD8:lI105|H3BFE8C +3BFE8C:lI99|H3BFF30 +3BFF30:lI97|H3BFFD4 +3BFFD4:lI108|H3C0078 +3C0078:lI47|H3C011C +3C011C:lI120|H3C01C0 +3C01C0:lI45|H3C0274 +3C0274:lI112|H3C0320 +3C0320:lI100|H3C03CC +3C03CC:lI98|N +3BFAD0:lI112|H3BFB9C +3BFB9C:lI100|H3BFC58 +3BFC58:lI98|N +3BFA10:lH3BFAE0|H3BFAEC +3BFAE0:t2:H3BFBAC,H3BFBB4 +3BFBB4:lI99|H3BFC70 +3BFC70:lI104|H3BFD24 +3BFD24:lI101|H3BFDE0 +3BFDE0:lI109|H3BFE94 +3BFE94:lI105|H3BFF38 +3BFF38:lI99|H3BFFDC +3BFFDC:lI97|H3C0080 +3C0080:lI108|H3C0124 +3C0124:lI47|H3C01C8 +3C01C8:lI120|H3C027C +3C027C:lI45|H3C0328 +3C0328:lI112|H3C03D4 +3C03D4:lI100|H3C0460 +3C0460:lI98|N +3BFBAC:lI120|H3BFC68 +3BFC68:lI121|H3BFD1C +3BFD1C:lI122|N +3BFAEC:lH3BFBBC|H3BFBC8 +3BFBBC:t2:H3BFC78,H3BFC80 +3BFC80:lI97|H3BFD34 +3BFD34:lI117|H3BFDF0 +3BFDF0:lI100|H3BFE9C +3BFE9C:lI105|H3BFF40 +3BFF40:lI111|H3BFFE4 +3BFFE4:lI47|H3C0088 +3C0088:lI120|H3C012C +3C012C:lI45|H3C01D0 +3C01D0:lI119|H3C0284 +3C0284:lI97|H3C0330 +3C0330:lI118|N +3BFC78:lI119|H3BFD2C +3BFD2C:lI97|H3BFDE8 +3BFDE8:lI118|N +3BFBC8:lH3BFC88|H3BFC94 +3BFC88:t2:H3BFD3C,H3BFD44 +3BFD44:lI97|H3BFE00 +3BFE00:lI117|H3BFEA4 +3BFEA4:lI100|H3BFF48 +3BFF48:lI105|H3BFFEC +3BFFEC:lI111|H3C0090 +3C0090:lI47|H3C0134 +3C0134:lI120|H3C01D8 +3C01D8:lI45|H3C028C +3C028C:lI114|H3C0338 +3C0338:lI101|H3C03DC +3C03DC:lI97|H3C0468 +3C0468:lI108|H3C04FC +3C04FC:lI97|H3C0598 +3C0598:lI117|H3C063C +3C063C:lI100|H3C06E8 +3C06E8:lI105|H3C0794 +3C0794:lI111|N +3BFD3C:lI114|H3BFDF8 +3BFDF8:lI97|N +3BFC94:lH3BFD4C|H3BFD58 +3BFD4C:t2:H3BFE08,H3BFE10 +3BFE10:lI97|H3BFEB4 +3BFEB4:lI117|H3BFF58 +3BFF58:lI100|H3BFFF4 +3BFFF4:lI105|H3C0098 +3C0098:lI111|H3C013C +3C013C:lI47|H3C01E0 +3C01E0:lI120|H3C0294 +3C0294:lI45|H3C0340 +3C0340:lI112|H3C03E4 +3C03E4:lI110|H3C0470 +3C0470:lI45|H3C0504 +3C0504:lI114|H3C05A0 +3C05A0:lI101|H3C0644 +3C0644:lI97|H3C06F0 +3C06F0:lI108|H3C079C +3C079C:lI97|H3C0838 +3C0838:lI117|H3C08C4 +3C08C4:lI100|H3C0958 +3C0958:lI105|H3C09EC +3C09EC:lI111|H3C0A88 +3C0A88:lI45|H3C0B2C +3C0B2C:lI112|H3C0BD0 +3C0BD0:lI108|H3C0C84 +3C0C84:lI117|H3C0D38 +3C0D38:lI103|H3C0DEC +3C0DEC:lI105|H3C0EA0 +3C0EA0:lI110|N +3BFE08:lI114|H3BFEAC +3BFEAC:lI112|H3BFF50 +3BFF50:lI109|N +3BFD58:lH3BFE18|H3BFE24 +3BFE18:t2:H3BFEBC,H3BFEC4 +3BFEC4:lI97|H3BFF68 +3BFF68:lI117|H3C0004 +3C0004:lI100|H3C00A0 +3C00A0:lI105|H3C0144 +3C0144:lI111|H3C01E8 +3C01E8:lI47|H3C029C +3C029C:lI120|H3C0348 +3C0348:lI45|H3C03EC +3C03EC:lI112|H3C0478 +3C0478:lI110|H3C050C +3C050C:lI45|H3C05A8 +3C05A8:lI114|H3C064C +3C064C:lI101|H3C06F8 +3C06F8:lI97|H3C07A4 +3C07A4:lI108|H3C0840 +3C0840:lI97|H3C08CC +3C08CC:lI117|H3C0960 +3C0960:lI100|H3C09F4 +3C09F4:lI105|H3C0A90 +3C0A90:lI111|N +3BFEBC:lI114|H3BFF60 +3BFF60:lI97|H3BFFFC +3BFFFC:lI109|N +3BFE24:lH3BFECC|H3BFED8 +3BFECC:t2:H3BFF70,H3BFF78 +3BFF78:lI97|H3C0014 +3C0014:lI117|H3C00B0 +3C00B0:lI100|H3C014C +3C014C:lI105|H3C01F0 +3C01F0:lI111|H3C02A4 +3C02A4:lI47|H3C0350 +3C0350:lI120|H3C03F4 +3C03F4:lI45|H3C0480 +3C0480:lI97|H3C0514 +3C0514:lI105|H3C05B0 +3C05B0:lI102|H3C0654 +3C0654:lI102|N +3BFF70:lI97|H3C000C +3C000C:lI105|H3C00A8 +3C00A8:lI102|N +3BFED8:lH3BFF80|H3BFF8C +3BFF80:t2:H3C001C,H3C0024 +3C0024:lI97|H3C00C0 +3C00C0:lI117|H3C015C +3C015C:lI100|H3C0200 +3C0200:lI105|H3C02AC +3C02AC:lI111|H3C0358 +3C0358:lI47|H3C03FC +3C03FC:lI120|H3C0488 +3C0488:lI45|H3C051C +3C051C:lI97|H3C05B8 +3C05B8:lI105|H3C065C +3C065C:lI102|H3C0700 +3C0700:lI102|N +3C001C:lI97|H3C00B8 +3C00B8:lI105|H3C0154 +3C0154:lI102|H3C01F8 +3C01F8:lI102|N +3BFF8C:lH3C002C|H3C0038 +3C002C:t2:H3C00C8,H3C00D0 +3C00D0:lI97|H3C016C +3C016C:lI117|H3C0210 +3C0210:lI100|H3C02BC +3C02BC:lI105|H3C0360 +3C0360:lI111|H3C0404 +3C0404:lI47|H3C0490 +3C0490:lI120|H3C0524 +3C0524:lI45|H3C05C0 +3C05C0:lI97|H3C0664 +3C0664:lI105|H3C0708 +3C0708:lI102|H3C07AC +3C07AC:lI102|N +3C00C8:lI97|H3C0164 +3C0164:lI105|H3C0208 +3C0208:lI102|H3C02B4 +3C02B4:lI99|N +3C0038:lH3C00D8|H3C00E4 +3C00D8:t2:H3C0174,H3C017C +3C017C:lI97|H3C0220 +3C0220:lI117|H3C02CC +3C02CC:lI100|H3C0370 +3C0370:lI105|H3C040C +3C040C:lI111|H3C0498 +3C0498:lI47|H3C052C +3C052C:lI109|H3C05C8 +3C05C8:lI112|H3C066C +3C066C:lI101|H3C0710 +3C0710:lI103|N +3C0174:lI109|H3C0218 +3C0218:lI112|H3C02C4 +3C02C4:lI103|H3C0368 +3C0368:lI97|N +3C00E4:lH3C0184|H3C0190 +3C0184:t2:H3C0228,H3C0230 +3C0230:lI97|H3C02DC +3C02DC:lI117|H3C0380 +3C0380:lI100|H3C0414 +3C0414:lI105|H3C04A0 +3C04A0:lI111|H3C0534 +3C0534:lI47|H3C05D0 +3C05D0:lI109|H3C0674 +3C0674:lI112|H3C0718 +3C0718:lI101|H3C07B4 +3C07B4:lI103|N +3C0228:lI109|H3C02D4 +3C02D4:lI112|H3C0378 +3C0378:lI50|N +3C0190:lH3C0238|H3C0244 +3C0238:t2:H3C02E4,H3C02EC +3C02EC:lI97|H3C0390 +3C0390:lI117|H3C041C +3C041C:lI100|H3C04A8 +3C04A8:lI105|H3C053C +3C053C:lI111|H3C05D8 +3C05D8:lI47|H3C067C +3C067C:lI98|H3C0720 +3C0720:lI97|H3C07BC +3C07BC:lI115|H3C0848 +3C0848:lI105|H3C08D4 +3C08D4:lI99|N +3C02E4:lI97|H3C0388 +3C0388:lI117|N +3C0244:lH3C02F4|H3C0300 +3C02F4:t2:H3C0398,H3C03A0 +3C03A0:lI97|H3C042C +3C042C:lI117|H3C04B8 +3C04B8:lI100|H3C0544 +3C0544:lI105|H3C05E0 +3C05E0:lI111|H3C0684 +3C0684:lI47|H3C0728 +3C0728:lI98|H3C07C4 +3C07C4:lI97|H3C0850 +3C0850:lI115|H3C08DC +3C08DC:lI105|H3C0968 +3C0968:lI99|N +3C0398:lI115|H3C0424 +3C0424:lI110|H3C04B0 +3C04B0:lI100|N +3C0300:lH3C03A8|H3C03B4 +3C03A8:t2:H3C0434,H3C043C +3C043C:lI97|H3C04C8 +3C04C8:lI112|H3C0554 +3C0554:lI112|H3C05E8 +3C05E8:lI108|H3C068C +3C068C:lI105|H3C0730 +3C0730:lI99|H3C07CC +3C07CC:lI97|H3C0858 +3C0858:lI116|H3C08E4 +3C08E4:lI105|H3C0970 +3C0970:lI111|H3C09FC +3C09FC:lI110|H3C0A98 +3C0A98:lI47|H3C0B34 +3C0B34:lI122|H3C0BD8 +3C0BD8:lI105|H3C0C8C +3C0C8C:lI112|N +3C0434:lI122|H3C04C0 +3C04C0:lI105|H3C054C +3C054C:lI112|N +3C03B4:lH3C0444|H3C0450 +3C0444:t2:H3C04D0,H3C04D8 +3C04D8:lI97|H3C0564 +3C0564:lI112|H3C05F8 +3C05F8:lI112|H3C0694 +3C0694:lI108|H3C0738 +3C0738:lI105|H3C07D4 +3C07D4:lI99|H3C0860 +3C0860:lI97|H3C08EC +3C08EC:lI116|H3C0978 +3C0978:lI105|H3C0A04 +3C0A04:lI111|H3C0AA0 +3C0AA0:lI110|H3C0B3C +3C0B3C:lI47|H3C0BE0 +3C0BE0:lI120|H3C0C94 +3C0C94:lI45|H3C0D40 +3C0D40:lI119|H3C0DF4 +3C0DF4:lI97|H3C0EA8 +3C0EA8:lI105|H3C0F64 +3C0F64:lI115|H3C1030 +3C1030:lI45|H3C1104 +3C1104:lI115|H3C11D8 +3C11D8:lI111|H3C12A4 +3C12A4:lI117|H3C1378 +3C1378:lI114|H3C1454 +3C1454:lI99|H3C1538 +3C1538:lI101|N +3C04D0:lI115|H3C055C +3C055C:lI114|H3C05F0 +3C05F0:lI99|N +3C0450:lH3C04E0|H3C04EC +3C04E0:t2:H3C056C,H3C0574 +3C0574:lI97|H3C0608 +3C0608:lI112|H3C06A4 +3C06A4:lI112|H3C0748 +3C0748:lI108|H3C07E4 +3C07E4:lI105|H3C0868 +3C0868:lI99|H3C08F4 +3C08F4:lI97|H3C0980 +3C0980:lI116|H3C0A0C +3C0A0C:lI105|H3C0AA8 +3C0AA8:lI111|H3C0B44 +3C0B44:lI110|H3C0BE8 +3C0BE8:lI47|H3C0C9C +3C0C9C:lI120|H3C0D48 +3C0D48:lI45|H3C0DFC +3C0DFC:lI117|H3C0EB0 +3C0EB0:lI115|H3C0F6C +3C0F6C:lI116|H3C1038 +3C1038:lI97|H3C110C +3C110C:lI114|N +3C056C:lI117|H3C0600 +3C0600:lI115|H3C069C +3C069C:lI116|H3C0740 +3C0740:lI97|H3C07DC +3C07DC:lI114|N +3C04EC:lH3C057C|H3C0588 +3C057C:t2:H3C0610,H3C0618 +3C0618:lI97|H3C06B4 +3C06B4:lI112|H3C0750 +3C0750:lI112|H3C07EC +3C07EC:lI108|H3C0870 +3C0870:lI105|H3C08FC +3C08FC:lI99|H3C0988 +3C0988:lI97|H3C0A14 +3C0A14:lI116|H3C0AB0 +3C0AB0:lI105|H3C0B4C +3C0B4C:lI111|H3C0BF0 +3C0BF0:lI110|H3C0CA4 +3C0CA4:lI47|H3C0D50 +3C0D50:lI120|H3C0E04 +3C0E04:lI45|H3C0EB8 +3C0EB8:lI116|H3C0F74 +3C0F74:lI114|H3C1040 +3C1040:lI111|H3C1114 +3C1114:lI102|H3C11E0 +3C11E0:lI102|H3C12AC +3C12AC:lI45|H3C1380 +3C1380:lI109|H3C145C +3C145C:lI115|N +3C0610:lI109|H3C06AC +3C06AC:lI115|N +3C0588:lH3C0620|H3C062C +3C0620:t2:H3C06BC,H3C06C4 +3C06C4:lI97|H3C0760 +3C0760:lI112|H3C07F4 +3C07F4:lI112|H3C0878 +3C0878:lI108|H3C0904 +3C0904:lI105|H3C0990 +3C0990:lI99|H3C0A1C +3C0A1C:lI97|H3C0AB8 +3C0AB8:lI116|H3C0B54 +3C0B54:lI105|H3C0BF8 +3C0BF8:lI111|H3C0CAC +3C0CAC:lI110|H3C0D58 +3C0D58:lI47|H3C0E0C +3C0E0C:lI120|H3C0EC0 +3C0EC0:lI45|H3C0F7C +3C0F7C:lI116|H3C1048 +3C1048:lI114|H3C111C +3C111C:lI111|H3C11E8 +3C11E8:lI102|H3C12B4 +3C12B4:lI102|H3C1388 +3C1388:lI45|H3C1464 +3C1464:lI109|H3C1540 +3C1540:lI101|N +3C06BC:lI109|H3C0758 +3C0758:lI101|N +3C062C:lH3C06CC|H3C06D8 +3C06CC:t2:H3C0768,H3C0770 +3C0770:lI97|H3C0804 +3C0804:lI112|H3C0888 +3C0888:lI112|H3C090C +3C090C:lI108|H3C0998 +3C0998:lI105|H3C0A24 +3C0A24:lI99|H3C0AC0 +3C0AC0:lI97|H3C0B5C +3C0B5C:lI116|H3C0C00 +3C0C00:lI105|H3C0CB4 +3C0CB4:lI111|H3C0D60 +3C0D60:lI110|H3C0E14 +3C0E14:lI47|H3C0EC8 +3C0EC8:lI120|H3C0F84 +3C0F84:lI45|H3C1050 +3C1050:lI116|H3C1124 +3C1124:lI114|H3C11F0 +3C11F0:lI111|H3C12BC +3C12BC:lI102|H3C1390 +3C1390:lI102|H3C146C +3C146C:lI45|H3C1548 +3C1548:lI109|H3C161C +3C161C:lI97|H3C16F0 +3C16F0:lI110|N +3C0768:lI109|H3C07FC +3C07FC:lI97|H3C0880 +3C0880:lI110|N +3C06D8:lH3C0778|H3C0784 +3C0778:t2:H3C080C,H3C0814 +3C0814:lI97|H3C0890 +3C0890:lI112|H3C0914 +3C0914:lI112|H3C09A0 +3C09A0:lI108|H3C0A2C +3C0A2C:lI105|H3C0AC8 +3C0AC8:lI99|H3C0B64 +3C0B64:lI97|H3C0C08 +3C0C08:lI116|H3C0CBC +3C0CBC:lI105|H3C0D68 +3C0D68:lI111|H3C0E1C +3C0E1C:lI110|H3C0ED0 +3C0ED0:lI47|H3C0F8C +3C0F8C:lI120|H3C1058 +3C1058:lI45|H3C112C +3C112C:lI116|H3C11F8 +3C11F8:lI114|H3C12C4 +3C12C4:lI111|H3C1398 +3C1398:lI102|H3C1474 +3C1474:lI102|N +3C080C:lI116|N +3C0784:lH3C081C|H3C0828 +3C081C:t2:H3C0898,H3C08A0 +3C08A0:lI97|H3C0924 +3C0924:lI112|H3C09A8 +3C09A8:lI112|H3C0A34 +3C0A34:lI108|H3C0AD0 +3C0AD0:lI105|H3C0B6C +3C0B6C:lI99|H3C0C10 +3C0C10:lI97|H3C0CC4 +3C0CC4:lI116|H3C0D70 +3C0D70:lI105|H3C0E24 +3C0E24:lI111|H3C0ED8 +3C0ED8:lI110|H3C0F94 +3C0F94:lI47|H3C1060 +3C1060:lI120|H3C1134 +3C1134:lI45|H3C1200 +3C1200:lI116|H3C12CC +3C12CC:lI114|H3C13A0 +3C13A0:lI111|H3C147C +3C147C:lI102|H3C1550 +3C1550:lI102|N +3C0898:lI116|H3C091C +3C091C:lI114|N +3C0828:lH3C08A8|H3C08B4 +3C08A8:t2:H3C092C,H3C0934 +3C0934:lI97|H3C09B8 +3C09B8:lI112|H3C0A44 +3C0A44:lI112|H3C0AE0 +3C0AE0:lI108|H3C0B74 +3C0B74:lI105|H3C0C18 +3C0C18:lI99|H3C0CCC +3C0CCC:lI97|H3C0D78 +3C0D78:lI116|H3C0E2C +3C0E2C:lI105|H3C0EE0 +3C0EE0:lI111|H3C0F9C +3C0F9C:lI110|H3C1068 +3C1068:lI47|H3C113C +3C113C:lI120|H3C1208 +3C1208:lI45|H3C12D4 +3C12D4:lI116|H3C13A8 +3C13A8:lI114|H3C1484 +3C1484:lI111|H3C1558 +3C1558:lI102|H3C1624 +3C1624:lI102|N +3C092C:lI114|H3C09B0 +3C09B0:lI111|H3C0A3C +3C0A3C:lI102|H3C0AD8 +3C0AD8:lI102|N +3C08B4:lH3C093C|H3C0948 +3C093C:t2:H3C09C0,H3C09C8 +3C09C8:lI97|H3C0A54 +3C0A54:lI112|H3C0AF0 +3C0AF0:lI112|H3C0B84 +3C0B84:lI108|H3C0C28 +3C0C28:lI105|H3C0CDC +3C0CDC:lI99|H3C0D88 +3C0D88:lI97|H3C0E34 +3C0E34:lI116|H3C0EE8 +3C0EE8:lI105|H3C0FA4 +3C0FA4:lI111|H3C1070 +3C1070:lI110|H3C1144 +3C1144:lI47|H3C1210 +3C1210:lI120|H3C12DC +3C12DC:lI45|H3C13B0 +3C13B0:lI116|H3C148C +3C148C:lI101|H3C1560 +3C1560:lI120|H3C162C +3C162C:lI105|H3C16F8 +3C16F8:lI110|H3C17BC +3C17BC:lI102|H3C1880 +3C1880:lI111|N +3C09C0:lI116|H3C0A4C +3C0A4C:lI101|H3C0AE8 +3C0AE8:lI120|H3C0B7C +3C0B7C:lI105|H3C0C20 +3C0C20:lI110|H3C0CD4 +3C0CD4:lI102|H3C0D80 +3C0D80:lI111|N +3C0948:lH3C09D0|H3C09DC +3C09D0:t2:H3C0A5C,H3C0A64 +3C0A64:lI97|H3C0B00 +3C0B00:lI112|H3C0B94 +3C0B94:lI112|H3C0C38 +3C0C38:lI108|H3C0CE4 +3C0CE4:lI105|H3C0D90 +3C0D90:lI99|H3C0E3C +3C0E3C:lI97|H3C0EF0 +3C0EF0:lI116|H3C0FAC +3C0FAC:lI105|H3C1078 +3C1078:lI111|H3C114C +3C114C:lI110|H3C1218 +3C1218:lI47|H3C12E4 +3C12E4:lI120|H3C13B8 +3C13B8:lI45|H3C1494 +3C1494:lI116|H3C1568 +3C1568:lI101|H3C1634 +3C1634:lI120|H3C1700 +3C1700:lI105|H3C17C4 +3C17C4:lI110|H3C1888 +3C1888:lI102|H3C1944 +3C1944:lI111|N +3C0A5C:lI116|H3C0AF8 +3C0AF8:lI101|H3C0B8C +3C0B8C:lI120|H3C0C30 +3C0C30:lI105|N +3C09DC:lH3C0A6C|H3C0A78 +3C0A6C:t2:H3C0B08,H3C0B10 +3C0B10:lI97|H3C0BA4 +3C0BA4:lI112|H3C0C48 +3C0C48:lI112|H3C0CEC +3C0CEC:lI108|H3C0D98 +3C0D98:lI105|H3C0E44 +3C0E44:lI99|H3C0EF8 +3C0EF8:lI97|H3C0FB4 +3C0FB4:lI116|H3C1080 +3C1080:lI105|H3C1154 +3C1154:lI111|H3C1220 +3C1220:lI110|H3C12EC +3C12EC:lI47|H3C13C0 +3C13C0:lI120|H3C149C +3C149C:lI45|H3C1570 +3C1570:lI116|H3C163C +3C163C:lI101|H3C1708 +3C1708:lI120|N +3C0B08:lI116|H3C0B9C +3C0B9C:lI101|H3C0C40 +3C0C40:lI120|N +3C0A78:lH3C0B18|H3C0B24 +3C0B18:t2:H3C0BAC,H3C0BB4 +3C0BB4:lI97|H3C0C58 +3C0C58:lI112|H3C0CFC +3C0CFC:lI112|H3C0DA0 +3C0DA0:lI108|H3C0E4C +3C0E4C:lI105|H3C0F00 +3C0F00:lI99|H3C0FBC +3C0FBC:lI97|H3C1088 +3C1088:lI116|H3C115C +3C115C:lI105|H3C1228 +3C1228:lI111|H3C12F4 +3C12F4:lI110|H3C13C8 +3C13C8:lI47|H3C14A4 +3C14A4:lI120|H3C1578 +3C1578:lI45|H3C1644 +3C1644:lI116|H3C1710 +3C1710:lI99|H3C17CC +3C17CC:lI108|N +3C0BAC:lI116|H3C0C50 +3C0C50:lI99|H3C0CF4 +3C0CF4:lI108|N +3C0B24:lH3C0BBC|H3C0BC8 +3C0BBC:t2:H3C0C60,H3C0C68 +3C0C68:lI97|H3C0D0C +3C0D0C:lI112|H3C0DB0 +3C0DB0:lI112|H3C0E54 +3C0E54:lI108|H3C0F08 +3C0F08:lI105|H3C0FC4 +3C0FC4:lI99|H3C1090 +3C1090:lI97|H3C1164 +3C1164:lI116|H3C1230 +3C1230:lI105|H3C12FC +3C12FC:lI111|H3C13D0 +3C13D0:lI110|H3C14AC +3C14AC:lI47|H3C1580 +3C1580:lI120|H3C164C +3C164C:lI45|H3C1718 +3C1718:lI116|H3C17D4 +3C17D4:lI97|H3C1890 +3C1890:lI114|N +3C0C60:lI116|H3C0D04 +3C0D04:lI97|H3C0DA8 +3C0DA8:lI114|N +3C0BC8:lH3C0C70|H3C0C7C +3C0C70:t2:H3C0D14,H3C0D1C +3C0D1C:lI97|H3C0DC0 +3C0DC0:lI112|H3C0E64 +3C0E64:lI112|H3C0F18 +3C0F18:lI108|H3C0FD4 +3C0FD4:lI105|H3C10A0 +3C10A0:lI99|H3C116C +3C116C:lI97|H3C1238 +3C1238:lI116|H3C1304 +3C1304:lI105|H3C13D8 +3C13D8:lI111|H3C14B4 +3C14B4:lI110|H3C1588 +3C1588:lI47|H3C1654 +3C1654:lI120|H3C1720 +3C1720:lI45|H3C17DC +3C17DC:lI115|H3C1898 +3C1898:lI118|H3C194C +3C194C:lI52|H3C1A00 +3C1A00:lI99|H3C1AB4 +3C1AB4:lI114|H3C1B78 +3C1B78:lI99|N +3C0D14:lI115|H3C0DB8 +3C0DB8:lI118|H3C0E5C +3C0E5C:lI52|H3C0F10 +3C0F10:lI99|H3C0FCC +3C0FCC:lI114|H3C1098 +3C1098:lI99|N +3C0C7C:lH3C0D24|H3C0D30 +3C0D24:t2:H3C0DC8,H3C0DD0 +3C0DD0:lI97|H3C0E74 +3C0E74:lI112|H3C0F28 +3C0F28:lI112|H3C0FE4 +3C0FE4:lI108|H3C10B0 +3C10B0:lI105|H3C117C +3C117C:lI99|H3C1248 +3C1248:lI97|H3C130C +3C130C:lI116|H3C13E0 +3C13E0:lI105|H3C14BC +3C14BC:lI111|H3C1590 +3C1590:lI110|H3C165C +3C165C:lI47|H3C1728 +3C1728:lI120|H3C17E4 +3C17E4:lI45|H3C18A0 +3C18A0:lI115|H3C1954 +3C1954:lI118|H3C1A08 +3C1A08:lI52|H3C1ABC +3C1ABC:lI99|H3C1B80 +3C1B80:lI112|H3C1C4C +3C1C4C:lI105|H3C1D10 +3C1D10:lI111|N +3C0DC8:lI115|H3C0E6C +3C0E6C:lI118|H3C0F20 +3C0F20:lI52|H3C0FDC +3C0FDC:lI99|H3C10A8 +3C10A8:lI112|H3C1174 +3C1174:lI105|H3C1240 +3C1240:lI111|N +3C0D30:lH3C0DD8|H3C0DE4 +3C0DD8:t2:H3C0E7C,H3C0E84 +3C0E84:lI97|H3C0F38 +3C0F38:lI112|H3C0FF4 +3C0FF4:lI112|H3C10B8 +3C10B8:lI108|H3C1184 +3C1184:lI105|H3C1250 +3C1250:lI99|H3C1314 +3C1314:lI97|H3C13E8 +3C13E8:lI116|H3C14C4 +3C14C4:lI105|H3C1598 +3C1598:lI111|H3C1664 +3C1664:lI110|H3C1730 +3C1730:lI47|H3C17EC +3C17EC:lI120|H3C18A8 +3C18A8:lI45|H3C195C +3C195C:lI115|H3C1A10 +3C1A10:lI116|H3C1AC4 +3C1AC4:lI117|H3C1B88 +3C1B88:lI102|H3C1C54 +3C1C54:lI102|H3C1D18 +3C1D18:lI105|H3C1DD4 +3C1DD4:lI116|N +3C0E7C:lI115|H3C0F30 +3C0F30:lI105|H3C0FEC +3C0FEC:lI116|N +3C0DE4:lH3C0E8C|H3C0E98 +3C0E8C:t2:H3C0F40,H3C0F48 +3C0F48:lI97|H3C1004 +3C1004:lI112|H3C10C8 +3C10C8:lI112|H3C1194 +3C1194:lI108|H3C1258 +3C1258:lI105|H3C131C +3C131C:lI99|H3C13F0 +3C13F0:lI97|H3C14CC +3C14CC:lI116|H3C15A0 +3C15A0:lI105|H3C166C +3C166C:lI111|H3C1738 +3C1738:lI110|H3C17F4 +3C17F4:lI47|H3C18B0 +3C18B0:lI120|H3C1964 +3C1964:lI45|H3C1A18 +3C1A18:lI115|H3C1ACC +3C1ACC:lI104|H3C1B90 +3C1B90:lI97|H3C1C5C +3C1C5C:lI114|N +3C0F40:lI115|H3C0FFC +3C0FFC:lI104|H3C10C0 +3C10C0:lI97|H3C118C +3C118C:lI114|N +3C0E98:lH3C0F50|H3C0F5C +3C0F50:t2:H3C100C,H3C1014 +3C1014:lI97|H3C10D8 +3C10D8:lI112|H3C119C +3C119C:lI112|H3C1260 +3C1260:lI108|H3C1324 +3C1324:lI105|H3C13F8 +3C13F8:lI99|H3C14D4 +3C14D4:lI97|H3C15A8 +3C15A8:lI116|H3C1674 +3C1674:lI105|H3C1740 +3C1740:lI111|H3C17FC +3C17FC:lI110|H3C18B8 +3C18B8:lI47|H3C196C +3C196C:lI120|H3C1A20 +3C1A20:lI45|H3C1AD4 +3C1AD4:lI115|H3C1B98 +3C1B98:lI104|N +3C100C:lI115|H3C10D0 +3C10D0:lI104|N +3C0F5C:lH3C101C|H3C1028 +3C101C:t2:H3C10E0,H3C10E8 +3C10E8:lI97|H3C11AC +3C11AC:lI112|H3C1268 +3C1268:lI112|H3C132C +3C132C:lI108|H3C1400 +3C1400:lI105|H3C14DC +3C14DC:lI99|H3C15B0 +3C15B0:lI97|H3C167C +3C167C:lI116|H3C1748 +3C1748:lI105|H3C1804 +3C1804:lI111|H3C18C0 +3C18C0:lI110|H3C1974 +3C1974:lI47|H3C1A28 +3C1A28:lI120|H3C1ADC +3C1ADC:lI45|H3C1BA0 +3C1BA0:lI110|H3C1C64 +3C1C64:lI101|H3C1D20 +3C1D20:lI116|H3C1DDC +3C1DDC:lI99|H3C1E98 +3C1E98:lI100|H3C1F5C +3C1F5C:lI102|N +3C10E0:lI110|H3C11A4 +3C11A4:lI99|N +3C1028:lH3C10F0|H3C10FC +3C10F0:t2:H3C11B4,H3C11BC +3C11BC:lI97|H3C1278 +3C1278:lI112|H3C133C +3C133C:lI112|H3C1408 +3C1408:lI108|H3C14E4 +3C14E4:lI105|H3C15B8 +3C15B8:lI99|H3C1684 +3C1684:lI97|H3C1750 +3C1750:lI116|H3C180C +3C180C:lI105|H3C18C8 +3C18C8:lI111|H3C197C +3C197C:lI110|H3C1A30 +3C1A30:lI47|H3C1AE4 +3C1AE4:lI120|H3C1BA8 +3C1BA8:lI45|H3C1C6C +3C1C6C:lI110|H3C1D28 +3C1D28:lI101|H3C1DE4 +3C1DE4:lI116|H3C1EA0 +3C1EA0:lI99|H3C1F64 +3C1F64:lI100|H3C2018 +3C2018:lI102|N +3C11B4:lI99|H3C1270 +3C1270:lI100|H3C1334 +3C1334:lI102|N +3C10FC:lH3C11C4|H3C11D0 +3C11C4:t2:H3C1280,H3C1288 +3C1288:lI97|H3C134C +3C134C:lI112|H3C1418 +3C1418:lI112|H3C14EC +3C14EC:lI108|H3C15C0 +3C15C0:lI105|H3C168C +3C168C:lI99|H3C1758 +3C1758:lI97|H3C1814 +3C1814:lI116|H3C18D0 +3C18D0:lI105|H3C1984 +3C1984:lI111|H3C1A38 +3C1A38:lI110|H3C1AEC +3C1AEC:lI47|H3C1BB0 +3C1BB0:lI120|H3C1C74 +3C1C74:lI45|H3C1D30 +3C1D30:lI109|H3C1DEC +3C1DEC:lI105|H3C1EA8 +3C1EA8:lI102|N +3C1280:lI109|H3C1344 +3C1344:lI105|H3C1410 +3C1410:lI102|N +3C11D0:lH3C1290|H3C129C +3C1290:t2:H3C1354,H3C135C +3C135C:lI97|H3C1428 +3C1428:lI112|H3C14FC +3C14FC:lI112|H3C15D0 +3C15D0:lI108|H3C169C +3C169C:lI105|H3C1760 +3C1760:lI99|H3C181C +3C181C:lI97|H3C18D8 +3C18D8:lI116|H3C198C +3C198C:lI105|H3C1A40 +3C1A40:lI111|H3C1AF4 +3C1AF4:lI110|H3C1BB8 +3C1BB8:lI47|H3C1C7C +3C1C7C:lI120|H3C1D38 +3C1D38:lI45|H3C1DF4 +3C1DF4:lI108|H3C1EB0 +3C1EB0:lI97|H3C1F6C +3C1F6C:lI116|H3C2020 +3C2020:lI101|H3C20DC +3C20DC:lI120|N +3C1354:lI108|H3C1420 +3C1420:lI97|H3C14F4 +3C14F4:lI116|H3C15C8 +3C15C8:lI101|H3C1694 +3C1694:lI120|N +3C129C:lH3C1364|H3C1370 +3C1364:t2:H3C1430,H3C1438 +3C1438:lI97|H3C150C +3C150C:lI112|H3C15E0 +3C15E0:lI112|H3C16A4 +3C16A4:lI108|H3C1768 +3C1768:lI105|H3C1824 +3C1824:lI99|H3C18E0 +3C18E0:lI97|H3C1994 +3C1994:lI116|H3C1A48 +3C1A48:lI105|H3C1AFC +3C1AFC:lI111|H3C1BC0 +3C1BC0:lI110|H3C1C84 +3C1C84:lI47|H3C1D40 +3C1D40:lI120|H3C1DFC +3C1DFC:lI45|H3C1EB8 +3C1EB8:lI107|H3C1F74 +3C1F74:lI111|H3C2028 +3C2028:lI97|H3C20E4 +3C20E4:lI110|N +3C1430:lI115|H3C1504 +3C1504:lI107|H3C15D8 +3C15D8:lI112|N +3C1370:lH3C1440|H3C144C +3C1440:t2:H3C1514,H3C151C +3C151C:lI97|H3C15F0 +3C15F0:lI112|H3C16B4 +3C16B4:lI112|H3C1770 +3C1770:lI108|H3C182C +3C182C:lI105|H3C18E8 +3C18E8:lI99|H3C199C +3C199C:lI97|H3C1A50 +3C1A50:lI116|H3C1B04 +3C1B04:lI105|H3C1BC8 +3C1BC8:lI111|H3C1C8C +3C1C8C:lI110|H3C1D48 +3C1D48:lI47|H3C1E04 +3C1E04:lI120|H3C1EC0 +3C1EC0:lI45|H3C1F7C +3C1F7C:lI107|H3C2030 +3C2030:lI111|H3C20EC +3C20EC:lI97|H3C21A0 +3C21A0:lI110|N +3C1514:lI115|H3C15E8 +3C15E8:lI107|H3C16AC +3C16AC:lI100|N +3C144C:lH3C1524|H3C1530 +3C1524:t2:H3C15F8,H3C1600 +3C1600:lI97|H3C16C4 +3C16C4:lI112|H3C1780 +3C1780:lI112|H3C1834 +3C1834:lI108|H3C18F0 +3C18F0:lI105|H3C19A4 +3C19A4:lI99|H3C1A58 +3C1A58:lI97|H3C1B0C +3C1B0C:lI116|H3C1BD0 +3C1BD0:lI105|H3C1C94 +3C1C94:lI111|H3C1D50 +3C1D50:lI110|H3C1E0C +3C1E0C:lI47|H3C1EC8 +3C1EC8:lI120|H3C1F84 +3C1F84:lI45|H3C2038 +3C2038:lI107|H3C20F4 +3C20F4:lI111|H3C21A8 +3C21A8:lI97|H3C225C +3C225C:lI110|N +3C15F8:lI115|H3C16BC +3C16BC:lI107|H3C1778 +3C1778:lI116|N +3C1530:lH3C1608|H3C1614 +3C1608:t2:H3C16CC,H3C16D4 +3C16D4:lI97|H3C1790 +3C1790:lI112|H3C1844 +3C1844:lI112|H3C18F8 +3C18F8:lI108|H3C19AC +3C19AC:lI105|H3C1A60 +3C1A60:lI99|H3C1B14 +3C1B14:lI97|H3C1BD8 +3C1BD8:lI116|H3C1C9C +3C1C9C:lI105|H3C1D58 +3C1D58:lI111|H3C1E14 +3C1E14:lI110|H3C1ED0 +3C1ED0:lI47|H3C1F8C +3C1F8C:lI120|H3C2040 +3C2040:lI45|H3C20FC +3C20FC:lI107|H3C21B0 +3C21B0:lI111|H3C2264 +3C2264:lI97|H3C2320 +3C2320:lI110|N +3C16CC:lI115|H3C1788 +3C1788:lI107|H3C183C +3C183C:lI109|N +3C1614:lH3C16DC|H3C16E8 +3C16DC:t2:H3C1798,H3C17A0 +3C17A0:lI97|H3C1854 +3C1854:lI112|H3C1908 +3C1908:lI112|H3C19B4 +3C19B4:lI108|H3C1A68 +3C1A68:lI105|H3C1B1C +3C1B1C:lI99|H3C1BE0 +3C1BE0:lI97|H3C1CA4 +3C1CA4:lI116|H3C1D60 +3C1D60:lI105|H3C1E1C +3C1E1C:lI111|H3C1ED8 +3C1ED8:lI110|H3C1F94 +3C1F94:lI47|H3C2048 +3C2048:lI120|H3C2104 +3C2104:lI45|H3C21B8 +3C21B8:lI104|H3C226C +3C226C:lI116|H3C2328 +3C2328:lI116|H3C23E4 +3C23E4:lI112|H3C2498 +3C2498:lI100|H3C2554 +3C2554:lI45|H3C2610 +3C2610:lI99|H3C26D4 +3C26D4:lI103|H3C2790 +3C2790:lI105|N +3C1798:lI99|H3C184C +3C184C:lI103|H3C1900 +3C1900:lI105|N +3C16E8:lH3C17A8|H3C17B4 +3C17A8:t2:H3C185C,H3C1864 +3C1864:lI97|H3C1918 +3C1918:lI112|H3C19C4 +3C19C4:lI112|H3C1A70 +3C1A70:lI108|H3C1B24 +3C1B24:lI105|H3C1BE8 +3C1BE8:lI99|H3C1CAC +3C1CAC:lI97|H3C1D68 +3C1D68:lI116|H3C1E24 +3C1E24:lI105|H3C1EE0 +3C1EE0:lI111|H3C1F9C +3C1F9C:lI110|H3C2050 +3C2050:lI47|H3C210C +3C210C:lI120|H3C21C0 +3C21C0:lI45|H3C2274 +3C2274:lI104|H3C2330 +3C2330:lI100|H3C23EC +3C23EC:lI102|N +3C185C:lI104|H3C1910 +3C1910:lI100|H3C19BC +3C19BC:lI102|N +3C17B4:lH3C186C|H3C1878 +3C186C:t2:H3C1920,H3C1928 +3C1928:lI97|H3C19D4 +3C19D4:lI112|H3C1A78 +3C1A78:lI112|H3C1B2C +3C1B2C:lI108|H3C1BF0 +3C1BF0:lI105|H3C1CB4 +3C1CB4:lI99|H3C1D70 +3C1D70:lI97|H3C1E2C +3C1E2C:lI116|H3C1EE8 +3C1EE8:lI105|H3C1FA4 +3C1FA4:lI111|H3C2058 +3C2058:lI110|H3C2114 +3C2114:lI47|H3C21C8 +3C21C8:lI120|H3C227C +3C227C:lI45|H3C2338 +3C2338:lI103|H3C23F4 +3C23F4:lI122|H3C24A0 +3C24A0:lI105|H3C255C +3C255C:lI112|N +3C1920:lI103|H3C19CC +3C19CC:lI122|N +3C1878:lH3C1930|H3C193C +3C1930:t2:H3C19DC,H3C19E4 +3C19E4:lI97|H3C1A88 +3C1A88:lI112|H3C1B3C +3C1B3C:lI112|H3C1C00 +3C1C00:lI108|H3C1CBC +3C1CBC:lI105|H3C1D78 +3C1D78:lI99|H3C1E34 +3C1E34:lI97|H3C1EF0 +3C1EF0:lI116|H3C1FAC +3C1FAC:lI105|H3C2060 +3C2060:lI111|H3C211C +3C211C:lI110|H3C21D0 +3C21D0:lI47|H3C2284 +3C2284:lI120|H3C2340 +3C2340:lI45|H3C23FC +3C23FC:lI103|H3C24A8 +3C24A8:lI116|H3C2564 +3C2564:lI97|H3C2618 +3C2618:lI114|N +3C19DC:lI103|H3C1A80 +3C1A80:lI116|H3C1B34 +3C1B34:lI97|H3C1BF8 +3C1BF8:lI114|N +3C193C:lH3C19EC|H3C19F8 +3C19EC:t2:H3C1A90,H3C1A98 +3C1A98:lI97|H3C1B4C +3C1B4C:lI112|H3C1C10 +3C1C10:lI112|H3C1CC4 +3C1CC4:lI108|H3C1D80 +3C1D80:lI105|H3C1E3C +3C1E3C:lI99|H3C1EF8 +3C1EF8:lI97|H3C1FB4 +3C1FB4:lI116|H3C2068 +3C2068:lI105|H3C2124 +3C2124:lI111|H3C21D8 +3C21D8:lI110|H3C228C +3C228C:lI47|H3C2348 +3C2348:lI120|H3C2404 +3C2404:lI45|H3C24B0 +3C24B0:lI100|H3C256C +3C256C:lI118|H3C2620 +3C2620:lI105|N +3C1A90:lI100|H3C1B44 +3C1B44:lI118|H3C1C08 +3C1C08:lI105|N +3C19F8:lH3C1AA0|H3C1AAC +3C1AA0:t2:H3C1B54,H3C1B5C +3C1B5C:lI97|H3C1C20 +3C1C20:lI112|H3C1CD4 +3C1CD4:lI112|H3C1D88 +3C1D88:lI108|H3C1E44 +3C1E44:lI105|H3C1F00 +3C1F00:lI99|H3C1FBC +3C1FBC:lI97|H3C2070 +3C2070:lI116|H3C212C +3C212C:lI105|H3C21E0 +3C21E0:lI111|H3C2294 +3C2294:lI110|H3C2350 +3C2350:lI47|H3C240C +3C240C:lI120|H3C24B8 +3C24B8:lI45|H3C2574 +3C2574:lI100|H3C2628 +3C2628:lI105|H3C26DC +3C26DC:lI114|H3C2798 +3C2798:lI101|H3C2854 +3C2854:lI99|H3C2918 +3C2918:lI116|H3C29E4 +3C29E4:lI111|H3C2AB0 +3C2AB0:lI114|N +3C1B54:lI100|H3C1C18 +3C1C18:lI99|H3C1CCC +3C1CCC:lI114|N +3C1AAC:lH3C1B64|H3C1B70 +3C1B64:t2:H3C1C28,H3C1C30 +3C1C30:lI97|H3C1CE4 +3C1CE4:lI112|H3C1D98 +3C1D98:lI112|H3C1E4C +3C1E4C:lI108|H3C1F08 +3C1F08:lI105|H3C1FC4 +3C1FC4:lI99|H3C2078 +3C2078:lI97|H3C2134 +3C2134:lI116|H3C21E8 +3C21E8:lI105|H3C229C +3C229C:lI111|H3C2358 +3C2358:lI110|H3C2414 +3C2414:lI47|H3C24C0 +3C24C0:lI120|H3C257C +3C257C:lI45|H3C2630 +3C2630:lI100|H3C26E4 +3C26E4:lI105|H3C27A0 +3C27A0:lI114|H3C285C +3C285C:lI101|H3C2920 +3C2920:lI99|H3C29EC +3C29EC:lI116|H3C2AB8 +3C2AB8:lI111|H3C2B84 +3C2B84:lI114|N +3C1C28:lI100|H3C1CDC +3C1CDC:lI105|H3C1D90 +3C1D90:lI114|N +3C1B70:lH3C1C38|H3C1C44 +3C1C38:t2:H3C1CEC,H3C1CF4 +3C1CF4:lI97|H3C1DA8 +3C1DA8:lI112|H3C1E5C +3C1E5C:lI112|H3C1F10 +3C1F10:lI108|H3C1FCC +3C1FCC:lI105|H3C2080 +3C2080:lI99|H3C213C +3C213C:lI97|H3C21F0 +3C21F0:lI116|H3C22A4 +3C22A4:lI105|H3C2360 +3C2360:lI111|H3C241C +3C241C:lI110|H3C24C8 +3C24C8:lI47|H3C2584 +3C2584:lI120|H3C2638 +3C2638:lI45|H3C26EC +3C26EC:lI100|H3C27A8 +3C27A8:lI105|H3C2864 +3C2864:lI114|H3C2928 +3C2928:lI101|H3C29F4 +3C29F4:lI99|H3C2AC0 +3C2AC0:lI116|H3C2B8C +3C2B8C:lI111|H3C2C48 +3C2C48:lI114|N +3C1CEC:lI100|H3C1DA0 +3C1DA0:lI120|H3C1E54 +3C1E54:lI114|N +3C1C44:lH3C1CFC|H3C1D08 +3C1CFC:t2:H3C1DB0,H3C1DB8 +3C1DB8:lI97|H3C1E6C +3C1E6C:lI112|H3C1F20 +3C1F20:lI112|H3C1FD4 +3C1FD4:lI108|H3C2088 +3C2088:lI105|H3C2144 +3C2144:lI99|H3C21F8 +3C21F8:lI97|H3C22AC +3C22AC:lI116|H3C2368 +3C2368:lI105|H3C2424 +3C2424:lI111|H3C24D0 +3C24D0:lI110|H3C258C +3C258C:lI47|H3C2640 +3C2640:lI120|H3C26F4 +3C26F4:lI45|H3C27B0 +3C27B0:lI99|H3C286C +3C286C:lI115|H3C2930 +3C2930:lI104|N +3C1DB0:lI99|H3C1E64 +3C1E64:lI115|H3C1F18 +3C1F18:lI104|N +3C1D08:lH3C1DC0|H3C1DCC +3C1DC0:t2:H3C1E74,H3C1E7C +3C1E7C:lI97|H3C1F30 +3C1F30:lI112|H3C1FE4 +3C1FE4:lI112|H3C2098 +3C2098:lI108|H3C214C +3C214C:lI105|H3C2200 +3C2200:lI99|H3C22B4 +3C22B4:lI97|H3C2370 +3C2370:lI116|H3C242C +3C242C:lI105|H3C24D8 +3C24D8:lI111|H3C2594 +3C2594:lI110|H3C2648 +3C2648:lI47|H3C26FC +3C26FC:lI120|H3C27B8 +3C27B8:lI45|H3C2874 +3C2874:lI99|H3C2938 +3C2938:lI112|H3C29FC +3C29FC:lI105|H3C2AC8 +3C2AC8:lI111|N +3C1E74:lI99|H3C1F28 +3C1F28:lI112|H3C1FDC +3C1FDC:lI105|H3C2090 +3C2090:lI111|N +3C1DCC:lH3C1E84|H3C1E90 +3C1E84:t2:H3C1F38,H3C1F40 +3C1F40:lI97|H3C1FEC +3C1FEC:lI112|H3C20A0 +3C20A0:lI112|H3C2154 +3C2154:lI108|H3C2208 +3C2208:lI105|H3C22BC +3C22BC:lI99|H3C2378 +3C2378:lI97|H3C2434 +3C2434:lI116|H3C24E0 +3C24E0:lI105|H3C259C +3C259C:lI111|H3C2650 +3C2650:lI110|H3C2704 +3C2704:lI47|H3C27C0 +3C27C0:lI120|H3C287C +3C287C:lI45|H3C2940 +3C2940:lI99|H3C2A04 +3C2A04:lI111|H3C2AD0 +3C2AD0:lI109|H3C2B94 +3C2B94:lI112|H3C2C50 +3C2C50:lI114|H3C2D00 +3C2D00:lI101|H3C2DA8 +3C2DA8:lI115|H3C2E40 +3C2E40:lI115|N +3C1F38:lI90|N +3C1E90:lH3C1F48|H3C1F54 +3C1F48:t2:H3C1FF4,H3C1FFC +3C1FFC:lI97|H3C20B0 +3C20B0:lI112|H3C2164 +3C2164:lI112|H3C2210 +3C2210:lI108|H3C22C4 +3C22C4:lI105|H3C2380 +3C2380:lI99|H3C243C +3C243C:lI97|H3C24E8 +3C24E8:lI116|H3C25A4 +3C25A4:lI105|H3C2658 +3C2658:lI111|H3C270C +3C270C:lI110|H3C27C8 +3C27C8:lI47|H3C2884 +3C2884:lI120|H3C2948 +3C2948:lI45|H3C2A0C +3C2A0C:lI99|H3C2AD8 +3C2AD8:lI100|H3C2B9C +3C2B9C:lI108|H3C2C58 +3C2C58:lI105|H3C2D08 +3C2D08:lI110|H3C2DB0 +3C2DB0:lI107|N +3C1FF4:lI118|H3C20A8 +3C20A8:lI99|H3C215C +3C215C:lI100|N +3C1F54:lH3C2004|H3C2010 +3C2004:t2:H3C20B8,H3C20C0 +3C20C0:lI97|H3C2174 +3C2174:lI112|H3C2220 +3C2220:lI112|H3C22D4 +3C22D4:lI108|H3C2390 +3C2390:lI105|H3C2444 +3C2444:lI99|H3C24F0 +3C24F0:lI97|H3C25AC +3C25AC:lI116|H3C2660 +3C2660:lI105|H3C2714 +3C2714:lI111|H3C27D0 +3C27D0:lI110|H3C288C +3C288C:lI47|H3C2950 +3C2950:lI120|H3C2A14 +3C2A14:lI45|H3C2AE0 +3C2AE0:lI98|H3C2BA4 +3C2BA4:lI99|H3C2C60 +3C2C60:lI112|H3C2D10 +3C2D10:lI105|H3C2DB8 +3C2DB8:lI111|N +3C20B8:lI98|H3C216C +3C216C:lI99|H3C2218 +3C2218:lI112|H3C22CC +3C22CC:lI105|H3C2388 +3C2388:lI111|N +3C2010:lH3C20C8|H3C20D4 +3C20C8:t2:H3C217C,H3C2184 +3C2184:lI97|H3C2230 +3C2230:lI112|H3C22E4 +3C22E4:lI112|H3C2398 +3C2398:lI108|H3C244C +3C244C:lI105|H3C24F8 +3C24F8:lI99|H3C25B4 +3C25B4:lI97|H3C2668 +3C2668:lI116|H3C271C +3C271C:lI105|H3C27D8 +3C27D8:lI111|H3C2894 +3C2894:lI110|H3C2958 +3C2958:lI47|H3C2A1C +3C2A1C:lI114|H3C2AE8 +3C2AE8:lI116|H3C2BAC +3C2BAC:lI102|N +3C217C:lI114|H3C2228 +3C2228:lI116|H3C22DC +3C22DC:lI102|N +3C20D4:lH3C218C|H3C2198 +3C218C:t2:H3C2238,H3C2240 +3C2240:lI97|H3C22F4 +3C22F4:lI112|H3C23A8 +3C23A8:lI112|H3C2454 +3C2454:lI108|H3C2500 +3C2500:lI105|H3C25BC +3C25BC:lI99|H3C2670 +3C2670:lI97|H3C2724 +3C2724:lI116|H3C27E0 +3C27E0:lI105|H3C289C +3C289C:lI111|H3C2960 +3C2960:lI110|H3C2A24 +3C2A24:lI47|H3C2AF0 +3C2AF0:lI112|H3C2BB4 +3C2BB4:lI111|H3C2C68 +3C2C68:lI119|H3C2D18 +3C2D18:lI101|H3C2DC0 +3C2DC0:lI114|H3C2E48 +3C2E48:lI112|H3C2EC0 +3C2EC0:lI111|H3C2F38 +3C2F38:lI105|H3C2FA8 +3C2FA8:lI110|H3C3010 +3C3010:lI116|N +3C2238:lI112|H3C22EC +3C22EC:lI112|H3C23A0 +3C23A0:lI116|N +3C2198:lH3C2248|H3C2254 +3C2248:t2:H3C22FC,H3C2304 +3C2304:lI97|H3C23B8 +3C23B8:lI112|H3C245C +3C245C:lI112|H3C2508 +3C2508:lI108|H3C25C4 +3C25C4:lI105|H3C2678 +3C2678:lI99|H3C272C +3C272C:lI97|H3C27E8 +3C27E8:lI116|H3C28A4 +3C28A4:lI105|H3C2968 +3C2968:lI111|H3C2A2C +3C2A2C:lI110|H3C2AF8 +3C2AF8:lI47|H3C2BBC +3C2BBC:lI112|H3C2C70 +3C2C70:lI111|H3C2D20 +3C2D20:lI115|H3C2DC8 +3C2DC8:lI116|H3C2E50 +3C2E50:lI115|H3C2EC8 +3C2EC8:lI99|H3C2F40 +3C2F40:lI114|H3C2FB0 +3C2FB0:lI105|H3C3018 +3C3018:lI112|H3C3078 +3C3078:lI116|N +3C22FC:lI97|H3C23B0 +3C23B0:lI105|N +3C2254:lH3C230C|H3C2318 +3C230C:t2:H3C23C0,H3C23C8 +3C23C8:lI97|H3C246C +3C246C:lI112|H3C2518 +3C2518:lI112|H3C25CC +3C25CC:lI108|H3C2680 +3C2680:lI105|H3C2734 +3C2734:lI99|H3C27F0 +3C27F0:lI97|H3C28AC +3C28AC:lI116|H3C2970 +3C2970:lI105|H3C2A34 +3C2A34:lI111|H3C2B00 +3C2B00:lI110|H3C2BC4 +3C2BC4:lI47|H3C2C78 +3C2C78:lI112|H3C2D28 +3C2D28:lI111|H3C2DD0 +3C2DD0:lI115|H3C2E58 +3C2E58:lI116|H3C2ED0 +3C2ED0:lI115|H3C2F48 +3C2F48:lI99|H3C2FB8 +3C2FB8:lI114|H3C3020 +3C3020:lI105|H3C3080 +3C3080:lI112|H3C30D8 +3C30D8:lI116|N +3C23C0:lI101|H3C2464 +3C2464:lI112|H3C2510 +3C2510:lI115|N +3C2318:lH3C23D0|H3C23DC +3C23D0:t2:H3C2474,H3C247C +3C247C:lI97|H3C2528 +3C2528:lI112|H3C25D4 +3C25D4:lI112|H3C2688 +3C2688:lI108|H3C273C +3C273C:lI105|H3C27F8 +3C27F8:lI99|H3C28B4 +3C28B4:lI97|H3C2978 +3C2978:lI116|H3C2A3C +3C2A3C:lI105|H3C2B08 +3C2B08:lI111|H3C2BCC +3C2BCC:lI110|H3C2C80 +3C2C80:lI47|H3C2D30 +3C2D30:lI112|H3C2DD8 +3C2DD8:lI111|H3C2E60 +3C2E60:lI115|H3C2ED8 +3C2ED8:lI116|H3C2F50 +3C2F50:lI115|H3C2FC0 +3C2FC0:lI99|H3C3028 +3C3028:lI114|H3C3088 +3C3088:lI105|H3C30E0 +3C30E0:lI112|H3C3130 +3C3130:lI116|N +3C2474:lI112|H3C2520 +3C2520:lI115|N +3C23DC:lH3C2484|H3C2490 +3C2484:t2:H3C2530,H3C2538 +3C2538:lI97|H3C25E4 +3C25E4:lI112|H3C2698 +3C2698:lI112|H3C2744 +3C2744:lI108|H3C2800 +3C2800:lI105|H3C28BC +3C28BC:lI99|H3C2980 +3C2980:lI97|H3C2A44 +3C2A44:lI116|H3C2B10 +3C2B10:lI105|H3C2BD4 +3C2BD4:lI111|H3C2C88 +3C2C88:lI110|H3C2D38 +3C2D38:lI47|H3C2DE0 +3C2DE0:lI112|H3C2E68 +3C2E68:lI100|H3C2EE0 +3C2EE0:lI102|N +3C2530:lI112|H3C25DC +3C25DC:lI100|H3C2690 +3C2690:lI102|N +3C2490:lH3C2540|H3C254C +3C2540:t2:H3C25EC,H3C25F4 +3C25F4:lI97|H3C26A8 +3C26A8:lI112|H3C2754 +3C2754:lI112|H3C2808 +3C2808:lI108|H3C28C4 +3C28C4:lI105|H3C2988 +3C2988:lI99|H3C2A4C +3C2A4C:lI97|H3C2B18 +3C2B18:lI116|H3C2BDC +3C2BDC:lI105|H3C2C90 +3C2C90:lI111|H3C2D40 +3C2D40:lI110|H3C2DE8 +3C2DE8:lI47|H3C2E70 +3C2E70:lI111|H3C2EE8 +3C2EE8:lI100|H3C2F58 +3C2F58:lI97|N +3C25EC:lI111|H3C26A0 +3C26A0:lI100|H3C274C +3C274C:lI97|N +3C254C:lH3C25FC|H3C2608 +3C25FC:t2:H3C26B0,H3C26B8 +3C26B8:lI97|H3C2764 +3C2764:lI112|H3C2818 +3C2818:lI112|H3C28CC +3C28CC:lI108|H3C2990 +3C2990:lI105|H3C2A54 +3C2A54:lI99|H3C2B20 +3C2B20:lI97|H3C2BE4 +3C2BE4:lI116|H3C2C98 +3C2C98:lI105|H3C2D48 +3C2D48:lI111|H3C2DF0 +3C2DF0:lI110|H3C2E78 +3C2E78:lI47|H3C2EF0 +3C2EF0:lI111|H3C2F60 +3C2F60:lI99|H3C2FC8 +3C2FC8:lI116|H3C3030 +3C3030:lI101|H3C3090 +3C3090:lI116|H3C30E8 +3C30E8:lI45|H3C3138 +3C3138:lI115|H3C3180 +3C3180:lI116|H3C31C8 +3C31C8:lI114|H3C3210 +3C3210:lI101|H3C3258 +3C3258:lI97|H3C32A0 +3C32A0:lI109|N +3C26B0:lI98|H3C275C +3C275C:lI105|H3C2810 +3C2810:lI110|N +3C2608:lH3C26C0|H3C26CC +3C26C0:t2:H3C276C,H3C2774 +3C2774:lI97|H3C2828 +3C2828:lI112|H3C28DC +3C28DC:lI112|H3C2998 +3C2998:lI108|H3C2A5C +3C2A5C:lI105|H3C2B28 +3C2B28:lI99|H3C2BEC +3C2BEC:lI97|H3C2CA0 +3C2CA0:lI116|H3C2D50 +3C2D50:lI105|H3C2DF8 +3C2DF8:lI111|H3C2E80 +3C2E80:lI110|H3C2EF8 +3C2EF8:lI47|H3C2F68 +3C2F68:lI111|H3C2FD0 +3C2FD0:lI99|H3C3038 +3C3038:lI116|H3C3098 +3C3098:lI101|H3C30F0 +3C30F0:lI116|H3C3140 +3C3140:lI45|H3C3188 +3C3188:lI115|H3C31D0 +3C31D0:lI116|H3C3218 +3C3218:lI114|H3C3260 +3C3260:lI101|H3C32A8 +3C32A8:lI97|H3C32E8 +3C32E8:lI109|N +3C276C:lI100|H3C2820 +3C2820:lI109|H3C28D4 +3C28D4:lI115|N +3C26CC:lH3C277C|H3C2788 +3C277C:t2:H3C2830,H3C2838 +3C2838:lI97|H3C28EC +3C28EC:lI112|H3C29A8 +3C29A8:lI112|H3C2A64 +3C2A64:lI108|H3C2B30 +3C2B30:lI105|H3C2BF4 +3C2BF4:lI99|H3C2CA8 +3C2CA8:lI97|H3C2D58 +3C2D58:lI116|H3C2E00 +3C2E00:lI105|H3C2E88 +3C2E88:lI111|H3C2F00 +3C2F00:lI110|H3C2F70 +3C2F70:lI47|H3C2FD8 +3C2FD8:lI111|H3C3040 +3C3040:lI99|H3C30A0 +3C30A0:lI116|H3C30F8 +3C30F8:lI101|H3C3148 +3C3148:lI116|H3C3190 +3C3190:lI45|H3C31D8 +3C31D8:lI115|H3C3220 +3C3220:lI116|H3C3268 +3C3268:lI114|H3C32B0 +3C32B0:lI101|H3C32F0 +3C32F0:lI97|H3C3320 +3C3320:lI109|N +3C2830:lI108|H3C28E4 +3C28E4:lI104|H3C29A0 +3C29A0:lI97|N +3C2788:lH3C2840|H3C284C +3C2840:t2:H3C28F4,H3C28FC +3C28FC:lI97|H3C29B8 +3C29B8:lI112|H3C2A74 +3C2A74:lI112|H3C2B38 +3C2B38:lI108|H3C2BFC +3C2BFC:lI105|H3C2CB0 +3C2CB0:lI99|H3C2D60 +3C2D60:lI97|H3C2E08 +3C2E08:lI116|H3C2E90 +3C2E90:lI105|H3C2F08 +3C2F08:lI111|H3C2F78 +3C2F78:lI110|H3C2FE0 +3C2FE0:lI47|H3C3048 +3C3048:lI111|H3C30A8 +3C30A8:lI99|H3C3100 +3C3100:lI116|H3C3150 +3C3150:lI101|H3C3198 +3C3198:lI116|H3C31E0 +3C31E0:lI45|H3C3228 +3C3228:lI115|H3C3270 +3C3270:lI116|H3C32B8 +3C32B8:lI114|H3C32F8 +3C32F8:lI101|H3C3328 +3C3328:lI97|H3C3350 +3C3350:lI109|N +3C28F4:lI108|H3C29B0 +3C29B0:lI122|H3C2A6C +3C2A6C:lI104|N +3C284C:lH3C2904|H3C2910 +3C2904:t2:H3C29C0,H3C29C8 +3C29C8:lI97|H3C2A84 +3C2A84:lI112|H3C2B48 +3C2B48:lI112|H3C2C04 +3C2C04:lI108|H3C2CB8 +3C2CB8:lI105|H3C2D68 +3C2D68:lI99|H3C2E10 +3C2E10:lI97|H3C2E98 +3C2E98:lI116|H3C2F10 +3C2F10:lI105|H3C2F80 +3C2F80:lI111|H3C2FE8 +3C2FE8:lI110|H3C3050 +3C3050:lI47|H3C30B0 +3C30B0:lI111|H3C3108 +3C3108:lI99|H3C3158 +3C3158:lI116|H3C31A0 +3C31A0:lI101|H3C31E8 +3C31E8:lI116|H3C3230 +3C3230:lI45|H3C3278 +3C3278:lI115|H3C32C0 +3C32C0:lI116|H3C3300 +3C3300:lI114|H3C3330 +3C3330:lI101|H3C3358 +3C3358:lI97|H3C3378 +3C3378:lI109|N +3C29C0:lI101|H3C2A7C +3C2A7C:lI120|H3C2B40 +3C2B40:lI101|N +3C2910:lH3C29D0|H3C29DC +3C29D0:t2:H3C2A8C,H3C2A94 +3C2A94:lI97|H3C2B58 +3C2B58:lI112|H3C2C14 +3C2C14:lI112|H3C2CC8 +3C2CC8:lI108|H3C2D78 +3C2D78:lI105|H3C2E18 +3C2E18:lI99|H3C2EA0 +3C2EA0:lI97|H3C2F18 +3C2F18:lI116|H3C2F88 +3C2F88:lI105|H3C2FF0 +3C2FF0:lI111|H3C3058 +3C3058:lI110|H3C30B8 +3C30B8:lI47|H3C3110 +3C3110:lI111|H3C3160 +3C3160:lI99|H3C31A8 +3C31A8:lI116|H3C31F0 +3C31F0:lI101|H3C3238 +3C3238:lI116|H3C3280 +3C3280:lI45|H3C32C8 +3C32C8:lI115|H3C3308 +3C3308:lI116|H3C3338 +3C3338:lI114|H3C3360 +3C3360:lI101|H3C3380 +3C3380:lI97|H3C3398 +3C3398:lI109|N +3C2A8C:lI99|H3C2B50 +3C2B50:lI108|H3C2C0C +3C2C0C:lI97|H3C2CC0 +3C2CC0:lI115|H3C2D70 +3C2D70:lI115|N +3C29DC:lH3C2A9C|H3C2AA8 +3C2A9C:t2:H3C2B60,H3C2B68 +3C2B68:lI97|H3C2C24 +3C2C24:lI112|H3C2CD8 +3C2CD8:lI112|H3C2D80 +3C2D80:lI108|H3C2E20 +3C2E20:lI105|H3C2EA8 +3C2EA8:lI99|H3C2F20 +3C2F20:lI97|H3C2F90 +3C2F90:lI116|H3C2FF8 +3C2FF8:lI105|H3C3060 +3C3060:lI111|H3C30C0 +3C30C0:lI110|H3C3118 +3C3118:lI47|H3C3168 +3C3168:lI109|H3C31B0 +3C31B0:lI115|H3C31F8 +3C31F8:lI119|H3C3240 +3C3240:lI111|H3C3288 +3C3288:lI114|H3C32D0 +3C32D0:lI100|N +3C2B60:lI100|H3C2C1C +3C2C1C:lI111|H3C2CD0 +3C2CD0:lI99|N +3C2AA8:lH3C2B70|H3C2B7C +3C2B70:t2:H3C2C2C,H3C2C34 +3C2C34:lI97|H3C2CE8 +3C2CE8:lI112|H3C2D90 +3C2D90:lI112|H3C2E28 +3C2E28:lI108|H3C2EB0 +3C2EB0:lI105|H3C2F28 +3C2F28:lI99|H3C2F98 +3C2F98:lI97|H3C3000 +3C3000:lI116|H3C3068 +3C3068:lI105|H3C30C8 +3C30C8:lI111|H3C3120 +3C3120:lI110|H3C3170 +3C3170:lI47|H3C31B8 +3C31B8:lI109|H3C3200 +3C3200:lI97|H3C3248 +3C3248:lI99|H3C3290 +3C3290:lI45|H3C32D8 +3C32D8:lI99|H3C3310 +3C3310:lI111|H3C3340 +3C3340:lI109|H3C3368 +3C3368:lI112|H3C3388 +3C3388:lI97|H3C33A0 +3C33A0:lI99|H3C33B0 +3C33B0:lI116|H3C33C0 +3C33C0:lI112|H3C33D0 +3C33D0:lI114|H3C33E0 +3C33E0:lI111|N +3C2C2C:lI99|H3C2CE0 +3C2CE0:lI112|H3C2D88 +3C2D88:lI116|N +3C2B7C:lH3C2C3C|N +3C2C3C:t2:H3C2CF0,H3C2CF8 +3C2CF8:lI97|H3C2DA0 +3C2DA0:lI112|H3C2E38 +3C2E38:lI112|H3C2EB8 +3C2EB8:lI108|H3C2F30 +3C2F30:lI105|H3C2FA0 +3C2FA0:lI99|H3C3008 +3C3008:lI97|H3C3070 +3C3070:lI116|H3C30D0 +3C30D0:lI105|H3C3128 +3C3128:lI111|H3C3178 +3C3178:lI110|H3C31C0 +3C31C0:lI47|H3C3208 +3C3208:lI109|H3C3250 +3C3250:lI97|H3C3298 +3C3298:lI99|H3C32E0 +3C32E0:lI45|H3C3318 +3C3318:lI98|H3C3348 +3C3348:lI105|H3C3370 +3C3370:lI110|H3C3390 +3C3390:lI104|H3C33A8 +3C33A8:lI101|H3C33B8 +3C33B8:lI120|H3C33C8 +3C33C8:lI52|H3C33D8 +3C33D8:lI48|N +3C2CF0:lI104|H3C2D98 +3C2D98:lI113|H3C2E30 +3C2E30:lI120|N +3BDBCC:lH3BDA78|H3BDA8C +3BDA78:t2:A4:port,I8888 +3BDA8C:lH3BDB04|H3BDB10 +3BDB04:t2:AC:bind_address,H3BDB64 +3BDB64:t4:I127,I0,I0,I1 +3BDB10:lH3BDB78|H3BDB84 +3BDB78:t2:AB:server_name,H3BDBD4 +3BDBD4:lI108|H3BDC24 +3BDC24:lI111|H3BDC88 +3BDC88:lI99|H3BDCF0 +3BDCF0:lI97|H3BDD70 +3BDD70:lI108|H3BDDF8 +3BDDF8:lI104|H3BDE90 +3BDE90:lI111|H3BDF40 +3BDF40:lI115|H3BDFFC +3BDFFC:lI116|N +3BDB84:lH3BDBDC|H3BDBE8 +3BDBDC:t2:AE:max_header_siz,I1024 +3BDBE8:lH3BDC2C|H3BDC38 +3BDC2C:t2:A11:max_header_action,A8:reply414 +3BDC38:lH3BDC90|H3BDC9C +3BDC90:t2:A8:com_type,A7:ip_comm +3BDC9C:lH3BDCF8|H3BDD04 +3BDCF8:t2:A7:modules,H3BDD78 +3BDD78:lA9:mod_alias|H3BDE00 +3BDE00:lA8:mod_auth|H3BDE98 +3BDE98:lA7:mod_esi|H3BDF48 +3BDF48:lAB:mod_actions|H3BE004 +3BE004:lA7:mod_cgi|H3BE0D0 +3BE0D0:lAB:mod_include|H3BE1A4 +3BE1A4:lA7:mod_dir|H3BE288 +3BE288:lA7:mod_get|H3BE378 +3BE378:lA8:mod_head|H3BE47C +3BE47C:lA7:mod_log|H3BE580 +3BE580:lAC:mod_disk_log|N +3BDD04:lH3BDD80|H3BDD8C +3BDD80:t2:AF:directory_index,H3BDE08 +3BDE08:lH3BDEA0|N +3BDEA0:lI105|H3BDF50 +3BDF50:lI110|H3BE00C +3BE00C:lI100|H3BE0D8 +3BE0D8:lI101|H3BE1AC +3BE1AC:lI120|H3BE290 +3BE290:lI46|H3BE380 +3BE380:lI104|H3BE484 +3BE484:lI116|H3BE588 +3BE588:lI109|H3BE68C +3BE68C:lI108|N +3BDD8C:lH3BDE10|H3BDE1C +3BDE10:t2:AC:default_type,H3BDEA8 +3BDEA8:lI116|H3BDF58 +3BDF58:lI101|H3BE014 +3BE014:lI120|H3BE0E0 +3BE0E0:lI116|H3BE1B4 +3BE1B4:lI47|H3BE298 +3BE298:lI112|H3BE388 +3BE388:lI108|H3BE48C +3BE48C:lI97|H3BE590 +3BE590:lI105|H3BE694 +3BE694:lI110|N +3BDE1C:lH3BDEB0|H3BDEBC +3BDEB0:t2:A10:erl_script_alias,H3BDF60 +3BDF60:t2:H3BE01C,H3BE024 +3BE024:lH3BE0F0|N +3BE0F0:lI119|H3BE1C4 +3BE1C4:lI101|H3BE2A8 +3BE2A8:lI98|H3BE398 +3BE398:lI116|H3BE49C +3BE49C:lI111|H3BE5A0 +3BE5A0:lI111|H3BE6A4 +3BE6A4:lI108|N +3BE01C:lI47|H3BE0E8 +3BE0E8:lI119|H3BE1BC +3BE1BC:lI101|H3BE2A0 +3BE2A0:lI98|H3BE390 +3BE390:lI116|H3BE494 +3BE494:lI111|H3BE598 +3BE598:lI111|H3BE69C +3BE69C:lI108|N +3BDEBC:lH3BDF6C|H3BDF78 +3BDF6C:t2:A5:alias,H3BE02C +3BE02C:t2:H3BE0F8,H3BE100 +3BE100:lI47|H3BE1D4 +3BE1D4:lI99|H3BE2B8 +3BE2B8:lI108|H3BE3A8 +3BE3A8:lI101|H3BE4AC +3BE4AC:lI97|H3BE5B0 +3BE5B0:lI114|H3BE6B4 +3BE6B4:lI99|H3BE7A8 +3BE7A8:lI97|H3BE894 +3BE894:lI115|H3BE980 +3BE980:lI101|H3BEA74 +3BEA74:lI47|H3BEB68 +3BEB68:lI111|H3BEC54 +3BEC54:lI116|H3BED40 +3BED40:lI112|H3BEE2C +3BEE2C:lI47|H3BEF00 +3BEF00:lI101|H3BEFD4 +3BEFD4:lI114|H3BF0A0 +3BF0A0:lI116|H3BF174 +3BF174:lI115|H3BF238 +3BF238:lI47|H3BF2FC +3BF2FC:lI108|H3BF3A8 +3BF3A8:lI105|H3BF45C +3BF45C:lI98|H3BF518 +3BF518:lI47|H3BF5DC +3BF5DC:lI111|H3BF6B0 +3BF6B0:lI98|H3BF784 +3BF784:lI115|H3BF858 +3BF858:lI101|H3BF93C +3BF93C:lI114|H3BFA18 +3BFA18:lI118|H3BFAF4 +3BFAF4:lI101|H3BFBD0 +3BFBD0:lI114|H3BFC9C +3BFC9C:lI47|H3BFD60 +3BFD60:lI112|H3BFE2C +3BFE2C:lI114|H3BFEE0 +3BFEE0:lI105|H3BFF94 +3BFF94:lI118|H3C0040 +3C0040:lI47|H3C00EC +3C00EC:lI99|H3C0198 +3C0198:lI114|H3C024C +3C024C:lI97|H3C0308 +3C0308:lI115|H3C03BC +3C03BC:lI104|H3C0458 +3C0458:lI100|H3C04F4 +3C04F4:lI117|H3C0590 +3C0590:lI109|H3C0634 +3C0634:lI112|H3C06E0 +3C06E0:lI95|H3C078C +3C078C:lI118|H3C0830 +3C0830:lI105|H3C08BC +3C08BC:lI101|H3C0950 +3C0950:lI119|H3C09E4 +3C09E4:lI101|H3C0A80 +3C0A80:lI114|N +3BE0F8:lI47|H3BE1CC +3BE1CC:lI99|H3BE2B0 +3BE2B0:lI114|H3BE3A0 +3BE3A0:lI97|H3BE4A4 +3BE4A4:lI115|H3BE5A8 +3BE5A8:lI104|H3BE6AC +3BE6AC:lI100|H3BE7A0 +3BE7A0:lI117|H3BE88C +3BE88C:lI109|H3BE978 +3BE978:lI112|H3BEA6C +3BEA6C:lI95|H3BEB60 +3BEB60:lI118|H3BEC4C +3BEC4C:lI105|H3BED38 +3BED38:lI101|H3BEE24 +3BEE24:lI119|H3BEEF8 +3BEEF8:lI101|H3BEFCC +3BEFCC:lI114|N +3BDF78:lH3BE038|H3BE044 +3BE038:t2:A5:alias,H3BE108 +3BE108:t2:H3BE1DC,H3BE1E4 +3BE1E4:lI47|H3BE2C8 +3BE2C8:lI99|H3BE3B8 +3BE3B8:lI108|H3BE4BC +3BE4BC:lI101|H3BE5C0 +3BE5C0:lI97|H3BE6C4 +3BE6C4:lI114|H3BE7B8 +3BE7B8:lI99|H3BE8A4 +3BE8A4:lI97|H3BE990 +3BE990:lI115|H3BEA84 +3BEA84:lI101|H3BEB78 +3BEB78:lI47|H3BEC64 +3BEC64:lI111|H3BED50 +3BED50:lI116|H3BEE3C +3BEE3C:lI112|H3BEF10 +3BEF10:lI47|H3BEFE4 +3BEFE4:lI101|H3BF0B0 +3BF0B0:lI114|H3BF184 +3BF184:lI116|H3BF248 +3BF248:lI115|H3BF304 +3BF304:lI47|H3BF3B0 +3BF3B0:lI101|H3BF464 +3BF464:lI114|H3BF520 +3BF520:lI116|H3BF5E4 +3BF5E4:lI115|H3BF6B8 +3BF6B8:lI47|H3BF78C +3BF78C:lI100|H3BF860 +3BF860:lI111|H3BF944 +3BF944:lI99|H3BFA20 +3BFA20:lI47|H3BFAFC +3BFAFC:lI104|H3BFBD8 +3BFBD8:lI116|H3BFCA4 +3BFCA4:lI109|H3BFD68 +3BFD68:lI108|N +3BE1DC:lI47|H3BE2C0 +3BE2C0:lI99|H3BE3B0 +3BE3B0:lI114|H3BE4B4 +3BE4B4:lI97|H3BE5B8 +3BE5B8:lI115|H3BE6BC +3BE6BC:lI104|H3BE7B0 +3BE7B0:lI100|H3BE89C +3BE89C:lI117|H3BE988 +3BE988:lI109|H3BEA7C +3BEA7C:lI112|H3BEB70 +3BEB70:lI95|H3BEC5C +3BEC5C:lI101|H3BED48 +3BED48:lI114|H3BEE34 +3BEE34:lI116|H3BEF08 +3BEF08:lI115|H3BEFDC +3BEFDC:lI95|H3BF0A8 +3BF0A8:lI100|H3BF17C +3BF17C:lI111|H3BF240 +3BF240:lI99|N +3BE044:lH3BE114|H3BE120 +3BE114:t2:A5:alias,H3BE1EC +3BE1EC:t2:H3BE2D0,H3BE2D8 +3BE2D8:lI47|H3BE3C8 +3BE3C8:lI99|H3BE4CC +3BE4CC:lI108|H3BE5D0 +3BE5D0:lI101|H3BE6D4 +3BE6D4:lI97|H3BE7C8 +3BE7C8:lI114|H3BE8B4 +3BE8B4:lI99|H3BE9A0 +3BE9A0:lI97|H3BEA94 +3BEA94:lI115|H3BEB88 +3BEB88:lI101|H3BEC74 +3BEC74:lI47|H3BED60 +3BED60:lI111|H3BEE4C +3BEE4C:lI116|H3BEF20 +3BEF20:lI112|H3BEFEC +3BEFEC:lI47|H3BF0B8 +3BF0B8:lI101|H3BF18C +3BF18C:lI114|H3BF250 +3BF250:lI116|H3BF30C +3BF30C:lI115|H3BF3B8 +3BF3B8:lI47|H3BF46C +3BF46C:lI108|H3BF528 +3BF528:lI105|H3BF5EC +3BF5EC:lI98|H3BF6C0 +3BF6C0:lI47|H3BF794 +3BF794:lI111|H3BF868 +3BF868:lI98|H3BF94C +3BF94C:lI115|H3BFA28 +3BFA28:lI101|H3BFB04 +3BFB04:lI114|H3BFBE0 +3BFBE0:lI118|H3BFCAC +3BFCAC:lI101|H3BFD70 +3BFD70:lI114|H3BFE34 +3BFE34:lI47|H3BFEE8 +3BFEE8:lI100|H3BFF9C +3BFF9C:lI111|H3C0048 +3C0048:lI99|H3C00F4 +3C00F4:lI47|H3C01A0 +3C01A0:lI104|H3C0254 +3C0254:lI116|H3C0310 +3C0310:lI109|H3C03C4 +3C03C4:lI108|N +3BE2D0:lI47|H3BE3C0 +3BE3C0:lI99|H3BE4C4 +3BE4C4:lI114|H3BE5C8 +3BE5C8:lI97|H3BE6CC +3BE6CC:lI115|H3BE7C0 +3BE7C0:lI104|H3BE8AC +3BE8AC:lI100|H3BE998 +3BE998:lI117|H3BEA8C +3BEA8C:lI109|H3BEB80 +3BEB80:lI112|H3BEC6C +3BEC6C:lI95|H3BED58 +3BED58:lI100|H3BEE44 +3BEE44:lI111|H3BEF18 +3BEF18:lI99|N +3BE120:lH3BE1F8|N +3BE1F8:t2:A10:erl_script_alias,H3BE2E0 +3BE2E0:t2:H3BE3D0,H3BE3D8 +3BE3D8:lH3BE4DC|N +3BE4DC:lI99|H3BE5E0 +3BE5E0:lI114|H3BE6E4 +3BE6E4:lI97|H3BE7D8 +3BE7D8:lI115|H3BE8C4 +3BE8C4:lI104|H3BE9B0 +3BE9B0:lI100|H3BEAA4 +3BEAA4:lI117|H3BEB90 +3BEB90:lI109|H3BEC7C +3BEC7C:lI112|H3BED68 +3BED68:lI95|H3BEE54 +3BEE54:lI118|H3BEF28 +3BEF28:lI105|H3BEFF4 +3BEFF4:lI101|H3BF0C0 +3BF0C0:lI119|H3BF194 +3BF194:lI101|H3BF258 +3BF258:lI114|N +3BE3D0:lI47|H3BE4D4 +3BE4D4:lI99|H3BE5D8 +3BE5D8:lI100|H3BE6DC +3BE6DC:lI118|H3BE7D0 +3BE7D0:lI95|H3BE8BC +3BE8BC:lI101|H3BE9A8 +3BE9A8:lI114|H3BEA9C +3BEA9C:lI108|N +3BDE2C:lH3BDA9C|H3BDECC +3BDA9C:t4:I127,I0,I0,I1 +3BDECC:lI8888|H3BDF88 +3BDF88:lN|N +3BDD1C:lN|N +3BDA50:t2:AD:$initial_call,H3BDAB8 +3BDAB8:t3:A3:gen,A7:init_it,H3BDAB0 +3BDA5C:t2:A9:verbosity,A7:silence +3BDAC8:t2:AE:auth_verbosity,A7:silence +3BDB28:t2:A12:security_verbosity,A7:silence +3BDB9C:t2:A12:acceptor_verbosity,A7:silence +3BDC00:t2:AA:$ancestors,H3BDC5C +3BDC5C:lA1A:httpd_sup__127_0_0_1__8888|H3BDCB4 +3BDCB4:lA8:web_tool|H3BDD24 +3BDD24:lP<0.27.0>|N +3BDADC:t2:A19:request_handler_verbosity,A7:silence +3BDB3C:t2:A5:sname,A3:man +=proc_dictionary:<0.47.0> +H36E688 +H36E694 +H36E6A0 +H36E6AC +=proc_stack:<0.47.0> +36c520:SReturn addr 0x362C9C (inet_tcp:accept/2 + 20) +y0:I5 +y1:p<0.161> +y2:p<0.141> +36c530:SReturn addr 0x500C5C (httpd_socket:accept/3 + 280) +y0:N +36c538:SReturn addr 0x502BFC (httpd_acceptor:acceptor/4 + 164) +y0:N +36c540:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:SCatch 0x502BFC (httpd_acceptor:acceptor/4 + 164) +y1:P<0.46.0> +y2:A7:ip_comm +y3:p<0.141> +y4:A1B:httpd_conf__127_0_0_1__8888 +36c558:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:AE:httpd_acceptor +y2:A8:acceptor +y3:H36E6C8 +=proc_heap:<0.47.0> +36E6C8:lP<0.44.0>|H36E724 +36E724:lP<0.46.0>|H36E748 +36E748:lA7:ip_comm|H36E760 +36E760:lH36E6D0|H36E778 +36E6D0:t4:I127,I0,I0,I1 +36E778:lI8888|H36E788 +36E788:lA1B:httpd_conf__127_0_0_1__8888|H36E798 +36E798:lA7:silence|N +36E688:t2:AD:$initial_call,H36E6F0 +36E6F0:t3:AE:httpd_acceptor,A8:acceptor,H36E6C8 +36E694:t2:A9:verbosity,A7:silence +36E6A0:t2:AA:$ancestors,H36E700 +36E700:lA1E:httpd_acc_sup__127_0_0_1__8888|H36E72C +36E72C:lA1A:httpd_sup__127_0_0_1__8888|H36E750 +36E750:lA8:web_tool|H36E768 +36E768:lP<0.27.0>|N +36E6AC:t2:A5:sname,A3:acc +=proc_dictionary:<0.48.0> +H385E48 +H385E54 +=proc_stack:<0.48.0> +3ac1bc:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A10:crashdump_viewer +y3:H3AB280 +y4:A17:crashdump_viewer_server +y5:P<0.41.0> +3ac1d8:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H385E90 +=proc_heap:<0.48.0> +3AB280:t8:A5:state,A9:undefined,A9:undefined,A9:undefined,A5:false,I4,A9:undefined,P<0.56.0> +385E90:lAA:gen_server|H385ED8 +385ED8:lP<0.41.0>|H385F10 +385F10:lP<0.41.0>|H385F58 +385F58:lH385FA8|H385FB4 +385FA8:t2:A5:local,A17:crashdump_viewer_server +385FB4:lA10:crashdump_viewer|H386014 +386014:lN|H38606C +38606C:lN|N +385E48:t2:AD:$initial_call,H385EB0 +385EB0:t3:A3:gen,A7:init_it,H385E90 +385E54:t2:AA:$ancestors,H385EC0 +385EC0:lA6:websup|H385F08 +385F08:lA8:web_tool|H385F50 +385F50:lP<0.27.0>|N +=proc_stack:<0.49.0> +36a114:SReturn addr 0x30174C (io:parse_erl_exprs/3 + 92) +y0:H369E10 +y1:P<0.22.0> +36a120:SReturn addr 0x2E5360 (shell:'-get_command/4-fun-0-'/1 + 20) +y0:N +36a128:SReturn addr 0x156F90 (<terminate process normally>) +=proc_heap:<0.49.0> +369E10:E21:8372000364000D6E6F6E6F6465406E6F686F737400000001330000000000000000 +=atoms +http_cache_control +copy_word +drop_line +copy_line +write_rest_of_line +drop_to_empty_line +read_to_empty_line_reverse +set_pos +read_line_backwards +jumped +jump_to_empty_line_or_eof +get_pos +translate_atoms +translate_fun +translate_funs +translate_loaded_modules2 +translate_loaded_modules_totals +translate_loaded_modules +translate_links +get_all_creations +translate_node_info2 +translate_node_info +translate_dist_info2 +translate_dist_info +get_msg +translate_timers +translate_ets +translate_ets_tables +do_translate_sl_alloc_r7_r8 +translate_sl_alloc_r7_r8 +translate_sl_alloc_line +do_translate_sl_alloc +translate_sl_alloc +translate_memory_and_allocated_area_r9b +translate_allocated_areas +translate_internal_table_line +translate_index_table +translate_hash_table +translate_internal_tables +translate_ports +write_last_calls +write_msg_q_stuff +translate_process +translate_processes +erts_vsn +translate_summary +'Send' +erl_crash_dump +internal_tables +mods diff --git a/lib/observer/test/crashdump_viewer_SUITE_data/r10b_dump.trunc.noatoms b/lib/observer/test/crashdump_viewer_SUITE_data/r10b_dump.trunc.noatoms new file mode 100644 index 0000000000..9f20ef3e44 --- /dev/null +++ b/lib/observer/test/crashdump_viewer_SUITE_data/r10b_dump.trunc.noatoms @@ -0,0 +1,13035 @@ +=erl_crash_dump:0.1 +Wed Apr 21 13:22:44 2004 +Slogan: eheap_alloc: Cannot allocate 785672 bytes of memory (of type "heap"). +System version: Erlang (BEAM) emulator version 5.4 [source] [hipe] [threads:0] +Compiled: Thu Dec 18 14:07:45 2003 +Atoms: 5614 +=memory +total: 653336887 +processes: 1768396 +processes_used: 1765460 +system: 651568491 +atom: 244837 +atom_used: 237116 +binary: 648618369 +code: 2158413 +ets: 225620 +=hash_table:atom_tab +size: 4813 +used: 3304 +objs: 5614 +depth: 7 +=index_table:atom_tab +size: 5700 +limit: 1048576 +used: 5614 +rate: 100 +=hash_table:module_code +size: 97 +used: 69 +objs: 107 +depth: 5 +=index_table:module_code +size: 110 +limit: 65536 +used: 107 +rate: 10 +=hash_table:export_list +size: 2411 +used: 1674 +objs: 2843 +depth: 6 +=index_table:export_list +size: 2900 +limit: 65536 +used: 2843 +rate: 100 +=hash_table:process_reg +size: 47 +used: 16 +objs: 23 +depth: 3 +=hash_table:fun_table +size: 397 +used: 261 +objs: 400 +depth: 4 +=hash_table:node_table +size: 11 +used: 1 +objs: 1 +depth: 1 +=hash_table:dist_table +size: 11 +used: 1 +objs: 1 +depth: 1 +=allocated_areas +processes: 1765460 1768396 +ets: 225620 +sys_misc: 24634 +static: 295033 +atom_space: 65544 57967 +binary: 648618369 +atom_table: 42141 +module_table: 920 +export_table: 21336 +register_table: 252 +fun_table: 1650 +module_refs: 1024 +loaded_code: 1968915 +dist_table: 159 +node_table: 131 +bits_bufs_size: 19 +bif_timer: 13392 +link_lh: 0 +dist_buf: 0 +proc: 15080 13576 +atom_entry: 137152 137008 +export_entry: 138448 137632 +module_entry: 4872 4352 +reg_proc: 1000 592 +link_nh: 2464 2080 +link_sh: 832 192 +proc_list: 24 24 +fun_entry: 22584 22584 +db_tab: 1632 1632 +=allocator:sys_alloc +option e: true +option m: libc +=allocator:temp_alloc +versions: 0.9 2.1 +option e: true +option sbct: 524288 +option asbcst: 4145152 +option rsbcst: 90 +option rsbcmt: 80 +option mmbcs: 65536 +option mmsbc: 256 +option mmmbc: 10 +option lmbcs: 5242880 +option smbcs: 1048576 +option mbcgs: 10 +option as: af +mbcs blocks: 0 9 9 +mbcs blocks size: 0 35376 35376 +mbcs carriers: 1 1 1 +mbcs mseg carriers: 0 +mbcs sys_alloc carriers: 1 +mbcs carriers size: 65568 65568 65568 +mbcs mseg carriers size: 0 +mbcs sys_alloc carriers size: 65568 +sbcs blocks: 0 0 0 +sbcs blocks size: 0 0 0 +sbcs carriers: 0 0 0 +sbcs mseg carriers: 0 +sbcs sys_alloc carriers: 0 +sbcs carriers size: 0 0 0 +sbcs mseg carriers size: 0 +sbcs sys_alloc carriers size: 0 +temp_alloc calls: 6155 +temp_free calls: 6155 +temp_realloc calls: 29 +mseg_alloc calls: 0 +mseg_dealloc calls: 0 +mseg_realloc calls: 0 +sys_alloc calls: 1 +sys_free calls: 0 +sys_realloc calls: 0 +=allocator:sl_alloc +option e: false +=allocator:std_alloc +option e: false +=allocator:ll_alloc +versions: 0.9 2.1 +option e: true +option sbct: 4294967295 +option asbcst: 0 +option rsbcst: 0 +option rsbcmt: 0 +option mmbcs: 2097152 +option mmsbc: 0 +option mmmbc: 0 +option lmbcs: 5242880 +option smbcs: 1048576 +option mbcgs: 10 +option as: aobf +mbcs blocks: 592 592 592 +mbcs blocks size: 2838520 2863304 2863304 +mbcs carriers: 2 2 2 +mbcs mseg carriers: 0 +mbcs sys_alloc carriers: 2 +mbcs carriers size: 3145760 3145760 3145760 +mbcs mseg carriers size: 0 +mbcs sys_alloc carriers size: 3145760 +sbcs blocks: 0 0 0 +sbcs blocks size: 0 0 0 +sbcs carriers: 0 0 0 +sbcs mseg carriers: 0 +sbcs sys_alloc carriers: 0 +sbcs carriers size: 0 0 0 +sbcs mseg carriers size: 0 +sbcs sys_alloc carriers size: 0 +ll_alloc calls: 592 +ll_free calls: 0 +ll_realloc calls: 235 +mseg_alloc calls: 0 +mseg_dealloc calls: 0 +mseg_realloc calls: 0 +sys_alloc calls: 2 +sys_free calls: 0 +sys_realloc calls: 0 +=allocator:eheap_alloc +versions: 2.1 2.1 +option e: true +option sbct: 524288 +option asbcst: 4145152 +option rsbcst: 50 +option rsbcmt: 80 +option mmbcs: 524288 +option mmsbc: 256 +option mmmbc: 10 +option lmbcs: 5242880 +option smbcs: 1048576 +option mbcgs: 10 +option mbsd: 3 +option as: gf +mbcs blocks: 56 102 102 +mbcs blocks size: 833280 1638920 1638920 +mbcs carriers: 2 3 3 +mbcs mseg carriers: 1 +mbcs sys_alloc carriers: 1 +mbcs carriers size: 1998880 3047456 3047456 +mbcs mseg carriers size: 1474560 +mbcs sys_alloc carriers size: 524320 +sbcs blocks: 0 0 0 +sbcs blocks size: 0 0 0 +sbcs carriers: 0 0 0 +sbcs mseg carriers: 0 +sbcs sys_alloc carriers: 0 +sbcs carriers size: 0 0 0 +sbcs mseg carriers size: 0 +sbcs sys_alloc carriers size: 0 +eheap_alloc calls: 6971 +eheap_free calls: 6914 +eheap_realloc calls: 461 +mseg_alloc calls: 16 +mseg_dealloc calls: 14 +mseg_realloc calls: 0 +sys_alloc calls: 3 +sys_free calls: 0 +sys_realloc calls: 0 +=allocator:binary_alloc +option e: false +=allocator:ets_alloc +option e: false +=allocator:fix_alloc +option e: true +proc: 15080 13576 +atom_entry: 137152 137008 +export_entry: 138448 137632 +module_entry: 4872 4352 +reg_proc: 1000 592 +link_nh: 2464 2080 +link_sh: 832 192 +proc_list: 24 24 +fun_entry: 22584 22584 +db_tab: 1632 1632 +=allocator:mseg_alloc +version: 0.9 +option amcbf: 4194304 +option rmcbf: 20 +option mcs: 5 +option cci: 1000 +cached_segments: 0 +cache_hits: 13 +segments: 2 +segments_watermark: 2 +mseg_alloc calls: 16 +mseg_dealloc calls: 14 +mseg_realloc calls: 0 +mseg_create calls: 4 +mseg_destroy calls: 1 +mseg_clear_cache calls: 6 +mseg_check_cache calls: 2 +=allocator:alloc_util +option mmc: 1024 +option ycs: 1048576 +=allocator:instr +option m: false +option s: false +option t: false +=proc:<0.0.0> +State: Waiting +Name: init +Spawned as: otp_ring0:start/2 +Spawned by: [] +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.5.0>,<0.4.0>,<0.2.0>] +Reductions: 3851 +Stack+heap: 377 +OldHeap: 610 +Heap unused: 53 +OldHeap unused: 610 +Program counter: 0x1f496c (init:loop/1 + 20) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.2.0> +State: Waiting +Name: erl_prim_loader +Spawned as: erlang:apply/2 +Spawned by: <0.1.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.0.0>,#Port<0.2>] +Reductions: 201036 +Stack+heap: 987 +OldHeap: 987 +Heap unused: 923 +OldHeap unused: 987 +Program counter: 0x20cc94 (erl_prim_loader:loop/3 + 52) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.4.0> +State: Waiting +Name: error_logger +Spawned as: proc_lib:init_p/5 +Spawned by: <0.1.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.21.0>,<0.0.0>] +Reductions: 296 +Stack+heap: 6765 +OldHeap: 0 +Heap unused: 851 +OldHeap unused: 0 +Program counter: 0x21f5b8 (gen_event:loop/4 + 40) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.5.0> +State: Waiting +Name: application_controller +Spawned as: proc_lib:init_p/5 +Spawned by: <0.1.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.7.0>,<0.0.0>] +Reductions: 1508 +Stack+heap: 1597 +OldHeap: 0 +Heap unused: 835 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.7.0> +State: Waiting +Spawned as: proc_lib:init_p/5 +Spawned by: <0.6.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.8.0>,<0.5.0>] +Reductions: 23 +Stack+heap: 377 +OldHeap: 0 +Heap unused: 79 +OldHeap unused: 0 +Program counter: 0x248d04 (application_master:main_loop/2 + 28) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.8.0> +State: Waiting +Spawned as: application_master:start_it/4 +Spawned by: <0.7.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.9.0>,<0.7.0>] +Reductions: 91 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 177 +OldHeap unused: 0 +Program counter: 0x24a26c (application_master:loop_it/4 + 40) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.9.0> +State: Waiting +Name: kernel_sup +Spawned as: proc_lib:init_p/5 +Spawned by: <0.8.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.24.0>,<0.23.0>,<0.19.0>,<0.18.0>,<0.17.0>,<0.16.0>,<0.15.0>,<0.14.0>,<0.11.0>,<0.10.0>,<0.8.0>] +Reductions: 7402 +Stack+heap: 610 +OldHeap: 987 +Heap unused: 311 +OldHeap unused: 987 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.10.0> +State: Waiting +Name: rex +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.9.0>] +Reductions: 44 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 144 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.11.0> +State: Waiting +Name: global_name_server +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.13.0>,<0.12.0>,<0.9.0>] +Reductions: 47 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 98 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.12.0> +State: Waiting +Spawned as: global:init_the_locker/1 +Spawned by: <0.11.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.11.0>] +Reductions: 3 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 227 +OldHeap unused: 0 +Program counter: 0x261340 (global:loop_the_locker/2 + 92) +CP: 0x261184 (global:init_the_locker/1 + 112) +arity = 0 +=proc:<0.13.0> +State: Waiting +Spawned as: erlang:apply/2 +Spawned by: <0.11.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.11.0>] +Reductions: 4 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 221 +OldHeap unused: 0 +Program counter: 0x265288 (global:collect_deletions/2 + 76) +CP: 0x2651ac (global:loop_the_deleter/1 + 36) +arity = 0 +=proc:<0.14.0> +State: Waiting +Name: inet_db +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.9.0>] +Reductions: 376 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 30 +OldHeap unused: 233 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.15.0> +State: Waiting +Name: global_group +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.9.0>] +Reductions: 71 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 92 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.16.0> +State: Waiting +Name: file_server_2 +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 1 +Heap fragment data: 119 +Link list: [{from,<0.17.0>,#Ref<0.0.0.22>},#Port<0.4>,<0.9.0>] +Reductions: 83605 +Stack+heap: 4181 +OldHeap: 4181 +Heap unused: 1720 +OldHeap unused: 4181 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.17.0> +State: Waiting +Name: file_server +Spawned as: erlang:apply/2 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [{to,<0.16.0>,#Ref<0.0.0.22>},<0.9.0>] +Reductions: 12 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 207 +OldHeap unused: 0 +Program counter: 0x2a18e8 (old_file_server:relay_loop/3 + 32) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.18.0> +State: Waiting +Name: code_server +Spawned as: erlang:apply/2 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:07 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.9.0>] +Reductions: 108900 +Stack+heap: 6765 +OldHeap: 6765 +Heap unused: 4389 +OldHeap unused: 6765 +Program counter: 0x2a6e64 (code_server:loop/1 + 64) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.19.0> +State: Waiting +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.21.0>,<0.9.0>] +Reductions: 74 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 180 +OldHeap unused: 233 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.20.0> +State: Waiting +Spawned as: user_drv:server/2 +Spawned by: <0.19.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.22.0>,<0.21.0>,#Port<0.72>] +Reductions: 596 +Stack+heap: 233 +OldHeap: 377 +Heap unused: 214 +OldHeap unused: 377 +Program counter: 0x2ca4e0 (user_drv:server_loop/5 + 56) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.21.0> +State: Waiting +Name: user +Spawned as: group:server/2 +Spawned by: <0.20.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.4.0>,<0.19.0>,<0.20.0>] +Reductions: 26 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 202 +OldHeap unused: 0 +Program counter: 0x2cd9d8 (group:server_loop/3 + 32) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.22.0> +State: Waiting +Spawned as: group:server/2 +Spawned by: <0.20.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [{from,<0.49.0>,#Ref<0.0.0.307>},<0.25.0>,<0.20.0>] +Reductions: 1244 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 40 +OldHeap unused: 233 +Program counter: 0x2cf238 (group:get_line1/3 + 1652) +CP: 0x2cf230 (group:get_line1/3 + 1644) +arity = 0 +=proc:<0.23.0> +State: Waiting +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.9.0>] +Reductions: 45 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 63 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.24.0> +State: Waiting +Name: kernel_safe_sup +Spawned as: proc_lib:init_p/5 +Spawned by: <0.9.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.31.0>,<0.9.0>] +Reductions: 133 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 198 +OldHeap unused: 233 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.25.0> +State: Waiting +Spawned as: erlang:apply/2 +Spawned by: <0.22.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.49.0>,<0.27.0>,<0.22.0>] +Reductions: 161 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 169 +OldHeap unused: 0 +Program counter: 0x2e0d00 (shell:get_command1/4 + 40) +CP: 0x2e06fc (shell:server_loop/6 + 140) +arity = 0 +=proc:<0.27.0> +State: Waiting +Spawned as: erlang:apply/2 +Spawned by: <0.25.0> +Started: Wed Apr 21 13:22:08 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.25.0>] +Reductions: 506 +Stack+heap: 4181 +OldHeap: 0 +Heap unused: 1131 +OldHeap unused: 0 +Program counter: 0x2e2bbc (shell:eval_loop/2 + 32) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.31.0> +State: Waiting +Name: inet_gethost_native_sup +Spawned as: proc_lib:init_p/5 +Spawned by: <0.24.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.32.0>,<0.24.0>] +Reductions: 49 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 87 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.32.0> +State: Waiting +Name: inet_gethost_native +Spawned as: inet_gethost_native:server_init/2 +Spawned by: <0.31.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 1 +Heap fragment data: 118 +Link list: [#Port<0.105>,<0.31.0>] +Reductions: 65 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 13 +OldHeap unused: 0 +Program counter: 0x4ad840 (inet_gethost_native:main_loop/1 + 20) +CP: 0x156f90 (<terminate process normally>) +arity = 0 +=proc:<0.33.0> +State: Waiting +Name: web_tool +Spawned as: proc_lib:init_p/5 +Spawned by: <0.27.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.41.0>] +Reductions: 131773 +Stack+heap: 6765 +OldHeap: 6765 +Heap unused: 2941 +OldHeap unused: 6765 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.41.0> +State: Waiting +Name: websup +Spawned as: proc_lib:init_p/5 +Spawned by: <0.33.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.48.0>,<0.33.0>] +Reductions: 118 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 205 +OldHeap unused: 233 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.43.0> +State: Waiting +Name: httpd_sup__127_0_0_1__8888 +Spawned as: proc_lib:init_p/5 +Spawned by: <0.33.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.46.0>,<0.45.0>,<0.44.0>] +Reductions: 1220 +Stack+heap: 6765 +OldHeap: 0 +Heap unused: 277 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.44.0> +State: Waiting +Name: httpd_acc_sup__127_0_0_1__8888 +Spawned as: proc_lib:init_p/5 +Spawned by: <0.43.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.47.0>,<0.43.0>] +Reductions: 147 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 77 +OldHeap unused: 233 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.45.0> +State: Waiting +Name: httpd_misc_sup__127_0_0_1__8888 +Spawned as: proc_lib:init_p/5 +Spawned by: <0.43.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.43.0>] +Reductions: 52 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 80 +OldHeap unused: 0 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.46.0> +State: Waiting +Name: httpd__127_0_0_1__8888 +Spawned as: proc_lib:init_p/5 +Spawned by: <0.43.0> +Started: Wed Apr 21 13:22:17 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.43.0>] +Reductions: 2905 +Stack+heap: 6765 +OldHeap: 10946 +Heap unused: 138 +OldHeap unused: 10946 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.47.0> +State: Waiting +Spawned as: proc_lib:init_p/5 +Spawned by: <0.44.0> +Started: Wed Apr 21 13:22:18 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [#Port<0.161>,#Port<0.141>,<0.44.0>] +Reductions: 874 +Stack+heap: 233 +OldHeap: 233 +Heap unused: 190 +OldHeap unused: 233 +Program counter: 0x1fe798 (prim_inet:accept0/2 + 96) +CP: 0x1feb04 (prim_inet:async_accept/2 + 380) +arity = 0 +=proc:<0.48.0> +State: Waiting +Name: crashdump_viewer_server +Spawned as: proc_lib:init_p/5 +Spawned by: <0.41.0> +Started: Wed Apr 21 13:22:18 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [<0.56.0>,<0.41.0>] +Reductions: 1913 +Stack+heap: 987 +OldHeap: 987 +Heap unused: 524 +OldHeap unused: 987 +Program counter: 0x239d50 (gen_server:loop/6 + 52) +CP: 0x225860 (proc_lib:init_p/5 + 164) +arity = 0 +=proc:<0.49.0> +State: Waiting +Spawned as: erlang:apply/2 +Spawned by: <0.25.0> +Started: Wed Apr 21 13:22:18 2004 +Message queue length: 0 +Number of heap fragments: 0 +Heap fragment data: 0 +Link list: [{to,<0.22.0>,#Ref<0.0.0.307>},<0.25.0>] +Reductions: 15 +Stack+heap: 233 +OldHeap: 0 +Heap unused: 190 +OldHeap unused: 0 +Program counter: 0x301d58 (io:wait_io_mon_reply/2 + 28) +CP: 0x30174c (io:parse_erl_exprs/3 + 92) +arity = 0 +=proc:<0.56.0> +State: Garbing +Spawned as: erlang:apply/2 +Last scheduled in for: erlang:garbage_collect/0 +Spawned by: <0.48.0> +Started: Wed Apr 21 13:22:27 2004 +Message queue length: 0 +Number of heap fragments: 1 +Heap fragment data: 121 +Link list: [#Port<0.158>,#Port<0.157>,<0.48.0>] +Reductions: 2420470 +Stack+heap: 121393 +OldHeap: 0 +Heap unused: 22172 +OldHeap unused: 0 +New heap start: FE5768E0 +New heap top: FE5D7734 +Stack top: FE5ED130 +Stack end: FE5ED1A4 +Old heap start: 0 +Old heap top: 0 +Old heap end: 0 +Program counter: 0x1a4980 (unknown function) +CP: 0x20710c (prim_file:read/2 + 436) +=port:#Port<0.1> +Slot: 1 +Connected: #Port<0.0> +Port controls linked-in driver: async +=port:#Port<0.2> +Slot: 2 +Connected: <0.2.0> +Links: <0.2.0> +Port controls linked-in driver: efile +=port:#Port<0.4> +Slot: 4 +Connected: <0.16.0> +Links: <0.16.0> +Port controls linked-in driver: efile +=port:#Port<0.72> +Slot: 72 +Connected: <0.20.0> +Links: <0.20.0> +Port controls linked-in driver: tty_sl -c -e +=port:#Port<0.105> +Slot: 105 +Connected: <0.32.0> +Links: <0.32.0> +Port controls external process: inet_gethost 4 +=port:#Port<0.141> +Slot: 141 +Connected: <0.47.0> +Links: <0.47.0> +Port controls linked-in driver: tcp_inet +=port:#Port<0.157> +Slot: 157 +Connected: <0.56.0> +Links: <0.56.0> +Port controls linked-in driver: efile +=port:#Port<0.158> +Slot: 158 +Connected: <0.56.0> +Links: <0.56.0> +Port controls linked-in driver: efile +=port:#Port<0.161> +Slot: 161 +Connected: <0.47.0> +Links: <0.47.0> +Port controls linked-in driver: tcp_inet +=ets:<0.18.0> +Slot: 9 +Table: 9 +Name: code +Buckets: 256 +Objects: 289 +Words: 14108 +=ets:<0.18.0> +Slot: 10 +Table: 10 +Name: code_names +Buckets: 256 +Objects: 47 +Words: 4334 +=ets:<0.32.0> +Slot: 11 +Table: 11 +Name: ign_requests +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.32.0> +Slot: 12 +Table: 12 +Name: ign_req_index +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.33.0> +Slot: 13 +Table: 13 +Name: app_data +Buckets: 256 +Objects: 7 +Words: 952 +=ets:<0.46.0> +Slot: 15 +Table: 15 +Name: httpd_mime__127_0_0_1__8888 +Buckets: 256 +Objects: 105 +Words: 5742 +=ets:<0.11.0> +Slot: 84 +Table: global_names +Name: global_names +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.11.0> +Slot: 95 +Table: global_locks +Name: global_locks +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.11.0> +Slot: 96 +Table: global_names_ext +Name: global_names_ext +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.14.0> +Slot: 316 +Table: inet_cache +Name: inet_cache +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.48.0> +Slot: 340 +Table: cdv_menu_table +Name: cdv_menu_table +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.48.0> +Slot: 341 +Table: cdv_dump_index_table +Name: cdv_dump_index_table +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.48.0> +Slot: 342 +Table: cdv_decode_heap_table +Name: cdv_decode_heap_table +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.16.0> +Slot: 780 +Table: file_io_servers +Name: file_io_servers +Buckets: 256 +Objects: 0 +Words: 277 +=ets:<0.46.0> +Slot: 984 +Table: httpd_conf__127_0_0_1__8888 +Name: httpd_conf__127_0_0_1__8888 +Buckets: 256 +Objects: 17 +Words: 1176 +=ets:<0.14.0> +Slot: 1342 +Table: inet_hosts +Name: inet_hosts +Buckets: 256 +Objects: 4 +Words: 421 +=ets:<0.14.0> +Slot: 1362 +Table: inet_db +Name: inet_db +Buckets: 256 +Objects: 20 +Words: 671 +=ets:<0.5.0> +Slot: 1655 +Table: ac_tab +Name: ac_tab +Buckets: 256 +Objects: 6 +Words: 843 +=timer:<0.14.0> +Message: refresh_timeout +Time left: 3565692 ms +=node:'nonode@nohost' +=no_distribution +=loaded_modules +Current code: 1968915 +Old code: 0 +=mod:otp_ring0 +Current size: 489 +=mod:init +Current size: 30110 +=mod:prim_inet +Current size: 35532 +=mod:prim_file +Current size: 24965 +=mod:erl_prim_loader +Current size: 19607 +=mod:erlang +Current size: 11137 +=mod:error_handler +Current size: 2389 +Current attributes: 836C00000001680264000376736E6C000000016E100030769A34345F26EF6D3433254FF2AE576A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613161216802640006736F757263656B00342F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6572726F725F68616E646C65722E65726C6A +=mod:heart +Current size: 6687 +Current attributes: 836C00000001680264000376736E6C000000016E10003094F7BECF345494DDBB4D7186E694186A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261086802640006736F757263656B002C2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F68656172742E65726C6A +=mod:error_logger +Current size: 7051 +Current attributes: 836C00000001680264000376736E6C000000016E10004E3347F841DEAE2EB6A74389E6E127146A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613161246802640006736F757263656B00332F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6572726F725F6C6F676765722E65726C6A +=mod:gen_event +Current size: 18288 +Current attributes: 836C00000001680264000376736E6C000000016E1000336F22DF1EA75E0EA4AE65D3B8C34F946A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61346802640006736F757263656B00302F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F67656E5F6576656E742E65726C6A +=mod:gen +Current size: 7129 +Current attributes: 836C00000001680264000376736E6C000000016E10007BE6AEB66EF48D8B33323C89C9936A526A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61316802640006736F757263656B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F67656E2E65726C6A +=mod:proc_lib +Current size: 11658 +Current attributes: 836C00000001680264000376736E6C000000016E10005C589A8C9BD2E1F2E895E765CAE983406A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E612D6802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F70726F635F6C69622E65726C6A +=mod:application_controller +Current size: 55249 +Current attributes: 836C00000002680264000376736E6C000000016E10003372E1AB0410565065FA086086A721316A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613061246802640006736F757263656B003D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6170706C69636174696F6E5F636F6E74726F6C6C65722E65726C6A +=mod:gen_server +Current size: 18728 +Current attributes: 836C00000001680264000376736E6C000000016E10004C5E93533036DAC7698FC4112F59CF236A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61396802640006736F757263656B00312F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F67656E5F7365727665722E65726C6A +=mod:sys +Current size: 11589 +Current attributes: 836C00000001680264000376736E6C000000016E1000E12B0E8267551204BD5924BAB9629ADF6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612F61176802640006736F757263656B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F7379732E65726C6A +=mod:lists +Current size: 18638 +Current attributes: 836C00000002680264000376736E6C000000016E10001E95B32C30E4CDAF0BDD1ABA58CBB5F36A680264000A646570726563617465646C0000000B68026400066B65796D617061046802640003616C6C61036802640003616E79610368026400036D617061036802640007666C61746D617061036802640005666F6C646C61046802640005666F6C64726104680264000666696C746572610368026400086D6170666F6C646C610468026400086D6170666F6C647261046802640007666F726561636861036A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61116802640006736F757263656B002C2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6C697374732E65726C6A +=mod:application +Current size: 2666 +Current attributes: 836C00000001680264000376736E6C000000016E1000C0C5A7B67B306300FEFF9D91AA50ECB36A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6130611F6802640006736F757263656B00322F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6170706C69636174696F6E2E65726C6A +=mod:application_master +Current size: 10912 +Current attributes: 836C00000001680264000376736E6C000000016E1000360420F5CEB80AD7DD51B3A8A0E2AFA26A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613061266802640006736F757263656B00392F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6170706C69636174696F6E5F6D61737465722E65726C6A +=mod:kernel +Current size: 7639 +Current attributes: 836C00000002680264000376736E6C000000016E10004D418ACCB0F948D4D3CA6B9A81B462746A68026400096265686176696F75726C0000000164000A73757065727669736F726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261336802640006736F757263656B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6B65726E656C2E65726C6A +=mod:supervisor +Current size: 24469 +Current attributes: 836C00000002680264000376736E6C000000016E1000979F65727577135484BE0892A35087CC6A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612F61126802640006736F757263656B00312F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F73757065727669736F722E65726C6A +=mod:rpc +Current size: 14539 +Current attributes: 836C00000002680264000376736E6C000000016E10008C5D6242D36B3201E3B11E82D5E1581E6A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6133610F6802640006736F757263656B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F7270632E65726C6A +=mod:gb_trees +Current size: 8274 +Current attributes: 836C00000001680264000376736E6C000000016E1000094BEFDE7B866EF2CB6FCD895AC2EE056A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D612B6802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F67625F74726565732E65726C6A +=mod:global +Current size: 40753 +Current attributes: 836C00000002680264000376736E6C000000016E10001D02C89BDE6CB2052F099894683C14CA6A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613161386802640006736F757263656B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F676C6F62616C2E65726C6A +=mod:inet_db +Current size: 34555 +Current attributes: 836C00000001680264000376736E6C000000016E1000C1CF6A6F2E83D4EBC23D2CCECBF376226A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6132611A6802640006736F757263656B002E2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F64622E65726C6A +=mod:inet_config +Current size: 13575 +Current attributes: 836C00000001680264000376736E6C000000016E1000650F6571C03BC9C16BB7973A747565066A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261166802640006736F757263656B00322F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F636F6E6669672E65726C6A +=mod:os +Current size: 5997 +Current attributes: 836C00000001680264000376736E6C000000016E100017144CD766A604A9DFBA0B58C8FCA78B6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613361056802640006736F757263656B00292F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6F732E65726C6A +=mod:inet_udp +Current size: 2451 +Current attributes: 836C00000001680264000376736E6C000000016E1000ACB163E87A687A6683B50B331C6E289B6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261306802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F7564702E65726C6A +=mod:inet +Current size: 28288 +Current attributes: 836C00000001680264000376736E6C000000016E10009B9AD400F0BAF6AAF17A4788A4EFF11E6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6132610C6802640006736F757263656B002B2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65742E65726C6A +=mod:inet_parse +Current size: 21928 +Current attributes: 836C00000001680264000376736E6C000000016E1000E0E65454C096847749930EDC1C53C80B6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261266802640006736F757263656B00312F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F70617273652E65726C6A +=mod:filename +Current size: 17411 +Current attributes: 836C00000001680264000376736E6C000000016E100068085214F459D51A3E08819BF8D7698A6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61296802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F66696C656E616D652E65726C6A +=mod:inet_hosts +Current size: 3745 +Current attributes: 836C00000001680264000376736E6C000000016E1000E7430304E86230057150DEE5D279881F6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261226802640006736F757263656B00312F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F686F7374732E65726C6A +=mod:erl_distribution +Current size: 2512 +Current attributes: 836C00000002680264000376736E6C000000016E1000CDE49D63ACA767E0D49679657E99D2046A68026400096265686176696F75726C0000000164000A73757065727669736F726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613161186802640006736F757263656B00372F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F65726C5F646973747269627574696F6E2E65726C6A +=mod:global_group +Current size: 30960 +Current attributes: 836C00000002680264000376736E6C000000016E10008ECE759E5920988CA3ACFF34B32F86736A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6131613B6802640006736F757263656B00332F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F676C6F62616C5F67726F75702E65726C6A +=mod:net_kernel +Current size: 37648 +Current attributes: 836C00000002680264000376736E6C000000016E1000967CE7DE41F9B39906CCCF3225E6E5286A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613361026802640006736F757263656B00312F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6E65745F6B65726E656C2E65726C6A +=mod:file_server +Current size: 8372 +Current attributes: 836C00000002680264000376736E6C000000016E1000EF90906EC6204204AC0A77C4A25B65236A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6131612D6802640006736F757263656B00322F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F66696C655F7365727665722E65726C6A +=mod:old_file_server +Current size: 3074 +Current attributes: 836C00000001680264000376736E6C000000016E1000C802085DD76D4EFBA6A8F528FECB94B36A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6131612F6802640006736F757263656B00362F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6F6C645F66696C655F7365727665722E65726C6A +=mod:code +Current size: 7419 +Current attributes: 836C00000001680264000376736E6C000000016E1000AE618E3041C8E3807A3719CD5140DF5E6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6130612E6802640006736F757263656B002B2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F636F64652E65726C6A +=mod:code_server +Current size: 30811 +Current attributes: 836C00000001680264000376736E6C000000016E0F00BFB96248C2CA8601B4CB7F543F52E26A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613061346802640006736F757263656B00322F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F636F64655F7365727665722E65726C6A +=mod:code_aux +Current size: 1736 +Current attributes: 836C00000001680264000376736E6C000000016E10007A90DB53FCCECD52504F20E7A3B6BAE26A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613061316802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F636F64655F6175782E65726C6A +=mod:packages +Current size: 3119 +Current attributes: 836C00000001680264000376736E6C000000016E1000044DC8EEB65F178AE23EF2465E1954496A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613361076802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F7061636B616765732E65726C6A +=mod:hipe_unified_loader +Current size: 37330 +Current attributes: 836C00000001680264000376736E6C000000016E1000DABD57945702E56F4B3AA7B7B19C1D166A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613361326802640006736F757263656B003A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F686970655F756E69666965645F6C6F616465722E65726C6A +=mod:hipe_sparc_loader +Current size: 1821 +Current attributes: 836C00000001680264000376736E6C000000016E1000582BC55E9FADFF879C2C45D25A6CB7E56A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C7564656802640001696B00322F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F2E2E2F686970652F6D61696E6802640001696B00312F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F2E2E2F686970652F72746C6802640001696B00332F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F2E2E2F686970652F737061726364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6133612B6802640006736F757263656B00382F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F686970655F73706172635F6C6F616465722E65726C6A +=mod:ets +Current size: 16577 +Current attributes: 836C00000002680264000376736E6C000000016E100033D982AC91129E5FC35E0AC3337A4EB56A680264000A646570726563617465646C0000000168026400086669787461626C6561026A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D611C6802640006736F757263656B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6574732E65726C6A +=mod:lists_sort +Current size: 38692 +Current attributes: 836C00000001680264000376736E6C000000016E1000E17EC92FA9AA3199DD71701C215044616A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000B68026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736802640006696E6C696E656C0000000468026400096D65726765335F3132610768026400096D65726765335F32316107680264000A726D65726765335F31326107680264000A726D65726765335F323161076A6802640006696E6C696E656C00000004680264000A756D65726765335F31326108680264000A756D65726765335F32316108680264000C72756D65726765335F3132616107680264000C72756D65726765335F31326261086A6802640006696E6C696E656C00000004680264000C6B65796D65726765335F3132610C680264000C6B65796D65726765335F3231610C680264000D726B65796D65726765335F3132610C680264000D726B65796D65726765335F3231610C6A6802640006696E6C696E656C00000006680264000D756B65796D65726765335F3132610D680264000D756B65796D65726765335F3231610D680264000F72756B65796D65726765335F313261610B680264000F72756B65796D65726765335F323161610D680264000F72756B65796D65726765335F313262610D680264000F72756B65796D65726765335F323162610C6A6A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61166802640006736F757263656B00312F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6C697374735F736F72742E65726C6A +=mod:user_sup +Current size: 2355 +Current attributes: 836C00000002680264000376736E6C000000016E100074BA860804CB4D60D6908C705E6544BD6A68026400096265686176696F75726C0000000164001173757065727669736F725F6272696467656A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613361246802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F757365725F7375702E65726C6A +=mod:supervisor_bridge +Current size: 2944 +Current attributes: 836C00000002680264000376736E6C000000016E10001590DDC10CF8A9D09763CDB7479678ED6A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612F61156802640006736F757263656B00382F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F73757065727669736F725F6272696467652E65726C6A +=mod:user_drv +Current size: 14630 +Current attributes: 836C00000001680264000376736E6C000000016E1000F29F3B193A1EB1ADA9975D97E51BF0E86A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613361216802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F757365725F6472762E65726C6A +=mod:group +Current size: 10165 +Current attributes: 836C00000001680264000376736E6C000000016E1000F6427D0DA330BBFAD5D4C19058516FF36A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261066802640006736F757263656B002C2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F67726F75702E65726C6A +=mod:io_lib +Current size: 12601 +Current attributes: 836C00000002680264000376736E6C000000016E10004160DD78F37EE7C72F7C5B6A751DB7F56A680264000A646570726563617465646C0000000468026400047363616E610168026400047363616E610268026400047363616E6103680264000D72657365727665645F776F726461016A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61036802640006736F757263656B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F696F5F6C69622E65726C6A +=mod:edlin +Current size: 18178 +Current attributes: 836C00000001680264000376736E6C000000016E100035D752FCBA8ED7F4D26990EF3E6A1A526A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612C61016802640006736F757263656B002C2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F65646C696E2E65726C6A +=mod:io_lib_format +Current size: 16189 +Current attributes: 836C00000001680264000376736E6C000000016E10004F382F327C456F83F33C3D5EBFBD87906A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61066802640006736F757263656B00342F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F696F5F6C69625F666F726D61742E65726C6A +=mod:kernel_config +Current size: 3295 +Current attributes: 836C00000002680264000376736E6C000000016E100077B8EE6C9E95FBBE5DB0371F6DB235226A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261356802640006736F757263656B00342F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F6B65726E656C5F636F6E6669672E65726C6A +=mod:shell +Current size: 22571 +Current attributes: 836C00000001680264000376736E6C000000016E10007D1354325618EB98A5BD4E8F41E6A0226A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612F61016802640006736F757263656B002C2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F7368656C6C2E65726C6A +=mod:error_logger_tty_h +Current size: 7773 +Current attributes: 836C00000002680264000376736E6C000000016E10001502D55D6C1777F07E2E05CDD91D16986A68026400096265686176696F75726C0000000164000967656E5F6576656E746A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61196802640006736F757263656B00392F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6572726F725F6C6F676765725F7474795F682E65726C6A +=mod:erl_eval +Current size: 33481 +Current attributes: 836C00000002680264000376736E6C000000016E1000D06903753C86BBC49A5CBD789CCB09B66A680264000A646570726563617465646C00000004680264000373657161026802640003736571610368026400086172675F6C697374610268026400086172675F6C69737461036A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612C610D6802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F65726C5F6576616C2E65726C6A +=mod:orddict +Current size: 4872 +Current attributes: 836C00000002680264000376736E6C000000016E100078DCF69F3949D79BC54168266A3ABF566A680264000A646570726563617465646C00000002680264000C646963745F746F5F6C6973746101680264000C6C6973745F746F5F6469637461016A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61236802640006736F757263656B002E2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6F7264646963742E65726C6A +=mod:c +Current size: 19555 +Current attributes: 836C00000001680264000376736E6C000000016E10003FACCF5DE16ABBC988ABF0811980C33B6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612B61136802640006736F757263656B00282F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F632E65726C6A +=mod:io +Current size: 7417 +Current attributes: 836C00000002680264000376736E6C000000016E1000E2F2A6094B3C3D945865225D0620E7546A680264000A646570726563617465646C00000007680264000B70617273655F65787072736102680264000C7363616E5F65726C5F7365716101680264000C7363616E5F65726C5F7365716102680264000C7363616E5F65726C5F7365716103680264000D70617273655F65726C5F7365716101680264000D70617273655F65726C5F7365716102680264000D70617273655F65726C5F73657161036A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61006802640006736F757263656B00292F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F696F2E65726C6A +=mod:file +Current size: 20795 +Current attributes: 836C00000002680264000376736E6C000000016E1000D291AF77EE8B08B792B7FE99274504506A680264000A646570726563617465646C00000001680264000966696C655F696E666F61016A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613161276802640006736F757263656B002B2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F66696C652E65726C6A +=mod:file_io_server +Current size: 12071 +Current attributes: 836C00000001680264000376736E6C000000016E1000A5A8C4E2B2646855AD5C617CB216CB966A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6131612A6802640006736F757263656B00352F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F66696C655F696F5F7365727665722E65726C6A +=mod:erl_scan +Current size: 21891 +Current attributes: 836C00000001680264000376736E6C000000016E100094F386F0C378B258E5D9CEADD4F03B6A6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61116802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F65726C5F7363616E2E65726C6A +=mod:erl_parse +Current size: 161233 +Current attributes: 836C00000001680264000376736E6C000000016E10000E8CBC32C293BFC1FBC721CE918062236A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000968026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F76617273640006696E6C696E656802640004686970656C000000016802640008726567616C6C6F6364000B6C696E6561725F7363616E6A6A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61076802640006736F757263656B00302F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F65726C5F70617273652E65726C6A +=mod:erl_lint +Current size: 73159 +Current attributes: 836C00000001680264000376736E6C000000016E1000D1D2A7D6DDFD1195CB180993C76FD2CD6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612C61156802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F65726C5F6C696E742E65726C6A +=mod:ordsets +Current size: 3257 +Current attributes: 836C00000002680264000376736E6C000000016E1000FD39D8FD846511128F5670BA28600F676A680264000A646570726563617465646C0000000468026400076E65775F7365746100680264000B7365745F746F5F6C6973746101680264000B6C6973745F746F5F7365746101680264000673756273657461026A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61256802640006736F757263656B002E2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6F7264736574732E65726C6A +=mod:dict +Current size: 15637 +Current attributes: 836C00000002680264000376736E6C000000016E1000BC846E7EF85045A5D76190CE9B1AE97C6A680264000A646570726563617465646C00000002680264000C646963745F746F5F6C6973746101680264000C6C6973745F746F5F6469637461016A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612B61356802640006736F757263656B002B2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F646963742E65726C6A +=mod:otp_internal +Current size: 7133 +Current attributes: 836C00000001680264000376736E6C000000016E1000DC494F64DE590AFC4919DFEB0EB026B66A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61206802640006736F757263656B00332F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F6F74705F696E7465726E616C2E65726C6A +=mod:user_default +Current size: 1261 +Current attributes: 836C00000002680264000376736E6C000000016E1000505078ACD9B84D514FC6DA2BE249E6756A6802640006617574686F726C0000000164001765656973686E6E406565692E6572696373736F6E2E73656A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000368026400036377646B00112F686F6D652F736972692F65726C616E6768026400066F75746469726B00112F686F6D652F736972692F65726C616E676400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D461036116610D612C61126802640006736F757263656B00222F686F6D652F736972692F65726C616E672F757365725F64656661756C742E65726C6A +=mod:tt +Current size: 2959 +Current attributes: 836C00000002680264000376736E6C000000016E10001D71FD5A55D3BCBF06BFEDF2426C3C386A6802640006617574686F726C0000000164001765656973686E6E406565692E6572696373736F6E2E73656A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000368026400036377646B00112F686F6D652F736972692F65726C616E6768026400066F75746469726B00112F686F6D652F736972692F65726C616E676400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D461036116610D612B610C6802640006736F757263656B00182F686F6D652F736972692F65726C616E672F74742E65726C6A +=mod:distel +Current size: 18214 +Current attributes: 836C00000002680264000376736E6C000000016E1000CC9C9EF141459249C1CCA00993B2E29A6A6802640006617574686F726C000000016400116C756B6540626C75657461696C2E636F6D6A6A +Current compilation info: 836C0000000368026400076F7074696F6E736C0000000664000276336400107761726E5F756E757365645F7661727364000A64656275675F696E666F68026400066F75746469726B00046562696E68026400036377646B001C2F6C6469736B2F736972692F746F6F6C732F64697374656C2D332E3164000A6578706F72745F616C6C6A680264000776657273696F6E6B0003342E31680264000474696D65680662000007D2610B6114610B610361336A +=mod:crashdump_viewer +Current size: 125756 +Current attributes: 836C00000001680264000376736E6C000000016E10002DC5D9D96190A2D5F27FAC3FA3D5C7956A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868026400036377646B00212F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F73726368026400066F75746469726B00292F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F6562696E6802640001696B002C2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F696E636C7564656802640001696B00322F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F2E2E2F65742F696E636C7564656802640001696B003F2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F2E2E2F2E2E2F6C69627261726965732F65742F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F76617273680264000F70617273655F7472616E73666F726D64000C6D735F7472616E73666F726D6A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461146108611B61366802640006736F757263656B00362F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F637261736864756D705F7669657765722E65726C6A +=mod:webtool +Current size: 29229 +Current attributes: 836C00000002680264000376736E6C000000016E10008AEEF06B60527A3390CBC2C98083CC0A6A68026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00202F636C656172636173652F6F74702F746F6F6C732F776562746F6F6C2F73726368026400066F75746469726B00282F636C656172636173652F6F74702F746F6F6C732F776562746F6F6C2F7372632F2E2E2F6562696E64000A64656275675F696E666F6400107761726E5F756E757365645F76617273680264000F70617273655F7472616E73666F726D64000C6D735F7472616E73666F726D6A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104610661086106612D6802640006736F757263656B002C2F636C656172636173652F6F74702F746F6F6C732F776562746F6F6C2F7372632F776562746F6F6C2E65726C6A +=mod:gen_tcp +Current size: 3574 +Current attributes: 836C00000001680264000376736E6C000000016E1000C965E4EAFDAA94D7F21EDCBE30B21E7B6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613161316802640006736F757263656B002E2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F67656E5F7463702E65726C6A +=mod:inet_tcp +Current size: 2743 +Current attributes: 836C00000001680264000376736E6C000000016E1000C4AFE0B49768E4CF78B2C42EA1D3DB7F6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B6132612B6802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F7463702E65726C6A +=mod:inet_gethost_native +Current size: 15611 +Current attributes: 836C00000002680264000376736E6C000000016E10005D8CD4277D0BD2425B9C26036AE314506A68026400096265686176696F75726C0000000164001173757065727669736F725F6272696467656A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000568026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F2E2E2F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B613261206802640006736F757263656B003A2F636C656172636173652F6F74702F657274732F6C69622F6B65726E656C2F7372632F696E65745F676574686F73745F6E61746976652E65726C6A +=mod:filelib +Current size: 7202 +Current attributes: 836C00000001680264000376736E6C000000016E10007B42AA23FF99DF2CD9D586635B77556A6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612D61266802640006736F757263656B002E2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F66696C656C69622E65726C6A +=mod:httpd_util +Current size: 24068 +Current attributes: 836C00000002680264000376736E6C000000016E10008D99E096221B88D542E52CB9C8377F6D6A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104611561066128613B6802640006736F757263656B00312F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F7574696C2E65726C6A +=mod:webtool_sup +Current size: 695 +Current attributes: 836C00000002680264000376736E6C000000016E1000FA5449E12816CF3AD0A3085BB26CDB9B6A68026400096265686176696F75726C0000000164000A73757065727669736F726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000468026400036377646B00202F636C656172636173652F6F74702F746F6F6C732F776562746F6F6C2F73726368026400066F75746469726B00282F636C656172636173652F6F74702F746F6F6C732F776562746F6F6C2F7372632F2E2E2F6562696E64000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461066108610761236802640006736F757263656B00302F636C656172636173652F6F74702F746F6F6C732F776562746F6F6C2F7372632F776562746F6F6C5F7375702E65726C6A +=mod:httpd_conf +Current size: 33659 +Current attributes: 836C00000002680264000376736E6C000000016E1000E3198FBDC73BC48CB7D0C1C762B8F1AB6A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861116802640006736F757263656B00312F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F636F6E662E65726C6A +=mod:regexp +Current size: 13698 +Current attributes: 836C00000001680264000376736E6C000000016E10009DD44F3D02F8328BE3ABF4DDA89E0CAE6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E61376802640006736F757263656B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F7265676578702E65726C6A +=mod:string +Current size: 7740 +Current attributes: 836C00000002680264000376736E6C000000016E10005521DDF38903D46D7C53DB864266F7456A680264000A646570726563617465646C00000007680264000C72655F73685F746F5F61776B6101680264000872655F70617273656101680264000872655F6D617463686102680264000672655F7375626103680264000772655F677375626103680264000872655F73706C697461026802640005696E64657861026A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612F610F6802640006736F757263656B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F737472696E672E65726C6A +=mod:httpd +Current size: 7563 +Current attributes: 836C00000002680264000376736E6C000000016E1000BFD190D951EB3CAD2CC72ADEF20886906A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861036802640006736F757263656B002C2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470642E65726C6A +=mod:httpd_sup +Current size: 4068 +Current attributes: 836C00000003680264000376736E6C000000016E10007FA5C790118F18F3D20A2BFAF0229F0A6A68026400076170705F76736E6B000B696E6574732D332E302E3768026400096265686176696F75726C0000000164000A73757065727669736F726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861366802640006736F757263656B00302F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F7375702E65726C6A +=mod:httpd_acceptor_sup +Current size: 2161 +Current attributes: 836C00000003680264000376736E6C000000016E10003E6F9289B64C13F1EC8A1184BACF055F6A68026400076170705F76736E6B000B696E6574732D332E302E3768026400096265686176696F75726C0000000164000A73757065727669736F726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104611561066128610C6802640006736F757263656B00392F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F6163636570746F725F7375702E65726C6A +=mod:httpd_verbosity +Current size: 2672 +Current attributes: 836C00000002680264000376736E6C000000016E100018B6F407D391872421748F87877DAAF36A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612961036802640006736F757263656B00362F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F766572626F736974792E65726C6A +=mod:timer +Current size: 8223 +Current attributes: 836C00000001680264000376736E6C000000016E10001D0D64DB1B923D1B3B9497655C43B4AD6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612F611A6802640006736F757263656B002C2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F74696D65722E65726C6A +=mod:httpd_misc_sup +Current size: 2066 +Current attributes: 836C00000003680264000376736E6C000000016E100092342F38AC16C074DDC21532FBFB52C26A68026400076170705F76736E6B000B696E6574732D332E302E3768026400096265686176696F75726C0000000164000A73757065727669736F726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104611561066128611F6802640006736F757263656B00352F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F6D6973635F7375702E65726C6A +=mod:httpd_manager +Current size: 28916 +Current attributes: 836C00000003680264000376736E6C000000016E100013F7A1E6A4B6407A0A1892A794EE10A36A68026400076170705F76736E6B000B696E6574732D332E302E3768026400096265686176696F75726C0000000164000A67656E5F7365727665726A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104611561066128611B6802640006736F757263656B00342F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F6D616E616765722E65726C6A +=mod:mod_alias +Current size: 6720 +Current attributes: 836C00000002680264000376736E6C000000016E10002F35C36060B4AC45474440381D146AB96A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612961106802640006736F757263656B00302F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F616C6961732E65726C6A +=mod:mod_auth +Current size: 25168 +Current attributes: 836C00000002680264000376736E6C000000016E100083F3CA0C7A3E7B5E19A635A7F916595D6A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612961166802640006736F757263656B002F2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F617574682E65726C6A +=mod:mod_esi +Current size: 22534 +Current attributes: 836C00000002680264000376736E6C000000016E1000513E3FF733E1E6592B86CB55B9C14E086A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612A61026802640006736F757263656B002E2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F6573692E65726C6A +=mod:mod_actions +Current size: 3625 +Current attributes: 836C00000002680264000376736E6C000000016E10008E5437921662830490CA76DFF88548966A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104611561066129610C6802640006736F757263656B00322F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F616374696F6E732E65726C6A +=mod:mod_cgi +Current size: 25891 +Current attributes: 836C00000002680264000376736E6C000000016E1000F91D405488188F1BD25110B4ED9EE8786A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612961306802640006736F757263656B002E2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F6367692E65726C6A +=mod:mod_include +Current size: 34923 +Current attributes: 836C00000002680264000376736E6C000000016E1000B9CCE88D63DD6AC49D5DF533C46B97D56A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612A61176802640006736F757263656B00322F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F696E636C7564652E65726C6A +=mod:mod_dir +Current size: 13488 +Current attributes: 836C00000002680264000376736E6C000000016E1000EF620CB4B5DE5586ED681347496DA1C86A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612961356802640006736F757263656B002E2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F6469722E65726C6A +=mod:mod_get +Current size: 4672 +Current attributes: 836C00000002680264000376736E6C000000016E1000AD2730B6BE6AF875A500AF4857C4D7F86A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612A61076802640006736F757263656B002E2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F6765742E65726C6A +=mod:mod_head +Current size: 3074 +Current attributes: 836C00000002680264000376736E6C000000016E1000CAF803B9FA6A28D4153BC109B00D7DF96A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612A610B6802640006736F757263656B002F2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F686561642E65726C6A +=mod:mod_log +Current size: 8546 +Current attributes: 836C00000002680264000376736E6C000000016E1000F9664B54861260DEA081249379219AF86A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612A611B6802640006736F757263656B002E2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F6C6F672E65726C6A +=mod:mod_disk_log +Current size: 15160 +Current attributes: 836C00000002680264000376736E6C000000016E1000DDA1E88A9C423A2866B56425DF36F5C66A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612961396802640006736F757263656B00332F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F6D6F645F6469736B5F6C6F672E65726C6A +=mod:httpd_socket +Current size: 7426 +Current attributes: 836C00000002680264000376736E6C000000016E1000B831219096661E4D2E200A07C4A9A7776A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861326802640006736F757263656B00332F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F736F636B65742E65726C6A +=mod:httpd_acceptor +Current size: 4472 +Current attributes: 836C00000002680264000376736E6C000000016E1000A501686DF4E4053E7D978E0CA162BEC56A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861076802640006736F757263656B00352F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F6163636570746F722E65726C6A +=mod:io_lib_pretty +Current size: 8171 +Current attributes: 836C00000001680264000376736E6C000000016E1000CD397E11D2D380D02A4BC6EE309B98CB6A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612E610C6802640006736F757263656B00342F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F696F5F6C69625F7072657474792E65726C6A +=mod:httpd_request_handler +Current size: 26393 +Current attributes: 836C00000002680264000376736E6C000000016E100021C280A5EB5B9CCD00A2C418A341202A6A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861296802640006736F757263656B003C2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F726571756573745F68616E646C65722E65726C6A +=mod:calendar +Current size: 7158 +Current attributes: 836C00000002680264000376736E6C000000016E10008C44498546709037F8D72DA4AF8B7FB76A680264000A646570726563617465646C00000001680264001C6C6F63616C5F74696D655F746F5F756E6976657273616C5F74696D6561016A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00222F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F6562696E6802640001696B002D2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F696E636C7564656802640001696B00372F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F2E2E2F2E2E2F6B65726E656C2F696E636C7564656400107761726E5F756E757365645F7661727364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E31680264000474696D65680662000007D3610C6112610B612B61166802640006736F757263656B002F2F636C656172636173652F6F74702F657274732F6C69622F7374646C69622F7372632F63616C656E6461722E65726C6A +=mod:httpd_parse +Current size: 9977 +Current attributes: 836C00000002680264000376736E6C000000016E1000174653BAA652261FEB44FFDED99E50B76A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461156106612861246802640006736F757263656B00322F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F70617273652E65726C6A +=mod:httpd_response +Current size: 13535 +Current attributes: 836C00000002680264000376736E6C000000016E1000785B247D894BA08A40D814EF11F848976A68026400076170705F76736E6B000B696E6574732D332E302E376A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000868036400016464001164656661756C745F766572626F7369747964000773696C656E636568036400016464000F5345525645525F534F4654574152456B000B696E6574732F332E302E3768026400036377646B00222F636C656172636173652F6F74702F6C69627261726965732F696E6574732F73726368026400066F75746469726B002A2F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F2E2E2F6562696E6804640009617474726962757465640006696E736572746400076170705F76736E6B000B696E6574732D332E302E37680264000F70617273655F7472616E73666F726D6400127379735F7072655F6174747269627574657364000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D46104611561066128612D6802640006736F757263656B00352F636C656172636173652F6F74702F6C69627261726965732F696E6574732F7372632F68747470645F726573706F6E73652E65726C6A +=mod:crashdump_viewer_html +Current size: 68343 +Current attributes: 836C00000001680264000376736E6C000000016E1000AE414770FDB0806C5583FF8D6D71DC766A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000768026400036377646B00212F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F73726368026400066F75746469726B00292F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F6562696E6802640001696B002C2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F696E636C7564656802640001696B00322F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F2E2E2F65742F696E636C7564656802640001696B003F2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F2E2E2F2E2E2F6C69627261726965732F65742F696E636C75646564000A64656275675F696E666F6400107761726E5F756E757365645F766172736A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D4610461146108611C61026802640006736F757263656B003B2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F637261736864756D705F7669657765725F68746D6C2E65726C6A +=mod:crashdump_translate +Current size: 89840 +Current attributes: 836C00000001680264000376736E6C000000016E100038F332287181E933A76CEF4799BDB6416A6A +Current compilation info: 836C0000000468026400076F7074696F6E736C0000000668026400036377646B00212F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F73726368026400066F75746469726B00292F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F6562696E6802640001696B002C2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F696E636C7564656802640001696B00322F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F2E2E2F65742F696E636C7564656802640001696B003F2F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F2E2E2F2E2E2F2E2E2F6C69627261726965732F65742F696E636C75646564000A64656275675F696E666F6A680264000776657273696F6E6B0005342E322E32680264000474696D65680662000007D461046115610B611661106802640006736F757263656B00392F636C656172636173652F6F74702F746F6F6C732F6F627365727665722F7372632F637261736864756D705F7472616E736C6174652E65726C6A +=fun +Module: crashdump_viewer_html +Uniq: 9122590 +Index: 0 +Address: 526308 +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 77168418 +Index: 14 +Address: 26541c +Native_address: bcf04 +Refc: 1 +=fun +Module: inet_parse +Uniq: 88083515 +Index: 9 +Address: 284c30 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 36747896 +Index: 4 +Address: 26df84 +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 80395734 +Index: 8 +Address: 265838 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 103184573 +Index: 5 +Address: 2fa59c +Native_address: bce80 +Refc: 1 +=fun +Module: erl_lint +Uniq: 88265811 +Index: 24 +Address: 34f6a0 +Native_address: bcefc +Refc: 1 +=fun +Module: global_group +Uniq: 9644262 +Index: 2 +Address: 292cec +Native_address: bcef4 +Refc: 1 +=fun +Module: net_kernel +Uniq: 100885585 +Index: 0 +Address: 29eb2c +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 128335479 +Index: 6 +Address: 26de84 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_prim_loader +Uniq: 42988083 +Index: 1 +Address: 210c14 +Native_address: bcf04 +Refc: 1 +=fun +Module: dict +Uniq: 7105125 +Index: 7 +Address: 354f84 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 29030584 +Index: 8 +Address: 234978 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 29214351 +Index: 2 +Address: 285660 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_config +Uniq: 5158633 +Index: 4 +Address: 274034 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 74624950 +Index: 25 +Address: 34f63c +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 6477018 +Index: 3 +Address: 2adb6c +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 117885138 +Index: 7 +Address: 2ffff8 +Native_address: bcefc +Refc: 1 +=fun +Module: dict +Uniq: 47566924 +Index: 6 +Address: 354fb8 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 114637756 +Index: 12 +Address: 313c60 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 121316204 +Index: 31 +Address: 313a68 +Native_address: bced4 +Refc: 1 +=fun +Module: code_server +Uniq: 61363639 +Index: 12 +Address: 2ad6a4 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_config +Uniq: 116208699 +Index: 3 +Address: 274094 +Native_address: bcefc +Refc: 1 +=fun +Module: global_group +Uniq: 113750737 +Index: 0 +Address: 292d54 +Native_address: bcefc +Refc: 1 +=fun +Module: gen_event +Uniq: 12853672 +Index: 0 +Address: 222e74 +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 108046357 +Index: 12 +Address: 4ab0b0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 111569299 +Index: 47 +Address: 34e80c +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 20108653 +Index: 15 +Address: 2f9f94 +Native_address: bcea4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 45252965 +Index: 15 +Address: 313c0c +Native_address: bced4 +Refc: 1 +=fun +Module: webtool +Uniq: 12437425 +Index: 9 +Address: 4ab3e0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 30942993 +Index: 22 +Address: 34f6ec +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_parse +Uniq: 93430337 +Index: 3 +Address: 33b100 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_parse +Uniq: 6604883 +Index: 2 +Address: 33b16c +Native_address: bcefc +Refc: 1 +=fun +Module: rpc +Uniq: 36867745 +Index: 5 +Address: 255e28 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 90563105 +Index: 1 +Address: 285708 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 18519297 +Index: 7 +Address: 26ddfc +Native_address: bcef4 +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 8058975 +Index: 16 +Address: 4a36b4 +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 30694569 +Index: 7 +Address: 27d018 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_config +Uniq: 76933943 +Index: 0 +Address: 2741b4 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 9033258 +Index: 6 +Address: 4a4690 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 74851752 +Index: 5 +Address: 4a4798 +Native_address: bcef4 +Refc: 1 +=fun +Module: global +Uniq: 50855382 +Index: 4 +Address: 2659a8 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 39211582 +Index: 52 +Address: 34e504 +Native_address: bceec +Refc: 1 +=fun +Module: file_server +Uniq: 77665472 +Index: 0 +Address: 2a0dec +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_eval +Uniq: 57487277 +Index: 8 +Address: 2fa3c4 +Native_address: bce94 +Refc: 1 +=fun +Module: webtool +Uniq: 87386575 +Index: 11 +Address: 4ab1c8 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 58991950 +Index: 8 +Address: 4a4338 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 118859163 +Index: 17 +Address: 4a34d4 +Native_address: bcefc +Refc: 1 +=fun +Module: dict +Uniq: 38265609 +Index: 12 +Address: 354dec +Native_address: bcefc +Refc: 1 +=fun +Module: supervisor +Uniq: 56903339 +Index: 1 +Address: 2527c4 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_hosts +Uniq: 129504763 +Index: 0 +Address: 28aae8 +Native_address: bcefc +Refc: 1 +=fun +Module: dict +Uniq: 44817307 +Index: 10 +Address: 354e3c +Native_address: bceec +Refc: 1 +=fun +Module: erl_lint +Uniq: 52856894 +Index: 41 +Address: 34eb70 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 22623360 +Index: 23 +Address: 34f5d4 +Native_address: bceec +Refc: 1 +=fun +Module: orddict +Uniq: 34963136 +Index: 0 +Address: 2fbbbc +Native_address: bcef4 +Refc: 1 +=fun +Module: erlang +Uniq: 24496633 +Index: 0 +Address: 213744 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 99313855 +Index: 27 +Address: 2f9914 +Native_address: bcef4 +Refc: 1 +=fun +Module: httpd_util +Uniq: 99137703 +Index: 3 +Address: 4b5dfc +Native_address: bcefc +Refc: 1 +=fun +Module: gen_event +Uniq: 124043500 +Index: 3 +Address: 222b84 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 102650878 +Index: 22 +Address: 313b48 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 13333720 +Index: 12 +Address: 34fb2c +Native_address: bcef4 +Refc: 1 +=fun +Module: global_group +Uniq: 133457 +Index: 5 +Address: 292a80 +Native_address: bcefc +Refc: 1 +=fun +Module: net_kernel +Uniq: 64640983 +Index: 4 +Address: 29e944 +Native_address: bcefc +Refc: 1 +=fun +Module: rpc +Uniq: 7580218 +Index: 2 +Address: 255f08 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_lint +Uniq: 131850870 +Index: 59 +Address: 34e6b8 +Native_address: bcef4 +Refc: 1 +=fun +Module: inet_parse +Uniq: 56617403 +Index: 10 +Address: 284b40 +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 108680306 +Index: 4 +Address: 4ab5e0 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 90880071 +Index: 2 +Address: 26e150 +Native_address: bcefc +Refc: 1 +=fun +Module: file_io_server +Uniq: 23980778 +Index: 0 +Address: 30ac30 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_eval +Uniq: 12006418 +Index: 19 +Address: 2f9d54 +Native_address: bce80 +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 81701030 +Index: 8 +Address: 526228 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 71013875 +Index: 1 +Address: 4a4ddc +Native_address: bcf04 +Refc: 1 +=fun +Module: distel +Uniq: 87740845 +Index: 2 +Address: 35c0e0 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_eval +Uniq: 90782401 +Index: 17 +Address: 2f9e8c +Native_address: bced4 +Refc: 1 +=fun +Module: shell +Uniq: 133882676 +Index: 6 +Address: 2e52ac +Native_address: bcef4 +Refc: 1 +=fun +Module: inet_parse +Uniq: 105698088 +Index: 3 +Address: 2855b4 +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 58370899 +Index: 0 +Address: 27d370 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 15274536 +Index: 25 +Address: 2f9a94 +Native_address: bcef4 +Refc: 1 +=fun +Module: supervisor +Uniq: 94349557 +Index: 0 +Address: 252844 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_parse +Uniq: 33328185 +Index: 1 +Address: 33b1d8 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 86971387 +Index: 16 +Address: 313db0 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 53364473 +Index: 38 +Address: 34ee84 +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 128145687 +Index: 0 +Address: 4ab944 +Native_address: bcee4 +Refc: 1 +=fun +Module: c +Uniq: 98651404 +Index: 10 +Address: 2fff20 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 78224618 +Index: 0 +Address: 313dcc +Native_address: bced4 +Refc: 1 +=fun +Module: shell +Uniq: 40779085 +Index: 11 +Address: 2e50c8 +Native_address: bcef4 +Refc: 1 +=fun +Module: c +Uniq: 93517350 +Index: 4 +Address: 300090 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 58551291 +Index: 0 +Address: 234f14 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 10055518 +Index: 17 +Address: 526170 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 15795706 +Index: 19 +Address: 313bd4 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 31129467 +Index: 13 +Address: 313c44 +Native_address: bced4 +Refc: 1 +=fun +Module: old_file_server +Uniq: 115635393 +Index: 0 +Address: 2a1a4c +Native_address: bcf04 +Refc: 2 +=fun +Module: erl_eval +Uniq: 65839696 +Index: 22 +Address: 2f9c00 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 69275064 +Index: 28 +Address: 313aa0 +Native_address: bced4 +Refc: 1 +=fun +Module: dict +Uniq: 55938066 +Index: 11 +Address: 354d6c +Native_address: bceec +Refc: 1 +=fun +Module: supervisor +Uniq: 22323433 +Index: 3 +Address: 252688 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 129726129 +Index: 29 +Address: 313abc +Native_address: bced4 +Refc: 1 +=fun +Module: dict +Uniq: 84346832 +Index: 0 +Address: 3550fc +Native_address: bceec +Refc: 1 +=fun +Module: shell +Uniq: 102096820 +Index: 7 +Address: 2e5290 +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 70385762 +Index: 11 +Address: 27cf44 +Native_address: bcefc +Refc: 1 +=fun +Module: mod_cgi +Uniq: 1483038 +Index: 0 +Address: 4ec2e8 +Native_address: bcefc +Refc: 1 +=fun +Module: dict +Uniq: 3664813 +Index: 1 +Address: 3550b4 +Native_address: bcef4 +Refc: 1 +=fun +Module: inet +Uniq: 131143671 +Index: 6 +Address: 27d08c +Native_address: bcef4 +Refc: 1 +=fun +Module: inet_config +Uniq: 46286977 +Index: 2 +Address: 2740b0 +Native_address: bcefc +Refc: 1 +=fun +Module: mod_esi +Uniq: 49099432 +Index: 0 +Address: 4e522c +Native_address: bcefc +Refc: 1 +=fun +Module: application_master +Uniq: 95764905 +Index: 2 +Address: 24aaa8 +Native_address: bcefc +Refc: 1 +=fun +Module: packages +Uniq: 62890926 +Index: 0 +Address: 2ae814 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 41564771 +Index: 35 +Address: 3139f8 +Native_address: bced4 +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 95490768 +Index: 0 +Address: 4a4dc0 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_scan +Uniq: 121559432 +Index: 3 +Address: 313d78 +Native_address: bced4 +Refc: 1 +=fun +Module: httpd_conf +Uniq: 21152662 +Index: 0 +Address: 4be5a0 +Native_address: bcefc +Refc: 1 +=fun +Module: net_kernel +Uniq: 41630916 +Index: 5 +Address: 29e914 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 19747201 +Index: 5 +Address: 313d24 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 100584837 +Index: 36 +Address: 34f0f4 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 64635712 +Index: 15 +Address: 34f94c +Native_address: bcef4 +Refc: 1 +=fun +Module: net_kernel +Uniq: 46398361 +Index: 3 +Address: 29e9a4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 86699817 +Index: 27 +Address: 313b2c +Native_address: bced4 +Refc: 1 +=fun +Module: distel +Uniq: 40869731 +Index: 0 +Address: 35c12c +Native_address: bcf04 +Refc: 1 +=fun +Module: inet +Uniq: 83701641 +Index: 1 +Address: 27d33c +Native_address: bcefc +Refc: 1 +=fun +Module: mod_auth +Uniq: 85845790 +Index: 0 +Address: 4dfd84 +Native_address: bcefc +Refc: 1 +=fun +Module: shell +Uniq: 101292714 +Index: 9 +Address: 2e519c +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 134173702 +Index: 1 +Address: 265b68 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 92433687 +Index: 6 +Address: 2ad9f4 +Native_address: bcef4 +Refc: 1 +=fun +Module: dict +Uniq: 62315241 +Index: 8 +Address: 354f38 +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 11615541 +Index: 12 +Address: 265530 +Native_address: bcefc +Refc: 1 +=fun +Module: hipe_unified_loader +Uniq: 11160090 +Index: 2 +Address: 2b6bb4 +Native_address: bcef4 +Refc: 1 +=fun +Module: application_controller +Uniq: 12116524 +Index: 15 +Address: 2342c4 +Native_address: bcef4 +Refc: 1 +=fun +Module: mod_log +Uniq: 61620901 +Index: 2 +Address: 4fc670 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 23665189 +Index: 12 +Address: 4a3b94 +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 43844413 +Index: 0 +Address: 300100 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 100514258 +Index: 6 +Address: 313d08 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 54271286 +Index: 17 +Address: 34f8a0 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 47017252 +Index: 3 +Address: 26dfa0 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 1228304 +Index: 7 +Address: 4a45a4 +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 127131470 +Index: 10 +Address: 2655a0 +Native_address: bcefc +Refc: 1 +=fun +Module: file_server +Uniq: 22638227 +Index: 1 +Address: 2a0e20 +Native_address: bcf04 +Refc: 1 +=fun +Module: code_server +Uniq: 112704920 +Index: 15 +Address: 2ad488 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 88302875 +Index: 2 +Address: 2fa76c +Native_address: bceb4 +Refc: 1 +=fun +Module: inet_hosts +Uniq: 85808984 +Index: 1 +Address: 28ab18 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_parse +Uniq: 106391799 +Index: 0 +Address: 33b22c +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 25830519 +Index: 5 +Address: 27d0c0 +Native_address: bcefc +Refc: 1 +=fun +Module: shell +Uniq: 110491036 +Index: 1 +Address: 2e5398 +Native_address: bcef4 +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 13128736 +Index: 5 +Address: 52627c +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 84644982 +Index: 21 +Address: 313b9c +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 120577486 +Index: 3 +Address: 34fffc +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 4504456 +Index: 44 +Address: 34e938 +Native_address: bceec +Refc: 1 +=fun +Module: mod_disk_log +Uniq: 28754183 +Index: 0 +Address: 500140 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 88043334 +Index: 14 +Address: 313c28 +Native_address: bced4 +Refc: 1 +=fun +Module: code_server +Uniq: 61592373 +Index: 0 +Address: 2adc28 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_scan +Uniq: 74468346 +Index: 26 +Address: 313ad8 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 69896253 +Index: 21 +Address: 2f9c40 +Native_address: bce80 +Refc: 1 +=fun +Module: global_group +Uniq: 59656873 +Index: 4 +Address: 292ac0 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 103891261 +Index: 2 +Address: 4a4d70 +Native_address: bcefc +Refc: 1 +=fun +Module: httpd_util +Uniq: 89619733 +Index: 0 +Address: 4b5e64 +Native_address: bcefc +Refc: 1 +=fun +Module: shell +Uniq: 133201466 +Index: 10 +Address: 2e5180 +Native_address: bceec +Refc: 1 +=fun +Module: webtool +Uniq: 32159369 +Index: 2 +Address: 4ab820 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 76861396 +Index: 2 +Address: 2adbb0 +Native_address: bcefc +Refc: 1 +=fun +Module: mod_log +Uniq: 48206487 +Index: 0 +Address: 4fc6f0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 118996551 +Index: 28 +Address: 34f384 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 12593774 +Index: 50 +Address: 34e60c +Native_address: bcef4 +Refc: 1 +=fun +Module: httpd_request_handler +Uniq: 48542841 +Index: 1 +Address: 50e88c +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 56178490 +Index: 9 +Address: 4a420c +Native_address: bcefc +Refc: 1 +=fun +Module: distel +Uniq: 88212576 +Index: 4 +Address: 35bf44 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 79562132 +Index: 29 +Address: 34f368 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 129524917 +Index: 32 +Address: 34f2c0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 54029891 +Index: 23 +Address: 2f9af0 +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 108872092 +Index: 4 +Address: 27d0f0 +Native_address: bcef4 +Refc: 1 +=fun +Module: application_controller +Uniq: 40905124 +Index: 6 +Address: 234ac0 +Native_address: bcef4 +Refc: 1 +=fun +Module: code_server +Uniq: 50124876 +Index: 10 +Address: 2ad760 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 791358 +Index: 48 +Address: 34e7b0 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 18404828 +Index: 24 +Address: 313af4 +Native_address: bced4 +Refc: 1 +=fun +Module: httpd_util +Uniq: 13278653 +Index: 1 +Address: 4b5e48 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 110307423 +Index: 13 +Address: 284a7c +Native_address: bcefc +Refc: 1 +=fun +Module: rpc +Uniq: 99592247 +Index: 0 +Address: 256118 +Native_address: bcf04 +Refc: 1 +=fun +Module: global +Uniq: 99918211 +Index: 2 +Address: 265af4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 71442319 +Index: 27 +Address: 34f510 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 7612785 +Index: 13 +Address: 2fa0fc +Native_address: bce80 +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 56095795 +Index: 15 +Address: 4a38a0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 23626796 +Index: 25 +Address: 313b10 +Native_address: bced4 +Refc: 1 +=fun +Module: file_server +Uniq: 126074974 +Index: 2 +Address: 2a0cac +Native_address: bcef4 +Refc: 1 +=fun +Module: inet_config +Uniq: 104278122 +Index: 1 +Address: 274154 +Native_address: bcefc +Refc: 1 +=fun +Module: sys +Uniq: 90854051 +Index: 0 +Address: 240344 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 113334594 +Index: 2 +Address: 313d5c +Native_address: bced4 +Refc: 1 +=fun +Module: inet_parse +Uniq: 8832142 +Index: 7 +Address: 284e30 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 9159706 +Index: 42 +Address: 34eb54 +Native_address: bceec +Refc: 1 +=fun +Module: inet_db +Uniq: 123946665 +Index: 8 +Address: 26e494 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 3149789 +Index: 1 +Address: 5262d0 +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 48288621 +Index: 11 +Address: 2ffed8 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 8953292 +Index: 20 +Address: 4a4d54 +Native_address: bcee4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 9632158 +Index: 4 +Address: 34ff88 +Native_address: bcefc +Refc: 1 +=fun +Module: net_kernel +Uniq: 31111567 +Index: 7 +Address: 29e8c8 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 85307443 +Index: 10 +Address: 2fa29c +Native_address: bcec4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 104417191 +Index: 7 +Address: 313cd0 +Native_address: bced4 +Refc: 1 +=fun +Module: dict +Uniq: 43625777 +Index: 5 +Address: 354fec +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 92698798 +Index: 3 +Address: 4ab780 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 39074546 +Index: 6 +Address: 2fa54c +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 71451126 +Index: 5 +Address: 234b98 +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 122084387 +Index: 6 +Address: 300038 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 9625924 +Index: 14 +Address: 284a60 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 128777368 +Index: 11 +Address: 313c7c +Native_address: bced4 +Refc: 1 +=fun +Module: webtool +Uniq: 10203723 +Index: 7 +Address: 4ab4f8 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 35032400 +Index: 10 +Address: 313c98 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 17252586 +Index: 34 +Address: 313a14 +Native_address: bced4 +Refc: 1 +=fun +Module: code_server +Uniq: 7177165 +Index: 11 +Address: 2ad734 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 115778175 +Index: 3 +Address: 4a4930 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 96440880 +Index: 51 +Address: 34e590 +Native_address: bcefc +Refc: 1 +=fun +Module: hipe_unified_loader +Uniq: 68275407 +Index: 0 +Address: 2b7340 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 88854488 +Index: 16 +Address: 2f9f04 +Native_address: bcebc +Refc: 1 +=fun +Module: global +Uniq: 26353848 +Index: 13 +Address: 2654e8 +Native_address: bcf04 +Refc: 3 +=fun +Module: global +Uniq: 93414722 +Index: 11 +Address: 265568 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 11194189 +Index: 60 +Address: 34fe0c +Native_address: bcef4 +Refc: 1 +=fun +Module: c +Uniq: 125189992 +Index: 8 +Address: 2fffdc +Native_address: bcefc +Refc: 1 +=fun +Module: dict +Uniq: 112472016 +Index: 2 +Address: 355088 +Native_address: bceec +Refc: 1 +=fun +Module: shell +Uniq: 104426442 +Index: 5 +Address: 2e52e0 +Native_address: bceec +Refc: 1 +=fun +Module: global +Uniq: 17426458 +Index: 0 +Address: 265bc4 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 81191039 +Index: 5 +Address: 2ada48 +Native_address: bcef4 +Refc: 1 +=fun +Module: inet_parse +Uniq: 71765042 +Index: 5 +Address: 284f74 +Native_address: bcefc +Refc: 1 +=fun +Module: init +Uniq: 85855821 +Index: 2 +Address: 1fa298 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 70586122 +Index: 10 +Address: 4a3fe4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 87067911 +Index: 49 +Address: 34e708 +Native_address: bcef4 +Refc: 1 +=fun +Module: distel +Uniq: 63126735 +Index: 1 +Address: 35c0fc +Native_address: bcf04 +Refc: 1 +=fun +Module: c +Uniq: 58270309 +Index: 1 +Address: 3000e4 +Native_address: bcefc +Refc: 1 +=fun +Module: ets +Uniq: 80538457 +Index: 1 +Address: 2bc1a0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 69827241 +Index: 9 +Address: 34fd70 +Native_address: bcef4 +Refc: 1 +=fun +Module: dict +Uniq: 103968752 +Index: 3 +Address: 355054 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 117175573 +Index: 21 +Address: 34f728 +Native_address: bcef4 +Refc: 1 +=fun +Module: shell +Uniq: 57865450 +Index: 2 +Address: 2e537c +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 14705965 +Index: 20 +Address: 313b80 +Native_address: bced4 +Refc: 1 +=fun +Module: webtool +Uniq: 85360931 +Index: 6 +Address: 4ab56c +Native_address: bcefc +Refc: 1 +=fun +Module: kernel_config +Uniq: 41755598 +Index: 0 +Address: 2d9e20 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 7110547 +Index: 37 +Address: 34ef14 +Native_address: bcef4 +Refc: 1 +=fun +Module: application_controller +Uniq: 28091577 +Index: 16 +Address: 234244 +Native_address: bcef4 +Refc: 2 +=fun +Module: code_server +Uniq: 96448152 +Index: 14 +Address: 2ad4e4 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 40177568 +Index: 13 +Address: 4a39a4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 31948320 +Index: 58 +Address: 34dfdc +Native_address: bcef4 +Refc: 1 +=fun +Module: global +Uniq: 54153760 +Index: 7 +Address: 265854 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 60156260 +Index: 3 +Address: 5262b4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 1010616 +Index: 2 +Address: 350064 +Native_address: bcef4 +Refc: 1 +=fun +Module: init +Uniq: 96784459 +Index: 1 +Address: 1fa2b4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 48691771 +Index: 18 +Address: 313bb8 +Native_address: bced4 +Refc: 1 +=fun +Module: global +Uniq: 26895060 +Index: 9 +Address: 265710 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 109625093 +Index: 7 +Address: 2ad8fc +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 59436171 +Index: 1 +Address: 3500dc +Native_address: bcef4 +Refc: 1 +=fun +Module: dict +Uniq: 92768306 +Index: 9 +Address: 354f04 +Native_address: bcefc +Refc: 1 +=fun +Module: global_group +Uniq: 106430008 +Index: 3 +Address: 292b38 +Native_address: bcefc +Refc: 1 +=fun +Module: init +Uniq: 79749196 +Index: 6 +Address: 1fa01c +Native_address: bceec +Refc: 1 +=fun +Module: erl_eval +Uniq: 6014929 +Index: 9 +Address: 2fa324 +Native_address: bceac +Refc: 1 +=fun +Module: application_controller +Uniq: 57051922 +Index: 7 +Address: 234a28 +Native_address: bcef4 +Refc: 1 +=fun +Module: net_kernel +Uniq: 77043468 +Index: 6 +Address: 29e8e4 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 36176045 +Index: 9 +Address: 52620c +Native_address: bcefc +Refc: 1 +=fun +Module: rpc +Uniq: 35862809 +Index: 3 +Address: 255edc +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 113649451 +Index: 4 +Address: 2850a0 +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 67943969 +Index: 5 +Address: 2658f4 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 109003032 +Index: 16 +Address: 5260d0 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 104711447 +Index: 13 +Address: 525f5c +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 107666872 +Index: 9 +Address: 27cfb0 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 89410000 +Index: 10 +Address: 5261f0 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 47356870 +Index: 11 +Address: 284ab4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 17873449 +Index: 56 +Address: 34e1e8 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 8839441 +Index: 33 +Address: 34f25c +Native_address: bcefc +Refc: 1 +=fun +Module: gen_event +Uniq: 82513204 +Index: 2 +Address: 222c18 +Native_address: bcefc +Refc: 1 +=fun +Module: application_master +Uniq: 5973059 +Index: 0 +Address: 24ab7c +Native_address: bcefc +Refc: 1 +=fun +Module: inet_gethost_native +Uniq: 127832132 +Index: 0 +Address: 4b065c +Native_address: bcefc +Refc: 2 +=fun +Module: crashdump_viewer_html +Uniq: 39322658 +Index: 14 +Address: 525f40 +Native_address: bcefc +Refc: 1 +=fun +Module: gen_server +Uniq: 100284021 +Index: 0 +Address: 23d288 +Native_address: bcf04 +Refc: 1 +=fun +Module: inet_parse +Uniq: 17430070 +Index: 12 +Address: 284a98 +Native_address: bcefc +Refc: 1 +=fun +Module: init +Uniq: 97509773 +Index: 3 +Address: 1fa27c +Native_address: bcefc +Refc: 1 +=fun +Module: distel +Uniq: 32364818 +Index: 3 +Address: 35c050 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 58576084 +Index: 32 +Address: 313a4c +Native_address: bced4 +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 38384851 +Index: 14 +Address: 4a3988 +Native_address: bceec +Refc: 1 +=fun +Module: application_controller +Uniq: 14139883 +Index: 4 +Address: 234d78 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 122590256 +Index: 0 +Address: 2fa8b4 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_eval +Uniq: 14705629 +Index: 11 +Address: 2fa22c +Native_address: bcedc +Refc: 1 +=fun +Module: erl_eval +Uniq: 9273769 +Index: 4 +Address: 2fa684 +Native_address: bcee4 +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 87950142 +Index: 11 +Address: 5261d4 +Native_address: bcefc +Refc: 1 +=fun +Module: mod_log +Uniq: 54913678 +Index: 1 +Address: 4fc6b0 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 28370334 +Index: 0 +Address: 26e4b0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 24927227 +Index: 40 +Address: 34ed4c +Native_address: bceec +Refc: 1 +=fun +Module: erl_scan +Uniq: 105437500 +Index: 33 +Address: 313a30 +Native_address: bced4 +Refc: 1 +=fun +Module: application_controller +Uniq: 10921695 +Index: 1 +Address: 234eac +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 112431564 +Index: 55 +Address: 34e22c +Native_address: bceec +Refc: 1 +=fun +Module: webtool +Uniq: 129460863 +Index: 5 +Address: 4ab5c4 +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 89001648 +Index: 3 +Address: 27d2ec +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 36199507 +Index: 8 +Address: 27cfe4 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 35620771 +Index: 2 +Address: 5262ec +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 83214871 +Index: 18 +Address: 2f9e34 +Native_address: bceec +Refc: 1 +=fun +Module: code_server +Uniq: 122455383 +Index: 1 +Address: 2adc0c +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_lint +Uniq: 22389488 +Index: 31 +Address: 34f1b8 +Native_address: bceec +Refc: 1 +=fun +Module: erl_eval +Uniq: 41869059 +Index: 12 +Address: 2fa1d4 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 18130505 +Index: 45 +Address: 34e904 +Native_address: bcefc +Refc: 1 +=fun +Module: hipe_unified_loader +Uniq: 107414126 +Index: 1 +Address: 2b706c +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 116638945 +Index: 28 +Address: 2f98f8 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 48465762 +Index: 9 +Address: 2348c8 +Native_address: bcefc +Refc: 1 +=fun +Module: httpd_request_handler +Uniq: 87633852 +Index: 0 +Address: 50e97c +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 28213098 +Index: 8 +Address: 4ab42c +Native_address: bcefc +Refc: 1 +=fun +Module: gen_event +Uniq: 123630574 +Index: 4 +Address: 222b58 +Native_address: bcefc +Refc: 1 +=fun +Module: dict +Uniq: 127425508 +Index: 13 +Address: 354eb4 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 95048118 +Index: 16 +Address: 2ad46c +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 108661978 +Index: 19 +Address: 34f75c +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 21272619 +Index: 13 +Address: 34fad8 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 29943747 +Index: 17 +Address: 313bf0 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 120240397 +Index: 4 +Address: 313d94 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 124060676 +Index: 0 +Address: 350124 +Native_address: bcef4 +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 100975346 +Index: 6 +Address: 526260 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 61421476 +Index: 4 +Address: 2ada9c +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 45197232 +Index: 7 +Address: 34fe5c +Native_address: bcef4 +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 3151900 +Index: 15 +Address: 525f24 +Native_address: bcefc +Refc: 1 +=fun +Module: httpd_util +Uniq: 77509245 +Index: 2 +Address: 4b5e2c +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 94110229 +Index: 8 +Address: 2ad7e4 +Native_address: bcef4 +Refc: 3 +=fun +Module: rpc +Uniq: 101217130 +Index: 1 +Address: 2560c4 +Native_address: bcf04 +Refc: 1 +=fun +Module: lists +Uniq: 103647452 +Index: 0 +Address: 244b7c +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 37841211 +Index: 9 +Address: 2ad77c +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 40109251 +Index: 54 +Address: 34e2b4 +Native_address: bcef4 +Refc: 1 +=fun +Module: init +Uniq: 98012300 +Index: 0 +Address: 1fa2d0 +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 73604759 +Index: 10 +Address: 4ab270 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 12042434 +Index: 1 +Address: 313d40 +Native_address: bced4 +Refc: 1 +=fun +Module: shell +Uniq: 127137775 +Index: 4 +Address: 2e531c +Native_address: bcf04 +Refc: 1 +=fun +Module: inet +Uniq: 45498037 +Index: 12 +Address: 27cec0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 122441107 +Index: 34 +Address: 34f1d4 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 70933889 +Index: 46 +Address: 34e8d0 +Native_address: bcef4 +Refc: 1 +=fun +Module: inet +Uniq: 69850797 +Index: 2 +Address: 27d308 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 103965539 +Index: 13 +Address: 234684 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 29979659 +Index: 30 +Address: 313a84 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 17148721 +Index: 20 +Address: 34f778 +Native_address: bcefc +Refc: 1 +=fun +Module: httpd_response +Uniq: 100673049 +Index: 0 +Address: 5165dc +Native_address: bcefc +Refc: 1 +=fun +Module: inet_gethost_native +Uniq: 10508176 +Index: 1 +Address: 4b04dc +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 32476064 +Index: 57 +Address: 34e1c4 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 74835078 +Index: 9 +Address: 313cec +Native_address: bced4 +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 60689814 +Index: 19 +Address: 4a3b78 +Native_address: bceec +Refc: 1 +=fun +Module: erl_lint +Uniq: 39269715 +Index: 5 +Address: 34ff14 +Native_address: bcef4 +Refc: 1 +=fun +Module: shell +Uniq: 112923172 +Index: 0 +Address: 2e5404 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_eval +Uniq: 43010824 +Index: 14 +Address: 2fa03c +Native_address: bce8c +Refc: 1 +=fun +Module: global +Uniq: 82495254 +Index: 3 +Address: 265ac8 +Native_address: bcefc +Refc: 1 +=fun +Module: shell +Uniq: 48568081 +Index: 8 +Address: 2e5220 +Native_address: bcefc +Refc: 1 +=fun +Module: init +Uniq: 77236637 +Index: 7 +Address: 1fa000 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_eval +Uniq: 109386574 +Index: 1 +Address: 2fa804 +Native_address: bce9c +Refc: 1 +=fun +Module: erl_lint +Uniq: 42613220 +Index: 14 +Address: 34f980 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_scan +Uniq: 67093144 +Index: 23 +Address: 313b64 +Native_address: bced4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 86833790 +Index: 11 +Address: 34fbe8 +Native_address: bcefc +Refc: 1 +=fun +Module: net_kernel +Uniq: 6344855 +Index: 1 +Address: 29eabc +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 5149749 +Index: 35 +Address: 34f220 +Native_address: bcefc +Refc: 1 +=fun +Module: init +Uniq: 93451769 +Index: 5 +Address: 1fa120 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 117428568 +Index: 11 +Address: 234758 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 15225890 +Index: 4 +Address: 526298 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 120760477 +Index: 2 +Address: 234cdc +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 88561919 +Index: 3 +Address: 3000ac +Native_address: bcefc +Refc: 1 +=fun +Module: erl_scan +Uniq: 108931174 +Index: 8 +Address: 313cb4 +Native_address: bced4 +Refc: 1 +=fun +Module: rpc +Uniq: 122901192 +Index: 4 +Address: 255e44 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_lint +Uniq: 32985930 +Index: 10 +Address: 34fc40 +Native_address: bcef4 +Refc: 1 +=fun +Module: global_group +Uniq: 97968498 +Index: 1 +Address: 292b7c +Native_address: bcef4 +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 45671671 +Index: 18 +Address: 4a32d0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 117968056 +Index: 3 +Address: 2fa6ec +Native_address: bcecc +Refc: 1 +=fun +Module: init +Uniq: 108717591 +Index: 4 +Address: 1fa194 +Native_address: bcf04 +Refc: 1 +=fun +Module: supervisor +Uniq: 15091954 +Index: 2 +Address: 2526dc +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 65707495 +Index: 6 +Address: 2658a4 +Native_address: bcefc +Refc: 1 +=fun +Module: code_server +Uniq: 34473969 +Index: 17 +Address: 2ad450 +Native_address: bcef4 +Refc: 2 +=fun +Module: crashdump_viewer_html +Uniq: 124296602 +Index: 7 +Address: 526244 +Native_address: bcefc +Refc: 1 +=fun +Module: global +Uniq: 23074707 +Index: 15 +Address: 265460 +Native_address: bcefc +Refc: 1 +=fun +Module: inet +Uniq: 25972856 +Index: 10 +Address: 27cf74 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 43110452 +Index: 24 +Address: 2f9ad4 +Native_address: bceec +Refc: 1 +=fun +Module: code_server +Uniq: 106445918 +Index: 13 +Address: 2ad660 +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer_html +Uniq: 116071286 +Index: 12 +Address: 5261b8 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 130814477 +Index: 8 +Address: 284cfc +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 121017037 +Index: 39 +Address: 34ed80 +Native_address: bcef4 +Refc: 1 +=fun +Module: ets +Uniq: 104895267 +Index: 0 +Address: 2bc1bc +Native_address: bcefc +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 104682437 +Index: 11 +Address: 4a3de0 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 70248777 +Index: 30 +Address: 34f30c +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 13274975 +Index: 5 +Address: 300074 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 98442771 +Index: 53 +Address: 34e2d0 +Native_address: bceec +Refc: 1 +=fun +Module: erl_eval +Uniq: 69829006 +Index: 7 +Address: 2fa47c +Native_address: bce80 +Refc: 1 +=fun +Module: old_file_server +Uniq: 36444943 +Index: 1 +Address: 2a1a80 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_lint +Uniq: 58719455 +Index: 26 +Address: 34f5f0 +Native_address: bcefc +Refc: 1 +=fun +Module: timer +Uniq: 42505885 +Index: 0 +Address: 4cd62c +Native_address: bcefc +Refc: 1 +=fun +Module: erl_eval +Uniq: 54682479 +Index: 20 +Address: 2f9d08 +Native_address: bcf04 +Refc: 1 +=fun +Module: gen_event +Uniq: 86070332 +Index: 1 +Address: 222d7c +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 54728136 +Index: 9 +Address: 2fff68 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 16474219 +Index: 3 +Address: 234c60 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 108831556 +Index: 10 +Address: 234810 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 72053761 +Index: 16 +Address: 34f8ec +Native_address: bcef4 +Refc: 1 +=fun +Module: net_kernel +Uniq: 65127616 +Index: 2 +Address: 29ea04 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 126167637 +Index: 14 +Address: 234640 +Native_address: bcef4 +Refc: 1 +=fun +Module: inet_parse +Uniq: 113704917 +Index: 0 +Address: 285788 +Native_address: bcefc +Refc: 1 +=fun +Module: mod_disk_log +Uniq: 75279647 +Index: 1 +Address: 500100 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 119218247 +Index: 5 +Address: 26df68 +Native_address: bcef4 +Refc: 1 +=fun +Module: httpd_util +Uniq: 85690044 +Index: 4 +Address: 4b5d6c +Native_address: bcefc +Refc: 1 +=fun +Module: inet_db +Uniq: 53075592 +Index: 1 +Address: 26e16c +Native_address: bcefc +Refc: 1 +=fun +Module: c +Uniq: 39490182 +Index: 2 +Address: 3000c8 +Native_address: bcefc +Refc: 1 +=fun +Module: application_controller +Uniq: 75189006 +Index: 12 +Address: 234714 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 14980808 +Index: 43 +Address: 34eb38 +Native_address: bceec +Refc: 1 +=fun +Module: crashdump_viewer +Uniq: 16463468 +Index: 4 +Address: 4a4914 +Native_address: bcee4 +Refc: 1 +=fun +Module: dict +Uniq: 99965326 +Index: 4 +Address: 355020 +Native_address: bcefc +Refc: 1 +=fun +Module: inet_parse +Uniq: 36900786 +Index: 6 +Address: 284f3c +Native_address: bcefc +Refc: 1 +=fun +Module: erl_lint +Uniq: 45447147 +Index: 18 +Address: 34f794 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 32353825 +Index: 6 +Address: 34fe78 +Native_address: bcef4 +Refc: 1 +=fun +Module: erl_lint +Uniq: 134052338 +Index: 8 +Address: 34fdc0 +Native_address: bceec +Refc: 1 +=fun +Module: application_master +Uniq: 23840924 +Index: 1 +Address: 24aae0 +Native_address: bcefc +Refc: 1 +=fun +Module: webtool +Uniq: 108282500 +Index: 1 +Address: 4ab918 +Native_address: bcefc +Refc: 1 +=fun +Module: erl_prim_loader +Uniq: 31081110 +Index: 0 +Address: 210c68 +Native_address: bcf04 +Refc: 1 +=fun +Module: erl_eval +Uniq: 54275742 +Index: 26 +Address: 2f9a4c +Native_address: bcef4 +Refc: 1 +=fun +Module: shell +Uniq: 45083091 +Index: 3 +Address: 2e5350 +Native_address: bcf04 +Refc: 3 +=proc_stack:<0.0.0> +3a48bc:SReturn addr 0x156F90 (<terminate process normally>) +y0:H371264 +=proc_heap:<0.0.0> +371264:t9:A5:state,H3710D8,N,N,H3710F4,P<0.1.0>,H37128C,H3710FC,N +3710FC:t2:H371138,H371140 +371140:lI80|H371194 +371194:lI49|H3711E0 +3711E0:lI48|H371204 +371204:lI66|N +371138:lI79|H37118C +37118C:lI84|H3711D8 +3711D8:lI80|H3711FC +3711FC:lI32|H37120C +37120C:lI32|H371214 +371214:lI65|H37121C +37121C:lI80|H371224 +371224:lI78|H37122C +37122C:lI32|H371234 +371234:lI49|H37123C +37123C:lI56|H371244 +371244:lI49|H37124C +37124C:lI32|H371254 +371254:lI48|H37125C +37125C:lI49|N +37128C:t2:A7:started,A7:started +3710F4:lH371124|H371130 +371124:t2:A16:application_controller,P<0.5.0> +371130:lH371178|H371184 +371178:t2:AC:error_logger,P<0.4.0> +371184:lH3711CC|N +3711CC:t2:AF:erl_prim_loader,P<0.2.0> +3710D8:lH3710E0|H3710EC +3710E0:t2:A5:-root,H371108 +371108:lH371148|N +371148:Yh13:2F636C656172636173652F6F74702F65727473 +3710EC:lH371110|H37111C +371110:t2:A9:-progname,H371164 +371164:lH37119C|N +37119C:Yh1D:2F636C656172636173652F6F74702F657274732F62696E2F6365726C20 +37111C:lH37116C|N +37116C:t2:A5:-home,H3711C4 +3711C4:lH3711E8|N +3711E8:YhA:2F686F6D652F73697269 +=proc_stack:<0.2.0> +38eca8:SReturn addr 0x156F90 (<terminate process normally>) +y0:H367D20 +y1:P<0.1.0> +y2:H367D28 +y3:A8:infinity +=proc_heap:<0.2.0> +367D20:lH367D48|H367D50 +367D48:lI47|H367D58 +367D58:lI99|H367D68 +367D68:lI108|H367D78 +367D78:lI101|H367D88 +367D88:lI97|H367D98 +367D98:lI114|H367DA8 +367DA8:lI99|H367DB8 +367DB8:lI97|H367DC8 +367DC8:lI115|H367DD8 +367DD8:lI101|H367DE8 +367DE8:lI47|H367DF8 +367DF8:lI111|H367E08 +367E08:lI116|H367E18 +367E18:lI112|H367E28 +367E28:lI47|H367E38 +367E38:lI101|H367E48 +367E48:lI114|H367E58 +367E58:lI116|H367E68 +367E68:lI115|H367E78 +367E78:lI47|H367E88 +367E88:lI108|H367E98 +367E98:lI105|H367EA8 +367EA8:lI98|H367EB8 +367EB8:lI47|H367EC8 +367EC8:lI107|H367ED8 +367ED8:lI101|H367EE8 +367EE8:lI114|H367EF8 +367EF8:lI110|H367F08 +367F08:lI101|H367F18 +367F18:lI108|H367F28 +367F28:lI47|H367F38 +367F38:lI101|H367F48 +367F48:lI98|H367F58 +367F58:lI105|H367F68 +367F68:lI110|N +367D50:lH367D60|N +367D60:lI47|H367D70 +367D70:lI99|H367D80 +367D80:lI108|H367D90 +367D90:lI101|H367DA0 +367DA0:lI97|H367DB0 +367DB0:lI114|H367DC0 +367DC0:lI99|H367DD0 +367DD0:lI97|H367DE0 +367DE0:lI115|H367DF0 +367DF0:lI101|H367E00 +367E00:lI47|H367E10 +367E10:lI111|H367E20 +367E20:lI116|H367E30 +367E30:lI112|H367E40 +367E40:lI47|H367E50 +367E50:lI101|H367E60 +367E60:lI114|H367E70 +367E70:lI116|H367E80 +367E80:lI115|H367E90 +367E90:lI47|H367EA0 +367EA0:lI108|H367EB0 +367EB0:lI105|H367EC0 +367EC0:lI98|H367ED0 +367ED0:lI47|H367EE0 +367EE0:lI115|H367EF0 +367EF0:lI116|H367F00 +367F00:lI100|H367F10 +367F10:lI108|H367F20 +367F20:lI105|H367F30 +367F30:lI98|H367F40 +367F40:lI47|H367F50 +367F50:lI101|H367F60 +367F60:lI98|H367F70 +367F70:lI105|H367F78 +367F78:lI110|N +367D28:t7:A5:state,A5:efile,N,A4:none,p<0.2>,A8:infinity,A5:false +=proc_dictionary:<0.4.0> +H3AC588 +H3AC594 +=proc_stack:<0.4.0> +3b2f14:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:H3B21E8 +y2:AC:error_logger +y3:P<0.1.0> +3b2f28:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H3AC5A8 +=proc_heap:<0.4.0> +3B21E8:lH3B2144|H3B21E0 +3B2144:t5:A7:handler,AC:error_logger,A5:false,N,A5:false +3B21E0:lH3B21BC|N +3B21BC:t5:A7:handler,A12:error_logger_tty_h,A5:false,H3AC610,A5:false +3AC610:t2:P<0.21.0>,AC:error_logger +3AC5A8:lA9:gen_event|H3AC5E8 +3AC5E8:lP<0.1.0>|H3AC608 +3AC608:lP<0.1.0>|H3AC61C +3AC61C:lH3AC624|H3AC630 +3AC624:t2:A5:local,AC:error_logger +3AC630:lN|H3AC638 +3AC638:lN|H3AC640 +3AC640:lN|N +3AC588:t2:AD:$initial_call,H3AC5B0 +3AC5B0:t3:A3:gen,A7:init_it,H3AC5A8 +3AC594:t2:AA:$ancestors,H3AC5C0 +3AC5C0:lP<0.1.0>|N +=proc_dictionary:<0.5.0> +H372E4C +H372E58 +=proc_stack:<0.5.0> +374704:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A16:application_controller +y3:H3739F4 +y4:A16:application_controller +y5:P<0.1.0> +374720:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H372ED0 +=proc_heap:<0.5.0> +3739F4:t9:A5:state,N,N,N,H373914,N,H373928,N,N +373928:lH37391C|H372F54 +37391C:t2:A6:stdlib,A9:permanent +372F54:lH372F90|N +372F90:t2:A6:kernel,A9:permanent +373914:lH373908|H372F4C +373908:t2:A6:stdlib,A9:undefined +372F4C:lH372F84|N +372F84:t2:A6:kernel,P<0.7.0> +372ED0:lAA:gen_server|H372F5C +372F5C:lP<0.1.0>|H372F9C +372F9C:lP<0.1.0>|H372FC4 +372FC4:lH372FEC|H372FF8 +372FEC:t2:A5:local,A16:application_controller +372FF8:lA16:application_controller|H373018 +373018:lH373038|H373048 +373038:t3:AB:application,A6:kernel,H373060 +373060:lH373078|H373084 +373078:t2:AB:description,H37309C +37309C:lI69|H3730C8 +3730C8:lI82|H3730FC +3730FC:lI84|H373130 +373130:lI83|H37316C +37316C:lI32|H3731A8 +3731A8:lI32|H3731E4 +3731E4:lI67|H373220 +373220:lI88|H37325C +37325C:lI67|H37329C +37329C:lI32|H3732D0 +3732D0:lI49|H3732FC +3732FC:lI51|H373328 +373328:lI56|H373348 +373348:lI32|H373368 +373368:lI49|H373388 +373388:lI48|N +373084:lH3730A4|H3730B0 +3730A4:t2:A3:vsn,H3730D0 +3730D0:lI50|H373104 +373104:lI46|H373138 +373138:lI57|N +3730B0:lH3730D8|H3730E4 +3730D8:t2:A2:id,N +3730E4:lH37310C|H373118 +37310C:t2:A7:modules,H373140 +373140:lAB:application|H373174 +373174:lA16:application_controller|H3731B0 +3731B0:lA12:application_master|H3731EC +3731EC:lA13:application_starter|H373228 +373228:lA4:auth|H373264 +373264:lA4:code|H3732A4 +3732A4:lA8:code_aux|H3732D8 +3732D8:lA8:packages|H373304 +373304:lAB:code_server|H373330 +373330:lA9:dist_util|H373350 +373350:lAF:erl_boot_server|H373370 +373370:lA10:erl_distribution|H373390 +373390:lAF:erl_prim_loader|H3733A8 +3733A8:lA9:erl_reply|H3733C0 +3733C0:lA6:erlang|H3733D8 +3733D8:lAD:error_handler|H3733F0 +3733F0:lAC:error_logger|H373408 +373408:lA4:file|H373420 +373420:lAB:file_server|H373438 +373438:lAF:old_file_server|H373450 +373450:lAE:file_io_server|H373468 +373468:lA9:prim_file|H373480 +373480:lA6:global|H373498 +373498:lAC:global_group|H3734B0 +3734B0:lAD:global_search|H3734C8 +3734C8:lA5:group|H3734E0 +3734E0:lA5:heart|H3734F8 +3734F8:lA13:hipe_unified_loader|H373510 +373510:lA11:hipe_sparc_loader|H373520 +373520:lAF:hipe_x86_loader|H373530 +373530:lA9:inet6_tcp|H373540 +373540:lAE:inet6_tcp_dist|H373550 +373550:lA9:inet6_udp|H373560 +373560:lAB:inet_config|H373570 +373570:lAA:inet_hosts|H373580 +373580:lA13:inet_gethost_native|H373590 +373590:lAD:inet_tcp_dist|H3735A0 +3735A0:lA4:init|H3735B0 +3735B0:lA6:kernel|H3735C0 +3735C0:lAD:kernel_config|H3735D0 +3735D0:lA3:net|H3735E0 +3735E0:lA7:net_adm|H3735F0 +3735F0:lAA:net_kernel|H373600 +373600:lA2:os|H373610 +373610:lA8:ram_file|H373620 +373620:lA3:rpc|H373630 +373630:lA4:user|H373640 +373640:lA8:user_drv|H373650 +373650:lA8:user_sup|H373660 +373660:lA8:disk_log|H373670 +373670:lAA:disk_log_1|H373680 +373680:lAF:disk_log_server|H373690 +373690:lAC:disk_log_sup|H3736A0 +3736A0:lA7:dist_ac|H3736B0 +3736B0:lA8:erl_ddll|H3736C0 +3736C0:lA8:erl_epmd|H3736D0 +3736D0:lAA:erts_debug|H3736E0 +3736E0:lA7:gen_tcp|H3736F0 +3736F0:lA7:gen_udp|H373700 +373700:lA9:prim_inet|H373708 +373708:lA4:inet|H373710 +373710:lA7:inet_db|H373718 +373718:lA8:inet_dns|H373720 +373720:lAA:inet_parse|H373728 +373728:lA8:inet_res|H373730 +373730:lA8:inet_tcp|H373738 +373738:lA8:inet_udp|H373740 +373740:lA3:pg2|H373748 +373748:lA9:seq_trace|H373750 +373750:lA6:socks5|H373758 +373758:lAB:socks5_auth|H373760 +373760:lAA:socks5_tcp|H373768 +373768:lAA:socks5_udp|H373770 +373770:lAF:wrap_log_reader|H373778 +373778:lA4:zlib|H373780 +373780:lA9:otp_ring0|N +373118:lH373148|H373154 +373148:t2:AA:registered,H37317C +37317C:lA16:application_controller|H3731B8 +3731B8:lA9:erl_reply|H3731F4 +3731F4:lA4:auth|H373230 +373230:lAB:boot_server|H37326C +37326C:lAB:code_server|H3732AC +3732AC:lAF:disk_log_server|H3732E0 +3732E0:lAC:disk_log_sup|H37330C +37330C:lAF:erl_prim_loader|H373338 +373338:lAC:error_logger|H373358 +373358:lAB:file_server|H373378 +373378:lAD:file_server_2|H373398 +373398:lAF:fixtable_server|H3733B0 +3733B0:lAC:global_group|H3733C8 +3733C8:lA12:global_name_server|H3733E0 +3733E0:lA5:heart|H3733F8 +3733F8:lA4:init|H373410 +373410:lAD:kernel_config|H373428 +373428:lAA:kernel_sup|H373440 +373440:lAA:net_kernel|H373458 +373458:lA7:net_sup|H373470 +373470:lA3:rex|H373488 +373488:lA4:user|H3734A0 +3734A0:lA9:os_server|H3734B8 +3734B8:lAB:ddll_server|H3734D0 +3734D0:lA8:erl_epmd|H3734E8 +3734E8:lA7:inet_db|H373500 +373500:lA3:pg2|N +373154:lH373184|H373190 +373184:t2:AC:applications,N +373190:lH3731C0|H3731CC +3731C0:t2:A15:included_applications,N +3731CC:lH3731FC|H373208 +3731FC:t2:A3:env,H373238 +373238:lH373274|N +373274:t2:AC:error_logger,A3:tty +373208:lH373240|H37324C +373240:t2:AC:start_phases,A9:undefined +37324C:lH373280|H37328C +373280:t2:A4:maxT,A8:infinity +37328C:lH3732B4|H3732C0 +3732B4:t2:A4:maxP,A8:infinity +3732C0:lH3732E8|N +3732E8:t2:A3:mod,H373314 +373314:t2:A6:kernel,N +373048:lN|N +372E4C:t2:AD:$initial_call,H372EE4 +372EE4:t3:A3:gen,A7:init_it,H372ED0 +372E58:t2:AA:$ancestors,H372EF4 +372EF4:lP<0.1.0>|N +=proc_dictionary:<0.7.0> +H369B78 +H369B5C +=proc_stack:<0.7.0> +369d64:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:H369C2C +y1:P<0.5.0> +369d70:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A12:application_master +y2:A4:init +y3:H369B2C +=proc_heap:<0.7.0> +369C2C:t6:A5:state,P<0.8.0>,H3697B0,N,I0,P<0.0.0> +3697B0:t9:A9:appl_data,A6:kernel,H369B14,A9:undefined,H3697D8,H369A3C,N,A8:infinity,A8:infinity +369A3C:lAB:application|H369A34 +369A34:lA16:application_controller|H369A2C +369A2C:lA12:application_master|H369A24 +369A24:lA13:application_starter|H369A1C +369A1C:lA4:auth|H369A14 +369A14:lA4:code|H369A0C +369A0C:lA8:code_aux|H369A04 +369A04:lA8:packages|H3699FC +3699FC:lAB:code_server|H3699F4 +3699F4:lA9:dist_util|H3699EC +3699EC:lAF:erl_boot_server|H3699E4 +3699E4:lA10:erl_distribution|H3699DC +3699DC:lAF:erl_prim_loader|H3699D4 +3699D4:lA9:erl_reply|H3699CC +3699CC:lA6:erlang|H3699C4 +3699C4:lAD:error_handler|H3699BC +3699BC:lAC:error_logger|H3699B4 +3699B4:lA4:file|H3699AC +3699AC:lAB:file_server|H3699A4 +3699A4:lAF:old_file_server|H36999C +36999C:lAE:file_io_server|H369994 +369994:lA9:prim_file|H36998C +36998C:lA6:global|H369984 +369984:lAC:global_group|H36997C +36997C:lAD:global_search|H369974 +369974:lA5:group|H36996C +36996C:lA5:heart|H369964 +369964:lA13:hipe_unified_loader|H36995C +36995C:lA11:hipe_sparc_loader|H369954 +369954:lAF:hipe_x86_loader|H36994C +36994C:lA9:inet6_tcp|H369944 +369944:lAE:inet6_tcp_dist|H36993C +36993C:lA9:inet6_udp|H369934 +369934:lAB:inet_config|H36992C +36992C:lAA:inet_hosts|H369924 +369924:lA13:inet_gethost_native|H36991C +36991C:lAD:inet_tcp_dist|H369914 +369914:lA4:init|H36990C +36990C:lA6:kernel|H369904 +369904:lAD:kernel_config|H3698FC +3698FC:lA3:net|H3698F4 +3698F4:lA7:net_adm|H3698EC +3698EC:lAA:net_kernel|H3698E4 +3698E4:lA2:os|H3698DC +3698DC:lA8:ram_file|H3698D4 +3698D4:lA3:rpc|H3698CC +3698CC:lA4:user|H3698C4 +3698C4:lA8:user_drv|H3698BC +3698BC:lA8:user_sup|H3698B4 +3698B4:lA8:disk_log|H3698AC +3698AC:lAA:disk_log_1|H3698A4 +3698A4:lAF:disk_log_server|H36989C +36989C:lAC:disk_log_sup|H369894 +369894:lA7:dist_ac|H36988C +36988C:lA8:erl_ddll|H369884 +369884:lA8:erl_epmd|H36987C +36987C:lAA:erts_debug|H369874 +369874:lA7:gen_tcp|H36986C +36986C:lA7:gen_udp|H369864 +369864:lA9:prim_inet|H36985C +36985C:lA4:inet|H369854 +369854:lA7:inet_db|H36984C +36984C:lA8:inet_dns|H369844 +369844:lAA:inet_parse|H36983C +36983C:lA8:inet_res|H369834 +369834:lA8:inet_tcp|H36982C +36982C:lA8:inet_udp|H369824 +369824:lA3:pg2|H36981C +36981C:lA9:seq_trace|H369814 +369814:lA6:socks5|H36980C +36980C:lAB:socks5_auth|H369804 +369804:lAA:socks5_tcp|H3697FC +3697FC:lAA:socks5_udp|H3697F4 +3697F4:lAF:wrap_log_reader|H3697EC +3697EC:lA4:zlib|H3697E4 +3697E4:lA9:otp_ring0|N +3697D8:t2:A6:kernel,N +369B14:lA16:application_controller|H369B0C +369B0C:lA9:erl_reply|H369B04 +369B04:lA4:auth|H369AFC +369AFC:lAB:boot_server|H369AF4 +369AF4:lAB:code_server|H369AEC +369AEC:lAF:disk_log_server|H369AE4 +369AE4:lAC:disk_log_sup|H369ADC +369ADC:lAF:erl_prim_loader|H369AD4 +369AD4:lAC:error_logger|H369ACC +369ACC:lAB:file_server|H369AC4 +369AC4:lAD:file_server_2|H369ABC +369ABC:lAF:fixtable_server|H369AB4 +369AB4:lAC:global_group|H369AAC +369AAC:lA12:global_name_server|H369AA4 +369AA4:lA5:heart|H369A9C +369A9C:lA4:init|H369A94 +369A94:lAD:kernel_config|H369A8C +369A8C:lAA:kernel_sup|H369A84 +369A84:lAA:net_kernel|H369A7C +369A7C:lA7:net_sup|H369A74 +369A74:lA3:rex|H369A6C +369A6C:lA4:user|H369A64 +369A64:lA9:os_server|H369A5C +369A5C:lAB:ddll_server|H369A54 +369A54:lA8:erl_epmd|H369A4C +369A4C:lA7:inet_db|H369A44 +369A44:lA3:pg2|N +369B2C:lP<0.5.0>|H369B24 +369B24:lP<0.6.0>|H3697A8 +3697A8:lH3697B0|H369B1C +369B1C:lA6:normal|N +369B78:t2:AD:$initial_call,H369B68 +369B68:t3:A12:application_master,A4:init,H369B2C +369B5C:t2:AA:$ancestors,H369B54 +369B54:lP<0.6.0>|N +=proc_stack:<0.8.0> +384ec0:SReturn addr 0x156F90 (<terminate process normally>) +y0:H384BDC +y1:A6:kernel +y2:P<0.9.0> +y3:P<0.7.0> +=proc_heap:<0.8.0> +384BDC:t2:A5:state,A3:tty +=proc_dictionary:<0.9.0> +H376850 +H37685C +=proc_stack:<0.9.0> +36bde8:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AA:supervisor +y3:H36B8E8 +y4:AA:kernel_sup +y5:P<0.8.0> +36be04:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H3768D4 +=proc_heap:<0.9.0> +36B8E8:tA:A5:state,H376868,AB:one_for_all,H36B8D4,N,I0,I1,N,A6:kernel,N +36B8D4:lH36B8B0|H36B6E8 +36B8B0:t8:A5:child,P<0.24.0>,AF:kernel_safe_sup,H376BF0,A9:permanent,A8:infinity,AA:supervisor,H376C00 +376C00:lA6:kernel|N +376BF0:t3:AA:supervisor,AA:start_link,H376C08 +376C08:lH376C10|H376C1C +376C10:t2:A5:local,AF:kernel_safe_sup +376C1C:lA6:kernel|H376C24 +376C24:lA4:safe|N +36B6E8:lH36B6C4|H36B490 +36B6C4:t8:A5:child,P<0.23.0>,AD:kernel_config,H376BB4,A9:permanent,I2000,A6:worker,H376BC4 +376BC4:lAD:kernel_config|N +376BB4:t3:AD:kernel_config,AA:start_link,N +36B490:lH36B498|H36B4BC +36B498:t8:A5:child,P<0.19.0>,A4:user,H376B70,A9:temporary,I2000,AA:supervisor,H376B80 +376B80:lA8:user_sup|N +376B70:t3:A8:user_sup,A5:start,N +36B4BC:lH36B4C4|H376CB0 +36B4C4:t8:A5:child,P<0.18.0>,AB:code_server,H376B0C,A9:permanent,I2000,A6:worker,H376B1C +376B1C:lA4:code|N +376B0C:t3:A4:code,AA:start_link,N +376CB0:lH376CB8|H376CDC +376CB8:t8:A5:child,P<0.17.0>,AB:file_server,H376AB8,A9:permanent,I2000,A6:worker,H376AC8 +376AC8:lAF:old_file_server|N +376AB8:t3:AF:old_file_server,AA:start_link,N +376CDC:lH376CE4|H376C2C +376CE4:t8:A5:child,P<0.16.0>,AD:file_server_2,H376A58,A9:permanent,I2000,A6:worker,H376A68 +376A68:lA4:file|H376AB0 +376AB0:lAB:file_server|H376B04 +376B04:lAE:file_io_server|H376B68 +376B68:lA9:prim_file|N +376A58:t3:AB:file_server,AA:start_link,N +376C2C:lH376C34|H376C58 +376C34:t8:A5:child,P<0.15.0>,AC:global_group,H3769F4,A9:permanent,I2000,A6:worker,H376A04 +376A04:lAC:global_group|N +3769F4:t3:AC:global_group,AA:start_link,N +376C58:lH376C60|H376C84 +376C60:t8:A5:child,A9:undefined,A7:net_sup,H37696C,A9:permanent,A8:infinity,AA:supervisor,H37697C +37697C:lA10:erl_distribution|N +37696C:t3:A10:erl_distribution,AA:start_link,N +376C84:lH376C8C|H3768A0 +376C8C:t8:A5:child,P<0.14.0>,A7:inet_db,H3768F4,A9:permanent,I2000,A6:worker,H376904 +376904:lA7:inet_db|N +3768F4:t3:A7:inet_db,AA:start_link,N +3768A0:lH376938|H37695C +376938:t8:A5:child,P<0.11.0>,A12:global_name_server,H3769B0,A9:permanent,I2000,A6:worker,H3769C0 +3769C0:lA6:global|N +3769B0:t3:A6:global,AA:start_link,N +37695C:lH3769C8|N +3769C8:t8:A5:child,P<0.10.0>,A3:rex,H376A38,A9:permanent,I2000,A6:worker,H376A48 +376A48:lA3:rpc|N +376A38:t3:A3:rpc,AA:start_link,N +376868:t2:A5:local,AA:kernel_sup +3768D4:lAA:gen_server|H376964 +376964:lP<0.8.0>|H3769EC +3769EC:lP<0.8.0>|H376A50 +376A50:lH376A9C|H376AA8 +376A9C:t2:A5:local,AA:kernel_sup +376AA8:lAA:supervisor|H376AFC +376AFC:lH376B50|H376B60 +376B50:t3:H376868,A6:kernel,N +376B60:lN|N +376850:t2:AD:$initial_call,H3768DC +3768DC:t3:A3:gen,A7:init_it,H3768D4 +37685C:t2:AA:$ancestors,H3768EC +3768EC:lP<0.8.0>|N +=proc_dictionary:<0.10.0> +H367A10 +H3679F4 +=proc_stack:<0.10.0> +367cec:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A3:rpc +y3:H367AA8 +y4:A3:rex +y5:P<0.9.0> +367d08:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H3679C4 +=proc_heap:<0.10.0> +367AA8:t2:I0,A3:nil +3679C4:lAA:gen_server|H3679BC +3679BC:lP<0.9.0>|H3679B4 +3679B4:lP<0.9.0>|H367988 +367988:lH367990|H3679AC +367990:t2:A5:local,A3:rex +3679AC:lA3:rpc|H3679A4 +3679A4:lN|H36799C +36799C:lN|N +367A10:t2:AD:$initial_call,H367A00 +367A00:t3:A3:gen,A7:init_it,H3679C4 +3679F4:t2:AA:$ancestors,H3679EC +3679EC:lAA:kernel_sup|H3679CC +3679CC:lP<0.8.0>|N +=proc_dictionary:<0.11.0> +H36ADD8 +H36ADBC +=proc_stack:<0.11.0> +36b0b4:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A6:global +y3:H36AF0C +y4:A12:global_name_server +y5:P<0.9.0> +36b0d0:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H36AD8C +=proc_heap:<0.11.0> +36AF0C:t9:A5:state,A4:true,N,N,N,N,AD:nonode@nohost,P<0.12.0>,P<0.13.0> +36AD8C:lAA:gen_server|H36AD84 +36AD84:lP<0.9.0>|H36AD7C +36AD7C:lP<0.9.0>|H36AD50 +36AD50:lH36AD58|H36AD74 +36AD58:t2:A5:local,A12:global_name_server +36AD74:lA6:global|H36AD6C +36AD6C:lN|H36AD64 +36AD64:lN|N +36ADD8:t2:AD:$initial_call,H36ADC8 +36ADC8:t3:A3:gen,A7:init_it,H36AD8C +36ADBC:t2:AA:$ancestors,H36ADB4 +36ADB4:lAA:kernel_sup|H36AD94 +36AD94:lP<0.8.0>|N +=proc_stack:<0.12.0> +36921c:SReturn addr 0x261184 (global:init_the_locker/1 + 112) +y0:N +y1:N +y2:N +y3:N +y4:N +y5:N +y6:A8:infinity +y7:H368EB0 +y8:P<0.11.0> +369244:SReturn addr 0x156F90 (<terminate process normally>) +y0:N +=proc_heap:<0.12.0> +368EB0:t3:A5:multi,A9:undefined,N +=proc_stack:<0.13.0> +3695d0:SReturn addr 0x2651AC (global:loop_the_deleter/1 + 36) +y0:A8:infinity +y1:N +y2:P<0.11.0> +3695e0:SReturn addr 0x2654F8 (global:'-start_the_deleter/1-fun-0-'/1 + 20) +y0:N +y1:N +y2:P<0.11.0> +3695f0:SReturn addr 0x156F90 (<terminate process normally>) +=proc_heap:<0.13.0> +=proc_dictionary:<0.14.0> +H36A998 +H36A9A4 +=proc_stack:<0.14.0> +372e0c:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A7:inet_db +y3:H36A9B0 +y4:A7:inet_db +y5:P<0.9.0> +372e28:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H36A9C8 +=proc_heap:<0.14.0> +36A9B0:t5:A5:state,A7:inet_db,AA:inet_cache,AA:inet_hosts,H36A9E8 +36A9E8:E21:8372000364000D6E6F6E6F6465406E6F686F737400000000060000000000000000 +36A9C8:lAA:gen_server|H36A9F8 +36A9F8:lP<0.9.0>|H36AA08 +36AA08:lP<0.9.0>|H36AA10 +36AA10:lH36AA18|H36AA24 +36AA18:t2:A5:local,A7:inet_db +36AA24:lA7:inet_db|H36AA2C +36AA2C:lN|H36AA34 +36AA34:lN|N +36A998:t2:AD:$initial_call,H36A9D0 +36A9D0:t3:A3:gen,A7:init_it,H36A9C8 +36A9A4:t2:AA:$ancestors,H36A9E0 +36A9E0:lAA:kernel_sup|H36AA00 +36AA00:lP<0.8.0>|N +=proc_dictionary:<0.15.0> +H372788 +H3727F8 +H37276C +H37280C +H372820 +=proc_stack:<0.15.0> +372a64:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AC:global_group +y3:H3728C8 +y4:AC:global_group +y5:P<0.9.0> +372a80:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H37273C +=proc_heap:<0.15.0> +3728C8:tC:A5:state,A7:no_conf,A4:true,N,N,N,N,N,AD:nonode@nohost,N,A6:normal,A6:normal +37273C:lAA:gen_server|H372734 +372734:lP<0.9.0>|H37272C +37272C:lP<0.9.0>|H372700 +372700:lH372708|H372724 +372708:t2:A5:local,AC:global_group +372724:lAC:global_group|H37271C +37271C:lN|H372714 +372714:lN|N +372788:t2:AD:$initial_call,H372778 +372778:t3:A3:gen,A7:init_it,H37273C +3727F8:t2:A10:registered_names,H3727F0 +3727F0:lA9:undefined|N +37276C:t2:AA:$ancestors,H372764 +372764:lAA:kernel_sup|H372744 +372744:lP<0.8.0>|N +37280C:t2:A4:send,H372804 +372804:lA9:undefined|N +372820:t2:AC:whereis_name,H372818 +372818:lA9:undefined|N +=proc_dictionary:<0.16.0> +H37B918 +H37B924 +=proc_stack:<0.16.0> +3d303c:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AB:file_server +y3:p<0.4> +y4:AD:file_server_2 +y5:P<0.9.0> +3d3058:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H37B930 +=proc_heap:<0.16.0> +37B930:lAA:gen_server|H37B950 +37B950:lP<0.9.0>|H37B960 +37B960:lP<0.9.0>|H37B968 +37B968:lH37B970|H37B97C +37B970:t2:A5:local,AD:file_server_2 +37B97C:lAB:file_server|H37B984 +37B984:lN|H37B98C +37B98C:lN|N +37B918:t2:AD:$initial_call,H37B938 +37B938:t3:A3:gen,A7:init_it,H37B930 +37B924:t2:AA:$ancestors,H37B948 +37B948:lAA:kernel_sup|H37B958 +37B958:lP<0.8.0>|N +=proc_stack:<0.17.0> +3763cc:SReturn addr 0x156F90 (<terminate process normally>) +y0:H376084 +y1:P<0.16.0> +y2:P<0.9.0> +=proc_heap:<0.17.0> +376084:E21:8372000364000D6E6F6E6F6465406E6F686F737400000000160000000000000000 +=proc_stack:<0.18.0> +3b98e8:SReturn addr 0x156F90 (<terminate process normally>) +y0:H38AE84 +y1:P<0.9.0> +=proc_heap:<0.18.0> +38AE84:t8:A5:state,P<0.9.0>,H3873BC,H38AEB8,I9,I10,A8:no_cache,AB:interactive +38AEB8:lH3873D4|H38AEE0 +3873D4:lI46|N +38AEE0:lH3873EC|H38AF10 +3873EC:lI47|H387404 +387404:lI99|H387424 +387424:lI108|H38744C +38744C:lI101|H38747C +38747C:lI97|H3874B4 +3874B4:lI114|H3874F4 +3874F4:lI99|H38753C +38753C:lI97|H38758C +38758C:lI115|H3875E4 +3875E4:lI101|H387644 +387644:lI47|H3876AC +3876AC:lI111|H38771C +38771C:lI116|H387794 +387794:lI112|H387814 +387814:lI47|H38789C +38789C:lI101|H38792C +38792C:lI114|H3879BC +3879BC:lI116|H387A54 +387A54:lI115|H387AF4 +387AF4:lI47|H387B9C +387B9C:lI108|H387C4C +387C4C:lI105|H387D04 +387D04:lI98|H387DC4 +387DC4:lI47|H387E8C +387E8C:lI107|H387F5C +387F5C:lI101|H388034 +388034:lI114|H388114 +388114:lI110|H3881FC +3881FC:lI101|H3882EC +3882EC:lI108|H3883E4 +3883E4:lI47|H3884E4 +3884E4:lI101|H3885EC +3885EC:lI98|H3886FC +3886FC:lI105|H388814 +388814:lI110|N +38AF10:lH38740C|H38AF48 +38740C:lI47|H38742C +38742C:lI99|H387454 +387454:lI108|H387484 +387484:lI101|H3874BC +3874BC:lI97|H3874FC +3874FC:lI114|H387544 +387544:lI99|H387594 +387594:lI97|H3875EC +3875EC:lI115|H38764C +38764C:lI101|H3876B4 +3876B4:lI47|H387724 +387724:lI111|H38779C +38779C:lI116|H38781C +38781C:lI112|H3878A4 +3878A4:lI47|H387934 +387934:lI101|H3879C4 +3879C4:lI114|H387A5C +387A5C:lI116|H387AFC +387AFC:lI115|H387BA4 +387BA4:lI47|H387C54 +387C54:lI108|H387D0C +387D0C:lI105|H387DCC +387DCC:lI98|H387E94 +387E94:lI47|H387F64 +387F64:lI115|H38803C +38803C:lI116|H38811C +38811C:lI100|H388204 +388204:lI108|H3882F4 +3882F4:lI105|H3883EC +3883EC:lI98|H3884EC +3884EC:lI47|H3885F4 +3885F4:lI101|H388704 +388704:lI98|H38881C +38881C:lI105|H38892C +38892C:lI110|N +38AF48:lH387434|H38AF70 +387434:lI47|H38745C +38745C:lI99|H38748C +38748C:lI108|H3874C4 +3874C4:lI101|H387504 +387504:lI97|H38754C +38754C:lI114|H38759C +38759C:lI99|H3875F4 +3875F4:lI97|H387654 +387654:lI115|H3876BC +3876BC:lI101|H38772C +38772C:lI47|H3877A4 +3877A4:lI111|H387824 +387824:lI116|H3878AC +3878AC:lI112|H38793C +38793C:lI47|H3879CC +3879CC:lI101|H387A64 +387A64:lI114|H387B04 +387B04:lI116|H387BAC +387BAC:lI115|H387C5C +387C5C:lI47|H387D14 +387D14:lI108|H387DD4 +387DD4:lI105|H387E9C +387E9C:lI98|H387F6C +387F6C:lI47|H388044 +388044:lI119|H388124 +388124:lI101|H38820C +38820C:lI98|H3882FC +3882FC:lI116|H3883F4 +3883F4:lI111|H3884F4 +3884F4:lI111|H3885FC +3885FC:lI108|H38870C +38870C:lI47|H388824 +388824:lI101|H388934 +388934:lI98|H388A44 +388A44:lI105|H388B54 +388B54:lI110|N +38AF70:lH387464|H38AF98 +387464:lI47|H387494 +387494:lI99|H3874CC +3874CC:lI108|H38750C +38750C:lI101|H387554 +387554:lI97|H3875A4 +3875A4:lI114|H3875FC +3875FC:lI99|H38765C +38765C:lI97|H3876C4 +3876C4:lI115|H387734 +387734:lI101|H3877AC +3877AC:lI47|H38782C +38782C:lI111|H3878B4 +3878B4:lI116|H387944 +387944:lI112|H3879D4 +3879D4:lI47|H387A6C +387A6C:lI101|H387B0C +387B0C:lI114|H387BB4 +387BB4:lI116|H387C64 +387C64:lI115|H387D1C +387D1C:lI47|H387DDC +387DDC:lI108|H387EA4 +387EA4:lI105|H387F74 +387F74:lI98|H38804C +38804C:lI47|H38812C +38812C:lI116|H388214 +388214:lI118|H388304 +388304:lI47|H3883FC +3883FC:lI101|H3884FC +3884FC:lI98|H388604 +388604:lI105|H388714 +388714:lI110|N +38AF98:lH38749C|H38AFC0 +38749C:lI47|H3874D4 +3874D4:lI99|H387514 +387514:lI108|H38755C +38755C:lI101|H3875AC +3875AC:lI97|H387604 +387604:lI114|H387664 +387664:lI99|H3876CC +3876CC:lI97|H38773C +38773C:lI115|H3877B4 +3877B4:lI101|H387834 +387834:lI47|H3878BC +3878BC:lI111|H38794C +38794C:lI116|H3879DC +3879DC:lI112|H387A74 +387A74:lI47|H387B14 +387B14:lI101|H387BBC +387BBC:lI114|H387C6C +387C6C:lI116|H387D24 +387D24:lI115|H387DE4 +387DE4:lI47|H387EAC +387EAC:lI108|H387F7C +387F7C:lI105|H388054 +388054:lI98|H388134 +388134:lI47|H38821C +38821C:lI116|H38830C +38830C:lI115|H388404 +388404:lI112|H388504 +388504:lI47|H38860C +38860C:lI101|H38871C +38871C:lI98|H38882C +38882C:lI105|H38893C +38893C:lI110|N +38AFC0:lH3874DC|H38AFE8 +3874DC:lI47|H38751C +38751C:lI99|H387564 +387564:lI108|H3875B4 +3875B4:lI101|H38760C +38760C:lI97|H38766C +38766C:lI114|H3876D4 +3876D4:lI99|H387744 +387744:lI97|H3877BC +3877BC:lI115|H38783C +38783C:lI101|H3878C4 +3878C4:lI47|H387954 +387954:lI111|H3879E4 +3879E4:lI116|H387A7C +387A7C:lI112|H387B1C +387B1C:lI47|H387BC4 +387BC4:lI101|H387C74 +387C74:lI114|H387D2C +387D2C:lI116|H387DEC +387DEC:lI115|H387EB4 +387EB4:lI47|H387F84 +387F84:lI108|H38805C +38805C:lI105|H38813C +38813C:lI98|H388224 +388224:lI47|H388314 +388314:lI116|H38840C +38840C:lI111|H38850C +38850C:lI111|H388614 +388614:lI108|H388724 +388724:lI115|H388834 +388834:lI47|H388944 +388944:lI101|H388A4C +388A4C:lI98|H388B5C +388B5C:lI105|H388C6C +388C6C:lI110|N +38AFE8:lH387524|H38B008 +387524:lI47|H38756C +38756C:lI99|H3875BC +3875BC:lI108|H387614 +387614:lI101|H387674 +387674:lI97|H3876DC +3876DC:lI114|H38774C +38774C:lI99|H3877C4 +3877C4:lI97|H387844 +387844:lI115|H3878CC +3878CC:lI101|H38795C +38795C:lI47|H3879EC +3879EC:lI111|H387A84 +387A84:lI116|H387B24 +387B24:lI112|H387BCC +387BCC:lI47|H387C7C +387C7C:lI101|H387D34 +387D34:lI114|H387DF4 +387DF4:lI116|H387EBC +387EBC:lI115|H387F8C +387F8C:lI47|H388064 +388064:lI108|H388144 +388144:lI105|H38822C +38822C:lI98|H38831C +38831C:lI47|H388414 +388414:lI116|H388514 +388514:lI111|H38861C +38861C:lI111|H38872C +38872C:lI108|H38883C +38883C:lI98|H38894C +38894C:lI97|H388A54 +388A54:lI114|H388B64 +388B64:lI47|H388C74 +388C74:lI101|H388D84 +388D84:lI98|H388E9C +388E9C:lI105|H388FB4 +388FB4:lI110|N +38B008:lH387574|H38B018 +387574:lI47|H3875C4 +3875C4:lI99|H38761C +38761C:lI108|H38767C +38767C:lI101|H3876E4 +3876E4:lI97|H387754 +387754:lI114|H3877CC +3877CC:lI99|H38784C +38784C:lI97|H3878D4 +3878D4:lI115|H387964 +387964:lI101|H3879F4 +3879F4:lI47|H387A8C +387A8C:lI111|H387B2C +387B2C:lI116|H387BD4 +387BD4:lI112|H387C84 +387C84:lI47|H387D3C +387D3C:lI101|H387DFC +387DFC:lI114|H387EC4 +387EC4:lI116|H387F94 +387F94:lI115|H38806C +38806C:lI47|H38814C +38814C:lI108|H388234 +388234:lI105|H388324 +388324:lI98|H38841C +38841C:lI47|H38851C +38851C:lI116|H388624 +388624:lI101|H388734 +388734:lI115|H388844 +388844:lI116|H388954 +388954:lI95|H388A5C +388A5C:lI115|H388B6C +388B6C:lI101|H388C7C +388C7C:lI114|H388D8C +388D8C:lI118|H388EA4 +388EA4:lI101|H388FBC +388FBC:lI114|H3890D4 +3890D4:lI47|H3891EC +3891EC:lI101|H3892FC +3892FC:lI98|H38940C +38940C:lI105|H38951C +38951C:lI110|N +38B018:lH3875CC|H38AE7C +3875CC:lI47|H387624 +387624:lI99|H387684 +387684:lI108|H3876EC +3876EC:lI101|H38775C +38775C:lI97|H3877D4 +3877D4:lI114|H387854 +387854:lI99|H3878DC +3878DC:lI97|H38796C +38796C:lI115|H3879FC +3879FC:lI101|H387A94 +387A94:lI47|H387B34 +387B34:lI111|H387BDC +387BDC:lI116|H387C8C +387C8C:lI112|H387D44 +387D44:lI47|H387E04 +387E04:lI101|H387ECC +387ECC:lI114|H387F9C +387F9C:lI116|H388074 +388074:lI115|H388154 +388154:lI47|H38823C +38823C:lI108|H38832C +38832C:lI105|H388424 +388424:lI98|H388524 +388524:lI47|H38862C +38862C:lI115|H38873C +38873C:lI115|H38884C +38884C:lI108|H38895C +38895C:lI47|H388A64 +388A64:lI101|H388B74 +388B74:lI98|H388C84 +388C84:lI105|H388D94 +388D94:lI110|N +38AE7C:lH38762C|H38AEB0 +38762C:lI47|H38768C +38768C:lI99|H3876F4 +3876F4:lI108|H387764 +387764:lI101|H3877DC +3877DC:lI97|H38785C +38785C:lI114|H3878E4 +3878E4:lI99|H387974 +387974:lI97|H387A04 +387A04:lI115|H387A9C +387A9C:lI101|H387B3C +387B3C:lI47|H387BE4 +387BE4:lI111|H387C94 +387C94:lI116|H387D4C +387D4C:lI112|H387E0C +387E0C:lI47|H387ED4 +387ED4:lI101|H387FA4 +387FA4:lI114|H38807C +38807C:lI116|H38815C +38815C:lI115|H388244 +388244:lI47|H388334 +388334:lI108|H38842C +38842C:lI105|H38852C +38852C:lI98|H388634 +388634:lI47|H388744 +388744:lI115|H388854 +388854:lI110|H388964 +388964:lI109|H388A6C +388A6C:lI112|H388B7C +388B7C:lI47|H388C8C +388C8C:lI101|H388D9C +388D9C:lI98|H388EAC +388EAC:lI105|H388FC4 +388FC4:lI110|N +38AEB0:lH387694|H38AED8 +387694:lI47|H3876FC +3876FC:lI99|H38776C +38776C:lI108|H3877E4 +3877E4:lI101|H387864 +387864:lI97|H3878EC +3878EC:lI114|H38797C +38797C:lI99|H387A0C +387A0C:lI97|H387AA4 +387AA4:lI115|H387B44 +387B44:lI101|H387BEC +387BEC:lI47|H387C9C +387C9C:lI111|H387D54 +387D54:lI116|H387E14 +387E14:lI112|H387EDC +387EDC:lI47|H387FAC +387FAC:lI101|H388084 +388084:lI114|H388164 +388164:lI116|H38824C +38824C:lI115|H38833C +38833C:lI47|H388434 +388434:lI108|H388534 +388534:lI105|H38863C +38863C:lI98|H38874C +38874C:lI47|H38885C +38885C:lI115|H38896C +38896C:lI97|H388A74 +388A74:lI115|H388B84 +388B84:lI108|H388C94 +388C94:lI47|H388DA4 +388DA4:lI101|H388EB4 +388EB4:lI98|H388FCC +388FCC:lI105|H3890DC +3890DC:lI110|N +38AED8:lH387704|H38AF08 +387704:lI47|H387774 +387774:lI99|H3877EC +3877EC:lI108|H38786C +38786C:lI101|H3878F4 +3878F4:lI97|H387984 +387984:lI114|H387A14 +387A14:lI99|H387AAC +387AAC:lI97|H387B4C +387B4C:lI115|H387BF4 +387BF4:lI101|H387CA4 +387CA4:lI47|H387D5C +387D5C:lI111|H387E1C +387E1C:lI116|H387EE4 +387EE4:lI112|H387FB4 +387FB4:lI47|H38808C +38808C:lI101|H38816C +38816C:lI114|H388254 +388254:lI116|H388344 +388344:lI115|H38843C +38843C:lI47|H38853C +38853C:lI108|H388644 +388644:lI105|H388754 +388754:lI98|H388864 +388864:lI47|H388974 +388974:lI114|H388A7C +388A7C:lI117|H388B8C +388B8C:lI110|H388C9C +388C9C:lI116|H388DAC +388DAC:lI105|H388EBC +388EBC:lI109|H388FD4 +388FD4:lI101|H3890E4 +3890E4:lI95|H3891F4 +3891F4:lI116|H389304 +389304:lI111|H389414 +389414:lI111|H389524 +389524:lI108|H389624 +389624:lI115|H38971C +38971C:lI47|H389814 +389814:lI101|H38990C +38990C:lI98|H389A04 +389A04:lI105|H389AE4 +389AE4:lI110|N +38AF08:lH38777C|H38AF40 +38777C:lI47|H3877F4 +3877F4:lI99|H387874 +387874:lI108|H3878FC +3878FC:lI101|H38798C +38798C:lI97|H387A1C +387A1C:lI114|H387AB4 +387AB4:lI99|H387B54 +387B54:lI97|H387BFC +387BFC:lI115|H387CAC +387CAC:lI101|H387D64 +387D64:lI47|H387E24 +387E24:lI111|H387EEC +387EEC:lI116|H387FBC +387FBC:lI112|H388094 +388094:lI47|H388174 +388174:lI101|H38825C +38825C:lI114|H38834C +38834C:lI116|H388444 +388444:lI115|H388544 +388544:lI47|H38864C +38864C:lI108|H38875C +38875C:lI105|H38886C +38886C:lI98|H38897C +38897C:lI47|H388A84 +388A84:lI114|H388B94 +388B94:lI115|H388CA4 +388CA4:lI104|H388DB4 +388DB4:lI101|H388EC4 +388EC4:lI108|H388FDC +388FDC:lI108|H3890EC +3890EC:lI47|H3891FC +3891FC:lI101|H38930C +38930C:lI98|H38941C +38941C:lI105|H38952C +38952C:lI110|N +38AF40:lH3877FC|H38AF68 +3877FC:lI47|H38787C +38787C:lI99|H387904 +387904:lI108|H387994 +387994:lI101|H387A24 +387A24:lI97|H387ABC +387ABC:lI114|H387B5C +387B5C:lI99|H387C04 +387C04:lI97|H387CB4 +387CB4:lI115|H387D6C +387D6C:lI101|H387E2C +387E2C:lI47|H387EF4 +387EF4:lI111|H387FC4 +387FC4:lI116|H38809C +38809C:lI112|H38817C +38817C:lI47|H388264 +388264:lI101|H388354 +388354:lI114|H38844C +38844C:lI116|H38854C +38854C:lI115|H388654 +388654:lI47|H388764 +388764:lI108|H388874 +388874:lI105|H388984 +388984:lI98|H388A8C +388A8C:lI47|H388B9C +388B9C:lI112|H388CAC +388CAC:lI109|H388DBC +388DBC:lI97|H388ECC +388ECC:lI110|H388FE4 +388FE4:lI47|H3890F4 +3890F4:lI101|H389204 +389204:lI98|H389314 +389314:lI105|H389424 +389424:lI110|N +38AF68:lH387884|H38AF90 +387884:lI47|H38790C +38790C:lI99|H38799C +38799C:lI108|H387A2C +387A2C:lI101|H387AC4 +387AC4:lI97|H387B64 +387B64:lI114|H387C0C +387C0C:lI99|H387CBC +387CBC:lI97|H387D74 +387D74:lI115|H387E34 +387E34:lI101|H387EFC +387EFC:lI47|H387FCC +387FCC:lI111|H3880A4 +3880A4:lI116|H388184 +388184:lI112|H38826C +38826C:lI47|H38835C +38835C:lI101|H388454 +388454:lI114|H388554 +388554:lI116|H38865C +38865C:lI115|H38876C +38876C:lI47|H38887C +38887C:lI108|H38898C +38898C:lI105|H388A94 +388A94:lI98|H388BA4 +388BA4:lI47|H388CB4 +388CB4:lI112|H388DC4 +388DC4:lI97|H388ED4 +388ED4:lI114|H388FEC +388FEC:lI115|H3890FC +3890FC:lI101|H38920C +38920C:lI116|H38931C +38931C:lI111|H38942C +38942C:lI111|H389534 +389534:lI108|H38962C +38962C:lI115|H389724 +389724:lI47|H38981C +38981C:lI101|H389914 +389914:lI98|H389A0C +389A0C:lI105|H389AEC +389AEC:lI110|N +38AF90:lH387914|H38AFB8 +387914:lI47|H3879A4 +3879A4:lI99|H387A34 +387A34:lI108|H387ACC +387ACC:lI101|H387B6C +387B6C:lI97|H387C14 +387C14:lI114|H387CC4 +387CC4:lI99|H387D7C +387D7C:lI97|H387E3C +387E3C:lI115|H387F04 +387F04:lI101|H387FD4 +387FD4:lI47|H3880AC +3880AC:lI111|H38818C +38818C:lI116|H388274 +388274:lI112|H388364 +388364:lI47|H38845C +38845C:lI101|H38855C +38855C:lI114|H388664 +388664:lI116|H388774 +388774:lI115|H388884 +388884:lI47|H388994 +388994:lI108|H388A9C +388A9C:lI105|H388BAC +388BAC:lI98|H388CBC +388CBC:lI47|H388DCC +388DCC:lI111|H388EDC +388EDC:lI116|H388FF4 +388FF4:lI112|H389104 +389104:lI95|H389214 +389214:lI109|H389324 +389324:lI105|H389434 +389434:lI98|H38953C +38953C:lI115|H389634 +389634:lI47|H38972C +38972C:lI101|H389824 +389824:lI98|H38991C +38991C:lI105|H389A14 +389A14:lI110|N +38AFB8:lH3879AC|H38AFE0 +3879AC:lI47|H387A3C +387A3C:lI99|H387AD4 +387AD4:lI108|H387B74 +387B74:lI101|H387C1C +387C1C:lI97|H387CCC +387CCC:lI114|H387D84 +387D84:lI99|H387E44 +387E44:lI97|H387F0C +387F0C:lI115|H387FDC +387FDC:lI101|H3880B4 +3880B4:lI47|H388194 +388194:lI111|H38827C +38827C:lI116|H38836C +38836C:lI112|H388464 +388464:lI47|H388564 +388564:lI101|H38866C +38866C:lI114|H38877C +38877C:lI116|H38888C +38888C:lI115|H38899C +38899C:lI47|H388AA4 +388AA4:lI108|H388BB4 +388BB4:lI105|H388CC4 +388CC4:lI98|H388DD4 +388DD4:lI47|H388EE4 +388EE4:lI111|H388FFC +388FFC:lI115|H38910C +38910C:lI95|H38921C +38921C:lI109|H38932C +38932C:lI111|H38943C +38943C:lI110|H389544 +389544:lI47|H38963C +38963C:lI101|H389734 +389734:lI98|H38982C +38982C:lI105|H389924 +389924:lI110|N +38AFE0:lH387A44|H38B000 +387A44:lI47|H387ADC +387ADC:lI99|H387B7C +387B7C:lI108|H387C24 +387C24:lI101|H387CD4 +387CD4:lI97|H387D8C +387D8C:lI114|H387E4C +387E4C:lI99|H387F14 +387F14:lI97|H387FE4 +387FE4:lI115|H3880BC +3880BC:lI101|H38819C +38819C:lI47|H388284 +388284:lI111|H388374 +388374:lI116|H38846C +38846C:lI112|H38856C +38856C:lI47|H388674 +388674:lI101|H388784 +388784:lI114|H388894 +388894:lI116|H3889A4 +3889A4:lI115|H388AAC +388AAC:lI47|H388BBC +388BBC:lI108|H388CCC +388CCC:lI105|H388DDC +388DDC:lI98|H388EEC +388EEC:lI47|H389004 +389004:lI111|H389114 +389114:lI114|H389224 +389224:lI98|H389334 +389334:lI101|H389444 +389444:lI114|H38954C +38954C:lI47|H389644 +389644:lI101|H38973C +38973C:lI98|H389834 +389834:lI105|H38992C +38992C:lI110|N +38B000:lH387AE4|H38B010 +387AE4:lI47|H387B84 +387B84:lI99|H387C2C +387C2C:lI108|H387CDC +387CDC:lI101|H387D94 +387D94:lI97|H387E54 +387E54:lI114|H387F1C +387F1C:lI99|H387FEC +387FEC:lI97|H3880C4 +3880C4:lI115|H3881A4 +3881A4:lI101|H38828C +38828C:lI47|H38837C +38837C:lI111|H388474 +388474:lI116|H388574 +388574:lI112|H38867C +38867C:lI47|H38878C +38878C:lI101|H38889C +38889C:lI114|H3889AC +3889AC:lI116|H388AB4 +388AB4:lI115|H388BC4 +388BC4:lI47|H388CD4 +388CD4:lI108|H388DE4 +388DE4:lI105|H388EF4 +388EF4:lI98|H38900C +38900C:lI47|H38911C +38911C:lI111|H38922C +38922C:lI100|H38933C +38933C:lI98|H38944C +38944C:lI99|H389554 +389554:lI47|H38964C +38964C:lI101|H389744 +389744:lI98|H38983C +38983C:lI105|H389934 +389934:lI110|N +38B010:lH387B8C|H38B020 +387B8C:lI47|H387C34 +387C34:lI99|H387CE4 +387CE4:lI108|H387D9C +387D9C:lI101|H387E5C +387E5C:lI97|H387F24 +387F24:lI114|H387FF4 +387FF4:lI99|H3880CC +3880CC:lI97|H3881AC +3881AC:lI115|H388294 +388294:lI101|H388384 +388384:lI47|H38847C +38847C:lI111|H38857C +38857C:lI116|H388684 +388684:lI112|H388794 +388794:lI47|H3888A4 +3888A4:lI101|H3889B4 +3889B4:lI114|H388ABC +388ABC:lI116|H388BCC +388BCC:lI115|H388CDC +388CDC:lI47|H388DEC +388DEC:lI108|H388EFC +388EFC:lI105|H389014 +389014:lI98|H389124 +389124:lI47|H389234 +389234:lI111|H389344 +389344:lI98|H389454 +389454:lI115|H38955C +38955C:lI101|H389654 +389654:lI114|H38974C +38974C:lI118|H389844 +389844:lI101|H38993C +38993C:lI114|H389A1C +389A1C:lI47|H389AF4 +389AF4:lI101|H389BBC +389BBC:lI98|H389C84 +389C84:lI105|H389D4C +389D4C:lI110|N +38B020:lH387C3C|H38B028 +387C3C:lI47|H387CEC +387CEC:lI99|H387DA4 +387DA4:lI108|H387E64 +387E64:lI101|H387F2C +387F2C:lI97|H387FFC +387FFC:lI114|H3880D4 +3880D4:lI99|H3881B4 +3881B4:lI97|H38829C +38829C:lI115|H38838C +38838C:lI101|H388484 +388484:lI47|H388584 +388584:lI111|H38868C +38868C:lI116|H38879C +38879C:lI112|H3888AC +3888AC:lI47|H3889BC +3889BC:lI101|H388AC4 +388AC4:lI114|H388BD4 +388BD4:lI116|H388CE4 +388CE4:lI115|H388DF4 +388DF4:lI47|H388F04 +388F04:lI108|H38901C +38901C:lI105|H38912C +38912C:lI98|H38923C +38923C:lI47|H38934C +38934C:lI109|H38945C +38945C:lI110|H389564 +389564:lI101|H38965C +38965C:lI115|H389754 +389754:lI105|H38984C +38984C:lI97|H389944 +389944:lI95|H389A24 +389A24:lI115|H389AFC +389AFC:lI101|H389BC4 +389BC4:lI115|H389C8C +389C8C:lI115|H389D54 +389D54:lI105|H389E14 +389E14:lI111|H389ECC +389ECC:lI110|H389F7C +389F7C:lI47|H38A01C +38A01C:lI101|H38A0AC +38A0AC:lI98|H38A12C +38A12C:lI105|H38A19C +38A19C:lI110|N +38B028:lH387CF4|H38B030 +387CF4:lI47|H387DAC +387DAC:lI99|H387E6C +387E6C:lI108|H387F34 +387F34:lI101|H388004 +388004:lI97|H3880DC +3880DC:lI114|H3881BC +3881BC:lI99|H3882A4 +3882A4:lI97|H388394 +388394:lI115|H38848C +38848C:lI101|H38858C +38858C:lI47|H388694 +388694:lI111|H3887A4 +3887A4:lI116|H3888B4 +3888B4:lI112|H3889C4 +3889C4:lI47|H388ACC +388ACC:lI101|H388BDC +388BDC:lI114|H388CEC +388CEC:lI116|H388DFC +388DFC:lI115|H388F0C +388F0C:lI47|H389024 +389024:lI108|H389134 +389134:lI105|H389244 +389244:lI98|H389354 +389354:lI47|H389464 +389464:lI109|H38956C +38956C:lI110|H389664 +389664:lI101|H38975C +38975C:lI115|H389854 +389854:lI105|H38994C +38994C:lI97|H389A2C +389A2C:lI47|H389B04 +389B04:lI101|H389BCC +389BCC:lI98|H389C94 +389C94:lI105|H389D5C +389D5C:lI110|N +38B030:lH387DB4|H38B038 +387DB4:lI47|H387E74 +387E74:lI99|H387F3C +387F3C:lI108|H38800C +38800C:lI101|H3880E4 +3880E4:lI97|H3881C4 +3881C4:lI114|H3882AC +3882AC:lI99|H38839C +38839C:lI97|H388494 +388494:lI115|H388594 +388594:lI101|H38869C +38869C:lI47|H3887AC +3887AC:lI111|H3888BC +3888BC:lI116|H3889CC +3889CC:lI112|H388AD4 +388AD4:lI47|H388BE4 +388BE4:lI101|H388CF4 +388CF4:lI114|H388E04 +388E04:lI116|H388F14 +388F14:lI115|H38902C +38902C:lI47|H38913C +38913C:lI108|H38924C +38924C:lI105|H38935C +38935C:lI98|H38946C +38946C:lI47|H389574 +389574:lI109|H38966C +38966C:lI110|H389764 +389764:lI101|H38985C +38985C:lI109|H389954 +389954:lI111|H389A34 +389A34:lI115|H389B0C +389B0C:lI121|H389BD4 +389BD4:lI110|H389C9C +389C9C:lI101|H389D64 +389D64:lI47|H389E1C +389E1C:lI101|H389ED4 +389ED4:lI98|H389F84 +389F84:lI105|H38A024 +38A024:lI110|N +38B038:lH387E7C|H38B040 +387E7C:lI47|H387F44 +387F44:lI99|H388014 +388014:lI108|H3880EC +3880EC:lI101|H3881CC +3881CC:lI97|H3882B4 +3882B4:lI114|H3883A4 +3883A4:lI99|H38849C +38849C:lI97|H38859C +38859C:lI115|H3886A4 +3886A4:lI101|H3887B4 +3887B4:lI47|H3888C4 +3888C4:lI111|H3889D4 +3889D4:lI116|H388ADC +388ADC:lI112|H388BEC +388BEC:lI47|H388CFC +388CFC:lI101|H388E0C +388E0C:lI114|H388F1C +388F1C:lI116|H389034 +389034:lI115|H389144 +389144:lI47|H389254 +389254:lI108|H389364 +389364:lI105|H389474 +389474:lI98|H38957C +38957C:lI47|H389674 +389674:lI109|H38976C +38976C:lI101|H389864 +389864:lI103|H38995C +38995C:lI97|H389A3C +389A3C:lI99|H389B14 +389B14:lI111|H389BDC +389BDC:lI47|H389CA4 +389CA4:lI101|H389D6C +389D6C:lI98|H389E24 +389E24:lI105|H389EDC +389EDC:lI110|N +38B040:lH387F4C|H38B048 +387F4C:lI47|H38801C +38801C:lI99|H3880F4 +3880F4:lI108|H3881D4 +3881D4:lI101|H3882BC +3882BC:lI97|H3883AC +3883AC:lI114|H3884A4 +3884A4:lI99|H3885A4 +3885A4:lI97|H3886AC +3886AC:lI115|H3887BC +3887BC:lI101|H3888CC +3888CC:lI47|H3889DC +3889DC:lI111|H388AE4 +388AE4:lI116|H388BF4 +388BF4:lI112|H388D04 +388D04:lI47|H388E14 +388E14:lI101|H388F24 +388F24:lI114|H38903C +38903C:lI116|H38914C +38914C:lI115|H38925C +38925C:lI47|H38936C +38936C:lI108|H38947C +38947C:lI105|H389584 +389584:lI98|H38967C +38967C:lI47|H389774 +389774:lI106|H38986C +38986C:lI105|H389964 +389964:lI110|H389A44 +389A44:lI116|H389B1C +389B1C:lI101|H389BE4 +389BE4:lI114|H389CAC +389CAC:lI102|H389D74 +389D74:lI97|H389E2C +389E2C:lI99|H389EE4 +389EE4:lI101|N +38B048:lH388024|H38B050 +388024:lI47|H3880FC +3880FC:lI99|H3881DC +3881DC:lI108|H3882C4 +3882C4:lI101|H3883B4 +3883B4:lI97|H3884AC +3884AC:lI114|H3885AC +3885AC:lI99|H3886B4 +3886B4:lI97|H3887C4 +3887C4:lI115|H3888D4 +3888D4:lI101|H3889E4 +3889E4:lI47|H388AEC +388AEC:lI111|H388BFC +388BFC:lI116|H388D0C +388D0C:lI112|H388E1C +388E1C:lI47|H388F2C +388F2C:lI101|H389044 +389044:lI114|H389154 +389154:lI116|H389264 +389264:lI115|H389374 +389374:lI47|H389484 +389484:lI108|H38958C +38958C:lI105|H389684 +389684:lI98|H38977C +38977C:lI47|H389874 +389874:lI105|H38996C +38996C:lI110|H389A4C +389A4C:lI101|H389B24 +389B24:lI116|H389BEC +389BEC:lI115|H389CB4 +389CB4:lI47|H389D7C +389D7C:lI101|H389E34 +389E34:lI98|H389EEC +389EEC:lI105|H389F8C +389F8C:lI110|N +38B050:lH388104|H38B058 +388104:lI47|H3881E4 +3881E4:lI99|H3882CC +3882CC:lI108|H3883BC +3883BC:lI101|H3884B4 +3884B4:lI97|H3885B4 +3885B4:lI114|H3886BC +3886BC:lI99|H3887CC +3887CC:lI97|H3888DC +3888DC:lI115|H3889EC +3889EC:lI101|H388AF4 +388AF4:lI47|H388C04 +388C04:lI111|H388D14 +388D14:lI116|H388E24 +388E24:lI112|H388F34 +388F34:lI47|H38904C +38904C:lI101|H38915C +38915C:lI114|H38926C +38926C:lI116|H38937C +38937C:lI115|H38948C +38948C:lI47|H389594 +389594:lI108|H38968C +38968C:lI105|H389784 +389784:lI98|H38987C +38987C:lI47|H389974 +389974:lI105|H389A54 +389A54:lI99|H389B2C +389B2C:lI47|H389BF4 +389BF4:lI101|H389CBC +389CBC:lI98|H389D84 +389D84:lI105|H389E3C +389E3C:lI110|N +38B058:lH3881EC|H38B060 +3881EC:lI47|H3882D4 +3882D4:lI99|H3883C4 +3883C4:lI108|H3884BC +3884BC:lI101|H3885BC +3885BC:lI97|H3886C4 +3886C4:lI114|H3887D4 +3887D4:lI99|H3888E4 +3888E4:lI97|H3889F4 +3889F4:lI115|H388AFC +388AFC:lI101|H388C0C +388C0C:lI47|H388D1C +388D1C:lI111|H388E2C +388E2C:lI116|H388F3C +388F3C:lI112|H389054 +389054:lI47|H389164 +389164:lI101|H389274 +389274:lI114|H389384 +389384:lI116|H389494 +389494:lI115|H38959C +38959C:lI47|H389694 +389694:lI108|H38978C +38978C:lI105|H389884 +389884:lI98|H38997C +38997C:lI47|H389A5C +389A5C:lI104|H389B34 +389B34:lI105|H389BFC +389BFC:lI112|H389CC4 +389CC4:lI101|H389D8C +389D8C:lI47|H389E44 +389E44:lI101|H389EF4 +389EF4:lI98|H389F94 +389F94:lI105|H38A02C +38A02C:lI110|N +38B060:lH3882DC|H38B068 +3882DC:lI47|H3883CC +3883CC:lI99|H3884C4 +3884C4:lI108|H3885C4 +3885C4:lI101|H3886CC +3886CC:lI97|H3887DC +3887DC:lI114|H3888EC +3888EC:lI99|H3889FC +3889FC:lI97|H388B04 +388B04:lI115|H388C14 +388C14:lI101|H388D24 +388D24:lI47|H388E34 +388E34:lI111|H388F44 +388F44:lI116|H38905C +38905C:lI112|H38916C +38916C:lI47|H38927C +38927C:lI101|H38938C +38938C:lI114|H38949C +38949C:lI116|H3895A4 +3895A4:lI115|H38969C +38969C:lI47|H389794 +389794:lI108|H38988C +38988C:lI105|H389984 +389984:lI98|H389A64 +389A64:lI47|H389B3C +389B3C:lI103|H389C04 +389C04:lI115|H389CCC +389CCC:lI47|H389D94 +389D94:lI101|H389E4C +389E4C:lI98|H389EFC +389EFC:lI105|H389F9C +389F9C:lI110|N +38B068:lH3883D4|H38B070 +3883D4:lI47|H3884CC +3884CC:lI99|H3885CC +3885CC:lI108|H3886D4 +3886D4:lI101|H3887E4 +3887E4:lI97|H3888F4 +3888F4:lI114|H388A04 +388A04:lI99|H388B0C +388B0C:lI97|H388C1C +388C1C:lI115|H388D2C +388D2C:lI101|H388E3C +388E3C:lI47|H388F4C +388F4C:lI111|H389064 +389064:lI116|H389174 +389174:lI112|H389284 +389284:lI47|H389394 +389394:lI101|H3894A4 +3894A4:lI114|H3895AC +3895AC:lI116|H3896A4 +3896A4:lI115|H38979C +38979C:lI47|H389894 +389894:lI108|H38998C +38998C:lI105|H389A6C +389A6C:lI98|H389B44 +389B44:lI47|H389C0C +389C0C:lI101|H389CD4 +389CD4:lI118|H389D9C +389D9C:lI97|H389E54 +389E54:lI47|H389F04 +389F04:lI101|H389FA4 +389FA4:lI98|H38A034 +38A034:lI105|H38A0B4 +38A0B4:lI110|N +38B070:lH3884D4|H38B078 +3884D4:lI47|H3885D4 +3885D4:lI99|H3886DC +3886DC:lI108|H3887EC +3887EC:lI101|H3888FC +3888FC:lI97|H388A0C +388A0C:lI114|H388B14 +388B14:lI99|H388C24 +388C24:lI97|H388D34 +388D34:lI115|H388E44 +388E44:lI101|H388F54 +388F54:lI47|H38906C +38906C:lI111|H38917C +38917C:lI116|H38928C +38928C:lI112|H38939C +38939C:lI47|H3894AC +3894AC:lI101|H3895B4 +3895B4:lI114|H3896AC +3896AC:lI116|H3897A4 +3897A4:lI115|H38989C +38989C:lI47|H389994 +389994:lI108|H389A74 +389A74:lI105|H389B4C +389B4C:lI98|H389C14 +389C14:lI47|H389CDC +389CDC:lI101|H389DA4 +389DA4:lI116|H389E5C +389E5C:lI47|H389F0C +389F0C:lI101|H389FAC +389FAC:lI98|H38A03C +38A03C:lI105|H38A0BC +38A0BC:lI110|N +38B078:lH3885DC|H38B080 +3885DC:lI47|H3886E4 +3886E4:lI99|H3887F4 +3887F4:lI108|H388904 +388904:lI101|H388A14 +388A14:lI97|H388B1C +388B1C:lI114|H388C2C +388C2C:lI99|H388D3C +388D3C:lI97|H388E4C +388E4C:lI115|H388F5C +388F5C:lI101|H389074 +389074:lI47|H389184 +389184:lI111|H389294 +389294:lI116|H3893A4 +3893A4:lI112|H3894B4 +3894B4:lI47|H3895BC +3895BC:lI101|H3896B4 +3896B4:lI114|H3897AC +3897AC:lI116|H3898A4 +3898A4:lI115|H38999C +38999C:lI47|H389A7C +389A7C:lI108|H389B54 +389B54:lI105|H389C1C +389C1C:lI98|H389CE4 +389CE4:lI47|H389DAC +389DAC:lI101|H389E64 +389E64:lI114|H389F14 +389F14:lI108|H389FB4 +389FB4:lI95|H38A044 +38A044:lI105|H38A0C4 +38A0C4:lI110|H38A134 +38A134:lI116|H38A1A4 +38A1A4:lI101|H38A20C +38A20C:lI114|H38A274 +38A274:lI102|H38A2DC +38A2DC:lI97|H38A344 +38A344:lI99|H38A3AC +38A3AC:lI101|N +38B080:lH3886EC|H38B088 +3886EC:lI47|H3887FC +3887FC:lI99|H38890C +38890C:lI108|H388A1C +388A1C:lI101|H388B24 +388B24:lI97|H388C34 +388C34:lI114|H388D44 +388D44:lI99|H388E54 +388E54:lI97|H388F64 +388F64:lI115|H38907C +38907C:lI101|H38918C +38918C:lI47|H38929C +38929C:lI111|H3893AC +3893AC:lI116|H3894BC +3894BC:lI112|H3895C4 +3895C4:lI47|H3896BC +3896BC:lI101|H3897B4 +3897B4:lI114|H3898AC +3898AC:lI116|H3899A4 +3899A4:lI115|H389A84 +389A84:lI47|H389B5C +389B5C:lI108|H389C24 +389C24:lI105|H389CEC +389CEC:lI98|H389DB4 +389DB4:lI47|H389E6C +389E6C:lI100|H389F1C +389F1C:lI101|H389FBC +389FBC:lI98|H38A04C +38A04C:lI117|H38A0CC +38A0CC:lI103|H38A13C +38A13C:lI103|H38A1AC +38A1AC:lI101|H38A214 +38A214:lI114|H38A27C +38A27C:lI47|H38A2E4 +38A2E4:lI101|H38A34C +38A34C:lI98|H38A3B4 +38A3B4:lI105|H38A414 +38A414:lI110|N +38B088:lH388804|H38B090 +388804:lI47|H388914 +388914:lI99|H388A24 +388A24:lI108|H388B2C +388B2C:lI101|H388C3C +388C3C:lI97|H388D4C +388D4C:lI114|H388E5C +388E5C:lI99|H388F6C +388F6C:lI97|H389084 +389084:lI115|H389194 +389194:lI101|H3892A4 +3892A4:lI47|H3893B4 +3893B4:lI111|H3894C4 +3894C4:lI116|H3895CC +3895CC:lI112|H3896C4 +3896C4:lI47|H3897BC +3897BC:lI101|H3898B4 +3898B4:lI114|H3899AC +3899AC:lI116|H389A8C +389A8C:lI115|H389B64 +389B64:lI47|H389C2C +389C2C:lI108|H389CF4 +389CF4:lI105|H389DBC +389DBC:lI98|H389E74 +389E74:lI47|H389F24 +389F24:lI99|H389FC4 +389FC4:lI114|H38A054 +38A054:lI121|H38A0D4 +38A0D4:lI112|H38A144 +38A144:lI116|H38A1B4 +38A1B4:lI111|H38A21C +38A21C:lI47|H38A284 +38A284:lI101|H38A2EC +38A2EC:lI98|H38A354 +38A354:lI105|H38A3BC +38A3BC:lI110|N +38B090:lH38891C|H38B098 +38891C:lI47|H388A2C +388A2C:lI99|H388B34 +388B34:lI108|H388C44 +388C44:lI101|H388D54 +388D54:lI97|H388E64 +388E64:lI114|H388F74 +388F74:lI99|H38908C +38908C:lI97|H38919C +38919C:lI115|H3892AC +3892AC:lI101|H3893BC +3893BC:lI47|H3894CC +3894CC:lI111|H3895D4 +3895D4:lI116|H3896CC +3896CC:lI112|H3897C4 +3897C4:lI47|H3898BC +3898BC:lI101|H3899B4 +3899B4:lI114|H389A94 +389A94:lI116|H389B6C +389B6C:lI115|H389C34 +389C34:lI47|H389CFC +389CFC:lI108|H389DC4 +389DC4:lI105|H389E7C +389E7C:lI98|H389F2C +389F2C:lI47|H389FCC +389FCC:lI99|H38A05C +38A05C:lI111|H38A0DC +38A0DC:lI115|H38A14C +38A14C:lI84|H38A1BC +38A1BC:lI114|H38A224 +38A224:lI97|H38A28C +38A28C:lI110|H38A2F4 +38A2F4:lI115|H38A35C +38A35C:lI97|H38A3C4 +38A3C4:lI99|H38A41C +38A41C:lI116|H38A46C +38A46C:lI105|H38A4BC +38A4BC:lI111|H38A50C +38A50C:lI110|H38A554 +38A554:lI115|H38A59C +38A59C:lI47|H38A5E4 +38A5E4:lI101|H38A62C +38A62C:lI98|H38A66C +38A66C:lI105|H38A6A4 +38A6A4:lI110|N +38B098:lH388A34|H38B0A0 +388A34:lI47|H388B3C +388B3C:lI99|H388C4C +388C4C:lI108|H388D5C +388D5C:lI101|H388E6C +388E6C:lI97|H388F7C +388F7C:lI114|H389094 +389094:lI99|H3891A4 +3891A4:lI97|H3892B4 +3892B4:lI115|H3893C4 +3893C4:lI101|H3894D4 +3894D4:lI47|H3895DC +3895DC:lI111|H3896D4 +3896D4:lI116|H3897CC +3897CC:lI112|H3898C4 +3898C4:lI47|H3899BC +3899BC:lI101|H389A9C +389A9C:lI114|H389B74 +389B74:lI116|H389C3C +389C3C:lI115|H389D04 +389D04:lI47|H389DCC +389DCC:lI108|H389E84 +389E84:lI105|H389F34 +389F34:lI98|H389FD4 +389FD4:lI47|H38A064 +38A064:lI99|H38A0E4 +38A0E4:lI111|H38A154 +38A154:lI115|H38A1C4 +38A1C4:lI84|H38A22C +38A22C:lI105|H38A294 +38A294:lI109|H38A2FC +38A2FC:lI101|H38A364 +38A364:lI47|H38A3CC +38A3CC:lI101|H38A424 +38A424:lI98|H38A474 +38A474:lI105|H38A4C4 +38A4C4:lI110|N +38B0A0:lH388B44|H38B0A8 +388B44:lI47|H388C54 +388C54:lI99|H388D64 +388D64:lI108|H388E74 +388E74:lI101|H388F84 +388F84:lI97|H38909C +38909C:lI114|H3891AC +3891AC:lI99|H3892BC +3892BC:lI97|H3893CC +3893CC:lI115|H3894DC +3894DC:lI101|H3895E4 +3895E4:lI47|H3896DC +3896DC:lI111|H3897D4 +3897D4:lI116|H3898CC +3898CC:lI112|H3899C4 +3899C4:lI47|H389AA4 +389AA4:lI101|H389B7C +389B7C:lI114|H389C44 +389C44:lI116|H389D0C +389D0C:lI115|H389DD4 +389DD4:lI47|H389E8C +389E8C:lI108|H389F3C +389F3C:lI105|H389FDC +389FDC:lI98|H38A06C +38A06C:lI47|H38A0EC +38A0EC:lI99|H38A15C +38A15C:lI111|H38A1CC +38A1CC:lI115|H38A234 +38A234:lI80|H38A29C +38A29C:lI114|H38A304 +38A304:lI111|H38A36C +38A36C:lI112|H38A3D4 +38A3D4:lI101|H38A42C +38A42C:lI114|H38A47C +38A47C:lI116|H38A4CC +38A4CC:lI121|H38A514 +38A514:lI47|H38A55C +38A55C:lI101|H38A5A4 +38A5A4:lI98|H38A5EC +38A5EC:lI105|H38A634 +38A634:lI110|N +38B0A8:lH388C5C|H38B0B0 +388C5C:lI47|H388D6C +388D6C:lI99|H388E7C +388E7C:lI108|H388F8C +388F8C:lI101|H3890A4 +3890A4:lI97|H3891B4 +3891B4:lI114|H3892C4 +3892C4:lI99|H3893D4 +3893D4:lI97|H3894E4 +3894E4:lI115|H3895EC +3895EC:lI101|H3896E4 +3896E4:lI47|H3897DC +3897DC:lI111|H3898D4 +3898D4:lI116|H3899CC +3899CC:lI112|H389AAC +389AAC:lI47|H389B84 +389B84:lI101|H389C4C +389C4C:lI114|H389D14 +389D14:lI116|H389DDC +389DDC:lI115|H389E94 +389E94:lI47|H389F44 +389F44:lI108|H389FE4 +389FE4:lI105|H38A074 +38A074:lI98|H38A0F4 +38A0F4:lI47|H38A164 +38A164:lI99|H38A1D4 +38A1D4:lI111|H38A23C +38A23C:lI115|H38A2A4 +38A2A4:lI78|H38A30C +38A30C:lI111|H38A374 +38A374:lI116|H38A3DC +38A3DC:lI105|H38A434 +38A434:lI102|H38A484 +38A484:lI105|H38A4D4 +38A4D4:lI99|H38A51C +38A51C:lI97|H38A564 +38A564:lI116|H38A5AC +38A5AC:lI105|H38A5F4 +38A5F4:lI111|H38A63C +38A63C:lI110|H38A674 +38A674:lI47|H38A6AC +38A6AC:lI101|H38A6D4 +38A6D4:lI98|H38A6EC +38A6EC:lI105|H38A704 +38A704:lI110|N +38B0B0:lH388D74|H38B0B8 +388D74:lI47|H388E84 +388E84:lI99|H388F94 +388F94:lI108|H3890AC +3890AC:lI101|H3891BC +3891BC:lI97|H3892CC +3892CC:lI114|H3893DC +3893DC:lI99|H3894EC +3894EC:lI97|H3895F4 +3895F4:lI115|H3896EC +3896EC:lI101|H3897E4 +3897E4:lI47|H3898DC +3898DC:lI111|H3899D4 +3899D4:lI116|H389AB4 +389AB4:lI112|H389B8C +389B8C:lI47|H389C54 +389C54:lI101|H389D1C +389D1C:lI114|H389DE4 +389DE4:lI116|H389E9C +389E9C:lI115|H389F4C +389F4C:lI47|H389FEC +389FEC:lI108|H38A07C +38A07C:lI105|H38A0FC +38A0FC:lI98|H38A16C +38A16C:lI47|H38A1DC +38A1DC:lI99|H38A244 +38A244:lI111|H38A2AC +38A2AC:lI115|H38A314 +38A314:lI70|H38A37C +38A37C:lI105|H38A3E4 +38A3E4:lI108|H38A43C +38A43C:lI101|H38A48C +38A48C:lI84|H38A4DC +38A4DC:lI114|H38A524 +38A524:lI97|H38A56C +38A56C:lI110|H38A5B4 +38A5B4:lI115|H38A5FC +38A5FC:lI102|H38A644 +38A644:lI101|H38A67C +38A67C:lI114|H38A6B4 +38A6B4:lI47|H38A6DC +38A6DC:lI101|H38A6F4 +38A6F4:lI98|H38A70C +38A70C:lI105|H38A71C +38A71C:lI110|N +38B0B8:lH388E8C|H38B0C0 +388E8C:lI47|H388F9C +388F9C:lI99|H3890B4 +3890B4:lI108|H3891C4 +3891C4:lI101|H3892D4 +3892D4:lI97|H3893E4 +3893E4:lI114|H3894F4 +3894F4:lI99|H3895FC +3895FC:lI97|H3896F4 +3896F4:lI115|H3897EC +3897EC:lI101|H3898E4 +3898E4:lI47|H3899DC +3899DC:lI111|H389ABC +389ABC:lI116|H389B94 +389B94:lI112|H389C5C +389C5C:lI47|H389D24 +389D24:lI101|H389DEC +389DEC:lI114|H389EA4 +389EA4:lI116|H389F54 +389F54:lI115|H389FF4 +389FF4:lI47|H38A084 +38A084:lI108|H38A104 +38A104:lI105|H38A174 +38A174:lI98|H38A1E4 +38A1E4:lI47|H38A24C +38A24C:lI99|H38A2B4 +38A2B4:lI111|H38A31C +38A31C:lI115|H38A384 +38A384:lI69|H38A3EC +38A3EC:lI118|H38A444 +38A444:lI101|H38A494 +38A494:lI110|H38A4E4 +38A4E4:lI116|H38A52C +38A52C:lI68|H38A574 +38A574:lI111|H38A5BC +38A5BC:lI109|H38A604 +38A604:lI97|H38A64C +38A64C:lI105|H38A684 +38A684:lI110|H38A6BC +38A6BC:lI47|H38A6E4 +38A6E4:lI101|H38A6FC +38A6FC:lI98|H38A714 +38A714:lI105|H38A724 +38A724:lI110|N +38B0C0:lH388FA4|H38B0C8 +388FA4:lI47|H3890BC +3890BC:lI99|H3891CC +3891CC:lI108|H3892DC +3892DC:lI101|H3893EC +3893EC:lI97|H3894FC +3894FC:lI114|H389604 +389604:lI99|H3896FC +3896FC:lI97|H3897F4 +3897F4:lI115|H3898EC +3898EC:lI101|H3899E4 +3899E4:lI47|H389AC4 +389AC4:lI111|H389B9C +389B9C:lI116|H389C64 +389C64:lI112|H389D2C +389D2C:lI47|H389DF4 +389DF4:lI101|H389EAC +389EAC:lI114|H389F5C +389F5C:lI116|H389FFC +389FFC:lI115|H38A08C +38A08C:lI47|H38A10C +38A10C:lI108|H38A17C +38A17C:lI105|H38A1EC +38A1EC:lI98|H38A254 +38A254:lI47|H38A2BC +38A2BC:lI99|H38A324 +38A324:lI111|H38A38C +38A38C:lI115|H38A3F4 +38A3F4:lI69|H38A44C +38A44C:lI118|H38A49C +38A49C:lI101|H38A4EC +38A4EC:lI110|H38A534 +38A534:lI116|H38A57C +38A57C:lI47|H38A5C4 +38A5C4:lI101|H38A60C +38A60C:lI98|H38A654 +38A654:lI105|H38A68C +38A68C:lI110|N +38B0C8:lH3890C4|H38B0D0 +3890C4:lI47|H3891D4 +3891D4:lI99|H3892E4 +3892E4:lI108|H3893F4 +3893F4:lI101|H389504 +389504:lI97|H38960C +38960C:lI114|H389704 +389704:lI99|H3897FC +3897FC:lI97|H3898F4 +3898F4:lI115|H3899EC +3899EC:lI101|H389ACC +389ACC:lI47|H389BA4 +389BA4:lI111|H389C6C +389C6C:lI116|H389D34 +389D34:lI112|H389DFC +389DFC:lI47|H389EB4 +389EB4:lI101|H389F64 +389F64:lI114|H38A004 +38A004:lI116|H38A094 +38A094:lI115|H38A114 +38A114:lI47|H38A184 +38A184:lI108|H38A1F4 +38A1F4:lI105|H38A25C +38A25C:lI98|H38A2C4 +38A2C4:lI47|H38A32C +38A32C:lI99|H38A394 +38A394:lI111|H38A3FC +38A3FC:lI109|H38A454 +38A454:lI112|H38A4A4 +38A4A4:lI105|H38A4F4 +38A4F4:lI108|H38A53C +38A53C:lI101|H38A584 +38A584:lI114|H38A5CC +38A5CC:lI47|H38A614 +38A614:lI101|H38A65C +38A65C:lI98|H38A694 +38A694:lI105|H38A6C4 +38A6C4:lI110|N +38B0D0:lH3891DC|H38B0D8 +3891DC:lI47|H3892EC +3892EC:lI99|H3893FC +3893FC:lI108|H38950C +38950C:lI101|H389614 +389614:lI97|H38970C +38970C:lI114|H389804 +389804:lI99|H3898FC +3898FC:lI97|H3899F4 +3899F4:lI115|H389AD4 +389AD4:lI101|H389BAC +389BAC:lI47|H389C74 +389C74:lI111|H389D3C +389D3C:lI116|H389E04 +389E04:lI112|H389EBC +389EBC:lI47|H389F6C +389F6C:lI101|H38A00C +38A00C:lI114|H38A09C +38A09C:lI116|H38A11C +38A11C:lI115|H38A18C +38A18C:lI47|H38A1FC +38A1FC:lI108|H38A264 +38A264:lI105|H38A2CC +38A2CC:lI98|H38A334 +38A334:lI47|H38A39C +38A39C:lI97|H38A404 +38A404:lI115|H38A45C +38A45C:lI110|H38A4AC +38A4AC:lI49|H38A4FC +38A4FC:lI47|H38A544 +38A544:lI101|H38A58C +38A58C:lI98|H38A5D4 +38A5D4:lI105|H38A61C +38A61C:lI110|N +38B0D8:lH3892F4|H38B0E0 +3892F4:lI47|H389404 +389404:lI99|H389514 +389514:lI108|H38961C +38961C:lI101|H389714 +389714:lI97|H38980C +38980C:lI114|H389904 +389904:lI99|H3899FC +3899FC:lI97|H389ADC +389ADC:lI115|H389BB4 +389BB4:lI101|H389C7C +389C7C:lI47|H389D44 +389D44:lI111|H389E0C +389E0C:lI116|H389EC4 +389EC4:lI112|H389F74 +389F74:lI47|H38A014 +38A014:lI101|H38A0A4 +38A0A4:lI114|H38A124 +38A124:lI116|H38A194 +38A194:lI115|H38A204 +38A204:lI47|H38A26C +38A26C:lI108|H38A2D4 +38A2D4:lI105|H38A33C +38A33C:lI98|H38A3A4 +38A3A4:lI47|H38A40C +38A40C:lI97|H38A464 +38A464:lI112|H38A4B4 +38A4B4:lI112|H38A504 +38A504:lI109|H38A54C +38A54C:lI111|H38A594 +38A594:lI110|H38A5DC +38A5DC:lI47|H38A624 +38A624:lI101|H38A664 +38A664:lI98|H38A69C +38A69C:lI105|H38A6CC +38A6CC:lI110|N +38B0E0:lH38AA88|H38B0E8 +38AA88:lI47|H38AA90 +38AA90:lI104|H38AA98 +38AA98:lI111|H38AAA0 +38AAA0:lI109|H38AAA8 +38AAA8:lI101|H38AAB0 +38AAB0:lI47|H38AAB8 +38AAB8:lI115|H38AAC0 +38AAC0:lI105|H38AAC8 +38AAC8:lI114|H38AAD0 +38AAD0:lI105|H38AAD8 +38AAD8:lI47|H38AAE0 +38AAE0:lI101|H38AAE8 +38AAE8:lI114|H38AAF0 +38AAF0:lI108|H38AAF8 +38AAF8:lI97|H38AB00 +38AB00:lI110|H38AB08 +38AB08:lI103|N +38B0E8:lH38AB1C|H38B0F0 +38AB1C:lI47|H38AB2C +38AB2C:lI104|H38AB4C +38AB4C:lI111|H38AB74 +38AB74:lI109|H38ABA4 +38ABA4:lI101|H38ABC4 +38ABC4:lI47|H38ABE4 +38ABE4:lI115|H38AC04 +38AC04:lI105|H38AC24 +38AC24:lI114|H38AC3C +38AC3C:lI105|H38AC44 +38AC44:lI47|H38AC4C +38AC4C:lI116|H38AC54 +38AC54:lI111|H38AC5C +38AC5C:lI111|H38AC64 +38AC64:lI108|H38AC6C +38AC6C:lI115|H38AC74 +38AC74:lI47|H38AC7C +38AC7C:lI100|H38AC84 +38AC84:lI105|H38AC8C +38AC8C:lI115|H38AC94 +38AC94:lI116|H38AC9C +38AC9C:lI101|H38ACA4 +38ACA4:lI108|H38ACAC +38ACAC:lI47|H38ACB4 +38ACB4:lI101|H38ACBC +38ACBC:lI98|H38ACC4 +38ACC4:lI105|H38ACCC +38ACCC:lI110|N +38B0F0:lH38B0F8|N +38B0F8:lI47|H38B100 +38B100:lI104|H38B108 +38B108:lI111|H38B110 +38B110:lI109|H38B118 +38B118:lI101|H38B120 +38B120:lI47|H38B128 +38B128:lI115|H38B130 +38B130:lI105|H38B138 +38B138:lI114|H38B140 +38B140:lI105|H38B148 +38B148:lI47|H38B150 +38B150:lI79|H38B158 +38B158:lI84|H38B160 +38B160:lI80|H38B168 +38B168:lI47|H38B170 +38B170:lI103|H38B178 +38B178:lI112|H38B180 +38B180:lI114|H38B188 +38B188:lI115|H38B190 +38B190:lI95|H38B198 +38B198:lI116|H38B1A0 +38B1A0:lI114|H38B1A8 +38B1A8:lI97|H38B1B0 +38B1B0:lI99|H38B1B8 +38B1B8:lI101|H38B1C0 +38B1C0:lI47|H38B1C8 +38B1C8:lI106|H38B1D0 +38B1D0:lI97|H38B1D8 +38B1D8:lI110|N +3873BC:lI47|H3873CC +3873CC:lI99|H3873E4 +3873E4:lI108|H3873FC +3873FC:lI101|H38741C +38741C:lI97|H387444 +387444:lI114|H387474 +387474:lI99|H3874AC +3874AC:lI97|H3874EC +3874EC:lI115|H387534 +387534:lI101|H387584 +387584:lI47|H3875DC +3875DC:lI111|H38763C +38763C:lI116|H3876A4 +3876A4:lI112|H387714 +387714:lI47|H38778C +38778C:lI101|H38780C +38780C:lI114|H387894 +387894:lI116|H387924 +387924:lI115|N +=proc_dictionary:<0.19.0> +H370244 +H370250 +=proc_stack:<0.19.0> +36b45c:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A11:supervisor_bridge +y3:H36B17C +y4:P<0.19.0> +y5:P<0.9.0> +36b478:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H37025C +=proc_heap:<0.19.0> +36B17C:t5:A5:state,A8:user_sup,P<0.21.0>,P<0.21.0>,H370238 +370238:t2:P<0.19.0>,A8:user_sup +37025C:lAA:gen_server|H37027C +37027C:lP<0.9.0>|H37028C +37028C:lP<0.9.0>|H370294 +370294:lA11:supervisor_bridge|H37029C +37029C:lH3702A4|H3702AC +3702A4:lA8:user_sup|H3702B4 +3702B4:lN|H3702BC +3702BC:lA4:self|N +3702AC:lN|N +370244:t2:AD:$initial_call,H370264 +370264:t3:A3:gen,A7:init_it,H37025C +370250:t2:AA:$ancestors,H370274 +370274:lAA:kernel_sup|H370284 +370284:lP<0.8.0>|N +=proc_dictionary:<0.20.0> +H36F8A8 +=proc_stack:<0.20.0> +36a714:SReturn addr 0x156F90 (<terminate process normally>) +y0:N +y1:N +y2:H36F8C4 +y3:P<0.21.0> +y4:P<0.22.0> +y5:p<0.72> +y6:p<0.72> +=proc_heap:<0.20.0> +36F8C4:t4:I3,I2,P<0.22.0>,H36F8F0 +36F8F0:lH36F900|H36F910 +36F900:t3:I1,P<0.21.0>,H36F920 +36F920:t0: +36F910:lH36F924|N +36F924:t3:I2,P<0.22.0>,H36F93C +36F93C:t3:A5:shell,A5:start,N +36F8A8:t2:A3:eof,A5:false +=proc_dictionary:<0.21.0> +H3709DC +H3709D0 +H3709F8 +=proc_stack:<0.21.0> +370d1c:SReturn addr 0x156F90 (<terminate process normally>) +y0:N +y1:A9:undefined +y2:P<0.20.0> +=proc_heap:<0.21.0> +3709DC:t2:AB:line_buffer,N +3709D0:t2:AB:kill_buffer,N +3709F8:t2:A9:read_mode,A4:list +=proc_dictionary:<0.22.0> +H370D44 +H370D60 +H370D7C +H370D38 +=proc_stack:<0.22.0> +374a88:SReturn addr 0x2CE718 (group:get_chars_loop/7 + 80) +y0:N +y1:N +y2:A8:infinity +y3:H374A00 +y4:P<0.20.0> +y5:H374A28 +374aa4:SReturn addr 0x2CDC18 (group:io_request/5 + 48) +y0:H37499C +y1:A6:io_lib +y2:A9:get_until +y3:H3748B8 +y4:P<0.20.0> +y5:A5:start +374ac0:SReturn addr 0x2CDB2C (group:server_loop/3 + 372) +y0:P<0.49.0> +y1:P<0.22.0> +374acc:SReturn addr 0x156F90 (<terminate process normally>) +y0:N +y1:P<0.25.0> +y2:P<0.20.0> +=proc_heap:<0.22.0> +374A00:t4:A4:line,H37499C,H3749A4,A4:none +3749A4:t2:N,N +37499C:lI50|H374994 +374994:lI62|H37498C +37498C:lI32|N +374A28:t4:A5:stack,H370D58,H374A24,N +374A24:t0: +370D58:lH370D74|N +370D74:lI99|H370D88 +370D88:lI114|H370D90 +370D90:lI97|H370D98 +370D98:lI115|H370DA0 +370DA0:lI104|H370DA8 +370DA8:lI100|H370DB0 +370DB0:lI117|H370DB8 +370DB8:lI109|H370DC0 +370DC0:lI112|H370DC8 +370DC8:lI95|H370DD0 +370DD0:lI118|H370DD8 +370DD8:lI105|H370DE0 +370DE0:lI101|H370DE8 +370DE8:lI119|H370DF0 +370DF0:lI101|H370DF8 +370DF8:lI114|H370E00 +370E00:lI58|H370E08 +370E08:lI115|H370E10 +370E10:lI116|H370E18 +370E18:lI97|H370E20 +370E20:lI114|H370E28 +370E28:lI116|H370E30 +370E30:lI40|H370E38 +370E38:lI41|H370E40 +370E40:lI46|H370E48 +370E48:lI10|N +3748B8:t3:A8:erl_scan,A6:tokens,H3748B0 +3748B0:lI1|N +370D44:t2:AB:line_buffer,H370D58 +370D60:t2:A5:shell,P<0.25.0> +370D7C:t2:AB:kill_buffer,N +370D38:t2:A9:read_mode,A4:list +=proc_dictionary:<0.23.0> +H376464 +H376448 +=proc_stack:<0.23.0> +376754:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AD:kernel_config +y3:N +y4:P<0.23.0> +y5:P<0.9.0> +376770:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H376418 +=proc_heap:<0.23.0> +376418:lAA:gen_server|H376410 +376410:lP<0.9.0>|H376408 +376408:lP<0.9.0>|H376400 +376400:lAD:kernel_config|H3763F8 +3763F8:lN|H3763F0 +3763F0:lN|N +376464:t2:AD:$initial_call,H376454 +376454:t3:A3:gen,A7:init_it,H376418 +376448:t2:AA:$ancestors,H376440 +376440:lAA:kernel_sup|H376420 +376420:lP<0.8.0>|N +=proc_dictionary:<0.24.0> +H3705E0 +H3705EC +=proc_stack:<0.24.0> +36f38c:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AA:supervisor +y3:H36F018 +y4:AF:kernel_safe_sup +y5:P<0.9.0> +36f3a8:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H37063C +=proc_heap:<0.24.0> +36F018:tA:A5:state,H370644,AB:one_for_one,H36F044,N,I4,I3600,N,A6:kernel,A4:safe +36F044:lH36F04C|N +36F04C:t8:A5:child,P<0.31.0>,A17:inet_gethost_native_sup,H370650,A9:temporary,I1000,A6:worker,H370660 +370660:lA13:inet_gethost_native|N +370650:t3:A13:inet_gethost_native,AA:start_link,N +370644:t2:A5:local,AF:kernel_safe_sup +37063C:lAA:gen_server|H3706AC +3706AC:lP<0.9.0>|H3706BC +3706BC:lP<0.9.0>|H3706C4 +3706C4:lH3706CC|H3706D8 +3706CC:t2:A5:local,AF:kernel_safe_sup +3706D8:lAA:supervisor|H3706E0 +3706E0:lH3706E8|H3706F8 +3706E8:t3:H370644,A6:kernel,A4:safe +3706F8:lN|N +3705E0:t2:AD:$initial_call,H370668 +370668:t3:A3:gen,A7:init_it,H37063C +3705EC:t2:AA:$ancestors,H370678 +370678:lAA:kernel_sup|H3706B4 +3706B4:lP<0.8.0>|N +=proc_dictionary:<0.25.0> +H36E304 +H36E31C +=proc_stack:<0.25.0> +36e610:SReturn addr 0x2E06FC (shell:server_loop/6 + 140) +y0:N +y1:N +y2:P<0.27.0> +y3:P<0.49.0> +36e624:SReturn addr 0x156F90 (<terminate process normally>) +y0:N +y1:N +y2:I2 +y3:I1 +y4:N +y5:N +y6:N +y7:I20 +y8:I20 +=proc_heap:<0.25.0> +36E304:t2:H36E2F8,H36E2A8 +36E2A8:lH36E2B0|N +36E2B0:t4:A4:call,I1,H36E2C4,N +36E2C4:t4:A6:remote,I1,H36E2D8,H36E2E8 +36E2E8:t3:A4:atom,I1,A5:start +36E2D8:t3:A4:atom,I1,A10:crashdump_viewer +36E2F8:t2:A7:command,I1 +36E31C:t2:H36E310,A2:ok +36E310:t2:A6:result,I1 +=proc_stack:<0.27.0> +3bda3c:SReturn addr 0x156F90 (<terminate process normally>) +y0:N +y1:N +y2:P<0.25.0> +=proc_heap:<0.27.0> +=proc_dictionary:<0.31.0> +H36DA24 +H36DA08 +=proc_stack:<0.31.0> +36dcd4:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A11:supervisor_bridge +y3:H36DB68 +y4:A17:inet_gethost_native_sup +y5:P<0.24.0> +36dcf0:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H36D9D0 +=proc_heap:<0.31.0> +36DB68:t5:A5:state,A13:inet_gethost_native,P<0.32.0>,P<0.32.0>,H36D994 +36D994:t2:A5:local,A17:inet_gethost_native_sup +36D9D0:lAA:gen_server|H36D9C8 +36D9C8:lP<0.24.0>|H36D9C0 +36D9C0:lP<0.24.0>|H36D970 +36D970:lH36D980|H36D9B8 +36D980:t2:A5:local,A17:inet_gethost_native_sup +36D9B8:lA11:supervisor_bridge|H36D978 +36D978:lH36D9A8|H36D9B0 +36D9A8:lA13:inet_gethost_native|H36D9A0 +36D9A0:lN|H36D98C +36D98C:lH36D994|N +36D9B0:lN|N +36DA24:t2:AD:$initial_call,H36DA14 +36DA14:t3:A3:gen,A7:init_it,H36D9D0 +36DA08:t2:AA:$ancestors,H36DA00 +36DA00:lAF:kernel_safe_sup|H36D9E0 +36D9E0:lAA:kernel_sup|H36D9D8 +36D9D8:lP<0.8.0>|N +=proc_dictionary:<0.32.0> +H36CFD4 +H36D0BC +=proc_stack:<0.32.0> +36d12c:SReturn addr 0x156F90 (<terminate process normally>) +y0:H36CF18 +=proc_heap:<0.32.0> +36CF18:t8:A5:state,p<0.105>,I8000,I11,I12,P<0.31.0>,I4,H36CEF0 +36CEF0:t9:AA:statistics,I0,I0,I0,I0,I0,I0,I0,I0 +36CFD4:t2:A3:rid,I1 +36D0BC:t2:AC:num_requests,I0 +=proc_dictionary:<0.33.0> +H3905C4 +H3905D0 +=proc_stack:<0.33.0> +3ceee4:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A7:webtool +y3:H3C8570 +y4:A8:web_tool +y5:P<0.33.0> +3cef00:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H3905FC +=proc_heap:<0.33.0> +3C8570:t6:A5:state,H3905EC,I13,P<0.41.0>,H3905F4,H3C85D4 +3C85D4:lA10:crashdump_viewer|N +3905F4:lH390650|H39065C +390650:t2:A4:port,I8888 +39065C:lH3906C8|H3906D4 +3906C8:t2:AC:bind_address,H390760 +390760:t4:I127,I0,I0,I1 +3906D4:lH390774|H390780 +390774:t2:AB:server_name,H39082C +39082C:lI108|H390908 +390908:lI111|H3909DC +3909DC:lI99|H390AC0 +390AC0:lI97|H390B98 +390B98:lI108|H390C78 +390C78:lI104|H390D58 +390D58:lI111|H390E2C +390E2C:lI115|H390F10 +390F10:lI116|N +390780:lH390834|H390840 +390834:t2:AE:max_header_siz,I1024 +390840:lH390910|H39091C +390910:t2:A11:max_header_action,A8:reply414 +39091C:lH3909E4|H3909F0 +3909E4:t2:A8:com_type,A7:ip_comm +3909F0:lH390AC8|H390AD4 +390AC8:t2:A7:modules,H390BA0 +390BA0:lA9:mod_alias|H390C80 +390C80:lA8:mod_auth|H390D60 +390D60:lA7:mod_esi|H390E34 +390E34:lAB:mod_actions|H390F18 +390F18:lA7:mod_cgi|H390FF4 +390FF4:lAB:mod_include|H3910D8 +3910D8:lA7:mod_dir|H3911B4 +3911B4:lA7:mod_get|H3912A0 +3912A0:lA8:mod_head|H39139C +39139C:lA7:mod_log|H3914A0 +3914A0:lAC:mod_disk_log|N +390AD4:lH390BA8|H390BB4 +390BA8:t2:AF:directory_index,H390C88 +390C88:lH390D68|N +390D68:lI105|H390E3C +390E3C:lI110|H390F20 +390F20:lI100|H390FFC +390FFC:lI101|H3910E0 +3910E0:lI120|H3911BC +3911BC:lI46|H3912A8 +3912A8:lI104|H3913A4 +3913A4:lI116|H3914A8 +3914A8:lI109|H39159C +39159C:lI108|N +390BB4:lH390C90|N +390C90:t2:AC:default_type,H390D70 +390D70:lI116|H390E44 +390E44:lI101|H390F28 +390F28:lI120|H391004 +391004:lI116|H3910E8 +3910E8:lI47|H3911C4 +3911C4:lI112|H3912B0 +3912B0:lI108|H3913AC +3913AC:lI97|H3914B0 +3914B0:lI105|H3915A4 +3915A4:lI110|N +3905EC:lI47|H390648 +390648:lI99|H3906C0 +3906C0:lI108|H390758 +390758:lI101|H390824 +390824:lI97|H390900 +390900:lI114|H3909D4 +3909D4:lI99|H390AB8 +390AB8:lI97|H390B90 +390B90:lI115|H390C70 +390C70:lI101|H390D50 +390D50:lI47|H390E24 +390E24:lI111|H390F08 +390F08:lI116|H390FEC +390FEC:lI112|H3910D0 +3910D0:lI47|H3911AC +3911AC:lI101|H391298 +391298:lI114|H391394 +391394:lI116|H391498 +391498:lI115|H391594 +391594:lI47|H391680 +391680:lI108|H39175C +39175C:lI105|H391840 +391840:lI98|H391924 +391924:lI47|H3919F8 +3919F8:lI119|H391AC4 +391AC4:lI101|H391B90 +391B90:lI98|H391C54 +391C54:lI116|H391D18 +391D18:lI111|H391DD4 +391DD4:lI111|H391E90 +391E90:lI108|H391F5C +391F5C:lI47|H392030 +392030:lI112|H3920EC +3920EC:lI114|H3921A8 +3921A8:lI105|H392264 +392264:lI118|N +3905FC:lAA:gen_server|H390664 +390664:lP<0.27.0>|H3906DC +3906DC:lA4:self|H390788 +390788:lH390848|H390854 +390848:t2:A5:local,A8:web_tool +390854:lA7:webtool|H390924 +390924:lH3909F8|H390A04 +3909F8:t2:H3905EC,H3905F4 +390A04:lN|N +3905C4:t2:AD:$initial_call,H390614 +390614:t3:A3:gen,A7:init_it,H3905FC +3905D0:t2:AA:$ancestors,H390624 +390624:lP<0.27.0>|N +=proc_dictionary:<0.41.0> +H36DF0C +H36DF18 +=proc_stack:<0.41.0> +36eda4:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AA:supervisor +y3:H36EA3C +y4:A6:websup +y5:P<0.33.0> +36edc0:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H36DF24 +=proc_heap:<0.41.0> +36EA3C:tA:A5:state,H36DF2C,AB:one_for_one,H36EA68,N,I100,I10,N,AB:webtool_sup,N +36EA68:lH36EA70|N +36EA70:t8:A5:child,P<0.48.0>,H36DF38,H36DF44,A9:permanent,I100,A6:worker,H36DF54 +36DF54:lA10:crashdump_viewer|N +36DF44:t3:A10:crashdump_viewer,AA:start_link,N +36DF38:t2:A5:local,A17:crashdump_viewer_server +36DF2C:t2:A5:local,A6:websup +36DF24:lAA:gen_server|H36DF84 +36DF84:lP<0.33.0>|H36DF94 +36DF94:lP<0.33.0>|H36DF9C +36DF9C:lH36DFA4|H36DFB0 +36DFA4:t2:A5:local,A6:websup +36DFB0:lAA:supervisor|H36DFB8 +36DFB8:lH36DFC0|H36DFD0 +36DFC0:t3:H36DF2C,AB:webtool_sup,N +36DFD0:lN|N +36DF0C:t2:AD:$initial_call,H36DF6C +36DF6C:t3:A3:gen,A7:init_it,H36DF24 +36DF18:t2:AA:$ancestors,H36DF7C +36DF7C:lA8:web_tool|H36DF8C +36DF8C:lP<0.27.0>|N +=proc_dictionary:<0.43.0> +H39D940 +H39D94C +=proc_stack:<0.43.0> +3a42ac:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AA:supervisor +y3:H3A3E34 +y4:A1A:httpd_sup__127_0_0_1__8888 +y5:P<0.33.0> +3a42c8:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H39D9CC +=proc_heap:<0.43.0> +3A3E34:tA:A5:state,H39D960,AB:one_for_one,H3A3E20,N,I0,I1,N,A9:httpd_sup,H39DA88 +39DA88:lA9:undefined|H39DB18 +39DB18:lH39DB50|H39DB58 +39DB50:lH39DB88|H39DB94 +39DB88:t2:AB:server_root,H39DBD0 +39DBD0:lI47|H39DC0C +39DC0C:lI99|H39DC50 +39DC50:lI108|H39DC84 +39DC84:lI101|H39DCC4 +39DCC4:lI97|H39DD28 +39DD28:lI114|H39DD90 +39DD90:lI99|H39DE00 +39DE00:lI97|H39DE78 +39DE78:lI115|H39DF00 +39DF00:lI101|H39DF90 +39DF90:lI47|H39E038 +39E038:lI111|H39E0E8 +39E0E8:lI116|H39E1AC +39E1AC:lI112|H39E288 +39E288:lI47|H39E37C +39E37C:lI101|H39E478 +39E478:lI114|H39E580 +39E580:lI116|H39E69C +39E69C:lI115|H39E7B0 +39E7B0:lI47|H39E8C4 +39E8C4:lI108|H39E9D8 +39E9D8:lI105|H39EACC +39EACC:lI98|H39EBC0 +39EBC0:lI47|H39ECB4 +39ECB4:lI119|H39EDA8 +39EDA8:lI101|H39EE7C +39EE7C:lI98|H39EF50 +39EF50:lI116|H39F02C +39F02C:lI111|H39F110 +39F110:lI111|H39F1E4 +39F1E4:lI108|H39F2B0 +39F2B0:lI47|H39F36C +39F36C:lI112|H39F430 +39F430:lI114|H39F4FC +39F4FC:lI105|H39F5C0 +39F5C0:lI118|H39F694 +39F694:lI47|H39F768 +39F768:lI114|H39F83C +39F83C:lI111|H39F920 +39F920:lI111|H39F9FC +39F9FC:lI116|N +39DB94:lH39DBD8|H39DBE4 +39DBD8:t2:AD:document_root,H39DC14 +39DC14:lI47|H39DC58 +39DC58:lI99|H39DC8C +39DC8C:lI108|H39DCCC +39DCCC:lI101|H39DD30 +39DD30:lI97|H39DD98 +39DD98:lI114|H39DE08 +39DE08:lI99|H39DE80 +39DE80:lI97|H39DF08 +39DF08:lI115|H39DF98 +39DF98:lI101|H39E040 +39E040:lI47|H39E0F0 +39E0F0:lI111|H39E1B4 +39E1B4:lI116|H39E290 +39E290:lI112|H39E384 +39E384:lI47|H39E480 +39E480:lI101|H39E588 +39E588:lI114|H39E6A4 +39E6A4:lI116|H39E7B8 +39E7B8:lI115|H39E8CC +39E8CC:lI47|H39E9E0 +39E9E0:lI108|H39EAD4 +39EAD4:lI105|H39EBC8 +39EBC8:lI98|H39ECBC +39ECBC:lI47|H39EDB0 +39EDB0:lI119|H39EE84 +39EE84:lI101|H39EF58 +39EF58:lI98|H39F034 +39F034:lI116|H39F118 +39F118:lI111|H39F1EC +39F1EC:lI111|H39F2B8 +39F2B8:lI108|H39F374 +39F374:lI47|H39F438 +39F438:lI112|H39F504 +39F504:lI114|H39F5C8 +39F5C8:lI105|H39F69C +39F69C:lI118|H39F770 +39F770:lI47|H39F844 +39F844:lI114|H39F928 +39F928:lI111|H39FA04 +39FA04:lI111|H39FAD8 +39FAD8:lI116|H39FBB4 +39FBB4:lI47|H39FC80 +39FC80:lI100|H39FD44 +39FD44:lI111|H39FE10 +39FE10:lI99|N +39DBE4:lH39DC1C|H39DC28 +39DC1C:t2:AA:mime_types,H39DC60 +39DC60:lH39DC94|H39DCA0 +39DC94:t2:H39DCD4,H39DCDC +39DCDC:lI120|H39DD40 +39DD40:lI45|H39DDA8 +39DDA8:lI119|H39DE10 +39DE10:lI111|H39DE88 +39DE88:lI114|H39DF10 +39DF10:lI108|H39DFA0 +39DFA0:lI100|H39E048 +39E048:lI47|H39E0F8 +39E0F8:lI120|H39E1BC +39E1BC:lI45|H39E298 +39E298:lI118|H39E38C +39E38C:lI114|H39E488 +39E488:lI109|H39E590 +39E590:lI108|N +39DCD4:lI119|H39DD38 +39DD38:lI114|H39DDA0 +39DDA0:lI108|N +39DCA0:lH39DCE4|H39DCF0 +39DCE4:t2:H39DD48,H39DD50 +39DD50:lI120|H39DDB8 +39DDB8:lI45|H39DE20 +39DE20:lI119|H39DE98 +39DE98:lI111|H39DF18 +39DF18:lI114|H39DFA8 +39DFA8:lI108|H39E050 +39E050:lI100|H39E100 +39E100:lI47|H39E1C4 +39E1C4:lI120|H39E2A0 +39E2A0:lI45|H39E394 +39E394:lI118|H39E490 +39E490:lI114|H39E598 +39E598:lI109|H39E6AC +39E6AC:lI108|N +39DD48:lI118|H39DDB0 +39DDB0:lI114|H39DE18 +39DE18:lI109|H39DE90 +39DE90:lI108|N +39DCF0:lH39DD58|H39DD64 +39DD58:t2:H39DDC0,H39DDC8 +39DDC8:lI120|H39DE30 +39DE30:lI45|H39DEA8 +39DEA8:lI99|H39DF20 +39DF20:lI111|H39DFB0 +39DFB0:lI110|H39E058 +39E058:lI102|H39E108 +39E108:lI101|H39E1CC +39E1CC:lI114|H39E2A8 +39E2A8:lI101|H39E39C +39E39C:lI110|H39E498 +39E498:lI99|H39E5A0 +39E5A0:lI101|H39E6B4 +39E6B4:lI47|H39E7C0 +39E7C0:lI120|H39E8D4 +39E8D4:lI45|H39E9E8 +39E9E8:lI99|H39EADC +39EADC:lI111|H39EBD0 +39EBD0:lI111|H39ECC4 +39ECC4:lI108|H39EDB8 +39EDB8:lI116|H39EE8C +39EE8C:lI97|H39EF60 +39EF60:lI108|H39F03C +39F03C:lI107|N +39DDC0:lI105|H39DE28 +39DE28:lI99|H39DEA0 +39DEA0:lI101|N +39DD64:lH39DDD0|H39DDDC +39DDD0:t2:H39DE38,H39DE40 +39DE40:lI118|H39DEB8 +39DEB8:lI105|H39DF30 +39DF30:lI100|H39DFC0 +39DFC0:lI101|H39E068 +39E068:lI111|H39E110 +39E110:lI47|H39E1D4 +39E1D4:lI120|H39E2B0 +39E2B0:lI45|H39E3A4 +39E3A4:lI115|H39E4A0 +39E4A0:lI103|H39E5A8 +39E5A8:lI105|H39E6BC +39E6BC:lI45|H39E7C8 +39E7C8:lI109|H39E8DC +39E8DC:lI111|H39E9F0 +39E9F0:lI118|H39EAE4 +39EAE4:lI105|H39EBD8 +39EBD8:lI101|N +39DE38:lI109|H39DEB0 +39DEB0:lI111|H39DF28 +39DF28:lI118|H39DFB8 +39DFB8:lI105|H39E060 +39E060:lI101|N +39DDDC:lH39DE48|H39DE54 +39DE48:t2:H39DEC0,H39DEC8 +39DEC8:lI118|H39DF40 +39DF40:lI105|H39DFD0 +39DFD0:lI100|H39E070 +39E070:lI101|H39E118 +39E118:lI111|H39E1DC +39E1DC:lI47|H39E2B8 +39E2B8:lI120|H39E3AC +39E3AC:lI45|H39E4A8 +39E4A8:lI109|H39E5B0 +39E5B0:lI115|H39E6C4 +39E6C4:lI118|H39E7D0 +39E7D0:lI105|H39E8E4 +39E8E4:lI100|H39E9F8 +39E9F8:lI101|H39EAEC +39EAEC:lI111|N +39DEC0:lI97|H39DF38 +39DF38:lI118|H39DFC8 +39DFC8:lI105|N +39DE54:lH39DED0|H39DEDC +39DED0:t2:H39DF48,H39DF50 +39DF50:lI118|H39DFE0 +39DFE0:lI105|H39E078 +39E078:lI100|H39E120 +39E120:lI101|H39E1E4 +39E1E4:lI111|H39E2C0 +39E2C0:lI47|H39E3B4 +39E3B4:lI113|H39E4B0 +39E4B0:lI117|H39E5B8 +39E5B8:lI105|H39E6CC +39E6CC:lI99|H39E7D8 +39E7D8:lI107|H39E8EC +39E8EC:lI116|H39EA00 +39EA00:lI105|H39EAF4 +39EAF4:lI109|H39EBE0 +39EBE0:lI101|N +39DF48:lI113|H39DFD8 +39DFD8:lI116|N +39DEDC:lH39DF58|H39DF64 +39DF58:t2:H39DFE8,H39DFF0 +39DFF0:lI118|H39E088 +39E088:lI105|H39E130 +39E130:lI100|H39E1EC +39E1EC:lI101|H39E2C8 +39E2C8:lI111|H39E3BC +39E3BC:lI47|H39E4B8 +39E4B8:lI113|H39E5C0 +39E5C0:lI117|H39E6D4 +39E6D4:lI105|H39E7E0 +39E7E0:lI99|H39E8F4 +39E8F4:lI107|H39EA08 +39EA08:lI116|H39EAFC +39EAFC:lI105|H39EBE8 +39EBE8:lI109|H39ECCC +39ECCC:lI101|N +39DFE8:lI109|H39E080 +39E080:lI111|H39E128 +39E128:lI118|N +39DF64:lH39DFF8|H39E004 +39DFF8:t2:H39E090,H39E098 +39E098:lI118|H39E140 +39E140:lI105|H39E1FC +39E1FC:lI100|H39E2D8 +39E2D8:lI101|H39E3C4 +39E3C4:lI111|H39E4C0 +39E4C0:lI47|H39E5C8 +39E5C8:lI109|H39E6DC +39E6DC:lI112|H39E7E8 +39E7E8:lI101|H39E8FC +39E8FC:lI103|N +39E090:lI109|H39E138 +39E138:lI112|H39E1F4 +39E1F4:lI101|H39E2D0 +39E2D0:lI103|N +39E004:lH39E0A0|H39E0AC +39E0A0:t2:H39E148,H39E150 +39E150:lI118|H39E20C +39E20C:lI105|H39E2E8 +39E2E8:lI100|H39E3CC +39E3CC:lI101|H39E4C8 +39E4C8:lI111|H39E5D0 +39E5D0:lI47|H39E6E4 +39E6E4:lI109|H39E7F0 +39E7F0:lI112|H39E904 +39E904:lI101|H39EA10 +39EA10:lI103|N +39E148:lI109|H39E204 +39E204:lI112|H39E2E0 +39E2E0:lI103|N +39E0AC:lH39E158|H39E164 +39E158:t2:H39E214,H39E21C +39E21C:lI118|H39E2F8 +39E2F8:lI105|H39E3DC +39E3DC:lI100|H39E4D0 +39E4D0:lI101|H39E5D8 +39E5D8:lI111|H39E6EC +39E6EC:lI47|H39E7F8 +39E7F8:lI109|H39E90C +39E90C:lI112|H39EA18 +39EA18:lI101|H39EB04 +39EB04:lI103|N +39E214:lI109|H39E2F0 +39E2F0:lI112|H39E3D4 +39E3D4:lI101|N +39E164:lH39E224|H39E230 +39E224:t2:H39E300,H39E308 +39E308:lI116|H39E3EC +39E3EC:lI101|H39E4E0 +39E4E0:lI120|H39E5E8 +39E5E8:lI116|H39E6F4 +39E6F4:lI47|H39E800 +39E800:lI120|H39E914 +39E914:lI45|H39EA20 +39EA20:lI115|H39EB0C +39EB0C:lI103|H39EBF0 +39EBF0:lI109|H39ECD4 +39ECD4:lI108|N +39E300:lI115|H39E3E4 +39E3E4:lI103|H39E4D8 +39E4D8:lI109|H39E5E0 +39E5E0:lI108|N +39E230:lH39E310|H39E31C +39E310:t2:H39E3F4,H39E3FC +39E3FC:lI116|H39E4F0 +39E4F0:lI101|H39E5F8 +39E5F8:lI120|H39E6FC +39E6FC:lI116|H39E808 +39E808:lI47|H39E91C +39E91C:lI120|H39EA28 +39EA28:lI45|H39EB14 +39EB14:lI115|H39EBF8 +39EBF8:lI103|H39ECDC +39ECDC:lI109|H39EDC0 +39EDC0:lI108|N +39E3F4:lI115|H39E4E8 +39E4E8:lI103|H39E5F0 +39E5F0:lI109|N +39E31C:lH39E404|H39E410 +39E404:t2:H39E4F8,H39E500 +39E500:lI116|H39E608 +39E608:lI101|H39E70C +39E70C:lI120|H39E810 +39E810:lI116|H39E924 +39E924:lI47|H39EA30 +39EA30:lI120|H39EB1C +39EB1C:lI45|H39EC00 +39EC00:lI115|H39ECE4 +39ECE4:lI101|H39EDC8 +39EDC8:lI116|H39EE94 +39EE94:lI101|H39EF68 +39EF68:lI120|H39F044 +39F044:lI116|N +39E4F8:lI101|H39E600 +39E600:lI116|H39E704 +39E704:lI120|N +39E410:lH39E508|H39E514 +39E508:t2:H39E610,H39E618 +39E618:lI116|H39E71C +39E71C:lI101|H39E820 +39E820:lI120|H39E92C +39E92C:lI116|H39EA38 +39EA38:lI47|H39EB24 +39EB24:lI116|H39EC08 +39EC08:lI97|H39ECEC +39ECEC:lI98|H39EDD0 +39EDD0:lI45|H39EE9C +39EE9C:lI115|H39EF70 +39EF70:lI101|H39F04C +39F04C:lI112|H39F120 +39F120:lI97|H39F1F4 +39F1F4:lI114|H39F2C0 +39F2C0:lI97|H39F37C +39F37C:lI116|H39F440 +39F440:lI101|H39F50C +39F50C:lI100|H39F5D0 +39F5D0:lI45|H39F6A4 +39F6A4:lI118|H39F778 +39F778:lI97|H39F84C +39F84C:lI108|H39F930 +39F930:lI117|H39FA0C +39FA0C:lI101|H39FAE0 +39FAE0:lI115|N +39E610:lI116|H39E714 +39E714:lI115|H39E818 +39E818:lI118|N +39E514:lH39E620|H39E62C +39E620:t2:H39E724,H39E72C +39E72C:lI116|H39E830 +39E830:lI101|H39E93C +39E93C:lI120|H39EA40 +39EA40:lI116|H39EB2C +39EB2C:lI47|H39EC10 +39EC10:lI114|H39ECF4 +39ECF4:lI105|H39EDD8 +39EDD8:lI99|H39EEA4 +39EEA4:lI104|H39EF78 +39EF78:lI116|H39F054 +39F054:lI101|H39F128 +39F128:lI120|H39F1FC +39F1FC:lI116|N +39E724:lI114|H39E828 +39E828:lI116|H39E934 +39E934:lI120|N +39E62C:lH39E734|H39E740 +39E734:t2:H39E838,H39E840 +39E840:lI116|H39E94C +39E94C:lI101|H39EA50 +39EA50:lI120|H39EB34 +39EB34:lI116|H39EC18 +39EC18:lI47|H39ECFC +39ECFC:lI112|H39EDE0 +39EDE0:lI108|H39EEAC +39EEAC:lI97|H39EF80 +39EF80:lI105|H39F05C +39F05C:lI110|N +39E838:lI116|H39E944 +39E944:lI120|H39EA48 +39EA48:lI116|N +39E740:lH39E848|H39E854 +39E848:t2:H39E954,H39E95C +39E95C:lI116|H39EA60 +39EA60:lI101|H39EB44 +39EB44:lI120|H39EC28 +39EC28:lI116|H39ED0C +39ED0C:lI47|H39EDE8 +39EDE8:lI120|H39EEB4 +39EEB4:lI45|H39EF88 +39EF88:lI115|H39F064 +39F064:lI101|H39F130 +39F130:lI114|H39F204 +39F204:lI118|H39F2C8 +39F2C8:lI101|H39F384 +39F384:lI114|H39F448 +39F448:lI45|H39F514 +39F514:lI112|H39F5D8 +39F5D8:lI97|H39F6AC +39F6AC:lI114|H39F780 +39F780:lI115|H39F854 +39F854:lI101|H39F938 +39F938:lI100|H39FA14 +39FA14:lI45|H39FAE8 +39FAE8:lI104|H39FBBC +39FBBC:lI116|H39FC88 +39FC88:lI109|H39FD4C +39FD4C:lI108|N +39E954:lI115|H39EA58 +39EA58:lI104|H39EB3C +39EB3C:lI116|H39EC20 +39EC20:lI109|H39ED04 +39ED04:lI108|N +39E854:lH39E964|H39E970 +39E964:t2:H39EA68,H39EA70 +39EA70:lI116|H39EB54 +39EB54:lI101|H39EC38 +39EC38:lI120|H39ED1C +39ED1C:lI116|H39EDF0 +39EDF0:lI47|H39EEBC +39EEBC:lI104|H39EF90 +39EF90:lI116|H39F06C +39F06C:lI109|H39F138 +39F138:lI108|N +39EA68:lI104|H39EB4C +39EB4C:lI116|H39EC30 +39EC30:lI109|H39ED14 +39ED14:lI108|N +39E970:lH39EA78|H39EA84 +39EA78:t2:H39EB5C,H39EB64 +39EB64:lI116|H39EC48 +39EC48:lI101|H39ED2C +39ED2C:lI120|H39EDF8 +39EDF8:lI116|H39EEC4 +39EEC4:lI47|H39EF98 +39EF98:lI104|H39F074 +39F074:lI116|H39F140 +39F140:lI109|H39F20C +39F20C:lI108|N +39EB5C:lI104|H39EC40 +39EC40:lI116|H39ED24 +39ED24:lI109|N +39EA84:lH39EB6C|H39EB78 +39EB6C:t2:H39EC50,H39EC58 +39EC58:lI105|H39ED3C +39ED3C:lI109|H39EE08 +39EE08:lI97|H39EECC +39EECC:lI103|H39EFA0 +39EFA0:lI101|H39F07C +39F07C:lI47|H39F148 +39F148:lI120|H39F214 +39F214:lI45|H39F2D0 +39F2D0:lI120|H39F38C +39F38C:lI119|H39F450 +39F450:lI105|H39F51C +39F51C:lI110|H39F5E0 +39F5E0:lI100|H39F6B4 +39F6B4:lI111|H39F788 +39F788:lI119|H39F85C +39F85C:lI100|H39F940 +39F940:lI117|H39FA1C +39FA1C:lI109|H39FAF0 +39FAF0:lI112|N +39EC50:lI120|H39ED34 +39ED34:lI119|H39EE00 +39EE00:lI100|N +39EB78:lH39EC60|H39EC6C +39EC60:t2:H39ED44,H39ED4C +39ED4C:lI105|H39EE18 +39EE18:lI109|H39EEDC +39EEDC:lI97|H39EFA8 +39EFA8:lI103|H39F084 +39F084:lI101|H39F150 +39F150:lI47|H39F21C +39F21C:lI120|H39F2D8 +39F2D8:lI45|H39F394 +39F394:lI120|H39F458 +39F458:lI112|H39F524 +39F524:lI105|H39F5E8 +39F5E8:lI120|H39F6BC +39F6BC:lI109|H39F790 +39F790:lI97|H39F864 +39F864:lI112|N +39ED44:lI120|H39EE10 +39EE10:lI112|H39EED4 +39EED4:lI109|N +39EC6C:lH39ED54|H39ED60 +39ED54:t2:H39EE20,H39EE28 +39EE28:lI105|H39EEEC +39EEEC:lI109|H39EFB8 +39EFB8:lI97|H39F08C +39F08C:lI103|H39F158 +39F158:lI101|H39F224 +39F224:lI47|H39F2E0 +39F2E0:lI120|H39F39C +39F39C:lI45|H39F460 +39F460:lI120|H39F52C +39F52C:lI98|H39F5F0 +39F5F0:lI105|H39F6C4 +39F6C4:lI116|H39F798 +39F798:lI109|H39F86C +39F86C:lI97|H39F948 +39F948:lI112|N +39EE20:lI120|H39EEE4 +39EEE4:lI98|H39EFB0 +39EFB0:lI109|N +39ED60:lH39EE30|H39EE3C +39EE30:t2:H39EEF4,H39EEFC +39EEFC:lI105|H39EFC8 +39EFC8:lI109|H39F09C +39F09C:lI97|H39F160 +39F160:lI103|H39F22C +39F22C:lI101|H39F2E8 +39F2E8:lI47|H39F3A4 +39F3A4:lI120|H39F468 +39F468:lI45|H39F534 +39F534:lI114|H39F5F8 +39F5F8:lI103|H39F6CC +39F6CC:lI98|N +39EEF4:lI114|H39EFC0 +39EFC0:lI103|H39F094 +39F094:lI98|N +39EE3C:lH39EF04|H39EF10 +39EF04:t2:H39EFD0,H39EFD8 +39EFD8:lI105|H39F0AC +39F0AC:lI109|H39F170 +39F170:lI97|H39F234 +39F234:lI103|H39F2F0 +39F2F0:lI101|H39F3AC +39F3AC:lI47|H39F470 +39F470:lI120|H39F53C +39F53C:lI45|H39F600 +39F600:lI112|H39F6D4 +39F6D4:lI111|H39F7A0 +39F7A0:lI114|H39F874 +39F874:lI116|H39F950 +39F950:lI97|H39FA24 +39FA24:lI98|H39FAF8 +39FAF8:lI108|H39FBC4 +39FBC4:lI101|H39FC90 +39FC90:lI45|H39FD54 +39FD54:lI112|H39FE18 +39FE18:lI105|H39FECC +39FECC:lI120|H39FF88 +39FF88:lI109|H3A003C +3A003C:lI97|H3A00E8 +3A00E8:lI112|N +39EFD0:lI112|H39F0A4 +39F0A4:lI112|H39F168 +39F168:lI109|N +39EF10:lH39EFE0|H39EFEC +39EFE0:t2:H39F0B4,H39F0BC +39F0BC:lI105|H39F180 +39F180:lI109|H39F244 +39F244:lI97|H39F2F8 +39F2F8:lI103|H39F3B4 +39F3B4:lI101|H39F478 +39F478:lI47|H39F544 +39F544:lI120|H39F608 +39F608:lI45|H39F6DC +39F6DC:lI112|H39F7A8 +39F7A8:lI111|H39F87C +39F87C:lI114|H39F958 +39F958:lI116|H39FA2C +39FA2C:lI97|H39FB00 +39FB00:lI98|H39FBCC +39FBCC:lI108|H39FC98 +39FC98:lI101|H39FD5C +39FD5C:lI45|H39FE20 +39FE20:lI103|H39FED4 +39FED4:lI114|H39FF90 +39FF90:lI97|H3A0044 +3A0044:lI121|H3A00F0 +3A00F0:lI109|H3A0194 +3A0194:lI97|H3A0248 +3A0248:lI112|N +39F0B4:lI112|H39F178 +39F178:lI103|H39F23C +39F23C:lI109|N +39EFEC:lH39F0C4|H39F0D0 +39F0C4:t2:H39F188,H39F190 +39F190:lI105|H39F254 +39F254:lI109|H39F308 +39F308:lI97|H39F3BC +39F3BC:lI103|H39F480 +39F480:lI101|H39F54C +39F54C:lI47|H39F610 +39F610:lI120|H39F6E4 +39F6E4:lI45|H39F7B0 +39F7B0:lI112|H39F884 +39F884:lI111|H39F960 +39F960:lI114|H39FA34 +39FA34:lI116|H39FB08 +39FB08:lI97|H39FBD4 +39FBD4:lI98|H39FCA0 +39FCA0:lI108|H39FD64 +39FD64:lI101|H39FE28 +39FE28:lI45|H39FEDC +39FEDC:lI98|H39FF98 +39FF98:lI105|H3A004C +3A004C:lI116|H3A00F8 +3A00F8:lI109|H3A019C +3A019C:lI97|H3A0250 +3A0250:lI112|N +39F188:lI112|H39F24C +39F24C:lI98|H39F300 +39F300:lI109|N +39F0D0:lH39F198|H39F1A4 +39F198:t2:H39F25C,H39F264 +39F264:lI105|H39F318 +39F318:lI109|H39F3CC +39F3CC:lI97|H39F488 +39F488:lI103|H39F554 +39F554:lI101|H39F618 +39F618:lI47|H39F6EC +39F6EC:lI120|H39F7B8 +39F7B8:lI45|H39F88C +39F88C:lI112|H39F968 +39F968:lI111|H39FA3C +39FA3C:lI114|H39FB10 +39FB10:lI116|H39FBDC +39FBDC:lI97|H39FCA8 +39FCA8:lI98|H39FD6C +39FD6C:lI108|H39FE30 +39FE30:lI101|H39FEE4 +39FEE4:lI45|H39FFA0 +39FFA0:lI97|H3A0054 +3A0054:lI110|H3A0100 +3A0100:lI121|H3A01A4 +3A01A4:lI109|H3A0258 +3A0258:lI97|H3A0304 +3A0304:lI112|N +39F25C:lI112|H39F310 +39F310:lI110|H39F3C4 +39F3C4:lI109|N +39F1A4:lH39F26C|H39F278 +39F26C:t2:H39F320,H39F328 +39F328:lI105|H39F3DC +39F3DC:lI109|H39F498 +39F498:lI97|H39F55C +39F55C:lI103|H39F620 +39F620:lI101|H39F6F4 +39F6F4:lI47|H39F7C0 +39F7C0:lI120|H39F894 +39F894:lI45|H39F970 +39F970:lI99|H39FA44 +39FA44:lI109|H39FB18 +39FB18:lI117|H39FBE4 +39FBE4:lI45|H39FCB0 +39FCB0:lI114|H39FD74 +39FD74:lI97|H39FE38 +39FE38:lI115|H39FEEC +39FEEC:lI116|H39FFA8 +39FFA8:lI101|H3A005C +3A005C:lI114|N +39F320:lI114|H39F3D4 +39F3D4:lI97|H39F490 +39F490:lI115|N +39F278:lH39F330|H39F33C +39F330:t2:H39F3E4,H39F3EC +39F3EC:lI105|H39F4A8 +39F4A8:lI109|H39F56C +39F56C:lI97|H39F630 +39F630:lI103|H39F6FC +39F6FC:lI101|H39F7C8 +39F7C8:lI47|H39F89C +39F89C:lI116|H39F978 +39F978:lI105|H39FA4C +39FA4C:lI102|H39FB20 +39FB20:lI102|N +39F3E4:lI116|H39F4A0 +39F4A0:lI105|H39F564 +39F564:lI102|H39F628 +39F628:lI102|N +39F33C:lH39F3F4|H39F400 +39F3F4:t2:H39F4B0,H39F4B8 +39F4B8:lI105|H39F57C +39F57C:lI109|H39F640 +39F640:lI97|H39F704 +39F704:lI103|H39F7D0 +39F7D0:lI101|H39F8A4 +39F8A4:lI47|H39F980 +39F980:lI116|H39FA54 +39FA54:lI105|H39FB28 +39FB28:lI102|H39FBEC +39FBEC:lI102|N +39F4B0:lI116|H39F574 +39F574:lI105|H39F638 +39F638:lI102|N +39F400:lH39F4C0|H39F4CC +39F4C0:t2:H39F584,H39F58C +39F58C:lI105|H39F650 +39F650:lI109|H39F714 +39F714:lI97|H39F7D8 +39F7D8:lI103|H39F8AC +39F8AC:lI101|H39F988 +39F988:lI47|H39FA5C +39FA5C:lI112|H39FB30 +39FB30:lI110|H39FBF4 +39FBF4:lI103|N +39F584:lI112|H39F648 +39F648:lI110|H39F70C +39F70C:lI103|N +39F4CC:lH39F594|H39F5A0 +39F594:t2:H39F658,H39F660 +39F660:lI105|H39F724 +39F724:lI109|H39F7E8 +39F7E8:lI97|H39F8BC +39F8BC:lI103|H39F990 +39F990:lI101|H39FA64 +39FA64:lI47|H39FB38 +39FB38:lI106|H39FBFC +39FBFC:lI112|H39FCB8 +39FCB8:lI101|H39FD7C +39FD7C:lI103|N +39F658:lI106|H39F71C +39F71C:lI112|H39F7E0 +39F7E0:lI101|H39F8B4 +39F8B4:lI103|N +39F5A0:lH39F668|H39F674 +39F668:t2:H39F72C,H39F734 +39F734:lI105|H39F7F8 +39F7F8:lI109|H39F8CC +39F8CC:lI97|H39F998 +39F998:lI103|H39FA6C +39FA6C:lI101|H39FB40 +39FB40:lI47|H39FC04 +39FC04:lI106|H39FCC0 +39FCC0:lI112|H39FD84 +39FD84:lI101|H39FE40 +39FE40:lI103|N +39F72C:lI106|H39F7F0 +39F7F0:lI112|H39F8C4 +39F8C4:lI103|N +39F674:lH39F73C|H39F748 +39F73C:t2:H39F800,H39F808 +39F808:lI105|H39F8DC +39F8DC:lI109|H39F9A8 +39F9A8:lI97|H39FA74 +39FA74:lI103|H39FB48 +39FB48:lI101|H39FC0C +39FC0C:lI47|H39FCC8 +39FCC8:lI106|H39FD8C +39FD8C:lI112|H39FE48 +39FE48:lI101|H39FEF4 +39FEF4:lI103|N +39F800:lI106|H39F8D4 +39F8D4:lI112|H39F9A0 +39F9A0:lI101|N +39F748:lH39F810|H39F81C +39F810:t2:H39F8E4,H39F8EC +39F8EC:lI105|H39F9B8 +39F9B8:lI109|H39FA84 +39FA84:lI97|H39FB50 +39FB50:lI103|H39FC14 +39FC14:lI101|H39FCD0 +39FCD0:lI47|H39FD94 +39FD94:lI105|H39FE50 +39FE50:lI101|H39FEFC +39FEFC:lI102|N +39F8E4:lI105|H39F9B0 +39F9B0:lI101|H39FA7C +39FA7C:lI102|N +39F81C:lH39F8F4|H39F900 +39F8F4:t2:H39F9C0,H39F9C8 +39F9C8:lI105|H39FA94 +39FA94:lI109|H39FB60 +39FB60:lI97|H39FC1C +39FC1C:lI103|H39FCD8 +39FCD8:lI101|H39FD9C +39FD9C:lI47|H39FE58 +39FE58:lI103|H39FF04 +39FF04:lI105|H39FFB0 +39FFB0:lI102|N +39F9C0:lI103|H39FA8C +39FA8C:lI105|H39FB58 +39FB58:lI102|N +39F900:lH39F9D0|H39F9DC +39F9D0:t2:H39FA9C,H39FAA4 +39FAA4:lI99|H39FB70 +39FB70:lI104|H39FC2C +39FC2C:lI101|H39FCE0 +39FCE0:lI109|H39FDA4 +39FDA4:lI105|H39FE60 +39FE60:lI99|H39FF0C +39FF0C:lI97|H39FFB8 +39FFB8:lI108|H3A0064 +3A0064:lI47|H3A0108 +3A0108:lI120|H3A01AC +3A01AC:lI45|H3A0260 +3A0260:lI112|H3A030C +3A030C:lI100|H3A03B8 +3A03B8:lI98|N +39FA9C:lI112|H39FB68 +39FB68:lI100|H39FC24 +39FC24:lI98|N +39F9DC:lH39FAAC|H39FAB8 +39FAAC:t2:H39FB78,H39FB80 +39FB80:lI99|H39FC3C +39FC3C:lI104|H39FCF0 +39FCF0:lI101|H39FDAC +39FDAC:lI109|H39FE68 +39FE68:lI105|H39FF14 +39FF14:lI99|H39FFC0 +39FFC0:lI97|H3A006C +3A006C:lI108|H3A0110 +3A0110:lI47|H3A01B4 +3A01B4:lI120|H3A0268 +3A0268:lI45|H3A0314 +3A0314:lI112|H3A03C0 +3A03C0:lI100|H3A0454 +3A0454:lI98|N +39FB78:lI120|H39FC34 +39FC34:lI121|H39FCE8 +39FCE8:lI122|N +39FAB8:lH39FB88|H39FB94 +39FB88:t2:H39FC44,H39FC4C +39FC4C:lI97|H39FD00 +39FD00:lI117|H39FDBC +39FDBC:lI100|H39FE70 +39FE70:lI105|H39FF1C +39FF1C:lI111|H39FFC8 +39FFC8:lI47|H3A0074 +3A0074:lI120|H3A0118 +3A0118:lI45|H3A01BC +3A01BC:lI119|H3A0270 +3A0270:lI97|H3A031C +3A031C:lI118|N +39FC44:lI119|H39FCF8 +39FCF8:lI97|H39FDB4 +39FDB4:lI118|N +39FB94:lH39FC54|H39FC60 +39FC54:t2:H39FD08,H39FD10 +39FD10:lI97|H39FDCC +39FDCC:lI117|H39FE78 +39FE78:lI100|H39FF24 +39FF24:lI105|H39FFD0 +39FFD0:lI111|H3A007C +3A007C:lI47|H3A0120 +3A0120:lI120|H3A01C4 +3A01C4:lI45|H3A0278 +3A0278:lI114|H3A0324 +3A0324:lI101|H3A03C8 +3A03C8:lI97|H3A045C +3A045C:lI108|H3A04F8 +3A04F8:lI97|H3A059C +3A059C:lI117|H3A0648 +3A0648:lI100|H3A06F4 +3A06F4:lI105|H3A07A0 +3A07A0:lI111|N +39FD08:lI114|H39FDC4 +39FDC4:lI97|N +39FC60:lH39FD18|H39FD24 +39FD18:t2:H39FDD4,H39FDDC +39FDDC:lI97|H39FE88 +39FE88:lI117|H39FF34 +39FF34:lI100|H39FFD8 +39FFD8:lI105|H3A0084 +3A0084:lI111|H3A0128 +3A0128:lI47|H3A01CC +3A01CC:lI120|H3A0280 +3A0280:lI45|H3A032C +3A032C:lI112|H3A03D0 +3A03D0:lI110|H3A0464 +3A0464:lI45|H3A0500 +3A0500:lI114|H3A05A4 +3A05A4:lI101|H3A0650 +3A0650:lI97|H3A06FC +3A06FC:lI108|H3A07A8 +3A07A8:lI97|H3A0844 +3A0844:lI117|H3A08D0 +3A08D0:lI100|H3A0964 +3A0964:lI105|H3A09F8 +3A09F8:lI111|H3A0A94 +3A0A94:lI45|H3A0B40 +3A0B40:lI112|H3A0BEC +3A0BEC:lI108|H3A0CA8 +3A0CA8:lI117|H3A0D64 +3A0D64:lI103|H3A0E18 +3A0E18:lI105|H3A0ECC +3A0ECC:lI110|N +39FDD4:lI114|H39FE80 +39FE80:lI112|H39FF2C +39FF2C:lI109|N +39FD24:lH39FDE4|H39FDF0 +39FDE4:t2:H39FE90,H39FE98 +39FE98:lI97|H39FF44 +39FF44:lI117|H39FFE8 +39FFE8:lI100|H3A008C +3A008C:lI105|H3A0130 +3A0130:lI111|H3A01D4 +3A01D4:lI47|H3A0288 +3A0288:lI120|H3A0334 +3A0334:lI45|H3A03D8 +3A03D8:lI112|H3A046C +3A046C:lI110|H3A0508 +3A0508:lI45|H3A05AC +3A05AC:lI114|H3A0658 +3A0658:lI101|H3A0704 +3A0704:lI97|H3A07B0 +3A07B0:lI108|H3A084C +3A084C:lI97|H3A08D8 +3A08D8:lI117|H3A096C +3A096C:lI100|H3A0A00 +3A0A00:lI105|H3A0A9C +3A0A9C:lI111|N +39FE90:lI114|H39FF3C +39FF3C:lI97|H39FFE0 +39FFE0:lI109|N +39FDF0:lH39FEA0|H39FEAC +39FEA0:t2:H39FF4C,H39FF54 +39FF54:lI97|H39FFF8 +39FFF8:lI117|H3A009C +3A009C:lI100|H3A0138 +3A0138:lI105|H3A01DC +3A01DC:lI111|H3A0290 +3A0290:lI47|H3A033C +3A033C:lI120|H3A03E0 +3A03E0:lI45|H3A0474 +3A0474:lI97|H3A0510 +3A0510:lI105|H3A05B4 +3A05B4:lI102|H3A0660 +3A0660:lI102|N +39FF4C:lI97|H39FFF0 +39FFF0:lI105|H3A0094 +3A0094:lI102|N +39FEAC:lH39FF5C|H39FF68 +39FF5C:t2:H3A0000,H3A0008 +3A0008:lI97|H3A00AC +3A00AC:lI117|H3A0148 +3A0148:lI100|H3A01EC +3A01EC:lI105|H3A0298 +3A0298:lI111|H3A0344 +3A0344:lI47|H3A03E8 +3A03E8:lI120|H3A047C +3A047C:lI45|H3A0518 +3A0518:lI97|H3A05BC +3A05BC:lI105|H3A0668 +3A0668:lI102|H3A070C +3A070C:lI102|N +3A0000:lI97|H3A00A4 +3A00A4:lI105|H3A0140 +3A0140:lI102|H3A01E4 +3A01E4:lI102|N +39FF68:lH3A0010|H3A001C +3A0010:t2:H3A00B4,H3A00BC +3A00BC:lI97|H3A0158 +3A0158:lI117|H3A01FC +3A01FC:lI100|H3A02A8 +3A02A8:lI105|H3A034C +3A034C:lI111|H3A03F0 +3A03F0:lI47|H3A0484 +3A0484:lI120|H3A0520 +3A0520:lI45|H3A05C4 +3A05C4:lI97|H3A0670 +3A0670:lI105|H3A0714 +3A0714:lI102|H3A07B8 +3A07B8:lI102|N +3A00B4:lI97|H3A0150 +3A0150:lI105|H3A01F4 +3A01F4:lI102|H3A02A0 +3A02A0:lI99|N +3A001C:lH3A00C4|H3A00D0 +3A00C4:t2:H3A0160,H3A0168 +3A0168:lI97|H3A020C +3A020C:lI117|H3A02B8 +3A02B8:lI100|H3A035C +3A035C:lI105|H3A03F8 +3A03F8:lI111|H3A048C +3A048C:lI47|H3A0528 +3A0528:lI109|H3A05CC +3A05CC:lI112|H3A0678 +3A0678:lI101|H3A071C +3A071C:lI103|N +3A0160:lI109|H3A0204 +3A0204:lI112|H3A02B0 +3A02B0:lI103|H3A0354 +3A0354:lI97|N +3A00D0:lH3A0170|H3A017C +3A0170:t2:H3A0214,H3A021C +3A021C:lI97|H3A02C8 +3A02C8:lI117|H3A036C +3A036C:lI100|H3A0400 +3A0400:lI105|H3A0494 +3A0494:lI111|H3A0530 +3A0530:lI47|H3A05D4 +3A05D4:lI109|H3A0680 +3A0680:lI112|H3A0724 +3A0724:lI101|H3A07C0 +3A07C0:lI103|N +3A0214:lI109|H3A02C0 +3A02C0:lI112|H3A0364 +3A0364:lI50|N +3A017C:lH3A0224|H3A0230 +3A0224:t2:H3A02D0,H3A02D8 +3A02D8:lI97|H3A037C +3A037C:lI117|H3A0408 +3A0408:lI100|H3A049C +3A049C:lI105|H3A0538 +3A0538:lI111|H3A05DC +3A05DC:lI47|H3A0688 +3A0688:lI98|H3A072C +3A072C:lI97|H3A07C8 +3A07C8:lI115|H3A0854 +3A0854:lI105|H3A08E0 +3A08E0:lI99|N +3A02D0:lI97|H3A0374 +3A0374:lI117|N +3A0230:lH3A02E0|H3A02EC +3A02E0:t2:H3A0384,H3A038C +3A038C:lI97|H3A0418 +3A0418:lI117|H3A04AC +3A04AC:lI100|H3A0540 +3A0540:lI105|H3A05E4 +3A05E4:lI111|H3A0690 +3A0690:lI47|H3A0734 +3A0734:lI98|H3A07D0 +3A07D0:lI97|H3A085C +3A085C:lI115|H3A08E8 +3A08E8:lI105|H3A0974 +3A0974:lI99|N +3A0384:lI115|H3A0410 +3A0410:lI110|H3A04A4 +3A04A4:lI100|N +3A02EC:lH3A0394|H3A03A0 +3A0394:t2:H3A0420,H3A0428 +3A0428:lI97|H3A04BC +3A04BC:lI112|H3A0550 +3A0550:lI112|H3A05EC +3A05EC:lI108|H3A0698 +3A0698:lI105|H3A073C +3A073C:lI99|H3A07D8 +3A07D8:lI97|H3A0864 +3A0864:lI116|H3A08F0 +3A08F0:lI105|H3A097C +3A097C:lI111|H3A0A08 +3A0A08:lI110|H3A0AA4 +3A0AA4:lI47|H3A0B48 +3A0B48:lI122|H3A0BF4 +3A0BF4:lI105|H3A0CB0 +3A0CB0:lI112|N +3A0420:lI122|H3A04B4 +3A04B4:lI105|H3A0548 +3A0548:lI112|N +3A03A0:lH3A0430|H3A043C +3A0430:t2:H3A04C4,H3A04CC +3A04CC:lI97|H3A0560 +3A0560:lI112|H3A05FC +3A05FC:lI112|H3A06A0 +3A06A0:lI108|H3A0744 +3A0744:lI105|H3A07E0 +3A07E0:lI99|H3A086C +3A086C:lI97|H3A08F8 +3A08F8:lI116|H3A0984 +3A0984:lI105|H3A0A10 +3A0A10:lI111|H3A0AAC +3A0AAC:lI110|H3A0B50 +3A0B50:lI47|H3A0BFC +3A0BFC:lI120|H3A0CB8 +3A0CB8:lI45|H3A0D6C +3A0D6C:lI119|H3A0E20 +3A0E20:lI97|H3A0ED4 +3A0ED4:lI105|H3A0F90 +3A0F90:lI115|H3A105C +3A105C:lI45|H3A1130 +3A1130:lI115|H3A1204 +3A1204:lI111|H3A12D0 +3A12D0:lI117|H3A13A4 +3A13A4:lI114|H3A1480 +3A1480:lI99|H3A1564 +3A1564:lI101|N +3A04C4:lI115|H3A0558 +3A0558:lI114|H3A05F4 +3A05F4:lI99|N +3A043C:lH3A04D4|H3A04E0 +3A04D4:t2:H3A0568,H3A0570 +3A0570:lI97|H3A060C +3A060C:lI112|H3A06B0 +3A06B0:lI112|H3A0754 +3A0754:lI108|H3A07F0 +3A07F0:lI105|H3A0874 +3A0874:lI99|H3A0900 +3A0900:lI97|H3A098C +3A098C:lI116|H3A0A18 +3A0A18:lI105|H3A0AB4 +3A0AB4:lI111|H3A0B58 +3A0B58:lI110|H3A0C04 +3A0C04:lI47|H3A0CC0 +3A0CC0:lI120|H3A0D74 +3A0D74:lI45|H3A0E28 +3A0E28:lI117|H3A0EDC +3A0EDC:lI115|H3A0F98 +3A0F98:lI116|H3A1064 +3A1064:lI97|H3A1138 +3A1138:lI114|N +3A0568:lI117|H3A0604 +3A0604:lI115|H3A06A8 +3A06A8:lI116|H3A074C +3A074C:lI97|H3A07E8 +3A07E8:lI114|N +3A04E0:lH3A0578|H3A0584 +3A0578:t2:H3A0614,H3A061C +3A061C:lI97|H3A06C0 +3A06C0:lI112|H3A075C +3A075C:lI112|H3A07F8 +3A07F8:lI108|H3A087C +3A087C:lI105|H3A0908 +3A0908:lI99|H3A0994 +3A0994:lI97|H3A0A20 +3A0A20:lI116|H3A0ABC +3A0ABC:lI105|H3A0B60 +3A0B60:lI111|H3A0C0C +3A0C0C:lI110|H3A0CC8 +3A0CC8:lI47|H3A0D7C +3A0D7C:lI120|H3A0E30 +3A0E30:lI45|H3A0EE4 +3A0EE4:lI116|H3A0FA0 +3A0FA0:lI114|H3A106C +3A106C:lI111|H3A1140 +3A1140:lI102|H3A120C +3A120C:lI102|H3A12D8 +3A12D8:lI45|H3A13AC +3A13AC:lI109|H3A1488 +3A1488:lI115|N +3A0614:lI109|H3A06B8 +3A06B8:lI115|N +3A0584:lH3A0624|H3A0630 +3A0624:t2:H3A06C8,H3A06D0 +3A06D0:lI97|H3A076C +3A076C:lI112|H3A0800 +3A0800:lI112|H3A0884 +3A0884:lI108|H3A0910 +3A0910:lI105|H3A099C +3A099C:lI99|H3A0A28 +3A0A28:lI97|H3A0AC4 +3A0AC4:lI116|H3A0B68 +3A0B68:lI105|H3A0C14 +3A0C14:lI111|H3A0CD0 +3A0CD0:lI110|H3A0D84 +3A0D84:lI47|H3A0E38 +3A0E38:lI120|H3A0EEC +3A0EEC:lI45|H3A0FA8 +3A0FA8:lI116|H3A1074 +3A1074:lI114|H3A1148 +3A1148:lI111|H3A1214 +3A1214:lI102|H3A12E0 +3A12E0:lI102|H3A13B4 +3A13B4:lI45|H3A1490 +3A1490:lI109|H3A156C +3A156C:lI101|N +3A06C8:lI109|H3A0764 +3A0764:lI101|N +3A0630:lH3A06D8|H3A06E4 +3A06D8:t2:H3A0774,H3A077C +3A077C:lI97|H3A0810 +3A0810:lI112|H3A0894 +3A0894:lI112|H3A0918 +3A0918:lI108|H3A09A4 +3A09A4:lI105|H3A0A30 +3A0A30:lI99|H3A0ACC +3A0ACC:lI97|H3A0B70 +3A0B70:lI116|H3A0C1C +3A0C1C:lI105|H3A0CD8 +3A0CD8:lI111|H3A0D8C +3A0D8C:lI110|H3A0E40 +3A0E40:lI47|H3A0EF4 +3A0EF4:lI120|H3A0FB0 +3A0FB0:lI45|H3A107C +3A107C:lI116|H3A1150 +3A1150:lI114|H3A121C +3A121C:lI111|H3A12E8 +3A12E8:lI102|H3A13BC +3A13BC:lI102|H3A1498 +3A1498:lI45|H3A1574 +3A1574:lI109|H3A1648 +3A1648:lI97|H3A171C +3A171C:lI110|N +3A0774:lI109|H3A0808 +3A0808:lI97|H3A088C +3A088C:lI110|N +3A06E4:lH3A0784|H3A0790 +3A0784:t2:H3A0818,H3A0820 +3A0820:lI97|H3A089C +3A089C:lI112|H3A0920 +3A0920:lI112|H3A09AC +3A09AC:lI108|H3A0A38 +3A0A38:lI105|H3A0AD4 +3A0AD4:lI99|H3A0B78 +3A0B78:lI97|H3A0C24 +3A0C24:lI116|H3A0CE0 +3A0CE0:lI105|H3A0D94 +3A0D94:lI111|H3A0E48 +3A0E48:lI110|H3A0EFC +3A0EFC:lI47|H3A0FB8 +3A0FB8:lI120|H3A1084 +3A1084:lI45|H3A1158 +3A1158:lI116|H3A1224 +3A1224:lI114|H3A12F0 +3A12F0:lI111|H3A13C4 +3A13C4:lI102|H3A14A0 +3A14A0:lI102|N +3A0818:lI116|N +3A0790:lH3A0828|H3A0834 +3A0828:t2:H3A08A4,H3A08AC +3A08AC:lI97|H3A0930 +3A0930:lI112|H3A09B4 +3A09B4:lI112|H3A0A40 +3A0A40:lI108|H3A0ADC +3A0ADC:lI105|H3A0B80 +3A0B80:lI99|H3A0C2C +3A0C2C:lI97|H3A0CE8 +3A0CE8:lI116|H3A0D9C +3A0D9C:lI105|H3A0E50 +3A0E50:lI111|H3A0F04 +3A0F04:lI110|H3A0FC0 +3A0FC0:lI47|H3A108C +3A108C:lI120|H3A1160 +3A1160:lI45|H3A122C +3A122C:lI116|H3A12F8 +3A12F8:lI114|H3A13CC +3A13CC:lI111|H3A14A8 +3A14A8:lI102|H3A157C +3A157C:lI102|N +3A08A4:lI116|H3A0928 +3A0928:lI114|N +3A0834:lH3A08B4|H3A08C0 +3A08B4:t2:H3A0938,H3A0940 +3A0940:lI97|H3A09C4 +3A09C4:lI112|H3A0A50 +3A0A50:lI112|H3A0AEC +3A0AEC:lI108|H3A0B88 +3A0B88:lI105|H3A0C34 +3A0C34:lI99|H3A0CF0 +3A0CF0:lI97|H3A0DA4 +3A0DA4:lI116|H3A0E58 +3A0E58:lI105|H3A0F0C +3A0F0C:lI111|H3A0FC8 +3A0FC8:lI110|H3A1094 +3A1094:lI47|H3A1168 +3A1168:lI120|H3A1234 +3A1234:lI45|H3A1300 +3A1300:lI116|H3A13D4 +3A13D4:lI114|H3A14B0 +3A14B0:lI111|H3A1584 +3A1584:lI102|H3A1650 +3A1650:lI102|N +3A0938:lI114|H3A09BC +3A09BC:lI111|H3A0A48 +3A0A48:lI102|H3A0AE4 +3A0AE4:lI102|N +3A08C0:lH3A0948|H3A0954 +3A0948:t2:H3A09CC,H3A09D4 +3A09D4:lI97|H3A0A60 +3A0A60:lI112|H3A0AFC +3A0AFC:lI112|H3A0B98 +3A0B98:lI108|H3A0C44 +3A0C44:lI105|H3A0D00 +3A0D00:lI99|H3A0DB4 +3A0DB4:lI97|H3A0E60 +3A0E60:lI116|H3A0F14 +3A0F14:lI105|H3A0FD0 +3A0FD0:lI111|H3A109C +3A109C:lI110|H3A1170 +3A1170:lI47|H3A123C +3A123C:lI120|H3A1308 +3A1308:lI45|H3A13DC +3A13DC:lI116|H3A14B8 +3A14B8:lI101|H3A158C +3A158C:lI120|H3A1658 +3A1658:lI105|H3A1724 +3A1724:lI110|H3A17E8 +3A17E8:lI102|H3A18AC +3A18AC:lI111|N +3A09CC:lI116|H3A0A58 +3A0A58:lI101|H3A0AF4 +3A0AF4:lI120|H3A0B90 +3A0B90:lI105|H3A0C3C +3A0C3C:lI110|H3A0CF8 +3A0CF8:lI102|H3A0DAC +3A0DAC:lI111|N +3A0954:lH3A09DC|H3A09E8 +3A09DC:t2:H3A0A68,H3A0A70 +3A0A70:lI97|H3A0B0C +3A0B0C:lI112|H3A0BA8 +3A0BA8:lI112|H3A0C54 +3A0C54:lI108|H3A0D08 +3A0D08:lI105|H3A0DBC +3A0DBC:lI99|H3A0E68 +3A0E68:lI97|H3A0F1C +3A0F1C:lI116|H3A0FD8 +3A0FD8:lI105|H3A10A4 +3A10A4:lI111|H3A1178 +3A1178:lI110|H3A1244 +3A1244:lI47|H3A1310 +3A1310:lI120|H3A13E4 +3A13E4:lI45|H3A14C0 +3A14C0:lI116|H3A1594 +3A1594:lI101|H3A1660 +3A1660:lI120|H3A172C +3A172C:lI105|H3A17F0 +3A17F0:lI110|H3A18B4 +3A18B4:lI102|H3A1970 +3A1970:lI111|N +3A0A68:lI116|H3A0B04 +3A0B04:lI101|H3A0BA0 +3A0BA0:lI120|H3A0C4C +3A0C4C:lI105|N +3A09E8:lH3A0A78|H3A0A84 +3A0A78:t2:H3A0B14,H3A0B1C +3A0B1C:lI97|H3A0BB8 +3A0BB8:lI112|H3A0C64 +3A0C64:lI112|H3A0D10 +3A0D10:lI108|H3A0DC4 +3A0DC4:lI105|H3A0E70 +3A0E70:lI99|H3A0F24 +3A0F24:lI97|H3A0FE0 +3A0FE0:lI116|H3A10AC +3A10AC:lI105|H3A1180 +3A1180:lI111|H3A124C +3A124C:lI110|H3A1318 +3A1318:lI47|H3A13EC +3A13EC:lI120|H3A14C8 +3A14C8:lI45|H3A159C +3A159C:lI116|H3A1668 +3A1668:lI101|H3A1734 +3A1734:lI120|N +3A0B14:lI116|H3A0BB0 +3A0BB0:lI101|H3A0C5C +3A0C5C:lI120|N +3A0A84:lH3A0B24|H3A0B30 +3A0B24:t2:H3A0BC0,H3A0BC8 +3A0BC8:lI97|H3A0C74 +3A0C74:lI112|H3A0D20 +3A0D20:lI112|H3A0DCC +3A0DCC:lI108|H3A0E78 +3A0E78:lI105|H3A0F2C +3A0F2C:lI99|H3A0FE8 +3A0FE8:lI97|H3A10B4 +3A10B4:lI116|H3A1188 +3A1188:lI105|H3A1254 +3A1254:lI111|H3A1320 +3A1320:lI110|H3A13F4 +3A13F4:lI47|H3A14D0 +3A14D0:lI120|H3A15A4 +3A15A4:lI45|H3A1670 +3A1670:lI116|H3A173C +3A173C:lI99|H3A17F8 +3A17F8:lI108|N +3A0BC0:lI116|H3A0C6C +3A0C6C:lI99|H3A0D18 +3A0D18:lI108|N +3A0B30:lH3A0BD0|H3A0BDC +3A0BD0:t2:H3A0C7C,H3A0C84 +3A0C84:lI97|H3A0D30 +3A0D30:lI112|H3A0DDC +3A0DDC:lI112|H3A0E80 +3A0E80:lI108|H3A0F34 +3A0F34:lI105|H3A0FF0 +3A0FF0:lI99|H3A10BC +3A10BC:lI97|H3A1190 +3A1190:lI116|H3A125C +3A125C:lI105|H3A1328 +3A1328:lI111|H3A13FC +3A13FC:lI110|H3A14D8 +3A14D8:lI47|H3A15AC +3A15AC:lI120|H3A1678 +3A1678:lI45|H3A1744 +3A1744:lI116|H3A1800 +3A1800:lI97|H3A18BC +3A18BC:lI114|N +3A0C7C:lI116|H3A0D28 +3A0D28:lI97|H3A0DD4 +3A0DD4:lI114|N +3A0BDC:lH3A0C8C|H3A0C98 +3A0C8C:t2:H3A0D38,H3A0D40 +3A0D40:lI97|H3A0DEC +3A0DEC:lI112|H3A0E90 +3A0E90:lI112|H3A0F44 +3A0F44:lI108|H3A1000 +3A1000:lI105|H3A10CC +3A10CC:lI99|H3A1198 +3A1198:lI97|H3A1264 +3A1264:lI116|H3A1330 +3A1330:lI105|H3A1404 +3A1404:lI111|H3A14E0 +3A14E0:lI110|H3A15B4 +3A15B4:lI47|H3A1680 +3A1680:lI120|H3A174C +3A174C:lI45|H3A1808 +3A1808:lI115|H3A18C4 +3A18C4:lI118|H3A1978 +3A1978:lI52|H3A1A2C +3A1A2C:lI99|H3A1AE0 +3A1AE0:lI114|H3A1BA4 +3A1BA4:lI99|N +3A0D38:lI115|H3A0DE4 +3A0DE4:lI118|H3A0E88 +3A0E88:lI52|H3A0F3C +3A0F3C:lI99|H3A0FF8 +3A0FF8:lI114|H3A10C4 +3A10C4:lI99|N +3A0C98:lH3A0D48|H3A0D54 +3A0D48:t2:H3A0DF4,H3A0DFC +3A0DFC:lI97|H3A0EA0 +3A0EA0:lI112|H3A0F54 +3A0F54:lI112|H3A1010 +3A1010:lI108|H3A10DC +3A10DC:lI105|H3A11A8 +3A11A8:lI99|H3A1274 +3A1274:lI97|H3A1338 +3A1338:lI116|H3A140C +3A140C:lI105|H3A14E8 +3A14E8:lI111|H3A15BC +3A15BC:lI110|H3A1688 +3A1688:lI47|H3A1754 +3A1754:lI120|H3A1810 +3A1810:lI45|H3A18CC +3A18CC:lI115|H3A1980 +3A1980:lI118|H3A1A34 +3A1A34:lI52|H3A1AE8 +3A1AE8:lI99|H3A1BAC +3A1BAC:lI112|H3A1C78 +3A1C78:lI105|H3A1D3C +3A1D3C:lI111|N +3A0DF4:lI115|H3A0E98 +3A0E98:lI118|H3A0F4C +3A0F4C:lI52|H3A1008 +3A1008:lI99|H3A10D4 +3A10D4:lI112|H3A11A0 +3A11A0:lI105|H3A126C +3A126C:lI111|N +3A0D54:lH3A0E04|H3A0E10 +3A0E04:t2:H3A0EA8,H3A0EB0 +3A0EB0:lI97|H3A0F64 +3A0F64:lI112|H3A1020 +3A1020:lI112|H3A10E4 +3A10E4:lI108|H3A11B0 +3A11B0:lI105|H3A127C +3A127C:lI99|H3A1340 +3A1340:lI97|H3A1414 +3A1414:lI116|H3A14F0 +3A14F0:lI105|H3A15C4 +3A15C4:lI111|H3A1690 +3A1690:lI110|H3A175C +3A175C:lI47|H3A1818 +3A1818:lI120|H3A18D4 +3A18D4:lI45|H3A1988 +3A1988:lI115|H3A1A3C +3A1A3C:lI116|H3A1AF0 +3A1AF0:lI117|H3A1BB4 +3A1BB4:lI102|H3A1C80 +3A1C80:lI102|H3A1D44 +3A1D44:lI105|H3A1E00 +3A1E00:lI116|N +3A0EA8:lI115|H3A0F5C +3A0F5C:lI105|H3A1018 +3A1018:lI116|N +3A0E10:lH3A0EB8|H3A0EC4 +3A0EB8:t2:H3A0F6C,H3A0F74 +3A0F74:lI97|H3A1030 +3A1030:lI112|H3A10F4 +3A10F4:lI112|H3A11C0 +3A11C0:lI108|H3A1284 +3A1284:lI105|H3A1348 +3A1348:lI99|H3A141C +3A141C:lI97|H3A14F8 +3A14F8:lI116|H3A15CC +3A15CC:lI105|H3A1698 +3A1698:lI111|H3A1764 +3A1764:lI110|H3A1820 +3A1820:lI47|H3A18DC +3A18DC:lI120|H3A1990 +3A1990:lI45|H3A1A44 +3A1A44:lI115|H3A1AF8 +3A1AF8:lI104|H3A1BBC +3A1BBC:lI97|H3A1C88 +3A1C88:lI114|N +3A0F6C:lI115|H3A1028 +3A1028:lI104|H3A10EC +3A10EC:lI97|H3A11B8 +3A11B8:lI114|N +3A0EC4:lH3A0F7C|H3A0F88 +3A0F7C:t2:H3A1038,H3A1040 +3A1040:lI97|H3A1104 +3A1104:lI112|H3A11C8 +3A11C8:lI112|H3A128C +3A128C:lI108|H3A1350 +3A1350:lI105|H3A1424 +3A1424:lI99|H3A1500 +3A1500:lI97|H3A15D4 +3A15D4:lI116|H3A16A0 +3A16A0:lI105|H3A176C +3A176C:lI111|H3A1828 +3A1828:lI110|H3A18E4 +3A18E4:lI47|H3A1998 +3A1998:lI120|H3A1A4C +3A1A4C:lI45|H3A1B00 +3A1B00:lI115|H3A1BC4 +3A1BC4:lI104|N +3A1038:lI115|H3A10FC +3A10FC:lI104|N +3A0F88:lH3A1048|H3A1054 +3A1048:t2:H3A110C,H3A1114 +3A1114:lI97|H3A11D8 +3A11D8:lI112|H3A1294 +3A1294:lI112|H3A1358 +3A1358:lI108|H3A142C +3A142C:lI105|H3A1508 +3A1508:lI99|H3A15DC +3A15DC:lI97|H3A16A8 +3A16A8:lI116|H3A1774 +3A1774:lI105|H3A1830 +3A1830:lI111|H3A18EC +3A18EC:lI110|H3A19A0 +3A19A0:lI47|H3A1A54 +3A1A54:lI120|H3A1B08 +3A1B08:lI45|H3A1BCC +3A1BCC:lI110|H3A1C90 +3A1C90:lI101|H3A1D4C +3A1D4C:lI116|H3A1E08 +3A1E08:lI99|H3A1EC4 +3A1EC4:lI100|H3A1F88 +3A1F88:lI102|N +3A110C:lI110|H3A11D0 +3A11D0:lI99|N +3A1054:lH3A111C|H3A1128 +3A111C:t2:H3A11E0,H3A11E8 +3A11E8:lI97|H3A12A4 +3A12A4:lI112|H3A1368 +3A1368:lI112|H3A1434 +3A1434:lI108|H3A1510 +3A1510:lI105|H3A15E4 +3A15E4:lI99|H3A16B0 +3A16B0:lI97|H3A177C +3A177C:lI116|H3A1838 +3A1838:lI105|H3A18F4 +3A18F4:lI111|H3A19A8 +3A19A8:lI110|H3A1A5C +3A1A5C:lI47|H3A1B10 +3A1B10:lI120|H3A1BD4 +3A1BD4:lI45|H3A1C98 +3A1C98:lI110|H3A1D54 +3A1D54:lI101|H3A1E10 +3A1E10:lI116|H3A1ECC +3A1ECC:lI99|H3A1F90 +3A1F90:lI100|H3A2044 +3A2044:lI102|N +3A11E0:lI99|H3A129C +3A129C:lI100|H3A1360 +3A1360:lI102|N +3A1128:lH3A11F0|H3A11FC +3A11F0:t2:H3A12AC,H3A12B4 +3A12B4:lI97|H3A1378 +3A1378:lI112|H3A1444 +3A1444:lI112|H3A1518 +3A1518:lI108|H3A15EC +3A15EC:lI105|H3A16B8 +3A16B8:lI99|H3A1784 +3A1784:lI97|H3A1840 +3A1840:lI116|H3A18FC +3A18FC:lI105|H3A19B0 +3A19B0:lI111|H3A1A64 +3A1A64:lI110|H3A1B18 +3A1B18:lI47|H3A1BDC +3A1BDC:lI120|H3A1CA0 +3A1CA0:lI45|H3A1D5C +3A1D5C:lI109|H3A1E18 +3A1E18:lI105|H3A1ED4 +3A1ED4:lI102|N +3A12AC:lI109|H3A1370 +3A1370:lI105|H3A143C +3A143C:lI102|N +3A11FC:lH3A12BC|H3A12C8 +3A12BC:t2:H3A1380,H3A1388 +3A1388:lI97|H3A1454 +3A1454:lI112|H3A1528 +3A1528:lI112|H3A15FC +3A15FC:lI108|H3A16C8 +3A16C8:lI105|H3A178C +3A178C:lI99|H3A1848 +3A1848:lI97|H3A1904 +3A1904:lI116|H3A19B8 +3A19B8:lI105|H3A1A6C +3A1A6C:lI111|H3A1B20 +3A1B20:lI110|H3A1BE4 +3A1BE4:lI47|H3A1CA8 +3A1CA8:lI120|H3A1D64 +3A1D64:lI45|H3A1E20 +3A1E20:lI108|H3A1EDC +3A1EDC:lI97|H3A1F98 +3A1F98:lI116|H3A204C +3A204C:lI101|H3A2108 +3A2108:lI120|N +3A1380:lI108|H3A144C +3A144C:lI97|H3A1520 +3A1520:lI116|H3A15F4 +3A15F4:lI101|H3A16C0 +3A16C0:lI120|N +3A12C8:lH3A1390|H3A139C +3A1390:t2:H3A145C,H3A1464 +3A1464:lI97|H3A1538 +3A1538:lI112|H3A160C +3A160C:lI112|H3A16D0 +3A16D0:lI108|H3A1794 +3A1794:lI105|H3A1850 +3A1850:lI99|H3A190C +3A190C:lI97|H3A19C0 +3A19C0:lI116|H3A1A74 +3A1A74:lI105|H3A1B28 +3A1B28:lI111|H3A1BEC +3A1BEC:lI110|H3A1CB0 +3A1CB0:lI47|H3A1D6C +3A1D6C:lI120|H3A1E28 +3A1E28:lI45|H3A1EE4 +3A1EE4:lI107|H3A1FA0 +3A1FA0:lI111|H3A2054 +3A2054:lI97|H3A2110 +3A2110:lI110|N +3A145C:lI115|H3A1530 +3A1530:lI107|H3A1604 +3A1604:lI112|N +3A139C:lH3A146C|H3A1478 +3A146C:t2:H3A1540,H3A1548 +3A1548:lI97|H3A161C +3A161C:lI112|H3A16E0 +3A16E0:lI112|H3A179C +3A179C:lI108|H3A1858 +3A1858:lI105|H3A1914 +3A1914:lI99|H3A19C8 +3A19C8:lI97|H3A1A7C +3A1A7C:lI116|H3A1B30 +3A1B30:lI105|H3A1BF4 +3A1BF4:lI111|H3A1CB8 +3A1CB8:lI110|H3A1D74 +3A1D74:lI47|H3A1E30 +3A1E30:lI120|H3A1EEC +3A1EEC:lI45|H3A1FA8 +3A1FA8:lI107|H3A205C +3A205C:lI111|H3A2118 +3A2118:lI97|H3A21CC +3A21CC:lI110|N +3A1540:lI115|H3A1614 +3A1614:lI107|H3A16D8 +3A16D8:lI100|N +3A1478:lH3A1550|H3A155C +3A1550:t2:H3A1624,H3A162C +3A162C:lI97|H3A16F0 +3A16F0:lI112|H3A17AC +3A17AC:lI112|H3A1860 +3A1860:lI108|H3A191C +3A191C:lI105|H3A19D0 +3A19D0:lI99|H3A1A84 +3A1A84:lI97|H3A1B38 +3A1B38:lI116|H3A1BFC +3A1BFC:lI105|H3A1CC0 +3A1CC0:lI111|H3A1D7C +3A1D7C:lI110|H3A1E38 +3A1E38:lI47|H3A1EF4 +3A1EF4:lI120|H3A1FB0 +3A1FB0:lI45|H3A2064 +3A2064:lI107|H3A2120 +3A2120:lI111|H3A21D4 +3A21D4:lI97|H3A2288 +3A2288:lI110|N +3A1624:lI115|H3A16E8 +3A16E8:lI107|H3A17A4 +3A17A4:lI116|N +3A155C:lH3A1634|H3A1640 +3A1634:t2:H3A16F8,H3A1700 +3A1700:lI97|H3A17BC +3A17BC:lI112|H3A1870 +3A1870:lI112|H3A1924 +3A1924:lI108|H3A19D8 +3A19D8:lI105|H3A1A8C +3A1A8C:lI99|H3A1B40 +3A1B40:lI97|H3A1C04 +3A1C04:lI116|H3A1CC8 +3A1CC8:lI105|H3A1D84 +3A1D84:lI111|H3A1E40 +3A1E40:lI110|H3A1EFC +3A1EFC:lI47|H3A1FB8 +3A1FB8:lI120|H3A206C +3A206C:lI45|H3A2128 +3A2128:lI107|H3A21DC +3A21DC:lI111|H3A2290 +3A2290:lI97|H3A234C +3A234C:lI110|N +3A16F8:lI115|H3A17B4 +3A17B4:lI107|H3A1868 +3A1868:lI109|N +3A1640:lH3A1708|H3A1714 +3A1708:t2:H3A17C4,H3A17CC +3A17CC:lI97|H3A1880 +3A1880:lI112|H3A1934 +3A1934:lI112|H3A19E0 +3A19E0:lI108|H3A1A94 +3A1A94:lI105|H3A1B48 +3A1B48:lI99|H3A1C0C +3A1C0C:lI97|H3A1CD0 +3A1CD0:lI116|H3A1D8C +3A1D8C:lI105|H3A1E48 +3A1E48:lI111|H3A1F04 +3A1F04:lI110|H3A1FC0 +3A1FC0:lI47|H3A2074 +3A2074:lI120|H3A2130 +3A2130:lI45|H3A21E4 +3A21E4:lI104|H3A2298 +3A2298:lI116|H3A2354 +3A2354:lI116|H3A2410 +3A2410:lI112|H3A24C4 +3A24C4:lI100|H3A2580 +3A2580:lI45|H3A263C +3A263C:lI99|H3A2700 +3A2700:lI103|H3A27BC +3A27BC:lI105|N +3A17C4:lI99|H3A1878 +3A1878:lI103|H3A192C +3A192C:lI105|N +3A1714:lH3A17D4|H3A17E0 +3A17D4:t2:H3A1888,H3A1890 +3A1890:lI97|H3A1944 +3A1944:lI112|H3A19F0 +3A19F0:lI112|H3A1A9C +3A1A9C:lI108|H3A1B50 +3A1B50:lI105|H3A1C14 +3A1C14:lI99|H3A1CD8 +3A1CD8:lI97|H3A1D94 +3A1D94:lI116|H3A1E50 +3A1E50:lI105|H3A1F0C +3A1F0C:lI111|H3A1FC8 +3A1FC8:lI110|H3A207C +3A207C:lI47|H3A2138 +3A2138:lI120|H3A21EC +3A21EC:lI45|H3A22A0 +3A22A0:lI104|H3A235C +3A235C:lI100|H3A2418 +3A2418:lI102|N +3A1888:lI104|H3A193C +3A193C:lI100|H3A19E8 +3A19E8:lI102|N +3A17E0:lH3A1898|H3A18A4 +3A1898:t2:H3A194C,H3A1954 +3A1954:lI97|H3A1A00 +3A1A00:lI112|H3A1AA4 +3A1AA4:lI112|H3A1B58 +3A1B58:lI108|H3A1C1C +3A1C1C:lI105|H3A1CE0 +3A1CE0:lI99|H3A1D9C +3A1D9C:lI97|H3A1E58 +3A1E58:lI116|H3A1F14 +3A1F14:lI105|H3A1FD0 +3A1FD0:lI111|H3A2084 +3A2084:lI110|H3A2140 +3A2140:lI47|H3A21F4 +3A21F4:lI120|H3A22A8 +3A22A8:lI45|H3A2364 +3A2364:lI103|H3A2420 +3A2420:lI122|H3A24CC +3A24CC:lI105|H3A2588 +3A2588:lI112|N +3A194C:lI103|H3A19F8 +3A19F8:lI122|N +3A18A4:lH3A195C|H3A1968 +3A195C:t2:H3A1A08,H3A1A10 +3A1A10:lI97|H3A1AB4 +3A1AB4:lI112|H3A1B68 +3A1B68:lI112|H3A1C2C +3A1C2C:lI108|H3A1CE8 +3A1CE8:lI105|H3A1DA4 +3A1DA4:lI99|H3A1E60 +3A1E60:lI97|H3A1F1C +3A1F1C:lI116|H3A1FD8 +3A1FD8:lI105|H3A208C +3A208C:lI111|H3A2148 +3A2148:lI110|H3A21FC +3A21FC:lI47|H3A22B0 +3A22B0:lI120|H3A236C +3A236C:lI45|H3A2428 +3A2428:lI103|H3A24D4 +3A24D4:lI116|H3A2590 +3A2590:lI97|H3A2644 +3A2644:lI114|N +3A1A08:lI103|H3A1AAC +3A1AAC:lI116|H3A1B60 +3A1B60:lI97|H3A1C24 +3A1C24:lI114|N +3A1968:lH3A1A18|H3A1A24 +3A1A18:t2:H3A1ABC,H3A1AC4 +3A1AC4:lI97|H3A1B78 +3A1B78:lI112|H3A1C3C +3A1C3C:lI112|H3A1CF0 +3A1CF0:lI108|H3A1DAC +3A1DAC:lI105|H3A1E68 +3A1E68:lI99|H3A1F24 +3A1F24:lI97|H3A1FE0 +3A1FE0:lI116|H3A2094 +3A2094:lI105|H3A2150 +3A2150:lI111|H3A2204 +3A2204:lI110|H3A22B8 +3A22B8:lI47|H3A2374 +3A2374:lI120|H3A2430 +3A2430:lI45|H3A24DC +3A24DC:lI100|H3A2598 +3A2598:lI118|H3A264C +3A264C:lI105|N +3A1ABC:lI100|H3A1B70 +3A1B70:lI118|H3A1C34 +3A1C34:lI105|N +3A1A24:lH3A1ACC|H3A1AD8 +3A1ACC:t2:H3A1B80,H3A1B88 +3A1B88:lI97|H3A1C4C +3A1C4C:lI112|H3A1D00 +3A1D00:lI112|H3A1DB4 +3A1DB4:lI108|H3A1E70 +3A1E70:lI105|H3A1F2C +3A1F2C:lI99|H3A1FE8 +3A1FE8:lI97|H3A209C +3A209C:lI116|H3A2158 +3A2158:lI105|H3A220C +3A220C:lI111|H3A22C0 +3A22C0:lI110|H3A237C +3A237C:lI47|H3A2438 +3A2438:lI120|H3A24E4 +3A24E4:lI45|H3A25A0 +3A25A0:lI100|H3A2654 +3A2654:lI105|H3A2708 +3A2708:lI114|H3A27C4 +3A27C4:lI101|H3A2880 +3A2880:lI99|H3A2944 +3A2944:lI116|H3A2A10 +3A2A10:lI111|H3A2ADC +3A2ADC:lI114|N +3A1B80:lI100|H3A1C44 +3A1C44:lI99|H3A1CF8 +3A1CF8:lI114|N +3A1AD8:lH3A1B90|H3A1B9C +3A1B90:t2:H3A1C54,H3A1C5C +3A1C5C:lI97|H3A1D10 +3A1D10:lI112|H3A1DC4 +3A1DC4:lI112|H3A1E78 +3A1E78:lI108|H3A1F34 +3A1F34:lI105|H3A1FF0 +3A1FF0:lI99|H3A20A4 +3A20A4:lI97|H3A2160 +3A2160:lI116|H3A2214 +3A2214:lI105|H3A22C8 +3A22C8:lI111|H3A2384 +3A2384:lI110|H3A2440 +3A2440:lI47|H3A24EC +3A24EC:lI120|H3A25A8 +3A25A8:lI45|H3A265C +3A265C:lI100|H3A2710 +3A2710:lI105|H3A27CC +3A27CC:lI114|H3A2888 +3A2888:lI101|H3A294C +3A294C:lI99|H3A2A18 +3A2A18:lI116|H3A2AE4 +3A2AE4:lI111|H3A2BB0 +3A2BB0:lI114|N +3A1C54:lI100|H3A1D08 +3A1D08:lI105|H3A1DBC +3A1DBC:lI114|N +3A1B9C:lH3A1C64|H3A1C70 +3A1C64:t2:H3A1D18,H3A1D20 +3A1D20:lI97|H3A1DD4 +3A1DD4:lI112|H3A1E88 +3A1E88:lI112|H3A1F3C +3A1F3C:lI108|H3A1FF8 +3A1FF8:lI105|H3A20AC +3A20AC:lI99|H3A2168 +3A2168:lI97|H3A221C +3A221C:lI116|H3A22D0 +3A22D0:lI105|H3A238C +3A238C:lI111|H3A2448 +3A2448:lI110|H3A24F4 +3A24F4:lI47|H3A25B0 +3A25B0:lI120|H3A2664 +3A2664:lI45|H3A2718 +3A2718:lI100|H3A27D4 +3A27D4:lI105|H3A2890 +3A2890:lI114|H3A2954 +3A2954:lI101|H3A2A20 +3A2A20:lI99|H3A2AEC +3A2AEC:lI116|H3A2BB8 +3A2BB8:lI111|H3A2C74 +3A2C74:lI114|N +3A1D18:lI100|H3A1DCC +3A1DCC:lI120|H3A1E80 +3A1E80:lI114|N +3A1C70:lH3A1D28|H3A1D34 +3A1D28:t2:H3A1DDC,H3A1DE4 +3A1DE4:lI97|H3A1E98 +3A1E98:lI112|H3A1F4C +3A1F4C:lI112|H3A2000 +3A2000:lI108|H3A20B4 +3A20B4:lI105|H3A2170 +3A2170:lI99|H3A2224 +3A2224:lI97|H3A22D8 +3A22D8:lI116|H3A2394 +3A2394:lI105|H3A2450 +3A2450:lI111|H3A24FC +3A24FC:lI110|H3A25B8 +3A25B8:lI47|H3A266C +3A266C:lI120|H3A2720 +3A2720:lI45|H3A27DC +3A27DC:lI99|H3A2898 +3A2898:lI115|H3A295C +3A295C:lI104|N +3A1DDC:lI99|H3A1E90 +3A1E90:lI115|H3A1F44 +3A1F44:lI104|N +3A1D34:lH3A1DEC|H3A1DF8 +3A1DEC:t2:H3A1EA0,H3A1EA8 +3A1EA8:lI97|H3A1F5C +3A1F5C:lI112|H3A2010 +3A2010:lI112|H3A20C4 +3A20C4:lI108|H3A2178 +3A2178:lI105|H3A222C +3A222C:lI99|H3A22E0 +3A22E0:lI97|H3A239C +3A239C:lI116|H3A2458 +3A2458:lI105|H3A2504 +3A2504:lI111|H3A25C0 +3A25C0:lI110|H3A2674 +3A2674:lI47|H3A2728 +3A2728:lI120|H3A27E4 +3A27E4:lI45|H3A28A0 +3A28A0:lI99|H3A2964 +3A2964:lI112|H3A2A28 +3A2A28:lI105|H3A2AF4 +3A2AF4:lI111|N +3A1EA0:lI99|H3A1F54 +3A1F54:lI112|H3A2008 +3A2008:lI105|H3A20BC +3A20BC:lI111|N +3A1DF8:lH3A1EB0|H3A1EBC +3A1EB0:t2:H3A1F64,H3A1F6C +3A1F6C:lI97|H3A2018 +3A2018:lI112|H3A20CC +3A20CC:lI112|H3A2180 +3A2180:lI108|H3A2234 +3A2234:lI105|H3A22E8 +3A22E8:lI99|H3A23A4 +3A23A4:lI97|H3A2460 +3A2460:lI116|H3A250C +3A250C:lI105|H3A25C8 +3A25C8:lI111|H3A267C +3A267C:lI110|H3A2730 +3A2730:lI47|H3A27EC +3A27EC:lI120|H3A28A8 +3A28A8:lI45|H3A296C +3A296C:lI99|H3A2A30 +3A2A30:lI111|H3A2AFC +3A2AFC:lI109|H3A2BC0 +3A2BC0:lI112|H3A2C7C +3A2C7C:lI114|H3A2D2C +3A2D2C:lI101|H3A2DD4 +3A2DD4:lI115|H3A2E6C +3A2E6C:lI115|N +3A1F64:lI90|N +3A1EBC:lH3A1F74|H3A1F80 +3A1F74:t2:H3A2020,H3A2028 +3A2028:lI97|H3A20DC +3A20DC:lI112|H3A2190 +3A2190:lI112|H3A223C +3A223C:lI108|H3A22F0 +3A22F0:lI105|H3A23AC +3A23AC:lI99|H3A2468 +3A2468:lI97|H3A2514 +3A2514:lI116|H3A25D0 +3A25D0:lI105|H3A2684 +3A2684:lI111|H3A2738 +3A2738:lI110|H3A27F4 +3A27F4:lI47|H3A28B0 +3A28B0:lI120|H3A2974 +3A2974:lI45|H3A2A38 +3A2A38:lI99|H3A2B04 +3A2B04:lI100|H3A2BC8 +3A2BC8:lI108|H3A2C84 +3A2C84:lI105|H3A2D34 +3A2D34:lI110|H3A2DDC +3A2DDC:lI107|N +3A2020:lI118|H3A20D4 +3A20D4:lI99|H3A2188 +3A2188:lI100|N +3A1F80:lH3A2030|H3A203C +3A2030:t2:H3A20E4,H3A20EC +3A20EC:lI97|H3A21A0 +3A21A0:lI112|H3A224C +3A224C:lI112|H3A2300 +3A2300:lI108|H3A23BC +3A23BC:lI105|H3A2470 +3A2470:lI99|H3A251C +3A251C:lI97|H3A25D8 +3A25D8:lI116|H3A268C +3A268C:lI105|H3A2740 +3A2740:lI111|H3A27FC +3A27FC:lI110|H3A28B8 +3A28B8:lI47|H3A297C +3A297C:lI120|H3A2A40 +3A2A40:lI45|H3A2B0C +3A2B0C:lI98|H3A2BD0 +3A2BD0:lI99|H3A2C8C +3A2C8C:lI112|H3A2D3C +3A2D3C:lI105|H3A2DE4 +3A2DE4:lI111|N +3A20E4:lI98|H3A2198 +3A2198:lI99|H3A2244 +3A2244:lI112|H3A22F8 +3A22F8:lI105|H3A23B4 +3A23B4:lI111|N +3A203C:lH3A20F4|H3A2100 +3A20F4:t2:H3A21A8,H3A21B0 +3A21B0:lI97|H3A225C +3A225C:lI112|H3A2310 +3A2310:lI112|H3A23C4 +3A23C4:lI108|H3A2478 +3A2478:lI105|H3A2524 +3A2524:lI99|H3A25E0 +3A25E0:lI97|H3A2694 +3A2694:lI116|H3A2748 +3A2748:lI105|H3A2804 +3A2804:lI111|H3A28C0 +3A28C0:lI110|H3A2984 +3A2984:lI47|H3A2A48 +3A2A48:lI114|H3A2B14 +3A2B14:lI116|H3A2BD8 +3A2BD8:lI102|N +3A21A8:lI114|H3A2254 +3A2254:lI116|H3A2308 +3A2308:lI102|N +3A2100:lH3A21B8|H3A21C4 +3A21B8:t2:H3A2264,H3A226C +3A226C:lI97|H3A2320 +3A2320:lI112|H3A23D4 +3A23D4:lI112|H3A2480 +3A2480:lI108|H3A252C +3A252C:lI105|H3A25E8 +3A25E8:lI99|H3A269C +3A269C:lI97|H3A2750 +3A2750:lI116|H3A280C +3A280C:lI105|H3A28C8 +3A28C8:lI111|H3A298C +3A298C:lI110|H3A2A50 +3A2A50:lI47|H3A2B1C +3A2B1C:lI112|H3A2BE0 +3A2BE0:lI111|H3A2C94 +3A2C94:lI119|H3A2D44 +3A2D44:lI101|H3A2DEC +3A2DEC:lI114|H3A2E74 +3A2E74:lI112|H3A2EEC +3A2EEC:lI111|H3A2F64 +3A2F64:lI105|H3A2FD4 +3A2FD4:lI110|H3A303C +3A303C:lI116|N +3A2264:lI112|H3A2318 +3A2318:lI112|H3A23CC +3A23CC:lI116|N +3A21C4:lH3A2274|H3A2280 +3A2274:t2:H3A2328,H3A2330 +3A2330:lI97|H3A23E4 +3A23E4:lI112|H3A2488 +3A2488:lI112|H3A2534 +3A2534:lI108|H3A25F0 +3A25F0:lI105|H3A26A4 +3A26A4:lI99|H3A2758 +3A2758:lI97|H3A2814 +3A2814:lI116|H3A28D0 +3A28D0:lI105|H3A2994 +3A2994:lI111|H3A2A58 +3A2A58:lI110|H3A2B24 +3A2B24:lI47|H3A2BE8 +3A2BE8:lI112|H3A2C9C +3A2C9C:lI111|H3A2D4C +3A2D4C:lI115|H3A2DF4 +3A2DF4:lI116|H3A2E7C +3A2E7C:lI115|H3A2EF4 +3A2EF4:lI99|H3A2F6C +3A2F6C:lI114|H3A2FDC +3A2FDC:lI105|H3A3044 +3A3044:lI112|H3A30A4 +3A30A4:lI116|N +3A2328:lI97|H3A23DC +3A23DC:lI105|N +3A2280:lH3A2338|H3A2344 +3A2338:t2:H3A23EC,H3A23F4 +3A23F4:lI97|H3A2498 +3A2498:lI112|H3A2544 +3A2544:lI112|H3A25F8 +3A25F8:lI108|H3A26AC +3A26AC:lI105|H3A2760 +3A2760:lI99|H3A281C +3A281C:lI97|H3A28D8 +3A28D8:lI116|H3A299C +3A299C:lI105|H3A2A60 +3A2A60:lI111|H3A2B2C +3A2B2C:lI110|H3A2BF0 +3A2BF0:lI47|H3A2CA4 +3A2CA4:lI112|H3A2D54 +3A2D54:lI111|H3A2DFC +3A2DFC:lI115|H3A2E84 +3A2E84:lI116|H3A2EFC +3A2EFC:lI115|H3A2F74 +3A2F74:lI99|H3A2FE4 +3A2FE4:lI114|H3A304C +3A304C:lI105|H3A30AC +3A30AC:lI112|H3A3104 +3A3104:lI116|N +3A23EC:lI101|H3A2490 +3A2490:lI112|H3A253C +3A253C:lI115|N +3A2344:lH3A23FC|H3A2408 +3A23FC:t2:H3A24A0,H3A24A8 +3A24A8:lI97|H3A2554 +3A2554:lI112|H3A2600 +3A2600:lI112|H3A26B4 +3A26B4:lI108|H3A2768 +3A2768:lI105|H3A2824 +3A2824:lI99|H3A28E0 +3A28E0:lI97|H3A29A4 +3A29A4:lI116|H3A2A68 +3A2A68:lI105|H3A2B34 +3A2B34:lI111|H3A2BF8 +3A2BF8:lI110|H3A2CAC +3A2CAC:lI47|H3A2D5C +3A2D5C:lI112|H3A2E04 +3A2E04:lI111|H3A2E8C +3A2E8C:lI115|H3A2F04 +3A2F04:lI116|H3A2F7C +3A2F7C:lI115|H3A2FEC +3A2FEC:lI99|H3A3054 +3A3054:lI114|H3A30B4 +3A30B4:lI105|H3A310C +3A310C:lI112|H3A315C +3A315C:lI116|N +3A24A0:lI112|H3A254C +3A254C:lI115|N +3A2408:lH3A24B0|H3A24BC +3A24B0:t2:H3A255C,H3A2564 +3A2564:lI97|H3A2610 +3A2610:lI112|H3A26C4 +3A26C4:lI112|H3A2770 +3A2770:lI108|H3A282C +3A282C:lI105|H3A28E8 +3A28E8:lI99|H3A29AC +3A29AC:lI97|H3A2A70 +3A2A70:lI116|H3A2B3C +3A2B3C:lI105|H3A2C00 +3A2C00:lI111|H3A2CB4 +3A2CB4:lI110|H3A2D64 +3A2D64:lI47|H3A2E0C +3A2E0C:lI112|H3A2E94 +3A2E94:lI100|H3A2F0C +3A2F0C:lI102|N +3A255C:lI112|H3A2608 +3A2608:lI100|H3A26BC +3A26BC:lI102|N +3A24BC:lH3A256C|H3A2578 +3A256C:t2:H3A2618,H3A2620 +3A2620:lI97|H3A26D4 +3A26D4:lI112|H3A2780 +3A2780:lI112|H3A2834 +3A2834:lI108|H3A28F0 +3A28F0:lI105|H3A29B4 +3A29B4:lI99|H3A2A78 +3A2A78:lI97|H3A2B44 +3A2B44:lI116|H3A2C08 +3A2C08:lI105|H3A2CBC +3A2CBC:lI111|H3A2D6C +3A2D6C:lI110|H3A2E14 +3A2E14:lI47|H3A2E9C +3A2E9C:lI111|H3A2F14 +3A2F14:lI100|H3A2F84 +3A2F84:lI97|N +3A2618:lI111|H3A26CC +3A26CC:lI100|H3A2778 +3A2778:lI97|N +3A2578:lH3A2628|H3A2634 +3A2628:t2:H3A26DC,H3A26E4 +3A26E4:lI97|H3A2790 +3A2790:lI112|H3A2844 +3A2844:lI112|H3A28F8 +3A28F8:lI108|H3A29BC +3A29BC:lI105|H3A2A80 +3A2A80:lI99|H3A2B4C +3A2B4C:lI97|H3A2C10 +3A2C10:lI116|H3A2CC4 +3A2CC4:lI105|H3A2D74 +3A2D74:lI111|H3A2E1C +3A2E1C:lI110|H3A2EA4 +3A2EA4:lI47|H3A2F1C +3A2F1C:lI111|H3A2F8C +3A2F8C:lI99|H3A2FF4 +3A2FF4:lI116|H3A305C +3A305C:lI101|H3A30BC +3A30BC:lI116|H3A3114 +3A3114:lI45|H3A3164 +3A3164:lI115|H3A31AC +3A31AC:lI116|H3A31F4 +3A31F4:lI114|H3A323C +3A323C:lI101|H3A3284 +3A3284:lI97|H3A32CC +3A32CC:lI109|N +3A26DC:lI98|H3A2788 +3A2788:lI105|H3A283C +3A283C:lI110|N +3A2634:lH3A26EC|H3A26F8 +3A26EC:t2:H3A2798,H3A27A0 +3A27A0:lI97|H3A2854 +3A2854:lI112|H3A2908 +3A2908:lI112|H3A29C4 +3A29C4:lI108|H3A2A88 +3A2A88:lI105|H3A2B54 +3A2B54:lI99|H3A2C18 +3A2C18:lI97|H3A2CCC +3A2CCC:lI116|H3A2D7C +3A2D7C:lI105|H3A2E24 +3A2E24:lI111|H3A2EAC +3A2EAC:lI110|H3A2F24 +3A2F24:lI47|H3A2F94 +3A2F94:lI111|H3A2FFC +3A2FFC:lI99|H3A3064 +3A3064:lI116|H3A30C4 +3A30C4:lI101|H3A311C +3A311C:lI116|H3A316C +3A316C:lI45|H3A31B4 +3A31B4:lI115|H3A31FC +3A31FC:lI116|H3A3244 +3A3244:lI114|H3A328C +3A328C:lI101|H3A32D4 +3A32D4:lI97|H3A3314 +3A3314:lI109|N +3A2798:lI100|H3A284C +3A284C:lI109|H3A2900 +3A2900:lI115|N +3A26F8:lH3A27A8|H3A27B4 +3A27A8:t2:H3A285C,H3A2864 +3A2864:lI97|H3A2918 +3A2918:lI112|H3A29D4 +3A29D4:lI112|H3A2A90 +3A2A90:lI108|H3A2B5C +3A2B5C:lI105|H3A2C20 +3A2C20:lI99|H3A2CD4 +3A2CD4:lI97|H3A2D84 +3A2D84:lI116|H3A2E2C +3A2E2C:lI105|H3A2EB4 +3A2EB4:lI111|H3A2F2C +3A2F2C:lI110|H3A2F9C +3A2F9C:lI47|H3A3004 +3A3004:lI111|H3A306C +3A306C:lI99|H3A30CC +3A30CC:lI116|H3A3124 +3A3124:lI101|H3A3174 +3A3174:lI116|H3A31BC +3A31BC:lI45|H3A3204 +3A3204:lI115|H3A324C +3A324C:lI116|H3A3294 +3A3294:lI114|H3A32DC +3A32DC:lI101|H3A331C +3A331C:lI97|H3A334C +3A334C:lI109|N +3A285C:lI108|H3A2910 +3A2910:lI104|H3A29CC +3A29CC:lI97|N +3A27B4:lH3A286C|H3A2878 +3A286C:t2:H3A2920,H3A2928 +3A2928:lI97|H3A29E4 +3A29E4:lI112|H3A2AA0 +3A2AA0:lI112|H3A2B64 +3A2B64:lI108|H3A2C28 +3A2C28:lI105|H3A2CDC +3A2CDC:lI99|H3A2D8C +3A2D8C:lI97|H3A2E34 +3A2E34:lI116|H3A2EBC +3A2EBC:lI105|H3A2F34 +3A2F34:lI111|H3A2FA4 +3A2FA4:lI110|H3A300C +3A300C:lI47|H3A3074 +3A3074:lI111|H3A30D4 +3A30D4:lI99|H3A312C +3A312C:lI116|H3A317C +3A317C:lI101|H3A31C4 +3A31C4:lI116|H3A320C +3A320C:lI45|H3A3254 +3A3254:lI115|H3A329C +3A329C:lI116|H3A32E4 +3A32E4:lI114|H3A3324 +3A3324:lI101|H3A3354 +3A3354:lI97|H3A337C +3A337C:lI109|N +3A2920:lI108|H3A29DC +3A29DC:lI122|H3A2A98 +3A2A98:lI104|N +3A2878:lH3A2930|H3A293C +3A2930:t2:H3A29EC,H3A29F4 +3A29F4:lI97|H3A2AB0 +3A2AB0:lI112|H3A2B74 +3A2B74:lI112|H3A2C30 +3A2C30:lI108|H3A2CE4 +3A2CE4:lI105|H3A2D94 +3A2D94:lI99|H3A2E3C +3A2E3C:lI97|H3A2EC4 +3A2EC4:lI116|H3A2F3C +3A2F3C:lI105|H3A2FAC +3A2FAC:lI111|H3A3014 +3A3014:lI110|H3A307C +3A307C:lI47|H3A30DC +3A30DC:lI111|H3A3134 +3A3134:lI99|H3A3184 +3A3184:lI116|H3A31CC +3A31CC:lI101|H3A3214 +3A3214:lI116|H3A325C +3A325C:lI45|H3A32A4 +3A32A4:lI115|H3A32EC +3A32EC:lI116|H3A332C +3A332C:lI114|H3A335C +3A335C:lI101|H3A3384 +3A3384:lI97|H3A33A4 +3A33A4:lI109|N +3A29EC:lI101|H3A2AA8 +3A2AA8:lI120|H3A2B6C +3A2B6C:lI101|N +3A293C:lH3A29FC|H3A2A08 +3A29FC:t2:H3A2AB8,H3A2AC0 +3A2AC0:lI97|H3A2B84 +3A2B84:lI112|H3A2C40 +3A2C40:lI112|H3A2CF4 +3A2CF4:lI108|H3A2DA4 +3A2DA4:lI105|H3A2E44 +3A2E44:lI99|H3A2ECC +3A2ECC:lI97|H3A2F44 +3A2F44:lI116|H3A2FB4 +3A2FB4:lI105|H3A301C +3A301C:lI111|H3A3084 +3A3084:lI110|H3A30E4 +3A30E4:lI47|H3A313C +3A313C:lI111|H3A318C +3A318C:lI99|H3A31D4 +3A31D4:lI116|H3A321C +3A321C:lI101|H3A3264 +3A3264:lI116|H3A32AC +3A32AC:lI45|H3A32F4 +3A32F4:lI115|H3A3334 +3A3334:lI116|H3A3364 +3A3364:lI114|H3A338C +3A338C:lI101|H3A33AC +3A33AC:lI97|H3A33C4 +3A33C4:lI109|N +3A2AB8:lI99|H3A2B7C +3A2B7C:lI108|H3A2C38 +3A2C38:lI97|H3A2CEC +3A2CEC:lI115|H3A2D9C +3A2D9C:lI115|N +3A2A08:lH3A2AC8|H3A2AD4 +3A2AC8:t2:H3A2B8C,H3A2B94 +3A2B94:lI97|H3A2C50 +3A2C50:lI112|H3A2D04 +3A2D04:lI112|H3A2DAC +3A2DAC:lI108|H3A2E4C +3A2E4C:lI105|H3A2ED4 +3A2ED4:lI99|H3A2F4C +3A2F4C:lI97|H3A2FBC +3A2FBC:lI116|H3A3024 +3A3024:lI105|H3A308C +3A308C:lI111|H3A30EC +3A30EC:lI110|H3A3144 +3A3144:lI47|H3A3194 +3A3194:lI109|H3A31DC +3A31DC:lI115|H3A3224 +3A3224:lI119|H3A326C +3A326C:lI111|H3A32B4 +3A32B4:lI114|H3A32FC +3A32FC:lI100|N +3A2B8C:lI100|H3A2C48 +3A2C48:lI111|H3A2CFC +3A2CFC:lI99|N +3A2AD4:lH3A2B9C|H3A2BA8 +3A2B9C:t2:H3A2C58,H3A2C60 +3A2C60:lI97|H3A2D14 +3A2D14:lI112|H3A2DBC +3A2DBC:lI112|H3A2E54 +3A2E54:lI108|H3A2EDC +3A2EDC:lI105|H3A2F54 +3A2F54:lI99|H3A2FC4 +3A2FC4:lI97|H3A302C +3A302C:lI116|H3A3094 +3A3094:lI105|H3A30F4 +3A30F4:lI111|H3A314C +3A314C:lI110|H3A319C +3A319C:lI47|H3A31E4 +3A31E4:lI109|H3A322C +3A322C:lI97|H3A3274 +3A3274:lI99|H3A32BC +3A32BC:lI45|H3A3304 +3A3304:lI99|H3A333C +3A333C:lI111|H3A336C +3A336C:lI109|H3A3394 +3A3394:lI112|H3A33B4 +3A33B4:lI97|H3A33CC +3A33CC:lI99|H3A33DC +3A33DC:lI116|H3A33EC +3A33EC:lI112|H3A33FC +3A33FC:lI114|H3A340C +3A340C:lI111|N +3A2C58:lI99|H3A2D0C +3A2D0C:lI112|H3A2DB4 +3A2DB4:lI116|N +3A2BA8:lH3A2C68|N +3A2C68:t2:H3A2D1C,H3A2D24 +3A2D24:lI97|H3A2DCC +3A2DCC:lI112|H3A2E64 +3A2E64:lI112|H3A2EE4 +3A2EE4:lI108|H3A2F5C +3A2F5C:lI105|H3A2FCC +3A2FCC:lI99|H3A3034 +3A3034:lI97|H3A309C +3A309C:lI116|H3A30FC +3A30FC:lI105|H3A3154 +3A3154:lI111|H3A31A4 +3A31A4:lI110|H3A31EC +3A31EC:lI47|H3A3234 +3A3234:lI109|H3A327C +3A327C:lI97|H3A32C4 +3A32C4:lI99|H3A330C +3A330C:lI45|H3A3344 +3A3344:lI98|H3A3374 +3A3374:lI105|H3A339C +3A339C:lI110|H3A33BC +3A33BC:lI104|H3A33D4 +3A33D4:lI101|H3A33E4 +3A33E4:lI120|H3A33F4 +3A33F4:lI52|H3A3404 +3A3404:lI48|N +3A2D1C:lI104|H3A2DC4 +3A2DC4:lI113|H3A2E5C +3A2E5C:lI120|N +39DC28:lH39DC68|H39DC74 +39DC68:t2:A4:port,I8888 +39DC74:lH39DCA8|H39DCB4 +39DCA8:t2:AC:bind_address,H39DCF8 +39DCF8:t4:I127,I0,I0,I1 +39DCB4:lH39DD0C|H39DD18 +39DD0C:t2:AB:server_name,H39DD6C +39DD6C:lI108|H39DDE4 +39DDE4:lI111|H39DE5C +39DE5C:lI99|H39DEE4 +39DEE4:lI97|H39DF6C +39DF6C:lI108|H39E00C +39E00C:lI104|H39E0B4 +39E0B4:lI111|H39E16C +39E16C:lI115|H39E238 +39E238:lI116|N +39DD18:lH39DD74|H39DD80 +39DD74:t2:AE:max_header_siz,I1024 +39DD80:lH39DDEC|H39DDF8 +39DDEC:t2:A11:max_header_action,A8:reply414 +39DDF8:lH39DE64|H39DE70 +39DE64:t2:A8:com_type,A7:ip_comm +39DE70:lH39DEEC|H39DEF8 +39DEEC:t2:A7:modules,H39DF74 +39DF74:lA9:mod_alias|H39E014 +39E014:lA8:mod_auth|H39E0BC +39E0BC:lA7:mod_esi|H39E174 +39E174:lAB:mod_actions|H39E240 +39E240:lA7:mod_cgi|H39E324 +39E324:lAB:mod_include|H39E418 +39E418:lA7:mod_dir|H39E51C +39E51C:lA7:mod_get|H39E634 +39E634:lA8:mod_head|H39E748 +39E748:lA7:mod_log|H39E85C +39E85C:lAC:mod_disk_log|N +39DEF8:lH39DF7C|H39DF88 +39DF7C:t2:AF:directory_index,H39E01C +39E01C:lH39E0C4|N +39E0C4:lI105|H39E17C +39E17C:lI110|H39E248 +39E248:lI100|H39E32C +39E32C:lI101|H39E420 +39E420:lI120|H39E524 +39E524:lI46|H39E63C +39E63C:lI104|H39E750 +39E750:lI116|H39E864 +39E864:lI109|H39E978 +39E978:lI108|N +39DF88:lH39E024|H39E030 +39E024:t2:AC:default_type,H39E0CC +39E0CC:lI116|H39E184 +39E184:lI101|H39E250 +39E250:lI120|H39E334 +39E334:lI116|H39E428 +39E428:lI47|H39E52C +39E52C:lI112|H39E644 +39E644:lI108|H39E758 +39E758:lI97|H39E86C +39E86C:lI105|H39E980 +39E980:lI110|N +39E030:lH39E0D4|H39E0E0 +39E0D4:t2:A10:erl_script_alias,H39E18C +39E18C:t2:H39E258,H39E260 +39E260:lH39E344|N +39E344:lI119|H39E438 +39E438:lI101|H39E53C +39E53C:lI98|H39E654 +39E654:lI116|H39E768 +39E768:lI111|H39E87C +39E87C:lI111|H39E990 +39E990:lI108|N +39E258:lI47|H39E33C +39E33C:lI119|H39E430 +39E430:lI101|H39E534 +39E534:lI98|H39E64C +39E64C:lI116|H39E760 +39E760:lI111|H39E874 +39E874:lI111|H39E988 +39E988:lI108|N +39E0E0:lH39E198|H39E1A4 +39E198:t2:A5:alias,H39E268 +39E268:t2:H39E34C,H39E354 +39E354:lI47|H39E448 +39E448:lI99|H39E54C +39E54C:lI108|H39E664 +39E664:lI101|H39E778 +39E778:lI97|H39E88C +39E88C:lI114|H39E9A0 +39E9A0:lI99|H39EA94 +39EA94:lI97|H39EB88 +39EB88:lI115|H39EC7C +39EC7C:lI101|H39ED70 +39ED70:lI47|H39EE4C +39EE4C:lI111|H39EF20 +39EF20:lI116|H39EFFC +39EFFC:lI112|H39F0E0 +39F0E0:lI47|H39F1B4 +39F1B4:lI101|H39F288 +39F288:lI114|H39F344 +39F344:lI116|H39F408 +39F408:lI115|H39F4D4 +39F4D4:lI47|H39F5A8 +39F5A8:lI108|H39F67C +39F67C:lI105|H39F750 +39F750:lI98|H39F824 +39F824:lI47|H39F908 +39F908:lI111|H39F9E4 +39F9E4:lI98|H39FAC0 +39FAC0:lI115|H39FB9C +39FB9C:lI101|H39FC68 +39FC68:lI114|H39FD2C +39FD2C:lI118|H39FDF8 +39FDF8:lI101|H39FEB4 +39FEB4:lI114|H39FF70 +39FF70:lI47|H3A0024 +3A0024:lI112|H3A00D8 +3A00D8:lI114|H3A0184 +3A0184:lI105|H3A0238 +3A0238:lI118|H3A02F4 +3A02F4:lI47|H3A03A8 +3A03A8:lI99|H3A0444 +3A0444:lI114|H3A04E8 +3A04E8:lI97|H3A058C +3A058C:lI115|H3A0638 +3A0638:lI104|H3A06EC +3A06EC:lI100|H3A0798 +3A0798:lI117|H3A083C +3A083C:lI109|H3A08C8 +3A08C8:lI112|H3A095C +3A095C:lI95|H3A09F0 +3A09F0:lI118|H3A0A8C +3A0A8C:lI105|H3A0B38 +3A0B38:lI101|H3A0BE4 +3A0BE4:lI119|H3A0CA0 +3A0CA0:lI101|H3A0D5C +3A0D5C:lI114|N +39E34C:lI47|H39E440 +39E440:lI99|H39E544 +39E544:lI114|H39E65C +39E65C:lI97|H39E770 +39E770:lI115|H39E884 +39E884:lI104|H39E998 +39E998:lI100|H39EA8C +39EA8C:lI117|H39EB80 +39EB80:lI109|H39EC74 +39EC74:lI112|H39ED68 +39ED68:lI95|H39EE44 +39EE44:lI118|H39EF18 +39EF18:lI105|H39EFF4 +39EFF4:lI101|H39F0D8 +39F0D8:lI119|H39F1AC +39F1AC:lI101|H39F280 +39F280:lI114|N +39E1A4:lH39E274|H39E280 +39E274:t2:A5:alias,H39E35C +39E35C:t2:H39E450,H39E458 +39E458:lI47|H39E55C +39E55C:lI99|H39E674 +39E674:lI108|H39E788 +39E788:lI101|H39E89C +39E89C:lI97|H39E9B0 +39E9B0:lI114|H39EAA4 +39EAA4:lI99|H39EB98 +39EB98:lI97|H39EC8C +39EC8C:lI115|H39ED80 +39ED80:lI101|H39EE5C +39EE5C:lI47|H39EF30 +39EF30:lI111|H39F00C +39F00C:lI116|H39F0F0 +39F0F0:lI112|H39F1C4 +39F1C4:lI47|H39F298 +39F298:lI101|H39F354 +39F354:lI114|H39F418 +39F418:lI116|H39F4E4 +39F4E4:lI115|H39F5B0 +39F5B0:lI47|H39F684 +39F684:lI101|H39F758 +39F758:lI114|H39F82C +39F82C:lI116|H39F910 +39F910:lI115|H39F9EC +39F9EC:lI47|H39FAC8 +39FAC8:lI100|H39FBA4 +39FBA4:lI111|H39FC70 +39FC70:lI99|H39FD34 +39FD34:lI47|H39FE00 +39FE00:lI104|H39FEBC +39FEBC:lI116|H39FF78 +39FF78:lI109|H3A002C +3A002C:lI108|N +39E450:lI47|H39E554 +39E554:lI99|H39E66C +39E66C:lI114|H39E780 +39E780:lI97|H39E894 +39E894:lI115|H39E9A8 +39E9A8:lI104|H39EA9C +39EA9C:lI100|H39EB90 +39EB90:lI117|H39EC84 +39EC84:lI109|H39ED78 +39ED78:lI112|H39EE54 +39EE54:lI95|H39EF28 +39EF28:lI101|H39F004 +39F004:lI114|H39F0E8 +39F0E8:lI116|H39F1BC +39F1BC:lI115|H39F290 +39F290:lI95|H39F34C +39F34C:lI100|H39F410 +39F410:lI111|H39F4DC +39F4DC:lI99|N +39E280:lH39E368|H39E374 +39E368:t2:A5:alias,H39E460 +39E460:t2:H39E564,H39E56C +39E56C:lI47|H39E684 +39E684:lI99|H39E798 +39E798:lI108|H39E8AC +39E8AC:lI101|H39E9C0 +39E9C0:lI97|H39EAB4 +39EAB4:lI114|H39EBA8 +39EBA8:lI99|H39EC9C +39EC9C:lI97|H39ED90 +39ED90:lI115|H39EE6C +39EE6C:lI101|H39EF40 +39EF40:lI47|H39F01C +39F01C:lI111|H39F100 +39F100:lI116|H39F1D4 +39F1D4:lI112|H39F2A0 +39F2A0:lI47|H39F35C +39F35C:lI101|H39F420 +39F420:lI114|H39F4EC +39F4EC:lI116|H39F5B8 +39F5B8:lI115|H39F68C +39F68C:lI47|H39F760 +39F760:lI108|H39F834 +39F834:lI105|H39F918 +39F918:lI98|H39F9F4 +39F9F4:lI47|H39FAD0 +39FAD0:lI111|H39FBAC +39FBAC:lI98|H39FC78 +39FC78:lI115|H39FD3C +39FD3C:lI101|H39FE08 +39FE08:lI114|H39FEC4 +39FEC4:lI118|H39FF80 +39FF80:lI101|H3A0034 +3A0034:lI114|H3A00E0 +3A00E0:lI47|H3A018C +3A018C:lI100|H3A0240 +3A0240:lI111|H3A02FC +3A02FC:lI99|H3A03B0 +3A03B0:lI47|H3A044C +3A044C:lI104|H3A04F0 +3A04F0:lI116|H3A0594 +3A0594:lI109|H3A0640 +3A0640:lI108|N +39E564:lI47|H39E67C +39E67C:lI99|H39E790 +39E790:lI114|H39E8A4 +39E8A4:lI97|H39E9B8 +39E9B8:lI115|H39EAAC +39EAAC:lI104|H39EBA0 +39EBA0:lI100|H39EC94 +39EC94:lI117|H39ED88 +39ED88:lI109|H39EE64 +39EE64:lI112|H39EF38 +39EF38:lI95|H39F014 +39F014:lI100|H39F0F8 +39F0F8:lI111|H39F1CC +39F1CC:lI99|N +39E374:lH39E46C|N +39E46C:t2:A10:erl_script_alias,H39E574 +39E574:t2:H39E68C,H39E694 +39E694:lH39E7A8|N +39E7A8:lI99|H39E8BC +39E8BC:lI114|H39E9D0 +39E9D0:lI97|H39EAC4 +39EAC4:lI115|H39EBB8 +39EBB8:lI104|H39ECAC +39ECAC:lI100|H39EDA0 +39EDA0:lI117|H39EE74 +39EE74:lI109|H39EF48 +39EF48:lI112|H39F024 +39F024:lI95|H39F108 +39F108:lI118|H39F1DC +39F1DC:lI105|H39F2A8 +39F2A8:lI101|H39F364 +39F364:lI119|H39F428 +39F428:lI101|H39F4F4 +39F4F4:lI114|N +39E68C:lI47|H39E7A0 +39E7A0:lI99|H39E8B4 +39E8B4:lI100|H39E9C8 +39E9C8:lI118|H39EABC +39EABC:lI95|H39EBB0 +39EBB0:lI101|H39ECA4 +39ECA4:lI114|H39ED98 +39ED98:lI108|N +39DB58:lN|H39DB9C +39DB9C:lH39D9FC|H39DBEC +39D9FC:t4:I127,I0,I0,I1 +39DBEC:lI8888|N +3A3E20:lH3A3DFC|H3A3704 +3A3DFC:t8:A5:child,P<0.46.0>,H39DAC8,H39DAD8,A9:permanent,I2000,A6:worker,H39DAE8 +39DAE8:lAD:httpd_manager|H39DB38 +39DB38:lAA:gen_server|N +39DAD8:t3:AD:httpd_manager,AA:start_link,H39DB30 +39DB30:lA9:undefined|H39DB78 +39DB78:lH39DB50|H39DBC0 +39DBC0:lN|N +39DAC8:t3:AD:httpd_manager,H39D9FC,I8888 +3A3704:lH3A36E0|H39D998 +3A36E0:t8:A5:child,P<0.45.0>,H39DA18,H39DA28,A9:permanent,I2000,AA:supervisor,H39DA38 +39DA38:lAE:httpd_misc_sup|H39DAC0 +39DAC0:lAA:supervisor|N +39DA28:t3:AE:httpd_misc_sup,A5:start,H39D958 +39D958:lH39D9FC|H39DA10 +39DA10:lI8888|H39DAB8 +39DAB8:lA7:silence|N +39DA18:t3:AE:httpd_misc_sup,H39D9FC,I8888 +39D998:lH39DA64|N +39DA64:t8:A5:child,P<0.44.0>,H39DAF0,H39DB00,A9:permanent,I2000,AA:supervisor,H39DB10 +39DB10:lA12:httpd_acceptor_sup|H39DB48 +39DB48:lAA:supervisor|N +39DB00:t3:A12:httpd_acceptor_sup,A5:start,H39DB40 +39DB40:lH39D9FC|H39DB80 +39DB80:lI8888|H39DBC8 +39DBC8:lA7:silence|N +39DAF0:t3:A12:httpd_acceptor_sup,H39D9FC,I8888 +39D960:t2:A5:local,A1A:httpd_sup__127_0_0_1__8888 +39D9CC:lAA:gen_server|H39DA90 +39DA90:lP<0.33.0>|H39DB20 +39DB20:lP<0.33.0>|H39DB60 +39DB60:lH39DBA4|H39DBB0 +39DBA4:t2:A5:local,A1A:httpd_sup__127_0_0_1__8888 +39DBB0:lAA:supervisor|H39DBF4 +39DBF4:lH39DC30|H39DC40 +39DC30:t3:H39D960,A9:httpd_sup,H39DA88 +39DC40:lN|N +39D940:t2:AD:$initial_call,H39D9E4 +39D9E4:t3:A3:gen,A7:init_it,H39D9CC +39D94C:t2:AA:$ancestors,H39D9F4 +39D9F4:lA8:web_tool|H39DAB0 +39DAB0:lP<0.27.0>|N +=proc_dictionary:<0.44.0> +H3756A8 +H3756B4 +H3756C0 +H3756CC +=proc_stack:<0.44.0> +36c194:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AA:supervisor +y3:H36C030 +y4:A1E:httpd_acc_sup__127_0_0_1__8888 +y5:P<0.43.0> +36c1b0:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H375710 +=proc_heap:<0.44.0> +36C030:tA:A5:state,H3756D8,AB:one_for_one,H36C028,N,I500,I100,N,A12:httpd_acceptor_sup,H375730 +375730:lA7:silence|N +36C028:lH36C004|N +36C004:t8:A5:child,P<0.47.0>,H36BE80,H36BE90,A9:permanent,I1000,A6:worker,H36BEA0 +36BEA0:lAE:httpd_acceptor|N +36BE90:t3:AE:httpd_acceptor,AA:start_link,H36BEE8 +36BEE8:lP<0.46.0>|H36BEF0 +36BEF0:lA7:ip_comm|H36BEF8 +36BEF8:lH36BF00|H36BF14 +36BF00:t4:I127,I0,I0,I1 +36BF14:lI8888|H36BF1C +36BF1C:lA1B:httpd_conf__127_0_0_1__8888|H36BF24 +36BF24:lA7:silence|N +36BE80:t3:AE:httpd_acceptor,H36BED4,I8888 +36BED4:t4:I127,I0,I0,I1 +3756D8:t2:A5:local,A1E:httpd_acc_sup__127_0_0_1__8888 +375710:lAA:gen_server|H375738 +375738:lP<0.43.0>|H375748 +375748:lP<0.43.0>|H375758 +375758:lH375760|H37576C +375760:t2:A5:local,A1E:httpd_acc_sup__127_0_0_1__8888 +37576C:lAA:supervisor|H375774 +375774:lH37577C|H37578C +37577C:t3:H3756D8,A12:httpd_acceptor_sup,H375730 +37578C:lN|N +3756A8:t2:AD:$initial_call,H375718 +375718:t3:A3:gen,A7:init_it,H375710 +3756B4:t2:A9:verbosity,A7:silence +3756C0:t2:AA:$ancestors,H375728 +375728:lA1A:httpd_sup__127_0_0_1__8888|H375740 +375740:lA8:web_tool|H375750 +375750:lP<0.27.0>|N +3756CC:t2:A5:sname,A7:acc_sup +=proc_dictionary:<0.45.0> +H36F484 +H36F4F4 +H36F468 +H36F500 +=proc_stack:<0.45.0> +36f734:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AA:supervisor +y3:H36F5D0 +y4:A1F:httpd_misc_sup__127_0_0_1__8888 +y5:P<0.43.0> +36f750:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H36F430 +=proc_heap:<0.45.0> +36F5D0:tA:A5:state,H36F3FC,AB:one_for_one,N,N,I0,I1,N,AE:httpd_misc_sup,H36F408 +36F408:lA7:silence|N +36F3FC:t2:A5:local,A1F:httpd_misc_sup__127_0_0_1__8888 +36F430:lAA:gen_server|H36F428 +36F428:lP<0.43.0>|H36F420 +36F420:lP<0.43.0>|H36F3D0 +36F3D0:lH36F3E0|H36F418 +36F3E0:t2:A5:local,A1F:httpd_misc_sup__127_0_0_1__8888 +36F418:lAA:supervisor|H36F3D8 +36F3D8:lH36F3EC|H36F410 +36F3EC:t3:H36F3FC,AE:httpd_misc_sup,H36F408 +36F410:lN|N +36F484:t2:AD:$initial_call,H36F474 +36F474:t3:A3:gen,A7:init_it,H36F430 +36F4F4:t2:A9:verbosity,A7:silence +36F468:t2:AA:$ancestors,H36F460 +36F460:lA1A:httpd_sup__127_0_0_1__8888|H36F440 +36F440:lA8:web_tool|H36F438 +36F438:lP<0.27.0>|N +36F500:t2:A5:sname,A8:misc_sup +=proc_dictionary:<0.46.0> +H3BDA50 +H3BDA5C +H3BDAC8 +H3BDB28 +H3BDB9C +H3BDC00 +H3BDADC +H3BDB3C +=proc_stack:<0.46.0> +39d8f4:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:AD:httpd_manager +y3:H39D5A4 +y4:A16:httpd__127_0_0_1__8888 +y5:P<0.43.0> +39d910:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H3BDAB0 +=proc_heap:<0.46.0> +39D5A4:t9:A5:state,A7:ip_comm,A9:undefined,A1B:httpd_conf__127_0_0_1__8888,N,A9:unblocked,A9:undefined,A9:undefined,H39D430 +39D430:lH39BF40|H39D428 +39BF40:t2:A8:max_conn,I1 +39D428:lH39BC80|H39D420 +39BC80:t2:AF:last_heavy_load,A5:never +39D420:lH39D414|N +39D414:t2:AF:last_connection,H39D408 +39D408:t2:H39D3E8,H39D3F8 +39D3F8:t3:I11,I22,I34 +39D3E8:t3:I2004,I4,I21 +3BDAB0:lAA:gen_server|H3BDB20 +3BDB20:lP<0.43.0>|H3BDB94 +3BDB94:lP<0.43.0>|H3BDBF8 +3BDBF8:lH3BDC48|H3BDC54 +3BDC48:t2:A5:local,A16:httpd__127_0_0_1__8888 +3BDC54:lAD:httpd_manager|H3BDCAC +3BDCAC:lH3BDD14|H3BDD1C +3BDD14:lA9:undefined|H3BDD9C +3BDD9C:lH3BDA84|H3BDE2C +3BDA84:lH3BDAF0|H3BDAFC +3BDAF0:t2:AB:server_root,H3BDB48 +3BDB48:lI47|H3BDBB0 +3BDBB0:lI99|H3BDC0C +3BDC0C:lI108|H3BDC64 +3BDC64:lI101|H3BDCBC +3BDCBC:lI97|H3BDD2C +3BDD2C:lI114|H3BDDA4 +3BDDA4:lI99|H3BDE34 +3BDE34:lI97|H3BDED4 +3BDED4:lI115|H3BDF90 +3BDF90:lI101|H3BE054 +3BE054:lI47|H3BE128 +3BE128:lI111|H3BE204 +3BE204:lI116|H3BE2EC +3BE2EC:lI112|H3BE3E0 +3BE3E0:lI47|H3BE4E4 +3BE4E4:lI101|H3BE5E8 +3BE5E8:lI114|H3BE6EC +3BE6EC:lI116|H3BE7E0 +3BE7E0:lI115|H3BE8CC +3BE8CC:lI47|H3BE9B8 +3BE9B8:lI108|H3BEAAC +3BEAAC:lI105|H3BEB98 +3BEB98:lI98|H3BEC84 +3BEC84:lI47|H3BED70 +3BED70:lI119|H3BEE5C +3BEE5C:lI101|H3BEF30 +3BEF30:lI98|H3BEFFC +3BEFFC:lI116|H3BF0C8 +3BF0C8:lI111|H3BF19C +3BF19C:lI111|H3BF260 +3BF260:lI108|H3BF314 +3BF314:lI47|H3BF3C0 +3BF3C0:lI112|H3BF474 +3BF474:lI114|H3BF530 +3BF530:lI105|H3BF5F4 +3BF5F4:lI118|H3BF6C8 +3BF6C8:lI47|H3BF79C +3BF79C:lI114|H3BF870 +3BF870:lI111|H3BF954 +3BF954:lI111|H3BFA30 +3BFA30:lI116|N +3BDAFC:lH3BDB50|H3BDB5C +3BDB50:t2:AD:document_root,H3BDBB8 +3BDBB8:lI47|H3BDC14 +3BDC14:lI99|H3BDC6C +3BDC6C:lI108|H3BDCC4 +3BDCC4:lI101|H3BDD34 +3BDD34:lI97|H3BDDAC +3BDDAC:lI114|H3BDE3C +3BDE3C:lI99|H3BDEDC +3BDEDC:lI97|H3BDF98 +3BDF98:lI115|H3BE05C +3BE05C:lI101|H3BE130 +3BE130:lI47|H3BE20C +3BE20C:lI111|H3BE2F4 +3BE2F4:lI116|H3BE3E8 +3BE3E8:lI112|H3BE4EC +3BE4EC:lI47|H3BE5F0 +3BE5F0:lI101|H3BE6F4 +3BE6F4:lI114|H3BE7E8 +3BE7E8:lI116|H3BE8D4 +3BE8D4:lI115|H3BE9C0 +3BE9C0:lI47|H3BEAB4 +3BEAB4:lI108|H3BEBA0 +3BEBA0:lI105|H3BEC8C +3BEC8C:lI98|H3BED78 +3BED78:lI47|H3BEE64 +3BEE64:lI119|H3BEF38 +3BEF38:lI101|H3BF004 +3BF004:lI98|H3BF0D0 +3BF0D0:lI116|H3BF1A4 +3BF1A4:lI111|H3BF268 +3BF268:lI111|H3BF31C +3BF31C:lI108|H3BF3C8 +3BF3C8:lI47|H3BF47C +3BF47C:lI112|H3BF538 +3BF538:lI114|H3BF5FC +3BF5FC:lI105|H3BF6D0 +3BF6D0:lI118|H3BF7A4 +3BF7A4:lI47|H3BF878 +3BF878:lI114|H3BF95C +3BF95C:lI111|H3BFA38 +3BFA38:lI111|H3BFB0C +3BFB0C:lI116|H3BFBE8 +3BFBE8:lI47|H3BFCB4 +3BFCB4:lI100|H3BFD78 +3BFD78:lI111|H3BFE3C +3BFE3C:lI99|N +3BDB5C:lH3BDBC0|H3BDBCC +3BDBC0:t2:AA:mime_types,H3BDC1C +3BDC1C:lH3BDC74|H3BDC80 +3BDC74:t2:H3BDCCC,H3BDCD4 +3BDCD4:lI120|H3BDD44 +3BDD44:lI45|H3BDDBC +3BDDBC:lI119|H3BDE44 +3BDE44:lI111|H3BDEE4 +3BDEE4:lI114|H3BDFA0 +3BDFA0:lI108|H3BE064 +3BE064:lI100|H3BE138 +3BE138:lI47|H3BE214 +3BE214:lI120|H3BE2FC +3BE2FC:lI45|H3BE3F0 +3BE3F0:lI118|H3BE4F4 +3BE4F4:lI114|H3BE5F8 +3BE5F8:lI109|H3BE6FC +3BE6FC:lI108|N +3BDCCC:lI119|H3BDD3C +3BDD3C:lI114|H3BDDB4 +3BDDB4:lI108|N +3BDC80:lH3BDCDC|H3BDCE8 +3BDCDC:t2:H3BDD4C,H3BDD54 +3BDD54:lI120|H3BDDCC +3BDDCC:lI45|H3BDE54 +3BDE54:lI119|H3BDEF4 +3BDEF4:lI111|H3BDFA8 +3BDFA8:lI114|H3BE06C +3BE06C:lI108|H3BE140 +3BE140:lI100|H3BE21C +3BE21C:lI47|H3BE304 +3BE304:lI120|H3BE3F8 +3BE3F8:lI45|H3BE4FC +3BE4FC:lI118|H3BE600 +3BE600:lI114|H3BE704 +3BE704:lI109|H3BE7F0 +3BE7F0:lI108|N +3BDD4C:lI118|H3BDDC4 +3BDDC4:lI114|H3BDE4C +3BDE4C:lI109|H3BDEEC +3BDEEC:lI108|N +3BDCE8:lH3BDD5C|H3BDD68 +3BDD5C:t2:H3BDDD4,H3BDDDC +3BDDDC:lI120|H3BDE64 +3BDE64:lI45|H3BDF04 +3BDF04:lI99|H3BDFB0 +3BDFB0:lI111|H3BE074 +3BE074:lI110|H3BE148 +3BE148:lI102|H3BE224 +3BE224:lI101|H3BE30C +3BE30C:lI114|H3BE400 +3BE400:lI101|H3BE504 +3BE504:lI110|H3BE608 +3BE608:lI99|H3BE70C +3BE70C:lI101|H3BE7F8 +3BE7F8:lI47|H3BE8DC +3BE8DC:lI120|H3BE9C8 +3BE9C8:lI45|H3BEABC +3BEABC:lI99|H3BEBA8 +3BEBA8:lI111|H3BEC94 +3BEC94:lI111|H3BED80 +3BED80:lI108|H3BEE6C +3BEE6C:lI116|H3BEF40 +3BEF40:lI97|H3BF00C +3BF00C:lI108|H3BF0D8 +3BF0D8:lI107|N +3BDDD4:lI105|H3BDE5C +3BDE5C:lI99|H3BDEFC +3BDEFC:lI101|N +3BDD68:lH3BDDE4|H3BDDF0 +3BDDE4:t2:H3BDE6C,H3BDE74 +3BDE74:lI118|H3BDF14 +3BDF14:lI105|H3BDFC0 +3BDFC0:lI100|H3BE084 +3BE084:lI101|H3BE158 +3BE158:lI111|H3BE22C +3BE22C:lI47|H3BE314 +3BE314:lI120|H3BE408 +3BE408:lI45|H3BE50C +3BE50C:lI115|H3BE610 +3BE610:lI103|H3BE714 +3BE714:lI105|H3BE800 +3BE800:lI45|H3BE8E4 +3BE8E4:lI109|H3BE9D0 +3BE9D0:lI111|H3BEAC4 +3BEAC4:lI118|H3BEBB0 +3BEBB0:lI105|H3BEC9C +3BEC9C:lI101|N +3BDE6C:lI109|H3BDF0C +3BDF0C:lI111|H3BDFB8 +3BDFB8:lI118|H3BE07C +3BE07C:lI105|H3BE150 +3BE150:lI101|N +3BDDF0:lH3BDE7C|H3BDE88 +3BDE7C:t2:H3BDF1C,H3BDF24 +3BDF24:lI118|H3BDFD0 +3BDFD0:lI105|H3BE094 +3BE094:lI100|H3BE160 +3BE160:lI101|H3BE234 +3BE234:lI111|H3BE31C +3BE31C:lI47|H3BE410 +3BE410:lI120|H3BE514 +3BE514:lI45|H3BE618 +3BE618:lI109|H3BE71C +3BE71C:lI115|H3BE808 +3BE808:lI118|H3BE8EC +3BE8EC:lI105|H3BE9D8 +3BE9D8:lI100|H3BEACC +3BEACC:lI101|H3BEBB8 +3BEBB8:lI111|N +3BDF1C:lI97|H3BDFC8 +3BDFC8:lI118|H3BE08C +3BE08C:lI105|N +3BDE88:lH3BDF2C|H3BDF38 +3BDF2C:t2:H3BDFD8,H3BDFE0 +3BDFE0:lI118|H3BE0A4 +3BE0A4:lI105|H3BE168 +3BE168:lI100|H3BE23C +3BE23C:lI101|H3BE324 +3BE324:lI111|H3BE418 +3BE418:lI47|H3BE51C +3BE51C:lI113|H3BE620 +3BE620:lI117|H3BE724 +3BE724:lI105|H3BE810 +3BE810:lI99|H3BE8F4 +3BE8F4:lI107|H3BE9E0 +3BE9E0:lI116|H3BEAD4 +3BEAD4:lI105|H3BEBC0 +3BEBC0:lI109|H3BECA4 +3BECA4:lI101|N +3BDFD8:lI113|H3BE09C +3BE09C:lI116|N +3BDF38:lH3BDFE8|H3BDFF4 +3BDFE8:t2:H3BE0AC,H3BE0B4 +3BE0B4:lI118|H3BE178 +3BE178:lI105|H3BE24C +3BE24C:lI100|H3BE32C +3BE32C:lI101|H3BE420 +3BE420:lI111|H3BE524 +3BE524:lI47|H3BE628 +3BE628:lI113|H3BE72C +3BE72C:lI117|H3BE818 +3BE818:lI105|H3BE8FC +3BE8FC:lI99|H3BE9E8 +3BE9E8:lI107|H3BEADC +3BEADC:lI116|H3BEBC8 +3BEBC8:lI105|H3BECAC +3BECAC:lI109|H3BED88 +3BED88:lI101|N +3BE0AC:lI109|H3BE170 +3BE170:lI111|H3BE244 +3BE244:lI118|N +3BDFF4:lH3BE0BC|H3BE0C8 +3BE0BC:t2:H3BE180,H3BE188 +3BE188:lI118|H3BE25C +3BE25C:lI105|H3BE33C +3BE33C:lI100|H3BE430 +3BE430:lI101|H3BE52C +3BE52C:lI111|H3BE630 +3BE630:lI47|H3BE734 +3BE734:lI109|H3BE820 +3BE820:lI112|H3BE904 +3BE904:lI101|H3BE9F0 +3BE9F0:lI103|N +3BE180:lI109|H3BE254 +3BE254:lI112|H3BE334 +3BE334:lI101|H3BE428 +3BE428:lI103|N +3BE0C8:lH3BE190|H3BE19C +3BE190:t2:H3BE264,H3BE26C +3BE26C:lI118|H3BE34C +3BE34C:lI105|H3BE440 +3BE440:lI100|H3BE534 +3BE534:lI101|H3BE638 +3BE638:lI111|H3BE73C +3BE73C:lI47|H3BE828 +3BE828:lI109|H3BE90C +3BE90C:lI112|H3BE9F8 +3BE9F8:lI101|H3BEAE4 +3BEAE4:lI103|N +3BE264:lI109|H3BE344 +3BE344:lI112|H3BE438 +3BE438:lI103|N +3BE19C:lH3BE274|H3BE280 +3BE274:t2:H3BE354,H3BE35C +3BE35C:lI118|H3BE450 +3BE450:lI105|H3BE544 +3BE544:lI100|H3BE640 +3BE640:lI101|H3BE744 +3BE744:lI111|H3BE830 +3BE830:lI47|H3BE914 +3BE914:lI109|H3BEA00 +3BEA00:lI112|H3BEAEC +3BEAEC:lI101|H3BEBD0 +3BEBD0:lI103|N +3BE354:lI109|H3BE448 +3BE448:lI112|H3BE53C +3BE53C:lI101|N +3BE280:lH3BE364|H3BE370 +3BE364:t2:H3BE458,H3BE460 +3BE460:lI116|H3BE554 +3BE554:lI101|H3BE650 +3BE650:lI120|H3BE754 +3BE754:lI116|H3BE838 +3BE838:lI47|H3BE91C +3BE91C:lI120|H3BEA08 +3BEA08:lI45|H3BEAF4 +3BEAF4:lI115|H3BEBD8 +3BEBD8:lI103|H3BECB4 +3BECB4:lI109|H3BED90 +3BED90:lI108|N +3BE458:lI115|H3BE54C +3BE54C:lI103|H3BE648 +3BE648:lI109|H3BE74C +3BE74C:lI108|N +3BE370:lH3BE468|H3BE474 +3BE468:t2:H3BE55C,H3BE564 +3BE564:lI116|H3BE660 +3BE660:lI101|H3BE764 +3BE764:lI120|H3BE840 +3BE840:lI116|H3BE924 +3BE924:lI47|H3BEA10 +3BEA10:lI120|H3BEAFC +3BEAFC:lI45|H3BEBE0 +3BEBE0:lI115|H3BECBC +3BECBC:lI103|H3BED98 +3BED98:lI109|H3BEE74 +3BEE74:lI108|N +3BE55C:lI115|H3BE658 +3BE658:lI103|H3BE75C +3BE75C:lI109|N +3BE474:lH3BE56C|H3BE578 +3BE56C:t2:H3BE668,H3BE670 +3BE670:lI116|H3BE774 +3BE774:lI101|H3BE850 +3BE850:lI120|H3BE92C +3BE92C:lI116|H3BEA18 +3BEA18:lI47|H3BEB04 +3BEB04:lI120|H3BEBE8 +3BEBE8:lI45|H3BECC4 +3BECC4:lI115|H3BEDA0 +3BEDA0:lI101|H3BEE7C +3BEE7C:lI116|H3BEF48 +3BEF48:lI101|H3BF014 +3BF014:lI120|H3BF0E0 +3BF0E0:lI116|N +3BE668:lI101|H3BE76C +3BE76C:lI116|H3BE848 +3BE848:lI120|N +3BE578:lH3BE678|H3BE684 +3BE678:t2:H3BE77C,H3BE784 +3BE784:lI116|H3BE860 +3BE860:lI101|H3BE93C +3BE93C:lI120|H3BEA20 +3BEA20:lI116|H3BEB0C +3BEB0C:lI47|H3BEBF0 +3BEBF0:lI116|H3BECCC +3BECCC:lI97|H3BEDA8 +3BEDA8:lI98|H3BEE84 +3BEE84:lI45|H3BEF50 +3BEF50:lI115|H3BF01C +3BF01C:lI101|H3BF0E8 +3BF0E8:lI112|H3BF1AC +3BF1AC:lI97|H3BF270 +3BF270:lI114|H3BF324 +3BF324:lI97|H3BF3D0 +3BF3D0:lI116|H3BF484 +3BF484:lI101|H3BF540 +3BF540:lI100|H3BF604 +3BF604:lI45|H3BF6D8 +3BF6D8:lI118|H3BF7AC +3BF7AC:lI97|H3BF880 +3BF880:lI108|H3BF964 +3BF964:lI117|H3BFA40 +3BFA40:lI101|H3BFB14 +3BFB14:lI115|N +3BE77C:lI116|H3BE858 +3BE858:lI115|H3BE934 +3BE934:lI118|N +3BE684:lH3BE78C|H3BE798 +3BE78C:t2:H3BE868,H3BE870 +3BE870:lI116|H3BE94C +3BE94C:lI101|H3BEA30 +3BEA30:lI120|H3BEB14 +3BEB14:lI116|H3BEBF8 +3BEBF8:lI47|H3BECD4 +3BECD4:lI114|H3BEDB0 +3BEDB0:lI105|H3BEE8C +3BEE8C:lI99|H3BEF58 +3BEF58:lI104|H3BF024 +3BF024:lI116|H3BF0F0 +3BF0F0:lI101|H3BF1B4 +3BF1B4:lI120|H3BF278 +3BF278:lI116|N +3BE868:lI114|H3BE944 +3BE944:lI116|H3BEA28 +3BEA28:lI120|N +3BE798:lH3BE878|H3BE884 +3BE878:t2:H3BE954,H3BE95C +3BE95C:lI116|H3BEA40 +3BEA40:lI101|H3BEB24 +3BEB24:lI120|H3BEC00 +3BEC00:lI116|H3BECDC +3BECDC:lI47|H3BEDB8 +3BEDB8:lI112|H3BEE94 +3BEE94:lI108|H3BEF60 +3BEF60:lI97|H3BF02C +3BF02C:lI105|H3BF0F8 +3BF0F8:lI110|N +3BE954:lI116|H3BEA38 +3BEA38:lI120|H3BEB1C +3BEB1C:lI116|N +3BE884:lH3BE964|H3BE970 +3BE964:t2:H3BEA48,H3BEA50 +3BEA50:lI116|H3BEB34 +3BEB34:lI101|H3BEC10 +3BEC10:lI120|H3BECEC +3BECEC:lI116|H3BEDC8 +3BEDC8:lI47|H3BEE9C +3BEE9C:lI120|H3BEF68 +3BEF68:lI45|H3BF034 +3BF034:lI115|H3BF100 +3BF100:lI101|H3BF1BC +3BF1BC:lI114|H3BF280 +3BF280:lI118|H3BF32C +3BF32C:lI101|H3BF3D8 +3BF3D8:lI114|H3BF48C +3BF48C:lI45|H3BF548 +3BF548:lI112|H3BF60C +3BF60C:lI97|H3BF6E0 +3BF6E0:lI114|H3BF7B4 +3BF7B4:lI115|H3BF888 +3BF888:lI101|H3BF96C +3BF96C:lI100|H3BFA48 +3BFA48:lI45|H3BFB1C +3BFB1C:lI104|H3BFBF0 +3BFBF0:lI116|H3BFCBC +3BFCBC:lI109|H3BFD80 +3BFD80:lI108|N +3BEA48:lI115|H3BEB2C +3BEB2C:lI104|H3BEC08 +3BEC08:lI116|H3BECE4 +3BECE4:lI109|H3BEDC0 +3BEDC0:lI108|N +3BE970:lH3BEA58|H3BEA64 +3BEA58:t2:H3BEB3C,H3BEB44 +3BEB44:lI116|H3BEC20 +3BEC20:lI101|H3BECFC +3BECFC:lI120|H3BEDD8 +3BEDD8:lI116|H3BEEA4 +3BEEA4:lI47|H3BEF70 +3BEF70:lI104|H3BF03C +3BF03C:lI116|H3BF108 +3BF108:lI109|H3BF1C4 +3BF1C4:lI108|N +3BEB3C:lI104|H3BEC18 +3BEC18:lI116|H3BECF4 +3BECF4:lI109|H3BEDD0 +3BEDD0:lI108|N +3BEA64:lH3BEB4C|H3BEB58 +3BEB4C:t2:H3BEC28,H3BEC30 +3BEC30:lI116|H3BED0C +3BED0C:lI101|H3BEDE8 +3BEDE8:lI120|H3BEEAC +3BEEAC:lI116|H3BEF78 +3BEF78:lI47|H3BF044 +3BF044:lI104|H3BF110 +3BF110:lI116|H3BF1CC +3BF1CC:lI109|H3BF288 +3BF288:lI108|N +3BEC28:lI104|H3BED04 +3BED04:lI116|H3BEDE0 +3BEDE0:lI109|N +3BEB58:lH3BEC38|H3BEC44 +3BEC38:t2:H3BED14,H3BED1C +3BED1C:lI105|H3BEDF8 +3BEDF8:lI109|H3BEEBC +3BEEBC:lI97|H3BEF80 +3BEF80:lI103|H3BF04C +3BF04C:lI101|H3BF118 +3BF118:lI47|H3BF1D4 +3BF1D4:lI120|H3BF290 +3BF290:lI45|H3BF334 +3BF334:lI120|H3BF3E0 +3BF3E0:lI119|H3BF494 +3BF494:lI105|H3BF550 +3BF550:lI110|H3BF614 +3BF614:lI100|H3BF6E8 +3BF6E8:lI111|H3BF7BC +3BF7BC:lI119|H3BF890 +3BF890:lI100|H3BF974 +3BF974:lI117|H3BFA50 +3BFA50:lI109|H3BFB24 +3BFB24:lI112|N +3BED14:lI120|H3BEDF0 +3BEDF0:lI119|H3BEEB4 +3BEEB4:lI100|N +3BEC44:lH3BED24|H3BED30 +3BED24:t2:H3BEE00,H3BEE08 +3BEE08:lI105|H3BEECC +3BEECC:lI109|H3BEF90 +3BEF90:lI97|H3BF054 +3BF054:lI103|H3BF120 +3BF120:lI101|H3BF1DC +3BF1DC:lI47|H3BF298 +3BF298:lI120|H3BF33C +3BF33C:lI45|H3BF3E8 +3BF3E8:lI120|H3BF49C +3BF49C:lI112|H3BF558 +3BF558:lI105|H3BF61C +3BF61C:lI120|H3BF6F0 +3BF6F0:lI109|H3BF7C4 +3BF7C4:lI97|H3BF898 +3BF898:lI112|N +3BEE00:lI120|H3BEEC4 +3BEEC4:lI112|H3BEF88 +3BEF88:lI109|N +3BED30:lH3BEE10|H3BEE1C +3BEE10:t2:H3BEED4,H3BEEDC +3BEEDC:lI105|H3BEFA0 +3BEFA0:lI109|H3BF064 +3BF064:lI97|H3BF128 +3BF128:lI103|H3BF1E4 +3BF1E4:lI101|H3BF2A0 +3BF2A0:lI47|H3BF344 +3BF344:lI120|H3BF3F0 +3BF3F0:lI45|H3BF4A4 +3BF4A4:lI120|H3BF560 +3BF560:lI98|H3BF624 +3BF624:lI105|H3BF6F8 +3BF6F8:lI116|H3BF7CC +3BF7CC:lI109|H3BF8A0 +3BF8A0:lI97|H3BF97C +3BF97C:lI112|N +3BEED4:lI120|H3BEF98 +3BEF98:lI98|H3BF05C +3BF05C:lI109|N +3BEE1C:lH3BEEE4|H3BEEF0 +3BEEE4:t2:H3BEFA8,H3BEFB0 +3BEFB0:lI105|H3BF074 +3BF074:lI109|H3BF138 +3BF138:lI97|H3BF1EC +3BF1EC:lI103|H3BF2A8 +3BF2A8:lI101|H3BF34C +3BF34C:lI47|H3BF3F8 +3BF3F8:lI120|H3BF4AC +3BF4AC:lI45|H3BF568 +3BF568:lI114|H3BF62C +3BF62C:lI103|H3BF700 +3BF700:lI98|N +3BEFA8:lI114|H3BF06C +3BF06C:lI103|H3BF130 +3BF130:lI98|N +3BEEF0:lH3BEFB8|H3BEFC4 +3BEFB8:t2:H3BF07C,H3BF084 +3BF084:lI105|H3BF148 +3BF148:lI109|H3BF1FC +3BF1FC:lI97|H3BF2B0 +3BF2B0:lI103|H3BF354 +3BF354:lI101|H3BF400 +3BF400:lI47|H3BF4B4 +3BF4B4:lI120|H3BF570 +3BF570:lI45|H3BF634 +3BF634:lI112|H3BF708 +3BF708:lI111|H3BF7D4 +3BF7D4:lI114|H3BF8A8 +3BF8A8:lI116|H3BF984 +3BF984:lI97|H3BFA58 +3BFA58:lI98|H3BFB2C +3BFB2C:lI108|H3BFBF8 +3BFBF8:lI101|H3BFCC4 +3BFCC4:lI45|H3BFD88 +3BFD88:lI112|H3BFE44 +3BFE44:lI105|H3BFEF0 +3BFEF0:lI120|H3BFFA4 +3BFFA4:lI109|H3C0050 +3C0050:lI97|H3C00FC +3C00FC:lI112|N +3BF07C:lI112|H3BF140 +3BF140:lI112|H3BF1F4 +3BF1F4:lI109|N +3BEFC4:lH3BF08C|H3BF098 +3BF08C:t2:H3BF150,H3BF158 +3BF158:lI105|H3BF20C +3BF20C:lI109|H3BF2C0 +3BF2C0:lI97|H3BF35C +3BF35C:lI103|H3BF408 +3BF408:lI101|H3BF4BC +3BF4BC:lI47|H3BF578 +3BF578:lI120|H3BF63C +3BF63C:lI45|H3BF710 +3BF710:lI112|H3BF7DC +3BF7DC:lI111|H3BF8B0 +3BF8B0:lI114|H3BF98C +3BF98C:lI116|H3BFA60 +3BFA60:lI97|H3BFB34 +3BFB34:lI98|H3BFC00 +3BFC00:lI108|H3BFCCC +3BFCCC:lI101|H3BFD90 +3BFD90:lI45|H3BFE4C +3BFE4C:lI103|H3BFEF8 +3BFEF8:lI114|H3BFFAC +3BFFAC:lI97|H3C0058 +3C0058:lI121|H3C0104 +3C0104:lI109|H3C01A8 +3C01A8:lI97|H3C025C +3C025C:lI112|N +3BF150:lI112|H3BF204 +3BF204:lI103|H3BF2B8 +3BF2B8:lI109|N +3BF098:lH3BF160|H3BF16C +3BF160:t2:H3BF214,H3BF21C +3BF21C:lI105|H3BF2D0 +3BF2D0:lI109|H3BF36C +3BF36C:lI97|H3BF410 +3BF410:lI103|H3BF4C4 +3BF4C4:lI101|H3BF580 +3BF580:lI47|H3BF644 +3BF644:lI120|H3BF718 +3BF718:lI45|H3BF7E4 +3BF7E4:lI112|H3BF8B8 +3BF8B8:lI111|H3BF994 +3BF994:lI114|H3BFA68 +3BFA68:lI116|H3BFB3C +3BFB3C:lI97|H3BFC08 +3BFC08:lI98|H3BFCD4 +3BFCD4:lI108|H3BFD98 +3BFD98:lI101|H3BFE54 +3BFE54:lI45|H3BFF00 +3BFF00:lI98|H3BFFB4 +3BFFB4:lI105|H3C0060 +3C0060:lI116|H3C010C +3C010C:lI109|H3C01B0 +3C01B0:lI97|H3C0264 +3C0264:lI112|N +3BF214:lI112|H3BF2C8 +3BF2C8:lI98|H3BF364 +3BF364:lI109|N +3BF16C:lH3BF224|H3BF230 +3BF224:t2:H3BF2D8,H3BF2E0 +3BF2E0:lI105|H3BF37C +3BF37C:lI109|H3BF420 +3BF420:lI97|H3BF4CC +3BF4CC:lI103|H3BF588 +3BF588:lI101|H3BF64C +3BF64C:lI47|H3BF720 +3BF720:lI120|H3BF7EC +3BF7EC:lI45|H3BF8C0 +3BF8C0:lI112|H3BF99C +3BF99C:lI111|H3BFA70 +3BFA70:lI114|H3BFB44 +3BFB44:lI116|H3BFC10 +3BFC10:lI97|H3BFCDC +3BFCDC:lI98|H3BFDA0 +3BFDA0:lI108|H3BFE5C +3BFE5C:lI101|H3BFF08 +3BFF08:lI45|H3BFFBC +3BFFBC:lI97|H3C0068 +3C0068:lI110|H3C0114 +3C0114:lI121|H3C01B8 +3C01B8:lI109|H3C026C +3C026C:lI97|H3C0318 +3C0318:lI112|N +3BF2D8:lI112|H3BF374 +3BF374:lI110|H3BF418 +3BF418:lI109|N +3BF230:lH3BF2E8|H3BF2F4 +3BF2E8:t2:H3BF384,H3BF38C +3BF38C:lI105|H3BF430 +3BF430:lI109|H3BF4DC +3BF4DC:lI97|H3BF590 +3BF590:lI103|H3BF654 +3BF654:lI101|H3BF728 +3BF728:lI47|H3BF7F4 +3BF7F4:lI120|H3BF8C8 +3BF8C8:lI45|H3BF9A4 +3BF9A4:lI99|H3BFA78 +3BFA78:lI109|H3BFB4C +3BFB4C:lI117|H3BFC18 +3BFC18:lI45|H3BFCE4 +3BFCE4:lI114|H3BFDA8 +3BFDA8:lI97|H3BFE64 +3BFE64:lI115|H3BFF10 +3BFF10:lI116|H3BFFC4 +3BFFC4:lI101|H3C0070 +3C0070:lI114|N +3BF384:lI114|H3BF428 +3BF428:lI97|H3BF4D4 +3BF4D4:lI115|N +3BF2F4:lH3BF394|H3BF3A0 +3BF394:t2:H3BF438,H3BF440 +3BF440:lI105|H3BF4EC +3BF4EC:lI109|H3BF5A0 +3BF5A0:lI97|H3BF664 +3BF664:lI103|H3BF730 +3BF730:lI101|H3BF7FC +3BF7FC:lI47|H3BF8D0 +3BF8D0:lI116|H3BF9AC +3BF9AC:lI105|H3BFA80 +3BFA80:lI102|H3BFB54 +3BFB54:lI102|N +3BF438:lI116|H3BF4E4 +3BF4E4:lI105|H3BF598 +3BF598:lI102|H3BF65C +3BF65C:lI102|N +3BF3A0:lH3BF448|H3BF454 +3BF448:t2:H3BF4F4,H3BF4FC +3BF4FC:lI105|H3BF5B0 +3BF5B0:lI109|H3BF674 +3BF674:lI97|H3BF738 +3BF738:lI103|H3BF804 +3BF804:lI101|H3BF8D8 +3BF8D8:lI47|H3BF9B4 +3BF9B4:lI116|H3BFA88 +3BFA88:lI105|H3BFB5C +3BFB5C:lI102|H3BFC20 +3BFC20:lI102|N +3BF4F4:lI116|H3BF5A8 +3BF5A8:lI105|H3BF66C +3BF66C:lI102|N +3BF454:lH3BF504|H3BF510 +3BF504:t2:H3BF5B8,H3BF5C0 +3BF5C0:lI105|H3BF684 +3BF684:lI109|H3BF748 +3BF748:lI97|H3BF80C +3BF80C:lI103|H3BF8E0 +3BF8E0:lI101|H3BF9BC +3BF9BC:lI47|H3BFA90 +3BFA90:lI112|H3BFB64 +3BFB64:lI110|H3BFC28 +3BFC28:lI103|N +3BF5B8:lI112|H3BF67C +3BF67C:lI110|H3BF740 +3BF740:lI103|N +3BF510:lH3BF5C8|H3BF5D4 +3BF5C8:t2:H3BF68C,H3BF694 +3BF694:lI105|H3BF758 +3BF758:lI109|H3BF81C +3BF81C:lI97|H3BF8F0 +3BF8F0:lI103|H3BF9C4 +3BF9C4:lI101|H3BFA98 +3BFA98:lI47|H3BFB6C +3BFB6C:lI106|H3BFC30 +3BFC30:lI112|H3BFCEC +3BFCEC:lI101|H3BFDB0 +3BFDB0:lI103|N +3BF68C:lI106|H3BF750 +3BF750:lI112|H3BF814 +3BF814:lI101|H3BF8E8 +3BF8E8:lI103|N +3BF5D4:lH3BF69C|H3BF6A8 +3BF69C:t2:H3BF760,H3BF768 +3BF768:lI105|H3BF82C +3BF82C:lI109|H3BF900 +3BF900:lI97|H3BF9CC +3BF9CC:lI103|H3BFAA0 +3BFAA0:lI101|H3BFB74 +3BFB74:lI47|H3BFC38 +3BFC38:lI106|H3BFCF4 +3BFCF4:lI112|H3BFDB8 +3BFDB8:lI101|H3BFE6C +3BFE6C:lI103|N +3BF760:lI106|H3BF824 +3BF824:lI112|H3BF8F8 +3BF8F8:lI103|N +3BF6A8:lH3BF770|H3BF77C +3BF770:t2:H3BF834,H3BF83C +3BF83C:lI105|H3BF910 +3BF910:lI109|H3BF9DC +3BF9DC:lI97|H3BFAA8 +3BFAA8:lI103|H3BFB7C +3BFB7C:lI101|H3BFC40 +3BFC40:lI47|H3BFCFC +3BFCFC:lI106|H3BFDC0 +3BFDC0:lI112|H3BFE74 +3BFE74:lI101|H3BFF18 +3BFF18:lI103|N +3BF834:lI106|H3BF908 +3BF908:lI112|H3BF9D4 +3BF9D4:lI101|N +3BF77C:lH3BF844|H3BF850 +3BF844:t2:H3BF918,H3BF920 +3BF920:lI105|H3BF9EC +3BF9EC:lI109|H3BFAB8 +3BFAB8:lI97|H3BFB84 +3BFB84:lI103|H3BFC48 +3BFC48:lI101|H3BFD04 +3BFD04:lI47|H3BFDC8 +3BFDC8:lI105|H3BFE7C +3BFE7C:lI101|H3BFF20 +3BFF20:lI102|N +3BF918:lI105|H3BF9E4 +3BF9E4:lI101|H3BFAB0 +3BFAB0:lI102|N +3BF850:lH3BF928|H3BF934 +3BF928:t2:H3BF9F4,H3BF9FC +3BF9FC:lI105|H3BFAC8 +3BFAC8:lI109|H3BFB94 +3BFB94:lI97|H3BFC50 +3BFC50:lI103|H3BFD0C +3BFD0C:lI101|H3BFDD0 +3BFDD0:lI47|H3BFE84 +3BFE84:lI103|H3BFF28 +3BFF28:lI105|H3BFFCC +3BFFCC:lI102|N +3BF9F4:lI103|H3BFAC0 +3BFAC0:lI105|H3BFB8C +3BFB8C:lI102|N +3BF934:lH3BFA04|H3BFA10 +3BFA04:t2:H3BFAD0,H3BFAD8 +3BFAD8:lI99|H3BFBA4 +3BFBA4:lI104|H3BFC60 +3BFC60:lI101|H3BFD14 +3BFD14:lI109|H3BFDD8 +3BFDD8:lI105|H3BFE8C +3BFE8C:lI99|H3BFF30 +3BFF30:lI97|H3BFFD4 +3BFFD4:lI108|H3C0078 +3C0078:lI47|H3C011C +3C011C:lI120|H3C01C0 +3C01C0:lI45|H3C0274 +3C0274:lI112|H3C0320 +3C0320:lI100|H3C03CC +3C03CC:lI98|N +3BFAD0:lI112|H3BFB9C +3BFB9C:lI100|H3BFC58 +3BFC58:lI98|N +3BFA10:lH3BFAE0|H3BFAEC +3BFAE0:t2:H3BFBAC,H3BFBB4 +3BFBB4:lI99|H3BFC70 +3BFC70:lI104|H3BFD24 +3BFD24:lI101|H3BFDE0 +3BFDE0:lI109|H3BFE94 +3BFE94:lI105|H3BFF38 +3BFF38:lI99|H3BFFDC +3BFFDC:lI97|H3C0080 +3C0080:lI108|H3C0124 +3C0124:lI47|H3C01C8 +3C01C8:lI120|H3C027C +3C027C:lI45|H3C0328 +3C0328:lI112|H3C03D4 +3C03D4:lI100|H3C0460 +3C0460:lI98|N +3BFBAC:lI120|H3BFC68 +3BFC68:lI121|H3BFD1C +3BFD1C:lI122|N +3BFAEC:lH3BFBBC|H3BFBC8 +3BFBBC:t2:H3BFC78,H3BFC80 +3BFC80:lI97|H3BFD34 +3BFD34:lI117|H3BFDF0 +3BFDF0:lI100|H3BFE9C +3BFE9C:lI105|H3BFF40 +3BFF40:lI111|H3BFFE4 +3BFFE4:lI47|H3C0088 +3C0088:lI120|H3C012C +3C012C:lI45|H3C01D0 +3C01D0:lI119|H3C0284 +3C0284:lI97|H3C0330 +3C0330:lI118|N +3BFC78:lI119|H3BFD2C +3BFD2C:lI97|H3BFDE8 +3BFDE8:lI118|N +3BFBC8:lH3BFC88|H3BFC94 +3BFC88:t2:H3BFD3C,H3BFD44 +3BFD44:lI97|H3BFE00 +3BFE00:lI117|H3BFEA4 +3BFEA4:lI100|H3BFF48 +3BFF48:lI105|H3BFFEC +3BFFEC:lI111|H3C0090 +3C0090:lI47|H3C0134 +3C0134:lI120|H3C01D8 +3C01D8:lI45|H3C028C +3C028C:lI114|H3C0338 +3C0338:lI101|H3C03DC +3C03DC:lI97|H3C0468 +3C0468:lI108|H3C04FC +3C04FC:lI97|H3C0598 +3C0598:lI117|H3C063C +3C063C:lI100|H3C06E8 +3C06E8:lI105|H3C0794 +3C0794:lI111|N +3BFD3C:lI114|H3BFDF8 +3BFDF8:lI97|N +3BFC94:lH3BFD4C|H3BFD58 +3BFD4C:t2:H3BFE08,H3BFE10 +3BFE10:lI97|H3BFEB4 +3BFEB4:lI117|H3BFF58 +3BFF58:lI100|H3BFFF4 +3BFFF4:lI105|H3C0098 +3C0098:lI111|H3C013C +3C013C:lI47|H3C01E0 +3C01E0:lI120|H3C0294 +3C0294:lI45|H3C0340 +3C0340:lI112|H3C03E4 +3C03E4:lI110|H3C0470 +3C0470:lI45|H3C0504 +3C0504:lI114|H3C05A0 +3C05A0:lI101|H3C0644 +3C0644:lI97|H3C06F0 +3C06F0:lI108|H3C079C +3C079C:lI97|H3C0838 +3C0838:lI117|H3C08C4 +3C08C4:lI100|H3C0958 +3C0958:lI105|H3C09EC +3C09EC:lI111|H3C0A88 +3C0A88:lI45|H3C0B2C +3C0B2C:lI112|H3C0BD0 +3C0BD0:lI108|H3C0C84 +3C0C84:lI117|H3C0D38 +3C0D38:lI103|H3C0DEC +3C0DEC:lI105|H3C0EA0 +3C0EA0:lI110|N +3BFE08:lI114|H3BFEAC +3BFEAC:lI112|H3BFF50 +3BFF50:lI109|N +3BFD58:lH3BFE18|H3BFE24 +3BFE18:t2:H3BFEBC,H3BFEC4 +3BFEC4:lI97|H3BFF68 +3BFF68:lI117|H3C0004 +3C0004:lI100|H3C00A0 +3C00A0:lI105|H3C0144 +3C0144:lI111|H3C01E8 +3C01E8:lI47|H3C029C +3C029C:lI120|H3C0348 +3C0348:lI45|H3C03EC +3C03EC:lI112|H3C0478 +3C0478:lI110|H3C050C +3C050C:lI45|H3C05A8 +3C05A8:lI114|H3C064C +3C064C:lI101|H3C06F8 +3C06F8:lI97|H3C07A4 +3C07A4:lI108|H3C0840 +3C0840:lI97|H3C08CC +3C08CC:lI117|H3C0960 +3C0960:lI100|H3C09F4 +3C09F4:lI105|H3C0A90 +3C0A90:lI111|N +3BFEBC:lI114|H3BFF60 +3BFF60:lI97|H3BFFFC +3BFFFC:lI109|N +3BFE24:lH3BFECC|H3BFED8 +3BFECC:t2:H3BFF70,H3BFF78 +3BFF78:lI97|H3C0014 +3C0014:lI117|H3C00B0 +3C00B0:lI100|H3C014C +3C014C:lI105|H3C01F0 +3C01F0:lI111|H3C02A4 +3C02A4:lI47|H3C0350 +3C0350:lI120|H3C03F4 +3C03F4:lI45|H3C0480 +3C0480:lI97|H3C0514 +3C0514:lI105|H3C05B0 +3C05B0:lI102|H3C0654 +3C0654:lI102|N +3BFF70:lI97|H3C000C +3C000C:lI105|H3C00A8 +3C00A8:lI102|N +3BFED8:lH3BFF80|H3BFF8C +3BFF80:t2:H3C001C,H3C0024 +3C0024:lI97|H3C00C0 +3C00C0:lI117|H3C015C +3C015C:lI100|H3C0200 +3C0200:lI105|H3C02AC +3C02AC:lI111|H3C0358 +3C0358:lI47|H3C03FC +3C03FC:lI120|H3C0488 +3C0488:lI45|H3C051C +3C051C:lI97|H3C05B8 +3C05B8:lI105|H3C065C +3C065C:lI102|H3C0700 +3C0700:lI102|N +3C001C:lI97|H3C00B8 +3C00B8:lI105|H3C0154 +3C0154:lI102|H3C01F8 +3C01F8:lI102|N +3BFF8C:lH3C002C|H3C0038 +3C002C:t2:H3C00C8,H3C00D0 +3C00D0:lI97|H3C016C +3C016C:lI117|H3C0210 +3C0210:lI100|H3C02BC +3C02BC:lI105|H3C0360 +3C0360:lI111|H3C0404 +3C0404:lI47|H3C0490 +3C0490:lI120|H3C0524 +3C0524:lI45|H3C05C0 +3C05C0:lI97|H3C0664 +3C0664:lI105|H3C0708 +3C0708:lI102|H3C07AC +3C07AC:lI102|N +3C00C8:lI97|H3C0164 +3C0164:lI105|H3C0208 +3C0208:lI102|H3C02B4 +3C02B4:lI99|N +3C0038:lH3C00D8|H3C00E4 +3C00D8:t2:H3C0174,H3C017C +3C017C:lI97|H3C0220 +3C0220:lI117|H3C02CC +3C02CC:lI100|H3C0370 +3C0370:lI105|H3C040C +3C040C:lI111|H3C0498 +3C0498:lI47|H3C052C +3C052C:lI109|H3C05C8 +3C05C8:lI112|H3C066C +3C066C:lI101|H3C0710 +3C0710:lI103|N +3C0174:lI109|H3C0218 +3C0218:lI112|H3C02C4 +3C02C4:lI103|H3C0368 +3C0368:lI97|N +3C00E4:lH3C0184|H3C0190 +3C0184:t2:H3C0228,H3C0230 +3C0230:lI97|H3C02DC +3C02DC:lI117|H3C0380 +3C0380:lI100|H3C0414 +3C0414:lI105|H3C04A0 +3C04A0:lI111|H3C0534 +3C0534:lI47|H3C05D0 +3C05D0:lI109|H3C0674 +3C0674:lI112|H3C0718 +3C0718:lI101|H3C07B4 +3C07B4:lI103|N +3C0228:lI109|H3C02D4 +3C02D4:lI112|H3C0378 +3C0378:lI50|N +3C0190:lH3C0238|H3C0244 +3C0238:t2:H3C02E4,H3C02EC +3C02EC:lI97|H3C0390 +3C0390:lI117|H3C041C +3C041C:lI100|H3C04A8 +3C04A8:lI105|H3C053C +3C053C:lI111|H3C05D8 +3C05D8:lI47|H3C067C +3C067C:lI98|H3C0720 +3C0720:lI97|H3C07BC +3C07BC:lI115|H3C0848 +3C0848:lI105|H3C08D4 +3C08D4:lI99|N +3C02E4:lI97|H3C0388 +3C0388:lI117|N +3C0244:lH3C02F4|H3C0300 +3C02F4:t2:H3C0398,H3C03A0 +3C03A0:lI97|H3C042C +3C042C:lI117|H3C04B8 +3C04B8:lI100|H3C0544 +3C0544:lI105|H3C05E0 +3C05E0:lI111|H3C0684 +3C0684:lI47|H3C0728 +3C0728:lI98|H3C07C4 +3C07C4:lI97|H3C0850 +3C0850:lI115|H3C08DC +3C08DC:lI105|H3C0968 +3C0968:lI99|N +3C0398:lI115|H3C0424 +3C0424:lI110|H3C04B0 +3C04B0:lI100|N +3C0300:lH3C03A8|H3C03B4 +3C03A8:t2:H3C0434,H3C043C +3C043C:lI97|H3C04C8 +3C04C8:lI112|H3C0554 +3C0554:lI112|H3C05E8 +3C05E8:lI108|H3C068C +3C068C:lI105|H3C0730 +3C0730:lI99|H3C07CC +3C07CC:lI97|H3C0858 +3C0858:lI116|H3C08E4 +3C08E4:lI105|H3C0970 +3C0970:lI111|H3C09FC +3C09FC:lI110|H3C0A98 +3C0A98:lI47|H3C0B34 +3C0B34:lI122|H3C0BD8 +3C0BD8:lI105|H3C0C8C +3C0C8C:lI112|N +3C0434:lI122|H3C04C0 +3C04C0:lI105|H3C054C +3C054C:lI112|N +3C03B4:lH3C0444|H3C0450 +3C0444:t2:H3C04D0,H3C04D8 +3C04D8:lI97|H3C0564 +3C0564:lI112|H3C05F8 +3C05F8:lI112|H3C0694 +3C0694:lI108|H3C0738 +3C0738:lI105|H3C07D4 +3C07D4:lI99|H3C0860 +3C0860:lI97|H3C08EC +3C08EC:lI116|H3C0978 +3C0978:lI105|H3C0A04 +3C0A04:lI111|H3C0AA0 +3C0AA0:lI110|H3C0B3C +3C0B3C:lI47|H3C0BE0 +3C0BE0:lI120|H3C0C94 +3C0C94:lI45|H3C0D40 +3C0D40:lI119|H3C0DF4 +3C0DF4:lI97|H3C0EA8 +3C0EA8:lI105|H3C0F64 +3C0F64:lI115|H3C1030 +3C1030:lI45|H3C1104 +3C1104:lI115|H3C11D8 +3C11D8:lI111|H3C12A4 +3C12A4:lI117|H3C1378 +3C1378:lI114|H3C1454 +3C1454:lI99|H3C1538 +3C1538:lI101|N +3C04D0:lI115|H3C055C +3C055C:lI114|H3C05F0 +3C05F0:lI99|N +3C0450:lH3C04E0|H3C04EC +3C04E0:t2:H3C056C,H3C0574 +3C0574:lI97|H3C0608 +3C0608:lI112|H3C06A4 +3C06A4:lI112|H3C0748 +3C0748:lI108|H3C07E4 +3C07E4:lI105|H3C0868 +3C0868:lI99|H3C08F4 +3C08F4:lI97|H3C0980 +3C0980:lI116|H3C0A0C +3C0A0C:lI105|H3C0AA8 +3C0AA8:lI111|H3C0B44 +3C0B44:lI110|H3C0BE8 +3C0BE8:lI47|H3C0C9C +3C0C9C:lI120|H3C0D48 +3C0D48:lI45|H3C0DFC +3C0DFC:lI117|H3C0EB0 +3C0EB0:lI115|H3C0F6C +3C0F6C:lI116|H3C1038 +3C1038:lI97|H3C110C +3C110C:lI114|N +3C056C:lI117|H3C0600 +3C0600:lI115|H3C069C +3C069C:lI116|H3C0740 +3C0740:lI97|H3C07DC +3C07DC:lI114|N +3C04EC:lH3C057C|H3C0588 +3C057C:t2:H3C0610,H3C0618 +3C0618:lI97|H3C06B4 +3C06B4:lI112|H3C0750 +3C0750:lI112|H3C07EC +3C07EC:lI108|H3C0870 +3C0870:lI105|H3C08FC +3C08FC:lI99|H3C0988 +3C0988:lI97|H3C0A14 +3C0A14:lI116|H3C0AB0 +3C0AB0:lI105|H3C0B4C +3C0B4C:lI111|H3C0BF0 +3C0BF0:lI110|H3C0CA4 +3C0CA4:lI47|H3C0D50 +3C0D50:lI120|H3C0E04 +3C0E04:lI45|H3C0EB8 +3C0EB8:lI116|H3C0F74 +3C0F74:lI114|H3C1040 +3C1040:lI111|H3C1114 +3C1114:lI102|H3C11E0 +3C11E0:lI102|H3C12AC +3C12AC:lI45|H3C1380 +3C1380:lI109|H3C145C +3C145C:lI115|N +3C0610:lI109|H3C06AC +3C06AC:lI115|N +3C0588:lH3C0620|H3C062C +3C0620:t2:H3C06BC,H3C06C4 +3C06C4:lI97|H3C0760 +3C0760:lI112|H3C07F4 +3C07F4:lI112|H3C0878 +3C0878:lI108|H3C0904 +3C0904:lI105|H3C0990 +3C0990:lI99|H3C0A1C +3C0A1C:lI97|H3C0AB8 +3C0AB8:lI116|H3C0B54 +3C0B54:lI105|H3C0BF8 +3C0BF8:lI111|H3C0CAC +3C0CAC:lI110|H3C0D58 +3C0D58:lI47|H3C0E0C +3C0E0C:lI120|H3C0EC0 +3C0EC0:lI45|H3C0F7C +3C0F7C:lI116|H3C1048 +3C1048:lI114|H3C111C +3C111C:lI111|H3C11E8 +3C11E8:lI102|H3C12B4 +3C12B4:lI102|H3C1388 +3C1388:lI45|H3C1464 +3C1464:lI109|H3C1540 +3C1540:lI101|N +3C06BC:lI109|H3C0758 +3C0758:lI101|N +3C062C:lH3C06CC|H3C06D8 +3C06CC:t2:H3C0768,H3C0770 +3C0770:lI97|H3C0804 +3C0804:lI112|H3C0888 +3C0888:lI112|H3C090C +3C090C:lI108|H3C0998 +3C0998:lI105|H3C0A24 +3C0A24:lI99|H3C0AC0 +3C0AC0:lI97|H3C0B5C +3C0B5C:lI116|H3C0C00 +3C0C00:lI105|H3C0CB4 +3C0CB4:lI111|H3C0D60 +3C0D60:lI110|H3C0E14 +3C0E14:lI47|H3C0EC8 +3C0EC8:lI120|H3C0F84 +3C0F84:lI45|H3C1050 +3C1050:lI116|H3C1124 +3C1124:lI114|H3C11F0 +3C11F0:lI111|H3C12BC +3C12BC:lI102|H3C1390 +3C1390:lI102|H3C146C +3C146C:lI45|H3C1548 +3C1548:lI109|H3C161C +3C161C:lI97|H3C16F0 +3C16F0:lI110|N +3C0768:lI109|H3C07FC +3C07FC:lI97|H3C0880 +3C0880:lI110|N +3C06D8:lH3C0778|H3C0784 +3C0778:t2:H3C080C,H3C0814 +3C0814:lI97|H3C0890 +3C0890:lI112|H3C0914 +3C0914:lI112|H3C09A0 +3C09A0:lI108|H3C0A2C +3C0A2C:lI105|H3C0AC8 +3C0AC8:lI99|H3C0B64 +3C0B64:lI97|H3C0C08 +3C0C08:lI116|H3C0CBC +3C0CBC:lI105|H3C0D68 +3C0D68:lI111|H3C0E1C +3C0E1C:lI110|H3C0ED0 +3C0ED0:lI47|H3C0F8C +3C0F8C:lI120|H3C1058 +3C1058:lI45|H3C112C +3C112C:lI116|H3C11F8 +3C11F8:lI114|H3C12C4 +3C12C4:lI111|H3C1398 +3C1398:lI102|H3C1474 +3C1474:lI102|N +3C080C:lI116|N +3C0784:lH3C081C|H3C0828 +3C081C:t2:H3C0898,H3C08A0 +3C08A0:lI97|H3C0924 +3C0924:lI112|H3C09A8 +3C09A8:lI112|H3C0A34 +3C0A34:lI108|H3C0AD0 +3C0AD0:lI105|H3C0B6C +3C0B6C:lI99|H3C0C10 +3C0C10:lI97|H3C0CC4 +3C0CC4:lI116|H3C0D70 +3C0D70:lI105|H3C0E24 +3C0E24:lI111|H3C0ED8 +3C0ED8:lI110|H3C0F94 +3C0F94:lI47|H3C1060 +3C1060:lI120|H3C1134 +3C1134:lI45|H3C1200 +3C1200:lI116|H3C12CC +3C12CC:lI114|H3C13A0 +3C13A0:lI111|H3C147C +3C147C:lI102|H3C1550 +3C1550:lI102|N +3C0898:lI116|H3C091C +3C091C:lI114|N +3C0828:lH3C08A8|H3C08B4 +3C08A8:t2:H3C092C,H3C0934 +3C0934:lI97|H3C09B8 +3C09B8:lI112|H3C0A44 +3C0A44:lI112|H3C0AE0 +3C0AE0:lI108|H3C0B74 +3C0B74:lI105|H3C0C18 +3C0C18:lI99|H3C0CCC +3C0CCC:lI97|H3C0D78 +3C0D78:lI116|H3C0E2C +3C0E2C:lI105|H3C0EE0 +3C0EE0:lI111|H3C0F9C +3C0F9C:lI110|H3C1068 +3C1068:lI47|H3C113C +3C113C:lI120|H3C1208 +3C1208:lI45|H3C12D4 +3C12D4:lI116|H3C13A8 +3C13A8:lI114|H3C1484 +3C1484:lI111|H3C1558 +3C1558:lI102|H3C1624 +3C1624:lI102|N +3C092C:lI114|H3C09B0 +3C09B0:lI111|H3C0A3C +3C0A3C:lI102|H3C0AD8 +3C0AD8:lI102|N +3C08B4:lH3C093C|H3C0948 +3C093C:t2:H3C09C0,H3C09C8 +3C09C8:lI97|H3C0A54 +3C0A54:lI112|H3C0AF0 +3C0AF0:lI112|H3C0B84 +3C0B84:lI108|H3C0C28 +3C0C28:lI105|H3C0CDC +3C0CDC:lI99|H3C0D88 +3C0D88:lI97|H3C0E34 +3C0E34:lI116|H3C0EE8 +3C0EE8:lI105|H3C0FA4 +3C0FA4:lI111|H3C1070 +3C1070:lI110|H3C1144 +3C1144:lI47|H3C1210 +3C1210:lI120|H3C12DC +3C12DC:lI45|H3C13B0 +3C13B0:lI116|H3C148C +3C148C:lI101|H3C1560 +3C1560:lI120|H3C162C +3C162C:lI105|H3C16F8 +3C16F8:lI110|H3C17BC +3C17BC:lI102|H3C1880 +3C1880:lI111|N +3C09C0:lI116|H3C0A4C +3C0A4C:lI101|H3C0AE8 +3C0AE8:lI120|H3C0B7C +3C0B7C:lI105|H3C0C20 +3C0C20:lI110|H3C0CD4 +3C0CD4:lI102|H3C0D80 +3C0D80:lI111|N +3C0948:lH3C09D0|H3C09DC +3C09D0:t2:H3C0A5C,H3C0A64 +3C0A64:lI97|H3C0B00 +3C0B00:lI112|H3C0B94 +3C0B94:lI112|H3C0C38 +3C0C38:lI108|H3C0CE4 +3C0CE4:lI105|H3C0D90 +3C0D90:lI99|H3C0E3C +3C0E3C:lI97|H3C0EF0 +3C0EF0:lI116|H3C0FAC +3C0FAC:lI105|H3C1078 +3C1078:lI111|H3C114C +3C114C:lI110|H3C1218 +3C1218:lI47|H3C12E4 +3C12E4:lI120|H3C13B8 +3C13B8:lI45|H3C1494 +3C1494:lI116|H3C1568 +3C1568:lI101|H3C1634 +3C1634:lI120|H3C1700 +3C1700:lI105|H3C17C4 +3C17C4:lI110|H3C1888 +3C1888:lI102|H3C1944 +3C1944:lI111|N +3C0A5C:lI116|H3C0AF8 +3C0AF8:lI101|H3C0B8C +3C0B8C:lI120|H3C0C30 +3C0C30:lI105|N +3C09DC:lH3C0A6C|H3C0A78 +3C0A6C:t2:H3C0B08,H3C0B10 +3C0B10:lI97|H3C0BA4 +3C0BA4:lI112|H3C0C48 +3C0C48:lI112|H3C0CEC +3C0CEC:lI108|H3C0D98 +3C0D98:lI105|H3C0E44 +3C0E44:lI99|H3C0EF8 +3C0EF8:lI97|H3C0FB4 +3C0FB4:lI116|H3C1080 +3C1080:lI105|H3C1154 +3C1154:lI111|H3C1220 +3C1220:lI110|H3C12EC +3C12EC:lI47|H3C13C0 +3C13C0:lI120|H3C149C +3C149C:lI45|H3C1570 +3C1570:lI116|H3C163C +3C163C:lI101|H3C1708 +3C1708:lI120|N +3C0B08:lI116|H3C0B9C +3C0B9C:lI101|H3C0C40 +3C0C40:lI120|N +3C0A78:lH3C0B18|H3C0B24 +3C0B18:t2:H3C0BAC,H3C0BB4 +3C0BB4:lI97|H3C0C58 +3C0C58:lI112|H3C0CFC +3C0CFC:lI112|H3C0DA0 +3C0DA0:lI108|H3C0E4C +3C0E4C:lI105|H3C0F00 +3C0F00:lI99|H3C0FBC +3C0FBC:lI97|H3C1088 +3C1088:lI116|H3C115C +3C115C:lI105|H3C1228 +3C1228:lI111|H3C12F4 +3C12F4:lI110|H3C13C8 +3C13C8:lI47|H3C14A4 +3C14A4:lI120|H3C1578 +3C1578:lI45|H3C1644 +3C1644:lI116|H3C1710 +3C1710:lI99|H3C17CC +3C17CC:lI108|N +3C0BAC:lI116|H3C0C50 +3C0C50:lI99|H3C0CF4 +3C0CF4:lI108|N +3C0B24:lH3C0BBC|H3C0BC8 +3C0BBC:t2:H3C0C60,H3C0C68 +3C0C68:lI97|H3C0D0C +3C0D0C:lI112|H3C0DB0 +3C0DB0:lI112|H3C0E54 +3C0E54:lI108|H3C0F08 +3C0F08:lI105|H3C0FC4 +3C0FC4:lI99|H3C1090 +3C1090:lI97|H3C1164 +3C1164:lI116|H3C1230 +3C1230:lI105|H3C12FC +3C12FC:lI111|H3C13D0 +3C13D0:lI110|H3C14AC +3C14AC:lI47|H3C1580 +3C1580:lI120|H3C164C +3C164C:lI45|H3C1718 +3C1718:lI116|H3C17D4 +3C17D4:lI97|H3C1890 +3C1890:lI114|N +3C0C60:lI116|H3C0D04 +3C0D04:lI97|H3C0DA8 +3C0DA8:lI114|N +3C0BC8:lH3C0C70|H3C0C7C +3C0C70:t2:H3C0D14,H3C0D1C +3C0D1C:lI97|H3C0DC0 +3C0DC0:lI112|H3C0E64 +3C0E64:lI112|H3C0F18 +3C0F18:lI108|H3C0FD4 +3C0FD4:lI105|H3C10A0 +3C10A0:lI99|H3C116C +3C116C:lI97|H3C1238 +3C1238:lI116|H3C1304 +3C1304:lI105|H3C13D8 +3C13D8:lI111|H3C14B4 +3C14B4:lI110|H3C1588 +3C1588:lI47|H3C1654 +3C1654:lI120|H3C1720 +3C1720:lI45|H3C17DC +3C17DC:lI115|H3C1898 +3C1898:lI118|H3C194C +3C194C:lI52|H3C1A00 +3C1A00:lI99|H3C1AB4 +3C1AB4:lI114|H3C1B78 +3C1B78:lI99|N +3C0D14:lI115|H3C0DB8 +3C0DB8:lI118|H3C0E5C +3C0E5C:lI52|H3C0F10 +3C0F10:lI99|H3C0FCC +3C0FCC:lI114|H3C1098 +3C1098:lI99|N +3C0C7C:lH3C0D24|H3C0D30 +3C0D24:t2:H3C0DC8,H3C0DD0 +3C0DD0:lI97|H3C0E74 +3C0E74:lI112|H3C0F28 +3C0F28:lI112|H3C0FE4 +3C0FE4:lI108|H3C10B0 +3C10B0:lI105|H3C117C +3C117C:lI99|H3C1248 +3C1248:lI97|H3C130C +3C130C:lI116|H3C13E0 +3C13E0:lI105|H3C14BC +3C14BC:lI111|H3C1590 +3C1590:lI110|H3C165C +3C165C:lI47|H3C1728 +3C1728:lI120|H3C17E4 +3C17E4:lI45|H3C18A0 +3C18A0:lI115|H3C1954 +3C1954:lI118|H3C1A08 +3C1A08:lI52|H3C1ABC +3C1ABC:lI99|H3C1B80 +3C1B80:lI112|H3C1C4C +3C1C4C:lI105|H3C1D10 +3C1D10:lI111|N +3C0DC8:lI115|H3C0E6C +3C0E6C:lI118|H3C0F20 +3C0F20:lI52|H3C0FDC +3C0FDC:lI99|H3C10A8 +3C10A8:lI112|H3C1174 +3C1174:lI105|H3C1240 +3C1240:lI111|N +3C0D30:lH3C0DD8|H3C0DE4 +3C0DD8:t2:H3C0E7C,H3C0E84 +3C0E84:lI97|H3C0F38 +3C0F38:lI112|H3C0FF4 +3C0FF4:lI112|H3C10B8 +3C10B8:lI108|H3C1184 +3C1184:lI105|H3C1250 +3C1250:lI99|H3C1314 +3C1314:lI97|H3C13E8 +3C13E8:lI116|H3C14C4 +3C14C4:lI105|H3C1598 +3C1598:lI111|H3C1664 +3C1664:lI110|H3C1730 +3C1730:lI47|H3C17EC +3C17EC:lI120|H3C18A8 +3C18A8:lI45|H3C195C +3C195C:lI115|H3C1A10 +3C1A10:lI116|H3C1AC4 +3C1AC4:lI117|H3C1B88 +3C1B88:lI102|H3C1C54 +3C1C54:lI102|H3C1D18 +3C1D18:lI105|H3C1DD4 +3C1DD4:lI116|N +3C0E7C:lI115|H3C0F30 +3C0F30:lI105|H3C0FEC +3C0FEC:lI116|N +3C0DE4:lH3C0E8C|H3C0E98 +3C0E8C:t2:H3C0F40,H3C0F48 +3C0F48:lI97|H3C1004 +3C1004:lI112|H3C10C8 +3C10C8:lI112|H3C1194 +3C1194:lI108|H3C1258 +3C1258:lI105|H3C131C +3C131C:lI99|H3C13F0 +3C13F0:lI97|H3C14CC +3C14CC:lI116|H3C15A0 +3C15A0:lI105|H3C166C +3C166C:lI111|H3C1738 +3C1738:lI110|H3C17F4 +3C17F4:lI47|H3C18B0 +3C18B0:lI120|H3C1964 +3C1964:lI45|H3C1A18 +3C1A18:lI115|H3C1ACC +3C1ACC:lI104|H3C1B90 +3C1B90:lI97|H3C1C5C +3C1C5C:lI114|N +3C0F40:lI115|H3C0FFC +3C0FFC:lI104|H3C10C0 +3C10C0:lI97|H3C118C +3C118C:lI114|N +3C0E98:lH3C0F50|H3C0F5C +3C0F50:t2:H3C100C,H3C1014 +3C1014:lI97|H3C10D8 +3C10D8:lI112|H3C119C +3C119C:lI112|H3C1260 +3C1260:lI108|H3C1324 +3C1324:lI105|H3C13F8 +3C13F8:lI99|H3C14D4 +3C14D4:lI97|H3C15A8 +3C15A8:lI116|H3C1674 +3C1674:lI105|H3C1740 +3C1740:lI111|H3C17FC +3C17FC:lI110|H3C18B8 +3C18B8:lI47|H3C196C +3C196C:lI120|H3C1A20 +3C1A20:lI45|H3C1AD4 +3C1AD4:lI115|H3C1B98 +3C1B98:lI104|N +3C100C:lI115|H3C10D0 +3C10D0:lI104|N +3C0F5C:lH3C101C|H3C1028 +3C101C:t2:H3C10E0,H3C10E8 +3C10E8:lI97|H3C11AC +3C11AC:lI112|H3C1268 +3C1268:lI112|H3C132C +3C132C:lI108|H3C1400 +3C1400:lI105|H3C14DC +3C14DC:lI99|H3C15B0 +3C15B0:lI97|H3C167C +3C167C:lI116|H3C1748 +3C1748:lI105|H3C1804 +3C1804:lI111|H3C18C0 +3C18C0:lI110|H3C1974 +3C1974:lI47|H3C1A28 +3C1A28:lI120|H3C1ADC +3C1ADC:lI45|H3C1BA0 +3C1BA0:lI110|H3C1C64 +3C1C64:lI101|H3C1D20 +3C1D20:lI116|H3C1DDC +3C1DDC:lI99|H3C1E98 +3C1E98:lI100|H3C1F5C +3C1F5C:lI102|N +3C10E0:lI110|H3C11A4 +3C11A4:lI99|N +3C1028:lH3C10F0|H3C10FC +3C10F0:t2:H3C11B4,H3C11BC +3C11BC:lI97|H3C1278 +3C1278:lI112|H3C133C +3C133C:lI112|H3C1408 +3C1408:lI108|H3C14E4 +3C14E4:lI105|H3C15B8 +3C15B8:lI99|H3C1684 +3C1684:lI97|H3C1750 +3C1750:lI116|H3C180C +3C180C:lI105|H3C18C8 +3C18C8:lI111|H3C197C +3C197C:lI110|H3C1A30 +3C1A30:lI47|H3C1AE4 +3C1AE4:lI120|H3C1BA8 +3C1BA8:lI45|H3C1C6C +3C1C6C:lI110|H3C1D28 +3C1D28:lI101|H3C1DE4 +3C1DE4:lI116|H3C1EA0 +3C1EA0:lI99|H3C1F64 +3C1F64:lI100|H3C2018 +3C2018:lI102|N +3C11B4:lI99|H3C1270 +3C1270:lI100|H3C1334 +3C1334:lI102|N +3C10FC:lH3C11C4|H3C11D0 +3C11C4:t2:H3C1280,H3C1288 +3C1288:lI97|H3C134C +3C134C:lI112|H3C1418 +3C1418:lI112|H3C14EC +3C14EC:lI108|H3C15C0 +3C15C0:lI105|H3C168C +3C168C:lI99|H3C1758 +3C1758:lI97|H3C1814 +3C1814:lI116|H3C18D0 +3C18D0:lI105|H3C1984 +3C1984:lI111|H3C1A38 +3C1A38:lI110|H3C1AEC +3C1AEC:lI47|H3C1BB0 +3C1BB0:lI120|H3C1C74 +3C1C74:lI45|H3C1D30 +3C1D30:lI109|H3C1DEC +3C1DEC:lI105|H3C1EA8 +3C1EA8:lI102|N +3C1280:lI109|H3C1344 +3C1344:lI105|H3C1410 +3C1410:lI102|N +3C11D0:lH3C1290|H3C129C +3C1290:t2:H3C1354,H3C135C +3C135C:lI97|H3C1428 +3C1428:lI112|H3C14FC +3C14FC:lI112|H3C15D0 +3C15D0:lI108|H3C169C +3C169C:lI105|H3C1760 +3C1760:lI99|H3C181C +3C181C:lI97|H3C18D8 +3C18D8:lI116|H3C198C +3C198C:lI105|H3C1A40 +3C1A40:lI111|H3C1AF4 +3C1AF4:lI110|H3C1BB8 +3C1BB8:lI47|H3C1C7C +3C1C7C:lI120|H3C1D38 +3C1D38:lI45|H3C1DF4 +3C1DF4:lI108|H3C1EB0 +3C1EB0:lI97|H3C1F6C +3C1F6C:lI116|H3C2020 +3C2020:lI101|H3C20DC +3C20DC:lI120|N +3C1354:lI108|H3C1420 +3C1420:lI97|H3C14F4 +3C14F4:lI116|H3C15C8 +3C15C8:lI101|H3C1694 +3C1694:lI120|N +3C129C:lH3C1364|H3C1370 +3C1364:t2:H3C1430,H3C1438 +3C1438:lI97|H3C150C +3C150C:lI112|H3C15E0 +3C15E0:lI112|H3C16A4 +3C16A4:lI108|H3C1768 +3C1768:lI105|H3C1824 +3C1824:lI99|H3C18E0 +3C18E0:lI97|H3C1994 +3C1994:lI116|H3C1A48 +3C1A48:lI105|H3C1AFC +3C1AFC:lI111|H3C1BC0 +3C1BC0:lI110|H3C1C84 +3C1C84:lI47|H3C1D40 +3C1D40:lI120|H3C1DFC +3C1DFC:lI45|H3C1EB8 +3C1EB8:lI107|H3C1F74 +3C1F74:lI111|H3C2028 +3C2028:lI97|H3C20E4 +3C20E4:lI110|N +3C1430:lI115|H3C1504 +3C1504:lI107|H3C15D8 +3C15D8:lI112|N +3C1370:lH3C1440|H3C144C +3C1440:t2:H3C1514,H3C151C +3C151C:lI97|H3C15F0 +3C15F0:lI112|H3C16B4 +3C16B4:lI112|H3C1770 +3C1770:lI108|H3C182C +3C182C:lI105|H3C18E8 +3C18E8:lI99|H3C199C +3C199C:lI97|H3C1A50 +3C1A50:lI116|H3C1B04 +3C1B04:lI105|H3C1BC8 +3C1BC8:lI111|H3C1C8C +3C1C8C:lI110|H3C1D48 +3C1D48:lI47|H3C1E04 +3C1E04:lI120|H3C1EC0 +3C1EC0:lI45|H3C1F7C +3C1F7C:lI107|H3C2030 +3C2030:lI111|H3C20EC +3C20EC:lI97|H3C21A0 +3C21A0:lI110|N +3C1514:lI115|H3C15E8 +3C15E8:lI107|H3C16AC +3C16AC:lI100|N +3C144C:lH3C1524|H3C1530 +3C1524:t2:H3C15F8,H3C1600 +3C1600:lI97|H3C16C4 +3C16C4:lI112|H3C1780 +3C1780:lI112|H3C1834 +3C1834:lI108|H3C18F0 +3C18F0:lI105|H3C19A4 +3C19A4:lI99|H3C1A58 +3C1A58:lI97|H3C1B0C +3C1B0C:lI116|H3C1BD0 +3C1BD0:lI105|H3C1C94 +3C1C94:lI111|H3C1D50 +3C1D50:lI110|H3C1E0C +3C1E0C:lI47|H3C1EC8 +3C1EC8:lI120|H3C1F84 +3C1F84:lI45|H3C2038 +3C2038:lI107|H3C20F4 +3C20F4:lI111|H3C21A8 +3C21A8:lI97|H3C225C +3C225C:lI110|N +3C15F8:lI115|H3C16BC +3C16BC:lI107|H3C1778 +3C1778:lI116|N +3C1530:lH3C1608|H3C1614 +3C1608:t2:H3C16CC,H3C16D4 +3C16D4:lI97|H3C1790 +3C1790:lI112|H3C1844 +3C1844:lI112|H3C18F8 +3C18F8:lI108|H3C19AC +3C19AC:lI105|H3C1A60 +3C1A60:lI99|H3C1B14 +3C1B14:lI97|H3C1BD8 +3C1BD8:lI116|H3C1C9C +3C1C9C:lI105|H3C1D58 +3C1D58:lI111|H3C1E14 +3C1E14:lI110|H3C1ED0 +3C1ED0:lI47|H3C1F8C +3C1F8C:lI120|H3C2040 +3C2040:lI45|H3C20FC +3C20FC:lI107|H3C21B0 +3C21B0:lI111|H3C2264 +3C2264:lI97|H3C2320 +3C2320:lI110|N +3C16CC:lI115|H3C1788 +3C1788:lI107|H3C183C +3C183C:lI109|N +3C1614:lH3C16DC|H3C16E8 +3C16DC:t2:H3C1798,H3C17A0 +3C17A0:lI97|H3C1854 +3C1854:lI112|H3C1908 +3C1908:lI112|H3C19B4 +3C19B4:lI108|H3C1A68 +3C1A68:lI105|H3C1B1C +3C1B1C:lI99|H3C1BE0 +3C1BE0:lI97|H3C1CA4 +3C1CA4:lI116|H3C1D60 +3C1D60:lI105|H3C1E1C +3C1E1C:lI111|H3C1ED8 +3C1ED8:lI110|H3C1F94 +3C1F94:lI47|H3C2048 +3C2048:lI120|H3C2104 +3C2104:lI45|H3C21B8 +3C21B8:lI104|H3C226C +3C226C:lI116|H3C2328 +3C2328:lI116|H3C23E4 +3C23E4:lI112|H3C2498 +3C2498:lI100|H3C2554 +3C2554:lI45|H3C2610 +3C2610:lI99|H3C26D4 +3C26D4:lI103|H3C2790 +3C2790:lI105|N +3C1798:lI99|H3C184C +3C184C:lI103|H3C1900 +3C1900:lI105|N +3C16E8:lH3C17A8|H3C17B4 +3C17A8:t2:H3C185C,H3C1864 +3C1864:lI97|H3C1918 +3C1918:lI112|H3C19C4 +3C19C4:lI112|H3C1A70 +3C1A70:lI108|H3C1B24 +3C1B24:lI105|H3C1BE8 +3C1BE8:lI99|H3C1CAC +3C1CAC:lI97|H3C1D68 +3C1D68:lI116|H3C1E24 +3C1E24:lI105|H3C1EE0 +3C1EE0:lI111|H3C1F9C +3C1F9C:lI110|H3C2050 +3C2050:lI47|H3C210C +3C210C:lI120|H3C21C0 +3C21C0:lI45|H3C2274 +3C2274:lI104|H3C2330 +3C2330:lI100|H3C23EC +3C23EC:lI102|N +3C185C:lI104|H3C1910 +3C1910:lI100|H3C19BC +3C19BC:lI102|N +3C17B4:lH3C186C|H3C1878 +3C186C:t2:H3C1920,H3C1928 +3C1928:lI97|H3C19D4 +3C19D4:lI112|H3C1A78 +3C1A78:lI112|H3C1B2C +3C1B2C:lI108|H3C1BF0 +3C1BF0:lI105|H3C1CB4 +3C1CB4:lI99|H3C1D70 +3C1D70:lI97|H3C1E2C +3C1E2C:lI116|H3C1EE8 +3C1EE8:lI105|H3C1FA4 +3C1FA4:lI111|H3C2058 +3C2058:lI110|H3C2114 +3C2114:lI47|H3C21C8 +3C21C8:lI120|H3C227C +3C227C:lI45|H3C2338 +3C2338:lI103|H3C23F4 +3C23F4:lI122|H3C24A0 +3C24A0:lI105|H3C255C +3C255C:lI112|N +3C1920:lI103|H3C19CC +3C19CC:lI122|N +3C1878:lH3C1930|H3C193C +3C1930:t2:H3C19DC,H3C19E4 +3C19E4:lI97|H3C1A88 +3C1A88:lI112|H3C1B3C +3C1B3C:lI112|H3C1C00 +3C1C00:lI108|H3C1CBC +3C1CBC:lI105|H3C1D78 +3C1D78:lI99|H3C1E34 +3C1E34:lI97|H3C1EF0 +3C1EF0:lI116|H3C1FAC +3C1FAC:lI105|H3C2060 +3C2060:lI111|H3C211C +3C211C:lI110|H3C21D0 +3C21D0:lI47|H3C2284 +3C2284:lI120|H3C2340 +3C2340:lI45|H3C23FC +3C23FC:lI103|H3C24A8 +3C24A8:lI116|H3C2564 +3C2564:lI97|H3C2618 +3C2618:lI114|N +3C19DC:lI103|H3C1A80 +3C1A80:lI116|H3C1B34 +3C1B34:lI97|H3C1BF8 +3C1BF8:lI114|N +3C193C:lH3C19EC|H3C19F8 +3C19EC:t2:H3C1A90,H3C1A98 +3C1A98:lI97|H3C1B4C +3C1B4C:lI112|H3C1C10 +3C1C10:lI112|H3C1CC4 +3C1CC4:lI108|H3C1D80 +3C1D80:lI105|H3C1E3C +3C1E3C:lI99|H3C1EF8 +3C1EF8:lI97|H3C1FB4 +3C1FB4:lI116|H3C2068 +3C2068:lI105|H3C2124 +3C2124:lI111|H3C21D8 +3C21D8:lI110|H3C228C +3C228C:lI47|H3C2348 +3C2348:lI120|H3C2404 +3C2404:lI45|H3C24B0 +3C24B0:lI100|H3C256C +3C256C:lI118|H3C2620 +3C2620:lI105|N +3C1A90:lI100|H3C1B44 +3C1B44:lI118|H3C1C08 +3C1C08:lI105|N +3C19F8:lH3C1AA0|H3C1AAC +3C1AA0:t2:H3C1B54,H3C1B5C +3C1B5C:lI97|H3C1C20 +3C1C20:lI112|H3C1CD4 +3C1CD4:lI112|H3C1D88 +3C1D88:lI108|H3C1E44 +3C1E44:lI105|H3C1F00 +3C1F00:lI99|H3C1FBC +3C1FBC:lI97|H3C2070 +3C2070:lI116|H3C212C +3C212C:lI105|H3C21E0 +3C21E0:lI111|H3C2294 +3C2294:lI110|H3C2350 +3C2350:lI47|H3C240C +3C240C:lI120|H3C24B8 +3C24B8:lI45|H3C2574 +3C2574:lI100|H3C2628 +3C2628:lI105|H3C26DC +3C26DC:lI114|H3C2798 +3C2798:lI101|H3C2854 +3C2854:lI99|H3C2918 +3C2918:lI116|H3C29E4 +3C29E4:lI111|H3C2AB0 +3C2AB0:lI114|N +3C1B54:lI100|H3C1C18 +3C1C18:lI99|H3C1CCC +3C1CCC:lI114|N +3C1AAC:lH3C1B64|H3C1B70 +3C1B64:t2:H3C1C28,H3C1C30 +3C1C30:lI97|H3C1CE4 +3C1CE4:lI112|H3C1D98 +3C1D98:lI112|H3C1E4C +3C1E4C:lI108|H3C1F08 +3C1F08:lI105|H3C1FC4 +3C1FC4:lI99|H3C2078 +3C2078:lI97|H3C2134 +3C2134:lI116|H3C21E8 +3C21E8:lI105|H3C229C +3C229C:lI111|H3C2358 +3C2358:lI110|H3C2414 +3C2414:lI47|H3C24C0 +3C24C0:lI120|H3C257C +3C257C:lI45|H3C2630 +3C2630:lI100|H3C26E4 +3C26E4:lI105|H3C27A0 +3C27A0:lI114|H3C285C +3C285C:lI101|H3C2920 +3C2920:lI99|H3C29EC +3C29EC:lI116|H3C2AB8 +3C2AB8:lI111|H3C2B84 +3C2B84:lI114|N +3C1C28:lI100|H3C1CDC +3C1CDC:lI105|H3C1D90 +3C1D90:lI114|N +3C1B70:lH3C1C38|H3C1C44 +3C1C38:t2:H3C1CEC,H3C1CF4 +3C1CF4:lI97|H3C1DA8 +3C1DA8:lI112|H3C1E5C +3C1E5C:lI112|H3C1F10 +3C1F10:lI108|H3C1FCC +3C1FCC:lI105|H3C2080 +3C2080:lI99|H3C213C +3C213C:lI97|H3C21F0 +3C21F0:lI116|H3C22A4 +3C22A4:lI105|H3C2360 +3C2360:lI111|H3C241C +3C241C:lI110|H3C24C8 +3C24C8:lI47|H3C2584 +3C2584:lI120|H3C2638 +3C2638:lI45|H3C26EC +3C26EC:lI100|H3C27A8 +3C27A8:lI105|H3C2864 +3C2864:lI114|H3C2928 +3C2928:lI101|H3C29F4 +3C29F4:lI99|H3C2AC0 +3C2AC0:lI116|H3C2B8C +3C2B8C:lI111|H3C2C48 +3C2C48:lI114|N +3C1CEC:lI100|H3C1DA0 +3C1DA0:lI120|H3C1E54 +3C1E54:lI114|N +3C1C44:lH3C1CFC|H3C1D08 +3C1CFC:t2:H3C1DB0,H3C1DB8 +3C1DB8:lI97|H3C1E6C +3C1E6C:lI112|H3C1F20 +3C1F20:lI112|H3C1FD4 +3C1FD4:lI108|H3C2088 +3C2088:lI105|H3C2144 +3C2144:lI99|H3C21F8 +3C21F8:lI97|H3C22AC +3C22AC:lI116|H3C2368 +3C2368:lI105|H3C2424 +3C2424:lI111|H3C24D0 +3C24D0:lI110|H3C258C +3C258C:lI47|H3C2640 +3C2640:lI120|H3C26F4 +3C26F4:lI45|H3C27B0 +3C27B0:lI99|H3C286C +3C286C:lI115|H3C2930 +3C2930:lI104|N +3C1DB0:lI99|H3C1E64 +3C1E64:lI115|H3C1F18 +3C1F18:lI104|N +3C1D08:lH3C1DC0|H3C1DCC +3C1DC0:t2:H3C1E74,H3C1E7C +3C1E7C:lI97|H3C1F30 +3C1F30:lI112|H3C1FE4 +3C1FE4:lI112|H3C2098 +3C2098:lI108|H3C214C +3C214C:lI105|H3C2200 +3C2200:lI99|H3C22B4 +3C22B4:lI97|H3C2370 +3C2370:lI116|H3C242C +3C242C:lI105|H3C24D8 +3C24D8:lI111|H3C2594 +3C2594:lI110|H3C2648 +3C2648:lI47|H3C26FC +3C26FC:lI120|H3C27B8 +3C27B8:lI45|H3C2874 +3C2874:lI99|H3C2938 +3C2938:lI112|H3C29FC +3C29FC:lI105|H3C2AC8 +3C2AC8:lI111|N +3C1E74:lI99|H3C1F28 +3C1F28:lI112|H3C1FDC +3C1FDC:lI105|H3C2090 +3C2090:lI111|N +3C1DCC:lH3C1E84|H3C1E90 +3C1E84:t2:H3C1F38,H3C1F40 +3C1F40:lI97|H3C1FEC +3C1FEC:lI112|H3C20A0 +3C20A0:lI112|H3C2154 +3C2154:lI108|H3C2208 +3C2208:lI105|H3C22BC +3C22BC:lI99|H3C2378 +3C2378:lI97|H3C2434 +3C2434:lI116|H3C24E0 +3C24E0:lI105|H3C259C +3C259C:lI111|H3C2650 +3C2650:lI110|H3C2704 +3C2704:lI47|H3C27C0 +3C27C0:lI120|H3C287C +3C287C:lI45|H3C2940 +3C2940:lI99|H3C2A04 +3C2A04:lI111|H3C2AD0 +3C2AD0:lI109|H3C2B94 +3C2B94:lI112|H3C2C50 +3C2C50:lI114|H3C2D00 +3C2D00:lI101|H3C2DA8 +3C2DA8:lI115|H3C2E40 +3C2E40:lI115|N +3C1F38:lI90|N +3C1E90:lH3C1F48|H3C1F54 +3C1F48:t2:H3C1FF4,H3C1FFC +3C1FFC:lI97|H3C20B0 +3C20B0:lI112|H3C2164 +3C2164:lI112|H3C2210 +3C2210:lI108|H3C22C4 +3C22C4:lI105|H3C2380 +3C2380:lI99|H3C243C +3C243C:lI97|H3C24E8 +3C24E8:lI116|H3C25A4 +3C25A4:lI105|H3C2658 +3C2658:lI111|H3C270C +3C270C:lI110|H3C27C8 +3C27C8:lI47|H3C2884 +3C2884:lI120|H3C2948 +3C2948:lI45|H3C2A0C +3C2A0C:lI99|H3C2AD8 +3C2AD8:lI100|H3C2B9C +3C2B9C:lI108|H3C2C58 +3C2C58:lI105|H3C2D08 +3C2D08:lI110|H3C2DB0 +3C2DB0:lI107|N +3C1FF4:lI118|H3C20A8 +3C20A8:lI99|H3C215C +3C215C:lI100|N +3C1F54:lH3C2004|H3C2010 +3C2004:t2:H3C20B8,H3C20C0 +3C20C0:lI97|H3C2174 +3C2174:lI112|H3C2220 +3C2220:lI112|H3C22D4 +3C22D4:lI108|H3C2390 +3C2390:lI105|H3C2444 +3C2444:lI99|H3C24F0 +3C24F0:lI97|H3C25AC +3C25AC:lI116|H3C2660 +3C2660:lI105|H3C2714 +3C2714:lI111|H3C27D0 +3C27D0:lI110|H3C288C +3C288C:lI47|H3C2950 +3C2950:lI120|H3C2A14 +3C2A14:lI45|H3C2AE0 +3C2AE0:lI98|H3C2BA4 +3C2BA4:lI99|H3C2C60 +3C2C60:lI112|H3C2D10 +3C2D10:lI105|H3C2DB8 +3C2DB8:lI111|N +3C20B8:lI98|H3C216C +3C216C:lI99|H3C2218 +3C2218:lI112|H3C22CC +3C22CC:lI105|H3C2388 +3C2388:lI111|N +3C2010:lH3C20C8|H3C20D4 +3C20C8:t2:H3C217C,H3C2184 +3C2184:lI97|H3C2230 +3C2230:lI112|H3C22E4 +3C22E4:lI112|H3C2398 +3C2398:lI108|H3C244C +3C244C:lI105|H3C24F8 +3C24F8:lI99|H3C25B4 +3C25B4:lI97|H3C2668 +3C2668:lI116|H3C271C +3C271C:lI105|H3C27D8 +3C27D8:lI111|H3C2894 +3C2894:lI110|H3C2958 +3C2958:lI47|H3C2A1C +3C2A1C:lI114|H3C2AE8 +3C2AE8:lI116|H3C2BAC +3C2BAC:lI102|N +3C217C:lI114|H3C2228 +3C2228:lI116|H3C22DC +3C22DC:lI102|N +3C20D4:lH3C218C|H3C2198 +3C218C:t2:H3C2238,H3C2240 +3C2240:lI97|H3C22F4 +3C22F4:lI112|H3C23A8 +3C23A8:lI112|H3C2454 +3C2454:lI108|H3C2500 +3C2500:lI105|H3C25BC +3C25BC:lI99|H3C2670 +3C2670:lI97|H3C2724 +3C2724:lI116|H3C27E0 +3C27E0:lI105|H3C289C +3C289C:lI111|H3C2960 +3C2960:lI110|H3C2A24 +3C2A24:lI47|H3C2AF0 +3C2AF0:lI112|H3C2BB4 +3C2BB4:lI111|H3C2C68 +3C2C68:lI119|H3C2D18 +3C2D18:lI101|H3C2DC0 +3C2DC0:lI114|H3C2E48 +3C2E48:lI112|H3C2EC0 +3C2EC0:lI111|H3C2F38 +3C2F38:lI105|H3C2FA8 +3C2FA8:lI110|H3C3010 +3C3010:lI116|N +3C2238:lI112|H3C22EC +3C22EC:lI112|H3C23A0 +3C23A0:lI116|N +3C2198:lH3C2248|H3C2254 +3C2248:t2:H3C22FC,H3C2304 +3C2304:lI97|H3C23B8 +3C23B8:lI112|H3C245C +3C245C:lI112|H3C2508 +3C2508:lI108|H3C25C4 +3C25C4:lI105|H3C2678 +3C2678:lI99|H3C272C +3C272C:lI97|H3C27E8 +3C27E8:lI116|H3C28A4 +3C28A4:lI105|H3C2968 +3C2968:lI111|H3C2A2C +3C2A2C:lI110|H3C2AF8 +3C2AF8:lI47|H3C2BBC +3C2BBC:lI112|H3C2C70 +3C2C70:lI111|H3C2D20 +3C2D20:lI115|H3C2DC8 +3C2DC8:lI116|H3C2E50 +3C2E50:lI115|H3C2EC8 +3C2EC8:lI99|H3C2F40 +3C2F40:lI114|H3C2FB0 +3C2FB0:lI105|H3C3018 +3C3018:lI112|H3C3078 +3C3078:lI116|N +3C22FC:lI97|H3C23B0 +3C23B0:lI105|N +3C2254:lH3C230C|H3C2318 +3C230C:t2:H3C23C0,H3C23C8 +3C23C8:lI97|H3C246C +3C246C:lI112|H3C2518 +3C2518:lI112|H3C25CC +3C25CC:lI108|H3C2680 +3C2680:lI105|H3C2734 +3C2734:lI99|H3C27F0 +3C27F0:lI97|H3C28AC +3C28AC:lI116|H3C2970 +3C2970:lI105|H3C2A34 +3C2A34:lI111|H3C2B00 +3C2B00:lI110|H3C2BC4 +3C2BC4:lI47|H3C2C78 +3C2C78:lI112|H3C2D28 +3C2D28:lI111|H3C2DD0 +3C2DD0:lI115|H3C2E58 +3C2E58:lI116|H3C2ED0 +3C2ED0:lI115|H3C2F48 +3C2F48:lI99|H3C2FB8 +3C2FB8:lI114|H3C3020 +3C3020:lI105|H3C3080 +3C3080:lI112|H3C30D8 +3C30D8:lI116|N +3C23C0:lI101|H3C2464 +3C2464:lI112|H3C2510 +3C2510:lI115|N +3C2318:lH3C23D0|H3C23DC +3C23D0:t2:H3C2474,H3C247C +3C247C:lI97|H3C2528 +3C2528:lI112|H3C25D4 +3C25D4:lI112|H3C2688 +3C2688:lI108|H3C273C +3C273C:lI105|H3C27F8 +3C27F8:lI99|H3C28B4 +3C28B4:lI97|H3C2978 +3C2978:lI116|H3C2A3C +3C2A3C:lI105|H3C2B08 +3C2B08:lI111|H3C2BCC +3C2BCC:lI110|H3C2C80 +3C2C80:lI47|H3C2D30 +3C2D30:lI112|H3C2DD8 +3C2DD8:lI111|H3C2E60 +3C2E60:lI115|H3C2ED8 +3C2ED8:lI116|H3C2F50 +3C2F50:lI115|H3C2FC0 +3C2FC0:lI99|H3C3028 +3C3028:lI114|H3C3088 +3C3088:lI105|H3C30E0 +3C30E0:lI112|H3C3130 +3C3130:lI116|N +3C2474:lI112|H3C2520 +3C2520:lI115|N +3C23DC:lH3C2484|H3C2490 +3C2484:t2:H3C2530,H3C2538 +3C2538:lI97|H3C25E4 +3C25E4:lI112|H3C2698 +3C2698:lI112|H3C2744 +3C2744:lI108|H3C2800 +3C2800:lI105|H3C28BC +3C28BC:lI99|H3C2980 +3C2980:lI97|H3C2A44 +3C2A44:lI116|H3C2B10 +3C2B10:lI105|H3C2BD4 +3C2BD4:lI111|H3C2C88 +3C2C88:lI110|H3C2D38 +3C2D38:lI47|H3C2DE0 +3C2DE0:lI112|H3C2E68 +3C2E68:lI100|H3C2EE0 +3C2EE0:lI102|N +3C2530:lI112|H3C25DC +3C25DC:lI100|H3C2690 +3C2690:lI102|N +3C2490:lH3C2540|H3C254C +3C2540:t2:H3C25EC,H3C25F4 +3C25F4:lI97|H3C26A8 +3C26A8:lI112|H3C2754 +3C2754:lI112|H3C2808 +3C2808:lI108|H3C28C4 +3C28C4:lI105|H3C2988 +3C2988:lI99|H3C2A4C +3C2A4C:lI97|H3C2B18 +3C2B18:lI116|H3C2BDC +3C2BDC:lI105|H3C2C90 +3C2C90:lI111|H3C2D40 +3C2D40:lI110|H3C2DE8 +3C2DE8:lI47|H3C2E70 +3C2E70:lI111|H3C2EE8 +3C2EE8:lI100|H3C2F58 +3C2F58:lI97|N +3C25EC:lI111|H3C26A0 +3C26A0:lI100|H3C274C +3C274C:lI97|N +3C254C:lH3C25FC|H3C2608 +3C25FC:t2:H3C26B0,H3C26B8 +3C26B8:lI97|H3C2764 +3C2764:lI112|H3C2818 +3C2818:lI112|H3C28CC +3C28CC:lI108|H3C2990 +3C2990:lI105|H3C2A54 +3C2A54:lI99|H3C2B20 +3C2B20:lI97|H3C2BE4 +3C2BE4:lI116|H3C2C98 +3C2C98:lI105|H3C2D48 +3C2D48:lI111|H3C2DF0 +3C2DF0:lI110|H3C2E78 +3C2E78:lI47|H3C2EF0 +3C2EF0:lI111|H3C2F60 +3C2F60:lI99|H3C2FC8 +3C2FC8:lI116|H3C3030 +3C3030:lI101|H3C3090 +3C3090:lI116|H3C30E8 +3C30E8:lI45|H3C3138 +3C3138:lI115|H3C3180 +3C3180:lI116|H3C31C8 +3C31C8:lI114|H3C3210 +3C3210:lI101|H3C3258 +3C3258:lI97|H3C32A0 +3C32A0:lI109|N +3C26B0:lI98|H3C275C +3C275C:lI105|H3C2810 +3C2810:lI110|N +3C2608:lH3C26C0|H3C26CC +3C26C0:t2:H3C276C,H3C2774 +3C2774:lI97|H3C2828 +3C2828:lI112|H3C28DC +3C28DC:lI112|H3C2998 +3C2998:lI108|H3C2A5C +3C2A5C:lI105|H3C2B28 +3C2B28:lI99|H3C2BEC +3C2BEC:lI97|H3C2CA0 +3C2CA0:lI116|H3C2D50 +3C2D50:lI105|H3C2DF8 +3C2DF8:lI111|H3C2E80 +3C2E80:lI110|H3C2EF8 +3C2EF8:lI47|H3C2F68 +3C2F68:lI111|H3C2FD0 +3C2FD0:lI99|H3C3038 +3C3038:lI116|H3C3098 +3C3098:lI101|H3C30F0 +3C30F0:lI116|H3C3140 +3C3140:lI45|H3C3188 +3C3188:lI115|H3C31D0 +3C31D0:lI116|H3C3218 +3C3218:lI114|H3C3260 +3C3260:lI101|H3C32A8 +3C32A8:lI97|H3C32E8 +3C32E8:lI109|N +3C276C:lI100|H3C2820 +3C2820:lI109|H3C28D4 +3C28D4:lI115|N +3C26CC:lH3C277C|H3C2788 +3C277C:t2:H3C2830,H3C2838 +3C2838:lI97|H3C28EC +3C28EC:lI112|H3C29A8 +3C29A8:lI112|H3C2A64 +3C2A64:lI108|H3C2B30 +3C2B30:lI105|H3C2BF4 +3C2BF4:lI99|H3C2CA8 +3C2CA8:lI97|H3C2D58 +3C2D58:lI116|H3C2E00 +3C2E00:lI105|H3C2E88 +3C2E88:lI111|H3C2F00 +3C2F00:lI110|H3C2F70 +3C2F70:lI47|H3C2FD8 +3C2FD8:lI111|H3C3040 +3C3040:lI99|H3C30A0 +3C30A0:lI116|H3C30F8 +3C30F8:lI101|H3C3148 +3C3148:lI116|H3C3190 +3C3190:lI45|H3C31D8 +3C31D8:lI115|H3C3220 +3C3220:lI116|H3C3268 +3C3268:lI114|H3C32B0 +3C32B0:lI101|H3C32F0 +3C32F0:lI97|H3C3320 +3C3320:lI109|N +3C2830:lI108|H3C28E4 +3C28E4:lI104|H3C29A0 +3C29A0:lI97|N +3C2788:lH3C2840|H3C284C +3C2840:t2:H3C28F4,H3C28FC +3C28FC:lI97|H3C29B8 +3C29B8:lI112|H3C2A74 +3C2A74:lI112|H3C2B38 +3C2B38:lI108|H3C2BFC +3C2BFC:lI105|H3C2CB0 +3C2CB0:lI99|H3C2D60 +3C2D60:lI97|H3C2E08 +3C2E08:lI116|H3C2E90 +3C2E90:lI105|H3C2F08 +3C2F08:lI111|H3C2F78 +3C2F78:lI110|H3C2FE0 +3C2FE0:lI47|H3C3048 +3C3048:lI111|H3C30A8 +3C30A8:lI99|H3C3100 +3C3100:lI116|H3C3150 +3C3150:lI101|H3C3198 +3C3198:lI116|H3C31E0 +3C31E0:lI45|H3C3228 +3C3228:lI115|H3C3270 +3C3270:lI116|H3C32B8 +3C32B8:lI114|H3C32F8 +3C32F8:lI101|H3C3328 +3C3328:lI97|H3C3350 +3C3350:lI109|N +3C28F4:lI108|H3C29B0 +3C29B0:lI122|H3C2A6C +3C2A6C:lI104|N +3C284C:lH3C2904|H3C2910 +3C2904:t2:H3C29C0,H3C29C8 +3C29C8:lI97|H3C2A84 +3C2A84:lI112|H3C2B48 +3C2B48:lI112|H3C2C04 +3C2C04:lI108|H3C2CB8 +3C2CB8:lI105|H3C2D68 +3C2D68:lI99|H3C2E10 +3C2E10:lI97|H3C2E98 +3C2E98:lI116|H3C2F10 +3C2F10:lI105|H3C2F80 +3C2F80:lI111|H3C2FE8 +3C2FE8:lI110|H3C3050 +3C3050:lI47|H3C30B0 +3C30B0:lI111|H3C3108 +3C3108:lI99|H3C3158 +3C3158:lI116|H3C31A0 +3C31A0:lI101|H3C31E8 +3C31E8:lI116|H3C3230 +3C3230:lI45|H3C3278 +3C3278:lI115|H3C32C0 +3C32C0:lI116|H3C3300 +3C3300:lI114|H3C3330 +3C3330:lI101|H3C3358 +3C3358:lI97|H3C3378 +3C3378:lI109|N +3C29C0:lI101|H3C2A7C +3C2A7C:lI120|H3C2B40 +3C2B40:lI101|N +3C2910:lH3C29D0|H3C29DC +3C29D0:t2:H3C2A8C,H3C2A94 +3C2A94:lI97|H3C2B58 +3C2B58:lI112|H3C2C14 +3C2C14:lI112|H3C2CC8 +3C2CC8:lI108|H3C2D78 +3C2D78:lI105|H3C2E18 +3C2E18:lI99|H3C2EA0 +3C2EA0:lI97|H3C2F18 +3C2F18:lI116|H3C2F88 +3C2F88:lI105|H3C2FF0 +3C2FF0:lI111|H3C3058 +3C3058:lI110|H3C30B8 +3C30B8:lI47|H3C3110 +3C3110:lI111|H3C3160 +3C3160:lI99|H3C31A8 +3C31A8:lI116|H3C31F0 +3C31F0:lI101|H3C3238 +3C3238:lI116|H3C3280 +3C3280:lI45|H3C32C8 +3C32C8:lI115|H3C3308 +3C3308:lI116|H3C3338 +3C3338:lI114|H3C3360 +3C3360:lI101|H3C3380 +3C3380:lI97|H3C3398 +3C3398:lI109|N +3C2A8C:lI99|H3C2B50 +3C2B50:lI108|H3C2C0C +3C2C0C:lI97|H3C2CC0 +3C2CC0:lI115|H3C2D70 +3C2D70:lI115|N +3C29DC:lH3C2A9C|H3C2AA8 +3C2A9C:t2:H3C2B60,H3C2B68 +3C2B68:lI97|H3C2C24 +3C2C24:lI112|H3C2CD8 +3C2CD8:lI112|H3C2D80 +3C2D80:lI108|H3C2E20 +3C2E20:lI105|H3C2EA8 +3C2EA8:lI99|H3C2F20 +3C2F20:lI97|H3C2F90 +3C2F90:lI116|H3C2FF8 +3C2FF8:lI105|H3C3060 +3C3060:lI111|H3C30C0 +3C30C0:lI110|H3C3118 +3C3118:lI47|H3C3168 +3C3168:lI109|H3C31B0 +3C31B0:lI115|H3C31F8 +3C31F8:lI119|H3C3240 +3C3240:lI111|H3C3288 +3C3288:lI114|H3C32D0 +3C32D0:lI100|N +3C2B60:lI100|H3C2C1C +3C2C1C:lI111|H3C2CD0 +3C2CD0:lI99|N +3C2AA8:lH3C2B70|H3C2B7C +3C2B70:t2:H3C2C2C,H3C2C34 +3C2C34:lI97|H3C2CE8 +3C2CE8:lI112|H3C2D90 +3C2D90:lI112|H3C2E28 +3C2E28:lI108|H3C2EB0 +3C2EB0:lI105|H3C2F28 +3C2F28:lI99|H3C2F98 +3C2F98:lI97|H3C3000 +3C3000:lI116|H3C3068 +3C3068:lI105|H3C30C8 +3C30C8:lI111|H3C3120 +3C3120:lI110|H3C3170 +3C3170:lI47|H3C31B8 +3C31B8:lI109|H3C3200 +3C3200:lI97|H3C3248 +3C3248:lI99|H3C3290 +3C3290:lI45|H3C32D8 +3C32D8:lI99|H3C3310 +3C3310:lI111|H3C3340 +3C3340:lI109|H3C3368 +3C3368:lI112|H3C3388 +3C3388:lI97|H3C33A0 +3C33A0:lI99|H3C33B0 +3C33B0:lI116|H3C33C0 +3C33C0:lI112|H3C33D0 +3C33D0:lI114|H3C33E0 +3C33E0:lI111|N +3C2C2C:lI99|H3C2CE0 +3C2CE0:lI112|H3C2D88 +3C2D88:lI116|N +3C2B7C:lH3C2C3C|N +3C2C3C:t2:H3C2CF0,H3C2CF8 +3C2CF8:lI97|H3C2DA0 +3C2DA0:lI112|H3C2E38 +3C2E38:lI112|H3C2EB8 +3C2EB8:lI108|H3C2F30 +3C2F30:lI105|H3C2FA0 +3C2FA0:lI99|H3C3008 +3C3008:lI97|H3C3070 +3C3070:lI116|H3C30D0 +3C30D0:lI105|H3C3128 +3C3128:lI111|H3C3178 +3C3178:lI110|H3C31C0 +3C31C0:lI47|H3C3208 +3C3208:lI109|H3C3250 +3C3250:lI97|H3C3298 +3C3298:lI99|H3C32E0 +3C32E0:lI45|H3C3318 +3C3318:lI98|H3C3348 +3C3348:lI105|H3C3370 +3C3370:lI110|H3C3390 +3C3390:lI104|H3C33A8 +3C33A8:lI101|H3C33B8 +3C33B8:lI120|H3C33C8 +3C33C8:lI52|H3C33D8 +3C33D8:lI48|N +3C2CF0:lI104|H3C2D98 +3C2D98:lI113|H3C2E30 +3C2E30:lI120|N +3BDBCC:lH3BDA78|H3BDA8C +3BDA78:t2:A4:port,I8888 +3BDA8C:lH3BDB04|H3BDB10 +3BDB04:t2:AC:bind_address,H3BDB64 +3BDB64:t4:I127,I0,I0,I1 +3BDB10:lH3BDB78|H3BDB84 +3BDB78:t2:AB:server_name,H3BDBD4 +3BDBD4:lI108|H3BDC24 +3BDC24:lI111|H3BDC88 +3BDC88:lI99|H3BDCF0 +3BDCF0:lI97|H3BDD70 +3BDD70:lI108|H3BDDF8 +3BDDF8:lI104|H3BDE90 +3BDE90:lI111|H3BDF40 +3BDF40:lI115|H3BDFFC +3BDFFC:lI116|N +3BDB84:lH3BDBDC|H3BDBE8 +3BDBDC:t2:AE:max_header_siz,I1024 +3BDBE8:lH3BDC2C|H3BDC38 +3BDC2C:t2:A11:max_header_action,A8:reply414 +3BDC38:lH3BDC90|H3BDC9C +3BDC90:t2:A8:com_type,A7:ip_comm +3BDC9C:lH3BDCF8|H3BDD04 +3BDCF8:t2:A7:modules,H3BDD78 +3BDD78:lA9:mod_alias|H3BDE00 +3BDE00:lA8:mod_auth|H3BDE98 +3BDE98:lA7:mod_esi|H3BDF48 +3BDF48:lAB:mod_actions|H3BE004 +3BE004:lA7:mod_cgi|H3BE0D0 +3BE0D0:lAB:mod_include|H3BE1A4 +3BE1A4:lA7:mod_dir|H3BE288 +3BE288:lA7:mod_get|H3BE378 +3BE378:lA8:mod_head|H3BE47C +3BE47C:lA7:mod_log|H3BE580 +3BE580:lAC:mod_disk_log|N +3BDD04:lH3BDD80|H3BDD8C +3BDD80:t2:AF:directory_index,H3BDE08 +3BDE08:lH3BDEA0|N +3BDEA0:lI105|H3BDF50 +3BDF50:lI110|H3BE00C +3BE00C:lI100|H3BE0D8 +3BE0D8:lI101|H3BE1AC +3BE1AC:lI120|H3BE290 +3BE290:lI46|H3BE380 +3BE380:lI104|H3BE484 +3BE484:lI116|H3BE588 +3BE588:lI109|H3BE68C +3BE68C:lI108|N +3BDD8C:lH3BDE10|H3BDE1C +3BDE10:t2:AC:default_type,H3BDEA8 +3BDEA8:lI116|H3BDF58 +3BDF58:lI101|H3BE014 +3BE014:lI120|H3BE0E0 +3BE0E0:lI116|H3BE1B4 +3BE1B4:lI47|H3BE298 +3BE298:lI112|H3BE388 +3BE388:lI108|H3BE48C +3BE48C:lI97|H3BE590 +3BE590:lI105|H3BE694 +3BE694:lI110|N +3BDE1C:lH3BDEB0|H3BDEBC +3BDEB0:t2:A10:erl_script_alias,H3BDF60 +3BDF60:t2:H3BE01C,H3BE024 +3BE024:lH3BE0F0|N +3BE0F0:lI119|H3BE1C4 +3BE1C4:lI101|H3BE2A8 +3BE2A8:lI98|H3BE398 +3BE398:lI116|H3BE49C +3BE49C:lI111|H3BE5A0 +3BE5A0:lI111|H3BE6A4 +3BE6A4:lI108|N +3BE01C:lI47|H3BE0E8 +3BE0E8:lI119|H3BE1BC +3BE1BC:lI101|H3BE2A0 +3BE2A0:lI98|H3BE390 +3BE390:lI116|H3BE494 +3BE494:lI111|H3BE598 +3BE598:lI111|H3BE69C +3BE69C:lI108|N +3BDEBC:lH3BDF6C|H3BDF78 +3BDF6C:t2:A5:alias,H3BE02C +3BE02C:t2:H3BE0F8,H3BE100 +3BE100:lI47|H3BE1D4 +3BE1D4:lI99|H3BE2B8 +3BE2B8:lI108|H3BE3A8 +3BE3A8:lI101|H3BE4AC +3BE4AC:lI97|H3BE5B0 +3BE5B0:lI114|H3BE6B4 +3BE6B4:lI99|H3BE7A8 +3BE7A8:lI97|H3BE894 +3BE894:lI115|H3BE980 +3BE980:lI101|H3BEA74 +3BEA74:lI47|H3BEB68 +3BEB68:lI111|H3BEC54 +3BEC54:lI116|H3BED40 +3BED40:lI112|H3BEE2C +3BEE2C:lI47|H3BEF00 +3BEF00:lI101|H3BEFD4 +3BEFD4:lI114|H3BF0A0 +3BF0A0:lI116|H3BF174 +3BF174:lI115|H3BF238 +3BF238:lI47|H3BF2FC +3BF2FC:lI108|H3BF3A8 +3BF3A8:lI105|H3BF45C +3BF45C:lI98|H3BF518 +3BF518:lI47|H3BF5DC +3BF5DC:lI111|H3BF6B0 +3BF6B0:lI98|H3BF784 +3BF784:lI115|H3BF858 +3BF858:lI101|H3BF93C +3BF93C:lI114|H3BFA18 +3BFA18:lI118|H3BFAF4 +3BFAF4:lI101|H3BFBD0 +3BFBD0:lI114|H3BFC9C +3BFC9C:lI47|H3BFD60 +3BFD60:lI112|H3BFE2C +3BFE2C:lI114|H3BFEE0 +3BFEE0:lI105|H3BFF94 +3BFF94:lI118|H3C0040 +3C0040:lI47|H3C00EC +3C00EC:lI99|H3C0198 +3C0198:lI114|H3C024C +3C024C:lI97|H3C0308 +3C0308:lI115|H3C03BC +3C03BC:lI104|H3C0458 +3C0458:lI100|H3C04F4 +3C04F4:lI117|H3C0590 +3C0590:lI109|H3C0634 +3C0634:lI112|H3C06E0 +3C06E0:lI95|H3C078C +3C078C:lI118|H3C0830 +3C0830:lI105|H3C08BC +3C08BC:lI101|H3C0950 +3C0950:lI119|H3C09E4 +3C09E4:lI101|H3C0A80 +3C0A80:lI114|N +3BE0F8:lI47|H3BE1CC +3BE1CC:lI99|H3BE2B0 +3BE2B0:lI114|H3BE3A0 +3BE3A0:lI97|H3BE4A4 +3BE4A4:lI115|H3BE5A8 +3BE5A8:lI104|H3BE6AC +3BE6AC:lI100|H3BE7A0 +3BE7A0:lI117|H3BE88C +3BE88C:lI109|H3BE978 +3BE978:lI112|H3BEA6C +3BEA6C:lI95|H3BEB60 +3BEB60:lI118|H3BEC4C +3BEC4C:lI105|H3BED38 +3BED38:lI101|H3BEE24 +3BEE24:lI119|H3BEEF8 +3BEEF8:lI101|H3BEFCC +3BEFCC:lI114|N +3BDF78:lH3BE038|H3BE044 +3BE038:t2:A5:alias,H3BE108 +3BE108:t2:H3BE1DC,H3BE1E4 +3BE1E4:lI47|H3BE2C8 +3BE2C8:lI99|H3BE3B8 +3BE3B8:lI108|H3BE4BC +3BE4BC:lI101|H3BE5C0 +3BE5C0:lI97|H3BE6C4 +3BE6C4:lI114|H3BE7B8 +3BE7B8:lI99|H3BE8A4 +3BE8A4:lI97|H3BE990 +3BE990:lI115|H3BEA84 +3BEA84:lI101|H3BEB78 +3BEB78:lI47|H3BEC64 +3BEC64:lI111|H3BED50 +3BED50:lI116|H3BEE3C +3BEE3C:lI112|H3BEF10 +3BEF10:lI47|H3BEFE4 +3BEFE4:lI101|H3BF0B0 +3BF0B0:lI114|H3BF184 +3BF184:lI116|H3BF248 +3BF248:lI115|H3BF304 +3BF304:lI47|H3BF3B0 +3BF3B0:lI101|H3BF464 +3BF464:lI114|H3BF520 +3BF520:lI116|H3BF5E4 +3BF5E4:lI115|H3BF6B8 +3BF6B8:lI47|H3BF78C +3BF78C:lI100|H3BF860 +3BF860:lI111|H3BF944 +3BF944:lI99|H3BFA20 +3BFA20:lI47|H3BFAFC +3BFAFC:lI104|H3BFBD8 +3BFBD8:lI116|H3BFCA4 +3BFCA4:lI109|H3BFD68 +3BFD68:lI108|N +3BE1DC:lI47|H3BE2C0 +3BE2C0:lI99|H3BE3B0 +3BE3B0:lI114|H3BE4B4 +3BE4B4:lI97|H3BE5B8 +3BE5B8:lI115|H3BE6BC +3BE6BC:lI104|H3BE7B0 +3BE7B0:lI100|H3BE89C +3BE89C:lI117|H3BE988 +3BE988:lI109|H3BEA7C +3BEA7C:lI112|H3BEB70 +3BEB70:lI95|H3BEC5C +3BEC5C:lI101|H3BED48 +3BED48:lI114|H3BEE34 +3BEE34:lI116|H3BEF08 +3BEF08:lI115|H3BEFDC +3BEFDC:lI95|H3BF0A8 +3BF0A8:lI100|H3BF17C +3BF17C:lI111|H3BF240 +3BF240:lI99|N +3BE044:lH3BE114|H3BE120 +3BE114:t2:A5:alias,H3BE1EC +3BE1EC:t2:H3BE2D0,H3BE2D8 +3BE2D8:lI47|H3BE3C8 +3BE3C8:lI99|H3BE4CC +3BE4CC:lI108|H3BE5D0 +3BE5D0:lI101|H3BE6D4 +3BE6D4:lI97|H3BE7C8 +3BE7C8:lI114|H3BE8B4 +3BE8B4:lI99|H3BE9A0 +3BE9A0:lI97|H3BEA94 +3BEA94:lI115|H3BEB88 +3BEB88:lI101|H3BEC74 +3BEC74:lI47|H3BED60 +3BED60:lI111|H3BEE4C +3BEE4C:lI116|H3BEF20 +3BEF20:lI112|H3BEFEC +3BEFEC:lI47|H3BF0B8 +3BF0B8:lI101|H3BF18C +3BF18C:lI114|H3BF250 +3BF250:lI116|H3BF30C +3BF30C:lI115|H3BF3B8 +3BF3B8:lI47|H3BF46C +3BF46C:lI108|H3BF528 +3BF528:lI105|H3BF5EC +3BF5EC:lI98|H3BF6C0 +3BF6C0:lI47|H3BF794 +3BF794:lI111|H3BF868 +3BF868:lI98|H3BF94C +3BF94C:lI115|H3BFA28 +3BFA28:lI101|H3BFB04 +3BFB04:lI114|H3BFBE0 +3BFBE0:lI118|H3BFCAC +3BFCAC:lI101|H3BFD70 +3BFD70:lI114|H3BFE34 +3BFE34:lI47|H3BFEE8 +3BFEE8:lI100|H3BFF9C +3BFF9C:lI111|H3C0048 +3C0048:lI99|H3C00F4 +3C00F4:lI47|H3C01A0 +3C01A0:lI104|H3C0254 +3C0254:lI116|H3C0310 +3C0310:lI109|H3C03C4 +3C03C4:lI108|N +3BE2D0:lI47|H3BE3C0 +3BE3C0:lI99|H3BE4C4 +3BE4C4:lI114|H3BE5C8 +3BE5C8:lI97|H3BE6CC +3BE6CC:lI115|H3BE7C0 +3BE7C0:lI104|H3BE8AC +3BE8AC:lI100|H3BE998 +3BE998:lI117|H3BEA8C +3BEA8C:lI109|H3BEB80 +3BEB80:lI112|H3BEC6C +3BEC6C:lI95|H3BED58 +3BED58:lI100|H3BEE44 +3BEE44:lI111|H3BEF18 +3BEF18:lI99|N +3BE120:lH3BE1F8|N +3BE1F8:t2:A10:erl_script_alias,H3BE2E0 +3BE2E0:t2:H3BE3D0,H3BE3D8 +3BE3D8:lH3BE4DC|N +3BE4DC:lI99|H3BE5E0 +3BE5E0:lI114|H3BE6E4 +3BE6E4:lI97|H3BE7D8 +3BE7D8:lI115|H3BE8C4 +3BE8C4:lI104|H3BE9B0 +3BE9B0:lI100|H3BEAA4 +3BEAA4:lI117|H3BEB90 +3BEB90:lI109|H3BEC7C +3BEC7C:lI112|H3BED68 +3BED68:lI95|H3BEE54 +3BEE54:lI118|H3BEF28 +3BEF28:lI105|H3BEFF4 +3BEFF4:lI101|H3BF0C0 +3BF0C0:lI119|H3BF194 +3BF194:lI101|H3BF258 +3BF258:lI114|N +3BE3D0:lI47|H3BE4D4 +3BE4D4:lI99|H3BE5D8 +3BE5D8:lI100|H3BE6DC +3BE6DC:lI118|H3BE7D0 +3BE7D0:lI95|H3BE8BC +3BE8BC:lI101|H3BE9A8 +3BE9A8:lI114|H3BEA9C +3BEA9C:lI108|N +3BDE2C:lH3BDA9C|H3BDECC +3BDA9C:t4:I127,I0,I0,I1 +3BDECC:lI8888|H3BDF88 +3BDF88:lN|N +3BDD1C:lN|N +3BDA50:t2:AD:$initial_call,H3BDAB8 +3BDAB8:t3:A3:gen,A7:init_it,H3BDAB0 +3BDA5C:t2:A9:verbosity,A7:silence +3BDAC8:t2:AE:auth_verbosity,A7:silence +3BDB28:t2:A12:security_verbosity,A7:silence +3BDB9C:t2:A12:acceptor_verbosity,A7:silence +3BDC00:t2:AA:$ancestors,H3BDC5C +3BDC5C:lA1A:httpd_sup__127_0_0_1__8888|H3BDCB4 +3BDCB4:lA8:web_tool|H3BDD24 +3BDD24:lP<0.27.0>|N +3BDADC:t2:A19:request_handler_verbosity,A7:silence +3BDB3C:t2:A5:sname,A3:man +=proc_dictionary:<0.47.0> +H36E688 +H36E694 +H36E6A0 +H36E6AC +=proc_stack:<0.47.0> +36c520:SReturn addr 0x362C9C (inet_tcp:accept/2 + 20) +y0:I5 +y1:p<0.161> +y2:p<0.141> +36c530:SReturn addr 0x500C5C (httpd_socket:accept/3 + 280) +y0:N +36c538:SReturn addr 0x502BFC (httpd_acceptor:acceptor/4 + 164) +y0:N +36c540:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:SCatch 0x502BFC (httpd_acceptor:acceptor/4 + 164) +y1:P<0.46.0> +y2:A7:ip_comm +y3:p<0.141> +y4:A1B:httpd_conf__127_0_0_1__8888 +36c558:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:AE:httpd_acceptor +y2:A8:acceptor +y3:H36E6C8 +=proc_heap:<0.47.0> +36E6C8:lP<0.44.0>|H36E724 +36E724:lP<0.46.0>|H36E748 +36E748:lA7:ip_comm|H36E760 +36E760:lH36E6D0|H36E778 +36E6D0:t4:I127,I0,I0,I1 +36E778:lI8888|H36E788 +36E788:lA1B:httpd_conf__127_0_0_1__8888|H36E798 +36E798:lA7:silence|N +36E688:t2:AD:$initial_call,H36E6F0 +36E6F0:t3:AE:httpd_acceptor,A8:acceptor,H36E6C8 +36E694:t2:A9:verbosity,A7:silence +36E6A0:t2:AA:$ancestors,H36E700 +36E700:lA1E:httpd_acc_sup__127_0_0_1__8888|H36E72C +36E72C:lA1A:httpd_sup__127_0_0_1__8888|H36E750 +36E750:lA8:web_tool|H36E768 +36E768:lP<0.27.0>|N +36E6AC:t2:A5:sname,A3:acc +=proc_dictionary:<0.48.0> +H385E48 +H385E54 +=proc_stack:<0.48.0> +3ac1bc:SReturn addr 0x225860 (proc_lib:init_p/5 + 164) +y0:N +y1:A8:infinity +y2:A10:crashdump_viewer +y3:H3AB280 +y4:A17:crashdump_viewer_server +y5:P<0.41.0> +3ac1d8:SReturn addr 0x156F90 (<terminate process normally>) +y0:SCatch 0x225860 (proc_lib:init_p/5 + 164) +y1:A3:gen +y2:A7:init_it +y3:H385E90 +=proc_heap:<0.48.0> +3AB280:t8:A5:state,A9:undefined,A9:undefined,A9:undefined,A5:false,I4,A9:undefined,P<0.56.0> +385E90:lAA:gen_server|H385ED8 +385ED8:lP<0.41.0>|H385F10 +385F10:lP<0.41.0>|H385F58 +385F58:lH385FA8|H385FB4 +385FA8:t2:A5:local,A17:crashdump_viewer_server +385FB4:lA10:crashdump_viewer|H386014 +386014:lN|H38606C +38606C:lN|N +385E48:t2:AD:$initial_call,H385EB0 +385EB0:t3:A3:gen,A7:init_it,H385E90 +385E54:t2:AA:$ancestors,H385EC0 +385EC0:lA6:websup|H385F08 +385F08:lA8:web_tool|H385F50 +385F50:lP<0.27.0>|N +=proc_stack:<0.49.0> +36a114:SReturn addr 0x30174C (io:parse_erl_exprs/3 + 92) +y0:H369E10 +y1:P<0.22.0> +36a120:SReturn addr 0x2E5360 (shell:'-get_command/4-fun-0-'/1 + 20) +y0:N +36a128:SReturn addr 0x156F90 (<terminate process normally>) +=proc_heap:<0.49.0> +369E10:E21:8372000364000D6E6F6E6F6465406E6F686F737400000001330000000000000000 +=atoms diff --git a/lib/observer/test/etop_SUITE.erl b/lib/observer/test/etop_SUITE.erl new file mode 100644 index 0000000000..54f4a78e69 --- /dev/null +++ b/lib/observer/test/etop_SUITE.erl @@ -0,0 +1,94 @@ +%% +%% %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% +%% + +-module(etop_SUITE). + +%% Test functions +-export([all/1,text/1,text_tracing_off/1]). +-export([init_per_testcase/2, fin_per_testcase/2]). + +-include("test_server.hrl"). + +-define(default_timeout, ?t:minutes(1)). + +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. +fin_per_testcase(_Case, Config) -> + Dog=?config(watchdog, Config), + ?t:timetrap_cancel(Dog), + ok. + +all(suite) -> [text,text_tracing_off]. + +text(suite) -> + []; +text(doc) -> + ["Start etop with text presentation"]; +text(Config) when is_list(Config) -> + ?line {ok,Node} = ?t:start_node(node2,peer,[]), + + %% Must spawn this process, else the test case will never end. + ?line spawn_link(etop,start,[[{node,Node},{output,text},{interval,3}]]), + ?line timer:sleep(4000), + ?line etop:config(interval,2), + ?line timer:sleep(3000), + ?line etop:config(lines,5), + ?line timer:sleep(3000), + ?line etop:config(accumulate,true), + ?line timer:sleep(3000), + ?line etop:config(sort,reductions), + ?line timer:sleep(3000), + ?line etop:config(sort,memory), + ?line timer:sleep(3000), + ?line etop:config(sort,msg_q), + ?line timer:sleep(3000), + ?line etop:stop(), + ?line ?t:stop_node(Node), + ok. + +text_tracing_off(suite) -> + []; +text_tracing_off(doc) -> + ["Start etop with text presentation, and tracing turned off"]; +text_tracing_off(Config) when is_list(Config) -> + ?line {ok,Node} = ?t:start_node(node2,peer,[]), + + %% Must spawn this process, else the test case will never end. + ?line spawn_link(etop,start,[[{node,Node}, + {output,text}, + {interval,3}, + {tracing,off}]]), + ?line timer:sleep(4000), + ?line etop:config(interval,2), + ?line timer:sleep(3000), + ?line etop:config(lines,5), + ?line timer:sleep(3000), + ?line etop:config(accumulate,true), + ?line timer:sleep(3000), + ?line etop:config(sort,memory), + ?line timer:sleep(3000), + ?line etop:config(sort,msg_q), + ?line timer:sleep(3000), + ?line etop:config(sort,runtime), % this should not crash, but has no effect + ?line timer:sleep(3000), + ?line etop:stop(), + ?line ?t:stop_node(Node), + ok. + diff --git a/lib/observer/test/observer.cover b/lib/observer/test/observer.cover new file mode 100644 index 0000000000..47770ba839 --- /dev/null +++ b/lib/observer/test/observer.cover @@ -0,0 +1,2 @@ +{exclude,[multitrace]}. +{include,[observer_backend]}. diff --git a/lib/observer/test/observer.dynspec b/lib/observer/test/observer.dynspec new file mode 100644 index 0000000000..66794dfa11 --- /dev/null +++ b/lib/observer/test/observer.dynspec @@ -0,0 +1,11 @@ +%% -*- erlang -*- +%% You can test this file using this command. +%% file:script("observer.dynspec", [{'Os',"Unix"}]). + +case erlang:system_info(modified_timing_level) of + undefined -> + []; + _ -> + Reason = "Return trace limitation for spawn BIFs when +T is used", + [{skip,{ttb_SUITE,Reason}}] +end. diff --git a/lib/observer/test/observer.spec b/lib/observer/test/observer.spec new file mode 100644 index 0000000000..801eb80607 --- /dev/null +++ b/lib/observer/test/observer.spec @@ -0,0 +1,2 @@ +{topcase, {dir, "../observer_test"}}. + diff --git a/lib/observer/test/observer_SUITE.erl b/lib/observer/test/observer_SUITE.erl new file mode 100644 index 0000000000..3e9522c7a4 --- /dev/null +++ b/lib/observer/test/observer_SUITE.erl @@ -0,0 +1,51 @@ +%% +%% %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% +%% + +-module(observer_SUITE). +-include("test_server.hrl"). + +%% Test server specific exports +-export([all/1]). +-export([init_per_testcase/2, end_per_testcase/2]). + +%% Test cases +-export([app_file/1]). + +%% Default timetrap timeout (set in init_per_testcase) +-define(default_timeout, ?t:minutes(1)). + +init_per_testcase(_Case, Config) -> + Dog = ?t:timetrap(?default_timeout), + [{watchdog, Dog} | Config]. + +end_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + ?t:timetrap_cancel(Dog), + ok. + +all(suite) -> + [app_file]. + +app_file(suite) -> + []; +app_file(doc) -> + ["Testing .app file"]; +app_file(Config) when is_list(Config) -> + ?line ok = ?t:app_test(os_mon), + ok. diff --git a/lib/observer/test/ttb_SUITE.erl b/lib/observer/test/ttb_SUITE.erl new file mode 100644 index 0000000000..6da5e36b29 --- /dev/null +++ b/lib/observer/test/ttb_SUITE.erl @@ -0,0 +1,775 @@ +%% +%% %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% +%% + +-module(ttb_SUITE). + +-compile(export_all). +%% Test functions +-export([all/1,file/1,file_no_pi/1,file_fetch/1,wrap/1,wrap_merge/1, + wrap_merge_fetch_format/1,write_config1/1,write_config2/1, + write_config3/1,history/1,write_trace_info/1,seq_trace/1, + diskless/1,otp_4967_1/1,otp_4967_2/1]). +-export([init_per_testcase/2, fin_per_testcase/2]). +-export([foo/0]). + +-include("test_server.hrl"). + +-define(default_timeout, ?t:minutes(1)). + +init_per_testcase(_Case, Config) -> + ttb:stop(), + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. +fin_per_testcase(_Case, Config) -> + Dog=?config(watchdog, Config), + ?t:timetrap_cancel(Dog), + ok. + +all(suite) -> [file,file_no_pi,file_fetch,wrap,wrap_merge, + wrap_merge_fetch_format,write_config1,write_config2, + write_config3,history,write_trace_info,seq_trace,diskless, + otp_4967_1,otp_4967_2]. + +file(suite) -> + []; +file(doc) -> + ["Start tracing on multiple nodes, single file"]; +file(Config) when is_list(Config) -> + ?line Node = node(), + ?line {ok,OtherNode} = ?t:start_node(node2,slave,[]), + ?line c:nl(?MODULE), + ?line S = self(), + ?line Privdir=?config(priv_dir, Config), + ?line File = filename:join(Privdir,"file"), + ?line {ok,[Node]} = + ttb:tracer(Node,[{file, File}, + {handler,{fun myhandler/4, S}}]), + ?line {ok,[{S,[{matched,Node,_}]}]} = ttb:p(S,call), + ?line {ok,[OtherNode]} = + ttb:tracer([Node,OtherNode],[{file, File}, + {handler,{fun myhandler/4, S}}]), + ?line {ok,[{all,[{matched,_,_},{matched,_,_}]}]} = ttb:p(all,call), + ?line {ok,[]} = ttb:tracer([Node,OtherNode], + [{file, File}, + {handler,{fun myhandler/4, S}}]), + ?line {ok,[{matched,_,1},{matched,_,1}]} = ttb:tp(?MODULE,foo,[]), + ?line ?MODULE:foo(), + ?line rpc:call(OtherNode,?MODULE,foo,[]), + ?line ttb:stop(), + ?line ?t:stop_node(OtherNode), + ?line ok = ttb:format(filename:join(Privdir,atom_to_list(Node)++"-file")), + ?line ok = ttb:format(filename:join(Privdir, + atom_to_list(OtherNode)++"-file")), + + ?line [{trace,{S,_,Node},call,{?MODULE,foo,[]}}, + end_of_trace, + {trace,{_,_,OtherNode},call,{?MODULE,foo,[]}}, + end_of_trace] = flush(), + ok. + +file_no_pi(suite) -> + []; +file_no_pi(doc) -> + ["Start tracing on multiple nodes, single file, no process information"]; +file_no_pi(Config) when is_list(Config) -> + ?line Node = node(), + ?line {ok,OtherNode} = ?t:start_node(node2,slave,[]), + ?line c:nl(?MODULE), + ?line S = self(), + ?line Privdir=?config(priv_dir, Config), + ?line File = filename:join(Privdir,"file"), + ?line {ok,[_,_]} = + ttb:tracer([Node,OtherNode],[{file, File}, + {handler,{fun myhandler/4, S}}, + {process_info,false}]), + ?line {ok,[{all,[{matched,_,_},{matched,_,_}]}]} = ttb:p(all,call), + ?line {ok,[{matched,_,1},{matched,_,1}]} = ttb:tp(?MODULE,foo,[]), + ?line ?MODULE:foo(), + ?line rpc:call(OtherNode,?MODULE,foo,[]), + ?line ttb:stop(), + ?line ?t:stop_node(OtherNode), + ?line ok = ttb:format(filename:join(Privdir,atom_to_list(Node)++"-file")), + ?line ok = ttb:format(filename:join(Privdir, + atom_to_list(OtherNode)++"-file")), + + ?line [{trace,LocalProc,call,{?MODULE,foo,[]}}, + end_of_trace, + {trace,RemoteProc,call,{?MODULE,foo,[]}}, + end_of_trace] = flush(), + ?line true = is_pid(LocalProc), + ?line true = is_pid(RemoteProc), + ok. + +file_fetch(suite) -> + []; +file_fetch(doc) -> + ["stop with the fetch option, i.e. collect all files when ttb is stopped"]; +file_fetch(Config) when is_list(Config) -> + ?line Node = node(), + ?line {ok,OtherNode} = ?t:start_node(node2,slave,[]), + ?line c:nl(?MODULE), + ?line S = self(), + ?line Privdir=?config(priv_dir, Config), + ?line ThisDir = filename:join(Privdir,this), + ?line ok = file:make_dir(ThisDir), + ?line OtherDir = filename:join(Privdir,other), + ?line ok = file:make_dir(OtherDir), + ?line ThisFile = filename:join(ThisDir,"file_fetch"), + ?line OtherFile = filename:join(OtherDir,"file_fetch"), + + %% I'm setting priv_dir as cwd, so ttb_upload directory is created there + %% and not in any other strange place! + ?line {ok,Cwd} = file:get_cwd(), + ?line ok = file:set_cwd(Privdir), + + ?line {ok,[Node]} = + ttb:tracer(Node,[{file, ThisFile}, + {handler,{fun myhandler/4, S}}]), + ?line {ok,[OtherNode]} = + ttb:tracer([OtherNode],[{file, OtherFile}, + {handler,{fun myhandler/4, S}}]), + ?line {ok,[{all,[{matched,_,_},{matched,_,_}]}]} = ttb:p(all,call), + ?line {ok,[{matched,_,1},{matched,_,1}]} = ttb:tp(?MODULE,foo,[]), + ?line ?MODULE:foo(), + ?line rpc:call(OtherNode,?MODULE,foo,[]), + ?line ?t:capture_start(), + ?line ttb:stop([fetch]), + ?line ?t:capture_stop(), + ?line [StoreString] = ?t:capture_get(), + ?line UploadDir = + lists:last(string:tokens(lists:flatten(StoreString),"$ \n")), + ?line ?t:stop_node(OtherNode), + + %% check that files are no longer in original directories... + ?line ok = check_gone(ThisDir,atom_to_list(Node)++"-file_fetch"), + ?line ok = check_gone(ThisDir,atom_to_list(Node)++"-file_fetch.ti"), +% ?line false = lists:member(TrcLog,ThisList), +% ?line false = lists:member(TIFile,ThisList), + + ?line {ok,OtherList} = file:list_dir(OtherDir), + ?line false = lists:member(atom_to_list(OtherNode)++"-file_fetch",OtherList), + ?line false = lists:member(atom_to_list(OtherNode)++"-file_fetch.ti", + OtherList), + + %% but instead in ttb_upload directory, where they can be formatted + ?line ok = ttb:format(filename:join(UploadDir, + atom_to_list(Node)++"-file_fetch")), + ?line ok = ttb:format(filename:join(UploadDir, + atom_to_list(OtherNode)++"-file_fetch")), + + ?line [{trace,{S,_,Node},call,{?MODULE,foo,[]}}, + end_of_trace, + {trace,{_,_,OtherNode},call,{?MODULE,foo,[]}}, + end_of_trace] = flush(), + + ?line ok = file:set_cwd(Cwd), + ok. + +wrap(suite) -> + []; +wrap(doc) -> + ["Start tracing on multiple nodes, wrap files"]; +wrap(Config) when is_list(Config) -> + ?line Node = node(), + ?line {ok,OtherNode} = ?t:start_node(node2,slave,[]), + ?line c:nl(?MODULE), + ?line S = self(), + ?line Privdir=?config(priv_dir, Config), + ?line File = filename:join(Privdir,"wrap"), + ?line {ok,[_,_]} = + ttb:tracer([Node,OtherNode],[{file, {wrap,File,200,3}}, + {handler,{fun myhandler/4, S}}]), + ?line {ok,[{all,[{matched,_,_},{matched,_,_}]}]} = ttb:p(all,call), + ?line {ok,[{matched,_,1},{matched,_,1}]} = ttb:tp(?MODULE,foo,[]), + ?line ?MODULE:foo(), + ?line rpc:call(OtherNode,?MODULE,foo,[]), + ?line ?MODULE:foo(), + ?line rpc:call(OtherNode,?MODULE,foo,[]), + ?line ?MODULE:foo(), + ?line rpc:call(OtherNode,?MODULE,foo,[]), + ?line ttb:stop(), + ?line ?t:stop_node(OtherNode), + ?line ok = ttb:format(filename:join(Privdir, + atom_to_list(Node)++"-wrap.*.wrp")), + ?line [{trace,{S,_,Node},call,{?MODULE,foo,[]}}, + {trace,{S,_,Node},call,{?MODULE,foo,[]}}, + {trace,{S,_,Node},call,{?MODULE,foo,[]}}, + end_of_trace] = flush(), + ?line ok = ttb:format(filename:join(Privdir, + atom_to_list(OtherNode)++"-wrap.*.wrp")), + ?line [{trace,{_,_,OtherNode},call,{?MODULE,foo,[]}}, + {trace,{_,_,OtherNode},call,{?MODULE,foo,[]}}, + {trace,{_,_,OtherNode},call,{?MODULE,foo,[]}}, + end_of_trace] = flush(), + + %% Check that merge does not crash even if the timestamp flag is not on. + ?line ok = ttb:format( + [filename:join(Privdir, + atom_to_list(Node)++"-wrap.*.wrp"), + filename:join(Privdir, + atom_to_list(OtherNode)++"-wrap.*.wrp")]), + ?line [{trace,{S,_,Node},call,{?MODULE,foo,[]}}, + {trace,{S,_,Node},call,{?MODULE,foo,[]}}, + {trace,{S,_,Node},call,{?MODULE,foo,[]}}, + end_of_trace, + {trace,{_,_,OtherNode},call,{?MODULE,foo,[]}}, + {trace,{_,_,OtherNode},call,{?MODULE,foo,[]}}, + {trace,{_,_,OtherNode},call,{?MODULE,foo,[]}}, + end_of_trace] = flush(), + ok. + +wrap_merge(suite) -> + []; +wrap_merge(doc) -> + ["Start tracing on multiple nodes, wrap files, merge logs from both nodes"]; +wrap_merge(Config) when is_list(Config) -> + ?line Node = node(), + ?line {ok,OtherNode} = ?t:start_node(node2,slave,[]), + ?line c:nl(?MODULE), + ?line S = self(), + ?line Privdir=?config(priv_dir, Config), + ?line File = filename:join(Privdir,"wrap_merge"), + ?line {ok,[_,_]} = + ttb:tracer([Node,OtherNode],[{file, {wrap,File,200,3}}, + {handler,{fun myhandler/4, S}}]), + ?line {ok,[{all,[{matched,_,_},{matched,_,_}]}]}=ttb:p(all,[call,timestamp]), + ?line {ok,[{matched,_,1},{matched,_,1}]} = ttb:tp(?MODULE,foo,[]), + ?line ?MODULE:foo(), + ?line rpc:call(OtherNode,?MODULE,foo,[]), + ?line ?MODULE:foo(), + ?line rpc:call(OtherNode,?MODULE,foo,[]), + ?line ?MODULE:foo(), + ?line rpc:call(OtherNode,?MODULE,foo,[]), + ?line ttb:stop(), + ?line ?t:stop_node(OtherNode), + ?line ok = ttb:format( + [filename:join(Privdir, + atom_to_list(Node)++"-wrap_merge.*.wrp"), + filename:join(Privdir, + atom_to_list(OtherNode)++"-wrap_merge.*.wrp")]), + ?line [{trace_ts,{S,_,Node},call,{?MODULE,foo,[]},_}, + {trace_ts,_,call,{?MODULE,foo,[]},_}, + {trace_ts,{S,_,Node},call,{?MODULE,foo,[]},_}, + {trace_ts,_,call,{?MODULE,foo,[]},_}, + {trace_ts,{S,_,Node},call,{?MODULE,foo,[]},_}, + end_of_trace, + {trace_ts,{_,_,OtherNode},call,{?MODULE,foo,[]},_}, + end_of_trace] = flush(), + ok. + + +wrap_merge_fetch_format(suite) -> + []; +wrap_merge_fetch_format(doc) -> + ["Start tracing on multiple nodes, wrap files, fetch and format at stop"]; +wrap_merge_fetch_format(Config) when is_list(Config) -> + ?line Node = node(), + ?line {ok,OtherNode} = ?t:start_node(node2,slave,[]), + ?line c:nl(?MODULE), + ?line S = self(), + ?line Privdir=?config(priv_dir, Config), + ?line File = filename:join(Privdir,"wrap_merge_fetch_format"), + + %% I'm setting priv_dir as cwd, so ttb_upload directory is created there + %% and not in any other strange place! + ?line {ok,Cwd} = file:get_cwd(), + ?line ok = file:set_cwd(Privdir), + + ?line {ok,[_,_]} = + ttb:tracer([Node,OtherNode],[{file, {wrap,File,200,3}}, + {handler,{fun myhandler/4, S}}]), + ?line {ok,[{all,[{matched,_,_},{matched,_,_}]}]}=ttb:p(all,[call,timestamp]), + ?line {ok,[{matched,_,1},{matched,_,1}]} = ttb:tp(?MODULE,foo,[]), + ?line ?MODULE:foo(), + ?line rpc:call(OtherNode,?MODULE,foo,[]), + ?line ?MODULE:foo(), + ?line rpc:call(OtherNode,?MODULE,foo,[]), + ?line ?MODULE:foo(), + ?line rpc:call(OtherNode,?MODULE,foo,[]), + ?line ttb:stop([format]), + ?line ?t:stop_node(OtherNode), + ?line [{trace_ts,{S,_,Node},call,{?MODULE,foo,[]},_}, + {trace_ts,{_,_,OtherNode},call,{?MODULE,foo,[]},_}, + {trace_ts,{S,_,Node},call,{?MODULE,foo,[]},_}, + {trace_ts,{_,_,OtherNode},call,{?MODULE,foo,[]},_}, + {trace_ts,{S,_,Node},call,{?MODULE,foo,[]},_}, + end_of_trace, + {trace_ts,{_,_,OtherNode},call,{?MODULE,foo,[]},_}, + end_of_trace] = flush(), + + ?line ok = file:set_cwd(Cwd), + ok. + + +write_config1(suite) -> + []; +write_config1(doc) -> + ["Write config given commands"]; +write_config1(Config) when is_list(Config) -> + ?line Node = node(), + ?line {ok,OtherNode} = ?t:start_node(node2,slave,[]), + ?line c:nl(?MODULE), + ?line S = self(), + + ?line Privdir=?config(priv_dir, Config), + ?line File = filename:join(Privdir,"write_config1"), + ?line ok = ttb:write_config(File, + [{ttb,tracer,[[Node,OtherNode], + [{file, File}, + {handler,{fun myhandler/4,S}}]]}, + {ttb,p,[all,call]}, + {ttb,tp,[?MODULE,foo,[]]}]), + ?line [_,_,_] = ttb:list_config(File), + ?line ok = ttb:run_config(File), + ?line ?MODULE:foo(), + ?line rpc:call(OtherNode,?MODULE,foo,[]), + ?line ttb:stop(), + ?line ?t:stop_node(OtherNode), + ?line ok = ttb:format( + [filename:join(Privdir, + atom_to_list(Node)++"-write_config1"), + filename:join(Privdir, + atom_to_list(OtherNode)++"-write_config1")]), + ?line [{trace,{S,_,Node},call,{?MODULE,foo,[]}}, + end_of_trace, + {trace,Other,call,{?MODULE,foo,[]}}, + end_of_trace] = flush(), + + case metatest(Other,OtherNode,Privdir,"-write_config1.ti") of + {error,Reason} -> + timer:sleep(5000), + ?line ok = ttb:format( + [filename:join(Privdir, + atom_to_list(Node)++"-write_config1"), + filename:join(Privdir, + atom_to_list(OtherNode)++ + "-write_config1")]), + ?line io:format("\nTrying again: ~p\n",[flush()]), + ?line ?t:fail(Reason); + ok -> + ok + end, + ok. + +write_config2(suite) -> + []; +write_config2(doc) -> + ["Write config from history (all)"]; +write_config2(Config) when is_list(Config) -> + ?line Node = node(), + ?line {ok,OtherNode} = ?t:start_node(node2,slave,[]), + ?line c:nl(?MODULE), + ?line S = self(), + ?line Privdir=?config(priv_dir, Config), + ?line File = filename:join(Privdir,"write_config2"), + ?line {ok,[_,_]} = + ttb:tracer([Node,OtherNode],[{file, File}, + {handler,{fun myhandler/4, S}}]), + ?line {ok,[{all,[{matched,_,_},{matched,_,_}]}]} = ttb:p(all,call), + ?line {ok,[{matched,_,1},{matched,_,1}]} = ttb:tp(?MODULE,foo,[]), + ?line ok = ttb:write_config(File,all), + ?line ttb:stop(), + ?line [_,_,_] = ttb:list_config(File), + ?line ok = ttb:run_config(File), + ?line ?MODULE:foo(), + ?line rpc:call(OtherNode,?MODULE,foo,[]), + ?line ttb:stop(), + ?line ?t:stop_node(OtherNode), + ?line ok = ttb:format( + [filename:join(Privdir, + atom_to_list(Node)++"-write_config2"), + filename:join(Privdir, + atom_to_list(OtherNode)++"-write_config2")]), + ?line [{trace,{S,_,Node},call,{?MODULE,foo,[]}}, + end_of_trace, + {trace,Other,call,{?MODULE,foo,[]}}, + end_of_trace] = flush(), + + case metatest(Other,OtherNode,Privdir,"-write_config2.ti") of + {error,Reason} -> + timer:sleep(5000), + ?line ok = ttb:format( + [filename:join(Privdir, + atom_to_list(Node)++"-write_config2"), + filename:join(Privdir, + atom_to_list(OtherNode)++ + "-write_config2")]), + ?line io:format("\nTrying again: ~p\n",[flush()]), + ?line ?t:fail(Reason); + ok -> + ok + end, + ok. + +write_config3(suite) -> + []; +write_config3(doc) -> + ["Write config from history (selected and append)"]; +write_config3(Config) when is_list(Config) -> + ?line Node = node(), + ?line {ok,OtherNode} = ?t:start_node(node2,slave,[]), + ?line c:nl(?MODULE), + ?line S = self(), + ?line Privdir=?config(priv_dir, Config), + ?line File = filename:join(Privdir,"write_config3"), + ?line {ok,[_,_]} = + ttb:tracer([Node,OtherNode],[{file, File}, + {handler,{fun myhandler/4, S}}]), + ?line {ok,[{all,[{matched,_,_},{matched,_,_}]}]} = ttb:p(all,call), + ?line {ok,[{matched,_,1},{matched,_,1}]} = ttb:tp(?MODULE,foo,[]), + ?line ok = ttb:write_config(File,[1,2]), + ?line ttb:stop(), + ?line [_,_] = ttb:list_config(File), + ?line ok = ttb:run_config(File), + ?line ?MODULE:foo(), + ?line rpc:call(OtherNode,?MODULE,foo,[]), + ?line ttb:stop(), + ?line ok = ttb:format( + [filename:join(Privdir, + atom_to_list(Node)++"-write_config3"), + filename:join(Privdir, + atom_to_list(OtherNode)++"-write_config3")]), + ?line [] = flush(), %foo is not traced + + ?line ok = ttb:write_config(File,[{ttb,tp,[?MODULE,foo,[]]}], + [append]), + ?line [_,_,_] = ttb:list_config(File), + ?line ok = ttb:run_config(File), + ?line ?MODULE:foo(), + ?line rpc:call(OtherNode,?MODULE,foo,[]), + ?line ttb:stop(), + ?line ?t:stop_node(OtherNode), + ?line ok = ttb:format( + [filename:join(Privdir, + atom_to_list(Node)++"-write_config3"), + filename:join(Privdir, + atom_to_list(OtherNode)++"-write_config3")]), + ?line [{trace,{S,_,Node},call,{?MODULE,foo,[]}}, + end_of_trace, + {trace,Other,call,{?MODULE,foo,[]}}, + end_of_trace] = flush(), + + case metatest(Other,OtherNode,Privdir,"-write_config3.ti") of + {error,Reason} -> + timer:sleep(5000), + ?line ok = ttb:format( + [filename:join(Privdir, + atom_to_list(Node)++"-write_config3"), + filename:join(Privdir, + atom_to_list(OtherNode)++ + "-write_config3")]), + ?line io:format("\nTrying again: ~p\n",[flush()]), + ?line ?t:fail(Reason); + ok -> + ok + end, + ok. + + +history(suite) -> + []; +history(doc) -> + ["List history and execute entry from history"]; +history(Config) when is_list(Config) -> + ?line Node = node(), + ?line {ok,OtherNode} = ?t:start_node(node2,slave,[]), + ?line c:nl(?MODULE), + ?line S = self(), + + ?line Nodes = [Node,OtherNode], + ?line Privdir=?config(priv_dir, Config), + ?line File = filename:join(Privdir,"history"), + ?line StartOpts = [{file, File}, + {handler,{fun myhandler/4, S}}], + ?line {ok,[_,_]} = ttb:tracer(Nodes,StartOpts), + ?line {ok,[{all,[{matched,_,_},{matched,_,_}]}]} = ttb:p(all,call), + ?line {ok,[{matched,_,1},{matched,_,1}]} = ttb:tp(?MODULE,foo,[]), + ?line {ok,[{matched,_,1},{matched,_,1}]} = ttb:ctp(?MODULE,foo), + ?line [{1,{ttb,tracer,[Nodes,StartOpts]}}, + {2,{ttb,p,[all,call]}}, + {3,{ttb,tp,[?MODULE,foo,[]]}}, + {4,{ttb,ctp,[?MODULE,foo]}}] = ttb:list_history(), + ?line rpc:call(OtherNode,?MODULE,foo,[]), + ?line ok = ttb:run_history(3), + ?line ?MODULE:foo(), + ?line ok = ttb:run_history([3,4]), + ?line ?MODULE:foo(), + ?line ttb:stop(), + ?line ?t:stop_node(OtherNode), + ?line ok = ttb:format( + [filename:join(Privdir,atom_to_list(Node)++"-history"), + filename:join(Privdir,atom_to_list(OtherNode)++"-history")]), + ?line [{trace,{S,_,Node},call,{?MODULE,foo,[]}}, + end_of_trace] = flush(), + ok. + + + +write_trace_info(suite) -> + []; +write_trace_info(doc) -> + ["Write trace info and give handler explicitly in format command"]; +write_trace_info(Config) when is_list(Config) -> + ?line Node = node(), + ?line {ok,OtherNode} = ?t:start_node(node2,slave,[]), + ?line c:nl(?MODULE), + ?line S = self(), + ?line Privdir=?config(priv_dir, Config), + ?line File = filename:join(Privdir,"write_trace_info"), + ?line {ok,[_,_]} = + ttb:tracer([Node,OtherNode],[{file, File}, + {handler,{fun myhandler/4, S}}]), + ?line {ok,[{all,[{matched,_,_},{matched,_,_}]}]} = ttb:p(all,call), + ?line {ok,[{matched,_,1},{matched,_,1}]} = ttb:tp(?MODULE,foo,[]), + ?line ok = ttb:write_trace_info(mytraceinfo,fun() -> node() end), + ?line ?MODULE:foo(), + ?line rpc:call(OtherNode,?MODULE,foo,[]), + ?line ttb:stop(), + ?line ?t:stop_node(OtherNode), + ?line ok = ttb:format( + [filename:join(Privdir,atom_to_list(Node)++"-write_trace_info"), + filename:join(Privdir, + atom_to_list(OtherNode)++"-write_trace_info")], + [{handler,{fun otherhandler/4,S}}]), + ?line [{{trace,{S,_,Node},call,{?MODULE,foo,[]}},[Node]}, + {end_of_trace,[Node]}, + {{trace,{_,_,OtherNode},call,{?MODULE,foo,[]}},[OtherNode]}, + {end_of_trace,[OtherNode]}] = flush(), + + ok. + + +seq_trace(suite) -> + []; +seq_trace(doc) -> + ["Test sequential tracing"]; +seq_trace(Config) when is_list(Config) -> + ?line S = self(), + + ?line Privdir=?config(priv_dir, Config), + ?line File = filename:join(Privdir,"seq_trace"), + ?line {ok,[Node]} = ttb:tracer(node(),[{file,File}, + {handler,{fun myhandler/4, S}}]), + ?line {ok,[{new,[{matched,Node,0}]}]} = ttb:p(new,call), + ?line {ok,[{matched,Node,1},{saved,1}]} = + ttb:tpl(?MODULE,seq,0,ttb:seq_trigger_ms(send)), + + ?line Start = spawn(fun() -> seq() end), + ?line timer:sleep(300), + ?line ttb:stop(), + ?line ok = ttb:format( + [filename:join(Privdir,atom_to_list(Node)++"-seq_trace")]), + ?line [{trace,StartProc,call,{?MODULE,seq,[]}}, + {seq_trace,0,{send,{0,1},StartProc,P1Proc,{Start,P2}}}, + {seq_trace,0,{send,{1,2},P1Proc,P2Proc,{P1,Start}}}, + {seq_trace,0,{send,{2,3},P2Proc,StartProc,{P2,P1}}}, + end_of_trace] = flush(), + + %% Additional test for metatrace + case StartProc of + {Start,_,_} -> ok; + Pid when is_pid(Pid) -> + io:format("\n\nProcinfo was pid: ~p.\n" + "Should have been {Pid,Name,Node}\n", + [Pid]), + io:format("Trace information file:\n~p\n", + [ttb:dump_ti( + filename:join(Privdir, + atom_to_list(Node)++"-seq_trace.ti"))]), + ?t:fail("metatrace failed for startproc") + end, + case P1Proc of + {P1,_,_} -> ok; + P1 when is_pid(P1) -> + io:format("\n\nProcinfo was pid: ~p.\n" + "Should have been {Pid,Name,Node}\n", + [P1]), + io:format("Trace information file:\n~p\n", + [ttb:dump_ti( + filename:join(Privdir, + atom_to_list(Node)++"-seq_trace.ti"))]), + ?t:fail("metatrace failed for P1") + end, + case P2Proc of + {P2,_,_} -> ok; + P2 when is_pid(P2) -> + io:format("\n\nProcinfo was pid: ~p.\n" + "Should have been {Pid,Name,Node}\n", + [P2]), + io:format("Trace information file:\n~p\n", + [ttb:dump_ti( + filename:join(Privdir, + atom_to_list(Node)++"-seq_trace.ti"))]), + ?t:fail("metatrace failed for P2") + end, + ok. + + +diskless(suite) -> + []; +diskless(doc) -> + ["Start tracing on diskless remote node"]; +diskless(Config) when is_list(Config) -> + ?line {ok,RemoteNode} = ?t:start_node(node2,slave,[]), + ?line c:nl(?MODULE), + ?line S = self(), + ?line Privdir=?config(priv_dir, Config), + ?line File = filename:join(Privdir,"diskless"), + ?line {ok,[RemoteNode]} = + ttb:tracer([RemoteNode],[{file, {local, File}}, + {handler,{fun myhandler/4, S}}]), + ?line {ok,[{all,[{matched,RemoteNode,_}]}]} = ttb:p(all,call), + ?line {ok,[{matched,RemoteNode,1}]} = ttb:tp(?MODULE,foo,[]), + + ?line rpc:call(RemoteNode,?MODULE,foo,[]), + ?line timer:sleep(500), % needed for the IP port to flush + ?line ttb:stop(), + ?line ?t:stop_node(RemoteNode), + ?line ok = ttb:format(filename:join(Privdir, + atom_to_list(RemoteNode)++"-diskless")), + + ?line [{trace,{_,_,RemoteNode},call,{?MODULE,foo,[]}}, + end_of_trace] = flush(), + ok. + + +otp_4967_1(suite) -> + []; +otp_4967_1(doc) -> + ["OTP-4967: clear flag"]; +otp_4967_1(Config) when is_list(Config) -> + ?line {ok,[Node]} = ttb:tracer(), + ?line {ok,[{all,[{matched,Node,_}]}]} = ttb:p(all,call), + ?line {ok,[{all,[{matched,Node,_}]}]} = ttb:p(all,clear), + ?line stopped = ttb:stop(), + ok. + + +otp_4967_2(suite) -> + []; +otp_4967_2(doc) -> + ["OTP-4967: Trace message sent to {Name, Node}"]; +otp_4967_2(Config) when is_list(Config) -> + io:format("1: ~p",[now()]), + ?line Privdir = ?config(priv_dir,Config), + io:format("2: ~p",[now()]), + ?line File = filename:join(Privdir,"otp_4967"), + io:format("3: ~p",[now()]), + ?line S = self(), + io:format("4: ~p",[now()]), + ?line {ok,[Node]} = + ttb:tracer(node(),[{file, File}, + {handler,{fun myhandler/4, S}}]), + + io:format("5: ~p",[now()]), + %% Test that delayed registration of a process works. + receive after 200 -> ok end, + ?line register(otp_4967,self()), + io:format("6: ~p",[now()]), + ?line {ok,[{S,[{matched,Node,1}]}]} = ttb:p(self(),s), + io:format("7: ~p",[now()]), + ?line {otp_4967,node()} ! heihopp, + io:format("8: ~p",[now()]), + ?line stopped = ttb:stop([format]), + io:format("9: ~p",[now()]), + ?line Msgs = flush(), + io:format("10: ~p",[now()]), + ?line io:format("Messages received: \n~p\n",[Msgs]), + io:format("11: ~p",[now()]), + ?line true = lists:member(heihopp,Msgs), % the heihopp message itself + io:format("13: ~p",[now()]), + ?line {value,{trace,_,send,heihopp,{_,otp_4967,Node}}} = + lists:keysearch(heihopp,4,Msgs), % trace trace of the heihopp message + io:format("14: ~p",[now()]), + ?line end_of_trace = lists:last(Msgs), % end of the trace + ok. + + + + +myhandler(_Fd,Trace,_,Relay) -> + Relay ! Trace, + Relay. + +otherhandler(_Fd,Trace,TI,Relay) -> + {value,{mytraceinfo,I}} = lists:keysearch(mytraceinfo,1,TI), + Relay ! {Trace,I}, + Relay. + +flush() -> + flush([]). +flush(Acc) -> + receive + X -> + flush(Acc ++ [X]) + after 1000 -> + Acc + end. + +foo() -> + %% Sync between nodes is not always exact, so here is a litle timeout to + %% make sure traces come i correct sequence when merging. + %% In the real world there is no way to avoid this kind of trouble + timer:sleep(100), + foo_called. + + +seq() -> + Fun = fun() -> timer:sleep(100), + receive {From,To} -> To ! {self(),From} end + end, + P1 = spawn(Fun), + P2 = spawn(Fun), + P1 ! {self(),P2}, + receive {P2,P1} -> ok end, + {P1,P2}. + +%% Additional test for metatrace which might fail on OtherNode +metatest(Proc,Node,Privdir,Filename) -> + case Proc of + {_,_,Node} -> ok; + Pid when is_pid(Pid) -> + io:format("\n\nProcinfo was pid: ~p.\n" + "Should have been {Pid,Name,Node}\n", + [Pid]), + io:format("Trace information file:\n~p\n", + [ttb:dump_ti( + filename:join(Privdir,atom_to_list(Node)++Filename))]), +% ?t:fail("metatrace failed on "++atom_to_list(Node)) + {error,"metatrace failed on "++atom_to_list(Node)} + end. + +check_gone(Dir,File) -> + ?line {ok,List} = file:list_dir(Dir), + ?line case lists:member(File,List) of + true -> + timer:sleep(2000), + {ok,NewList} = file:list_dir(Dir), + case lists:member(File,NewList) of + true -> + io:format("~p: ~p~n", + [Dir,NewList]), + ?t:fail(File ++ " not removed from original place"); + false -> + io:format("gone after 2 sec....~n",[]), + ok + end; + false -> + ok + end. diff --git a/lib/observer/vsn.mk b/lib/observer/vsn.mk index ff06fb992d..499cce6b97 100644 --- a/lib/observer/vsn.mk +++ b/lib/observer/vsn.mk @@ -1 +1 @@ -OBSERVER_VSN = 0.9.8.2 +OBSERVER_VSN = 0.9.8.3 diff --git a/lib/odbc/AUTHORS b/lib/odbc/AUTHORS index d1ed32bde1..38f72244ef 100644 --- a/lib/odbc/AUTHORS +++ b/lib/odbc/AUTHORS @@ -5,4 +5,6 @@ Original Authors: Contributors: Scott Lystig Fritchie - input/output variables for stored procedures [email protected] - Some 64 bits adjustments
\ No newline at end of file [email protected] - Some 64 bits adjustments +Juhani R�nkimies - SQL_WCHAR and SQL_WVARCHAR support +Juhani R�nkimies - TIMESTAMP support
\ No newline at end of file diff --git a/lib/odbc/c_src/odbcserver.c b/lib/odbc/c_src/odbcserver.c index aaaea20a10..c9627e9d05 100644 --- a/lib/odbc/c_src/odbcserver.c +++ b/lib/odbc/c_src/odbcserver.c @@ -59,7 +59,7 @@ they are converted to string values. [?OPEN_CONNECTION, C_AutoCommitMode, C_TraceDriver, C_SrollableCursors, - C_TupelRow, ConnectionStr] + C_TupelRow, BinaryStrings, ConnectionStr] [?CLOSE_CONNECTION] [?COMMIT_TRANSACTION, CommitMode] [?QUERY, SQLQuery] @@ -76,6 +76,7 @@ C_TraceDriver - ?ON | ?OFF C_SrollableCursors - ?ON | ?OFF C_TupelRow - - ?ON | ?OFF + BinaryStrings - ?ON | ?OFF ConnectionStr - String CommitMode - ?COMMIT | ?ROLLBACK SQLQuery - String @@ -88,7 +89,8 @@ InOrOut = [ERL_ODBC_IN | ERL_ODBC_OUT | ERL_ODBC_INOUT] Datatype - USER_INT | USER_SMALL_INT | {USER_DECIMAL, Precision, Scale} | {USER_NMERIC, Precision, Scale} | {USER_CHAR, Max} | {USER_VARCHAR, Max} | - {USER_FLOAT, Precision} | USER_REAL | USER_DOUBLE + {USER_WVARCHAR, Max} | {USER_FLOAT, Precision} | USER_REAL | USER_DOUBLE | + USER_TIMESTAMP Scale - integer Precision - integer Max - integer @@ -173,7 +175,7 @@ static void encode_column_dyn(db_column column, int column_nr, db_state *state); static void encode_data_type(SQLINTEGER sql_type, SQLINTEGER size, SQLSMALLINT decimal_digits, db_state *state); -static Boolean decode_params(byte *buffer, int *index, param_array **params, +static Boolean decode_params(db_state *state, byte *buffer, int *index, param_array **params, int i, int j); /*------------- Erlang port communication functions ----------------------*/ @@ -378,7 +380,7 @@ DWORD WINAPI database_handler(const char *port) shutdown(socket, 2); close_socket(socket); clean_socket_lib(); - DO_EXIT(EXIT_SUCCESS); + /* Exit will be done by suervisor thread */ } /* Description: Calls the appropriate function to handle the database @@ -433,26 +435,33 @@ static db_result_msg db_connect(byte *args, db_state *state) diagnos diagnos; byte *connStrIn; int erl_auto_commit_mode, erl_trace_driver, - use_srollable_cursors, tuple_row_state; + use_srollable_cursors, tuple_row_state, binary_strings; erl_auto_commit_mode = args[0]; erl_trace_driver = args[1]; use_srollable_cursors = args[2]; tuple_row_state = args[3]; - connStrIn = args + 4 * sizeof(byte); + binary_strings = args[4]; + connStrIn = args + 5 * sizeof(byte); if(tuple_row_state == ON) { - tuple_row(state) = TRUE; + tuple_row(state) = TRUE; } else { - tuple_row(state) = FALSE; + tuple_row(state) = FALSE; } - + + if(binary_strings == ON) { + binary_strings(state) = TRUE; + } else { + binary_strings(state) = FALSE; + } + if(use_srollable_cursors == ON) { - use_srollable_cursors(state) = TRUE; + use_srollable_cursors(state) = TRUE; } else { - use_srollable_cursors(state) = FALSE; + use_srollable_cursors(state) = FALSE; } - + init_driver(erl_auto_commit_mode, erl_trace_driver, state); connlen = (SQLSMALLINT)strlen((const char*)connStrIn); @@ -1072,6 +1081,7 @@ static db_result_msg encode_out_params(db_state *state, int j = 0; param_array column; db_result_msg msg; + TIMESTAMP_STRUCT* ts; msg = encode_empty_message(); ei_x_encode_tuple_header(&dynamic_buffer(state), 3); @@ -1101,9 +1111,34 @@ static db_result_msg encode_out_params(db_state *state, } else { void* values = retrive_param_values(&column); switch(column.type.c) { + case SQL_C_TYPE_TIMESTAMP: + ts = (TIMESTAMP_STRUCT*) values; + ei_x_encode_tuple_header(&dynamic_buffer(state), 2); + ei_x_encode_tuple_header(&dynamic_buffer(state), 3); + ei_x_encode_long(&dynamic_buffer(state), (long)(ts->year)); + ei_x_encode_long(&dynamic_buffer(state), (long)(ts->month)); + ei_x_encode_long(&dynamic_buffer(state), (long)(ts->day)); + ei_x_encode_tuple_header(&dynamic_buffer(state), 3); + ei_x_encode_long(&dynamic_buffer(state), (long)(ts->hour)); + ei_x_encode_long(&dynamic_buffer(state), (long)(ts->minute)); + ei_x_encode_long(&dynamic_buffer(state), (long)(ts->second)); + break; case SQL_C_CHAR: - ei_x_encode_string(&dynamic_buffer(state), ((char*)values)+j*column.type.len); - break; + if binary_strings(state) { + ei_x_encode_binary(&dynamic_buffer(state), + ((char*)values)+j*column.type.len, + (column.type.strlen_or_indptr_array[j])); + } + else { + ei_x_encode_string(&dynamic_buffer(state), + ((char*)values)+j*column.type.len); + } + break; + case SQL_C_WCHAR: + ei_x_encode_binary(&dynamic_buffer(state), + ((char*)values)+j*column.type.len, + (column.type.strlen_or_indptr_array[j])); + break; case SQL_C_SLONG: ei_x_encode_long(&dynamic_buffer(state), ((long*)values)[j]); break; @@ -1359,13 +1394,35 @@ static db_result_msg encode_row_count(SQLINTEGER num_of_rows, static void encode_column_dyn(db_column column, int column_nr, db_state *state) { + TIMESTAMP_STRUCT* ts; if (column.type.len == 0 || column.type.strlen_or_indptr == SQL_NULL_DATA) { ei_x_encode_atom(&dynamic_buffer(state), "null"); } else { switch(column.type.c) { + case SQL_C_TYPE_TIMESTAMP: + ts = (TIMESTAMP_STRUCT*)column.buffer; + ei_x_encode_tuple_header(&dynamic_buffer(state), 2); + ei_x_encode_tuple_header(&dynamic_buffer(state), 3); + ei_x_encode_ulong(&dynamic_buffer(state), ts->year); + ei_x_encode_ulong(&dynamic_buffer(state), ts->month); + ei_x_encode_ulong(&dynamic_buffer(state), ts->day); + ei_x_encode_tuple_header(&dynamic_buffer(state), 3); + ei_x_encode_ulong(&dynamic_buffer(state), ts->hour); + ei_x_encode_ulong(&dynamic_buffer(state), ts->minute); + ei_x_encode_ulong(&dynamic_buffer(state), ts->second); + break; case SQL_C_CHAR: - ei_x_encode_string(&dynamic_buffer(state), column.buffer); + if binary_strings(state) { + ei_x_encode_binary(&dynamic_buffer(state), + column.buffer,column.type.strlen_or_indptr); + } else { + ei_x_encode_string(&dynamic_buffer(state), column.buffer); + } + break; + case SQL_C_WCHAR: + ei_x_encode_binary(&dynamic_buffer(state), + column.buffer,column.type.strlen_or_indptr); break; case SQL_C_SLONG: ei_x_encode_long(&dynamic_buffer(state), @@ -1379,9 +1436,14 @@ static void encode_column_dyn(db_column column, int column_nr, ei_x_encode_atom(&dynamic_buffer(state), column.buffer[0]?"true":"false"); break; - case SQL_C_BINARY: + case SQL_C_BINARY: column = retrive_binary_data(column, column_nr, state); - ei_x_encode_string(&dynamic_buffer(state), (void *)column.buffer); + if binary_strings(state) { + ei_x_encode_binary(&dynamic_buffer(state), + column.buffer,column.type.strlen_or_indptr); + } else { + ei_x_encode_string(&dynamic_buffer(state), (void *)column.buffer); + } break; default: ei_x_encode_atom(&dynamic_buffer(state), "error"); @@ -1404,6 +1466,16 @@ static void encode_data_type(SQLINTEGER sql_type, SQLINTEGER size, ei_x_encode_atom(&dynamic_buffer(state), "sql_varchar"); ei_x_encode_long(&dynamic_buffer(state), size); break; + case SQL_WCHAR: + ei_x_encode_tuple_header(&dynamic_buffer(state), 2); + ei_x_encode_atom(&dynamic_buffer(state), "sql_wchar"); + ei_x_encode_long(&dynamic_buffer(state), size); + break; + case SQL_WVARCHAR: + ei_x_encode_tuple_header(&dynamic_buffer(state), 2); + ei_x_encode_atom(&dynamic_buffer(state), "sql_wvarchar"); + ei_x_encode_long(&dynamic_buffer(state), size); + break; case SQL_NUMERIC: ei_x_encode_tuple_header(&dynamic_buffer(state), 3); ei_x_encode_atom(&dynamic_buffer(state), "sql_numeric"); @@ -1446,7 +1518,7 @@ static void encode_data_type(SQLINTEGER sql_type, SQLINTEGER size, ei_x_encode_atom(&dynamic_buffer(state), "SQL_TYPE_TIME"); break; case SQL_TYPE_TIMESTAMP: - ei_x_encode_atom(&dynamic_buffer(state), "SQL_TYPE_TIMESTAMP"); + ei_x_encode_atom(&dynamic_buffer(state), "sql_timestamp"); break; case SQL_BIGINT: ei_x_encode_atom(&dynamic_buffer(state), "SQL_BIGINT"); @@ -1492,67 +1564,96 @@ static void encode_data_type(SQLINTEGER sql_type, SQLINTEGER size, } } -static Boolean decode_params(byte *buffer, int *index, param_array **params, +static Boolean decode_params(db_state *state, byte *buffer, int *index, param_array **params, int i, int j) { int erl_type, size; long bin_size, l64; + long val; param_array* param; - + TIMESTAMP_STRUCT* ts; + ei_get_type(buffer, index, &erl_type, &size); param = &(*params)[i]; switch (param->type.c) { case SQL_C_CHAR: - if(erl_type != ERL_STRING_EXT) { - return FALSE; - } - - ei_decode_string(buffer, index, &(param->values.string[param->offset])); - param->offset += param->type.len; - param->type.strlen_or_indptr_array[j] = SQL_NTS; - break; - + if (binary_strings(state)) { + ei_decode_binary(buffer, index, + &(param->values.string[param->offset]), &bin_size); + param->offset += param->type.len; + param->type.strlen_or_indptr_array[j] = SQL_NTS; + } else { + if(erl_type != ERL_STRING_EXT) { + return FALSE; + } + ei_decode_string(buffer, index, &(param->values.string[param->offset])); + param->offset += param->type.len; + param->type.strlen_or_indptr_array[j] = SQL_NTS; + } + break; + case SQL_C_WCHAR: + ei_decode_binary(buffer, index, &(param->values.string[param->offset]), &bin_size); + param->offset += param->type.len; + param->type.strlen_or_indptr_array[j] = SQL_NTS; + break; + case SQL_C_TYPE_TIMESTAMP: + ts = (TIMESTAMP_STRUCT*) param->values.string; + ei_decode_tuple_header(buffer, index, &val); + ei_decode_long(buffer, index, &val); + ts[j].year = (SQLUSMALLINT)val; + ei_decode_long(buffer, index, &val); + ts[j].month = (SQLUSMALLINT)val; + ei_decode_long(buffer, index, &val); + ts[j].day = (SQLUSMALLINT)val; + ei_decode_long(buffer, index, &val); + ts[j].hour = (SQLUSMALLINT)val; + ei_decode_long(buffer, index, &val); + ts[j].minute = (SQLUSMALLINT)val; + ei_decode_long(buffer, index, &val); + ts[j].second = (SQLUSMALLINT)val; + ts[j].fraction = (SQLINTEGER)0; + break; case SQL_C_SLONG: - if(!((erl_type == ERL_SMALL_INTEGER_EXT) || - (erl_type == ERL_INTEGER_EXT) || - (erl_type == ERL_SMALL_BIG_EXT) || - (erl_type == ERL_LARGE_BIG_EXT))) { - return FALSE; - } - - if(ei_decode_long(buffer, index, &l64)) { - return FALSE; - } - - /* For 64-bit platforms we downcast 8-byte long - * to 4-byte SQLINTEGER, checking for overflow */ - - if(l64>INT_MAX || l64<INT_MIN) { - return FALSE; - } + if(!((erl_type == ERL_SMALL_INTEGER_EXT) || + (erl_type == ERL_INTEGER_EXT) || + (erl_type == ERL_SMALL_BIG_EXT) || + (erl_type == ERL_LARGE_BIG_EXT))) { + return FALSE; + } + + if(ei_decode_long(buffer, index, &l64)) { + return FALSE; + } + + /* For 64-bit platforms we downcast 8-byte long + * to 4-byte SQLINTEGER, checking for overflow */ + + if(l64>INT_MAX || l64<INT_MIN) { + return FALSE; + } param->values.integer[j]=(SQLINTEGER)l64; break; - + case SQL_C_DOUBLE: - if((erl_type != ERL_FLOAT_EXT)) { - return FALSE; - } - ei_decode_double(buffer, index, &(param->values.floating[j])); - break; - + if((erl_type != ERL_FLOAT_EXT)) { + return FALSE; + } + ei_decode_double(buffer, index, &(param->values.floating[j])); + break; + case SQL_C_BIT: if((erl_type != ERL_ATOM_EXT)) { - return FALSE; + return FALSE; } ei_decode_boolean(buffer, index, &(param->values.bool[j])); break; - + default: - return FALSE; + return FALSE; } - + return TRUE; } @@ -1932,7 +2033,7 @@ static void init_driver(int erl_auto_commit_mode, int erl_trace_driver, db_state *state) { - int auto_commit_mode, trace_driver, use_srollable_cursors; + int auto_commit_mode, trace_driver; if(erl_auto_commit_mode == ON) { auto_commit_mode = SQL_AUTOCOMMIT_ON; @@ -1958,18 +2059,19 @@ static void init_driver(int erl_auto_commit_mode, int erl_trace_driver, environment_handle(state), &connection_handle(state)))) DO_EXIT(EXIT_ALLOC); + /* By default Erlang handles all timeouts */ if(!sql_success(SQLSetConnectAttr(connection_handle(state), SQL_ATTR_CONNECTION_TIMEOUT, (SQLPOINTER)TIME_OUT, 0))) - DO_EXIT(EXIT_CONNECTION); + DO_EXIT(EXIT_CONNECTION); if(!sql_success(SQLSetConnectAttr(connection_handle(state), SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)auto_commit_mode, 0))) - DO_EXIT(EXIT_CONNECTION); + DO_EXIT(EXIT_CONNECTION); if(!sql_success(SQLSetConnectAttr(connection_handle(state), SQL_ATTR_TRACE, (SQLPOINTER)trace_driver, 0))) - DO_EXIT(EXIT_CONNECTION); + DO_EXIT(EXIT_CONNECTION); } static void init_param_column(param_array *params, byte *buffer, int *index, @@ -2053,6 +2155,32 @@ static void init_param_column(param_array *params, byte *buffer, int *index, sizeof(byte)* params->type.len); break; + case USER_WCHAR: + case USER_WVARCHAR: + if(user_type == USER_WCHAR) { + params->type.sql = SQL_WCHAR; + } else { + params->type.sql = SQL_WVARCHAR; + } + ei_decode_long(buffer, index, &length); + /* Max string length + string terminator */ + params->type.len = (length+1)*sizeof(SQLWCHAR); + params->type.c = SQL_C_WCHAR; + params->type.col_size = (SQLUINTEGER)length; + params->type.strlen_or_indptr_array = + (SQLLEN*)safe_malloc(num_param_values * sizeof(SQLINTEGER)); + params->values.string = + (byte *)safe_malloc(num_param_values * sizeof(byte) * params->type.len); + + break; + case USER_TIMESTAMP: + params->type.sql = SQL_TYPE_TIMESTAMP; + params->type.len = sizeof(TIMESTAMP_STRUCT); + params->type.c = SQL_C_TYPE_TIMESTAMP; + params->type.col_size = (SQLUINTEGER)19;//;sizeof(TIMESTAMP_STRUCT); + params->values.string = + (TIMESTAMP_STRUCT *)safe_malloc(num_param_values * params->type.len); + break; case USER_FLOAT: params->type.sql = SQL_FLOAT; params->type.c = SQL_C_DOUBLE; @@ -2190,11 +2318,17 @@ static db_result_msg map_sql_2_c_column(db_column* column) case SQL_LONGVARCHAR: case SQL_VARBINARY: case SQL_LONGVARBINARY: - column -> type.len = (column -> type.col_size) + - /* Make place for NULL termination */ - sizeof(byte); - column -> type.c = SQL_C_CHAR; - column -> type.strlen_or_indptr = SQL_NTS; + column -> type.len = (column -> type.col_size) + + /* Make place for NULL termination */ + sizeof(byte); + column -> type.c = SQL_C_CHAR; + column -> type.strlen_or_indptr = SQL_NTS; + break; + case SQL_WCHAR: + case SQL_WVARCHAR: + column -> type.len = (column -> type.col_size + 1)*sizeof(SQLWCHAR); + column -> type.c = SQL_C_WCHAR; + column -> type.strlen_or_indptr = SQL_NTS; break; case SQL_NUMERIC: case SQL_DECIMAL: @@ -2218,12 +2352,16 @@ static db_result_msg map_sql_2_c_column(db_column* column) break; case SQL_TYPE_DATE: case SQL_TYPE_TIME: - case SQL_TYPE_TIMESTAMP: column -> type.len = (column -> type.col_size) + sizeof(byte); column -> type.c = SQL_C_CHAR; column -> type.strlen_or_indptr = SQL_NTS; break; + case SQL_TYPE_TIMESTAMP: + column -> type.len = sizeof(TIMESTAMP_STRUCT); + column -> type.c = SQL_C_TYPE_TIMESTAMP; + column -> type.strlen_or_indptr = (SQLINTEGER)NULL; + break; case SQL_BIGINT: column -> type.len = DEC_NUM_LENGTH; column -> type.c = SQL_C_CHAR; @@ -2280,7 +2418,7 @@ static param_array * bind_parameter_arrays(byte *buffer, int *index, } for (j = 0; j < num_param_values; j++) { - if(!decode_params(buffer, index, ¶ms, i, j)) { + if(!decode_params(state, buffer, index, ¶ms, i, j)) { /* An input parameter was not of the expected type */ free_params(¶ms, i); return params; @@ -2309,7 +2447,9 @@ static void * retrive_param_values(param_array *Param) { switch(Param->type.c) { case SQL_C_CHAR: - return (void *)Param->values.string; + case SQL_C_WCHAR: + case SQL_C_TYPE_TIMESTAMP: + return (void *)Param->values.string; case SQL_C_SLONG: return (void *)Param->values.integer; case SQL_C_DOUBLE: diff --git a/lib/odbc/c_src/odbcserver.h b/lib/odbc/c_src/odbcserver.h index ccd694a985..e6d8df1f58 100644 --- a/lib/odbc/c_src/odbcserver.h +++ b/lib/odbc/c_src/odbcserver.h @@ -1,19 +1,19 @@ /* * %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 * 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% * @@ -111,6 +111,9 @@ #define USER_DOUBLE 9 #define USER_BOOLEAN 10 #define USER_TINY_INT 11 +#define USER_WCHAR 12 +#define USER_WVARCHAR 13 +#define USER_TIMESTAMP 14 /*------------------------ TYPDEFS ----------------------------------*/ @@ -170,6 +173,7 @@ typedef struct { Boolean associated_result_set; Boolean use_srollable_cursors; Boolean tuple_row; + Boolean binary_strings; Boolean exists_more_result_sets; Boolean param_query; Boolean out_params; @@ -188,6 +192,7 @@ typedef enum { #define associated_result_set(db_state) (db_state -> associated_result_set) #define use_srollable_cursors(db_state) (db_state -> use_srollable_cursors) #define tuple_row(db_state) (db_state -> tuple_row) +#define binary_strings(db_state) (db_state -> binary_strings) #define exists_more_result_sets(db_state) (db_state -> exists_more_result_sets) #define param_query(db_state) (db_state -> param_query) #define out_params(db_state) (db_state -> out_params) diff --git a/lib/odbc/configure.in b/lib/odbc/configure.in index 24e286c290..94e8a214d4 100644 --- a/lib/odbc/configure.in +++ b/lib/odbc/configure.in @@ -1,3 +1,21 @@ +dnl +dnl %CopyrightBegin% +dnl +dnl Copyright Ericsson AB 2005-2010. All Rights Reserved. +dnl +dnl The contents of this file are subject to the Erlang Public License, +dnl Version 1.1, (the "License"); you may not use this file except in +dnl compliance with the License. You should have received a copy of the +dnl Erlang Public License along with this software. If not, it can be +dnl retrieved online at http://www.erlang.org/. +dnl +dnl Software distributed under the License is distributed on an "AS IS" +dnl basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +dnl the License for the specific language governing rights and limitations +dnl under the License. +dnl +dnl %CopyrightEnd% +dnl dnl define([AC_CACHE_LOAD], )dnl dnl define([AC_CACHE_SAVE], )dnl @@ -25,6 +43,11 @@ else host_os=win32 fi +AC_ARG_WITH(odbc, +[ --with-odbc=PATH specify location of ODBC include and lib + --with-odbc use ODBC (default) + --without-odbc don't use ODBC]) + if test "$with_odbc" = "no"; then rm -f "$ERL_TOP/lib/odbc/SKIP" @@ -116,7 +139,7 @@ AC_SUBST(TARGET_FLAGS) case $host_os in darwin*) TARGET_FLAGS="-DUNIX" - if test ! -d "$with_odbc" || test "$with_odbc" = "yes" ; then + if test ! -d "$with_odbc" || test "$with_odbc" = "yes"; then ODBC_LIB= -L"/usr/lib" ODBC_INCLUDE="-I/usr/lib/include" else @@ -129,7 +152,7 @@ AC_SUBST(TARGET_FLAGS) win32|cygwin) TARGET_FLAGS="-DWIN32" AC_CHECK_LIB(ws2_32, main) - if test ! -d "$with_odbc"; then + if test ! -d "$with_odbc" || test "$with_odbc" = "yes"; then ODBC_LIB="" ODBC_INCLUDE="" else @@ -147,7 +170,7 @@ AC_SUBST(TARGET_FLAGS) echo "$msg" > "$ERL_TOP/lib/odbc/SKIP" odbc_lib_link_success=wont_try ;; - no- ) + no-yes | no- ) AC_CHECK_SIZEOF(void *) AC_MSG_CHECKING([for odbc in standard locations]) for rdir in /usr/local/odbc /usr/local /usr/odbc \ @@ -177,7 +200,7 @@ AC_SUBST(TARGET_FLAGS) fi ;; - no-*) + *) ODBC_LIB=-L"$with_odbc/lib" ODBC_INCLUDE="-I$with_odbc/include" AC_CHECK_LIB(odbc, SQLAllocHandle,[ODBC_LIB="$ODBC_LIB -lodbc"; odbc_lib_link_success=yes]) diff --git a/lib/odbc/doc/src/databases.xml b/lib/odbc/doc/src/databases.xml index c06327e11d..a6ba0e5245 100644 --- a/lib/odbc/doc/src/databases.xml +++ b/lib/odbc/doc/src/databases.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2002</year><year>2009</year> + <year>2002</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>Databases</title> @@ -99,7 +99,7 @@ <p>Note that when the value of the data to input is a string, it has to be quoted with <c>'</c>. Example: </p> <code type="none"> -\011odbc:sql_query(Ref, "INSERT INTO EMPLOYEE VALUES(1, 'Jane', 'Doe', 'F')"). +odbc:sql_query(Ref, "INSERT INTO EMPLOYEE VALUES(1, 'Jane', 'Doe', 'F')"). </code> </note> <p>You may also input data using <seealso marker="odbc#param_query">param_query/[3,4]</seealso> and then @@ -117,7 +117,11 @@ </row> <row> <cell align="left" valign="middle">SQL_CHAR(size)</cell> - <cell align="left" valign="middle">String </cell> + <cell align="left" valign="middle">String | Binary (configurable)</cell> + </row> + <row> + <cell align="left" valign="middle">SQL_WCHAR(size) </cell> + <cell align="left" valign="middle">Unicode binary encoded as UTF16 little endian.</cell> </row> <row> <cell align="left" valign="middle">SQL_NUMERIC(p,s) <br></br> @@ -171,7 +175,11 @@ when p >= 16 </cell> </row> <row> <cell align="left" valign="middle">SQL_VARCHAR(size) </cell> - <cell align="left" valign="middle">String </cell> + <cell align="left" valign="middle">String | Binary (configurable)</cell> + </row> + <row> + <cell align="left" valign="middle">SQL_WVARCHAR(size) </cell> + <cell align="left" valign="middle">Unicode binary encoded as UTF16 little endian.</cell> </row> <tcaption>Mapping of ODBC data types to the Erlang data types returned to the Erlang application.</tcaption> </table> @@ -190,23 +198,23 @@ when p >= 16 </cell> </row> <row> <cell align="left" valign="middle">SQL_TYPE_TIMESTAMP </cell> - <cell align="left" valign="middle">String </cell> + <cell align="left" valign="middle"> {{YY, MM, DD}, {HH, MM, SS}} </cell> </row> <row> <cell align="left" valign="middle">SQL_LONGVARCHAR </cell> - <cell align="left" valign="middle">String</cell> + <cell align="left" valign="middle">String | Binary (configurable)</cell> </row> <row> <cell align="left" valign="middle">SQL_BINARY</cell> - <cell align="left" valign="middle">String </cell> + <cell align="left" valign="middle">String | Binary (configurable)</cell> </row> <row> <cell align="left" valign="middle">SQL_VARBINARY</cell> - <cell align="left" valign="middle">String </cell> + <cell align="left" valign="middle">String | Binary (configurable)</cell> </row> <row> <cell align="left" valign="middle">SQL_LONGVARBINARY</cell> - <cell align="left" valign="middle">String </cell> + <cell align="left" valign="middle">String | Binary (configurable)</cell> </row> <row> <cell align="left" valign="middle">SQL_TINYINT </cell> @@ -250,12 +258,12 @@ when p >= 16 </cell> that contains more than one SQL query. For example, the following SQLServer-specific statement creates a procedure that returns a result set containing information about employees - that work at the department and and a result set listing the + that work at the department and a result set listing the customers of that department. </p> <code type="none"> CREATE PROCEDURE DepartmentInfo (@DepartmentID INT) AS -\011SELECT * FROM Employee WHERE department = @DepartmentID -\011SELECT * FROM Customers WHERE department = @DepartmentID + SELECT * FROM Employee WHERE department = @DepartmentID + SELECT * FROM Customers WHERE department = @DepartmentID </code> </section> diff --git a/lib/odbc/doc/src/error_handling.xml b/lib/odbc/doc/src/error_handling.xml index 26ad7f9848..c30acc5fdc 100644 --- a/lib/odbc/doc/src/error_handling.xml +++ b/lib/odbc/doc/src/error_handling.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2003</year><year>2009</year> + <year>2003</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>Error handling</title> @@ -126,15 +126,7 @@ c-process will exit. If the c-process crashes/exits it will bring the erlang-process down too and vice versa i.e. the connection is terminated.</p> - <note> - <p>The function connect/2 will start the odbc application if - that is not already done. In this case a supervisor information - log will be produced stating that the odbc application was started - as a temporary application. It is really the responsibility of the - application that uses the API too make sure it is started in the - desired way.</p> - </note> - + <section> <title>Error types</title> <p>The types of errors that may occur can be divide into the diff --git a/lib/odbc/doc/src/getting_started.xml b/lib/odbc/doc/src/getting_started.xml index 864c3a7b65..d543ef64d6 100644 --- a/lib/odbc/doc/src/getting_started.xml +++ b/lib/odbc/doc/src/getting_started.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2002</year><year>2009</year> + <year>2002</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>Getting started</title> @@ -108,15 +108,15 @@ to insert many rows in one go. </p> <code type="none"> 6 > odbc:param_query(Ref,"INSERT INTO EMPLOYEE (NR, FIRSTNAME, " -\011 "LASTNAME, GENDER) VALUES(?, ?, ?, ?)", -\011 [{sql_integer,[2,3,4,5,6,7,8]}, -\011 {{sql_varchar, 20}, + "LASTNAME, GENDER) VALUES(?, ?, ?, ?)", + [{sql_integer,[2,3,4,5,6,7,8]}, + {{sql_varchar, 20}, ["John", "Monica", "Ross", "Rachel", "Piper", "Prue", "Louise"]}, -\011 {{sql_varchar, 20}, + {{sql_varchar, 20}, ["Doe","Geller","Geller", "Green", "Halliwell", "Halliwell", "Lane"]}, -\011 {{sql_char, 1}, ["M","F","M","F","F","F","F"]}]). + {{sql_char, 1}, ["M","F","M","F","F","F","F"]}]). {updated, 7} </code> <p>Fetch all data in the table employee </p> diff --git a/lib/odbc/doc/src/notes.xml b/lib/odbc/doc/src/notes.xml index 99584efec9..09d78c3248 100644 --- a/lib/odbc/doc/src/notes.xml +++ b/lib/odbc/doc/src/notes.xml @@ -20,7 +20,7 @@ under the License. </legalnotice> - + <title>ODBC Release Notes</title> <prepared>otp_appnotes</prepared> <docno>nil</docno> @@ -31,21 +31,50 @@ <p>This document describes the changes made to the odbc application. </p> - <section><title>ODBC 2.10.7</title> + <section><title>ODBC 2.10.8</title> - <section><title>Fixed Bugs and Malfunctions</title> + <section><title>Improvements and New Features</title> <list> <item> <p> - The odbc application can now be compiled on FreeBSD. - (Thanks to Kenji Rikitake.)</p> + ODBC now handles the types SQL_WCHAR and SQL_WVARCHAR. + Thanks to Juhani R�nkimies. ODBC also has a new + connection option to return all strings as binaries and + also expect strings to be binaries in the param_query + function. These changes provides some unicode support.</p> <p> - Own Id: OTP-8444</p> + Own Id: OTP-7452</p> + </item> + <item> + <p> + Now supports SQL_TYPE_TIMESTAMP on the format {{YY, MM, + DD}, {HH, MM, SS}}. Thanks to Juhani R�nkimies.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-8511</p> </item> </list> </section> +</section> + + <section><title>ODBC 2.10.7</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + The odbc application can now be compiled on FreeBSD. + (Thanks to Kenji Rikitake.)</p> + <p> + Own Id: OTP-8444</p> + </item> + </list> + </section> + + <section><title>Improvements and New Features</title> <list> <item> diff --git a/lib/odbc/doc/src/odbc.xml b/lib/odbc/doc/src/odbc.xml index 450531c81c..70d8cfbe22 100644 --- a/lib/odbc/doc/src/odbc.xml +++ b/lib/odbc/doc/src/odbc.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1999</year><year>2009</year> + <year>1999</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>odbc</title> @@ -101,7 +101,7 @@ odbc_data_type() = sql_integer | sql_smallint | sql_tinyint | {sql_decimal, precision(), scale()} | {sql_numeric, precision(), scale()} | - {sql_char, size()} | {sql_varchar, size()} | {sql_float, precision()} | + {sql_char, size()} | {sql_wchar, size()} | {sql_varchar, size()} | {sql_wvarchar, size()}| {sql_float, precision()} | {sql_float, precision()} | sql_real | sql_double | sql_bit | atom() </code> <code type="none"> @@ -141,16 +141,9 @@ <d>An example of a connection string:<c>"DSN=sql-server;UID=aladdin;PWD=sesame"</c>where DSN is your ODBC Data Source Name, UID is a database user id and PWD is the password for that user. These are usually the attributes required in the connection string, but some drivers have other driver specific attributes, for example<c>"DSN=Oracle8;DBQ=gandalf;UID=aladdin;PWD=sesame"</c>where DBQ is your TNSNAMES.ORA entry name e.g. some Oracle specific configuration attribute.</d> <v>Options = [] | [option()]</v> <d>All options has default values. </d> - <v>option() = {auto_commit, auto_commit_mode()} | {timeout, milliseconds()} | {tuple_row, tuple_mode()} | {scrollable_cursors, use_scrollable_cursors()} | {trace_driver, trace_mode()} </v> - <d>The default timeout is infinity </d> - <v>auto_commit_mode() = on | off </v> - <d>Default is on.</d> - <v>tuple_mode() = on | off </v> - <d>Default is on. The option is deprecated and should not be used in new code.</d> - <v>use_scrollable_cursors() = on | off </v> - <d>Default is on.</d> - <v>trace_mode() = on | off </v> - <d>Default is off.</d> + <v>option() = {auto_commit, on | off} | {timeout, milliseconds()} + | {binary_strings, on | off} | {tuple_row, on | off} | {scrollable_cursors, on | off} | + {trace_driver, on | off} </v> <v>Ref = connection_reference() - should be used to access the connection. </v> <v>Reason = port_program_executable_not_found | common_reason()</v> </type> @@ -161,21 +154,36 @@ to handle the connection. These processes will terminate if the process that created the connection dies or if you call disconnect/1.</p> - <p>If automatic commit mode is turned on, each query will be + + <p>If automatic commit mode is turned on, each query will be considered as an individual transaction and will be automatically committed after it has been executed. If you want more than one query to be part of the same transaction the automatic commit mode should be turned off. Then you will have to call commit/3 explicitly to end a transaction. </p> + + <p>The default timeout is infinity </p> + + <p> >If the option binary_strings is turned on all strings + will be returned as binaries and strings inputed to + param_query will be expected to be binaries. The user needs + to ensure that the binary is in an encoding that the + database expects. By default this option is turned off.</p> + <p>As default result sets are returned as a lists of tuples. The <c>TupleMode</c> option still exists to keep some degree of backwards compatibility. If the option is set to off, result sets will be returned as a lists of lists instead of a lists of tuples.</p> + <p>Scrollable cursors are nice but causes some overhead. For some connections speed might be more important than flexible data access and then you can disable scrollable cursor for a - connection, limiting the API but gaining speed</p> + connection, limiting the API but gaining speed.</p> + + <note><p>Turning the scrollable_cursors option off is noted + to make old odbc-drivers able to connect that will otherwhise fail.</p></note> + <p>If trace mode is turned on this tells the ODBC driver to write a trace log to the file SQL.LOG that is placed in the current directory of the erlang emulator. This information @@ -183,6 +191,7 @@ erlang ODBC application, and it might be relevant for you to send this file to our support. Otherwise you will probably not have much use of this.</p> + <note> <p>For more information about the <c>ConnectStr</c> see description of the function SQLDriverConnect in [1].</p> @@ -302,7 +311,7 @@ capital letters, alas it is not currently supported by the param_query function. Too know which Erlang data type corresponds to an ODBC data type see the Erlang to ODBC - data type<seealso marker="databases#type">mapping</seealso> in the User's Guide.</p> + data type <seealso marker="databases#type">mapping</seealso> in the User's Guide.</p> </note> </desc> </func> diff --git a/lib/odbc/src/odbc.erl b/lib/odbc/src/odbc.erl index 8178accf6d..eb27a471ec 100644 --- a/lib/odbc/src/odbc.erl +++ b/lib/odbc/src/odbc.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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% %% @@ -186,7 +186,7 @@ sql_query(ConnectionReference, SQLQuery, infinity) when call(ConnectionReference, {sql_query, ODBCCmd}, infinity); sql_query(ConnectionReference, SQLQuery, TimeOut) - when is_pid(ConnectionReference),is_list(SQLQuery),integer(TimeOut),TimeOut>0 -> + when is_pid(ConnectionReference),is_list(SQLQuery),is_integer(TimeOut),TimeOut>0 -> ODBCCmd = [?QUERY, SQLQuery], call(ConnectionReference, {sql_query, ODBCCmd}, TimeOut). @@ -397,7 +397,7 @@ describe_table(ConnectionReference, Table, infinity) when call(ConnectionReference, {describe_table, ODBCCmd}, infinity); describe_table(ConnectionReference, Table, TimeOut) - when is_pid(ConnectionReference),is_list(Table),integer(TimeOut),TimeOut>0 -> + when is_pid(ConnectionReference),is_list(Table),is_integer(TimeOut),TimeOut>0 -> ODBCCmd = [?DESCRIBE, "SELECT * FROM " ++ Table], call(ConnectionReference, {describe_table, ODBCCmd}, TimeOut). %%%========================================================================= @@ -801,9 +801,11 @@ connect(ConnectionReferense, ConnectionStr, Options) -> connection_config(scrollable_cursors, Options), {C_TupleRow, _} = connection_config(tuple_row, Options), + {BinaryStrings, _} = connection_config(binary_strings, Options), + ODBCCmd = [?OPEN_CONNECTION, C_AutoCommitMode, C_TraceDriver, - C_SrollableCursors, C_TupleRow, ConnectionStr], + C_SrollableCursors, C_TupleRow, BinaryStrings, ConnectionStr], %% Send request, to open a database connection, to the control process. case call(ConnectionReferense, @@ -848,7 +850,9 @@ connection_default(trace_driver) -> {?OFF, off}; connection_default(scrollable_cursors) -> - {?ON, on}. + {?ON, on}; +connection_default(binary_strings) -> + {?OFF, off}. %%------------------------------------------------------------------------- call(ConnectionReference, Msg, Timeout) -> @@ -858,7 +862,7 @@ call(ConnectionReference, Msg, Timeout) -> case Result of %% Normal case, the result from the port-program has directly %% been forwarded to the client - Binary when binary(Binary) -> + Binary when is_binary(Binary) -> decode(Binary); timeout -> exit(timeout); @@ -908,21 +912,17 @@ fix_params({{sql_numeric, Precision, 0}, InOut, fix_params({{sql_numeric, Precision, Scale}, InOut, Values}) -> {?USER_NUMERIC, Precision, Scale, fix_inout(InOut), Values}; fix_params({{sql_char, Max}, InOut, Values}) -> - NewValues = - case (catch - lists:map(fun(Str) -> Str ++ [?STR_TERMINATOR] end, Values)) of - Result -> - Result - end, + NewValues = string_terminate(Values), {?USER_CHAR, Max, fix_inout(InOut), NewValues}; fix_params({{sql_varchar, Max}, InOut, Values}) -> - NewValues = - case (catch - lists:map(fun(Str) -> Str ++ [?STR_TERMINATOR] end, Values)) of - Result -> - Result - end, + NewValues = string_terminate(Values), {?USER_VARCHAR, Max, fix_inout(InOut), NewValues}; +fix_params({{sql_wchar, Max}, InOut, Values}) -> + NewValues = string_terminate(Values), + {?USER_WCHAR, Max, fix_inout(InOut), NewValues}; +fix_params({{sql_wvarchar, Max}, InOut, Values}) -> + NewValues = string_terminate(Values), + {?USER_WVARCHAR, Max, fix_inout(InOut), NewValues}; fix_params({{sql_float, Precision}, InOut, Values}) -> {?USER_FLOAT, Precision, fix_inout(InOut), Values}; fix_params({sql_real, InOut, Values}) -> @@ -931,6 +931,16 @@ fix_params({sql_double, InOut, Values}) -> {?USER_DOUBLE, fix_inout(InOut), Values}; fix_params({sql_bit, InOut, Values}) -> {?USER_BOOLEAN, fix_inout(InOut), Values}; +fix_params({'sql_timestamp', InOut, Values}) -> + NewValues = + case (catch + lists:map(fun({{Year,Month,Day},{Hour,Minute,Second}}) -> + {Year,Month,Day,Hour,Minute,Second} + end, Values)) of + Result -> + Result + end, + {?USER_TIMESTAMP, fix_inout(InOut), NewValues}; %% default is IN %%% fix_params({Type, Values}) -> fix_params({Type, in, Values}). @@ -941,3 +951,16 @@ fix_inout(out) -> ?OUT; fix_inout(inout) -> ?INOUT. + +string_terminate([Value| _ ] = Values) when is_list(Value)-> + case (catch + lists:map(fun(Str) -> Str ++ [?STR_TERMINATOR] end, Values)) of + Result -> + Result + end; +string_terminate([Value| _ ] = Values) when is_binary(Value)-> + case (catch + lists:map(fun(B) -> <<B/binary,0:16>> end, Values)) of + Result -> + Result + end. diff --git a/lib/odbc/src/odbc_internal.hrl b/lib/odbc/src/odbc_internal.hrl index 144e3cd176..aa60120f9a 100644 --- a/lib/odbc/src/odbc_internal.hrl +++ b/lib/odbc/src/odbc_internal.hrl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -69,6 +69,9 @@ -define(USER_DOUBLE, 9). -define(USER_BOOLEAN, 10). -define(USER_TINY_INT, 11). +-define(USER_WCHAR, 12). +-define(USER_WVARCHAR, 13). +-define(USER_TIMESTAMP, 14). %% INPUT & OUTPUT TYPE -define(IN, 0). diff --git a/lib/odbc/test/Makefile b/lib/odbc/test/Makefile new file mode 100644 index 0000000000..935ecbf5a7 --- /dev/null +++ b/lib/odbc/test/Makefile @@ -0,0 +1,114 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 1999-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 + + +INCLUDES= -I. -I$(ERL_TOP)/lib/test_server/include/ -I$(ERL_TOP)/lib/odbc/src + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- + +MODULES= \ + odbc_start_SUITE \ + odbc_connect_SUITE \ + odbc_query_SUITE \ + odbc_data_type_SUITE \ + odbc_test_lib \ + oracle \ + sqlserver \ + postgres + +EBIN = . + +ERL_FILES= $(MODULES:%=%.erl) + +HRL_FILES= odbc_test.hrl\ + +TARGET_FILES= \ + $(MODULES:%=$(EBIN)/%.$(EMULATOR)) + +SPEC_FILES = odbc.spec odbc.dynspec \ + odbc.spec.win + +EMAKEFILE = Emakefile +MAKE_EMAKE = $(wildcard $(ERL_TOP)/make/make_emakefile) + +ifeq ($(MAKE_EMAKE),) +BUILDTARGET = $(TARGET_FILES) +RELTEST_FILES = $(SPEC_FILES) $(SOURCE) +else +BUILDTARGET = emakebuild +RELTEST_FILES = $(EMAKEFILE) $(SPEC_FILES) $(SOURCE) +endif + +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/odbc_test + +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- + +ERL_COMPILE_FLAGS += $(INCLUDES) \ + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- + +tests debug opt: $(BUILDTARGET) + +targets: $(TARGET_FILES) + +.PHONY: emakebuild + +emakebuild: $(EMAKEFILE) + +$(EMAKEFILE): + $(MAKE_EMAKE) $(ERL_COMPILE_FLAGS) -o$(EBIN) '*_SUITE_make' | grep -v Warning > $(EMAKEFILE) + $(MAKE_EMAKE) $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) | grep -v Warning >> $(EMAKEFILE) + +clean: + rm -f $(TARGET_FILES) + rm -f core + +docs: + +# ---------------------------------------------------- +# Release Target +# ---------------------------------------------------- +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: opt + +release_tests_spec: opt + $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DATA) $(SPEC_FILES) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR) + + +release_docs_spec: + + + + + + + diff --git a/lib/odbc/test/README b/lib/odbc/test/README new file mode 100644 index 0000000000..1f3c659e28 --- /dev/null +++ b/lib/odbc/test/README @@ -0,0 +1,86 @@ +------------------------------------------------------------------------- + TEST SUITE REQUIREMENTS +------------------------------------------------------------------------- +As third party products are involved when using ODBC you will have to +setup your own test environment to be able to run the ODBC test +suites. + +You need to install a database such as postgres, sql-server, oracle +etc, and ODBC-drivers for that database. + +Then you need to setup a test database, however you do not +need to create any tables that will be done by the test suites. +The test suites will also remove all tables that it creates when +the test is complete. + +------------------------------------------------------------------------- +ERLANG FILES YOU MAY NEED TO CHANGE +------------------------------------------------------------------------- + +A remote database management system has a callback module to handle +possible differences in data type handling etc, the callback module +also defines the ODBC connection string. Currently available callback +modules are postgres.erl, sqlserver.erl and oracle.erl. Depending on +how you set things up you might want to edit the connection string in +the callback module or even add your own callback module. + +The callback module used in each test case is defined by the ?RDBMS +macro defined in odbc_test.hrl so you might need to change this to +suite your purposes. + +------------------------------------------------------------------------- +EXAMPLE +------------------------------------------------------------------------- + +As an example say we have the database odbctestdb, with +the user odbctest that has the password Sesame. The database +runs on the host myhost. + +UINX/LINUX +----------- + +Set up a database and install the unixODBC drivers. +Then the unix/linux user that should run the test suits needs an .odbc.ini +file to map connection data. For example ODBC connection string: +"DSN=Postgres;UID=odbctest" will need an .odbc.ini entry that looks +something like this: + +--- Start example of .odbc.ini ---- + +[Postgres] +Driver=/usr/lib/psqlodbc.so +Description=Postgres driver +ServerName=myhost +Database=odbctestdb +Port=5432 +LogonID=odbctest +Password=Sesame + +---End example of .odbc.ini ------------ + + +WINDOWS MOST FLAVORS +-------------------- + +There will be a "ODBC data source administrator" tool under +Control Panel -> Administrative Tools, use this to set up +your database. Choose to connect with SQL Server authentication. +As odbc connection string use: "DSN=odbctestdb;UID=odbctest;PWD=Sesame" + + +> %CopyrightBegin% +> +> Copyright Ericsson AB 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% diff --git a/lib/odbc/test/odbc.dynspec b/lib/odbc/test/odbc.dynspec new file mode 100644 index 0000000000..bb15edceed --- /dev/null +++ b/lib/odbc/test/odbc.dynspec @@ -0,0 +1,31 @@ +%% -*- erlang -*- +%% You can test this file using this command. +%% file:script("odbc.dynspec", [{'Os',"Unix"}]). + +Exists = +fun() -> + case code:lib_dir(odbc) of + {error,bad_name} -> + false; + P -> + %% Make sure that the odbc directory really + %% contains the application (and not only documentation). + case filelib:is_file(filename:join(P, "ebin/odbc.beam")) of + false -> false; + true -> + %% We know that we don't have any odbc libraries + %% installed on this computer. + {ok,Host} = inet:gethostname(), + Host =/= "netsim200" + end + end +end, +case Exists() of + false -> + NoOdbc = "No odbc application", + [{skip, {odbc_connect_SUITE, NoOdbc}}, + {skip, {odbc_data_type_SUITE, NoOdbc}}, + {skip, {odbc_query_SUITE, NoOdbc}}]; + true -> + [] +end. diff --git a/lib/odbc/test/odbc.spec b/lib/odbc/test/odbc.spec new file mode 100644 index 0000000000..acba9f8d98 --- /dev/null +++ b/lib/odbc/test/odbc.spec @@ -0,0 +1,9 @@ +{topcase, {dir, "../odbc_test"}}. +{skip, {odbc_data_type_SUITE, varchar_upper_limit, "Known bug in database"}}. +{skip, {odbc_data_type_SUITE, text_upper_limit, "Consumes too much resources"}}. +{skip, {odbc_data_type_SUITE, bit_true , "Not supported by driver"}}. +{skip, {odbc_data_type_SUITE, bit_false, "Not supported by driver"}}. +{skip, {odbc_query_SUITE, multiple_select_result_sets,"Not supported by driver"}}. +{skip, {odbc_query_SUITE, multiple_mix_result_sets, "Not supported by driver"}}. +{skip, {odbc_query_SUITE, multiple_result_sets_error, "Not supported by driver"}}. +{skip, {odbc_query_SUITE, param_insert_tiny_int, "Not supported by driver"}}.
\ No newline at end of file diff --git a/lib/odbc/test/odbc.spec.win b/lib/odbc/test/odbc.spec.win new file mode 100644 index 0000000000..1fd349d2c3 --- /dev/null +++ b/lib/odbc/test/odbc.spec.win @@ -0,0 +1,5 @@ +{topcase, {dir, "../odbc_test"}}. +{skip, {odbc_data_type_SUITE, big_int_lower_limit, "Not supported by sqlserver 7.0"}}. +{skip, {odbc_data_type_SUITE, big_int_upper_limit, "Not supported by sqlserver7.0"}}. +{skip, {odbc_data_type_SUITE, text_upper_limit, "Consumes too much resources"}}. + diff --git a/lib/odbc/test/odbc_connect_SUITE.erl b/lib/odbc/test/odbc_connect_SUITE.erl new file mode 100644 index 0000000000..4d37a8f543 --- /dev/null +++ b/lib/odbc/test/odbc_connect_SUITE.erl @@ -0,0 +1,816 @@ +%% +%% %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% +%% + +%% + +-module(odbc_connect_SUITE). + +%% Note: This directive should only be used in test suites. +-compile(export_all). + +-include("test_server.hrl"). +-include("test_server_line.hrl"). +-include("odbc_test.hrl"). + +-define(MAX_SEQ_TIMEOUTS, 10). + +%%-------------------------------------------------------------------- +%% all(Arg) -> [Doc] | [Case] | {skip, Comment} +%% Arg - doc | suite +%% Doc - string() +%% Case - atom() +%% Name of a test case function. +%% Comment - string() +%% Description: Returns documentation/test cases in this test suite +%% or a skip tuple if the platform is not supported. +%%-------------------------------------------------------------------- +all(doc) -> + ["Tests the ability to connect and disconnet to/from the database"]; +all(suite) -> + case odbc_test_lib:odbc_check() of + ok -> all(); + Other -> {skip, Other} + end. + +all() -> + [not_exist_db, commit, rollback, not_explicit_commit, + no_c_node, port_dies, control_process_dies, client_dies, + connect_timeout, timeout, many_timeouts, timeout_reset, + disconnect_on_timeout, connection_closed, + disable_scrollable_cursors, return_rows_as_lists, api_missuse]. + +%%-------------------------------------------------------------------- +%% Function: init_per_suite(Config) -> Config +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Initiation before the whole suite +%% +%% Note: This function is free to add any key/value pairs to the Config +%% variable, but should NOT alter/remove any existing entries. +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + application:start(odbc), + case odbc:connect(?RDBMS:connection_string(), + [{auto_commit, off}]) of + {ok, Ref} -> + odbc:disconnect(Ref), + [{tableName, odbc_test_lib:unique_table_name()} | Config]; + _ -> + {skip, "ODBC is not properly setup"} + end. +%%-------------------------------------------------------------------- +%% Function: end_per_suite(Config) -> _ +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Cleanup after the whole suite +%%-------------------------------------------------------------------- +end_per_suite(_Config) -> + application:stop(odbc), + ok. + +%%-------------------------------------------------------------------- +%% Function: init_per_testcase(Case, Config) -> Config +%% Case - atom() +%% Name of the test case that is about to be run. +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% +%% Description: Initiation before each test case +%% +%% Note: This function is free to add any key/value pairs to the Config +%% variable, but should NOT alter/remove any existing entries. +%%-------------------------------------------------------------------- +init_per_testcase(_TestCase, Config) -> + test_server:format("ODBCINI = ~p~n", [os:getenv("ODBCINI")]), + Dog = test_server:timetrap(?default_timeout), + Temp = lists:keydelete(connection_ref, 1, Config), + NewConfig = lists:keydelete(watchdog, 1, Temp), + [{watchdog, Dog} | NewConfig]. + +%%-------------------------------------------------------------------- +%% Function: end_per_testcase(Case, Config) -> _ +%% Case - atom() +%% Name of the test case that is about to be run. +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Cleanup after each test case +%%-------------------------------------------------------------------- +end_per_testcase(_TestCase, Config) -> + %% Clean up if needed + Table = ?config(tableName, Config), + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []), + Result = odbc:sql_query(Ref, "DROP TABLE " ++ Table), + io:format("Drop table: ~p ~p~n", [Table, Result]), + odbc:disconnect(Ref), + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +%%------------------------------------------------------------------------- +%% Test cases starts here. +%%------------------------------------------------------------------------- +commit(doc)-> + ["Test the use of explicit commit"]; +commit(suite) -> []; +commit(Config) -> + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), + [{auto_commit, off}]), + + Table = ?config(tableName, Config), + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer, DATA varchar(10))"), + + {updated, 1} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1,'bar')"), + + {updated, 1} = + odbc:sql_query(Ref, "UPDATE " ++ Table ++ + " SET DATA = 'foo' WHERE ID = 1"), + + ok = odbc:commit(Ref, commit), + UpdateResult = ?RDBMS:update_result(), + UpdateResult = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + + {updated, 1} = + odbc:sql_query(Ref, "UPDATE " ++ Table ++ + " SET DATA = 'bar' WHERE ID = 1"), + ok = odbc:commit(Ref, commit, ?TIMEOUT), + InsertResult = ?RDBMS:insert_result(), + InsertResult = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + + {'EXIT', {function_clause, _}} = + (catch odbc:commit(Ref, commit, -1)), + + ok = odbc:disconnect(Ref), + + ok. +%%------------------------------------------------------------------------- + +rollback(doc)-> + ["Test the use of explicit rollback"]; +rollback(suite) -> []; +rollback(Config) -> + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), + [{auto_commit, off}]), + + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer, DATA varchar(10))"), + {updated, 1} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"), + ok = odbc:commit(Ref, commit), + + {updated, 1} = + odbc:sql_query(Ref, "UPDATE " ++ Table ++ + " SET DATA = 'foo' WHERE ID = 1"), + ok = odbc:commit(Ref, rollback), + InsertResult = ?RDBMS:insert_result(), + InsertResult = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + + {updated, 1} = + odbc:sql_query(Ref, "UPDATE " ++ Table ++ + " SET DATA = 'foo' WHERE ID = 1"), + ok = odbc:commit(Ref, rollback, ?TIMEOUT), + InsertResult = ?RDBMS:insert_result(), + InsertResult = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + + + {'EXIT', {function_clause, _}} = + (catch odbc:commit(Ref, rollback, -1)), + + ok = odbc:disconnect(Ref), + ok. + +%%------------------------------------------------------------------------- +not_explicit_commit(doc) -> + ["Test what happens if you try using commit on a auto_commit connection."]; +not_explicit_commit(suite) -> []; +not_explicit_commit(_Config) -> + {ok, Ref} = + odbc:connect(?RDBMS:connection_string(), [{auto_commit, on}]), + {error, _} = odbc:commit(Ref, commit), + ok = odbc:disconnect(Ref), + ok. + +%%------------------------------------------------------------------------- +not_exist_db(doc) -> + ["Tests valid data format but invalid data in the connection parameters."]; +not_exist_db(suite) -> []; +not_exist_db(_Config) -> + {error, _} = odbc:connect("DSN=foo;UID=bar;PWD=foobar", []), + %% So that the odbc control server can be stoped "in the correct way" + test_server:sleep(100), + ok. + +%%------------------------------------------------------------------------- +no_c_node(doc) -> + "Test what happens if the port-program can not be found"; +no_c_node(suite) -> []; +no_c_node(_Config) -> + process_flag(trap_exit, true), + Dir = filename:nativename(filename:join(code:priv_dir(odbc), + "bin")), + FileName1 = filename:nativename(os:find_executable("odbcserver", + Dir)), + FileName2 = filename:nativename(filename:join(Dir, "odbcsrv")), + ok = file:rename(FileName1, FileName2), + Result = + case catch odbc:connect(?RDBMS:connection_string(), []) of + {error, port_program_executable_not_found} -> + ok; + Else -> + Else + end, + + ok = file:rename(FileName2, FileName1), + ok = Result. +%%------------------------------------------------------------------------ + +port_dies(doc) -> + "Tests what happens if the port program dies"; +port_dies(suite) -> []; +port_dies(_Config) -> + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []), + {status, _} = process_info(Ref, status), + process_flag(trap_exit, true), + Port = lists:last(erlang:ports()), + exit(Port, kill), + %% Wait for exit_status from port 5000 ms (will not get a exit + %% status in this case), then wait a little longer to make sure + %% the port and the controlprocess has had time to terminate. + test_server:sleep(7000), + undefined = process_info(Ref, status), + ok. + +%%------------------------------------------------------------------------- +control_process_dies(doc) -> + "Tests what happens if the Erlang control process dies"; +control_process_dies(suite) -> []; +control_process_dies(_Config) -> + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []), + process_flag(trap_exit, true), + Port = lists:last(erlang:ports()), + {connected, Ref} = erlang:port_info(Port, connected), + exit(Ref, kill), + test_server:sleep(100), + undefined = erlang:port_info(Port, connected), + %% Check for c-program still running, how? + ok. + +%%------------------------------------------------------------------------- +client_dies(doc) -> + ["Test that the odbc process is terminated when the client process " + "dies"]; +client_dies(suite) -> + [client_dies_normal, client_dies_timeout, client_dies_error]. + +%%------------------------------------------------------------------------- +client_dies_normal(doc) -> + ["Client dies with reason normal."]; +client_dies_normal(suite) -> []; +client_dies_normal(Config) when is_list(Config) -> + Pid = spawn(?MODULE, client_normal, [self()]), + + MonitorReference = + receive + {dbRef, Ref} -> + MRef = erlang:monitor(process, Ref), + Pid ! continue, + MRef + end, + + receive + {'DOWN', MonitorReference, _Type, _Object, _Info} -> + ok + after 5000 -> + test_server:fail(control_process_not_stopped) + end. + +client_normal(Pid) -> + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []), + Pid ! {dbRef, Ref}, + receive + continue -> + ok + end, + exit(self(), normal). + + +%%------------------------------------------------------------------------- +client_dies_timeout(doc) -> + ["Client dies with reason timeout."]; +client_dies_timeout(suite) -> []; +client_dies_timeout(Config) when is_list(Config) -> + Pid = spawn(?MODULE, client_timeout, [self()]), + + MonitorReference = + receive + {dbRef, Ref} -> + MRef = erlang:monitor(process, Ref), + Pid ! continue, + MRef + end, + + receive + {'DOWN', MonitorReference, _Type, _Object, _Info} -> + ok + after 5000 -> + test_server:fail(control_process_not_stopped) + end. + +client_timeout(Pid) -> + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []), + Pid ! {dbRef, Ref}, + receive + continue -> + ok + end, + exit(self(), timeout). + + +%%------------------------------------------------------------------------- +client_dies_error(doc) -> + ["Client dies with reason error."]; +client_dies_error(suite) -> []; +client_dies_error(Config) when is_list(Config) -> + Pid = spawn(?MODULE, client_error, [self()]), + + MonitorReference = + receive + {dbRef, Ref} -> + MRef = erlang:monitor(process, Ref), + Pid ! continue, + MRef + end, + + receive + {'DOWN', MonitorReference, _Type, _Object, _Info} -> + ok + after 5000 -> + test_server:fail(control_process_not_stopped) + end. + +client_error(Pid) -> + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []), + Pid ! {dbRef, Ref}, + receive + continue -> + ok + end, + exit(self(), error). + + +%%------------------------------------------------------------------------- +connect_timeout(doc) -> + ["Test the timeout for the connect function."]; +connect_timeout(suite) -> []; +connect_timeout(Config) when is_list(Config) -> + {'EXIT',timeout} = (catch odbc:connect(?RDBMS:connection_string(), + [{timeout, 0}])), + ok. +%%------------------------------------------------------------------------- +timeout(doc) -> + ["Test that timeouts don't cause unwanted behavior sush as receiving" + " an anwser to a previously tiemed out query."]; +timeout(suite) -> []; +timeout(Config) when is_list(Config) -> + + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), + [{auto_commit, off}]), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer, DATA varchar(10), PRIMARY KEY(ID))"), + + {updated, 1} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"), + + ok = odbc:commit(Ref, commit), + + {updated, 1} = + odbc:sql_query(Ref, "UPDATE " ++ Table ++ + " SET DATA = 'foo' WHERE ID = 1"), + + {updated, 1} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(2,'baz')"), + + Pid = spawn_link(?MODULE, update_table_timeout, [Table, 5000, self()]), + + receive + timout_occurred -> + ok = odbc:commit(Ref, commit), + Pid ! continue + end, + + receive + altered -> + ok + end, + + {selected, Fields, [{"foobar"}]} = + odbc:sql_query(Ref, "SELECT DATA FROM " ++ Table ++ " WHERE ID = 1"), + ["DATA"] = odbc_test_lib:to_upper(Fields), + + ok = odbc:commit(Ref, commit), + ok = odbc:disconnect(Ref), + ok. + + +update_table_timeout(Table, TimeOut, Pid) -> + + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), + [{auto_commit, off}]), + UpdateQuery = "UPDATE " ++ Table ++ " SET DATA = 'foobar' WHERE ID = 1", + + case catch odbc:sql_query(Ref, UpdateQuery, TimeOut) of + {'EXIT', timeout} -> + Pid ! timout_occurred; + {updated, 1} -> + test_server:fail(database_locker_failed) + end, + + receive + continue -> + ok + end, + + %% Make sure we receive the correct result and not the answer + %% to the previous query. + {selected, Fields, [{"baz"}]} = + odbc:sql_query(Ref, "SELECT DATA FROM " ++ Table ++ " WHERE ID = 2"), + ["DATA"] = odbc_test_lib:to_upper(Fields), + + {updated, 1} = odbc:sql_query(Ref, UpdateQuery, TimeOut), + + ok = odbc:commit(Ref, commit), + + Pid ! altered, + + ok = odbc:disconnect(Ref), + + ok. +%%------------------------------------------------------------------------- +many_timeouts(doc) -> + ["Tests that many consecutive timeouts lead to that the connection " + "is shutdown."]; +many_timeouts(suite) -> []; +many_timeouts(Config) when is_list(Config) -> + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), + [{auto_commit, off}]), + + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer, DATA varchar(10), PRIMARY KEY(ID))"), + + {updated, 1} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"), + + ok = odbc:commit(Ref, commit), + + {updated, 1} = + odbc:sql_query(Ref, "UPDATE " ++ Table ++ + " SET DATA = 'foo' WHERE ID = 1"), + + _Pid = spawn_link(?MODULE, update_table_many_timeouts, + [Table, 5000, self()]), + + receive + many_timeouts_occurred -> + ok + end, + + ok = odbc:commit(Ref, commit), + ok = odbc:disconnect(Ref), + ok. + + +update_table_many_timeouts(Table, TimeOut, Pid) -> + + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), + [{auto_commit, off}]), + UpdateQuery = "UPDATE " ++ Table ++ " SET DATA = 'foobar' WHERE ID = 1", + + ok = loop_many_timouts(Ref, UpdateQuery, TimeOut), + + Pid ! many_timeouts_occurred, + + ok = odbc:disconnect(Ref), + ok. + + +loop_many_timouts(Ref, UpdateQuery, TimeOut) -> + case catch odbc:sql_query(Ref, UpdateQuery, TimeOut) of + {'EXIT',timeout} -> + loop_many_timouts(Ref, UpdateQuery, TimeOut); + {updated, 1} -> + test_server:fail(database_locker_failed); + {error, connection_closed} -> + ok + end. +%%------------------------------------------------------------------------- +timeout_reset(doc) -> + ["Check that the number of consecutive timouts is reset to 0 when " + "a successful call to the database is made."]; +timeout_reset(suite) -> []; +timeout_reset(Config) when is_list(Config) -> + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), + [{auto_commit, off}]), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer, DATA varchar(10), PRIMARY KEY(ID))"), + + {updated, 1} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"), + + ok = odbc:commit(Ref, commit), + + {updated, 1} = + odbc:sql_query(Ref, "UPDATE " ++ Table ++ + " SET DATA = 'foo' WHERE ID = 1"), + + {updated, 1} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(2,'baz')"), + + + Pid = spawn_link(?MODULE, update_table_timeout_reset, + [Table, 5000, self()]), + + receive + many_timeouts_occurred -> + ok + end, + + ok = odbc:commit(Ref, commit), + Pid ! continue, + + receive + altered -> + ok + end, + + {selected, Fields, [{"foobar"}]} = + odbc:sql_query(Ref, "SELECT DATA FROM " ++ Table ++ " WHERE ID = 1"), + ["DATA"] = odbc_test_lib:to_upper(Fields), + + ok = odbc:commit(Ref, commit), + ok = odbc:disconnect(Ref), + ok. + +update_table_timeout_reset(Table, TimeOut, Pid) -> + + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), + [{auto_commit, off}]), + UpdateQuery = "UPDATE " ++ Table ++ " SET DATA = 'foobar' WHERE ID = 1", + + ok = loop_timout_reset(Ref, UpdateQuery, TimeOut, + ?MAX_SEQ_TIMEOUTS-1), + + Pid ! many_timeouts_occurred, + + receive + continue -> + ok + end, + + {selected, Fields, [{"baz"}]} = + odbc:sql_query(Ref, "SELECT DATA FROM " ++ Table ++ " WHERE ID = 2"), + ["DATA"] = odbc_test_lib:to_upper(Fields), + + {updated,1} = odbc:sql_query(Ref, UpdateQuery, TimeOut), + + ok = odbc:commit(Ref, commit), + + Pid ! altered, + + ok = odbc:disconnect(Ref), + + ok. + +loop_timout_reset(_, _, _, 0) -> + ok; + +loop_timout_reset(Ref, UpdateQuery, TimeOut, NumTimeouts) -> + case catch odbc:sql_query(Ref, UpdateQuery, TimeOut) of + {'EXIT',timeout} -> + loop_timout_reset(Ref, UpdateQuery, + TimeOut, NumTimeouts - 1); + {updated, 1} -> + test_server:fail(database_locker_failed); + {error, connection_closed} -> + test_server:fail(connection_closed_premature) + end. + +%%------------------------------------------------------------------------- + +disconnect_on_timeout(doc) -> + ["Check that disconnect after a time out works properly"]; +disconnect_on_timeout(suite) -> []; +disconnect_on_timeout(Config) when is_list(Config) -> + + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), + [{auto_commit, off}]), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer, DATA varchar(10), PRIMARY KEY(ID))"), + + {updated, 1} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"), + + ok = odbc:commit(Ref, commit), + + {updated, 1} = + odbc:sql_query(Ref, "UPDATE " ++ Table ++ + " SET DATA = 'foo' WHERE ID = 1"), + + + _Pid = spawn_link(?MODULE, update_table_disconnect_on_timeout, + [Table, 5000, self()]), + receive + ok -> + ok = odbc:commit(Ref, commit); + nok -> + test_server:fail(database_locker_failed) + end. + +update_table_disconnect_on_timeout(Table, TimeOut, Pid) -> + + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), + [{auto_commit, off}]), + UpdateQuery = "UPDATE " ++ Table ++ " SET DATA = 'foobar' WHERE ID = 1", + + case catch odbc:sql_query(Ref, UpdateQuery, TimeOut) of + {'EXIT', timeout} -> + ok = odbc:disconnect(Ref), + Pid ! ok; + {updated, 1} -> + Pid ! nok + end. + +%%------------------------------------------------------------------------- +connection_closed(doc) -> + ["Checks that you get an appropriate error message if you try to" + " use a connection that has been closed"]; +connection_closed(suite) -> []; +connection_closed(Config) when is_list(Config) -> + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []), + + Table = ?config(tableName, Config), + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer, DATA char(10), PRIMARY KEY(ID))"), + + ok = odbc:disconnect(Ref), + + {error, connection_closed} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"), + {error, connection_closed} = + odbc:select_count(Ref, "SELECT * FROM " ++ Table), + {error, connection_closed} = odbc:first(Ref), + {error, connection_closed} = odbc:last(Ref), + {error, connection_closed} = odbc:next(Ref), + {error, connection_closed} = odbc:prev(Ref), + {error, connection_closed} = odbc:select(Ref, next, 3), + {error, connection_closed} = odbc:commit(Ref, commit), + ok. + +%%------------------------------------------------------------------------- +disable_scrollable_cursors(doc) -> + ["Test disabling of scrollable cursors."]; +disable_scrollable_cursors(suite) -> []; +disable_scrollable_cursors(Config) when is_list(Config) -> + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), + [{scrollable_cursors, off}]), + + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer, DATA varchar(10), PRIMARY KEY(ID))"), + + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"), + + {ok, _} = odbc:select_count(Ref, "SELECT ID FROM " ++ Table), + + NextResult = ?RDBMS:selected_ID(1, next), + + test_server:format("Expected: ~p~n", [NextResult]), + + Result = odbc:next(Ref), + test_server:format("Got: ~p~n", [Result]), + NextResult = Result, + + {error, scrollable_cursors_disabled} = odbc:first(Ref), + {error, scrollable_cursors_disabled} = odbc:last(Ref), + {error, scrollable_cursors_disabled} = odbc:prev(Ref), + {error, scrollable_cursors_disabled} = + odbc:select(Ref, {relative, 2}, 5), + {error, scrollable_cursors_disabled} = + odbc:select(Ref, {absolute, 2}, 5), + + {selected, _ColNames,[]} = odbc:select(Ref, next, 1), + ok. + +%%------------------------------------------------------------------------- +return_rows_as_lists(doc)-> + ["Test the option that a row may be returned as a list instead " + "of a tuple. Too be somewhat backward compatible."]; +return_rows_as_lists(suite) -> []; +return_rows_as_lists(Config) when is_list(Config) -> + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), + [{tuple_row, off}]), + + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer, DATA varchar(10), PRIMARY KEY(ID))"), + + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"), + + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(2,'foo')"), + + ListRows = ?RDBMS:selected_list_rows(), + ListRows = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + + {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table), + + First = ?RDBMS:first_list_rows(), + Last = ?RDBMS:last_list_rows(), + Prev = ?RDBMS:prev_list_rows(), + Next = ?RDBMS:next_list_rows(), + + Last = odbc:last(Ref), + Prev = odbc:prev(Ref), + First = odbc:first(Ref), + Next = odbc:next(Ref), + ok. + +%%------------------------------------------------------------------------- + +api_missuse(doc)-> + ["Test that behaviour of the control process if the api is abused"]; +api_missuse(suite) -> []; +api_missuse(Config) when is_list(Config)-> + + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []), + %% Serious programming fault, connetion will be shut down + gen_server:call(Ref, {self(), foobar, 10}, infinity), + test_server:sleep(10), + undefined = process_info(Ref, status), + + {ok, Ref2} = odbc:connect(?RDBMS:connection_string(), []), + %% Serious programming fault, connetion will be shut down + gen_server:cast(Ref2, {self(), foobar, 10}), + test_server:sleep(10), + undefined = process_info(Ref2, status), + + {ok, Ref3} = odbc:connect(?RDBMS:connection_string(), []), + %% Could be an innocent misstake the connection lives. + Ref3 ! foobar, + test_server:sleep(10), + {status, _} = process_info(Ref3, status), + ok. + diff --git a/lib/odbc/test/odbc_data_type_SUITE.erl b/lib/odbc/test/odbc_data_type_SUITE.erl new file mode 100644 index 0000000000..7d4a0ca15f --- /dev/null +++ b/lib/odbc/test/odbc_data_type_SUITE.erl @@ -0,0 +1,1498 @@ +%% +%% %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% +%% + +%% + +-module(odbc_data_type_SUITE). + +%% Note: This directive should only be used in test suites. +-compile(export_all). + +-include("test_server.hrl"). +-include_lib("stdlib/include/ms_transform.hrl"). +-include("test_server_line.hrl"). +-include("odbc_test.hrl"). + +%%-------------------------------------------------------------------- +%% all(Arg) -> [Doc] | [Case] | {skip, Comment} +%% Arg - doc | suite +%% Doc - string() +%% Case - atom() +%% Name of a test case function. +%% Comment - string() +%% Description: Returns documentation/test cases in this test suite +%% or a skip tuple if the platform is not supported. +%%-------------------------------------------------------------------- +all(doc) -> + ["Tests data types"]; +all(suite) -> + case odbc_test_lib:odbc_check() of + ok -> all(); + Other -> {skip,Other} + end. + +all() -> + [char, int, floats, dec_and_num, timestamp]. + +%%-------------------------------------------------------------------- +%% Function: init_per_suite(Config) -> Config +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Initiation before the whole suite +%% +%% Note: This function is free to add any key/value pairs to the Config +%% variable, but should NOT alter/remove any existing entries. +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + application:start(odbc), + [{tableName, odbc_test_lib:unique_table_name()} | Config]. + +%%-------------------------------------------------------------------- +%% Function: end_per_suite(Config) -> _ +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Cleanup after the whole suite +%%-------------------------------------------------------------------- +end_per_suite(_Config) -> + application:stop(odbc), + ok. + +%%-------------------------------------------------------------------- +%% Function: init_per_testcase(Case, Config) -> Config +%% Case - atom() +%% Name of the test case that is about to be run. +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% +%% Description: Initiation before each test case +%% +%% Note: This function is free to add any key/value pairs to the Config +%% variable, but should NOT alter/remove any existing entries. +%%-------------------------------------------------------------------- +init_per_testcase(Case, Config) -> + case atom_to_list(Case) of + "binary" ++ _ -> + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), + [{binary_strings, on}]); + "unicode" -> + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), + [{binary_strings, on}]); + _ -> + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []) + end, + Dog = test_server:timetrap(?default_timeout), + Temp = lists:keydelete(connection_ref, 1, Config), + NewConfig = lists:keydelete(watchdog, 1, Temp), + [{watchdog, Dog}, {connection_ref, Ref} | NewConfig]. + +%%-------------------------------------------------------------------- +%% Function: end_per_testcase(Case, Config) -> _ +%% Case - atom() +%% Name of the test case that is about to be run. +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Cleanup after each test case +%%-------------------------------------------------------------------- +end_per_testcase(_TestCase, Config) -> + Ref = ?config(connection_ref, Config), + ok = odbc:disconnect(Ref), + %% Clean up if needed + Table = ?config(tableName, Config), + {ok, NewRef} = odbc:connect(?RDBMS:connection_string(), []), + odbc:sql_query(NewRef, "DROP TABLE " ++ Table), + odbc:disconnect(NewRef), + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +%%------------------------------------------------------------------------- +%% Test cases starts here. +%%------------------------------------------------------------------------- +char(doc) -> + ["Tests char data types"]; + +char(suite) -> + [char_fixed_lower_limit, char_fixed_upper_limit, + char_fixed_padding, varchar_lower_limit, varchar_upper_limit, + varchar_no_padding, text_lower_limit, text_upper_limit, unicode + ]. + +char_fixed_lower_limit(doc) -> + ["Tests fixed length char data type lower boundaries."]; +char_fixed_lower_limit(suite) -> + []; +char_fixed_lower_limit(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + %% Below limit + {error, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + ?RDBMS:create_fixed_char_table( + (?RDBMS:fixed_char_min() - 1))), + %% Lower limit + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_fixed_char_table( + ?RDBMS:fixed_char_min())), + + %% Right length data + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ string:chars($a, ?RDBMS:fixed_char_min()) + ++ "')"), + %% Select data + {selected, Fields,[{"a"}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + + ["FIELD"] = odbc_test_lib:to_upper(Fields), + + %% Too long data + {error, _} = + odbc:sql_query(Ref,"INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ string:chars($a, + (?RDBMS:fixed_char_min() + + 1)) + ++ "')"), + ok. +%%------------------------------------------------------------------------- + +char_fixed_upper_limit(doc) -> + ["Tests fixed length char data type upper boundaries."]; +char_fixed_upper_limit(suite) -> + []; +char_fixed_upper_limit(Config) when is_list(Config) -> + + case ?RDBMS of + postgres -> + {skip, "Limit unknown"}; + _ -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + %% Upper limit + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_fixed_char_table( + ?RDBMS:fixed_char_max())), + {updated, _} = + odbc:sql_query(Ref,"INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ string:chars($a, + ?RDBMS:fixed_char_max()) + ++ "')"), + %% Select data + {selected, Fields, [{CharStr}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + true = length(CharStr) == ?RDBMS:fixed_char_max(), + + ["FIELD"] = odbc_test_lib:to_upper(Fields), + + %% Too long data + {error, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ string:chars($a, + (?RDBMS:fixed_char_max() + + 1)) + ++ "')"), + %% Clean up + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "DROP TABLE " ++ Table), + + %% Above limit + {error, _} = + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_fixed_char_table( + (?RDBMS:fixed_char_max() + 1))), + ok + end. + +%%------------------------------------------------------------------------- + +char_fixed_padding(doc) -> + ["Tests that data that is shorter than the given size is padded " + "with blanks."]; +char_fixed_padding(suite) -> + []; +char_fixed_padding(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + %% Data should be padded with blanks + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_fixed_char_table( + ?RDBMS:fixed_char_max())), + + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ string:chars($a, + ?RDBMS:fixed_char_min()) + ++ "')"), + + {selected, Fields, [{CharStr}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + true = length(CharStr) == ?RDBMS:fixed_char_max(), + ["FIELD"] = odbc_test_lib:to_upper(Fields), + ok. +%%------------------------------------------------------------------------- + +varchar_lower_limit(doc) -> + ["Tests variable length char data type lower boundaries."]; +varchar_lower_limit(suite) -> + []; +varchar_lower_limit(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + %% Below limit + {error, _} = + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_var_char_table( + ?RDBMS:var_char_min() - 1)), + %% Lower limit + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_var_char_table( + ?RDBMS:var_char_min())), + + %% Right length data + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ string:chars($a, ?RDBMS:var_char_min()) + ++ "')"), + %% Select data + {selected, Fields, [{"a"}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + + ["FIELD"] = odbc_test_lib:to_upper(Fields), + + %% Too long data + {error, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ string:chars($a, + (?RDBMS:var_char_min()+1)) + ++ "')"), + ok. + +%%------------------------------------------------------------------------- + +varchar_upper_limit(doc) -> + ["Tests variable length char data type upper boundaries."]; +varchar_upper_limit(suite) -> + []; +varchar_upper_limit(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + case ?RDBMS of + oracle -> + {skip, "Known bug in database"}; + postgres -> + {skip, "Limit unknown"}; + _ -> + %% Upper limit + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_var_char_table( + ?RDBMS:var_char_max())), + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ string:chars($a, + ?RDBMS:var_char_max()) + ++ "')"), + + {selected, Fields, [{CharStr}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + true = length(CharStr) == ?RDBMS:var_char_max(), + + ["FIELD"] = odbc_test_lib:to_upper(Fields), + + %% Too long data + {error, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ string:chars($a, + (?RDBMS:var_char_max()+1)) + ++ "')"), + %% Clean up + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "DROP TABLE " ++ Table), + + %% Above limit + {error, _} = + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_var_char_table( + (?RDBMS:var_char_max() + 1))), + ok + end. +%%------------------------------------------------------------------------- + +varchar_no_padding(doc) -> + ["Tests that data that is shorter than the given max size is not padded " + "with blanks."]; +varchar_no_padding(suite) -> + []; +varchar_no_padding(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + %% Data should NOT be padded with blanks + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_var_char_table( + ?RDBMS:var_char_max())), + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ string:chars($a, ?RDBMS:var_char_min()) + ++ "')"), + + {selected, Fields, [{CharStr}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + true = length(CharStr) /= ?RDBMS:var_char_max(), + ["FIELD"] = odbc_test_lib:to_upper(Fields), + ok. + +%%------------------------------------------------------------------------- + +text_lower_limit(doc) -> + ["Tests 'long' char data type lower boundaries."]; +text_lower_limit(suite) -> + []; +text_lower_limit(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_text_table()), + + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ string:chars($a, ?RDBMS:text_min()) + ++ "')"), + + {selected, Fields, [{"a"}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + ["FIELD"] = odbc_test_lib:to_upper(Fields), + ok. + +%%------------------------------------------------------------------------- + +text_upper_limit(doc) -> + []; +text_upper_limit(suite) -> + []; +text_upper_limit(Config) when is_list(Config) -> + + {skip,"Consumes too much resources" }. +%% Ref = ?config(connection_ref, Config), +%% Table = ?config(tableName, Config), + +%% {updated, _} = % Value == 0 || -1 driver dependent! +%% odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ +%% ?RDBMS:create_text_table()), +%% {updated, _} = +%% odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ +%% "'" ++ string:chars($a, ?RDBMS:text_max()) +%% ++ "')"), + +%% {selected, Fields, [{CharStr}]} = +%% odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), +%% length(CharStr) == ?RDBMS:text_max(), +%% ["FIELD"] = odbc_test_lib:to_upper(Fields), + +%% {error, _} = +%% odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ +%% "'" ++ string:chars($a, (?RDBMS:text_max()+1)) +%% ++ "')"), +%% ok. + +%%------------------------------------------------------------------------- +binary_char(doc) -> + ["Tests char data types returned as erlang binaries"]; + +binary_char(suite) -> + [binary_char_fixed_lower_limit, binary_char_fixed_upper_limit, + binary_char_fixed_padding, binary_varchar_lower_limit, binary_varchar_upper_limit, + binary_varchar_no_padding, binary_text_lower_limit, binary_text_upper_limit, unicode + ]. + +binary_char_fixed_lower_limit(doc) -> + ["Tests fixed length char data type lower boundaries."]; +binary_char_fixed_lower_limit(suite) -> + []; +binary_char_fixed_lower_limit(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + %% Below limit + {error, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + ?RDBMS:create_fixed_char_table( + (?RDBMS:fixed_char_min() - 1))), + %% Lower limit + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_fixed_char_table( + ?RDBMS:fixed_char_min())), + + %% Right length data + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ string:chars($a, ?RDBMS:fixed_char_min()) + ++ "')"), + %% Select data + {selected, Fields,[{<<"a">>}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + + ["FIELD"] = odbc_test_lib:to_upper(Fields), + + %% Too long data + {error, _} = + odbc:sql_query(Ref,"INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ string:chars($a, + (?RDBMS:fixed_char_min() + + 1)) + ++ "')"), + ok. +%%------------------------------------------------------------------------- + +binary_char_fixed_upper_limit(doc) -> + ["Tests fixed length char data type upper boundaries."]; +binary_char_fixed_upper_limit(suite) -> + []; +binary_char_fixed_upper_limit(Config) when is_list(Config) -> + + case ?RDBMS of + postgres -> + {skip, "Limit unknown"}; + _ -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + %% Upper limit + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_fixed_char_table( + ?RDBMS:fixed_char_max())), + {updated, _} = + odbc:sql_query(Ref,"INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ string:chars($a, + ?RDBMS:fixed_char_max()) + ++ "')"), + %% Select data + {selected, Fields, [{CharBin}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + true = size(CharBin) == ?RDBMS:fixed_char_max(), + + ["FIELD"] = odbc_test_lib:to_upper(Fields), + + %% Too long data + {error, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ string:chars($a, + (?RDBMS:fixed_char_max() + + 1)) + ++ "')"), + %% Clean up + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "DROP TABLE " ++ Table), + + %% Above limit + {error, _} = + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_fixed_char_table( + (?RDBMS:fixed_char_max() + 1))), + ok + end. + +%%------------------------------------------------------------------------- + +binary_char_fixed_padding(doc) -> + ["Tests that data that is shorter than the given size is padded " + "with blanks."]; +binary_char_fixed_padding(suite) -> + []; +binary_char_fixed_padding(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + %% Data should be padded with blanks + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_fixed_char_table( + ?RDBMS:fixed_char_max())), + + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ string:chars($a, + ?RDBMS:fixed_char_min()) + ++ "')"), + + {selected, Fields, [{CharBin}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + true = size(CharBin) == ?RDBMS:fixed_char_max(), + ["FIELD"] = odbc_test_lib:to_upper(Fields), + ok. +%%------------------------------------------------------------------------- + +binary_varchar_lower_limit(doc) -> + ["Tests variable length char data type lower boundaries."]; +binary_varchar_lower_limit(suite) -> + []; +binary_varchar_lower_limit(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + %% Below limit + {error, _} = + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_var_char_table( + ?RDBMS:var_char_min() - 1)), + %% Lower limit + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_var_char_table( + ?RDBMS:var_char_min())), + + %% Right length data + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ string:chars($a, ?RDBMS:var_char_min()) + ++ "')"), + %% Select data + {selected, Fields, [{<<"a">>}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + + ["FIELD"] = odbc_test_lib:to_upper(Fields), + + %% Too long data + {error, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ string:chars($a, + (?RDBMS:var_char_min()+1)) + ++ "')"), + ok. + +%%------------------------------------------------------------------------- + +binary_varchar_upper_limit(doc) -> + ["Tests variable length char data type upper boundaries."]; +binary_varchar_upper_limit(suite) -> + []; +binary_varchar_upper_limit(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + case ?RDBMS of + oracle -> + {skip, "Known bug in database"}; + postgres -> + {skip, "Limit unknown"}; + _ -> + %% Upper limit + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_var_char_table( + ?RDBMS:var_char_max())), + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ string:chars($a, + ?RDBMS:var_char_max()) + ++ "')"), + + {selected, Fields, [{CharBin}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + true = size(CharBin) == ?RDBMS:var_char_max(), + + ["FIELD"] = odbc_test_lib:to_upper(Fields), + + %% Too long data + {error, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ string:chars($a, + (?RDBMS:var_char_max()+1)) + ++ "')"), + %% Clean up + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "DROP TABLE " ++ Table), + + %% Above limit + {error, _} = + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_var_char_table( + (?RDBMS:var_char_max() + 1))), + ok + end. +%%------------------------------------------------------------------------- + +binary_varchar_no_padding(doc) -> + ["Tests that data that is shorter than the given max size is not padded " + "with blanks."]; +binary_varchar_no_padding(suite) -> + []; +binary_varchar_no_padding(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + %% Data should NOT be padded with blanks + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_var_char_table( + ?RDBMS:var_char_max())), + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ string:chars($a, ?RDBMS:var_char_min()) + ++ "')"), + + {selected, Fields, [{CharBin}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + true = size(CharBin) /= ?RDBMS:var_char_max(), + ["FIELD"] = odbc_test_lib:to_upper(Fields), + ok. + +%%------------------------------------------------------------------------- + +binary_text_lower_limit(doc) -> + ["Tests 'long' char data type lower boundaries."]; +binary_text_lower_limit(suite) -> + []; +binary_text_lower_limit(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_text_table()), + + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ string:chars($a, ?RDBMS:text_min()) + ++ "')"), + + {selected, Fields, [{<<"a">>}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + ["FIELD"] = odbc_test_lib:to_upper(Fields), + ok. + +%%------------------------------------------------------------------------- + +binary_text_upper_limit(doc) -> + []; +binary_text_upper_limit(suite) -> + []; +binary_text_upper_limit(Config) when is_list(Config) -> + + {skip,"Consumes too much resources" }. +%% Ref = ?config(connection_ref, Config), +%% Table = ?config(tableName, Config), + +%% {updated, _} = % Value == 0 || -1 driver dependent! +%% odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ +%% ?RDBMS:create_text_table()), +%% {updated, _} = +%% odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ +%% "'" ++ string:chars($a, ?RDBMS:text_max()) +%% ++ "')"), + +%% {selected, Fields, [{CharBin}]} = +%% odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), +%% size(CharBin) == ?RDBMS:text_max(), +%% ["FIELD"] = odbc_test_lib:to_upper(Fields), + +%% {error, _} = +%% odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ +%% "'" ++ string:chars($a, (?RDBMS:text_max()+1)) +%% ++ "')"), +%% ok. + + +%%------------------------------------------------------------------------- + +int(doc) -> + ["Tests integer data types"]; + +int(suite) -> + [tiny_int_lower_limit, tiny_int_upper_limit, small_int_lower_limit, + small_int_upper_limit, int_lower_limit, int_upper_limit, + big_int_lower_limit, big_int_upper_limit, bit_false, bit_true]. + +%%------------------------------------------------------------------------- + +tiny_int_lower_limit(doc) -> + ["Tests integer of type tinyint."]; +tiny_int_lower_limit(suite) -> + []; +tiny_int_lower_limit(Config) when is_list(Config) -> + case ?RDBMS of + postgres -> + {skip, "Type tiniyint not supported"}; + _ -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_tiny_int_table()), + + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ integer_to_list(?RDBMS:tiny_int_min()) + ++ "')"), + + SelectResult = ?RDBMS:tiny_int_min_selected(), + SelectResult = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + + {error, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ integer_to_list(?RDBMS:tiny_int_min() + - 1) + ++ "')"), + ok + end. + +%%------------------------------------------------------------------------- + +tiny_int_upper_limit(doc) -> + ["Tests integer of type tinyint."]; +tiny_int_upper_limit(suite) -> + []; +tiny_int_upper_limit(Config) when is_list(Config) -> + case ?RDBMS of + postgres -> + {skip, "Type tiniyint not supported"}; + _ -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_tiny_int_table()), + + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ integer_to_list(?RDBMS:tiny_int_max()) + ++ "')"), + + SelectResult = ?RDBMS:tiny_int_max_selected(), + SelectResult = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + + {error, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ integer_to_list(?RDBMS:tiny_int_max() + + 1) + ++ "')"), + ok + end. + +%%------------------------------------------------------------------------- + +small_int_lower_limit(doc) -> + ["Tests integer of type smallint."]; +small_int_lower_limit(suite) -> + []; +small_int_lower_limit(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_small_int_table()), + + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ integer_to_list(?RDBMS:small_int_min()) + ++ "')"), + + SelectResult = ?RDBMS:small_int_min_selected(), + SelectResult = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + + {error, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ integer_to_list(?RDBMS:small_int_min() + - 1) + ++ "')"), + ok. + +%%------------------------------------------------------------------------- + +small_int_upper_limit(doc) -> + ["Tests integer of type smallint."]; +small_int_upper_limit(suite) -> + []; +small_int_upper_limit(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_small_int_table()), + + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ integer_to_list(?RDBMS:small_int_max()) + ++ "')"), + + SelectResult = ?RDBMS:small_int_max_selected(), + SelectResult = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + + {error, _} = + odbc:sql_query(Ref,"INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ integer_to_list(?RDBMS:small_int_max() + + 1) + ++ "')"), + ok. + +%%------------------------------------------------------------------------- +int_lower_limit(doc) -> + ["Tests integer of type int."]; +int_lower_limit(suite) -> + []; +int_lower_limit(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_int_table()), + + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ integer_to_list(?RDBMS:int_min()) + ++ "')"), + + SelectResult = ?RDBMS:int_min_selected(), + SelectResult = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + + {error, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ integer_to_list(?RDBMS:int_min() - 1) + ++ "')"), + ok. + +%%------------------------------------------------------------------------- + +int_upper_limit(doc) -> + ["Tests integer of type int."]; +int_upper_limit(suite) -> + []; +int_upper_limit(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_int_table()), + + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ integer_to_list(?RDBMS:int_max()) + ++ "')"), + + SelectResult = ?RDBMS:int_max_selected(), + SelectResult = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + + {error, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ integer_to_list(?RDBMS:int_max() + 1) + ++ "')"), + ok. + + +%%------------------------------------------------------------------------- +big_int_lower_limit(doc) -> + ["Tests integer of type bigint"]; +big_int_lower_limit(suite) -> + []; +big_int_lower_limit(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_big_int_table()), + + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ integer_to_list(?RDBMS:big_int_min()) + ++ "')"), + + SelectResult = ?RDBMS:big_int_min_selected(), + SelectResult = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + + {error, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ integer_to_list(?RDBMS:big_int_min() + - 1) + ++ "')"), + ok. + +%%------------------------------------------------------------------------- + +big_int_upper_limit(doc) -> + ["Tests integer of type bigint."]; +big_int_upper_limit(suite) -> + []; +big_int_upper_limit(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_big_int_table()), + + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ integer_to_list(?RDBMS:big_int_max()) + ++ "')"), + + SelectResult = ?RDBMS:big_int_max_selected(), + SelectResult = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + + {error, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ integer_to_list(?RDBMS:big_int_max() + + 1) + ++ "')"), + ok. +%%------------------------------------------------------------------------- + +bit_false(doc) -> + [""]; +bit_false(suite) -> + []; +bit_false(Config) when is_list(Config) -> + case ?RDBMS of + oracle -> + {skip, "Not supported by driver"}; + _ -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_bit_table()), + + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(" ++ + "'" ++ integer_to_list(?RDBMS:bit_false()) + ++ "')"), + + SelectResult = ?RDBMS:bit_false_selected(), + SelectResult = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + + {error, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ integer_to_list(-1) + ++ "')"), + ok + end. + +%%------------------------------------------------------------------------- + +bit_true(doc) -> + [""]; +bit_true(suite) -> + []; +bit_true(Config) when is_list(Config) -> + case ?RDBMS of + oracle -> + {skip, "Not supported by driver"}; + _ -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_bit_table()), + + {updated, _} = + odbc:sql_query(Ref, + "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ integer_to_list(?RDBMS:bit_true()) + ++ "')"), + + SelectResult = ?RDBMS:bit_true_selected(), + SelectResult = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + + {error, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ integer_to_list(-1) + ++ "')"), + ok + end. + +%%------------------------------------------------------------------------- + +floats(doc) -> + ["Test the datatype float."]; +floats(suite) -> + [float_lower_limit, float_upper_limit, float_zero, real_zero]. + +%%------------------------------------------------------------------------- +float_lower_limit(doc) -> + [""]; +float_lower_limit(suite) -> + []; +float_lower_limit(Config) when is_list(Config) -> + + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_float_table()), + + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ float_to_list( + ?RDBMS:float_min()) + ++ "')"), + {selected,[_ColName],[{MinFloat}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + + true = ?RDBMS:float_min() == MinFloat, + + case ?RDBMS of + oracle -> + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "DROP TABLE " ++ Table), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_float_table()), + + {updated, _} = + odbc:sql_query(Ref, + "INSERT INTO " ++ Table ++" VALUES(" ++ + ?RDBMS:float_underflow() ++ ")"), + + SelectResult = ?RDBMS:float_zero_selected(), + SelectResult = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table); + _ -> + {error, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + ?RDBMS:float_underflow() ++ ")") + end, + ok. + + +%%------------------------------------------------------------------------- +float_upper_limit(doc) -> + [""]; +float_upper_limit(suite) -> + []; +float_upper_limit(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_float_table()), + + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + "'" ++ float_to_list( + ?RDBMS:float_max()) + ++ "')"), + + + {selected,[_ColName],[{MaxFloat}]} + = odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + + true = ?RDBMS:float_max() == MaxFloat, + + {error, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++ + ?RDBMS:float_overflow() ++ ")"), + ok. + +%%------------------------------------------------------------------------- +float_zero(doc) -> + ["Test the float value zero."]; +float_zero(suite) -> + []; +float_zero(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_float_table()), + + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES('0')"), + + SelectResult = ?RDBMS:float_zero_selected(), + SelectResult = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + ok. +%%------------------------------------------------------------------------- +real_zero(doc) -> + ["Test the real value zero."]; +real_zero(suite) -> + []; +real_zero(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + case ?RDBMS of + oracle -> + {skip, "Not supported in Oracle"}; + _ -> + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_real_table()), + + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES('0')"), + + SelectResult = ?RDBMS:real_zero_selected(), + SelectResult = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + ok + end. +%%------------------------------------------------------------------------- +dec_and_num(doc) -> + ["Tests decimal and numeric datatypes."]; +dec_and_num(suite) -> + [dec_long, dec_double, dec_bignum, num_long, num_double, num_bignum]. +%%------------------------------------------------------------------------ +dec_long(doc) -> + [""]; +dec_long(suit) -> + []; +dec_long(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + "(FIELD DECIMAL (9,0))"), + + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1.6)"), + + {selected, Fields, [{2}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + ["FIELD"] = odbc_test_lib:to_upper(Fields), + ok. +%%------------------------------------------------------------------------ +dec_double(doc) -> + [""]; +dec_double(suit) -> + []; +dec_double(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + "(FIELD DECIMAL (10,0))"), + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1.6)"), + + {selected, Fields, [{2.00000}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + ["FIELD"] = odbc_test_lib:to_upper(Fields), + + %% Clean up + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "DROP TABLE " ++ Table), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + "(FIELD DECIMAL (15,0))"), + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1.6)"), + + {selected, Fields1, [{2.00000}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + ["FIELD"] = odbc_test_lib:to_upper(Fields1), + + %% Clean up + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "DROP TABLE " ++ Table), + + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + "(FIELD DECIMAL (15, 1))"), + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1.6)"), + + {selected, Fields2, [{1.60000}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + ["FIELD"] = odbc_test_lib:to_upper(Fields2), + ok. + +%%------------------------------------------------------------------------ +dec_bignum(doc) -> + [""]; +dec_bignum(suit) -> + []; +dec_bignum(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + "(FIELD DECIMAL (16,0))"), + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1.6)"), + + {selected, Fields, [{"2"}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + ["FIELD"] = odbc_test_lib:to_upper(Fields), + + %% Clean up + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "DROP TABLE " ++ Table), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + "(FIELD DECIMAL (16,1))"), + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1.6)"), + + {selected, Fields1, [{"1.6"}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + ["FIELD"] = odbc_test_lib:to_upper(Fields1), + ok. +%%------------------------------------------------------------------------ +num_long(doc) -> + [""]; +num_long(suit) -> + []; +num_long(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + "(FIELD DECIMAL (9,0))"), + + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1.5)"), + + {selected, Fields, [{2}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + ["FIELD"] = odbc_test_lib:to_upper(Fields), + ok. +%%------------------------------------------------------------------------ +num_double(doc) -> + [""]; +num_double(suit) -> + []; +num_double(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + "(FIELD DECIMAL (10,0))"), + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1.6)"), + + {selected, Fields, [{2.0000}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + ["FIELD"] = odbc_test_lib:to_upper(Fields), + + %% Clean up + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "DROP TABLE " ++ Table), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + "(FIELD DECIMAL (15,0))"), + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1.6)"), + + {selected, Fields1, [{2.0000}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + ["FIELD"] = odbc_test_lib:to_upper(Fields1), + + %% Clean up + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "DROP TABLE " ++ Table), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + "(FIELD DECIMAL (15,1))"), + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1.6)"), + + {selected, Fields2, [{1.6000}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + ["FIELD"] = odbc_test_lib:to_upper(Fields2), + ok. +%%------------------------------------------------------------------------ +num_bignum(doc) -> + [""]; +num_bignum(suit) -> + []; +num_bignum(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + "(FIELD DECIMAL (16,0))"), + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1.6)"), + + {selected, Fields, [{"2"}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + ["FIELD"] = odbc_test_lib:to_upper(Fields), + + %% Clean up + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "DROP TABLE " ++ Table), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + "(FIELD DECIMAL (16,1))"), + {updated, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1.6)"), + + {selected, Fields1, [{"1.6"}]} = + odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table), + ["FIELD"] = odbc_test_lib:to_upper(Fields1), + ok. + +%%------------------------------------------------------------------------ +unicode(doc) -> + ["Test unicode support"]; +unicode(suit) -> + []; +unicode(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_unicode_table()), + + Latin1Data = ["���������", + "testasdf", + "Row 3", + "Row 4", + "Row 5", + "Row 6", + "Row 7", + "Row 8", + "Row 9", + "Row 10", + "Row 11", + "Row 12"], + + case ?RDBMS of + sqlserver -> + w_char_support_win(Ref, Table, Latin1Data); + postgres -> + direct_utf8(Ref, Table, Latin1Data); + oracle -> + {skip, "not currently supported"} + end. + +w_char_support_win(Ref, Table, Latin1Data) -> + UnicodeIn = lists:map(fun(S) -> + unicode:characters_to_binary(S,latin1,{utf16,little}) + end, + Latin1Data), + + test_server:format("UnicodeIn (utf 16): ~p ~n",[UnicodeIn]), + + {updated, _} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ "(FIELD) values(?)", + [{{sql_wvarchar,50},UnicodeIn}]), + + {selected,_,UnicodeOut} = odbc:sql_query(Ref,"SELECT * FROM " ++ Table), + + test_server:format("UnicodeOut: ~p~n", [UnicodeOut]), + + Result = lists:map(fun({Unicode}) -> + unicode:characters_to_list(Unicode,{utf16,little}) + end, + UnicodeOut), + Latin1Data = Result. + + +direct_utf8(Ref, Table, Latin1Data) -> + UnicodeIn = lists:map(fun(String) -> + unicode:characters_to_binary(String,latin1,utf8) + end, + Latin1Data), + + test_server:format("UnicodeIn: ~p ~n",[UnicodeIn]), + {updated, _} = odbc:param_query(Ref,"INSERT INTO " ++ Table ++ "(FIELD) values(?)", + [{{sql_varchar,50}, UnicodeIn}]), + + {selected,_,UnicodeOut} = odbc:sql_query(Ref,"SELECT * FROM " ++ Table), + + test_server:format("UnicodeOut: ~p~n", [UnicodeOut]), + + Result = lists:map(fun({Char}) -> + unicode:characters_to_list(Char,utf8) + end, UnicodeOut), + + test_server:format("Result: ~p ~n", [Result]), + + Latin1Data = Result. + +%%------------------------------------------------------------------------ +timestamp(doc) -> + [""]; +timestamp(suit) -> + []; +timestamp(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_timestamp_table()), + + Data = [calendar:local_time(), + {{2009,6,17},{20,54,59}}, + {{2009,6,18},{20,54,59}}, + {{2009,6,19},{20,54,59}}, + {{2009,6,20},{20,54,59}}, + {{2009,6,21},{20,54,59}}], + + {updated, _} = odbc:param_query(Ref,"INSERT INTO " ++ Table ++ "(FIELD) values(?)", + [{sql_timestamp,Data}]), + + %%% Crate list or database table rows + TimeStamps = lists:map(fun(Value) -> {Value} end, Data), + + {selected,_, TimeStamps} = odbc:sql_query(Ref, "SELECT * FROM " ++ Table). diff --git a/lib/odbc/test/odbc_query_SUITE.erl b/lib/odbc/test/odbc_query_SUITE.erl new file mode 100644 index 0000000000..12b39be3b7 --- /dev/null +++ b/lib/odbc/test/odbc_query_SUITE.erl @@ -0,0 +1,1453 @@ +%% +%% %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% +%% + +%% + +-module(odbc_query_SUITE). + +%% Note: This directive should only be used in test suites. +-compile(export_all). + +-include("test_server.hrl"). +-include("test_server_line.hrl"). +-include("odbc_test.hrl"). + +%%-------------------------------------------------------------------- +%% all(Arg) -> [Doc] | [Case] | {skip, Comment} +%% Arg - doc | suite +%% Doc - string() +%% Case - atom() +%% Name of a test case function. +%% Comment - string() +%% Description: Returns documentation/test cases in this test suite +%% or a skip tuple if the platform is not supported. +%%-------------------------------------------------------------------- +all(doc) -> + ["Tests SQL queries"]; +all(suite) -> + case odbc_test_lib:odbc_check() of + ok -> all(); + Other -> {skip, Other} + end. + +all() -> + [sql_query, first, last, next, prev, select_count,select_next, + select_relative, select_absolute, create_table_twice, + delete_table_twice, duplicate_key, not_connection_owner, + no_result_set, query_error, multiple_select_result_sets, + multiple_mix_result_sets, multiple_result_sets_error, + parameterized_queries, describe_table, + delete_nonexisting_row]. + + +%%-------------------------------------------------------------------- +%% Function: init_per_suite(Config) -> Config +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Initiation before the whole suite +%% +%% Note: This function is free to add any key/value pairs to the Config +%% variable, but should NOT alter/remove any existing entries. +%%-------------------------------------------------------------------- +init_per_suite(Config) when is_list(Config) -> + application:start(odbc), + [{tableName, odbc_test_lib:unique_table_name()}| Config]. + +%%-------------------------------------------------------------------- +%% Function: end_per_suite(Config) -> _ +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Cleanup after the whole suite +%%-------------------------------------------------------------------- +end_per_suite(_Config) -> + application:stop(odbc), + ok. + +%%-------------------------------------------------------------------- +%% Function: init_per_testcase(Case, Config) -> Config +%% Case - atom() +%% Name of the test case that is about to be run. +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% +%% Description: Initiation before each test case +%% +%% Note: This function is free to add any key/value pairs to the Config +%% variable, but should NOT alter/remove any existing entries. +%%-------------------------------------------------------------------- +init_per_testcase(_Case, Config) -> + {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []), + Dog = test_server:timetrap(?default_timeout), + Temp = lists:keydelete(connection_ref, 1, Config), + NewConfig = lists:keydelete(watchdog, 1, Temp), + [{watchdog, Dog}, {connection_ref, Ref} | NewConfig]. + +%%-------------------------------------------------------------------- +%% Function: end_per_testcase(Case, Config) -> _ +%% Case - atom() +%% Name of the test case that is about to be run. +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Cleanup after each test case +%%-------------------------------------------------------------------- +end_per_testcase(_Case, Config) -> + Ref = ?config(connection_ref, Config), + ok = odbc:disconnect(Ref), + %% Clean up if needed + Table = ?config(tableName, Config), + {ok, NewRef} = odbc:connect(?RDBMS:connection_string(), []), + odbc:sql_query(NewRef, "DROP TABLE " ++ Table), + odbc:disconnect(NewRef), + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +%%------------------------------------------------------------------------- +%% Test cases starts here. +%%------------------------------------------------------------------------- +sql_query(doc)-> + ["Test the common cases"]; +sql_query(suite) -> []; +sql_query(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer, DATA varchar(10))"), + + {updated, Count} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"), + + true = odbc_test_lib:check_row_count(1, Count), + + InsertResult = ?RDBMS:insert_result(), + InsertResult = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + + {updated, NewCount} = + odbc:sql_query(Ref, "UPDATE " ++ Table ++ + " SET DATA = 'foo' WHERE ID = 1"), + + true = odbc_test_lib:check_row_count(1, NewCount), + + UpdateResult = ?RDBMS:update_result(), + UpdateResult = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + + {updated, NewCount1} = odbc:sql_query(Ref, "DELETE FROM " ++ Table ++ + " WHERE ID = 1"), + + true = odbc_test_lib:check_row_count(1, NewCount1), + + {selected, Fields, []} = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + + ["ID","DATA"] = odbc_test_lib:to_upper(Fields), + ok. + +%%------------------------------------------------------------------------- +select_count(doc) -> + ["Tests select_count/[2,3]'s timeout, " + " select_count's functionality will be better tested by other tests " + " such as first."]; +select_count(sute) -> []; +select_count(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer)"), + + {updated, Count} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(1)"), + true = odbc_test_lib:check_row_count(1, Count), + {ok, _} = + odbc:select_count(Ref, "SELECT * FROM " ++ Table, ?TIMEOUT), + {'EXIT', {function_clause, _}} = + (catch odbc:select_count(Ref, "SELECT * FROM ", -1)), + ok. +%%------------------------------------------------------------------------- +first(doc) -> + ["Tests first/[1,2]"]; +first(suite) -> []; +first(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer)"), + + {updated, Count} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(1)"), + true = odbc_test_lib:check_row_count(1, Count), + {updated, NewCount} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(2)"), + true = odbc_test_lib:check_row_count(1, NewCount), + {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table), + + + FirstResult = ?RDBMS:selected_ID(1, first), + FirstResult = odbc:first(Ref), + FirstResult = odbc:first(Ref, ?TIMEOUT), + {'EXIT', {function_clause, _}} = (catch odbc:first(Ref, -1)), + ok. + +%%------------------------------------------------------------------------- +last(doc) -> + ["Tests last/[1,2]"]; +last(suite) -> []; +last(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer)"), + + {updated, Count} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(1)"), + true = odbc_test_lib:check_row_count(1, Count), + {updated, NewCount} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(2)"), + true = odbc_test_lib:check_row_count(1, NewCount), + {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table), + + LastResult = ?RDBMS:selected_ID(2, last), + LastResult = odbc:last(Ref), + + LastResult = odbc:last(Ref, ?TIMEOUT), + {'EXIT', {function_clause, _}} = (catch odbc:last(Ref, -1)), + ok. + +%%------------------------------------------------------------------------- +next(doc) -> + ["Tests next/[1,2]"]; +next(suite) -> []; +next(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer)"), + + {updated, Count} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(1)"), + true = odbc_test_lib:check_row_count(1, Count), + {updated, NewCount} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(2)"), + true = odbc_test_lib:check_row_count(1, NewCount), + {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table), + + NextResult = ?RDBMS:selected_ID(1, next), + NextResult = odbc:next(Ref), + NextResult2 = ?RDBMS:selected_ID(2, next), + NextResult2 = odbc:next(Ref, ?TIMEOUT), + {'EXIT', {function_clause, _}} = (catch odbc:next(Ref, -1)), + ok. +%%------------------------------------------------------------------------- +prev(doc) -> + ["Tests prev/[1,2]"]; +prev(suite) -> []; +prev(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer)"), + + {updated, Count} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(1)"), + true = odbc_test_lib:check_row_count(1, Count), + {updated, NewCount} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(2)"), + true = odbc_test_lib:check_row_count(1, NewCount), + + {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table), + + odbc:last(Ref), % Position cursor last so there will be a prev + PrevResult = ?RDBMS:selected_ID(1, prev), + PrevResult = odbc:prev(Ref), + + odbc:last(Ref), % Position cursor last so there will be a prev + PrevResult = odbc:prev(Ref, ?TIMEOUT), + {'EXIT', {function_clause, _}} = (catch odbc:prev(Ref, -1)), + ok. +%%------------------------------------------------------------------------- +select_next(doc) -> + ["Tests select/[4,5] with CursorRelation = next "]; +select_next(suit) -> []; +select_next(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer)"), + + {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(1)"), + {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(2)"), + {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(3)"), + {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(4)"), + {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(5)"), + + {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table), + + SelectResult1 = ?RDBMS:selected_next_N(1), + SelectResult1 = odbc:select(Ref, next, 3), + + %% Test that selecting stops at the end of the result set + SelectResult2 = ?RDBMS:selected_next_N(2), + SelectResult2 = odbc:select(Ref, next, 3, ?TIMEOUT), + {'EXIT',{function_clause, _}} = + (catch odbc:select(Ref, next, 2, -1)), + + %% If you try fetching data beyond the the end of result set, + %% you get an empty list. + {selected, Fields, []} = odbc:select(Ref, next, 1), + + ["ID"] = odbc_test_lib:to_upper(Fields), + ok. + +%%------------------------------------------------------------------------- +select_relative(doc) -> + ["Tests select/[4,5] with CursorRelation = relative "]; +select_relative(suit) -> []; +select_relative(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer)"), + + {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(1)"), + {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(2)"), + {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(3)"), + {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(4)"), + {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(5)"), + {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(6)"), + {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(7)"), + {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(8)"), + + {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table), + + SelectResult1 = ?RDBMS:selected_relative_N(1), + SelectResult1 = odbc:select(Ref, {relative, 2}, 3), + + %% Test that selecting stops at the end of the result set + SelectResult2 = ?RDBMS:selected_relative_N(2), + SelectResult2 = odbc:select(Ref, {relative, 3}, 3, ?TIMEOUT), + {'EXIT',{function_clause, _}} = + (catch odbc:select(Ref, {relative, 3} , 2, -1)), + ok. + +%%------------------------------------------------------------------------- +select_absolute(doc) -> + ["Tests select/[4,5] with CursorRelation = absolute "]; +select_absolute(suit) -> []; +select_absolute(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer)"), + + {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(1)"), + {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(2)"), + {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(3)"), + {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(4)"), + {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(5)"), + {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table), + + SelectResult1 = ?RDBMS:selected_absolute_N(1), + SelectResult1 = odbc:select(Ref, {absolute, 1}, 3), + + %% Test that selecting stops at the end of the result set + SelectResult2 = ?RDBMS:selected_absolute_N(2), + SelectResult2 = odbc:select(Ref, {absolute, 1}, 6, ?TIMEOUT), + {'EXIT',{function_clause, _}} = + (catch odbc:select(Ref, {absolute, 1}, 2, -1)), + ok. + +%%------------------------------------------------------------------------- +create_table_twice(doc) -> + ["Test what happens if you try to create the same table twice."]; +create_table_twice(suite) -> []; +create_table_twice(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer, DATA varchar(10))"), + {error, Error} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer, DATA varchar(10))"), + is_driver_error(Error), + ok. + +%%------------------------------------------------------------------------- +delete_table_twice(doc) -> + ["Test what happens if you try to delete the same table twice."]; +delete_table_twice(suite) -> []; +delete_table_twice(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer, DATA varchar(10))"), + {updated, _} = odbc:sql_query(Ref, "DROP TABLE " ++ Table), + {error, Error} = odbc:sql_query(Ref, "DROP TABLE " ++ Table), + is_driver_error(Error), + ok. + +%------------------------------------------------------------------------- +duplicate_key(doc) -> + ["Test what happens if you try to use the same key twice"]; +duplicate_key(suit) -> []; +duplicate_key(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer, DATA char(10), PRIMARY KEY(ID))"), + + {updated, 1} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"), + + {error, Error} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'foo')"), + is_driver_error(Error), + ok. + +%%------------------------------------------------------------------------- +not_connection_owner(doc) -> + ["Test what happens if a process that did not start the connection" + " tries to acess it."]; +not_connection_owner(suite) -> []; +not_connection_owner(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + spawn_link(?MODULE, not_owner, [self(), Ref, Table]), + + receive + continue -> + ok + end. + +not_owner(Pid, Ref, Table) -> + {error, process_not_owner_of_odbc_connection} = + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ " (ID integer)"), + + {error, process_not_owner_of_odbc_connection} = + odbc:disconnect(Ref), + + Pid ! continue. + +%%------------------------------------------------------------------------- +no_result_set(doc) -> + ["Tests what happens if you try to use a function that needs an " + "associated result set when there is none."]; +no_result_set(suite) -> []; +no_result_set(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + + {error, result_set_does_not_exist} = odbc:first(Ref), + {error, result_set_does_not_exist} = odbc:last(Ref), + {error, result_set_does_not_exist} = odbc:next(Ref), + {error, result_set_does_not_exist} = odbc:prev(Ref), + {error, result_set_does_not_exist} = odbc:select(Ref, next, 1), + {error, result_set_does_not_exist} = + odbc:select(Ref, {absolute, 2}, 1), + {error, result_set_does_not_exist} = + odbc:select(Ref, {relative, 2}, 1), + ok. +%%------------------------------------------------------------------------- +query_error(doc) -> + ["Test what happens if there is an error in the query."]; +query_error(suite) -> + []; +query_error(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer, DATA char(10), PRIMARY KEY(ID))"), + {updated, 1} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"), + + {error, _} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"), + + {error, _} = + odbc:sql_query(Ref, "INSERT ONTO " ++ Table ++ " VALUES(1,'bar')"), + ok. + +%%------------------------------------------------------------------------- +multiple_select_result_sets(doc) -> + ["Test what happens if you have a batch of select queries."]; +multiple_select_result_sets(suite) -> + []; +multiple_select_result_sets(Config) when is_list(Config) -> + case ?RDBMS of + sqlserver -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer, DATA varchar(10), " + "PRIMARY KEY(ID))"), + {updated, 1} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(1,'bar')"), + + {updated, 1} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(2, 'foo')"), + + MultipleResult = ?RDBMS:multiple_select(), + + MultipleResult = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table ++ + "; SELECT DATA FROM "++ Table ++ + " WHERE ID=2"), + ok; + _ -> + {skip, "multiple result_set not supported"} + end. + +%%------------------------------------------------------------------------- +multiple_mix_result_sets(doc) -> + ["Test what happens if you have a batch of select and other type of" + " queries."]; +multiple_mix_result_sets(suite) -> + []; +multiple_mix_result_sets(Config) when is_list(Config) -> + case ?RDBMS of + sqlserver -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer, DATA varchar(10), " + "PRIMARY KEY(ID))"), + {updated, 1} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(1,'bar')"), + + MultipleResult = ?RDBMS:multiple_mix(), + + MultipleResult = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(2,'foo'); UPDATE " ++ Table ++ + " SET DATA = 'foobar' WHERE ID =1;SELECT " + "* FROM " + ++ Table ++ ";DELETE FROM " ++ Table ++ + " WHERE ID =1; SELECT DATA FROM " ++ Table), + ok; + _ -> + {skip, "multiple result_set not supported"} + end. +%%------------------------------------------------------------------------- +multiple_result_sets_error(doc) -> + ["Test what happens if one of the batched queries fails."]; +multiple_result_sets_error(suite) -> + []; +multiple_result_sets_error(Config) when is_list(Config) -> + case ?RDBMS of + sqlserver -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID integer, DATA varchar(10), " + "PRIMARY KEY(ID))"), + {updated, 1} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(1,'bar')"), + + {error, Error} = + odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ + " VALUES(1,'foo'); SELECT * FROM " ++ Table), + is_driver_error(Error), + + {error, NewError} = + odbc:sql_query(Ref, "SELECT * FROM " + ++ Table ++ ";INSERT INTO " ++ Table ++ + " VALUES(1,'foo')"), + is_driver_error(NewError), + ok; + _ -> + {skip, "multiple result_set not supported"} + end. + +%%------------------------------------------------------------------------- +parameterized_queries(doc)-> + ["Tests diffrent variants of parameterized queries."]; +parameterized_queries(suite) -> + %% Note timestamps are inserted with param_query in odbc_data_type_SUITE + %% so no need to test this again. + [param_integers, + param_insert_decimal, param_insert_numeric, + param_insert_string, + param_insert_float, param_insert_real, param_insert_double, + param_insert_mix, param_update, param_delete, param_select]. + +%%------------------------------------------------------------------------- +param_integers(doc)-> + ["Test insertion of integers by parameterized queries."]; +param_integers(suite) -> + [param_insert_tiny_int, + param_insert_small_int, param_insert_int, param_insert_integer]. +%%------------------------------------------------------------------------- +param_insert_tiny_int(doc)-> + ["Test insertion of tiny ints by parameterized queries."]; +param_insert_tiny_int(suite) -> + []; +param_insert_tiny_int(Config) when is_list(Config) -> + case ?RDBMS of + sqlserver -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (FIELD TINYINT)"), + + {updated, Count} = + odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{sql_tinyint, [1, 2]}], + ?TIMEOUT),%Make sure to test timeout clause + + true = odbc_test_lib:check_row_count(2, Count), + + InsertResult = ?RDBMS:param_select_tiny_int(), + + InsertResult = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + + {'EXIT',{badarg,odbc,param_query,'Params'}} = + (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{sql_tinyint, [1, "2"]}])), + ok; + _ -> + {skip, "Type tiniyint not supported"} + end. +%%------------------------------------------------------------------------- +param_insert_small_int(doc)-> + ["Test insertion of small ints by parameterized queries."]; +param_insert_small_int(suite) -> + []; +param_insert_small_int(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (FIELD SMALLINT)"), + + {updated, Count} = + odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", [{sql_smallint, [1, 2]}], + ?TIMEOUT), %% Make sure to test timeout clause + + true = odbc_test_lib:check_row_count(2, Count), + + InsertResult = ?RDBMS:param_select_small_int(), + + InsertResult = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + + {'EXIT',{badarg,odbc,param_query,'Params'}} = + (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{sql_smallint, [1, "2"]}])), + ok. + +%%------------------------------------------------------------------------- +param_insert_int(doc)-> + ["Test insertion of ints by parameterized queries."]; +param_insert_int(suite) -> + []; +param_insert_int(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (FIELD INT)"), + + Int = ?RDBMS:small_int_max() + 1, + + {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{sql_integer, [1, Int]}]), + true = odbc_test_lib:check_row_count(2, Count), + + InsertResult = ?RDBMS:param_select_int(), + + InsertResult = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + + {'EXIT',{badarg,odbc,param_query,'Params'}} = + (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{sql_integer, [1, "2"]}])), + ok. + +%%------------------------------------------------------------------------- +param_insert_integer(doc)-> + ["Test insertion of integers by parameterized queries."]; +param_insert_integer(suite) -> + []; +param_insert_integer(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (FIELD INTEGER)"), + + Int = ?RDBMS:small_int_max() + 1, + + {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{sql_integer, [1, Int]}]), + true = odbc_test_lib:check_row_count(2, Count), + + InsertResult = ?RDBMS:param_select_int(), + + InsertResult = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + + {'EXIT',{badarg,odbc,param_query,'Params'}} = + (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{sql_integer, [1, 2.3]}])), + ok. + +%%------------------------------------------------------------------------- +param_insert_decimal(doc)-> + ["Test insertion of decimal numbers by parameterized queries."]; +param_insert_decimal(suite) -> + []; +param_insert_decimal(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (FIELD DECIMAL (3,0))"), + + {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{{sql_decimal, 3, 0}, [1, 2]}]), + true = odbc_test_lib:check_row_count(2, Count), + + InsertResult = ?RDBMS:param_select_decimal(), + + InsertResult = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + + {'EXIT',{badarg,odbc,param_query,'Params'}} = + (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{{sql_decimal, 3, 0}, [1, "2"]}])), + + + odbc:sql_query(Ref, "DROP TABLE " ++ Table), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (FIELD DECIMAL (3,1))"), + + {updated, NewCount} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{{sql_decimal, 3, 1}, [0.25]}]), + true = odbc_test_lib:check_row_count(1, NewCount), + + {selected, Fields, [{Value}]} = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + + ["FIELD"] = odbc_test_lib:to_upper(Fields), + + odbc_test_lib:match_float(Value, 0.3, 0.01), + + ok. + +%%------------------------------------------------------------------------- +param_insert_numeric(doc)-> + ["Test insertion of numeric numbers by parameterized queries."]; +param_insert_numeric(suite) -> + []; +param_insert_numeric(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (FIELD NUMERIC (3,0))"), + + {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{{sql_numeric,3,0}, [1, 2]}]), + + true = odbc_test_lib:check_row_count(2, Count), + + InsertResult = ?RDBMS:param_select_numeric(), + + InsertResult = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + + {'EXIT',{badarg,odbc,param_query,'Params'}} = + (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{{sql_decimal, 3, 0}, [1, "2"]}])), + + odbc:sql_query(Ref, "DROP TABLE " ++ Table), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (FIELD NUMERIC (3,1))"), + + {updated, NewCount} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{{sql_numeric, 3, 1}, [0.25]}]), + + true = odbc_test_lib:check_row_count(1, NewCount), + + {selected, Fileds, [{Value}]} = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + + ["FIELD"] = odbc_test_lib:to_upper(Fileds), + + odbc_test_lib:match_float(Value, 0.3, 0.01), + ok. + +%%------------------------------------------------------------------------- +param_insert_string(doc) -> + ["Test insertion of strings by parameterized queries."]; +param_insert_string(suite) -> + [param_insert_char, param_insert_character, param_insert_char_varying, + param_insert_character_varying]. + +%%------------------------------------------------------------------------- +param_insert_char(doc)-> + ["Test insertion of fixed length string by parameterized queries."]; +param_insert_char(suite) -> + []; +param_insert_char(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (FIELD CHAR (10))"), + + {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{{sql_char, 10}, + ["foofoofoof", "0123456789"]}]), + true = odbc_test_lib:check_row_count(2, Count), + + {selected,Fileds,[{"foofoofoof"}, {"0123456789"}]} = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + + ["FIELD"] = odbc_test_lib:to_upper(Fileds), + + {error, _} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{{sql_char, 10}, + ["foo", "01234567890"]}]), + + {'EXIT',{badarg,odbc,param_query,'Params'}} = + (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{{sql_char, 10}, ["1", 2.3]}])), + ok. + +%%------------------------------------------------------------------------- +param_insert_character(doc)-> + ["Test insertion of fixed length string by parameterized queries."]; +param_insert_character(suite) -> + []; +param_insert_character(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (FIELD CHARACTER (10))"), + + {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{{sql_char, 10}, + ["foofoofoof", "0123456789"]}]), + + true = odbc_test_lib:check_row_count(2, Count), + + {selected, Fileds, [{"foofoofoof"}, {"0123456789"}]} = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + + ["FIELD"] = odbc_test_lib:to_upper(Fileds), + + {error, _} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{{sql_char, 10}, + ["foo", "01234567890"]}]), + + {'EXIT',{badarg,odbc,param_query,'Params'}} = + (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{{sql_char, 10}, ["1", 2]}])), + ok. + +%%------------------------------------------------------------------------ +param_insert_char_varying(doc)-> + ["Test insertion of variable length strings by parameterized queries."]; +param_insert_char_varying(suite) -> + []; +param_insert_char_varying(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (FIELD CHAR VARYING(10))"), + + {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{{sql_varchar, 10}, + ["foo", "0123456789"]}]), + + true = odbc_test_lib:check_row_count(2, Count), + + {selected, Fileds, [{"foo"}, {"0123456789"}]} = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + + ["FIELD"] = odbc_test_lib:to_upper(Fileds), + + {error, _} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{{sql_varchar, 10}, + ["foo", "01234567890"]}]), + + {'EXIT',{badarg,odbc,param_query,'Params'}} = + (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{{sql_varchar, 10}, ["1", 2.3]}])), + ok. + +%%------------------------------------------------------------------------- +param_insert_character_varying(doc)-> + ["Test insertion of variable length strings by parameterized queries."]; +param_insert_character_varying(suite) -> + []; +param_insert_character_varying(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (FIELD CHARACTER VARYING(10))"), + + + {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{{sql_varchar, 10}, + ["foo", "0123456789"]}]), + + true = odbc_test_lib:check_row_count(2, Count), + + {selected, Fileds, [{"foo"}, {"0123456789"}]} = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + + ["FIELD"] = odbc_test_lib:to_upper(Fileds), + + {error, _} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{{sql_varchar, 10}, + ["foo", "01234567890"]}]), + + {'EXIT',{badarg,odbc,param_query,'Params'}} = + (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{{sql_varchar, 10}, ["1", 2]}])), + ok. +%%------------------------------------------------------------------------- +param_insert_float(doc)-> + ["Test insertion of floats by parameterized queries."]; +param_insert_float(suite) -> + []; +param_insert_float(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (FIELD FLOAT(5))"), + + {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{{sql_float,5}, [1.3, 1.2]}]), + + true = odbc_test_lib:check_row_count(2, Count), + + {selected, Fileds, [{Float1},{Float2}]} = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + + ["FIELD"] = odbc_test_lib:to_upper(Fileds), + + case (odbc_test_lib:match_float(Float1, 1.3, 0.000001) and + odbc_test_lib:match_float(Float2, 1.2, 0.000001)) of + true -> + ok; + false -> + test_server:fail(float_numbers_do_not_match) + end, + + {'EXIT',{badarg,odbc,param_query,'Params'}} = + (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{{sql_float, 5}, [1.0, "2"]}])), + ok. + +%%------------------------------------------------------------------------- +param_insert_real(doc)-> + ["Test insertion of real numbers by parameterized queries."]; +param_insert_real(suite) -> + []; +param_insert_real(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (FIELD REAL)"), + + {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{sql_real, [1.3, 1.2]}]), + + true = odbc_test_lib:check_row_count(2, Count), + + %_InsertResult = ?RDBMS:param_select_real(), + + {selected, Fileds, [{Real1},{Real2}]} = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + + ["FIELD"] = odbc_test_lib:to_upper(Fileds), + + case (odbc_test_lib:match_float(Real1, 1.3, 0.000001) and + odbc_test_lib:match_float(Real2, 1.2, 0.000001)) of + true -> + ok; + false -> + test_server:fail(real_numbers_do_not_match) + end, + + {'EXIT',{badarg,odbc,param_query,'Params'}} = + (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{sql_real,[1.0, "2"]}])), + ok. + +%%------------------------------------------------------------------------- +param_insert_double(doc)-> + ["Test insertion of doubles by parameterized queries."]; +param_insert_double(suite) -> + []; +param_insert_double(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (FIELD DOUBLE PRECISION)"), + + {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{sql_double, [1.3, 1.2]}]), + + true = odbc_test_lib:check_row_count(2, Count), + + {selected, Fileds, [{Double1},{Double2}]} = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + + ["FIELD"] = odbc_test_lib:to_upper(Fileds), + + case (odbc_test_lib:match_float(Double1, 1.3, 0.000001) and + odbc_test_lib:match_float(Double2, 1.2, 0.000001)) of + true -> + ok; + false -> + test_server:fail(double_numbers_do_not_match) + end, + + {'EXIT',{badarg,odbc,param_query,'Params'}} = + (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(FIELD) VALUES(?)", + [{sql_double, [1.0, "2"]}])), + ok. + +%%------------------------------------------------------------------------- +param_insert_mix(doc)-> + ["Test insertion of a mixture of datatypes by parameterized queries."]; +param_insert_mix(suite) -> + []; +param_insert_mix(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID INTEGER, DATA CHARACTER VARYING(10)," + " PRIMARY KEY(ID))"), + + {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(ID, DATA) VALUES(?, ?)", + [{sql_integer, [1, 2]}, + {{sql_varchar, 10}, ["foo", "bar"]}]), + + true = odbc_test_lib:check_row_count(2, Count), + + InsertResult = ?RDBMS:param_select_mix(), + + InsertResult = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + ok. +%%------------------------------------------------------------------------- +param_update(doc)-> + ["Test parameterized update query."]; +param_update(suite) -> + []; +param_update(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID INTEGER, DATA CHARACTER VARYING(10)," + " PRIMARY KEY(ID))"), + + {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(ID, DATA) VALUES(?, ?)", + [{sql_integer, [1, 2, 3]}, + {{sql_varchar, 10}, + ["foo", "bar", "baz"]}]), + + true = odbc_test_lib:check_row_count(3, Count), + + {updated, NewCount} = odbc:param_query(Ref, "UPDATE " ++ Table ++ + " SET DATA = 'foobar' WHERE ID = ?", + [{sql_integer, [1, 2]}]), + + true = odbc_test_lib:check_row_count(2, NewCount), + + UpdateResult = ?RDBMS:param_update(), + + UpdateResult = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + ok. + +%%------------------------------------------------------------------------- +delete_nonexisting_row(doc) -> % OTP-5759 + ["Make a delete...where with false conditions (0 rows deleted). ", + "This used to give an error message (see ticket OTP-5759)."]; +delete_nonexisting_row(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, "CREATE TABLE " ++ Table + ++ " (ID INTEGER, DATA CHARACTER VARYING(10))"), + {updated, Count} = + odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(ID, DATA) VALUES(?, ?)", + [{sql_integer, [1, 2, 3]}, + {{sql_varchar, 10}, ["foo", "bar", "baz"]}]), + + true = odbc_test_lib:check_row_count(3, Count), + + {updated, NewCount} = + odbc:sql_query(Ref, "DELETE FROM " ++ Table ++ " WHERE ID = 8"), + + true = odbc_test_lib:check_row_count(0, NewCount), + + {updated, _} = + odbc:sql_query(Ref, "DROP TABLE "++ Table), + + ok. + +%%------------------------------------------------------------------------- +param_delete(doc) -> + ["Test parameterized delete query."]; +param_delete(suite) -> + []; +param_delete(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID INTEGER, DATA CHARACTER VARYING(10)," + " PRIMARY KEY(ID))"), + + {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(ID, DATA) VALUES(?, ?)", + [{sql_integer, [1, 2, 3]}, + {{sql_varchar, 10}, + ["foo", "bar", "baz"]}]), + true = odbc_test_lib:check_row_count(3, Count), + + {updated, NewCount} = odbc:param_query(Ref, "DELETE FROM " ++ Table ++ + " WHERE ID = ?", + [{sql_integer, [1, 2]}]), + + true = odbc_test_lib:check_row_count(2, NewCount), + + UpdateResult = ?RDBMS:param_delete(), + + UpdateResult = + odbc:sql_query(Ref, "SELECT * FROM " ++ Table), + ok. + + +%%------------------------------------------------------------------------- +param_select(doc) -> + ["Test parameterized select query."]; +param_select(suite) -> + []; +param_select(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (ID INTEGER, DATA CHARACTER VARYING(10)," + " PRIMARY KEY(ID))"), + + {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ + "(ID, DATA) VALUES(?, ?)", + [{sql_integer, [1, 2, 3]}, + {{sql_varchar, 10}, + ["foo", "bar", "foo"]}]), + + true = odbc_test_lib:check_row_count(3, Count), + + SelectResult = ?RDBMS:param_select(), + + SelectResult = odbc:param_query(Ref, "SELECT * FROM " ++ Table ++ + " WHERE DATA = ?", + [{{sql_varchar, 10}, ["foo"]}]), + ok. + +%%------------------------------------------------------------------------- +describe_table(doc) -> + ["Test describe_table/[2,3]"]; +describe_table(suite) -> + [describe_integer, describe_string, describe_floating, describe_dec_num, + describe_no_such_table]. + +%%------------------------------------------------------------------------- +describe_integer(doc) -> + ["Test describe_table/[2,3] for integer columns."]; +describe_integer(suite) -> + []; +describe_integer(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (int1 SMALLINT, int2 INT, int3 INTEGER)"), + + Decs = ?RDBMS:describe_integer(), + %% Make sure to test timeout clause + Decs = odbc:describe_table(Ref, Table, ?TIMEOUT), + ok. + +%%------------------------------------------------------------------------- +describe_string(doc) -> + ["Test describe_table/[2,3] for string columns."]; +describe_string(suite) -> + []; +describe_string(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (str1 char(10), str2 character(10), " + "str3 CHAR VARYING(10), str4 " + "CHARACTER VARYING(10))"), + + Decs = ?RDBMS:describe_string(), + + Decs = odbc:describe_table(Ref, Table), + ok. + +%%------------------------------------------------------------------------- +describe_floating(doc) -> + ["Test describe_table/[2,3] for floting columns."]; +describe_floating(suite) -> + []; +describe_floating(Config) when is_list(Config) -> + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (f FLOAT(5), r REAL, " + "d DOUBLE PRECISION)"), + + Decs = ?RDBMS:describe_floating(), + + Decs = odbc:describe_table(Ref, Table), + ok. + +%%------------------------------------------------------------------------- +describe_dec_num(doc) -> + ["Test describe_table/[2,3] for decimal and numerical columns"]; +describe_dec_num(suite) -> + []; +describe_dec_num(Config) when is_list(Config) -> + + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = + odbc:sql_query(Ref, + "CREATE TABLE " ++ Table ++ + " (dec DECIMAL(9,3), num NUMERIC(9,2))"), + + Decs = ?RDBMS:describe_dec_num(), + + Decs = odbc:describe_table(Ref, Table), + ok. + + +%%------------------------------------------------------------------------- +describe_timestamp(doc) -> + ["Test describe_table/[2,3] for tinmestap columns"]; +describe_timestamp(suite) -> + []; +describe_timestamp(Config) when is_list(Config) -> + + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {updated, _} = % Value == 0 || -1 driver dependent! + odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ + ?RDBMS:create_timestamp_table()), + + Decs = ?RDBMS:describe_timestamp(), + + Decs = odbc:describe_table(Ref, Table), + ok. + +%%------------------------------------------------------------------------- +describe_no_such_table(doc) -> + ["Test what happens if you try to describe a table that does not exist."]; +describe_no_such_table(suite) -> + []; +describe_no_such_table(Config) when is_list(Config) -> + + Ref = ?config(connection_ref, Config), + Table = ?config(tableName, Config), + + {error, _ } = odbc:describe_table(Ref, Table), + ok. + +%%------------------------------------------------------------------------- +%% Internal functions +%%------------------------------------------------------------------------- + +is_driver_error(Error) -> + case is_list(Error) of + true -> + test_server:format("Driver error ~p~n", [Error]), + ok; + false -> + test_server:fail(Error) + end. diff --git a/lib/odbc/test/odbc_start_SUITE.erl b/lib/odbc/test/odbc_start_SUITE.erl new file mode 100644 index 0000000000..2cca8e4546 --- /dev/null +++ b/lib/odbc/test/odbc_start_SUITE.erl @@ -0,0 +1,147 @@ +%% +%% %CopyrightBegin% +%% +%% 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 +%% 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(odbc_start_SUITE). + +%% Note: This directive should only be used in test suites. +-compile(export_all). + +-include("test_server.hrl"). +-include("test_server_line.hrl"). +-include("odbc_test.hrl"). + +%% Test server callback functions +%%-------------------------------------------------------------------- +%% Function: init_per_suite(Config) -> Config +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Initialization before the whole suite +%% +%% Note: This function is free to add any key/value pairs to the Config +%% variable, but should NOT alter/remove any existing entries. +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + case code:which(odbc) of + non_existing -> + {skip, "No ODBC built"}; + _ -> + [{tableName, odbc_test_lib:unique_table_name()} | Config] + end. + +%%-------------------------------------------------------------------- +%% Function: end_per_suite(Config) -> _ +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Cleanup after the whole suite +%%-------------------------------------------------------------------- +end_per_suite(_Config) -> + ok. +%%-------------------------------------------------------------------- +%% Function: init_per_testcase(TestCase, Config) -> Config +%% Case - atom() +%% Name of the test case that is about to be run. +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% +%% Description: Initialization before each test case +%% +%% Note: This function is free to add any key/value pairs to the Config +%% variable, but should NOT alter/remove any existing entries. +%% Description: Initialization before each test case +%%-------------------------------------------------------------------- +init_per_testcase(_TestCase, Config0) -> + test_server:format("ODBCINI = ~p~n", [os:getenv("ODBCINI")]), + Config = lists:keydelete(watchdog, 1, Config0), + Dog = test_server:timetrap(?TIMEOUT), + [{watchdog, Dog} | Config]. + +%%-------------------------------------------------------------------- +%% Function: end_per_testcase(TestCase, Config) -> _ +%% Case - atom() +%% Name of the test case that is about to be run. +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Cleanup after each test case +%%-------------------------------------------------------------------- +end_per_testcase(_TestCase, Config) -> + Dog = ?config(watchdog, Config), + case Dog of + undefined -> + ok; + _ -> + test_server:timetrap_cancel(Dog) + end. + +%%-------------------------------------------------------------------- +%% Function: all(Clause) -> TestCases +%% Clause - atom() - suite | doc +%% TestCases - [Case] +%% Case - atom() +%% Name of a test case. +%% Description: Returns a list of all test cases in this test suite +%%-------------------------------------------------------------------- +all(doc) -> + ["Test start/stop of odbc"]; + +all(suite) -> + case odbc_test_lib:odbc_check() of + ok -> all(); + Other -> {skip, Other} + end. + +all() -> + [start]. + + +%% Test cases starts here. +%%-------------------------------------------------------------------- + +start(doc) -> + ["Test start/stop of odbc"]; +start(suite) -> + []; +start(Config) when is_list(Config) -> + {error,odbc_not_started} = odbc:connect(?RDBMS:connection_string(), []), + odbc:start(), + case odbc:connect(?RDBMS:connection_string(), []) of + {ok, Ref0} -> + ok = odbc:disconnect(Ref0), + odbc:stop(), + {error,odbc_not_started} = + odbc:connect(?RDBMS:connection_string(), []), + start_odbc(transient), + start_odbc(permanent); + {error, odbc_not_started} -> + test_server:fail(start_failed); + Error -> + test_server:format("Connection failed: ~p~n", [Error]), + {skip, "ODBC is not properly setup"} + end. + +start_odbc(Type) -> + ok = odbc:start(Type), + case odbc:connect(?RDBMS:connection_string(), []) of + {ok, Ref} -> + ok = odbc:disconnect(Ref), + odbc:stop(); + {error, odbc_not_started} -> + test_server:fail(start_failed) + end. diff --git a/lib/odbc/test/odbc_test.hrl b/lib/odbc/test/odbc_test.hrl new file mode 100644 index 0000000000..87f50043db --- /dev/null +++ b/lib/odbc/test/odbc_test.hrl @@ -0,0 +1,37 @@ +%% +%% %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% +%% + + +% Default timetrap timeout (set in init_per_testcase). +% This should be set relatively high (10-15 times the expected +% max testcasetime). +-define(default_timeout, ?t:minutes(10)). + +-define(RDBMS, case os:type() of + {unix, sunos} -> + postgres; + {unix,linux} -> + postgres; + {win32, _} -> + sqlserver + end). + +-define(TIMEOUT, 100000). + + diff --git a/lib/odbc/test/odbc_test_lib.erl b/lib/odbc/test/odbc_test_lib.erl new file mode 100644 index 0000000000..92e895eb87 --- /dev/null +++ b/lib/odbc/test/odbc_test_lib.erl @@ -0,0 +1,77 @@ +%% +%% %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% +%% + +%% + +-module(odbc_test_lib). + +%% Note: This directive should only be used in test suites. +-compile(export_all). + +-include("odbc_test.hrl"). +-include("test_server.hrl"). + +unique_table_name() -> + lists:reverse(lists:foldl(fun($@, Acc) -> [$t, $A |Acc] ; + (X, Acc) -> [X |Acc] end, + [], atom_to_list(node()))). + +match_float(Float, Match, Delta) -> + (Float < Match + Delta) and (Float > Match - Delta). + +odbc_check() -> + case erlang:system_info(wordsize) of + 4 -> + case test_server:os_type() of + {unix, sunos} -> + ok; + {unix, linux} -> + ok; + {win32, _} -> + ok; + Other -> + lists:flatten( + io_lib:format("Platform not supported: ~w", + [Other])) + end; + Other -> + case test_server:os_type() of + {unix, linux} -> + ok; + Platform -> + lists:flatten( + io_lib:format("Word on platform ~w size" + " ~w not supported", [Other, + Platform])) + end + end. + +check_row_count(Count, Count) -> + test_server:format("Correct row count Count: ~p~n", [Count]), + true; +check_row_count(_, undefined) -> + test_server:format("Undefined row count ~n", []), + true; +check_row_count(Expected, Count) -> + test_server:format("Incorrect row count Expected ~p Got ~p~n", + [Expected, Count]), + false. + +to_upper(List) -> + lists:map(fun(Str) -> string:to_upper(Str) end, List). diff --git a/lib/odbc/test/oracle.erl b/lib/odbc/test/oracle.erl new file mode 100644 index 0000000000..ebf6dbb6bf --- /dev/null +++ b/lib/odbc/test/oracle.erl @@ -0,0 +1,246 @@ +%% +%% %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% +%% + +%% + +-module(oracle). + +%% Note: This directive should only be used in test suites. +-compile(export_all). + +%------------------------------------------------------------------------- +connection_string() -> + "DSN=Oracle8;UID=odbctest". + +%------------------------------------------------------------------------- +insert_result() -> + {selected,["ID","DATA"],[{"1","bar"}]}. + +update_result() -> + {selected,["ID","DATA"],[{"1","foo"}]}. + +selected_ID(N, next) -> + {selected,["ID"],[{integer_to_list(N)}]}; + +selected_ID(_, _) -> + {error, driver_does_not_support_function}. + +selected_next_N(1)-> + {selected,["ID"], + [{"1"}, + {"2"}, + {"3"}]}; + +selected_next_N(2)-> + {selected,["ID"], + [{"4"}, + {"5"}]}. + +selected_relative_N(_)-> + {error, driver_does_not_support_function}. + +selected_absolute_N(_)-> + {error, driver_does_not_support_function}. + +selected_list_rows() -> + {selected,["ID", "DATA"],[["1", "bar"],["2","foo"]]}. + +first_list_rows() -> + {error, driver_does_not_support_function}. +last_list_rows() -> + {error, driver_does_not_support_function}. +prev_list_rows() -> + {error, driver_does_not_support_function}. +next_list_rows() -> + {selected,["ID","DATA"],[["1","bar"]]}. + +%% In case we get a better oracle driver that support this some day ..... +multiple_select()-> + [{selected,["ID", "DATA"],[{"1", "bar"},{"2", "foo"}]}, + {selected,["ID"],[{"foo"}]}]. + +multiple_mix()-> + [{updated, 1},{updated, 1}, + {selected,["ID", "DATA"],[{"1", "foobar"},{"2", "foo"}]}, + {updated, 1}, {selected,["DATA"],[{"foo"}]}]. + +%------------------------------------------------------------------------- +fixed_char_min() -> + 1. +fixed_char_max() -> + 2000. %% Should be 255 acording to manual but empirical tests say 2000 + +create_fixed_char_table(Size) -> + " (FIELD char(" ++ integer_to_list(Size) ++ "))". + +%------------------------------------------------------------------------- +var_char_min() -> + 1. +var_char_max() -> + 2000. + +create_var_char_table(Size) -> + " (FIELD varchar2(" ++ integer_to_list(Size) ++ "))". + +%------------------------------------------------------------------------- +text_min() -> + 1. +text_max() -> + 2147483646. % 2147483647. %% 2^31 - 1 + +create_text_table() -> + " (FIELD long)". %Oracle long is variable length char data + +%------------------------------------------------------------------------- +create_unicode_table() -> + " (FIELD nvarchar(50))". + +%------------------------------------------------------------------------- +create_timestamp_table() -> + " (FIELD DATETIME)". + +%------------------------------------------------------------------------- +tiny_int_min() -> + -999. +tiny_int_max() -> + 999. + +create_tiny_int_table() -> + " (FIELD number(3, 0))". + +tiny_int_min_selected() -> + {selected,["FIELD"],[{-999}]}. + +tiny_int_max_selected() -> + {selected,["FIELD"], [{999}]}. + +%------------------------------------------------------------------------- +small_int_min() -> + -99999. +small_int_max() -> + 99999. + +create_small_int_table() -> + " (FIELD number(5, 0))". + +small_int_min_selected() -> + {selected,["FIELD"],[{-99999}]}. + +small_int_max_selected() -> + {selected,["FIELD"], [{99999}]}. + +%------------------------------------------------------------------------- +int_min() -> + -999999999. +int_max() -> + 999999999. + +create_int_table() -> + " (FIELD number(9, 0))". + +int_min_selected() -> + {selected,["FIELD"],[{-999999999}]}. + +int_max_selected() -> + {selected,["FIELD"], [{999999999}]}. + +%------------------------------------------------------------------------- +big_int_min() -> + -99999999999999999999999999999999999999. + +big_int_max() -> + 99999999999999999999999999999999999999. + +create_big_int_table() -> + " (FIELD number(38,0))". + +big_int_min_selected() -> + {selected,["FIELD"], [{"-99999999999999999999999999999999999999"}]}. + +big_int_max_selected() -> + {selected,["FIELD"], [{"99999999999999999999999999999999999999"}]}. + +%------------------------------------------------------------------------- +float_min() -> + 1.40129846432481707e-45. + +float_max() -> + 3.40282346638528860e+38. + +create_float_table() -> + " (FIELD float(32))". + +float_underflow() -> + "'4.94065645841246544e-324'". +float_overflow() -> + "'1.79769313486231570e+308'". + +float_zero_selected() -> + {selected,["FIELD"],[{0.00000e+0}]}. + +%------------------------------------------------------------------------- +param_select_small_int() -> + {selected,["FIELD"],[{"1"}, {"2"}]}. + +param_select_int() -> + Int = small_int_max() + 1, + {selected,["FIELD"],[{"1"}, {integer_to_list(Int)}]}. + +param_select_decimal() -> + {selected,["FIELD"],[{1},{2}]}. + +param_select_numeric() -> + {selected,["FIELD"],[{1},{2}]}. + +param_select_float() -> + {selected,["FIELD"],[{1.30000},{1.20000}]}. + +param_select_real() -> + {selected,["FIELD"],[{1.30000},{1.20000}]}. + +param_select_double() -> + {selected,["FIELD"],[{1.30000},{1.20000}]}. + +param_select_mix() -> + {selected,["ID","DATA"],[{"1", "foo"}, {"2", "bar"}]}. + +param_update() -> + {selected,["ID","DATA"],[{"1", "foobar"}, {"2", "foobar"}, {"3", "baz"}]}. + +param_delete() -> + {selected,["ID","DATA"],[{"3", "baz"}]}. + +param_select() -> + {selected,["ID","DATA"],[{"1", "foo"},{"3", "foo"}]}. + +%------------------------------------------------------------------------- +describe_integer() -> + {ok,[{"INT1",{sql_decimal,38,0}},{"INT2",{sql_decimal,38,0}}, + {"INT3",{sql_decimal,38,0}}]}. + +describe_string() -> + {ok,[{"STR1",{sql_char,10}}, + {"STR2",{sql_char,10}}, + {"STR3",{sql_varchar,10}}, + {"STR4",{sql_varchar,10}}]}. + +describe_floating() -> + {ok,[{"F",sql_double},{"R",sql_double},{"D",sql_double}]}. +describe_dec_num() -> + {ok,[{"DEC",{sql_decimal,9,3}},{"NUM",{sql_decimal,9,2}}]}. diff --git a/lib/odbc/test/postgres.erl b/lib/odbc/test/postgres.erl new file mode 100644 index 0000000000..169ca26e43 --- /dev/null +++ b/lib/odbc/test/postgres.erl @@ -0,0 +1,294 @@ +%% +%% %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% +%% + +%% + +-module(postgres). + +%% Note: This directive should only be used in test suites. +-compile(export_all). + +%------------------------------------------------------------------------- +connection_string() -> + case test_server:os_type() of + {unix, sunos} -> + "DSN=Postgres;UID=odbctest"; + {unix, linux} -> + Size = erlang:system_info(wordsize), + linux_dist_connection_string(Size) + end. + +linux_dist_connection_string(4) -> + case linux_dist() of + "ubuntu" -> + "DSN=PostgresLinuxUbuntu;UID=odbctest"; + _ -> + "DSN=PostgresLinux;UID=odbctest" + end; + +linux_dist_connection_string(_) -> + "DSN=PostgresLinux64;UID=odbctest". + +linux_dist() -> + case file:read_file("/etc/issue") of + {ok, Binary} -> + [Dist | _ ] = string:tokens(binary_to_list(Binary), " "), + string:to_lower(Dist); + {error, _} -> + other + end. + + +%------------------------------------------------------------------------- +insert_result() -> + {selected,["id","data"],[{1,"bar"}]}. + +update_result() -> + {selected,["id","data"],[{1,"foo"}]}. + +selected_ID(N, next) -> + {selected,["id"],[{N}]}; + +selected_ID(_, _) -> + {error, driver_does_not_support_function}. + +selected_next_N(1)-> + {selected,["id"], + [{1}, + {2}, + {3}]}; + +selected_next_N(2)-> + {selected,["id"], + [{4}, + {5}]}. + +selected_relative_N(_)-> + {error, driver_does_not_support_function}. + +selected_absolute_N(_)-> + {error, driver_does_not_support_function}. + +selected_list_rows() -> + {selected,["id", "data"],[[1, "bar"],[2,"foo"]]}. + +first_list_rows() -> + {error, driver_does_not_support_function}. +last_list_rows() -> + {error, driver_does_not_support_function}. +prev_list_rows() -> + {error, driver_does_not_support_function}. +next_list_rows() -> + {selected,["id","data"],[[1,"bar"]]}. + +%% In case we get a better postgres driver that support this some day ..... +multiple_select()-> + [{selected,["id", "data"],[{1, "bar"},{2, "foo"}]}, + {selected,["id"],[{"foo"}]}]. + +multiple_mix()-> + [{updated, 1},{updated, 1}, + {selected,["id", "data"],[{1, "foobar"},{2, "foo"}]}, + {updated, 1}, {selected,["data"],[{"foo"}]}]. + +%------------------------------------------------------------------------- +fixed_char_min() -> + 1. +fixed_char_max() -> + 2000. + +create_fixed_char_table(Size) -> + " (FIELD char(" ++ integer_to_list(Size) ++ "))". + +%------------------------------------------------------------------------- +var_char_min() -> + 1. +var_char_max() -> + 2000. + +create_var_char_table(Size) -> + " (FIELD varchar(" ++ integer_to_list(Size) ++ "))". + +%------------------------------------------------------------------------- +text_min() -> + 1. +text_max() -> + 2147483646. % 2147483647. %% 2^31 - 1 + +create_text_table() -> + " (FIELD text)". + +%------------------------------------------------------------------------- +create_unicode_table() -> + " (FIELD text)". + +%------------------------------------------------------------------------- +create_timestamp_table() -> + " (FIELD TIMESTAMP)". + +%------------------------------------------------------------------------- +small_int_min() -> + -32768. +small_int_max() -> + 32767. + +create_small_int_table() -> + " (FIELD smallint)". + +small_int_min_selected() -> + {selected,["field"],[{-32768}]}. + +small_int_max_selected() -> + {selected,["field"], [{32767}]}. + +%------------------------------------------------------------------------- +int_min() -> + -2147483648. +int_max() -> + 2147483647. + +create_int_table() -> + " (FIELD int)". + +int_min_selected() -> + {selected,["field"],[{-2147483648}]}. + +int_max_selected() -> + {selected,["field"], [{2147483647}]}. + +%------------------------------------------------------------------------- +big_int_min() -> + -9223372036854775808. + +big_int_max() -> + 9223372036854775807. + +create_big_int_table() -> + " (FIELD bigint )". + +big_int_min_selected() -> + {selected,["field"], [{"-9223372036854775808"}]}. + +big_int_max_selected() -> + {selected,["field"], [{"9223372036854775807"}]}. + +%------------------------------------------------------------------------- +bit_false() -> + 0. +bit_true() -> + 1. + +create_bit_table() -> + " (FIELD bit)". + +bit_false_selected() -> + {selected,["field"],[{"0"}]}. + +bit_true_selected() -> + {selected,["field"], [{"1"}]}. + +%------------------------------------------------------------------------- +float_min() -> + 1.79e-307. +float_max() -> + 1.79e+308. + +create_float_table() -> + " (FIELD float)". + +float_underflow() -> + "1.80e-308". +float_overflow() -> + "1.80e+308". + +float_zero_selected() -> + {selected,["field"],[{0.00000e+0}]}. + +%------------------------------------------------------------------------- +real_min() -> + -3.40e+38. +real_max() -> + 3.40e+38. + +real_underflow() -> + "-3.41e+38". + +real_overflow() -> + "3.41e+38". + +create_real_table() -> + " (FIELD real)". + +real_zero_selected() -> + {selected,["field"],[{0.00000e+0}]}. + +%------------------------------------------------------------------------- +param_select_small_int() -> + {selected,["field"],[{1}, {2}]}. + +param_select_int() -> + Int = small_int_max() + 1, + {selected,["field"],[{1}, {Int}]}. + +param_select_decimal() -> + {selected,["field"],[{1},{2}]}. + +param_select_numeric() -> + {selected,["field"],[{1},{2}]}. + +param_select_float() -> + {selected,["field"],[{1.30000},{1.20000}]}. + +param_select_real() -> + {selected,["field"],[{1.30000},{1.20000}]}. + +param_select_double() -> + {selected,["field"],[{1.30000},{1.20000}]}. + +param_select_mix() -> + {selected,["id","data"],[{1, "foo"}, {2, "bar"}]}. + +param_update() -> + {selected,["id","data"],[{3, "baz"},{1, "foobar"}, {2, "foobar"}]}. + +param_delete() -> + {selected,["id","data"],[{3, "baz"}]}. + +param_select() -> + {selected,["id","data"],[{1, "foo"},{3, "foo"}]}. + +%------------------------------------------------------------------------- +describe_integer() -> + {ok,[{"int1",sql_smallint}, + {"int2",sql_integer}, + {"int3",sql_integer}]}. + +describe_string() -> + {ok,[{"str1",{sql_char,10}}, + {"str2",{sql_char,10}}, + {"str3",{sql_varchar,10}}, + {"str4",{sql_varchar,10}}]}. + +describe_floating() -> + {ok,[{"f",sql_real},{"r",sql_real},{"d",{sql_float,15}}]}. +describe_dec_num() -> + {ok,[{"dec",{sql_numeric,9,3}},{"num",{sql_numeric,9,2}}]}. + +describe_timestamp() -> + {ok, [{"field", sql_timestamp}]}. diff --git a/lib/odbc/test/sqlserver.erl b/lib/odbc/test/sqlserver.erl new file mode 100644 index 0000000000..e3fe30e0bc --- /dev/null +++ b/lib/odbc/test/sqlserver.erl @@ -0,0 +1,298 @@ +%% +%% %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% +%% + +%% + +-module(sqlserver). + +%% Note: This directive should only be used in test suites. +-compile(export_all). + +%------------------------------------------------------------------------- +connection_string() -> + "DSN=sql-server;UID=odbctest;PWD=gurka". + +%------------------------------------------------------------------------- +insert_result() -> + {selected,["ID","DATA"],[{1,"bar"}]}. + +update_result() -> + {selected,["ID","DATA"],[{1,"foo"}]}. + +selected_ID(N, _) -> + {selected,["ID"],[{N}]}. + +selected_next_N(1)-> + {selected,["ID"], + [{1}, + {2}, + {3}]}; + +selected_next_N(2)-> + {selected,["ID"], + [{4}, + {5}]}. + +selected_relative_N(1)-> + {selected,["ID"], + [{2}, + {3}, + {4}]}; + +selected_relative_N(2)-> + {selected,["ID"], + [{7}, + {8}]}. + +selected_absolute_N(1)-> + {selected,["ID"], + [{1}, + {2}, + {3}]}; + +selected_absolute_N(2)-> + {selected,["ID"], + [{1}, + {2}, + {3}, + {4}, + {5}]}. + +selected_list_rows() -> + {selected,["ID", "DATA"],[[1, "bar"],[2,"foo"]]}. + +first_list_rows() -> + {selected,["ID", "DATA"],[[1, "bar"]]}. +last_list_rows() -> + {selected,["ID", "DATA"],[[2, "foo"]]}. +prev_list_rows() -> + {selected,["ID", "DATA"],[[1, "bar"]]}. +next_list_rows() -> + {selected,["ID", "DATA"],[[2, "foo"]]}. + +multiple_select()-> + [{selected,["ID", "DATA"],[{1, "bar"},{2, "foo"}]}, + {selected,["DATA"],[{"foo"}]}]. + +multiple_mix()-> + [{updated, 1},{updated, 1}, + {selected,["ID", "DATA"],[{1, "foobar"},{2, "foo"}]}, + {updated, 1}, {selected,["DATA"],[{"foo"}]}]. + +%------------------------------------------------------------------------- +fixed_char_min() -> + 1. + +fixed_char_max() -> + 8000. + +create_fixed_char_table(Size) -> + " (FIELD char(" ++ integer_to_list(Size) ++ "))". + +%------------------------------------------------------------------------- +var_char_min() -> + 1. +var_char_max() -> + 8000. + +create_var_char_table(Size) -> + " (FIELD varchar(" ++ integer_to_list(Size) ++ "))". +%------------------------------------------------------------------------- +text_min() -> + 1. +text_max() -> + 2147483647. %% 2^31 - 1 + +create_text_table() -> + " (FIELD text)". + +%------------------------------------------------------------------------- +create_unicode_table() -> + " (FIELD nvarchar(50))". + +%------------------------------------------------------------------------- +create_timestamp_table() -> + " (FIELD DATETIME)". + +%------------------------------------------------------------------------- +tiny_int_min() -> + 0. +tiny_int_max() -> + 255. + +create_tiny_int_table() -> + " (FIELD tinyint)". + +tiny_int_min_selected() -> + {selected,["FIELD"],[{tiny_int_min()}]}. + +tiny_int_max_selected() -> + {selected,["FIELD"], [{tiny_int_max()}]}. + +%------------------------------------------------------------------------- +small_int_min() -> + -32768. % -2^15 +small_int_max() -> + 32767. % 2^15-1 + +create_small_int_table() -> + " (FIELD smallint)". + +small_int_min_selected() -> + {selected,["FIELD"],[{small_int_min()}]}. + +small_int_max_selected() -> + {selected,["FIELD"], [{small_int_max()}]}. + +%------------------------------------------------------------------------- +int_min() -> + -2147483648. % -2^31 +int_max() -> + 2147483647. % 2^31-1 + +create_int_table() -> + " (FIELD int)". + +int_min_selected() -> + {selected,["FIELD"],[{int_min()}]}. + +int_max_selected() -> + {selected,["FIELD"], [{int_max()}]}. + +%------------------------------------------------------------------------- +big_int_min() -> + -9223372036854775808. % -2^63 +big_int_max() -> + 9223372036854775807. % 2^63-1 + +create_big_int_table() -> + " (FIELD bigint)". + +big_int_min_selected() -> + {selected,["FIELD"],[{integer_to_list(big_int_min())}]}. + +big_int_max_selected() -> + {selected,["FIELD"], [{integer_to_list(big_int_max())}]}. + +%------------------------------------------------------------------------- +bit_false() -> + 0. +bit_true() -> + 1. + +create_bit_table() -> + " (FIELD bit)". + +bit_false_selected() -> + {selected,["FIELD"],[{false}]}. + +bit_true_selected() -> + {selected,["FIELD"], [{true}]}. +%------------------------------------------------------------------------- +float_min() -> + -1.79e+308. +float_max() -> + 1.79e+308. + +float_underflow() -> + "'-1.80e+308'". + +float_overflow() -> + "'-1.80e+308'". + +create_float_table() -> + " (FIELD float)". + +float_zero_selected() -> + {selected,["FIELD"],[{0.00000e+0}]}. +%------------------------------------------------------------------------- +real_min() -> + -3.40e+38. +real_max() -> + 3.40e+38. + +real_underflow() -> + -3.41e+38. + +real_overflow() -> + 3.41e+38. + +create_real_table() -> + " (FIELD real)". + +real_zero_selected() -> + {selected,["FIELD"],[{0.00000e+0}]}. +%------------------------------------------------------------------------- +param_select_tiny_int() -> + {selected,["FIELD"],[{1}, {2}]}. + +param_select_small_int() -> + {selected,["FIELD"],[{1}, {2}]}. + +param_select_int() -> + Int = small_int_max() + 1, + {selected,["FIELD"],[{1}, {Int}]}. + +param_select_decimal() -> + {selected,["FIELD"],[{1},{2}]}. + +param_select_numeric() -> + {selected,["FIELD"],[{1},{2}]}. + +param_select_float() -> + {selected,["FIELD"],[{1.30000},{1.20000}]}. + +param_select_real() -> + {selected,["FIELD"],[{1.30000},{1.20000}]}. + +param_select_double() -> + {selected,["FIELD"],[{1.30000},{1.20000}]}. + +param_select_mix() -> + {selected,["ID","DATA"],[{1, "foo"}, {2, "bar"}]}. + +param_update() -> + {selected,["ID","DATA"],[{1, "foobar"}, {2, "foobar"}, {3, "baz"}]}. + +param_delete() -> + {selected,["ID","DATA"],[{3, "baz"}]}. + +param_select() -> + {selected,["ID","DATA"],[{1, "foo"},{3, "foo"}]}. + +%------------------------------------------------------------------------- + +describe_integer() -> + {ok,[{"int1", sql_smallint},{"int2", sql_integer}, + {"int3", sql_integer}]}. + +describe_string() -> + {ok,[{"str1",{sql_char,10}}, + {"str2",{sql_char,10}}, + {"str3",{sql_varchar,10}}, + {"str4",{sql_varchar,10}}]}. + +describe_floating() -> + {ok,[{"f", sql_real},{"r", sql_real}, {"d", {sql_float, 53}}]}. + +describe_dec_num() -> + {ok,[{"dec",{sql_decimal,9,3}},{"num",{sql_numeric,9,2}}]}. + +describe_timestamp() -> + {ok, [{"field", sql_timestamp}]}. diff --git a/lib/odbc/vsn.mk b/lib/odbc/vsn.mk index 92540d90f8..fac3f06d4b 100644 --- a/lib/odbc/vsn.mk +++ b/lib/odbc/vsn.mk @@ -1,22 +1 @@ -ODBC_VSN = 2.10.7 - -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 +ODBC_VSN = 2.10.8 diff --git a/lib/orber/doc/src/notes.xml b/lib/orber/doc/src/notes.xml index d388cc42a8..17f7ac8270 100644 --- a/lib/orber/doc/src/notes.xml +++ b/lib/orber/doc/src/notes.xml @@ -32,6 +32,45 @@ <file>notes.xml</file> </header> + <section><title>Orber 3.6.17</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Eliminated warnings for auto-imported BIF clashes.</p> + <p> + Own Id: OTP-8840</p> + </item> + </list> + </section> + +</section> + +<section> + <title>Orber 3.6.16</title> + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p> + Test suites published.</p> + <p> + Own Id: OTP-8543 Aux Id:</p> + </item> + </list> + </section> + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>Added missing trailing bracket to define in hrl-file.</p> + <p>Own id: OTP-8489 Aux Id:</p> + </item> + </list> + </section> + </section> + <section> <title>Orber 3.6.15</title> diff --git a/lib/orber/include/ifr_types.hrl b/lib/orber/include/ifr_types.hrl index d982850e98..144ec7f8a1 100644 --- a/lib/orber/include/ifr_types.hrl +++ b/lib/orber/include/ifr_types.hrl @@ -1,20 +1,20 @@ %%-------------------------------------------------------------------- %% %% %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% %% %% @@ -54,7 +54,7 @@ id = Obj#Object_type.id, defined_in = Obj#Object_type.defined_in, version = Obj#Object_type.version, - type = Obj#Object_type.type}. + type = Obj#Object_type.type}). -record(exceptiondescription, {name, id, defined_in, version, type}). diff --git a/lib/orber/src/orber_tb.erl b/lib/orber/src/orber_tb.erl index 0dd2d95bc8..e6d5ee4400 100644 --- a/lib/orber/src/orber_tb.erl +++ b/lib/orber/src/orber_tb.erl @@ -2,7 +2,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% 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 @@ -35,6 +35,8 @@ %%---------------------------------------------------------------------- %% External exports %%---------------------------------------------------------------------- +%% Avoid warning for local function error/2 clashing with autoimported BIF. +-compile({no_auto_import,[error/2]}). -export([wait_for_tables/1, wait_for_tables/2, wait_for_tables/3, is_loaded/0, is_loaded/1, is_running/0, is_running/1, info/2, error/2, unique/1, keysearch/2, keysearch/3]). diff --git a/lib/orber/vsn.mk b/lib/orber/vsn.mk index d074bfb86c..681b82b51b 100644 --- a/lib/orber/vsn.mk +++ b/lib/orber/vsn.mk @@ -1,18 +1 @@ - -ORBER_VSN = 3.6.15 - -TICKETS = 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 +ORBER_VSN = 3.6.17 diff --git a/lib/parsetools/doc/src/notes.xml b/lib/parsetools/doc/src/notes.xml index 8a6f2c2714..544850308e 100644 --- a/lib/parsetools/doc/src/notes.xml +++ b/lib/parsetools/doc/src/notes.xml @@ -30,6 +30,43 @@ </header> <p>This document describes the changes made to the Parsetools application.</p> +<section><title>Parsetools 2.0.4</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Running HiPE-compiled Yecc parsers no longer results + in a <c>function_clause</c> error.</p> + <p> + Own Id: OTP-8771</p> + </item> + </list> + </section> + +</section> + +<section><title>Parsetools 2.0.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Yecc failed to report reduce/reduce conflicts where + one of the reductions involved the root symbol. This bug + has been fixed. (Thanks to Manolis Papadakis.)</p> + <p> + Own Id: OTP-8483</p> + </item> + <item> + <p>A bug introduced in Parsetools 1.4.4 (R12B-2) has been + fixed. (Thanks to Manolis Papadakis.)</p> + <p> + Own Id: OTP-8486</p> + </item> + </list> + </section> + +</section> + <section><title>Parsetools 2.0.2</title> <section><title>Improvements and New Features</title> 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/leex.erl b/lib/parsetools/src/leex.erl index fd494eaf06..d0b4b9efe7 100644 --- a/lib/parsetools/src/leex.erl +++ b/lib/parsetools/src/leex.erl @@ -35,7 +35,7 @@ -export([compile/3,file/1,file/2,format_error/1]). -import(lists, [member/2,reverse/1,sort/1,delete/2, - keysearch/3,keysort/2,keydelete/3,keyfind/3, + keysort/2,keydelete/3,keyfind/3, map/2,foldl/3,foreach/2,flatmap/2]). -import(string, [substr/2,substr/3,span/2]). -import(ordsets, [is_element/2,add_element/2,union/2]). @@ -182,18 +182,18 @@ options(Options0, [Key|Keys], L) when is_list(Options0) -> false -> Options0 end, - V = case keysearch(Key, 1, Options) of - {value, {Key, Filename0}} when Key =:= includefile; - Key =:= scannerfile -> + V = case lists:keyfind(Key, 1, Options) of + {Key, Filename0} when Key =:= includefile; + Key =:= scannerfile -> case is_filename(Filename0) of no -> badarg; Filename -> {ok,[{Key,Filename}]} end; - {value,{Key,Bool}} when Bool; not Bool -> - {ok,[{Key, Bool}]}; - {value,{Key, _}} -> + {Key, Bool} = KB when is_boolean(Bool) -> + {ok, [KB]}; + {Key, _} -> badarg; false -> {ok,[{Key,default_option(Key)}]} @@ -231,8 +231,7 @@ atom_option(verbose) -> {verbose,true}; atom_option(Key) -> Key. is_filename(T) -> - try filename:flatten(T) of - Filename -> Filename + try filename:flatten(T) catch error: _ -> no end. @@ -320,10 +319,10 @@ filenames(File, Opts, St0) -> St1 = St0#leex{xfile=Xfile, opts=Opts, module=Module}, - {value,{includefile,Ifile0}} = keysearch(includefile, 1, Opts), + {includefile,Ifile0} = lists:keyfind(includefile, 1, Opts), Ifile = inc_file_name(Ifile0), %% Test for explicit scanner file. - {value,{scannerfile,Ofile}} = keysearch(scannerfile, 1, Opts), + {scannerfile,Ofile} = lists:keyfind(scannerfile, 1, Opts), if Ofile =:= [] -> St1#leex{efile=filename:join(Dir, Efile), @@ -495,7 +494,7 @@ parse_rule(S, Line, Atoks, Ms, N, St) -> end. var_used(Name, Toks) -> - case keyfind(Name, 3, Toks) of + case lists:keyfind(Name, 3, Toks) of {var,_,Name} -> true; %It's the var we want _ -> false end. @@ -629,7 +628,7 @@ re_seq(Cs0, Sn0, St) -> {Rs,Sn1,Cs1} -> {{seq,Rs},Sn1,Cs1} end. -re_seq1([C|_]=Cs0, Sn0, St) when C /= $|, C /= $) -> +re_seq1([C|_]=Cs0, Sn0, St) when C =/= $|, C =/= $) -> {L,Sn1,Cs1} = re_repeat(Cs0, Sn0, St), {Rs,Sn2,Cs2} = re_seq1(Cs1, Sn1, St), {[L|Rs],Sn2,Cs2}; @@ -751,9 +750,9 @@ re_char_class("[:" ++ Cs0, Cc, #leex{posix=true}=St) -> {Pcl,":]" ++ Cs1} -> re_char_class(Cs1, [{posix,Pcl}|Cc], St); {_,Cs1} -> parse_error({posix_cc,string_between(Cs0, Cs1)}) end; -re_char_class([C1|Cs0], Cc, St) when C1 /= $] -> +re_char_class([C1|Cs0], Cc, St) when C1 =/= $] -> case re_char(C1, Cs0) of - {Cf,[$-,C2|Cs1]} when C2 /= $] -> + {Cf,[$-,C2|Cs1]} when C2 =/= $] -> case re_char(C2, Cs1) of {Cl,Cs2} when Cf < Cl -> re_char_class(Cs2, [{range,Cf,Cl}|Cc], St); @@ -998,7 +997,7 @@ pack_crs([{C1,C2},{C3,C4}|Crs]) when C2 >= C3, C2 < C4 -> %% C1 C2 %% C3 C4 pack_crs([{C1,C4}|Crs]); -pack_crs([{C1,C2},{C3,C4}|Crs]) when C2 + 1 == C3 -> +pack_crs([{C1,C2},{C3,C4}|Crs]) when C2 + 1 =:= C3 -> %% C1 C2 %% C3 C4 pack_crs([{C1,C4}|Crs]); @@ -1055,7 +1054,7 @@ build_dfa(Set, Us, N, Ts, Ms, NFA) -> %% List of all transition sets. Crs0 = [Cr || S <- Set, {Crs,_St} <- (element(S, NFA))#nfa_state.edges, - Crs /= epsilon, % Not an epsilon transition + Crs =/= epsilon, % Not an epsilon transition Cr <- Crs ], Crs1 = lists:usort(Crs0), % Must remove duplicates! %% Build list of disjoint test ranges. @@ -1072,7 +1071,7 @@ disjoint_crs([{_C1,C2}=Cr1,{C3,_C4}=Cr2|Crs]) when C2 < C3 -> %% C1 C2 %% C3 C4 [Cr1|disjoint_crs([Cr2|Crs])]; -disjoint_crs([{C1,C2},{C3,C4}|Crs]) when C1 == C3 -> +disjoint_crs([{C1,C2},{C3,C4}|Crs]) when C1 =:= C3 -> %% C1 C2 %% C3 C4 [{C1,C2}|disjoint_crs(add_element({C2+1,C4}, Crs))]; @@ -1080,7 +1079,7 @@ disjoint_crs([{C1,C2},{C3,C4}|Crs]) when C1 < C3, C2 >= C3, C2 < C4 -> %% C1 C2 %% C3 C4 [{C1,C3-1}|disjoint_crs(union([{C3,C2},{C2+1,C4}], Crs))]; -disjoint_crs([{C1,C2},{C3,C4}|Crs]) when C1 < C3, C2 == C4 -> +disjoint_crs([{C1,C2},{C3,C4}|Crs]) when C1 < C3, C2 =:= C4 -> %% C1 C2 %% C3 C4 [{C1,C3-1}|disjoint_crs(add_element({C3,C4}, Crs))]; @@ -1093,7 +1092,7 @@ disjoint_crs([]) -> []. build_dfa([Cr|Crs], Set, Us, N, Ts, Ms, NFA) -> case eclosure(move(Set, Cr, NFA), NFA) of - S when S /= [] -> + S when S =/= [] -> case dfa_state_exist(S, Us, Ms) of {yes,T} -> build_dfa(Crs, Set, Us, N, store(Cr, T, Ts), Ms, NFA); @@ -1110,11 +1109,11 @@ build_dfa([], _, Us, N, Ts, _, _) -> %% dfa_state_exist(Set, Unmarked, Marked) -> {yes,State} | no. dfa_state_exist(S, Us, Ms) -> - case keysearch(S, #dfa_state.nfa, Us) of - {value,#dfa_state{no=T}} -> {yes,T}; + case lists:keyfind(S, #dfa_state.nfa, Us) of + #dfa_state{no=T} -> {yes,T}; false -> - case keysearch(S, #dfa_state.nfa, Ms) of - {value,#dfa_state{no=T}} -> {yes,T}; + case lists:keyfind(S, #dfa_state.nfa, Ms) of + #dfa_state{no=T} -> {yes,T}; false -> no end end. @@ -1129,7 +1128,7 @@ eclosure(Sts, NFA) -> eclosure(Sts, NFA, []). eclosure([St|Sts], NFA, Ec) -> #nfa_state{edges=Es} = element(St, NFA), eclosure([ N || {epsilon,N} <- Es, - not is_element(N, Ec) ] ++ Sts, + not is_element(N, Ec) ] ++ Sts, NFA, add_element(St, Ec)); eclosure([], _, Ec) -> Ec. @@ -1137,7 +1136,7 @@ move(Sts, Cr, NFA) -> %% io:fwrite("move1: ~p\n", [{Sts,Cr}]), [ St || N <- Sts, {Crs,St} <- (element(N, NFA))#nfa_state.edges, - Crs /= epsilon, % Not an epsilon transition + Crs =/= epsilon, % Not an epsilon transition in_crs(Cr, Crs) ]. in_crs({C1,C2}, [{C3,C4}|_Crs]) when C1 >= C3, C2 =< C4 -> true; @@ -1436,7 +1435,7 @@ pack_trans([{{$\n,Cl},S}|Trs], Pt) -> pack_trans([{{Cf,Cl},S}|Trs], Pt) when Cf < $\n, Cl > $\n -> pack_trans([{{Cf,$\n-1},S},{{$\n+1,Cl},S}|Trs], [{$\n,S}|Pt]); %% Small ranges become singletons. -pack_trans([{{Cf,Cl},S}|Trs], Pt) when Cl == Cf + 1 -> +pack_trans([{{Cf,Cl},S}|Trs], Pt) when Cl =:= Cf + 1 -> pack_trans(Trs, [{Cf,S},{Cl,S}|Pt]); pack_trans([Tr|Trs], Pt) -> % The default uninteresting case pack_trans(Trs, Pt ++ [Tr]); diff --git a/lib/parsetools/src/yecc.erl b/lib/parsetools/src/yecc.erl index b8b2b2308c..4119e2631b 100644 --- a/lib/parsetools/src/yecc.erl +++ b/lib/parsetools/src/yecc.erl @@ -1582,6 +1582,11 @@ find_action_conflicts2(Rs, Cxt0) -> find_reduce_reduce([R], Cxt) -> {R, Cxt}; +find_reduce_reduce([accept=A, #reduce{}=R | Rs], Cxt0) -> + Confl = conflict(R, A, Cxt0), + St = conflict_error(Confl, Cxt0#cxt.yecc), + Cxt = Cxt0#cxt{yecc = St}, + find_reduce_reduce([R | Rs], Cxt); find_reduce_reduce([#reduce{head = Categ1, prec = {P1, _}}=R1, #reduce{head = Categ2, prec = {P2, _}}=R2 | Rs], Cxt0) -> #cxt{res = Res0, yecc = St0} = Cxt0, @@ -1773,6 +1778,8 @@ add_conflict(Conflict, St) -> case Conflict of {Symbol, StateN, _, {reduce, _, _, _}} -> St#yecc{reduce_reduce = [{StateN,Symbol} |St#yecc.reduce_reduce]}; + {Symbol, StateN, _, {accept, _}} -> + St#yecc{reduce_reduce = [{StateN,Symbol} |St#yecc.reduce_reduce]}; {Symbol, StateN, _, {shift, _, _}} -> St#yecc{shift_reduce = [{StateN,Symbol} | St#yecc.shift_reduce]}; {_Symbol, _StateN, {one_level_up, _, _}, _Confl} -> @@ -1791,6 +1798,8 @@ conflict(#reduce{rule_nmbr = RuleNmbr1}, NewAction, Cxt) -> #cxt{terminal = Symbol, state_n = N, yecc = St} = Cxt, {R1, RuleLine1, RuleN1} = rule(RuleNmbr1, St), Confl = case NewAction of + accept -> + {accept, St#yecc.rootsymbol}; #reduce{rule_nmbr = RuleNmbr2} -> {R2, RuleLine2, RuleN2} = rule(RuleNmbr2, St), {reduce, R2, RuleN2, RuleLine2}; @@ -1830,7 +1839,10 @@ format_conflict({Symbol, N, Reduce, Confl}) -> {shift, NewState, Sym} -> io_lib:fwrite(<<" shift to state ~w, adding right " "sisters to ~s.">>, - [NewState, format_symbol(Sym)]) + [NewState, format_symbol(Sym)]); + {accept, Rootsymbol} -> + io_lib:fwrite(<<" reduce to rootsymbol ~s.">>, + [format_symbol(Rootsymbol)]) end, [S1, S2, S3]. @@ -1863,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"])). @@ -1994,14 +2010,16 @@ output_actions(St0, StateJumps, StateInfo) -> %% Not all the clauses of the dispatcher function yeccpars2() can %% be reached. Only when shifting, that is, calling yeccpars1(), %% will yeccpars2() be called. - Y2CL = [NewState || {_State,{Actions,_J}} <- StateJumps, - {_LA, #shift{state = NewState}} <- Actions], + Y2CL = [NewState || {_State,{Actions,J}} <- StateJumps, + {_LA, #shift{state = NewState}} <- + (Actions + ++ [A || {_Tag,_To,Part} <- [J], A <- Part])], Y2CS = ordsets:from_list([0 | Y2CL]), Y2S = ordsets:from_list([S || {S,_} <- StateJumps]), NY2CS = ordsets:subtract(Y2S, Y2CS), Sel = [{S,true} || S <- ordsets:to_list(Y2CS)] ++ [{S,false} || S <- ordsets:to_list(NY2CS)], - + SelS = [{State,Called} || {{State,_JActions}, {State,Called}} <- lists:zip(StateJumps, lists:keysort(1, Sel))], @@ -2078,7 +2096,7 @@ output_action(St0, State, Terminal, #shift{state = NewState}, IsFirst, _SI) -> output_action(St0, State, Terminal, accept, IsFirst, _SI) -> St10 = delim(St0, IsFirst), St = fwrite(St10, - <<"yeccpars2_~w(_S, ~s, _Ss, Stack, _T, _Ts, _Tzr) ->\n">>, + <<"yeccpars2_~w(_S, ~s, _Ss, Stack, _T, _Ts, _Tzr) ->\n">>, [State, quoted_atom(Terminal)]), fwrite(St, <<" {ok, hd(Stack)}">>, []); output_action(St, _State, _Terminal, nonassoc, _IsFirst, _SI) -> @@ -2092,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, @@ -2402,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} -> @@ -2418,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 b5da414f7b..93949a074a 100644 --- a/lib/parsetools/test/yecc_SUITE.erl +++ b/lib/parsetools/test/yecc_SUITE.erl @@ -44,7 +44,7 @@ empty/1, prec/1, yeccpre/1, lalr/1, old_yecc/1, other_examples/1, bugs/1, - otp_5369/1, otp_6362/1, otp_7945/1, + otp_5369/1, otp_6362/1, otp_7945/1, otp_8483/1, otp_8486/1, improvements/1, otp_7292/1, otp_7969/1]). @@ -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. @@ -1284,7 +1284,7 @@ other_examples(Config) when is_list(Config) -> ok. bugs(suite) -> - [otp_5369, otp_6362, otp_7945]. + [otp_5369, otp_6362, otp_7945, otp_8483, otp_8486]. otp_5369(doc) -> "OTP-5369. A bug in parse_and_scan reported on erlang questions."; @@ -1486,6 +1486,60 @@ otp_7945(Config) when is_list(Config) -> ?line {error,_} = erl_parse:parse([{atom,3,foo},{'.',2,9,9}]), ok. +otp_8483(doc) -> + "OTP-8483. reduce/accept conflict"; +otp_8483(suite) -> []; +otp_8483(Config) when is_list(Config) -> + Dir = ?privdir, + Input = filename:join(Dir, "bug.yrl"), + + Bug1 = <<"Nonterminals elem seq. + Terminals 'foo'. + Rootsymbol elem. + elem -> 'foo'. + elem -> seq. + seq -> elem. + seq -> seq elem.">>, + ?line ok = file:write_file(Input, Bug1), + Ret = [return, {report, true}], + ?line {error,[{_,[{none,yecc,{conflict,_}}, + {none,yecc,{conflict,_}}, + {none,yecc,{conflict,_}}]}], + [{_,[{none,yecc,{conflicts,1,3}}]}]} = + yecc:file(Input, Ret), + file:delete(Input), + ok. + +otp_8486(doc) -> + "OTP-8486."; +otp_8486(suite) -> []; +otp_8486(Config) when is_list(Config) -> + Ts = [{otp_8486,<<" + Nonterminals boolean command. + Terminals '(' ')' if then else true and or skip while do. + Rootsymbol command. + Left 100 or. + Left 200 and. + boolean -> '(' boolean ')' : '$2'. + boolean -> 'true' : b. + boolean -> boolean 'and' boolean : {a,'$1','$3'}. + boolean -> boolean 'or' boolean : {o,'$1','$3'}. + command -> 'skip' : s. + command -> 'if' boolean 'then' command 'else' command : + {i,'$2','$4','$6'}. + command -> 'while' boolean 'do' command : {w,'$2','$4'}. + + Erlang code. + -export([t/0]). + t() -> + {ok,{i,{o,b,b},s,s}} = + parse([{'if',1},{'true',1},{'or',1},{'true',1}, + {'then',1},{'skip',1},{'else',1},{'skip',1}]), + ok. + ">>,default,ok}], + ?line run(Config, Ts), + ok. + improvements(suite) -> [otp_7292, otp_7969]. @@ -1530,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"), @@ -1548,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 b1354e89d8..46915baed6 100644 --- a/lib/parsetools/vsn.mk +++ b/lib/parsetools/vsn.mk @@ -1 +1 @@ -PARSETOOLS_VSN = 2.0.2 +PARSETOOLS_VSN = 2.0.4 diff --git a/lib/public_key/asn1/OTP-PKIX.asn1 b/lib/public_key/asn1/OTP-PKIX.asn1 index 2bcacc0990..c0cf440496 100644 --- a/lib/public_key/asn1/OTP-PKIX.asn1 +++ b/lib/public_key/asn1/OTP-PKIX.asn1 @@ -313,7 +313,7 @@ SupportedPublicKeyAlgorithms PUBLIC-KEY-ALGORITHM-CLASS ::= { dsa-with-sha1 SIGNATURE-ALGORITHM-CLASS ::= { ID id-dsa-with-sha1 - TYPE NULL } -- XXX Must be empty and not NULL + TYPE Dss-Parms } -- -- RSA Keys and Signatures 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/notes.xml b/lib/public_key/doc/src/notes.xml index 33a424f432..ca32063624 100644 --- a/lib/public_key/doc/src/notes.xml +++ b/lib/public_key/doc/src/notes.xml @@ -33,6 +33,125 @@ <rev>A</rev> <file>notes.xml</file> </header> + +<section><title>Public_Key 0.9</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Updated ssl to ignore CA certs that violate the asn1-spec + for a certificate, and updated public key asn1 spec to + handle inherited DSS-params.</p> + <p> + Own Id: OTP-7884</p> + </item> + <item> + <p> + Changed ssl implementation to retain backwards + compatibility for old option {verify, 0} that shall be + equivalent to {verify, verify_none}, also separate the + cases unknown ca and selfsigned peer cert, and restored + return value of deprecated function + public_key:pem_to_der/1.</p> + <p> + Own Id: OTP-8858</p> + </item> + <item> + <p> + Better handling of v1 and v2 certificates. V1 and v2 + certificates does not have any extensions so then + validate_extensions should just accept that there are + none and not end up in missing_basic_constraints clause.</p> + <p> + Own Id: OTP-8867</p> + </item> + <item> + <p> + Changed the verify fun so that it differentiate between + the peer certificate and CA certificates by using + valid_peer or valid as the second argument to the verify + fun. It may not always be trivial or even possible to + know when the peer certificate is reached otherwise.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-8873</p> + </item> + </list> + </section> + +</section> + +<section><title>Public_Key 0.8</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Handling of unknown CA certificates was changed in ssl + and public_key to work as intended.</p> + <p> + Own Id: OTP-8788</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Revise the public_key API - Cleaned up and documented the + public_key API to make it useful for general use, also + changed ssl to use the new API.</p> + <p> + Own Id: OTP-8722</p> + </item> + <item> + <p> + Added the functionality so that the verification fun will + be called when a certificate is considered valid by the + path validation to allow access to each certificate in + the path to the user application. Also try to verify + subject-AltName, if unable to verify it let the + application verify it.</p> + <p> + Own Id: OTP-8825</p> + </item> + </list> + </section> + +</section> + +<section><title>Public_Key 0.7</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Certificates without any extensions could not be handled + by public_key.</p> + <p> + Own Id: OTP-8626</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Code cleanup and minor bugfixes.</p> + <p> + Own Id: OTP-8649</p> + </item> + </list> + </section> + +</section> + <section><title>Public_Key 0.6</title> <section><title>Improvements and New Features</title> 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..4950597fb5 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,17 @@ algorithm, parameters = asn1_NOVALUE}). +-define(DEFAULT_VERIFYFUN, + {fun(_,{bad_cert, _} = Reason, _) -> + {fail, Reason}; + (_,{extension, _}, UserState) -> + {unknown, UserState}; + (_, valid, UserState) -> + {valid, UserState}; + (_, valid_peer, UserState) -> + {valid, UserState} + end, []}). + -record(path_validation_state, { valid_policy_tree, explicit_policy, @@ -42,7 +53,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 +70,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 8f7dfa8352..570f44e530 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, digest/2, is_self_signed/1, - is_issuer/2, issuer_id/2, is_fixed_dh_cert/1]). + normalize_general_name/1, digest_type/1, is_self_signed/1, + is_issuer/2, issuer_id/2, is_fixed_dh_cert/1, + verify_data/1, verify_fun/4]). -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,47 +127,68 @@ 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 -> - ok; + UserState; false -> TBSCert = OtpCert#'OTPCertificate'.tbsCertificate, Subject = TBSCert#'OTPTBSCertificate'.subject, + Extensions = + extensions_list(TBSCert#'OTPTBSCertificate'.extensions), AltSubject = - select_extension(?'id-ce-subjectAltName', - TBSCert#'OTPTBSCertificate'.extensions), + select_extension(?'id-ce-subjectAltName', Extensions), EmailAddress = extract_email(Subject), Name = [{directoryName, Subject}|EmailAddress], AltNames = case AltSubject of - undefined -> []; - _ -> AltSubject#'Extension'.extnValue + undefined -> + []; + _ -> + AltSubject#'Extension'.extnValue end, case (is_permitted(Name, Permit) andalso @@ -151,68 +196,77 @@ 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). - + case TBSCert#'OTPTBSCertificate'.version of + N when N >= 3 -> + Extensions = TBSCert#'OTPTBSCertificate'.extensions, + validate_extensions(OtpCert, Extensions, + ValidationState, no_basic_constraint, + is_self_signed(OtpCert), UserState, VerifyFun); + _ -> %% Extensions not present in versions 1 & 2 + {ValidationState, UserState} + end. +%%-------------------------------------------------------------------- +-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 = TBSCert#'OTPTBSCertificate'.extensions, + Extensions = extensions_list(TBSCert#'OTPTBSCertificate'.extensions), case select_extension(?'id-ce-authorityKeyIdentifier', Extensions) of undefined -> {error, issuer_not_found}; @@ -226,34 +280,92 @@ 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, extensions = Extensions}}) -> - is_fixed_dh_cert(SubjectPublicKeyInfo, Extensions). + is_fixed_dh_cert(SubjectPublicKeyInfo, extensions_list(Extensions)). + + +%%-------------------------------------------------------------------- +-spec verify_fun(#'OTPTBSCertificate'{}, {bad_cert, atom()} | {extension, #'Extension'{}}| + valid | valid_peer, term(), fun()) -> term(). +%% +%% Description: Gives the user application the opportunity handle path +%% validation errors and unknown extensions and optional do other +%% things with a validated certificate. +%% -------------------------------------------------------------------- +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. %%-------------------------------------------------------------------- %%% 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)). -not_valid(Error, true, _) -> - throw(Error); -not_valid(Error, false, AccErrors) -> - [Error | AccErrors]. +%% 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([]) -> []. -verify_signature(OtpCert, DerCert, Key, KeyParams) -> - %% Signature is an ASN1 compact bit string +extensions_list(asn1_NOVALUE) -> + []; +extensions_list(Extensions) -> + Extensions. + + +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} = @@ -269,13 +381,6 @@ digest_type(?md5WithRSAEncryption) -> digest_type(?'id-dsa-with-sha1') -> sha. -digest(?sha1WithRSAEncryption, Msg) -> - crypto:sha(Msg); -digest(?md5WithRSAEncryption, Msg) -> - crypto:md5(Msg); -digest(?'id-dsa-with-sha1', Msg) -> - crypto:sha(Msg). - public_key_info(PublicKeyInfo, #path_validation_state{working_public_key_algorithm = WorkingAlgorithm, @@ -326,12 +431,6 @@ is_dir_name([[{'AttributeTypeAndValue', Type, What1}]|Rest1], true -> is_dir_name(Rest1,Rest2,Exact); false -> false end; -is_dir_name([{'AttributeTypeAndValue', Type, What1}|Rest1], - [{'AttributeTypeAndValue', Type, What2}|Rest2], Exact) -> - case is_dir_name2(What1,What2) of - true -> is_dir_name(Rest1,Rest2,Exact); - false -> false - end; is_dir_name(_,[],false) -> true; is_dir_name(_,_,_) -> @@ -376,210 +475,179 @@ 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, + critical = true} = Ext | 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); - _ -> - AccErr = - not_valid({bad_cert, invalid_subject_altname}, - Verify, AccErr0), - validate_extensions(Rest, ValidationState, ExistBasicCon, - SelfSigned, UnknownExtensions, Verify, - AccErr) + true -> + validate_extensions(OtpCert, Rest, ValidationState, ExistBasicCon, + SelfSigned, UserState0, VerifyFun); + false -> + UserState = verify_fun(OtpCert, {extension, Ext}, + 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); - -%% 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], - ValidationState, - ExistBasicCon, SelfSigned, UnknownExtensions, - Verify, AccErr) - when Id == ?'id-ce-subjectKeyIdentifier'; - Id == ?'id-ce-authorityKeyIdentifier'-> - validate_extensions(Rest, ValidationState, ExistBasicCon, - SelfSigned, UnknownExtensions, Verify, AccErr); - -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). validate_subject_alt_names([]) -> - true; + false; validate_subject_alt_names([AltName | Rest]) -> case is_valid_subject_alt_name(AltName) of true -> - validate_subject_alt_names(Rest); + true; false -> - false + validate_subject_alt_names(Rest) end. is_valid_subject_alt_name({Name, Value}) when Name == rfc822Name; @@ -607,14 +675,11 @@ is_valid_subject_alt_name({directoryName, _}) -> true; is_valid_subject_alt_name({_, [_|_]}) -> true; +is_valid_subject_alt_name({otherName, #'AnotherName'{}}) -> + false; 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, _} -> @@ -677,10 +742,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. @@ -933,7 +999,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 c7d4080adb..20b322b4a4 100644 --- a/lib/public_key/src/pubkey_cert_records.erl +++ b/lib/public_key/src/pubkey_cert_records.erl @@ -23,89 +23,66 @@ -include("public_key.hrl"). --export([decode_cert/2, encode_cert/1, encode_tbs_cert/1, transform/2]). - --export([old_decode_cert/2, old_encode_cert/1]). %% Debugging and testing new code. +-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), - {ok, decode_all_otp(Cert)}. - -old_decode_cert(DerCert, otp) -> - {ok, Cert} = 'OTP-PUB-KEY':decode('Certificate', DerCert), - {ok, plain_to_otp(Cert)}. - -old_encode_cert(Cert) -> - PlainCert = otp_to_plain(Cert), - {ok, EncCert} = 'OTP-PUB-KEY':encode('Certificate', PlainCert), - list_to_binary(EncCert). - - -encode_cert(Cert = #'Certificate'{}) -> - {ok, EncCert} = 'OTP-PUB-KEY':encode('Certificate', Cert), - list_to_binary(EncCert); -encode_cert(C = #'OTPCertificate'{tbsCertificate = TBS = - #'OTPTBSCertificate'{ - issuer=Issuer0, - subject=Subject0, - subjectPublicKeyInfo=Spki0, - extensions=Exts0} - }) -> - Issuer = transform(Issuer0,encode), - Subject = transform(Subject0,encode), - Spki = encode_supportedPublicKey(Spki0), - Exts = encode_extensions(Exts0), - %% io:format("Extensions ~p~n",[Exts]), - Cert = C#'OTPCertificate'{tbsCertificate= - TBS#'OTPTBSCertificate'{ - issuer=Issuer, subject=Subject, - subjectPublicKeyInfo=Spki, - extensions=Exts}}, - {ok, EncCert} = 'OTP-PUB-KEY':encode('OTPCertificate', Cert), - list_to_binary(EncCert). + #'OTPCertificate'{tbsCertificate = TBS} = Cert, + {ok, Cert#'OTPCertificate'{tbsCertificate = decode_tbs(TBS)}}. -encode_tbs_cert(TBS = #'OTPTBSCertificate'{ - issuer=Issuer0, - subject=Subject0, - subjectPublicKeyInfo=Spki0, - extensions=Exts0}) -> - Issuer = transform(Issuer0,encode), - Subject = transform(Subject0,encode), - Spki = encode_supportedPublicKey(Spki0), - Exts = encode_extensions(Exts0), - TBSCert = TBS#'OTPTBSCertificate'{issuer=Issuer,subject=Subject, - subjectPublicKeyInfo=Spki,extensions=Exts}, - {ok, EncTBSCert} = 'OTP-PUB-KEY':encode('OTPTBSCertificate', TBSCert), - 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 %%-------------------------------------------------------------------- -decode_all_otp(C = #'OTPCertificate'{tbsCertificate = TBS = - #'OTPTBSCertificate'{ - issuer=Issuer0, - subject=Subject0, - subjectPublicKeyInfo=Spki0, - extensions=Exts0} - }) -> - Issuer = transform(Issuer0,decode), - Subject = transform(Subject0,decode), - Spki = decode_supportedPublicKey(Spki0), - Exts = decode_extensions(Exts0), - %% io:format("Extensions ~p~n",[Exts]), - C#'OTPCertificate'{tbsCertificate= - TBS#'OTPTBSCertificate'{ - issuer=Issuer, subject=Subject, - subjectPublicKeyInfo=Spki,extensions=Exts}}. - - %%% SubjectPublicKey supportedPublicKeyAlgorithms(?'rsaEncryption') -> 'RSAPublicKey'; supportedPublicKeyAlgorithms(?'id-dsa') -> 'DSAPublicKey'; @@ -186,33 +163,28 @@ 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(List = [{rdnSequence, _}|_],Func) -> -%% lists:map(fun(Element) -> transform(Element,Func) end, List); -transform(#'NameConstraints'{permittedSubtrees=Permitted, excludedSubtrees=Excluded}, Func) -> - Res = #'NameConstraints'{permittedSubtrees=transform_sub_tree(Permitted,Func), - excludedSubtrees=transform_sub_tree(Excluded,Func)}, -%% io:format("~p~n",[Res]), - Res; -transform(Other,_) -> - Other. +encode_tbs(TBS=#'OTPTBSCertificate'{issuer=Issuer0, + subject=Subject0, + subjectPublicKeyInfo=Spki0, + extensions=Exts0}) -> + Issuer = transform(Issuer0,encode), + Subject = transform(Subject0,encode), + Spki = encode_supportedPublicKey(Spki0), + Exts = encode_extensions(Exts0), + TBS#'OTPTBSCertificate'{issuer=Issuer, subject=Subject, + subjectPublicKeyInfo=Spki,extensions=Exts}. + +decode_tbs(TBS = #'OTPTBSCertificate'{issuer=Issuer0, + subject=Subject0, + subjectPublicKeyInfo=Spki0, + extensions=Exts0}) -> + Issuer = transform(Issuer0,decode), + Subject = transform(Subject0,decode), + Spki = decode_supportedPublicKey(Spki0), + Exts = decode_extensions(Exts0), + TBS#'OTPTBSCertificate'{issuer=Issuer, subject=Subject, + subjectPublicKeyInfo=Spki,extensions=Exts}. + transform_sub_tree(asn1_NOVALUE,_) -> asn1_NOVALUE; transform_sub_tree(TreeList,Func) -> [Tree#'GeneralSubtree'{base=transform(Name,Func)} || @@ -236,303 +208,3 @@ attribute_type(?'id-at-pseudonym') -> 'X520Pseudonym'; attribute_type(?'id-domainComponent') -> 'DomainComponent'; attribute_type(?'id-emailAddress') -> 'EmailAddress'; attribute_type(Type) -> Type. - -%%% Old code transforms - -plain_to_otp(#'Certificate'{tbsCertificate = TBSCert, - signatureAlgorithm = SigAlg, - signature = Signature} = Cert) -> - Cert#'Certificate'{tbsCertificate = plain_to_otp(TBSCert), - signatureAlgorithm = plain_to_otp(SigAlg), - signature = plain_to_otp(Signature)}; - -plain_to_otp(#'TBSCertificate'{signature = Signature, - issuer = Issuer, - subject = Subject, - subjectPublicKeyInfo = SPubKeyInfo, - extensions = Extensions} = TBSCert) -> - - TBSCert#'TBSCertificate'{signature = plain_to_otp(Signature), - issuer = plain_to_otp(Issuer), - subject = - plain_to_otp(Subject), - subjectPublicKeyInfo = - plain_to_otp(SPubKeyInfo), - extensions = - plain_to_otp_extensions(Extensions) - }; - -plain_to_otp(#'AlgorithmIdentifier'{algorithm = Algorithm, - parameters = Params}) -> - SignAlgAny = - #'SignatureAlgorithm-Any'{algorithm = Algorithm, - parameters = Params}, - {ok, AnyEnc} = 'OTP-PUB-KEY':encode('SignatureAlgorithm-Any', - SignAlgAny), - {ok, SignAlg} = 'OTP-PUB-KEY':decode('SignatureAlgorithm', - list_to_binary(AnyEnc)), - SignAlg; - -plain_to_otp({rdnSequence, SeqList}) when is_list(SeqList) -> - {rdnSequence, - lists:map(fun(Seq) -> - lists:map(fun(Element) -> - plain_to_otp(Element) - end, - Seq) - end, SeqList)}; - -plain_to_otp(#'AttributeTypeAndValue'{} = ATAV) -> - {ok, ATAVEnc} = - 'OTP-PUB-KEY':encode('AttributeTypeAndValue', ATAV), - {ok, ATAVDec} = 'OTP-PUB-KEY':decode('OTPAttributeTypeAndValue', - list_to_binary(ATAVEnc)), - #'AttributeTypeAndValue'{type = ATAVDec#'OTPAttributeTypeAndValue'.type, - value = - ATAVDec#'OTPAttributeTypeAndValue'.value}; - -plain_to_otp(#'SubjectPublicKeyInfo'{algorithm = - #'AlgorithmIdentifier'{algorithm - = Algo, - parameters = - Params}, - subjectPublicKey = PublicKey}) -> - - AnyAlgo = #'PublicKeyAlgorithm'{algorithm = Algo, - parameters = Params}, - {0, AnyKey} = PublicKey, - AnyDec = #'OTPSubjectPublicKeyInfo-Any'{algorithm = AnyAlgo, - subjectPublicKey = AnyKey}, - {ok, AnyEnc} = - 'OTP-PUB-KEY':encode('OTPSubjectPublicKeyInfo-Any', AnyDec), - {ok, InfoDec} = 'OTP-PUB-KEY':decode('OTPOLDSubjectPublicKeyInfo', - list_to_binary(AnyEnc)), - - AlgorithmDec = InfoDec#'OTPOLDSubjectPublicKeyInfo'.algorithm, - AlgoDec = AlgorithmDec#'OTPOLDSubjectPublicKeyInfo_algorithm'.algo, - NewParams = AlgorithmDec#'OTPOLDSubjectPublicKeyInfo_algorithm'.parameters, - PublicKeyDec = InfoDec#'OTPOLDSubjectPublicKeyInfo'.subjectPublicKey, - NewAlgorithmDec = - #'SubjectPublicKeyInfoAlgorithm'{algorithm = AlgoDec, - parameters = NewParams}, - #'SubjectPublicKeyInfo'{algorithm = NewAlgorithmDec, - subjectPublicKey = PublicKeyDec - }; - -plain_to_otp(#'Extension'{extnID = ExtID, - critical = Critical, - extnValue = Value}) - when ExtID == ?'id-ce-authorityKeyIdentifier'; - ExtID == ?'id-ce-subjectKeyIdentifier'; - ExtID == ?'id-ce-keyUsage'; - ExtID == ?'id-ce-privateKeyUsagePeriod'; - ExtID == ?'id-ce-certificatePolicies'; - ExtID == ?'id-ce-policyMappings'; - ExtID == ?'id-ce-subjectAltName'; - ExtID == ?'id-ce-issuerAltName'; - ExtID == ?'id-ce-subjectDirectoryAttributes'; - ExtID == ?'id-ce-basicConstraints'; - ExtID == ?'id-ce-nameConstraints'; - ExtID == ?'id-ce-policyConstraints'; - ExtID == ?'id-ce-extKeyUsage'; - ExtID == ?'id-ce-cRLDistributionPoints'; - ExtID == ?'id-ce-inhibitAnyPolicy'; - ExtID == ?'id-ce-freshestCRL' -> - ExtAny = #'Extension-Any'{extnID = ExtID, - critical = Critical, - extnValue = Value}, - {ok, AnyEnc} = 'OTP-PUB-KEY':encode('Extension-Any', ExtAny), - {ok, ExtDec} = 'OTP-PUB-KEY':decode('OTPExtension', - list_to_binary(AnyEnc)), - - ExtValue = plain_to_otp_extension_value(ExtID, - ExtDec#'OTPExtension'.extnValue), - #'Extension'{extnID = ExtID, - critical = ExtDec#'OTPExtension'.critical, - extnValue = ExtValue}; - -plain_to_otp(#'Extension'{} = Ext) -> - Ext; - -plain_to_otp(#'AuthorityKeyIdentifier'{} = Ext) -> - CertIssuer = Ext#'AuthorityKeyIdentifier'.authorityCertIssuer, - Ext#'AuthorityKeyIdentifier'{authorityCertIssuer = - plain_to_otp(CertIssuer)}; - - -plain_to_otp([{directoryName, Value}]) -> - [{directoryName, plain_to_otp(Value)}]; - -plain_to_otp(Value) -> - Value. - -otp_to_plain(#'Certificate'{tbsCertificate = TBSCert, - signatureAlgorithm = SigAlg, - signature = Signature} = Cert) -> - Cert#'Certificate'{tbsCertificate = otp_to_plain(TBSCert), - signatureAlgorithm = - otp_to_plain(SigAlg), - signature = otp_to_plain(Signature)}; - -otp_to_plain(#'TBSCertificate'{signature = Signature, - issuer = Issuer, - subject = Subject, - subjectPublicKeyInfo = SPubKeyInfo, - extensions = Extensions} = TBSCert) -> - - TBSCert#'TBSCertificate'{signature = otp_to_plain(Signature), - issuer = otp_to_plain(Issuer), - subject = - otp_to_plain(Subject), - subjectPublicKeyInfo = - otp_to_plain(SPubKeyInfo), - extensions = otp_to_plain_extensions(Extensions) - }; - -otp_to_plain(#'SignatureAlgorithm'{} = SignAlg) -> - {ok, EncSignAlg} = 'OTP-PUB-KEY':encode('SignatureAlgorithm', SignAlg), - {ok, #'SignatureAlgorithm-Any'{algorithm = Algorithm, - parameters = Params}} = - 'OTP-PUB-KEY':decode('SignatureAlgorithm-Any', - list_to_binary(EncSignAlg)), - #'AlgorithmIdentifier'{algorithm = Algorithm, - parameters = Params}; - -otp_to_plain({rdnSequence, SeqList}) when is_list(SeqList) -> - {rdnSequence, - lists:map(fun(Seq) -> - lists:map(fun(Element) -> - otp_to_plain(Element) - end, - Seq) - end, SeqList)}; - -otp_to_plain(#'AttributeTypeAndValue'{type = Type, value = Value}) -> - {ok, ATAVEnc} = - 'OTP-PUB-KEY':encode('OTPAttributeTypeAndValue', - #'OTPAttributeTypeAndValue'{type = Type, - value = Value}), - {ok, ATAVDec} = 'OTP-PUB-KEY':decode('AttributeTypeAndValue', - list_to_binary(ATAVEnc)), - ATAVDec; - -otp_to_plain(#'SubjectPublicKeyInfo'{algorithm = - #'SubjectPublicKeyInfoAlgorithm'{ - algorithm = Algo, - parameters = - Params}, - subjectPublicKey = PublicKey}) -> - - OtpAlgo = #'OTPOLDSubjectPublicKeyInfo_algorithm'{algo = Algo, - parameters = Params}, - OtpDec = #'OTPOLDSubjectPublicKeyInfo'{algorithm = OtpAlgo, - subjectPublicKey = PublicKey}, - {ok, OtpEnc} = - 'OTP-PUB-KEY':encode('OTPOLDSubjectPublicKeyInfo', OtpDec), - - {ok, AnyDec} = 'OTP-PUB-KEY':decode('OTPSubjectPublicKeyInfo-Any', - list_to_binary(OtpEnc)), - - #'OTPSubjectPublicKeyInfo-Any'{algorithm = #'PublicKeyAlgorithm'{ - algorithm = NewAlgo, - parameters = NewParams}, - subjectPublicKey = Bin} = AnyDec, - - #'SubjectPublicKeyInfo'{algorithm = - #'AlgorithmIdentifier'{ - algorithm = NewAlgo, - parameters = plain_key_params(NewParams)}, - subjectPublicKey = - {0, Bin} - }; - -otp_to_plain(#'Extension'{extnID = ExtID, - extnValue = Value} = Ext) -> - ExtValue = - otp_to_plain_extension_value(ExtID, Value), - - Ext#'Extension'{extnValue = ExtValue}; - -otp_to_plain(#'AuthorityKeyIdentifier'{} = Ext) -> - CertIssuer = Ext#'AuthorityKeyIdentifier'.authorityCertIssuer, - Ext#'AuthorityKeyIdentifier'{authorityCertIssuer = - otp_to_plain(CertIssuer)}; - -otp_to_plain([{directoryName, Value}]) -> - [{directoryName, otp_to_plain(Value)}]; - -otp_to_plain(Value) -> - Value. - -plain_key_params('NULL') -> - <<5,0>>; -plain_key_params(Value) -> - Value. - -plain_to_otp_extension_value(?'id-ce-authorityKeyIdentifier', Value) -> - plain_to_otp(Value); -plain_to_otp_extension_value(_, Value) -> - Value. - -plain_to_otp_extensions(Exts) when is_list(Exts) -> - lists:map(fun(Ext) -> plain_to_otp(Ext) end, Exts). - -otp_to_plain_extension_value(?'id-ce-authorityKeyIdentifier', Value) -> - {ok, Enc} = 'OTP-PUB-KEY':encode('AuthorityKeyIdentifier', - otp_to_plain(Value)), - otp_to_plain_extension_value_format(Enc); -otp_to_plain_extension_value(?'id-ce-subjectKeyIdentifier', Value) -> - {ok, Enc} = 'OTP-PUB-KEY':encode('SubjectKeyIdentifier', Value), - otp_to_plain_extension_value_format(Enc); -otp_to_plain_extension_value(?'id-ce-keyUsage', Value) -> - {ok, Enc} = 'OTP-PUB-KEY':encode('KeyUsage', Value), - otp_to_plain_extension_value_format(Enc); -otp_to_plain_extension_value(?'id-ce-privateKeyUsagePeriod', Value) -> - {ok, Enc} = 'OTP-PUB-KEY':encode('PrivateKeyUsagePeriod', Value), - otp_to_plain_extension_value_format(Enc); -otp_to_plain_extension_value(?'id-ce-certificatePolicies', Value) -> - {ok, Enc} = 'OTP-PUB-KEY':encode('CertificatePolicies', Value), - otp_to_plain_extension_value_format(Enc); -otp_to_plain_extension_value(?'id-ce-policyMappings', Value) -> - {ok, Enc} = 'OTP-PUB-KEY':encode('PolicyMappings', Value), - otp_to_plain_extension_value_format(Enc); -otp_to_plain_extension_value(?'id-ce-subjectAltName', Value) -> - {ok, Enc} = 'OTP-PUB-KEY':encode('SubjectAltName', Value), - otp_to_plain_extension_value_format(Enc); -otp_to_plain_extension_value(?'id-ce-issuerAltName', Value) -> - {ok, Enc} = 'OTP-PUB-KEY':encode('IssuerAltName', Value), - otp_to_plain_extension_value_format(Enc); -otp_to_plain_extension_value(?'id-ce-subjectDirectoryAttributes', Value) -> - {ok, Enc} = 'OTP-PUB-KEY':encode('SubjectDirectoryAttributes', Value), - otp_to_plain_extension_value_format(Enc); -otp_to_plain_extension_value(?'id-ce-basicConstraints', Value) -> - {ok, Enc} = 'OTP-PUB-KEY':encode('BasicConstraints', Value), - otp_to_plain_extension_value_format(Enc); -otp_to_plain_extension_value(?'id-ce-nameConstraints', Value) -> - {ok, Enc} = 'OTP-PUB-KEY':encode('NameConstraints', Value), - otp_to_plain_extension_value_format(Enc); -otp_to_plain_extension_value(?'id-ce-policyConstraints', Value) -> - {ok, Enc} = 'OTP-PUB-KEY':encode('PolicyConstraints', Value), - otp_to_plain_extension_value_format(Enc); -otp_to_plain_extension_value(?'id-ce-extKeyUsage', Value) -> - {ok, Enc} = 'OTP-PUB-KEY':encode('ExtKeyUsage', Value), - otp_to_plain_extension_value_format(Enc); -otp_to_plain_extension_value(?'id-ce-cRLDistributionPoints', Value) -> - {ok, Enc} = 'OTP-PUB-KEY':encode('CRLDistributionPoints', Value), - otp_to_plain_extension_value_format(Enc); -otp_to_plain_extension_value(?'id-ce-inhibitAnyPolicy', Value) -> - {ok, Enc} = 'OTP-PUB-KEY':encode('InhibitAnyPolicy', Value), - otp_to_plain_extension_value_format(Enc); -otp_to_plain_extension_value(?'id-ce-freshestCRL', Value) -> - {ok, Enc} = 'OTP-PUB-KEY':encode('FreshestCRL', Value), - otp_to_plain_extension_value_format(Enc); -otp_to_plain_extension_value(_Id, Value) -> - Value. - -otp_to_plain_extension_value_format(Value) -> - list_to_binary(Value). - -otp_to_plain_extensions(Exts) when is_list(Exts) -> - lists:map(fun(Ext) -> - otp_to_plain(Ext) - end, Exts). diff --git a/lib/public_key/src/pubkey_crypto.erl b/lib/public_key/src/pubkey_crypto.erl deleted file mode 100644 index 4ab655e977..0000000000 --- a/lib/public_key/src/pubkey_crypto.erl +++ /dev/null @@ -1,160 +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(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(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 9fc17b6f73..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,82 +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)}. - -%% TODO Support same as decode_file -encode_file(Ds) -> - lists:map( - fun({cert, Bin}) -> - %% PKIX (X.509) - ["-----BEGIN CERTIFICATE-----\n", - b64encode_and_split(Bin), - "-----END CERTIFICATE-----\n\n"]; - ({cert_req, Bin}) -> - %% PKCS#10 - ["-----BEGIN CERTIFICATE REQUEST-----\n", - b64encode_and_split(Bin), - "-----END CERTIFICATE REQUEST-----\n\n"]; - ({rsa_private_key, Bin}) -> - %% PKCS#? - ["XXX Following key assumed not encrypted\n", - "-----BEGIN RSA PRIVATE KEY-----\n", - b64encode_and_split(Bin), - "-----END RSA 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, @@ -171,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, <<>>), @@ -182,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 edede7c874..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' @@ -13,4 +12,5 @@ {registered, []}, {env, []} ] -}.
\ No newline at end of file +}. + diff --git a/lib/public_key/src/public_key.appup.src b/lib/public_key/src/public_key.appup.src index 46e5ecca33..0f9f62d2f6 100644 --- a/lib/public_key/src/public_key.appup.src +++ b/lib/public_key/src/public_key.appup.src @@ -1,40 +1,24 @@ %% -*- erlang -*- {"%VSN%", [ - {"0.5", + {"0.8", [ + {update, 'OTP-PUB-KEY', soft, soft_purge, soft_purge, []}, {update, public_key, soft, soft_purge, soft_purge, []}, - {update, pubkey_crypto, soft, soft_purge, soft_purge, []}, {update, pubkey_pem, soft, soft_purge, soft_purge, []}, - {update, pubkey_cert, soft, soft_purge, soft_purge, []} - ] - }, - {"0.4", - [ - {update, public_key, soft, soft_purge, soft_purge, []}, {update, pubkey_cert_records, soft, soft_purge, soft_purge, []}, - {update, pubkey_crypto, soft, soft_purge, soft_purge, []}, - {update, pubkey_pem, soft, soft_purge, soft_purge, []}, {update, pubkey_cert, soft, soft_purge, soft_purge, []} - ] + ] } ], [ - {"0.5", + {"0.8", [ + {update, 'OTP-PUB-KEY', soft, soft_purge, soft_purge, []}, {update, public_key, soft, soft_purge, soft_purge, []}, - {update, pubkey_crypto, soft, soft_purge, soft_purge, []}, {update, pubkey_pem, soft, soft_purge, soft_purge, []}, - {update, pubkey_cert, soft, soft_purge, soft_purge, []} - ] - }, - {"0.4", - [ - {update, public_key, soft, soft_purge, soft_purge, []}, {update, pubkey_cert_records, soft, soft_purge, soft_purge, []}, - {update, pubkey_crypto, soft, soft_purge, soft_purge, []}, - {update, pubkey_pem, soft, soft_purge, soft_purge, []}, {update, pubkey_cert, soft, soft_purge, soft_purge, []} ] - } + } ]}. diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index 157e76bb21..d514b9a3aa 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_oaep_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_oaep_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 +-spec pkix_sign(#'OTPTBSCertificate'{}, + rsa_private_key() | dsa_private_key()) -> der_encoded(). %% -%% CertPart = pkix part data -%% Op = encode | decode -%% -%% 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,151 +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 +-spec pkix_normalize_name({rdnSequence, + [#'AttributeTypeAndValue'{}]}) -> + {rdnSequence, + [#'AttributeTypeAndValue'{}]}. %% -%% Cert = asn1_der_encoded() | 'OTPCertificate'{} -%% IssuerCert = asn1_der_encoded() | 'OTPCertificate'{} -%% -%% 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'{} | atom(), + 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(PathErr, [Cert | Chain], Options0) when is_atom(PathErr)-> + {VerifyFun, Userstat0} = + proplists:get_value(verify_fun, Options0, ?DEFAULT_VERIFYFUN), + Otpcert = pkix_decode_cert(Cert, otp), + Reason = {bad_cert, PathErr}, + 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(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, @@ -419,38 +537,60 @@ 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), + UserState6 = pubkey_cert:validate_signature(OtpCert, DerCert, + Key, KeyParams, UserState5, VerifyFun), + UserState = case Last of + false -> + pubkey_cert:verify_fun(OtpCert, valid, UserState6, VerifyFun); + true -> + pubkey_cert:verify_fun(OtpCert, valid_peer, + UserState6, VerifyFun) + end, + 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), + {ok, 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 c7215020c7..e20b903942 100644 --- a/lib/public_key/test/Makefile +++ b/lib/public_key/test/Makefile @@ -28,6 +28,7 @@ INCLUDES= -I. -I ../include # ---------------------------------------------------- MODULES= \ + erl_make_certs \ public_key_SUITE \ pkits_SUITE @@ -40,6 +41,9 @@ TARGET_FILES= \ SPEC_FILES = public_key.spec +COVER_FILE = public_key.cover + + # ---------------------------------------------------- # Release directory specification # ---------------------------------------------------- @@ -74,7 +78,7 @@ release_spec: opt release_tests_spec: opt $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) $(SPEC_FILES) $(ERL_FILES) $(HRL_FILES)$(RELSYSDIR) + $(INSTALL_DATA) $(SPEC_FILES) $(ERL_FILES) $(COVER_FILE) $(HRL_FILES) $(RELSYSDIR) $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR) chmod -f -R u+w $(RELSYSDIR) @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) diff --git a/lib/public_key/test/erl_make_certs.erl b/lib/public_key/test/erl_make_certs.erl new file mode 100644 index 0000000000..e31e5552d3 --- /dev/null +++ b/lib/public_key/test/erl_make_certs.erl @@ -0,0 +1,421 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% +%% + +%% Create test certificates + +-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]). +-compile(export_all). + +%%-------------------------------------------------------------------- +%% @doc Create and return a der encoded certificate +%% Option Default +%% ------------------------------------------------------- +%% digest sha1 +%% validity {date(), date() + week()} +%% version 3 +%% subject [] list of the following content +%% {name, Name} +%% {email, Email} +%% {city, City} +%% {state, State} +%% {org, Org} +%% {org_unit, OrgUnit} +%% {country, Country} +%% {serial, Serial} +%% {title, Title} +%% {dnQualifer, DnQ} +%% issuer = {Issuer, IssuerKey} true (i.e. a ca cert is created) +%% (obs IssuerKey migth be {Key, Password} +%% key = KeyFile|KeyBin|rsa|dsa Subject PublicKey rsa or dsa generates key +%% +%% +%% (OBS: The generated keys are for testing only) +%% @spec ([{::atom(), ::term()}]) -> {Cert::binary(), Key::binary()} +%% @end +%%-------------------------------------------------------------------- + +make_cert(Opts) -> + SubjectPrivateKey = get_key(Opts), + {TBSCert, IssuerKey} = make_tbs(SubjectPrivateKey, Opts), + Cert = public_key:pkix_sign(TBSCert, IssuerKey), + true = verify_signature(Cert, IssuerKey, undef), %% verify that the keys where ok + {Cert, encode_key(SubjectPrivateKey)}. + +%%-------------------------------------------------------------------- +%% @doc Writes pem files in Dir with FileName ++ ".pem" and FileName ++ "_key.pem" +%% @spec (::string(), ::string(), {Cert,Key}) -> ok +%% @end +%%-------------------------------------------------------------------- +write_pem(Dir, FileName, {Cert, Key = {_,_,not_encrypted}}) when is_binary(Cert) -> + 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) +%% the size are in bytes +%% @spec (::integer()) -> {::atom(), ::binary(), ::opaque()} +%% @end +%%-------------------------------------------------------------------- +gen_rsa(Size) when is_integer(Size) -> + Key = gen_rsa2(Size), + {Key, encode_key(Key)}. + +%%-------------------------------------------------------------------- +%% @doc Creates a dsa key (OBS: for testing only) +%% the sizes are in bytes +%% @spec (::integer()) -> {::atom(), ::binary(), ::opaque()} +%% @end +%%-------------------------------------------------------------------- +gen_dsa(LSize,NSize) when is_integer(LSize), is_integer(NSize) -> + Key = gen_dsa2(LSize, NSize), + {Key, encode_key(Key)}. + +%%-------------------------------------------------------------------- +%% @doc Verifies cert signatures +%% @spec (::binary(), ::tuple()) -> ::boolean() +%% @end +%%-------------------------------------------------------------------- +verify_signature(DerEncodedCert, DerKey, _KeyParams) -> + Key = decode_key(DerKey), + case Key of + #'RSAPrivateKey'{modulus=Mod, publicExponent=Exp} -> + public_key:pkix_verify(DerEncodedCert, + #'RSAPublicKey'{modulus=Mod, publicExponent=Exp}); + #'DSAPrivateKey'{p=P, q=Q, g=G, y=Y} -> + public_key:pkix_verify(DerEncodedCert, {Y, #'Dss-Parms'{p=P, q=Q, g=G}}) + end. + +%%%%%%%%%%%%%%%%%%%%%%%%% Implementation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +get_key(Opts) -> + case proplists:get_value(key, Opts) of + undefined -> make_key(rsa, Opts); + rsa -> make_key(rsa, Opts); + dsa -> make_key(dsa, Opts); + Key -> + Password = proplists:get_value(password, Opts, no_passwd), + decode_key(Key, Password) + end. + +decode_key({Key, Pw}) -> + decode_key(Key, Pw); +decode_key(Key) -> + decode_key(Key, no_passwd). + + +decode_key(#'RSAPublicKey'{} = Key,_) -> + Key; +decode_key(#'RSAPrivateKey'{} = Key,_) -> + Key; +decode_key(#'DSAPrivateKey'{} = Key,_) -> + Key; +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), + {'RSAPrivateKey', list_to_binary(Der), not_encrypted}; +encode_key(Key = #'DSAPrivateKey'{}) -> + {ok, Der} = 'OTP-PUB-KEY':encode('DSAPrivateKey', Key), + {'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))), + + 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, + subjectPublicKeyInfo = publickey(SubjectKey), + version = Version, + extensions = extensions(Opts) + }, IssuerKey}. + +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) -> + Decoded = public_key:pkix_decode_cert(Issuer, otp), + #'OTPCertificate'{tbsCertificate=Tbs} = Decoded, + #'OTPTBSCertificate'{subject=Subject} = Tbs, + Subject. + +subject(undefined, IsRootCA) -> + User = if IsRootCA -> "RootCA"; true -> os:getenv("USER") end, + Opts = [{email, User ++ "@erlang.org"}, + {name, User}, + {city, "Stockholm"}, + {country, "SE"}, + {org, "erlang"}, + {org_unit, "testing dep"}], + subject(Opts); +subject(Opts, _) -> + subject(Opts). + +subject(SubjectOpts) when is_list(SubjectOpts) -> + Encode = fun(Opt) -> + {Type,Value} = subject_enc(Opt), + [#'AttributeTypeAndValue'{type=Type, value=Value}] + end, + {rdnSequence, [Encode(Opt) || Opt <- SubjectOpts]}. + +%% Fill in the blanks +subject_enc({name, Name}) -> {?'id-at-commonName', {printableString, Name}}; +subject_enc({email, Email}) -> {?'id-emailAddress', Email}; +subject_enc({city, City}) -> {?'id-at-localityName', {printableString, City}}; +subject_enc({state, State}) -> {?'id-at-stateOrProvinceName', {printableString, State}}; +subject_enc({org, Org}) -> {?'id-at-organizationName', {printableString, Org}}; +subject_enc({org_unit, OrgUnit}) -> {?'id-at-organizationalUnitName', {printableString, OrgUnit}}; +subject_enc({country, Country}) -> {?'id-at-countryName', Country}; +subject_enc({serial, Serial}) -> {?'id-at-serialNumber', Serial}; +subject_enc({title, Title}) -> {?'id-at-title', {printableString, Title}}; +subject_enc({dnQualifer, DnQ}) -> {?'id-at-dnQualifier', DnQ}; +subject_enc(Other) -> Other. + + +extensions(Opts) -> + case proplists:get_value(extensions, Opts, []) of + false -> + asn1_NOVALUE; + Exts -> + lists:flatten([extension(Ext) || Ext <- default_extensions(Exts)]) + end. + +default_extensions(Exts) -> + Def = [{key_usage,undefined}, + {subject_altname, undefined}, + {issuer_altname, undefined}, + {basic_constraints, default}, + {name_constraints, undefined}, + {policy_constraints, undefined}, + {ext_key_usage, undefined}, + {inhibit_any, undefined}, + {auth_key_id, undefined}, + {subject_key_id, undefined}, + {policy_mapping, undefined}], + Filter = fun({Key, _}, D) -> lists:keydelete(Key, 1, D) end, + Exts ++ lists:foldl(Filter, Def, Exts). + +extension({_, undefined}) -> []; +extension({basic_constraints, Data}) -> + case Data of + default -> + #'Extension'{extnID = ?'id-ce-basicConstraints', + extnValue = #'BasicConstraints'{cA=true}, + critical=true}; + false -> + []; + Len when is_integer(Len) -> + #'Extension'{extnID = ?'id-ce-basicConstraints', + extnValue = #'BasicConstraints'{cA=true, pathLenConstraint=Len}, + critical=true}; + _ -> + #'Extension'{extnID = ?'id-ce-basicConstraints', + extnValue = Data} + end; +extension({Id, Data, Critical}) -> + #'Extension'{extnID = Id, extnValue = Data, critical = Critical}. + + +publickey(#'RSAPrivateKey'{modulus=N, publicExponent=E}) -> + Public = #'RSAPublicKey'{modulus=N, publicExponent=E}, + Algo = #'PublicKeyAlgorithm'{algorithm= ?rsaEncryption, parameters='NULL'}, + #'OTPSubjectPublicKeyInfo'{algorithm = Algo, + subjectPublicKey = Public}; +publickey(#'DSAPrivateKey'{p=P, q=Q, g=G, y=Y}) -> + Algo = #'PublicKeyAlgorithm'{algorithm= ?'id-dsa', + parameters=#'Dss-Parms'{p=P, q=Q, g=G}}, + #'OTPSubjectPublicKeyInfo'{algorithm = Algo, subjectPublicKey = Y}. + +validity(Opts) -> + 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, + #'Validity'{notBefore={generalTime, Format(DefFrom)}, + notAfter ={generalTime, Format(DefTo)}}. + +sign_algorithm(#'RSAPrivateKey'{}, Opts) -> + Type = case proplists:get_value(digest, Opts, sha1) of + sha1 -> ?'sha1WithRSAEncryption'; + sha512 -> ?'sha512WithRSAEncryption'; + sha384 -> ?'sha384WithRSAEncryption'; + sha256 -> ?'sha256WithRSAEncryption'; + md5 -> ?'md5WithRSAEncryption'; + md2 -> ?'md2WithRSAEncryption' + end, + {Type, 'NULL'}; +sign_algorithm(#'DSAPrivateKey'{p=P, q=Q, g=G}, _Opts) -> + {?'id-dsa-with-sha1', #'Dss-Parms'{p=P, q=Q, g=G}}. + +make_key(rsa, _Opts) -> + %% (OBS: for testing only) + gen_rsa2(64); +make_key(dsa, _Opts) -> + gen_dsa2(128, 20). %% Bytes i.e. {1024, 160} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% RSA key generation (OBS: for testing only) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +-define(SMALL_PRIMES, [65537,97,89,83,79,73,71,67,61,59,53, + 47,43,41,37,31,29,23,19,17,13,11,7,5,3]). + +gen_rsa2(Size) -> + P = prime(Size), + Q = prime(Size), + N = P*Q, + Tot = (P - 1) * (Q - 1), + [E|_] = lists:dropwhile(fun(Candidate) -> (Tot rem Candidate) == 0 end, ?SMALL_PRIMES), + {D1,D2} = extended_gcd(E, Tot), + D = erlang:max(D1,D2), + case D < E of + true -> + gen_rsa2(Size); + false -> + {Co1,Co2} = extended_gcd(Q, P), + Co = erlang:max(Co1,Co2), + #'RSAPrivateKey'{version = 'two-prime', + modulus = N, + publicExponent = E, + privateExponent = D, + prime1 = P, + prime2 = Q, + exponent1 = D rem (P-1), + exponent2 = D rem (Q-1), + coefficient = Co + } + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% DSA key generation (OBS: for testing only) +%% See http://en.wikipedia.org/wiki/Digital_Signature_Algorithm +%% and the fips_186-3.pdf +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +gen_dsa2(LSize, NSize) -> + Q = prime(NSize), %% Choose N-bit prime Q + X0 = prime(LSize), + P0 = prime((LSize div 2) +1), + + %% Choose L-bit prime modulus P such that p–1 is a multiple of q. + case dsa_search(X0 div (2*Q*P0), P0, Q, 1000) of + error -> + gen_dsa2(LSize, NSize); + P -> + G = crypto:mod_exp(2, (P-1) div Q, P), % Choose G a number whose multiplicative order modulo p is q. + %% such that This may be done by setting g = h^(p–1)/q mod p, commonly h=2 is used. + + X = prime(20), %% Choose x by some random method, where 0 < x < q. + Y = crypto:mod_exp(G, X, P), %% Calculate y = g^x mod p. + + #'DSAPrivateKey'{version=0, p=P, q=Q, g=G, y=Y, x=X} + end. + +%% See fips_186-3.pdf +dsa_search(T, P0, Q, Iter) when Iter > 0 -> + P = 2*T*Q*P0 + 1, + case is_prime(crypto:mpint(P), 50) of + true -> P; + false -> dsa_search(T+1, P0, Q, Iter-1) + end; +dsa_search(_,_,_,_) -> + error. + + +%%%%%%% Crypto Math %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +prime(ByteSize) -> + Rand = odd_rand(ByteSize), + crypto:erlint(prime_odd(Rand, 0)). + +prime_odd(Rand, N) -> + case is_prime(Rand, 50) of + true -> + Rand; + false -> + NotPrime = crypto:erlint(Rand), + prime_odd(crypto:mpint(NotPrime+2), N+1) + end. + +%% see http://en.wikipedia.org/wiki/Fermat_primality_test +is_prime(_, 0) -> true; +is_prime(Candidate, Test) -> + CoPrime = odd_rand(<<0,0,0,4, 10000:32>>, Candidate), + case crypto:mod_exp(CoPrime, Candidate, Candidate) of + CoPrime -> is_prime(Candidate, Test-1); + _ -> false + end. + +odd_rand(Size) -> + Min = 1 bsl (Size*8-1), + Max = (1 bsl (Size*8))-1, + odd_rand(crypto:mpint(Min), crypto:mpint(Max)). + +odd_rand(Min,Max) -> + Rand = <<Sz:32, _/binary>> = crypto:rand_uniform(Min,Max), + BitSkip = (Sz+4)*8-1, + case Rand of + Odd = <<_:BitSkip, 1:1>> -> Odd; + Even = <<_:BitSkip, 0:1>> -> + crypto:mpint(crypto:erlint(Even)+1) + end. + +extended_gcd(A, B) -> + case A rem B of + 0 -> + {0, 1}; + N -> + {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.cover b/lib/public_key/test/public_key.cover new file mode 100644 index 0000000000..8477c76ef6 --- /dev/null +++ b/lib/public_key/test/public_key.cover @@ -0,0 +1,2 @@ + +{exclude, ['OTP-PUB-KEY']}.
\ No newline at end of file diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl index 8cc36e490d..81e01f3a02 100644 --- a/lib/public_key/test/public_key_SUITE.erl +++ b/lib/public_key/test/public_key_SUITE.erl @@ -101,14 +101,12 @@ all(doc) -> all(suite) -> [app, - pem_to_der, - decode_private_key -%% encrypt_decrypt, -%% rsa_verify -%% dsa_verify_sign, -%% pkix_encode_decode, -%% pkix_verify_sign, -%% pkix_path_validation + pk_decode_encode, + encrypt_decrypt, + sign_verify, + pkix, + pkix_path_validation, + deprecated ]. %% Test cases starts here. @@ -118,144 +116,324 @@ app(doc) -> "Test that the public_key app file is ok"; app(suite) -> []; -app(Config) when list(Config) -> +app(Config) when is_list(Config) -> ok = test_server:app_test(public_key). -pem_to_der(doc) -> - ["Check that supported PEM files are decoded into the expected entry type"]; -pem_to_der(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) -> []; -pem_to_der(Config) when is_list(Config) -> +pk_decode_encode(Config) when is_list(Config) -> Datadir = ?config(data_dir, Config), - {ok,[{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,[{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), + + [{'DSAPrivateKey', DerDSAKey, not_encrypted} = Entry0 ] = + erl_make_certs:pem_to_der(filename:join(Datadir, "dsa.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")), + 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'), - {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"), + 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"), + + Des3KeyFile = filename:join(Datadir, "des3_client_key.pem"), + + erl_make_certs:der_to_pem(Des3KeyFile, [Entry3]), + + [{'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) -> - RSAPrivateKey = #'RSAPrivateKey'{publicExponent = 17, - modulus = 3233, - privateExponent = 2753, - prime1 = 61, - prime2 = 53, - version = 'two-prime'}, - Msg = <<0,123>>, - {ok, Encrypted} = public_key:encrypt(Msg, RSAPrivateKey, [{block_type, 2}]), - test_server:format("Expected 855, Encrypted ~p ~n", [Encrypted]), + {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")), + RsaEncrypted = public_key:encrypt_private(Msg, PrivateKey), + Msg = public_key:decrypt_public(RsaEncrypted, PublicKey), + Msg = public_key:decrypt_public(RsaEncrypted, PrivateKey), + RsaEncrypted2 = public_key:encrypt_public(Msg, PublicKey), + RsaEncrypted3 = public_key:encrypt_public(Msg, PrivateKey), + Msg = public_key:decrypt_private(RsaEncrypted2, PrivateKey), + Msg = public_key:decrypt_private(RsaEncrypted3, PrivateKey), + ok. + +%%-------------------------------------------------------------------- +sign_verify(doc) -> + ["Checks that we can sign and verify signatures."]; +sign_verify(suite) -> + []; +sign_verify(Config) when is_list(Config) -> + %% Make cert signs and validates the signature using RSA and DSA + Ca = {_, CaKey} = erl_make_certs:make_cert([]), + PrivateRSA = #'RSAPrivateKey'{modulus=Mod, publicExponent=Exp} = + public_key:pem_entry_decode(CaKey), + + CertInfo = {Cert1,CertKey1} = erl_make_certs:make_cert([{key, dsa}, {issuer, Ca}]), + + PublicRSA = #'RSAPublicKey'{modulus=Mod, publicExponent=Exp}, + true = public_key:pkix_verify(Cert1, PublicRSA), + + {Cert2,_CertKey} = erl_make_certs:make_cert([{issuer, CertInfo}]), + + #'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(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), + [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, sha, DSAPrivateKey), + DSAPublicKey = Y1, + DSAParams = #'Dss-Parms'{p=P1, q=Q1, g=G1}, + 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), + 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, + [TestTransform(Cert) || Cert <- Certs0 ++ Certs1], + 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)) || + {'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_name(TestStr), -%% Datadir = ?config(data_dir, Config), -%% {ok,[{rsa_private_key, EncKey}]} = -%% public_key:pem_to_der(filename:join(Datadir, "server_key.pem")), -%% {ok, Key} = public_key:decode_private_key(EncKey, rsa), -%% RSAPublicKey = #'RSAPublicKey'{publicExponent = -%% Key#'RSAPrivateKey'.publicExponent, -%% modulus = Key#'RSAPrivateKey'.modulus}, -%% {ok, Msg} = file:read_file(filename:join(Datadir, "msg.txt")), -%% Hash = crypto:sha(Msg), -%% {ok, Encrypted} = public_key:encrypt(Hash, Key, [{block_type, 2}]), -%% test_server:format("Encrypted ~p", [Encrypted]), -%% {ok, Decrypted} = public_key:decrypt(Encrypted, -%% RSAPublicKey, [{block_type, 1}]), -%% test_server:format("Encrypted ~p", [Decrypted]), -%% true = Encrypted == Decrypted. - + ok. %%-------------------------------------------------------------------- -rsa_verify(doc) -> - ["Cheks that we can verify an rsa signature."]; -rsa_verify(suite) -> +pkix_path_validation(doc) -> + "Misc pkix tests not covered elsewhere"; +pkix_path_validation(suite) -> []; -rsa_verify(Config) when is_list(Config) -> - Datadir = ?config(data_dir, Config), +pkix_path_validation(Config) when is_list(Config) -> + CaK = {Trusted,_} = + erl_make_certs:make_cert([{key, dsa}, + {subject, [ + {name, "Public Key"}, + {?'id-at-name', {printableString, "public_key"}}, + {?'id-at-pseudonym', {printableString, "pubkey"}}, + {city, "Stockholm"}, + {country, "SE"}, + {org, "erlang"}, + {org_unit, "testing dep"} + ]} + ]), + ok = erl_make_certs:write_pem("./", "public_key_cacert", CaK), + + 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,[{cert, DerCert}]} = - public_key:pem_to_der(filename:join(Datadir, "server_cert.pem")), + {ok, _} = public_key:pkix_path_validation(Trusted, [Cert1], []), - {ok, OTPCert} = public_key:pkix_decode_cert(DerCert, otp), + {error, {bad_cert,invalid_issuer}} = + public_key:pkix_path_validation(Trusted, [Cert2], []), - {0, Signature} = OTPCert#'Certificate'.signature, - TBSCert = OTPCert#'Certificate'.tbsCertificate, + {ok, _} = public_key:pkix_path_validation(Trusted, [Cert1, Cert2], []), + {error, issuer_not_found} = public_key:pkix_issuer_id(Cert2, other), - #'TBSCertificate'{subjectPublicKeyInfo = Info} = TBSCert, - - #'SubjectPublicKeyInfo'{subjectPublicKey = RSAPublicKey} = Info, - - EncTBSCert = encoded_tbs_cert(DerCert), - Digest = crypto:sha(EncTBSCert), - - public_key:verify_signature(Digest, Signature, RSAPublicKey). - - -%% Signature is generated in the following way (in datadir): -%% openssl dgst -sha1 -binary -out rsa_signature -sign server_key.pem msg.txt -%%{ok, Signature} = file:read_file(filename:join(Datadir, "rsa_signature")), -%%{ok, Signature} = file:read_file(filename:join(Datadir, "rsa_signature")), -%% {ok, Msg} = file:read_file(filename:join(Datadir, "msg.txt")), -%% Digest = crypto:sha(Msg), -%% {ok,[{rsa_private_key, EncKey}]} = -%% public_key:pem_to_der(filename:join(Datadir, "server_key.pem")), -%% {ok, Key} = public_key:decode_private_key(EncKey, rsa), -%% RSAPublicKey = #'RSAPublicKey'{publicExponent = -%% Key#'RSAPrivateKey'.publicExponent, -%% modulus = Key#'RSAPrivateKey'.modulus}, - -encoded_tbs_cert(Cert) -> - {ok, PKIXCert} = - 'OTP-PUB-KEY':decode_TBSCert_exclusive(Cert), - {'Certificate', - {'Certificate_tbsCertificate', EncodedTBSCert}, _, _} = PKIXCert, - EncodedTBSCert. + 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], []), + + VerifyFunAndState0 = {fun(_,{bad_cert, missing_basic_constraint}, UserState) -> + {valid, UserState}; + (_,{bad_cert, _} = Reason, _) -> + {fail, Reason}; + (_,{extension, _}, UserState) -> + {unknown, UserState}; + (_, valid, UserState) -> + {valid, UserState}; + (_, valid_peer, UserState) -> + {valid, 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}; + (_, valid, UserState) -> + {valid, 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), + {ok, [DsaKey = {'DSAPrivateKey', _DsaKey, _}]} = + public_key:pem_to_der(filename:join(Datadir, "dsa.pem")), + {ok, [RsaKey = {'RSAPrivateKey', _RsaKey,_}]} = + public_key:pem_to_der(filename:join(Datadir, "client_key.pem")), + {ok, [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 da1465d538..2810942171 100644 --- a/lib/public_key/vsn.mk +++ b/lib/public_key/vsn.mk @@ -1,8 +1 @@ -PUBLIC_KEY_VSN = 0.6 -TICKETS = OTP-7046 \ - OTP-8553 -#TICKETS_o.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.9 diff --git a/lib/reltool/bin/reltool.escript b/lib/reltool/bin/reltool.escript new file mode 100755 index 0000000000..0dcd5ad1e9 --- /dev/null +++ b/lib/reltool/bin/reltool.escript @@ -0,0 +1,249 @@ +#!/usr/bin/env escript +%% -*- erlang -*- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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_lib("reltool/src/reltool.hrl"). + +main(Args) -> + process_flag(trap_exit, true), + try + Tokens = scan_args(Args, [], []), + {Options, Actions} = parse_args(Tokens, []), + case invoke(Options, Actions) of + ok -> + safe_stop(0); + {error, ReasonString} -> + fatal_error(ReasonString, 2) + end + catch + throw:usage -> + usage(), + safe_stop(1); + exit:Reason -> + String = lists:flatten(io_lib:format("EXIT: ~p", [Reason])), + fatal_error(String, 3) + end. + +usage() -> + Usage = + [ + "[Config] [--window]", + "[Config] --create_config [-defaults] [-derived] [ConfigFile]", + "[Config] --create_rel RelName [RelFile]", + "[Config] --create_script RelName [ScriptFile]", + "[Config] --create_target TargetDir", + "[Config] --create_target_spec [SpecFile]", + "[Config] --eval_target_spec Spec TargetDir RootDir" + ], + Script = script_name(), + String = lists:flatten([[Script, " ", U, "\n"] || U <- Usage]), + io:format("Erlang/OTP release management tool\n\n" + "~s\nConfig = ConfigFile | '{sys, [sys()]}'\n" + "Spec = SpecFile | '{spec, [target_spec()}']\n\n" + "See User's guide and Reference manual for more info.\n", + [String]). + +safe_stop(Code) -> + init:stop(Code), + timer:sleep(infinity). + +invoke(Options, Actions) -> + case Actions of + [] -> + invoke(Options, [["--window"]]); + [["--window"]] -> + start_window(Options); + [["--create_config" | OptArgs]] -> + DefArg = "-defaults", + DerivArg = "-derived", + InclDef = lists:member(DefArg, OptArgs), + InclDeriv = lists:member(DerivArg, OptArgs), + case reltool:get_config(Options, InclDef, InclDeriv) of + {ok, Config} -> + String = pretty("config", Config), + case OptArgs -- [DefArg, DerivArg] of + [] -> + format("~s", [String]); + [ConfigFile] -> + write_file(ConfigFile, String); + _ -> + throw(usage) + end; + {error, Reason} -> + {error, Reason} + end; + [["--create_rel", RelName | OptArgs]] -> + case reltool:get_rel(Options, RelName) of + {ok, Rel} -> + String = pretty("rel", Rel), + case OptArgs of + [] -> + format("~s", [String]); + [RelFile] -> + write_file(RelFile, String); + _ -> + throw(usage) + end; + {error, Reason} -> + {error, Reason} + end; + [["--create_script", RelName | OptArgs]] -> + case reltool:get_script(Options, RelName) of + {ok, Script} -> + String = pretty("script", Script), + case OptArgs of + [] -> + format("~s", [String]); + [ScriptFile] -> + write_file(ScriptFile, String); + _ -> + throw(usage) + end; + {error, Reason} -> + {error, Reason} + end; + [["--create_target", TargetDir]] -> + reltool:create_target(Options, TargetDir); + [["--create_target_spec" | OptArgs]] -> + case reltool:get_target_spec(Options) of + {ok, Script} -> + String = pretty("target_spec", Script), + case OptArgs of + [] -> + format("~s", [String]); + [SpecFile] -> + write_file(SpecFile, String); + _ -> + throw(usage) + end; + {error, Reason} -> + {error, Reason} + end; + [["--eval_target_spec", TargetSpec, TargetDir, RootDir]] -> + try + {ok, Tokens, _} = erl_scan:string(TargetSpec ++ ". "), + {ok, {spec, Spec}} = erl_parse:parse_term(Tokens), + reltool:eval_target_spec(Spec, TargetDir, RootDir) + catch + error:{badmatch, _} -> + case file:consult(TargetSpec) of + {ok, Spec2} -> + reltool:eval_target_spec(Spec2, TargetDir, RootDir); + {error, Reason} -> + Text = file:format_error(Reason), + {error, TargetSpec ++ ": " ++ Text} + end + end; + _ -> + throw(usage) + end. + +start_window(Options) -> + case reltool:start_link(Options) of + {ok, WinPid} -> + receive + {'EXIT', WinPid, shutdown} -> + ok; + {'EXIT', WinPid, normal} -> + ok; + {'EXIT', WinPid, Reason} -> + exit(Reason) + end; + {error, Reason} -> + {error, Reason} + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Helpers +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +script_name() -> + filename:basename(escript:script_name(), ".escript"). + +fatal_error(String, Code) -> + io:format(standard_error, "~s: ~s\n", [script_name(), String]), + safe_stop(Code). + +write_file(File, IoList) -> + case file:write_file(File, IoList) of + ok -> + ok; + {error, Reason} -> + {error, file:format_error(Reason)} + end. + +format(Format, Args) -> + io:format(Format, Args), + %% Wait a while for the I/O to be processed + timer:sleep(timer:seconds(1)). + +pretty(Tag, Term) -> + lists:flatten(io_lib:format("%% ~s generated at ~w ~w\n~p.\n\n", + [Tag, date(), time(), Term])). + +scan_args([H | T], Single, Multi) -> + case H of + "--" ++ _ when Single =:= [] -> + scan_args(T, [H], Multi); + "--" ++ _ -> + scan_args(T, [H], [lists:reverse(Single) | Multi]); + _ -> + scan_args(T, [H | Single], Multi) + end; +scan_args([], [], Multi) -> + lists:reverse(Multi); +scan_args([], Single, Multi) -> + lists:reverse([lists:reverse(Single) | Multi]). + +parse_args([H | T] = Args, Options) -> + case H of + ["--wx_debug" | Levels] -> + Dbg = + fun(L) -> + case catch list_to_integer(L) of + {'EXIT', _} -> + case catch list_to_atom(L) of + {'EXIT', _} -> + exit("Illegal wx debug level: " ++ L); + Atom -> + Atom + end; + Int -> + Int + end + end, + Levels2 = lists:map(Dbg, Levels), + parse_args(T, [{wx_debug, Levels2} | Options]); + ["--" ++ _ | _] -> + %% No more options + {lists:reverse(Options), Args}; + [Config] -> + try + {ok, Tokens, _} = erl_scan:string(Config ++ ". "), + {ok, {sys, _} = Sys} = erl_parse:parse_term(Tokens), + parse_args(T, [{config, Sys} | Options]) + catch + error:{badmatch, _} -> + parse_args(T, [{config, Config} | Options]); + X:Y -> + io:format("\n\n~p\n\n", [{X, Y}]) + end + end; +parse_args([], Options) -> + {lists:reverse(Options), []}. diff --git a/lib/reltool/doc/src/notes.xml b/lib/reltool/doc/src/notes.xml index 524d728901..95e379db53 100644 --- a/lib/reltool/doc/src/notes.xml +++ b/lib/reltool/doc/src/notes.xml @@ -37,6 +37,73 @@ thus constitutes one section in this document. The title of each section is the version number of Reltool.</p> + <section><title>Reltool 0.5.4</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Added function <c>zip:foldl/3</c> to iterate over zip + archives.</p> + <p> + Added functions to create and extract escripts. See + <c>escript:create/2</c> and <c>escript:extract/2</c>.</p> + <p> + The undocumented function <c>escript:foldl/3</c> has been + removed. The same functionality can be achieved with the + more flexible functions <c>escript:extract/2</c> and + <c>zip:foldl/3</c>.</p> + <p> + Record fields has been annotated with type info. Source + files as been adapted to fit within 80 chars and trailing + whitespace has been removed.</p> + <p> + Own Id: OTP-8521</p> + </item> + <item> + <p>A new escript, called <c>reltool</c>, has been + introduced in order to simplify the usage of the reltool + application from makefiles.</p> + <p>The handling of applications included in releases has + been improved. Applications that are required to be + started before other applications in a release are now + automatically included in the release. The <c>kernel</c> + and <c>stdlib</c> applications are always included as + they are mandatory.</p> + <p>Applications that are (explicitly or implicitly) + included in a release are now automatically included as + if they were explicitly included with the incl_cond + flag.</p> + <p>A new <c>embedded_app_type</c> option has been + introduced. It is intended to be used for embedded + systems where all included applications must be loaded + from the boot script, as these systems does not utilize + dynamic code loading. If <c>embedded_app_type </c> is set + to something else than <c>undefined</c>, all included + applications will be included in both the release as well + as in the boot script. If the <c>profile</c> is + <c>embedded</c> the <c>embedded_app_type</c> option + defaults to <c>load</c>.</p> + <p>A new function called <c>reltool:get_status/1</c> has + been introduced. It returns status about the + configuration in the server.</p> + <p>The API functions that may take <c>PidOrOptions</c> as + input and actually gets <c>Options</c> does now print out + warnings.</p> + <p>The internal error handling has been improved. For + example <c>{error,Reason}</c> is always returned in case + of errors even when the server dies.</p> + <p><c>app</c> and <c>appup</c> files has been added as + well as a corresponding test suite.</p> + <p>Various cleanups has been made in the code and in the + documentation.</p> + <p> + Own Id: OTP-8590</p> + </item> + </list> + </section> + + </section> <section><title>Reltool 0.5.3</title> diff --git a/lib/reltool/doc/src/reltool.xml b/lib/reltool/doc/src/reltool.xml index 9786928ae8..598594145a 100644 --- a/lib/reltool/doc/src/reltool.xml +++ b/lib/reltool/doc/src/reltool.xml @@ -48,8 +48,8 @@ <c>root_dir</c> is the root directory of the analysed system and it defaults to the system executing <c>reltool</c>. Applications may also be located outside <c>root_dir</c>. <c>lib_dirs</c> - defines additional library directories where applications - additional may reside and it defaults to the the directories + defines library directories where additional applications + may reside and it defaults to the directories listed by the operating system environment variable <c>ERL_LIBS</c>. See the module <c>code</c> for more info. Finally single modules and entire applications may be read from @@ -58,23 +58,23 @@ <p>Some configuration parameters control the behavior of Reltool on system (<c>sys</c>) level. Others provide control on application (<c>app</c>) level and yet others are on module - (<c>mod</c>) level. Module level parameters overrides application - level parameters and application level parameters overrides system + (<c>mod</c>) level. Module level parameters override application + level parameters and application level parameters override system level parameters. Escript <c>escript</c> level parameters - overrides system level parameters.</p> + override system level parameters.</p> <p>The following top level <c>options</c> are supported:</p> <taglist> - <tag><c><![CDATA[config]]></c></tag> + <tag><c>config</c></tag> <item> <p>This is the main option and it controls the configuration of <c>reltool</c>. It can either be a <c>sys</c> tuple or a name of a <c>file</c> containing a sys tuple.</p> </item> - <tag><c><![CDATA[trap_exit]]></c></tag> + <tag><c>trap_exit</c></tag> <item> <p>This option controls the error handling behavior of <c>reltool</c>. By default the window processes traps @@ -82,7 +82,7 @@ <c>trap_exit</c> to <c>false</c>.</p> </item> - <tag><c><![CDATA[wx_debug]]></c></tag> + <tag><c>wx_debug</c></tag> <item> <p>This option controls the debug level of <c>wx</c>. As its name indicates it is only useful for debugging. See @@ -97,36 +97,36 @@ <taglist> - <tag><c><![CDATA[erts]]></c></tag> + <tag><c>erts</c></tag> <item> <p>Erts specific configuration. See application level options below.</p> </item> - <tag><c><![CDATA[escript]]></c></tag> + <tag><c>escript</c></tag> <item> <p>Escript specific configuration. An escript has a mandatory file name and escript level options that are described below.</p> </item> - <tag><c><![CDATA[app]]></c></tag> + <tag><c>app</c></tag> <item> <p>Application specific configuration. An application has a mandatory name and application level options that are described below.</p> </item> - <tag><c><![CDATA[mod_cond]]></c></tag> + <tag><c>mod_cond</c></tag> <item> <p>This parameter controls the module inclusion policy. It defaults to <c>all</c> which means that if an application is included (either explicitly or implicitly) all modules in that application will be included. This implies that both modules - that exists on the <c>ebin</c> directory of the application, + that exist in the <c>ebin</c> directory of the application, as well as modules that are named in the <c>app</c> file will be included. If the parameter is set to <c>ebin</c>, both - modules on the <c>ebin</c> directory and derived modules are + modules in the <c>ebin</c> directory and derived modules are included. If the parameter is set to <c>app</c>, both modules in the <c>app</c> file and derived modules are included. <c>derived</c> means that only modules that are used by other @@ -134,69 +134,69 @@ system level is used as default for all applications.</p> </item> - <tag><c><![CDATA[incl_cond]]></c></tag> + <tag><c>incl_cond</c></tag> <item> - <p>This parameter controls the application and escript - inclusion policy. It defaults to <c>derived</c> which means - that the applications that not have any explicit - <c>incl_cond</c> setting, will only be included if any other - (explicitly or implicitly included) application uses it. The - value <c>include</c> implies that all applications and - escripts that that not have any explicit <c>incl_cond</c> - setting will be included. <c>exclude</c> implies that all - applications and escripts) that that not have any explicit - <c>incl_cond</c> setting will be excluded.</p> + <p>This parameter controls the application and escript + inclusion policy. It defaults to <c>derived</c> which means + that the applications that do not have any explicit + <c>incl_cond</c> setting, will only be included if any other + (explicitly or implicitly included) application uses it. The + value <c>include</c> implies that all applications and + escripts that do not have any explicit <c>incl_cond</c> + setting will be included. <c>exclude</c> implies that all + applications and escripts) that do not have any explicit + <c>incl_cond</c> setting will be excluded.</p> </item> - <tag><c><![CDATA[boot_rel]]></c></tag> + <tag><c>boot_rel</c></tag> <item> <p>A target system may have several releases but the one given as <c>boot_rel</c> will be used as default when the system is booting up.</p> </item> - <tag><c><![CDATA[rel]]></c></tag> + <tag><c>rel</c></tag> <item> <p>Release specific configuration. Each release maps to a - <c>rel</c>, <c>script</c> and <c>boot </c> file. See the + <c>rel</c>, <c>script</c> and <c>boot</c> file. See the module <c>systools</c> for more info about the details. Each release has a name, a version and a set of applications with a few release specific parameters such as type and included applications.</p> </item> - <tag><c><![CDATA[relocatable]]></c></tag> + <tag><c>relocatable</c></tag> <item> - <p>This parameter controls whether the <c>erl</c> executable - in the target system automatically should determine where it - is installed or if it should use a hardcoded path to the - installation. In the latter case the target system must be - installed with <c>reltool:install/2</c> before it can be - used. If the system is relocatable, the file tree containing - the target system can be moved to another location without - re-installation. The default is <c>true</c>.</p> + <p>This parameter controls whether the <c>erl</c> executable + in the target system should automatically determine where it + is installed or if it should use a hardcoded path to the + installation. In the latter case the target system must be + installed with <c>reltool:install/2</c> before it can be + used. If the system is relocatable, the file tree containing + the target system can be moved to another location without + re-installation. The default is <c>true</c>.</p> </item> - <tag><c><![CDATA[profile]]></c></tag> + <tag><c>profile</c></tag> <item> - <p>The creation of the specification for a target system is - performed in two steps. In the first step a complete - specification is generated. It will likely contain much more - files than you are interested in your customized target - system. In the second step the specification will be filtered - according to your filters. There you have the ability to - specify filters per application as well as system wide - filters. You can also select a <c>profile</c> for your - system. Depending on the <c>profile</c>, different default - filters will be used. There are three different profiles to - choose from: <c>development</c>, <c>embedded</c> and - <c>standalone</c>. <c>development</c> is default. The - parameters that are affected by the <c>profile</c> are: - <c>incl_sys_filters</c>, <c>excl_sys_filters</c>, - <c>incl_app_filters</c> and <c>excl_app_filters</c>.</p> + <p>The creation of the specification for a target system is + performed in two steps. In the first step a complete + specification is generated. It will likely contain much more + files than you are interested in in your customized target + system. In the second step the specification will be filtered + according to your filters. There you have the ability to + specify filters per application as well as system wide + filters. You can also select a <c>profile</c> for your + system. Depending on the <c>profile</c>, different default + filters will be used. There are three different profiles to + choose from: <c>development</c>, <c>embedded</c> and + <c>standalone</c>. <c>development</c> is default. The + parameters that are affected by the <c>profile</c> are: + <c>incl_sys_filters</c>, <c>excl_sys_filters</c>, + <c>incl_app_filters</c> and <c>excl_app_filters</c>.</p> </item> - <tag><c><![CDATA[app_file]]></c></tag> + <tag><c>app_file</c></tag> <item> <p>This parameter controls the default handling of the <c>app</c> files when a target system is generated. It @@ -213,7 +213,7 @@ and <c>strip</c>.</p> </item> - <tag><c><![CDATA[debug_info]]></c></tag> + <tag><c>debug_info</c></tag> <item> <p>The <c>debug_info</c> parameter controls whether the debug information in the beam file should be kept (<c>keep</c>) or @@ -221,31 +221,31 @@ system.</p> </item> - <tag><c><![CDATA[incl_sys_filters]]></c></tag> + <tag><c>incl_sys_filters</c></tag> <item> <p>This parameter normally contains a list of regular - expressions that controls which files in the system that + expressions that controls which files in the system should be included. Each file in the target system must match at least one of the listed regular expressions in order to be included. Further the files may not match any filter in <c>excl_sys_filters</c> in order to be included. Which - application files that should be included are controlled with + application files should be included is controlled with the parameters <c>incl_app_filters</c> and <c>excl_app_filters</c>. This parameter defaults to <c>[".*"]</c>.</p> </item> - <tag><c><![CDATA[excl_sys_filters]]></c></tag> + <tag><c>excl_sys_filters</c></tag> <item> <p>This parameter normally contains a list of regular - expressions that controls which files in the system that not - should be included in the target system. In order to be + expressions that controls which files in the system should + not be included in the target system. In order to be included, a file must match some filter in <c>incl_sys_filters</c> but not any filter in <c>excl_sys_filters</c>. This parameter defaults to <c>[]</c>.</p> </item> - <tag><c><![CDATA[incl_app_filters]]></c></tag> + <tag><c>incl_app_filters</c></tag> <item> <p>This parameter normally contains a list of regular expressions that controls which application specific files @@ -256,23 +256,23 @@ parameter defaults to <c>[".*"]</c>.</p> </item> - <tag><c><![CDATA[excl_app_filters]]></c></tag> + <tag><c>excl_app_filters</c></tag> <item> <p>This parameter normally contains a list of regular expressions that controls which application specific files - that not should be included in the target system. In order to + should not be included in the target system. In order to be included, a file must match some filter in <c>incl_app_filters</c> but not any filter in <c>excl_app_filters</c>. This parameter defaults to <c>[]</c>.</p> </item> - <tag><c><![CDATA[incl_archive_filters]]></c></tag> + <tag><c>incl_archive_filters</c></tag> <item> <p>This parameter normally contains a list of regular expressions that controls which top level directories in an - application that should be included in an archive file (as - opposed of beeing included as a regular directory outside the + application should be included in an archive file (as + opposed to being included as a regular directory outside the archive). Each top directory in the application must match at least one of the listed regular expressions in order to be included. Further the files may not match any filter in @@ -280,122 +280,122 @@ parameter defaults to <c>[".*"]</c>.</p> </item> - <tag><c><![CDATA[excl_archive_filters]]></c></tag> + <tag><c>excl_archive_filters</c></tag> <item> <p>This parameter normally contains a list of regular expressions that controls which top level directories in an - application that not should be included in an archive file. In + application should not be included in an archive file. In order to be included in the application archive, a top directory must match some filter in <c>incl_archive_filters</c> but not any filter in <c>excl_archive_filters</c>. This parameter defaults to <c>["^include$","^priv$"]</c>.</p> </item> - <tag><c><![CDATA[archive_opts]]></c></tag> + <tag><c>archive_opts</c></tag> <item> <p>This parameter contains a list of options that are given to <c>zip:create/3</c> when application specific files are - packaged into an archive. All options are not supported. The - most useful options in this context, are the ones that - controls which types of files that should be compressed. This + packaged into an archive. Only a subset of the options are + supported. The most useful options in this context are the ones + that control which types of files should be compressed. This parameter defaults to <c>[]</c>.</p> </item> </taglist> - <p>On application (<c>escript</c>) level,the following options are + <p>On application (<c>escript</c>) level, the following options are supported:</p> <taglist> - <tag><c><![CDATA[incl_cond]]></c></tag> + <tag><c>incl_cond</c></tag> <item> <p>The value of this parameter overrides the parameter with the same name on system level.</p> </item> </taglist> - <p>On application (<c>app</c>) level,the following options are + <p>On application (<c>app</c>) level, the following options are supported:</p> <taglist> - <tag><c><![CDATA[vsn]]></c></tag> + <tag><c>vsn</c></tag> <item> <p>The version of the application. In an installed system there may exist several versions of an application. The <c>vsn</c> parameter - controls which version of the application that will be choosen. If it - is omitted, the latest version will be choosen.</p> + controls which version of the application will be chosen. If it + is omitted, the latest version will be chosen.</p> </item> - <tag><c><![CDATA[mod]]></c></tag> + <tag><c>mod</c></tag> <item> <p>Module specific configuration. A module has a mandatory name and module level options that are described below.</p> </item> - <tag><c><![CDATA[mod_cond]]></c></tag> + <tag><c>mod_cond</c></tag> <item> <p>The value of this parameter overrides the parameter with the same name on system level.</p> </item> - <tag><c><![CDATA[incl_cond]]></c></tag> + <tag><c>incl_cond</c></tag> <item> <p>The value of this parameter overrides the parameter with the same name on system level.</p> </item> - <tag><c><![CDATA[app_file]]></c></tag> + <tag><c>app_file</c></tag> <item> <p>The value of this parameter overrides the parameter with the same name on system level.</p> </item> - <tag><c><![CDATA[debug_info]]></c></tag> + <tag><c>debug_info</c></tag> <item> <p>The value of this parameter overrides the parameter with the same name on system level.</p> </item> - <tag><c><![CDATA[incl_app_filters]]></c></tag> + <tag><c>incl_app_filters</c></tag> <item> <p>The value of this parameter overrides the parameter with the same name on system level.</p> </item> - <tag><c><![CDATA[excl_app_filters]]></c></tag> + <tag><c>excl_app_filters</c></tag> <item> <p>The value of this parameter overrides the parameter with the same name on system level.</p> </item> - <tag><c><![CDATA[incl_archive_filters]]></c></tag> + <tag><c>incl_archive_filters</c></tag> <item> <p>The value of this parameter overrides the parameter with the same name on system level.</p> </item> - <tag><c><![CDATA[excl_archive_filters]]></c></tag> + <tag><c>excl_archive_filters</c></tag> <item> <p>The value of this parameter overrides the parameter with the same name on system level.</p> </item> - <tag><c><![CDATA[archive_opts]]></c></tag> + <tag><c>archive_opts</c></tag> <item> <p>The value of this parameter overrides the parameter with the same name on system level.</p> </item> </taglist> - <p>On module (<c>mod</c>) level,the following options are + <p>On module (<c>mod</c>) level, the following options are supported:</p> <taglist> - <tag><c><![CDATA[incl_cond]]></c></tag> + <tag><c>incl_cond</c></tag> <item> - <p>This parameter controls whether the module is included or not. By - default the <c>mod_incl</c> parameter on application and system level - will be used to control whether the module is included or not. The - value of <c>incl_cond</c> overrides the module inclusion policy. - <c>include</c> implies that the module is included, while - <c>exclude</c> implies that the module not is included. - <c>derived</c> implies that the is included if any included uses the - module.</p> + <p>This parameter controls whether the module is included or not. By + default the <c>mod_incl</c> parameter on application and system level + will be used to control whether the module is included or not. The + value of <c>incl_cond</c> overrides the module inclusion policy. + <c>include</c> implies that the module is included, while + <c>exclude</c> implies that the module is not included. + <c>derived</c> implies that the module is included if it is used + by any other included module.</p> </item> - <tag><c><![CDATA[debug_info]]></c></tag> + <tag><c>debug_info</c></tag> <item> <p>The value of this parameter overrides the parameter with the same name on application level.</p> @@ -477,7 +477,9 @@ mod_name() = atom() profile() = development | embedded | standalone re_regexp() = string() reason() = string() -regexps() = [re_regexp()] | {add, [re_regexp()]} | {del, [re_regexp()]} +regexps() = [re_regexp()] + | {add, [re_regexp()]} + | {del, [re_regexp()]} rel_file() = term() rel_name() = string() rel_vsn() = string() @@ -487,7 +489,19 @@ script_file() = term() server() = server_pid() | options() server_pid() = pid() target_dir() = file() -window_pid() = pid()]]></code> +window_pid() = pid() +base_dir() = dir() +base_file() = file() +top_dir() = file() +top_file() = file() +target_spec() = [target_spec()] + | {create_dir, base_dir(), [target_spec()]} + | {create_dir, base_dir(), top_dir(), [target_spec()]} + | {archive, base_file(), [archive_opt()], [target_spec()]} + | {copy_file, base_file()} + | {copy_file, base_file(), top_file()} + | {write_file, base_file(), iolist()} + | {strip_beam_file, base_file()}]]></code> <marker id="start"></marker> </section> @@ -497,9 +511,9 @@ window_pid() = pid()]]></code> <name>create_target(Server, TargetDir) -> ok | {error, Reason}</name> <fsummary>Create a target system</fsummary> <type> - <v>Server = server()</v> + <v>Server = server()</v> <v>TargetDir = target_dir()</v> - <v>Reason = reason()</v> + <v>Reason = reason()</v> </type> <desc><p>Create a target system. Gives the same result as <c>{ok,TargetSpec}=reltool:get_target_spec(Server)</c> and @@ -532,12 +546,12 @@ window_pid() = pid()]]></code> files are by default copied to the target system. The <c>releases</c> directory contains generated <c>rel</c>, <c>script</c>, and <c>boot</c> files. The <c>lib</c> directory - contains the applications. Which applications that are included + contains the applications. Which applications are included and if they should be customized (archived, stripped from debug info etc.) is specified with various configuration parameters. The files in the <c>bin</c> directory are copied from the <c>erts-vsn/bin</c> directory, but only those files - that was originally included in <c>bin</c> directory of the + that were originally included in the <c>bin</c> directory of the source system.</p> <p>If the configuration parameter <c>relocatable</c> was set to @@ -570,10 +584,10 @@ window_pid() = pid()]]></code> <v>Reason = reason()</v> </type> <desc><p>Get reltool configuration. Normally, only the explicit - configuration parameters with values that differs from their + configuration parameters with values that differ from their defaults are interesting. But the builtin default values can be returned by setting <c>InclDefaults</c> to <c>true</c>. The - derived configuration can be return by setting + derived configuration can be returned by setting <c>InclDerived</c> to <c>true</c>.</p></desc> </func> @@ -604,6 +618,17 @@ window_pid() = pid()]]></code> </func> <func> + <name>get_status(Server) -> {ok, [Warning]} | {error, Reason}</name> + <fsummary>Get contents of a release file</fsummary> + <type> + <v>Server = server()</v> + <v>Warning = string()</v> + <v>Reason = reason()</v> + </type> + <desc><p>Get status about the configuration</p></desc> + </func> + + <func> <name>get_server(WindowPid) -> {ok, ServerPid} | {error, Reason}</name> <fsummary>Start server process with options</fsummary> <type> @@ -680,7 +705,7 @@ window_pid() = pid()]]></code> <v>Reason = reason()</v> </type> <desc><p>Start a server process with options. The server process - identity can be given as argument to several other functions in the + identity can be given as an argument to several other functions in the API.</p></desc> </func> diff --git a/lib/reltool/doc/src/reltool_examples.xml b/lib/reltool/doc/src/reltool_examples.xml index d6db246f6c..bce9413b52 100644 --- a/lib/reltool/doc/src/reltool_examples.xml +++ b/lib/reltool/doc/src/reltool_examples.xml @@ -249,11 +249,11 @@ Eshell V5.7.3 (abort with ^G) <pre> 5> {ok, Server} = reltool:start_server([{config, {sys, [{boot_rel, "NAME"}, {rel, "NAME", "VSN", - [kernel, stdlib, sasl]}]}}]). + [sasl]}]}}]). {ok,<0.1288.0>} 6> reltool:get_config(Server). {ok,{sys,[{boot_rel,"NAME"}, - {rel,"NAME","VSN",[kernel,stdlib,sasl]}]}} + {rel,"NAME","VSN",[sasl]}]}} 7> reltool:get_rel(Server, "NAME"). {ok,{release,{"NAME","VSN"}, {erts,"5.7"}, diff --git a/lib/reltool/doc/src/reltool_usage.xml b/lib/reltool/doc/src/reltool_usage.xml index 885828d1f0..0a053a014e 100644 --- a/lib/reltool/doc/src/reltool_usage.xml +++ b/lib/reltool/doc/src/reltool_usage.xml @@ -44,7 +44,7 @@ <section> <title>System window</title> <p>The system window is started with the function - <c>reltool:start/1</c>. At startup the tool will process the all + <c>reltool:start/1</c>. At startup the tool will process all <c>beam</c> files and <c>app</c> files in order to find out dependencies between applications and their modules. Once all this information has been derived, it will be possible to explore the tool.</p> @@ -67,29 +67,29 @@ <section> <title>Libraries</title> <p>On the library page it is possible to control which sources - that the tool will use. The page is organized as a tree which + the tool will use. The page is organized as a tree which can be expanded and collapsed by clicking on the little symbol in the beginning of the expandable/collapsible lines.</p> <p>The <c>Root directory</c> can be edited by selecting the line where the path of the root directory is displayed and - clicking with the right mouse button. Choose edit in the menu - that pops up. </p> + clicking the right mouse button. Choose edit in the menu + that pops up.</p> <p>Library directories can be added, edited or deleted. This is done by selecting the line where the path to a library - directory is displayed and clicking with the right mouse + directory is displayed and clicking the right mouse button. Choose add, edit or delete in the menu that pops up. New library directories can also be added by selecting the - line <c>Library directories</c> and clicking with the right + line <c>Library directories</c> and clicking the right mouse button. Choose add in the menu that pops up.</p> <p>Escript files can be added, edited or deleted. This is done by selecting the line where the path to an escript file is - displayed and clicking with the right mouse button. Choose + displayed and clicking the right mouse button. Choose add, edit or delete in the menu that pops up. New escripts can also be added by selecting the line <c>Escript files</c> and - clicking with the right mouse button. Choose add in the menu + clicking the right mouse button. Choose add in the menu that pops up.</p> <p>When libraries and escripts are expanded, the names of @@ -102,7 +102,7 @@ <p>On the system settings page it is possible to control some global settings that are used as defaults for all applications. Set the <c>Application inclusion policy</c> to - <c>include</c> to include all applications that not are + <c>include</c> to include all applications that are not explicitly excluded. See <c>incl_cond</c> (application inclusion) and <c>mod_cond</c> (module inclusion) in the reference manual for the module <c>reltool</c> for more @@ -131,14 +131,14 @@ <p>The symbols in front of the application names are intended to describe the status of the application. There are error - symbols and warning symbols that means that there are - something that needs attention. The tick symbol means that the + and warning symbols to signalize that there is + something which needs attention. The tick symbol means that the application is included or derived and no problem has been detected. The cross symbol means that the application is excluded or available and no problem has been detected. Applications with error symbols are listed first in - each category, then comes the warnings and the normal ones - (ticks and crosses) are found at the end.</p> + each category and are followed by the warnings and the + normal ones (ticks and crosses) at the end.</p> <p>Double click on an application to launch its application window.</p> @@ -175,8 +175,8 @@ </item> <item> <p><c>Save configuration</c> - Saves the current - configuration to file. Normally, only the explictit - configuration parameters with values that differs from their + configuration to file. Normally, only the explicit + configuration parameters with values that differ from their defaults are saved. But the configuration with or without default values and with or without derived values may also be saved.</p> @@ -204,21 +204,21 @@ <p>It is possible to perform some limited manipulations of the graph. Nodes can be moved, selected, locked or deleted. Move a single node or the entire graph by moving the mouse while the - left mouse button is pressed. A node is can be locked into a fix + left mouse button is pressed. A node can be locked into a fix position by holding down the shift button when the left mouse button is released. Select several nodes by moving the mouse - while the control key and the left mouse button i + while the control key and the left mouse button are pressed. Selected nodes can be locked, unlocked or deleted by - klicking on a suitable button.</p> + clicking on a suitable button.</p> <p>The algorithm that is used to draw a graph with as few crossed links as possible is called force graph. A force graph - consists of nodes and directed link between nodes. Each node is + consists of nodes and directed links between nodes. Each node is associated with a repulsive force that pushes nodes away from each other. This force can be adjusted with the left slider or with the mouse wheel. Each link is associated with an attractive - force that pulls the nodes nearer each other. This force can be - adjusted with the right slider. If this force becomes to strong, + force that pulls the nodes nearer to each other. This force can be + adjusted with the right slider. If this force becomes too strong, the graph will be unstable. The third parameter that can be adjusted is the length of the links. It is adjusted with the middle slider.</p> @@ -256,7 +256,7 @@ <p>Select version of the application in the <c>Source selection policy</c> part of the page. By default the latest version of the application is selected, but it is possible to override this by - explicitly select another version.</p> + explicitly selecting another version.</p> <p>By default the <c>Application inclusion policy</c> on system level is used for all applications. Set the value to @@ -272,10 +272,10 @@ want actually used modules to be included. Set it to <c>app</c> if you, besides derived modules, also want the modules listed in the app file to be included. Set it to <c>ebin</c> if you, besides - derived modules, also want the modules that exists as beam files - on the ebin directory to be included. Set it to <c>all</c> if you + derived modules, also want the modules that exist as beam files + in the ebin directory to be included. Set it to <c>all</c> if you want all modules to be included, that is the union of modules - found on the ebin directory and listed in the app file.</p> + found in the ebin directory and listed in the app file.</p> <p>The application settings page is rather incomplete.</p> </section> @@ -299,16 +299,16 @@ undone.</p> <p>The symbols in front of the module names are intended to - describe the status of the module. There are error symbols - and warning symbols that means that there are something that needs + describe the status of the module. There are error and + and warning symbols to signalize that there is something that needs attention. The tick symbol means that the module is included or derived and no problem has been detected. The cross symbol means that the module is excluded or available and no problem has been detected. Modules with error symbols are listed - first in each category, then comes the warnings and the normal - ones (ticks and crosses) are found at the end.</p> + first in each category and are followed by warnings and the + normal ones (ticks and crosses) at the end.</p> - <p>Double click on an module to launch its module window.</p> + <p>Double click on a module to launch its module window.</p> </section> @@ -323,7 +323,7 @@ <c>app</c> file. If the application includes other applications, these are listed under <c>Included</c>. These applications are listed in the <c>included_applications</c> part of the <c>app</c> - file. If the application uses modules other applications, these + file. If the application uses other applications, these are listed under <c>Uses</c>.</p> <p>Double click on an application name to launch an application window.</p> @@ -336,7 +336,7 @@ <p>There are two categories of modules on the <c>Module dependencies</c> page. If the module is used by other modules, these are listed under <c>Modules used by others</c>. If the - module uses modules other modules, these are listed under <c>Used + module uses other modules, these are listed under <c>Used modules</c>.</p> <p>Double click on an module name to launch a module window.</p> @@ -365,8 +365,8 @@ <p>There are two categories of modules on the <c>Dependencies</c> page. If the module is used by other modules, these are listed - under <c>Modules used by others</c>. If the module uses modules - other modules, these are listed under <c>Used modules</c>.</p> + under <c>Modules used by others</c>. If the module uses other + modules, these are listed under <c>Used modules</c>.</p> <p>Double click on an module name to launch a module window.</p> @@ -378,7 +378,7 @@ <p>On the <c>Code</c> page the Erlang source code is displayed. It is possible to search forwards and backwards for text in the module. Enter a regular expression in the <c>Find</c> field and - press enter. It is also possible to goto a certain line on the + press enter. It is also possible to go to a certain line in the module. The <c>Back</c> button can be used to go back to the previous position.</p> diff --git a/lib/reltool/src/Makefile b/lib/reltool/src/Makefile index fa24efbb8c..4e6a112b7e 100644 --- a/lib/reltool/src/Makefile +++ b/lib/reltool/src/Makefile @@ -1,19 +1,19 @@ # # %CopyrightBegin% -# -# Copyright Ericsson AB 2009. All Rights Reserved. -# +# +# 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% include $(ERL_TOP)/make/target.mk @@ -28,7 +28,6 @@ include ../vsn.mk VSN = $(RELTOOL_VSN) APP_VSN = "reltool-$(VSN)" - # ---------------------------------------------------- # Release directory specification # ---------------------------------------------------- @@ -39,25 +38,20 @@ RELSYSDIR = $(RELEASE_PATH)/lib/reltool-$(VSN) # Target Specs # ---------------------------------------------------- -MODULES = \ - reltool \ - reltool_app_win \ - reltool_fgraph \ - reltool_fgraph_win \ - reltool_mod_win \ - reltool_sys_win \ - reltool_server \ - reltool_target \ - reltool_utils - -HRL_FILES = - -INTERNAL_HRL_FILES = reltool.hrl reltool_fgraph.hrl +include files.mk ERL_FILES = $(MODULES:%=%.erl) TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) +APP_FILE = reltool.app +APP_SRC = $(APP_FILE).src +APP_TARGET = $(EBIN)/$(APP_FILE) + +APPUP_FILE = reltool.appup +APPUP_SRC = $(APPUP_FILE).src +APPUP_TARGET = $(EBIN)/$(APPUP_FILE) + # ---------------------------------------------------- # FLAGS # ---------------------------------------------------- @@ -69,15 +63,28 @@ ERL_COMPILE_FLAGS += +'{parse_transform,sys_pre_attributes}' \ # Targets # ---------------------------------------------------- -debug opt: $(TARGET_FILES) $(HRL_FILES) +debug: + @${MAKE} TYPE=debug opt + +opt: $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) clean: - rm -f $(TARGET_FILES) + rm -f $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) rm -f core docs: # ---------------------------------------------------- +# Special Build Targets +# ---------------------------------------------------- + +$(APP_TARGET): $(APP_SRC) ../vsn.mk + sed -e 's;%VSN%;$(VSN);' $< > $@ + +$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk + sed -e 's;%VSN%;$(VSN);' $< > $@ + +# ---------------------------------------------------- # Dependencies # ---------------------------------------------------- @@ -85,7 +92,7 @@ $(TARGET_FILES): $(HRL_FILES) $(INTERNAL_HRL_FILES) # ---------------------------------------------------- # Release Target -# ---------------------------------------------------- +# ---------------------------------------------------- include $(ERL_TOP)/make/otp_release_targets.mk @@ -94,6 +101,7 @@ release_spec: opt $(INSTALL_DATA) $(INTERNAL_HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src $(INSTALL_DIR) $(RELSYSDIR)/ebin $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DATA) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin release_docs_spec: diff --git a/lib/reltool/src/files.mk b/lib/reltool/src/files.mk new file mode 100644 index 0000000000..99a1f1c14a --- /dev/null +++ b/lib/reltool/src/files.mk @@ -0,0 +1,32 @@ +#-*-makefile-*- ; force emacs to enter makefile-mode +# %CopyrightBegin% +# +# Copyright Ericsson AB 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% + +MODULES = \ + reltool \ + reltool_app_win \ + reltool_fgraph \ + reltool_fgraph_win \ + reltool_mod_win \ + reltool_sys_win \ + reltool_server \ + reltool_target \ + reltool_utils + +HRL_FILES = + +INTERNAL_HRL_FILES = reltool.hrl reltool_fgraph.hrl diff --git a/lib/reltool/src/reltool.app.src b/lib/reltool/src/reltool.app.src index f83042c157..b80753e8fc 100644 --- a/lib/reltool/src/reltool.app.src +++ b/lib/reltool/src/reltool.app.src @@ -1,37 +1,38 @@ %% This is an -*- erlang -*- file. %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009. All Rights Reserved. -%% +%% +%% 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% %% +%% %CopyrightEnd% {application, reltool, - [{description, "Release management tool"}, - {vsn, "%VSN%"}, - {modules, [ - reltool, - reltool_app, - reltool_fgraph, - reltool_fgraph_win, - reltool_gen, - reltool_mod, - reltool_sys, - reltool_server, - reltool_utils - ]}, - {applications, [kernel, stdlib]} - ] -}. + [{description, "Reltool the release management tool"}, + {vsn, "%VSN%"}, + {modules, + [ + reltool_app_win, + reltool, + reltool_fgraph, + reltool_fgraph_win, + reltool_mod_win, + reltool_server, + reltool_sys_win, + reltool_target, + reltool_utils + ]}, + {registered, []}, + {applications, [stdlib, kernel]}, + {env, []} + ]}. diff --git a/lib/asn1/test/bench/bench.hrl b/lib/reltool/src/reltool.appup.src index 7c99447439..c02edd2afb 100644 --- a/lib/asn1/test/bench/bench.hrl +++ b/lib/reltool/src/reltool.appup.src @@ -1,24 +1,22 @@ +%% This is an -*- erlang -*- file. %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2002-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 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% -%% %% --define(rep5(X), X, X, X, X, X). --define(rep10(X), ?rep5(X), ?rep5(X)). --define(rep20(X), ?rep10(X), ?rep10(X)). --define(rep40(X), ?rep20(X), ?rep20(X)). --define(rep80(X), ?rep40(X), ?rep40(X)). +%% %CopyrightEnd% + +{"%VSN%", + [ ] +}. diff --git a/lib/reltool/src/reltool.erl b/lib/reltool/src/reltool.erl index e6548bfe68..9dd0a24f46 100644 --- a/lib/reltool/src/reltool.erl +++ b/lib/reltool/src/reltool.erl @@ -1,160 +1,56 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009. All Rights Reserved. -%% +%% +%% 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% -module(reltool). %% Public -export([ - main/1, % Escript start/0, start/1, start_link/1, debug/0, % GUI - start_server/1, get_server/1, stop/1, + start_server/1, get_server/1, get_status/1, stop/1, get_config/1, get_config/3, get_rel/2, get_script/2, - create_target/2, get_target_spec/1, eval_target_spec/3, + create_target/2, get_target_spec/1, eval_target_spec/3, install/2 ]). --type file() :: string(). --type dir() :: string(). --type mod_cond() :: all | app | ebin | derived | none. --type incl_cond() :: include | exclude | derived. --type debug_info() :: keep | strip. --type app_file() :: keep | strip | all. --type re_regexp() :: string(). --type regexps() :: [re_regexp()] | {add, [re_regexp()]} | {del, [re_regexp()]} . --type incl_sys_filters() :: regexps(). --type excl_sys_filters() :: regexps(). --type incl_app_filters() :: regexps(). --type excl_app_filters() :: regexps(). --type incl_archive_filters() :: regexps(). --type excl_archive_filters() :: regexps(). --type archive_opt() :: term(). --type root_dir() :: dir(). --type lib_dir() :: dir(). --type profile() :: development | embedded | standalone. --type relocatable() :: boolean(). --type escript_file() :: file(). --type mod_name() :: atom(). --type app_name() :: atom(). --type app_vsn() :: string(). --type app_type() :: permanent | transient | temporary | load | none. --type incl_app() :: app_name(). --type rel_name() :: string(). --type rel_vsn() :: string(). --type boot_rel() :: rel_name(). --type rel_app() :: app_name() - | {app_name(), app_type()} - | {app_name(), [incl_app()]} - | {app_name(), app_type(), [incl_app()]}. --type mod() :: {incl_cond, incl_cond()} - | {debug_info, debug_info()}. --type app() :: {vsn, app_vsn()} - | {mod, mod_name(), mod()} - | {mod_cond, mod_cond()} - | {incl_cond, incl_cond()} - | {app_file, app_file()} - | {debug_info, debug_info()} - | {incl_app_filters, incl_app_filters()} - | {excl_app_filters, excl_app_filters()} - | {incl_archive_filters, incl_archive_filters()} - | {excl_archive_filters, excl_archive_filters()}. --type escript() :: {incl_cond, incl_cond()}. --type sys() :: {mod_cond, mod_cond()} - | {incl_cond, incl_cond()} - | {debug_info, debug_info()} - | {app_file, app_file()} - | {profile, profile()} - | {incl_sys_filters, incl_sys_filters()} - | {excl_sys_filters, excl_sys_filters()} - | {incl_app_filters, incl_app_filters()} - | {excl_app_filters, excl_app_filters()} - | {incl_archive_filters, incl_archive_filters()} - | {excl_archive_filters, excl_archive_filters()} - | {archive_opts, [archive_opt()]} - | {root_dir, root_dir()} - | {lib_dirs, [lib_dir()]} - | {boot_rel, boot_rel()} - | {rel, rel_name(), rel_vsn(), [rel_app()]} - | {relocatable, relocatable()} - | {erts, app()} - | {escript, escript_file(), [escript()]} - | {app, app_name(), [app()]}. --type config() :: {sys, [sys()]}. --type option() :: {wx_debug, term()} | {trap_exit, boolean()} | config() | {config, config() | file()}. --type options() :: [option()]. --type server_pid() :: pid(). --type window_pid() :: pid(). --type server() :: server_pid() | options(). --type rel_file() :: term(). --type script_file() :: term(). --type reason() :: string(). --type escript_arg() :: string(). -%%-type base_dir() :: dir(). -%%-type base_file() :: file(). -%%-type top_dir() :: file(). -%%-type top_file() :: file(). -%%-type target_spec() :: [target_spec()] -%% | {create_dir, base_dir(), [target_spec()]} -%% | {create_dir, base_dir(), top_dir(), [target_spec()]} -%% | {archive, base_file(), [archive_opt()], [target_spec()]} -%% | {copy_file, base_file()} -%% | {copy_file, base_file(), top_file()} -%% | {write_file, base_file(), iolist()} -%% | {strip_beam_file, base_file()}. --type target_spec() :: term(). --type target_dir() :: dir(). --type incl_defaults() :: boolean(). --type incl_derived() :: boolean(). +-include("reltool.hrl"). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Main function for escript --spec main([escript_arg()]) -> ok. -main(_) -> - process_flag(trap_exit, true), - {ok, WinPid} = start_link([]), - receive - {'EXIT', WinPid, shutdown} -> - ok; - {'EXIT', WinPid, normal} -> - ok; - {'EXIT', WinPid, Reason} -> - io:format("EXIT: ~p\n", [Reason]), - erlang:halt(1) - end. - %% Start main window process --spec start() -> {ok, window_pid()}. +-spec start() -> {ok, window_pid()} | {error, reason()}. start() -> start([]). %% Start main window process --spec start(options()) -> {ok, window_pid() | {error, reason()}}. +-spec start(options()) -> {ok, window_pid()} | {error, reason()}. start(Options)when is_list(Options) -> - {ok, WinPid} = start_link(Options), - unlink(WinPid), - {ok, WinPid}. + case start_link(Options) of + {ok, WinPid} -> + unlink(WinPid), + {ok, WinPid}; + Other-> + Other + end. %% Start main window process with wx debugging enabled --spec debug() -> {ok, window_pid()}. +-spec debug() -> {ok, window_pid()} | {error, reason()}. debug() -> - {ok, WinPid} = start_link([{wx_debug, 2}]), - unlink(WinPid), - {ok, WinPid}. + start([{wx_debug, 2}]). %% Start main window process with options -spec start_link(options()) -> {ok, window_pid() | {error, reason()}}. @@ -164,7 +60,7 @@ start_link(Options) when is_list(Options) -> {ok, WinPid}; {error, Reason} -> {error, lists:flatten(io_lib:format("~p", [Reason]))} - end. + end. %% Start server process with options -spec start_server(options()) -> {ok, server_pid()} | {error, reason()}. @@ -200,51 +96,96 @@ stop(Pid) when is_pid(Pid) -> end. %% Internal library function --spec eval_server(server(), fun((server_pid()) -> term())) -> {ok, server_pid()} | {error, reason()}. -eval_server(Pid, Fun) when is_pid(Pid) -> +-spec eval_server(server(), boolean(), fun((server_pid()) -> term())) -> + {ok, server_pid()} | {error, reason()}. +eval_server(Pid, DisplayWarnings, Fun) + when is_pid(Pid) -> Fun(Pid); -eval_server(Options, Fun) when is_list(Options), is_function(Fun, 1) -> - case start_server(Options) of - {ok, Pid} -> - Res = Fun(Pid), - stop(Pid), - Res; - {error, Reason} -> - {error, Reason} +eval_server(Options, DisplayWarnings, Fun) + when is_list(Options) -> + TrapExit = process_flag(trap_exit, true), + Res = case start_server(Options) of + {ok, Pid} -> + apply_fun(Pid, DisplayWarnings, Fun); + {error, Reason} -> + {error, Reason} + end, + process_flag(trap_exit, TrapExit), + Res. + +apply_fun(Pid, false, Fun) -> + Res = Fun(Pid), + stop(Pid), + Res; +apply_fun(Pid, true, Fun) -> + case get_status(Pid) of + {ok, Warnings} -> + [io:format("~p: ~s\n", [?APPLICATION, W]) || W <- Warnings], + apply_fun(Pid, false, Fun); + {error, Reason} -> + stop(Pid), + {error, Reason} end. - + +%% Get status about the configuration +-type warning() :: string(). +-spec get_status(server()) -> + {ok, [warning()]} | {error, reason()}. +get_status(PidOrOptions) + when is_pid(PidOrOptions); is_list(PidOrOptions) -> + eval_server(PidOrOptions, false, + fun(Pid) -> + reltool_server:get_status(Pid) + end). + %% Get reltool configuration -spec get_config(server()) -> {ok, config()} | {error, reason()}. get_config(PidOrOption) -> get_config(PidOrOption, false, false). --spec get_config(server(), incl_defaults(), incl_derived()) -> {ok, config()} | {error, reason()}. -get_config(PidOrOptions, InclDefaults, InclDerived) when is_pid(PidOrOptions); is_list(PidOrOptions) -> - eval_server(PidOrOptions, fun(Pid) -> reltool_server:get_config(Pid, InclDefaults, InclDerived) end). +-spec get_config(server(), incl_defaults(), incl_derived()) -> + {ok, config()} | {error, reason()}. +get_config(PidOrOptions, InclDef, InclDeriv) + when is_pid(PidOrOptions); is_list(PidOrOptions) -> + eval_server(PidOrOptions, true, + fun(Pid) -> + reltool_server:get_config(Pid, InclDef, InclDeriv) + end). %% Get contents of release file -spec get_rel(server(), rel_name()) -> {ok, rel_file()} | {error, reason()}. -get_rel(PidOrOptions, RelName) when is_pid(PidOrOptions); is_list(PidOrOptions) -> - eval_server(PidOrOptions, fun(Pid) -> reltool_server:get_rel(Pid, RelName) end). +get_rel(PidOrOptions, RelName) + when is_pid(PidOrOptions); is_list(PidOrOptions) -> + eval_server(PidOrOptions, true, + fun(Pid) -> reltool_server:get_rel(Pid, RelName) end). %% Get contents of boot script file --spec get_script(server(), rel_name()) -> {ok, script_file()} | {error, reason()}. -get_script(PidOrOptions, RelName) when is_pid(PidOrOptions); is_list(PidOrOptions) -> - eval_server(PidOrOptions, fun(Pid) -> reltool_server:get_script(Pid, RelName) end). +-spec get_script(server(), rel_name()) -> + {ok, script_file()} | {error, reason()}. +get_script(PidOrOptions, RelName) + when is_pid(PidOrOptions); is_list(PidOrOptions) -> + eval_server(PidOrOptions, true, + fun(Pid) -> reltool_server:get_script(Pid, RelName) end). %% Generate a target system -spec create_target(server(), target_dir()) -> ok | {error, reason()}. -create_target(PidOrOptions, TargetDir) when is_pid(PidOrOptions); is_list(PidOrOptions) -> - eval_server(PidOrOptions, fun(Pid) -> reltool_server:gen_target(Pid, TargetDir) end). +create_target(PidOrOptions, TargetDir) + when is_pid(PidOrOptions); is_list(PidOrOptions) -> + eval_server(PidOrOptions, true, + fun(Pid) -> reltool_server:gen_target(Pid, TargetDir) end). %% Generate a target system -spec get_target_spec(server()) -> {ok, target_spec()} | {error, reason()}. -get_target_spec(PidOrOptions) when is_pid(PidOrOptions); is_list(PidOrOptions) -> - eval_server(PidOrOptions, fun(Pid) -> reltool_server:gen_spec(Pid) end). +get_target_spec(PidOrOptions) + when is_pid(PidOrOptions); is_list(PidOrOptions) -> + eval_server(PidOrOptions, true, + fun(Pid) -> reltool_server:gen_spec(Pid) end). %% Generate a target system --spec eval_target_spec(target_spec(), root_dir(), target_dir()) -> ok | {error, reason()}. -eval_target_spec(Spec, SourceDir, TargetDir) when is_list(SourceDir), is_list(TargetDir) -> +-spec eval_target_spec(target_spec(), root_dir(), target_dir()) -> + ok | {error, reason()}. +eval_target_spec(Spec, SourceDir, TargetDir) + when is_list(SourceDir), is_list(TargetDir) -> reltool_target:eval_spec(Spec, SourceDir, TargetDir). %% Install a target system diff --git a/lib/reltool/src/reltool.hrl b/lib/reltool/src/reltool.hrl index 736daab0f0..1a34ced89d 100644 --- a/lib/reltool/src/reltool.hrl +++ b/lib/reltool/src/reltool.hrl @@ -1,152 +1,255 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009. All Rights Reserved. -%% +%% +%% 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% --define(APPLICATION, reltool). --define(MISSING_APP, '*MISSING*'). +-define(APPLICATION, reltool). +-define(MISSING_APP_NAME, '*MISSING*'). -define(MISSING_APP_TEXT, "*MISSING*"). +-type file() :: string(). +-type dir() :: string(). +%% app - Include all modules in app file +%% ebin - Include all modules on ebin directory +%% derived - Include only those modules that others are dependent on +-type mod_cond() :: all | app | ebin | derived | none. +-type incl_cond() :: include | exclude | derived. +-type debug_info() :: keep | strip. +-type app_file() :: keep | strip | all. +-type re_regexp() :: string(). % re:regexp() +-type regexps() :: [re_regexp()] | + {add, [re_regexp()]} | + {del, [re_regexp()]} . +-type incl_sys_filters() :: regexps(). +-type excl_sys_filters() :: regexps(). +-type incl_app_filters() :: regexps(). +-type excl_app_filters() :: regexps(). +-type incl_archive_filters() :: regexps(). +-type excl_archive_filters() :: regexps(). +-type archive_opt() :: term(). % zip:create() +-type root_dir() :: dir(). +-type lib_dir() :: dir(). +-type profile() :: development | embedded | standalone. +-type relocatable() :: boolean(). +-type escript_file() :: file(). +-type mod_name() :: atom(). +-type app_name() :: atom(). +-type app_vsn() :: string(). % e.g. "4.7" +-type app_label() :: string().% e.g. "mnesia" or "mnesia-4.7" +-type app_type() :: permanent | transient | temporary | load | none. +-type incl_app() :: app_name(). +-type emu_name() :: string(). +-type rel_name() :: string(). +-type rel_vsn() :: string(). +-type boot_rel() :: rel_name(). +-type rel_app() :: app_name() + | {app_name(), app_type()} + | {app_name(), [incl_app()]} + | {app_name(), app_type(), [incl_app()]}. +-type mod() :: {incl_cond, incl_cond()} + | {debug_info, debug_info()}. +-type app() :: {vsn, app_vsn()} + | {mod, mod_name(), mod()} + | {mod_cond, mod_cond()} + | {incl_cond, incl_cond()} + | {app_file, app_file()} + | {debug_info, debug_info()} + | {incl_app_filters, incl_app_filters()} + | {excl_app_filters, excl_app_filters()} + | {incl_archive_filters, incl_archive_filters()} + | {excl_archive_filters, excl_archive_filters()}. +-type escript() :: {incl_cond, incl_cond()}. +-type sys() :: {mod_cond, mod_cond()} + | {incl_cond, incl_cond()} + | {debug_info, debug_info()} + | {app_file, app_file()} + | {profile, profile()} + | {incl_sys_filters, incl_sys_filters()} + | {excl_sys_filters, excl_sys_filters()} + | {incl_app_filters, incl_app_filters()} + | {excl_app_filters, excl_app_filters()} + | {incl_archive_filters, incl_archive_filters()} + | {excl_archive_filters, excl_archive_filters()} + | {archive_opts, [archive_opt()]} + | {root_dir, root_dir()} + | {lib_dirs, [lib_dir()]} + | {boot_rel, boot_rel()} + | {rel, rel_name(), rel_vsn(), [rel_app()]} + | {relocatable, relocatable()} + | {erts, app()} + | {escript, escript_file(), [escript()]} + | {app, app_name(), [app()]}. +-type config() :: {sys, [sys()]}. +-type option() :: {wx_debug, term()} | + {trap_exit, boolean()} | + config() | + {config, config() | file()}. +-type options() :: [option()]. +-type server_pid() :: pid(). +-type window_pid() :: pid(). +-type server() :: server_pid() | options(). +-type rel_file() :: term(). +-type script_file() :: term(). +-type reason() :: string(). + +-type base_dir() :: dir(). +-type base_file() :: file(). +-type top_dir() :: file(). +-type top_file() :: file(). +-type target_spec() :: [target_spec()] + | {create_dir, base_dir(), [target_spec()]} + | {create_dir, base_dir(), top_dir(), [target_spec()]} + | {archive, base_file(), [archive_opt()], [target_spec()]} + | {copy_file, base_file()} + | {copy_file, base_file(), top_file()} + | {write_file, base_file(), iolist()} + | {strip_beam_file, base_file()}. +-type target_dir() :: dir(). +-type incl_defaults() :: boolean(). +-type incl_derived() :: boolean(). +-type ets_tab() :: term(). +-type status() :: missing | ok. + -record(common, { - sys_debug, % term() - wx_debug, % term() - trap_exit, % bool() - app_tab, % ets_tab() - mod_tab, % ets_tab() - mod_used_by_tab % ets_tab() + sys_debug :: term(), + wx_debug :: term(), + trap_exit :: boolean(), + app_tab :: ets_tab(), + mod_tab :: ets_tab(), + mod_used_by_tab :: ets_tab() }). --record(sys, - { - %% Sources - root_dir, % directory() - lib_dirs, % [directory()] - escripts, % [file()] - mod_cond, % all | app | ebin | derived | none - incl_cond, % include | exclude | derived - apps, % [#app{}] - %% Target cond - boot_rel, % string() - rels, % [#rel{}] - emu_name, % string() - profile, % standalone | development | embedded - incl_sys_filters, % [regexp()] - excl_sys_filters, % [regexp()] - incl_app_filters, % [regexp()] - excl_app_filters, % [regexp()] - incl_archive_filters, % [regexp()] - excl_archive_filters, % [regexp()] - archive_opts, % [zip:create()] - relocatable, % bool() - app_type, % permanent | transient | temporary | load | none - app_file, % keep | strip | all - debug_info % keep | strip - }). +-record(mod, + {%% Static + name :: mod_name(), + app_name :: app_name(), + incl_cond :: incl_cond() | undefined, + debug_info :: debug_info() | undefined, + is_app_mod :: boolean(), + is_ebin_mod :: boolean(), + uses_mods :: [mod_name()], + exists :: boolean(), --record(rel, - { - name, % string() - vsn, % string() - rel_apps % [#rel_app{}] + %% Dynamic + status :: status(), + used_by_mods :: [mod_name()], + is_pre_included :: boolean() | undefined, + is_included :: boolean() | undefined }). --record(rel_app, +-record(app_info, { - name, % atom() - app_type, % permanent | transient | temporary | load | none - incl_apps % [atom()] + description = "" :: string(), + id = "" :: string(), + vsn = "" :: app_vsn(), + modules = [] :: [mod_name()], + maxP = infinity :: integer() | infinity, + maxT = infinity :: integer() | infinity, + registered = [] :: [atom()], + incl_apps = [] :: [app_name()], + applications = [] :: [app_name()], + env = [] :: [{atom(), term()}], + mod = undefined :: {mod_name(), [term()]} | undefined, + start_phases = undefined :: [{atom(), term()}] | undefined }). -record(app, {%% Static info - name, % atom() - is_escript, % bool() - use_selected_vsn,% bool() | undefined - active_dir, % dir_name() - sorted_dirs, % [dir_name()] - vsn, % string() e.g. "4.7" - label, % string() e.g. "mnesia" or "mnesia-4.7" - info, % #app_info{} | undefined - mods, % [#mod{}] + name :: app_name(), + is_escript :: boolean(), + use_selected_vsn :: boolean() | undefined, + active_dir :: dir(), + sorted_dirs :: [dir()], + vsn :: app_vsn(), + label :: app_label(), + info :: #app_info{} | undefined, + mods :: [#mod{}], %% Static source cond - mod_cond, % all | app | ebin | derived | none | undefined - incl_cond, % include | exclude | derived | undefined + mod_cond :: mod_cond() | undefined, + incl_cond :: incl_cond() | undefined, %% Static target cond - debug_info, % keep | strip | undefined - app_file, % keep | strip | all | undefined - app_type, % permanent | transient | temporary | load | none - incl_app_filters, % [regexp()] - excl_app_filters, % [regexp()] - incl_archive_filters, % [regexp()] - excl_archive_filters, % [regexp()] - archive_opts, % [zip_create_opt()] + debug_info :: debug_info() | undefined, + app_file :: app_file() | undefined, + app_type :: app_type() | undefined, + incl_app_filters :: incl_app_filters(), + excl_app_filters :: excl_app_filters(), + incl_archive_filters :: incl_archive_filters(), + excl_archive_filters :: excl_archive_filters(), + archive_opts :: [archive_opt()], %% Dynamic - status, % missing | ok - uses_mods, % [atom()] - used_by_mods, % [atom()] - uses_apps, % [atom()] - used_by_apps, % [atom()] - is_pre_included, % bool() - is_included % bool() - }). - --record(mod, - {%% Static - name, % atom() - app_name, % atom() - incl_cond, % include | exclude | derived | undefined - debug_info, % keep | strip | undefined - is_app_mod, % bool(), - is_ebin_mod, % bool(), - uses_mods, % [module()] - exists, % bool() - %% Dynamic - status, % missing | ok - used_by_mods, % [atom()] - is_pre_included, % bool() | undefined - is_included % bool() | undefined + status :: status(), + uses_mods :: [mod_name()], + used_by_mods :: [mod_name()], + uses_apps :: [app_name()], + used_by_apps :: [app_name()], + is_pre_included :: boolean(), + is_included :: boolean(), + rels :: [rel_name()] }). -%% app - Include all modules in app file -%% ebin - Include all modules on ebin directory -%% derived - Include only those modules that others are dependent on +-record(rel_app, + { + name :: app_name(), + app_type :: app_type(), + incl_apps :: [incl_app()] + }). --record(app_info, +-record(rel, { - description = "", - id = "", - vsn = "", - modules = [], - maxP = infinity, - maxT = infinity, - registered = [], - incl_apps = [], - applications = [], - env = [], - mod = undefined, - start_phases = undefined + name :: rel_name(), + vsn :: rel_vsn(), + rel_apps :: [#rel_app{}] + }). + +-record(sys, + { + %% Sources + root_dir :: dir(), + lib_dirs :: [dir()], + escripts :: [file()], + mod_cond :: mod_cond(), + incl_cond :: incl_cond(), + apps :: [#app{}], + + %% Target cond + boot_rel :: boot_rel(), + rels :: [#rel{}], + emu_name :: emu_name(), + profile :: profile(), + incl_sys_filters :: incl_sys_filters(), + excl_sys_filters :: excl_sys_filters(), + incl_app_filters :: incl_app_filters(), + excl_app_filters :: excl_app_filters(), + incl_archive_filters :: incl_archive_filters(), + excl_archive_filters :: excl_archive_filters(), + archive_opts :: [archive_opt()], + relocatable :: boolean(), + rel_app_type :: app_type(), + embedded_app_type :: app_type() | undefined, + app_file :: app_file(), + debug_info :: debug_info() }). -record(regexp, {source, compiled}). - + -define(ERR_IMAGE, 0). -define(WARN_IMAGE, 1). -define(QUEST_IMAGE, 2). @@ -165,12 +268,13 @@ -define(DEFAULT_EMU_NAME, "beam"). -define(DEFAULT_PROFILE, development). -define(DEFAULT_RELOCATABLE, true). --define(DEFAULT_APP_TYPE, permanent). +-define(DEFAULT_REL_APP_TYPE, permanent). +-define(DEFAULT_EMBEDDED_APP_TYPE, undefined). -define(DEFAULT_APP_FILE, keep). -define(DEFAULT_DEBUG_INFO, keep). -define(DEFAULT_INCL_ARCHIVE_FILTERS, [".*"]). --define(DEFAULT_EXCL_ARCHIVE_FILTERS, ["^include$", "^priv$"]). +-define(DEFAULT_EXCL_ARCHIVE_FILTERS, ["^include\$", "^priv\$"]). -define(DEFAULT_ARCHIVE_OPTS, []). -define(DEFAULT_INCL_SYS_FILTERS, [".*"]). @@ -178,25 +282,28 @@ -define(DEFAULT_INCL_APP_FILTERS, [".*"]). -define(DEFAULT_EXCL_APP_FILTERS, []). --define(EMBEDDED_INCL_SYS_FILTERS, ["^bin", - "^erts", - "^lib", - "^releases"]). --define(EMBEDDED_EXCL_SYS_FILTERS, ["^bin/(erlc|dialyzer|typer)(|\\.exe)$", - "^erts.*/bin/(erlc|dialyzer|typer)(|\\.exe)$", - "^erts.*/bin/.*(debug|pdb)"]). +-define(EMBEDDED_INCL_SYS_FILTERS, ["^bin", + "^erts", + "^lib", + "^releases"]). +-define(EMBEDDED_EXCL_SYS_FILTERS, + ["^bin/(erlc|dialyzer|typer)(|\\.exe)\$", + "^erts.*/bin/(erlc|dialyzer|typer)(|\\.exe)\$", + "^erts.*/bin/.*(debug|pdb)"]). -define(EMBEDDED_INCL_APP_FILTERS, ["^ebin", - "^priv", - "^include"]). + "^include", + "^priv"]). -define(EMBEDDED_EXCL_APP_FILTERS, []). +-define(EMBEDDED_APP_TYPE, load). --define(STANDALONE_INCL_SYS_FILTERS, ["^bin/(erl|epmd)(|\\.exe|\\.ini)$", - "^bin/start(|_clean).boot$", - "^erts.*/bin", - "^lib$"]). --define(STANDALONE_EXCL_SYS_FILTERS, ["^erts.*/bin/(erlc|dialyzer|typer)(|\\.exe)$", - "^erts.*/bin/(start|escript|to_erl|run_erl)(|\\.exe)$", - "^erts.*/bin/.*(debug|pdb)"]). --define(STANDALONE_INCL_APP_FILTERS, ["^ebin", +-define(STANDALONE_INCL_SYS_FILTERS, ["^bin/(erl|epmd)(|\\.exe|\\.ini)\$", + "^bin/start(|_clean).boot\$", + "^erts.*/bin", + "^lib\$"]). +-define(STANDALONE_EXCL_SYS_FILTERS, + ["^erts.*/bin/(erlc|dialyzer|typer)(|\\.exe)\$", + "^erts.*/bin/(start|escript|to_erl|run_erl)(|\\.exe)\$", + "^erts.*/bin/.*(debug|pdb)"]). +-define(STANDALONE_INCL_APP_FILTERS, ["^ebin", "^priv"]). --define(STANDALONE_EXCL_APP_FILTERS, ["^ebin/.*\\.appup$"]). +-define(STANDALONE_EXCL_APP_FILTERS, ["^ebin/.*\\.appup\$"]). diff --git a/lib/reltool/src/reltool_app_win.erl b/lib/reltool/src/reltool_app_win.erl index 6083493c02..70bd72b258 100644 --- a/lib/reltool/src/reltool_app_win.erl +++ b/lib/reltool/src/reltool_app_win.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009. All Rights Reserved. -%% +%% +%% 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% -module(reltool_app_win). @@ -34,7 +34,7 @@ -include_lib("wx/include/wx.hrl"). -include("reltool.hrl"). --record(state, +-record(state, {parent_pid, xref_pid, mod_wins, @@ -63,7 +63,7 @@ %% -define(APPS_APP_COL_WIDTH, 250). -define(CLOSE_ITEM, ?wxID_EXIT). %% Use OS specific version if available --define(ABOUT_ITEM, ?wxID_ABOUT). %% Use OS specific +-define(ABOUT_ITEM, ?wxID_ABOUT). %% Use OS specific -define(CONTENTS_ITEM, 300). -define(MODS_MOD_COL, 0). @@ -79,7 +79,11 @@ %% Client start_link(WxEnv, Xref, Common, AppName) -> - proc_lib:start_link(?MODULE, init, [self(), WxEnv, Xref, Common, AppName], infinity, []). + proc_lib:start_link(?MODULE, + init, + [self(), WxEnv, Xref, Common, AppName], + infinity, + []). raise(Pid) -> reltool_utils:cast(Pid, raise). @@ -121,7 +125,12 @@ loop(#state{xref_pid = Xref, common = C, app = App} = S) -> receive {system, From, Msg} -> Dbg = C#common.sys_debug, - sys:handle_system_msg(Msg, From, S#state.parent_pid, ?MODULE, Dbg, S); + sys:handle_system_msg(Msg, + From, + S#state.parent_pid, + ?MODULE, + Dbg, + S); {cast, _From, raise} -> wxFrame:raise(S#state.frame), wxFrame:setFocus(S#state.frame), @@ -131,7 +140,8 @@ loop(#state{xref_pid = Xref, common = C, app = App} = S) -> {ok, App2} -> {ok, Sys} = reltool_server:get_sys(Xref), S2 = redraw_window(S#state{sys = Sys, app = App2}), - [ok = reltool_mod_win:refresh(MW#mod_win.pid) || MW <- S2#state.mod_wins], + [ok = reltool_mod_win:refresh(MW#mod_win.pid) || + MW <- S2#state.mod_wins], ?MODULE:loop(S2); {error, _Reason} -> wxFrame:destroy(S#state.frame), @@ -139,7 +149,8 @@ loop(#state{xref_pid = Xref, common = C, app = App} = S) -> end; {call, ReplyTo, Ref, {open_mod, ModName}} -> S2 = create_mod_window(S, ModName), - {value, #mod_win{pid = ModPid}} = lists:keysearch(ModName, #mod_win.name, S2#state.mod_wins), + {value, #mod_win{pid = ModPid}} = + lists:keysearch(ModName, #mod_win.name, S2#state.mod_wins), reltool_utils:reply(ReplyTo, Ref, {ok, ModPid}), ?MODULE:loop(S2); #wx{event = #wxSize{}} = Wx -> @@ -157,7 +168,9 @@ loop(#state{xref_pid = Xref, common = C, app = App} = S) -> exit(Reason); {'EXIT', Pid, _Reason} = Exit -> exit_warning(Exit), - S2 = S#state{mod_wins = lists:keydelete(Pid, #mod_win.pid, S#state.mod_wins)}, + S2 = S#state{mod_wins = lists:keydelete(Pid, + #mod_win.pid, + S#state.mod_wins)}, ?MODULE:loop(S2); Msg -> error_logger:format("~p~p got unexpected message:\n\t~p\n", @@ -179,7 +192,7 @@ create_window(#state{app = App} = S) -> StatusBar = wxFrame:createStatusBar(Frame,[]), Book = wxNotebook:new(Panel, ?wxID_ANY, []), - + S2 = S#state{frame = Frame, panel = Panel, book = Book, @@ -210,12 +223,16 @@ create_apps_page(S, Derived) -> Lower = wxBoxSizer:new(?wxHORIZONTAL), UsedByCtrl = create_apps_list_ctrl(Panel, Upper, "Used by"), - wxSizer:add(Upper, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]), [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]), - + wxSizer:add(Upper, + wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]), + [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]), + RequiredCtrl = create_apps_list_ctrl(Panel, Upper, "Required"), - wxSizer:add(Upper, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]), [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]), + wxSizer:add(Upper, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]), + [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]), InclCtrl = create_apps_list_ctrl(Panel, Upper, "Included"), - wxSizer:add(Upper, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]), [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]), + wxSizer:add(Upper, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]), + [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]), UsesCtrl = create_apps_list_ctrl(Panel, Upper, "Uses"), S2 = S#state{app_required_ctrl = RequiredCtrl, app_used_by_ctrl = UsedByCtrl, @@ -262,8 +279,10 @@ create_apps_list_ctrl(Panel, Sizer, Text) -> [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}, {proportion, 1}]), - wxEvtHandler:connect(ListCtrl, size, [{skip, true}, {userData, apps_list_ctrl}]), - wxListCtrl:connect(ListCtrl, command_list_item_activated, [{userData, open_app}]), + wxEvtHandler:connect(ListCtrl, size, + [{skip, true}, {userData, apps_list_ctrl}]), + wxListCtrl:connect(ListCtrl, command_list_item_activated, + [{userData, open_app}]), wxWindow:connect(ListCtrl, enter_window), ListCtrl. @@ -271,9 +290,20 @@ create_deps_page(S, Derived) -> Panel = wxPanel:new(S#state.book, []), Main = wxBoxSizer:new(?wxHORIZONTAL), - UsedByCtrl = create_mods_list_ctrl(Panel, Main, "Modules used by others", " and their applications", undefined, undefined), - wxSizer:add(Main, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]), [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]), - UsesCtrl = create_mods_list_ctrl(Panel, Main, "Used modules", " and their applications", undefined, undefined), + UsedByCtrl = create_mods_list_ctrl(Panel, + Main, + "Modules used by others", + " and their applications", + undefined, + undefined), + wxSizer:add(Main, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]), + [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]), + UsesCtrl = create_mods_list_ctrl(Panel, + Main, + "Used modules", + " and their applications", + undefined, + undefined), S2 = S#state{deps_used_by_ctrl = UsedByCtrl, deps_uses_ctrl = UsesCtrl}, redraw_mods(S2, Derived), @@ -285,13 +315,36 @@ create_mods_page(S, Derived) -> Panel = wxPanel:new(S#state.book, []), MainSz = wxBoxSizer:new(?wxHORIZONTAL), - SourceCtrl = create_mods_list_ctrl(Panel, MainSz, ?source, "", whitelist_add, blacklist_add), - wxSizer:add(MainSz, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]), [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]), - WhiteCtrl = create_mods_list_ctrl(Panel, MainSz, ?whitelist, "", whitelist_del, blacklist_add), - wxSizer:add(MainSz, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]), [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]), - BlackCtrl = create_mods_list_ctrl(Panel, MainSz, ?blacklist, "", whitelist_add, blacklist_del), - wxSizer:add(MainSz, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]), [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]), - DerivedCtrl = create_mods_list_ctrl(Panel, MainSz, ?derived, "", whitelist_add, blacklist_add), + SourceCtrl = create_mods_list_ctrl(Panel, + MainSz, + ?source, + "", + whitelist_add, + blacklist_add), + wxSizer:add(MainSz, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]), + [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]), + WhiteCtrl = create_mods_list_ctrl(Panel, + MainSz, + ?whitelist, + "", + whitelist_del, + blacklist_add), + wxSizer:add(MainSz, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]), + [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]), + BlackCtrl = create_mods_list_ctrl(Panel, + MainSz, + ?blacklist, + "", + whitelist_add, + blacklist_del), + wxSizer:add(MainSz, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]), + [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]), + DerivedCtrl = create_mods_list_ctrl(Panel, + MainSz, + ?derived, + "", + whitelist_add, + blacklist_add), S2 = S#state{mods_source_ctrl = SourceCtrl, mods_white_ctrl = WhiteCtrl, mods_black_ctrl = BlackCtrl, @@ -309,7 +362,8 @@ create_mods_list_ctrl(Panel, OuterSz, Title, AppText, Tick, Cross) -> %% ?wxLC_SINGLE_SEL bor ?wxHSCROLL bor ?wxVSCROLL}]), - ToolTip = "Select module(s) or open separate module window with a double click.", + ToolTip = "Select module(s) or open separate module " + "window with a double click.", wxListCtrl:setToolTip(ListCtrl, ToolTip), %% Prep images @@ -326,7 +380,8 @@ create_mods_list_ctrl(Panel, OuterSz, Title, AppText, Tick, Cross) -> true -> wxListItem:setText(ListItem, AppText), wxListCtrl:insertColumn(ListCtrl, ?MODS_APP_COL, ListItem), - %% wxListCtrl:setColumnWidth(ListCtrl, ?MODS_APP_COL, ?MODS_APP_COL_WIDTH), + %% wxListCtrl:setColumnWidth(ListCtrl, ?MODS_APP_COL, + %% ?MODS_APP_COL_WIDTH), 2; false -> 1 @@ -336,9 +391,11 @@ create_mods_list_ctrl(Panel, OuterSz, Title, AppText, Tick, Cross) -> ButtonSz = wxBoxSizer:new(?wxHORIZONTAL), create_button(Panel, ButtonSz, ListCtrl, Title, "wxART_TICK_MARK", Tick), create_button(Panel, ButtonSz, ListCtrl, Title, "wxART_CROSS_MARK", Cross), - wxEvtHandler:connect(ListCtrl, size, [{skip, true}, {userData, mods_list_ctrl}]), - wxListCtrl:connect(ListCtrl, command_list_item_activated, [{userData, open_mod}]), - wxWindow:connect(ListCtrl, enter_window), + wxEvtHandler:connect(ListCtrl, size, + [{skip, true}, {userData, mods_list_ctrl}]), + wxListCtrl:connect(ListCtrl, command_list_item_activated, + [{userData, open_mod}]), + wxWindow:connect(ListCtrl, enter_window), InnerSz = wxBoxSizer:new(?wxVERTICAL), wxSizer:add(InnerSz, ListCtrl, [{border, 2}, @@ -377,7 +434,7 @@ action_to_tool_tip(Label, Action) -> "Remove selected module(s)from whitelist."; blacklist_add when Label =:= ?blacklist -> "Remove selected module(s) from blacklist."; - blacklist_add -> + blacklist_add -> "Add selected module(s) to blacklist."; blacklist_del -> "Remove selected module(s) from blacklist." @@ -444,8 +501,8 @@ create_config_page(#state{app = App} = S) -> wxNotebook:addPage(S2#state.book, Panel, "Application settings", []), S2. -create_double_box(Panel, Sizer, TopLabel, - OuterText, OuterData, +create_double_box(Panel, Sizer, TopLabel, + OuterText, OuterData, InnerText, InnerData, InternalLabel, InternalChoices, InternalChoiceData) -> TopSizer = wxStaticBoxSizer:new(?wxVERTICAL, Panel, @@ -457,10 +514,10 @@ create_double_box(Panel, Sizer, TopLabel, [{userData, OuterData}]), InnerRadio = wxRadioButton:new(Panel, ?wxID_ANY, InnerText), wxEvtHandler:connect(InnerRadio, command_radiobutton_selected, - [{userData, InnerData}]), - InnerBox = wxRadioBox:new(Panel, + [{userData, InnerData}]), + InnerBox = wxRadioBox:new(Panel, ?wxID_ANY, - InternalLabel, + InternalLabel, ?wxDefaultPosition, ?wxDefaultSize, InternalChoices, @@ -487,29 +544,38 @@ handle_event(#state{sys = Sys, app = App} = S, Wx) -> #wx{obj = ObjRef, event = #wxMouse{type = enter_window}} -> wxWindow:setFocus(ObjRef), S; - #wx{obj= ListCtrl, userData = mods_list_ctrl, event = #wxSize{type = size, size = {W, _H}}} -> + #wx{obj= ListCtrl, + userData = mods_list_ctrl, + event = #wxSize{type = size, size = {W, _H}}} -> HasApps = (wxListCtrl:getColumnCount(ListCtrl) > 1), case HasApps of false -> wxListCtrl:setColumnWidth(ListCtrl, ?MODS_MOD_COL, W); true -> - wxListCtrl:setColumnWidth(ListCtrl, ?MODS_MOD_COL, (2 * W) div 3), + wxListCtrl:setColumnWidth(ListCtrl, + ?MODS_MOD_COL, + (2 * W) div 3), wxListCtrl:setColumnWidth(ListCtrl, ?MODS_APP_COL, W div 3) end, S; - #wx{obj= ListCtrl, userData = apps_list_ctrl, event = #wxSize{type = size, size = {W, _H}}} -> + #wx{obj = ListCtrl, + userData = apps_list_ctrl, + event = #wxSize{type = size, size = {W, _H}}} -> wxListCtrl:setColumnWidth(ListCtrl, ?APPS_APP_COL, W), S; #wx{userData = open_app, obj = ListCtrl, - event = #wxList{type = command_list_item_activated, itemIndex = Pos}} -> + event = #wxList{type = command_list_item_activated, + itemIndex = Pos}} -> AppBase = wxListCtrl:getItemText(ListCtrl, Pos), {AppName, _AppVsn} = reltool_utils:split_app_name(AppBase), - {ok, _AppPid} = reltool_sys_win:open_app(S#state.parent_pid, AppName), + {ok, _AppPid} = reltool_sys_win:open_app(S#state.parent_pid, + AppName), S; #wx{userData = open_mod, obj = ListCtrl, - event = #wxList{type = command_list_item_activated, itemIndex = Pos}} -> + event = #wxList{type = command_list_item_activated, + itemIndex = Pos}} -> ModName = list_to_atom(wxListCtrl:getItemText(ListCtrl, Pos)), create_mod_window(S, ModName); #wx{userData = global_incl_cond} -> @@ -560,16 +626,19 @@ handle_event(#state{sys = Sys, app = App} = S, Wx) -> Items = reltool_utils:get_items(ListCtrl), handle_mod_button(S, Items, Action); _ -> - error_logger:format("~p~p got unexpected app event from wx:\n\t~p\n", + error_logger:format("~p~p got unexpected app event from " + "wx:\n\t~p\n", [?MODULE, self(), Wx]), S end. -create_mod_window(#state{parent_pid = RelPid, xref_pid = Xref, common = C} = S, ModName) -> +create_mod_window(#state{parent_pid = RelPid, xref_pid = Xref, common = C} = S, + ModName) -> case lists:keysearch(ModName, #mod_win.name, S#state.mod_wins) of false -> WxEnv = wx:get_env(), - {ok, Pid} = reltool_mod_win:start_link(WxEnv, Xref, RelPid, C, ModName), + {ok, Pid} = + reltool_mod_win:start_link(WxEnv, Xref, RelPid, C, ModName), MW = #mod_win{name = ModName, pid = Pid}, S#state{mod_wins = [MW | S#state.mod_wins]}; {value, MW} -> @@ -578,7 +647,9 @@ create_mod_window(#state{parent_pid = RelPid, xref_pid = Xref, common = C} = S, end. handle_mod_button(#state{app = App} = S, Items, Action) -> - App2 = lists:foldl(fun(Item, A) -> move_mod(A, Item, Action) end, App, Items), + App2 = lists:foldl(fun(Item, A) -> move_mod(A, Item, Action) end, + App, + Items), {ok, App3} = reltool_sys_win:set_app(S#state.parent_pid, App2), S2 = S#state{app = App3}, redraw_window(S2). @@ -587,7 +658,7 @@ move_mod(App, {_ItemNo, ModStr}, Action) -> ModName = list_to_atom(ModStr), Mods = App#app.mods, {value, M} = lists:keysearch(ModName, #mod.name, Mods), - AppCond = + AppCond = case Action of whitelist_add -> case M#mod.incl_cond of @@ -597,12 +668,13 @@ move_mod(App, {_ItemNo, ModStr}, Action) -> end; whitelist_del -> undefined; - blacklist_add -> + blacklist_add -> exclude; blacklist_del -> undefined; _ -> - error_logger:format("~p~p got unexpected mod button event: ~p\n\t ~p\n", + error_logger:format("~p~p got unexpected mod " + "button event: ~p\n\t ~p\n", [?MODULE, self(), ModName, Action]), M#mod.incl_cond end, @@ -623,7 +695,10 @@ change_mod_cond(S, App, NewModCond) -> redraw_window(S2). change_version(S, App, NewDir) -> - App2 = App#app{active_dir = NewDir, label = undefined, vsn = undefined, info = undefined}, + App2 = App#app{active_dir = NewDir, + label = undefined, + vsn = undefined, + info = undefined}, {ok, App3} = reltool_sys_win:set_app(S#state.parent_pid, App2), Title = app_title(App3), wxFrame:setTitle(S#state.frame, Title), @@ -635,8 +710,14 @@ redraw_apps(#state{app = #app{info = AppInfo}, app_incl_ctrl = InclCtrl, app_uses_ctrl = UsesCtrl, xref_pid = Xref}, - {_SourceMods, _WhiteMods, _BlackMods, _DerivedMods, UsedByMods, UsesMods}) -> - UsedByApps = lists:usort([{M#mod.app_name, Image} || {Image, _, M} <- UsedByMods]), + {_SourceMods, + _WhiteMods, + _BlackMods, + _DerivedMods, + UsedByMods, + UsesMods}) -> + UsedByApps = + lists:usort([{M#mod.app_name, Image} || {Image, _, M} <- UsedByMods]), Select = fun(AppName) -> {ok, App} = reltool_server:get_app(Xref, AppName), @@ -647,7 +728,8 @@ redraw_apps(#state{app = #app{info = AppInfo}, end, RequiredApps = lists:sort(lists:map(Select, AppInfo#app_info.applications)), InclApps = lists:map(Select, AppInfo#app_info.incl_apps), - UsesApps = lists:usort([{M#mod.app_name, Image} || {Image, _, M} <- UsesMods]), + UsesApps = + lists:usort([{M#mod.app_name, Image} || {Image, _, M} <- UsesMods]), do_redraw_apps(UsedByCtrl, UsedByApps), do_redraw_apps(RequiredCtrl, RequiredApps), do_redraw_apps(InclCtrl, InclApps), @@ -656,19 +738,26 @@ redraw_apps(#state{app = #app{info = AppInfo}, do_redraw_apps(ListCtrl, []) -> wxListCtrl:deleteAllItems(ListCtrl); - %% wxListCtrl:setColumnWidth(ListCtrl, ?APPS_APP_COL, ?wxLIST_AUTOSIZE_USEHEADER); + %% wxListCtrl:setColumnWidth(ListCtrl, ?APPS_APP_COL, +%% ?wxLIST_AUTOSIZE_USEHEADER); do_redraw_apps(ListCtrl, AppImages) -> wxListCtrl:deleteAllItems(ListCtrl), Add = fun({AppName, ImageId}, {Row, Prev}) when AppName =/= Prev -> - wxListCtrl:insertItem(ListCtrl, Row, ""), - if (Row rem 2) =:= 0 -> - wxListCtrl:setItemBackgroundColour(ListCtrl, Row, {240,240,255}); + wxListCtrl:insertItem(ListCtrl, Row, ""), + if (Row rem 2) =:= 0 -> + wxListCtrl:setItemBackgroundColour(ListCtrl, + Row, + {240,240,255}); true -> ignore end, Str = atom_to_list(AppName), - wxListCtrl:setItem(ListCtrl, Row, ?APPS_APP_COL, Str, [{imageId, ImageId}]), + wxListCtrl:setItem(ListCtrl, + Row, + ?APPS_APP_COL, + Str, + [{imageId, ImageId}]), {Row + 1, AppName}; ({_, _}, Acc) -> Acc @@ -688,8 +777,13 @@ redraw_mods(#state{mods_source_ctrl = SourceCtrl, deps_uses_ctrl = UsesCtrl, app = #app{is_pre_included = IsPre, is_included = IsIncl}, status_bar = Bar}, - {SourceMods, WhiteMods, BlackMods, DerivedMods, UsedByMods, UsesMods}) -> - InclStatus = + {SourceMods, + WhiteMods, + BlackMods, + DerivedMods, + UsedByMods, + UsesMods}) -> + InclStatus = case IsIncl of true when IsPre =:= true -> "Whitelist - "; true -> "Derived - "; @@ -711,7 +805,7 @@ app_to_mods(#state{xref_pid = Xref, app = App}) -> SourceMods = [M || M <- App#app.mods, M#mod.is_included =/= true, M#mod.is_pre_included =/= false], - WhiteMods = [M || M <- App#app.mods, + WhiteMods = [M || M <- App#app.mods, M#mod.is_pre_included =:= true], BlackMods = [M || M <- App#app.mods, M#mod.is_pre_included =:= false], @@ -722,7 +816,8 @@ app_to_mods(#state{xref_pid = Xref, app = App}) -> fun(ModName) when is_atom(ModName) -> {ok, M} = reltool_server:get_mod(Xref, ModName), if - M#mod.app_name =:= App#app.name, M#mod.is_included =:= true -> + M#mod.app_name =:= App#app.name, + M#mod.is_included =:= true -> false; true -> {true, M} @@ -780,20 +875,26 @@ opt_redraw_mods(undefined, _ImageMods) -> opt_redraw_mods(ListCtrl, ImageMods) -> HasApps = (wxListCtrl:getColumnCount(ListCtrl) > 1), do_redraw_mods(ListCtrl, ImageMods, HasApps). - + do_redraw_mods(ListCtrl, [], _HasApps) -> wxListCtrl:deleteAllItems(ListCtrl); do_redraw_mods(ListCtrl, ImageMods, HasApps) -> wxListCtrl:deleteAllItems(ListCtrl), Add = fun({ImageId, AppName, #mod{name = ModName}}, Row) -> - wxListCtrl:insertItem(ListCtrl, Row, ""), - if (Row rem 2) =:= 0 -> - wxListCtrl:setItemBackgroundColour(ListCtrl, Row, {240,240,255}); + wxListCtrl:insertItem(ListCtrl, Row, ""), + if (Row rem 2) =:= 0 -> + wxListCtrl:setItemBackgroundColour(ListCtrl, + Row, + {240,240,255}); true -> ignore end, - wxListCtrl:setItem(ListCtrl, Row, ?MODS_MOD_COL, atom_to_list(ModName), [{imageId, ImageId}]), + wxListCtrl:setItem(ListCtrl, + Row, + ?MODS_MOD_COL, + atom_to_list(ModName), + [{imageId, ImageId}]), case HasApps of false -> ok; @@ -842,13 +943,14 @@ redraw_config(#state{sys = #sys{incl_cond = GlobalIncl, SelectedRadio, SourceBox, fun(true) -> - reltool_utils:elem_to_index(ActiveDir, SortedDirs) - 1; + reltool_utils:elem_to_index(ActiveDir, + SortedDirs) - 1; (false) -> 0 end). redraw_double_box(Global, Local, GlobalRadio, LocalRadio, LocalBox, GetChoice) -> - AppCond = + AppCond = case Local of undefined -> wxRadioButton:setValue(GlobalRadio, true), diff --git a/lib/reltool/src/reltool_fgraph.erl b/lib/reltool/src/reltool_fgraph.erl index 09c4f8c8ce..2e8f39e418 100644 --- a/lib/reltool/src/reltool_fgraph.erl +++ b/lib/reltool/src/reltool_fgraph.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009. All Rights Reserved. -%% +%% +%% 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% -module(reltool_fgraph). @@ -80,7 +80,7 @@ foreach(Fun, Fg) -> end, Fg), Fg. -map(Fun, Fg) -> +map(Fun, Fg) -> lists:foreach(fun (Key) -> put(Key,Fun(get(Key))) end, Fg), @@ -105,7 +105,9 @@ step(Vs, Es) -> step(Vs, Es, {0,0}). step(Vs, Es, Pa) -> ?MODULE:map(fun (Node = {_, #fg_v{ type = static }}) -> Node; - ({Key, Value = #fg_v{ p = {Px, Py}, v = {Vx, Vy}, type = dynamic}}) when is_float(Px), is_float(Py), is_float(Vx), is_float(Vy) -> + ({Key, Value = #fg_v{ p = {Px, Py}, v = {Vx, Vy}, type = dynamic}}) + when is_float(Px), is_float(Py), + is_float(Vx), is_float(Vy) -> F0 = {0.0,0.0}, F1 = coulomb_repulsion(Key, Value, Vs, F0), F2 = hooke_attraction(Key, Value, Vs, Es, F1), @@ -115,7 +117,7 @@ step(Vs, Es, Pa) -> Vx1 = (Vx + ?fg_th*Fx)*?fg_damp, Vy1 = (Vy + ?fg_th*Fy)*?fg_damp, - + Px1 = Px + ?fg_th*Vx1, Py1 = Py + ?fg_th*Vy1, @@ -123,14 +125,16 @@ step(Vs, Es, Pa) -> (Node) -> Node end, Vs). -point_attraction(_, #fg_v{ p = P0 }, Pa, {Fx, Fy}) when is_float(Fx), is_float(Fy) -> +point_attraction(_, #fg_v{ p = P0 }, Pa, {Fx, Fy}) + when is_float(Fx), is_float(Fy) -> K = 20, L = 150, {R, {Cx,Cy}} = composition(P0, Pa), F = -K*?fg_stretch*(R - L), {Fx + Cx*F, Fy + Cy*F}. - -coulomb_repulsion(K0, #fg_v{ p = P0, q = Q0}, Vs, {Fx0, Fy0}) when is_float(Fx0), is_float(Fy0) -> + +coulomb_repulsion(K0, #fg_v{ p = P0, q = Q0}, Vs, {Fx0, Fy0}) + when is_float(Fx0), is_float(Fy0) -> ?MODULE:foldl(fun ({K1, _}, F) when K1 == K0 -> F; ({_, #fg_v{ p = P1, q = Q1}}, {Fx, Fy}) -> @@ -140,7 +144,8 @@ coulomb_repulsion(K0, #fg_v{ p = P0, q = Q0}, Vs, {Fx0, Fy0}) when is_float(Fx0) (_, F) -> F end, {Fx0, Fy0}, Vs). -hooke_attraction(Key0, #fg_v{ p = P0 }, Vs, Es, {Fx0, Fy0}) when is_float(Fx0), is_float(Fy0) -> +hooke_attraction(Key0, #fg_v{ p = P0 }, Vs, Es, {Fx0, Fy0}) + when is_float(Fx0), is_float(Fy0) -> ?MODULE:foldl(fun ({{Key1,Key1}, _}, F) -> F; ({{Key1,Key2}, #fg_e{ l = L, k = K}}, {Fx, Fy}) when Key1 =:= Key0-> @@ -153,10 +158,11 @@ hooke_attraction(Key0, #fg_v{ p = P0 }, Vs, Es, {Fx0, Fy0}) when is_float(Fx0), {R, {Cx,Cy}} = composition(P0, P1), F = -K*?fg_stretch*(R - L), {Fx + Cx*F, Fy + Cy*F}; - (_, F) -> F + (_, F) -> F end, {Fx0, Fy0}, Es). -composition({Px1, Py1}, {Px0, Py0}) when is_float(Px1), is_float(Py1), is_float(Px0), is_float(Py0) -> +composition({Px1, Py1}, {Px0, Py0}) + when is_float(Px1), is_float(Py1), is_float(Px0), is_float(Py0) -> Dx = Px1 - Px0, Dy = Py1 - Py0, R = math:sqrt(Dx*Dx + Dy*Dy + 0.001), diff --git a/lib/reltool/src/reltool_fgraph_win.erl b/lib/reltool/src/reltool_fgraph_win.erl index b063fb94ba..b0deb1bab2 100644 --- a/lib/reltool/src/reltool_fgraph_win.erl +++ b/lib/reltool/src/reltool_fgraph_win.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009. All Rights Reserved. -%% +%% +%% 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% -module(reltool_fgraph_win). @@ -95,7 +95,7 @@ change_node(Pid, Key, Color) -> Pid ! {change_node, Key, Color}. add_link(Pid, {FromKey, ToKey}) -> Pid ! {add_link, {FromKey, ToKey}}. del_link(Pid, {FromKey, ToKey}) -> Pid ! {del_link, {FromKey, ToKey}}. -stop(Pid, Reason) -> +stop(Pid, Reason) -> Ref = erlang:monitor(process, Pid), Pid ! {stop, Reason}, receive @@ -110,21 +110,24 @@ new(Parent, Options) -> Me = self(), Pid = spawn_link(fun() -> init([Parent, Me, Env, Options]) end), receive {Pid, {?MODULE, Panel}} -> {Pid,Panel} end. - + init([ParentWin, Pid, Env, Options]) -> wx:set_env(Env), - + BReset = wxButton:new(ParentWin, ?reset, [{label,"Reset"}]), BFreeze = wxButton:new(ParentWin, ?freeze, [{label,"Freeze"}]), BLock = wxButton:new(ParentWin, ?lock, [{label,"Lock"}]), BUnlock = wxButton:new(ParentWin, ?unlock, [{label,"Unlock"}]), BDelete = wxButton:new(ParentWin, ?delete, [{label,"Delete"}]), - SQ = wxSlider:new(ParentWin, ?q_slider, ?default_q, 1, 500, [{style, ?wxVERTICAL}]), - SL = wxSlider:new(ParentWin, ?l_slider, ?default_l, 1, 500, [{style, ?wxVERTICAL}]), - SK = wxSlider:new(ParentWin, ?k_slider, ?default_k, 1, 500, [{style, ?wxVERTICAL}]), + SQ = wxSlider:new(ParentWin, ?q_slider, ?default_q, 1, 500, + [{style, ?wxVERTICAL}]), + SL = wxSlider:new(ParentWin, ?l_slider, ?default_l, 1, 500, + [{style, ?wxVERTICAL}]), + SK = wxSlider:new(ParentWin, ?k_slider, ?default_k, 1, 500, + [{style, ?wxVERTICAL}]), Win = wxWindow:new(ParentWin, ?wxID_ANY, Options), - + ButtonSizer = wxBoxSizer:new(?wxVERTICAL), wxSizer:add(ButtonSizer, BReset), wxSizer:add(ButtonSizer, BFreeze), @@ -141,31 +144,34 @@ init([ParentWin, Pid, Env, Options]) -> WindowSizer = wxBoxSizer:new(?wxHORIZONTAL), wxSizer:add(WindowSizer, ButtonSizer, [{flag, ?wxEXPAND}, {proportion, 0}]), wxSizer:add(WindowSizer, Win, [{flag, ?wxEXPAND}, {proportion, 1}]), - + wxButton:setToolTip(BReset, "Remove selection and unlock all nodes."), wxButton:setToolTip(BFreeze, "Start/stop redraw of screen."), wxButton:setToolTip(BLock, "Lock all selected nodes."), wxButton:setToolTip(BUnlock, "Unlock all selected nodes."), wxButton:setToolTip(BDelete, "Delete all selected nodes."), - wxButton:setToolTip(SQ, "Control repulsive force. This can also be controlled with the mouse wheel on the canvas."), + wxButton:setToolTip(SQ, "Control repulsive force. This can also be" + " controlled with the mouse wheel on the canvas."), wxButton:setToolTip(SL, "Control link length."), wxButton:setToolTip(SK, "Control attractive force. Use with care."), - wxButton:setToolTip(Win, - "Drag mouse while left mouse button is pressed to perform various operations. " - "Combine with control key to select. Combine with shift key to lock single node."), + wxButton:setToolTip(Win, + "Drag mouse while left mouse button is pressed " + "to perform various operations. " + "Combine with control key to select. Combine " + "with shift key to lock single node."), wxButton:connect(BReset, command_button_clicked), wxButton:connect(BFreeze, command_button_clicked), wxButton:connect(BLock, command_button_clicked), wxButton:connect(BUnlock, command_button_clicked), wxButton:connect(BDelete, command_button_clicked), - + wxWindow:connect(SQ, command_slider_updated), wxWindow:connect(SL, command_slider_updated), wxWindow:connect(SK, command_slider_updated), - - wxWindow:connect(Win, enter_window), + + wxWindow:connect(Win, enter_window), wxWindow:connect(Win, move), wxWindow:connect(Win, motion), wxWindow:connect(Win, mousewheel), @@ -174,7 +180,7 @@ init([ParentWin, Pid, Env, Options]) -> wxWindow:connect(Win, left_up), wxWindow:connect(Win, right_down), wxWindow:connect(Win, paint, [{skip, true}]), - + Pen = wxPen:new({0,0,0}, [{width, 3}]), Font = wxFont:new(12, ?wxSWISS, ?wxNORMAL, ?wxNORMAL,[]), Brush = wxBrush:new({0,0,0}), @@ -182,13 +188,13 @@ init([ParentWin, Pid, Env, Options]) -> Pid ! {self(), {?MODULE, WindowSizer}}, wxWindow:setFocus(Win), %% Get keyboard focus - + Vs = reltool_fgraph:new(), Es = reltool_fgraph:new(), Me = self(), Ticker = spawn_link(fun() -> ticker_init(Me) end), - + loop( #state{ parent_pid = Pid, q_slider = SQ, l_slider = SL, @@ -215,14 +221,17 @@ graph_add_node(Key, Color, G = #graph{ vs = Vs}) -> M = 0.5, % mass P = {float(450 + random:uniform(100)), float(450 + random:uniform(100))}, - G#graph{ vs = reltool_fgraph:add(Key, #fg_v{ p = P, m = M, q = Q, color = Color}, Vs)}. + G#graph{ vs = reltool_fgraph:add(Key, + #fg_v{ p = P, m = M, q = Q, color = Color}, + Vs)}. graph_change_node(Key, Color, G) -> case reltool_fgraph:get(Key, G#graph.vs) of - undefined -> + undefined -> G; V -> - G#graph{ vs = reltool_fgraph:set(Key, V#fg_v{ color = Color }, G#graph.vs)} + G#graph{ vs = reltool_fgraph:set(Key, V#fg_v{ color = Color }, + G#graph.vs)} end. graph_del_node(Key, G = #graph{ vs = Vs0, es = Es0}) -> @@ -231,7 +240,7 @@ graph_del_node(Key, G = #graph{ vs = Vs0, es = Es0}) -> G#graph{ vs = Vs, es = Es }. graph_add_link(Key0, Key1, G = #graph{ es = Es}) -> - K = 60.0, % attractive force + K = 60.0, % attractive force L = 5.0, % spring length G#graph{ es = reltool_fgraph:add({Key0, Key1}, #fg_e{ k = K, l = L}, Es) }. @@ -249,15 +258,17 @@ ticker_loop(Pid, Time) -> D = timer:now_diff(T1, T0)/1000, case round(40 - D) of Ms when Ms < 0 -> - %io:format("ticker: wait is 0 ms [fg ~7s ms] [fps ~7s]~n", [s(D), s(1000/D)]), + %io:format("ticker: wait is 0 ms [fg ~7s ms] [fps ~7s]~n", + % [s(D), s(1000/D)]), ticker_loop(Pid, 0); Ms -> - %io:format("ticker: wait is ~3s ms [fg ~7s ms] [fps ~7s]~n", [s(Ms), s(D), s(1000/40)]), + %io:format("ticker: wait is ~3s ms [fg ~7s ms] [fps ~7s]~n", + % [s(Ms), s(D), s(1000/40)]), ticker_loop(Pid, Ms) end end. -delete_edges(Es, []) -> +delete_edges(Es, []) -> Es; delete_edges(Es, [Key|Keys]) -> Edges = reltool_fgraph:foldl(fun @@ -269,7 +280,7 @@ delete_edges(Es, [Key|Keys]) -> (K, Esi) -> reltool_fgraph:del(K, Esi) end, Es, Edges), delete_edges(Es1, Keys). - + set_charge(Q, Vs) -> % Repulsive force F = fun({Key, Value}) -> {Key, Value#fg_v{ q = Q}} end, @@ -295,36 +306,47 @@ loop(S, G) -> wxSlider:setValue(S#state.k_slider, K), Es = set_length(L, G#graph.es), Es2 = set_spring(K, Es), - - Vs2 = reltool_fgraph:map(fun({Key, V}) -> - {Key, V#fg_v{selected = false, type = dynamic, q = Q}} - end, - G#graph.vs), - - {Xs, Ys} = reltool_fgraph:foldl(fun({_Key, #fg_v{p = {X, Y}}}, {Xs, Ys}) -> - {[X| Xs], [Y | Ys]} - end, - {[], []}, - Vs2), + + Vs2 = + reltool_fgraph:map(fun({Key, V}) -> + {Key, V#fg_v{selected = false, + type = dynamic, + q = Q}} + end, + G#graph.vs), + + {Xs, Ys} = + reltool_fgraph:foldl(fun({_Key, + #fg_v{p = {X, Y}}}, {Xs, Ys}) -> + {[X| Xs], [Y | Ys]} + end, + {[], []}, + Vs2), %% io:format("Before: ~p\n", [G#graph.offset]), Offset = case length(Xs) of 0 -> {0, 0}; N -> - MeanX = (lists:sum(Xs) / N), + MeanX = (lists:sum(Xs) / N), MeanY = (lists:sum(Ys) / N), {SizeX, SizeY} = wxWindow:getSize(S#state.window), - %% io:format("Min: ~p\n", [{lists:min(Xs), lists:min(Ys)}]), - %% io:format("Mean: ~p\n", [{MeanX, MeanY}]), - %% io:format("Max: ~p\n", [{lists:max(Xs), lists:max(Ys)}]), + %% io:format("Min: ~p\n", + %% [{lists:min(Xs), lists:min(Ys)}]), + %% io:format("Mean: ~p\n", + %% [{MeanX, MeanY}]), + %% io:format("Max: ~p\n", + %% [{lists:max(Xs), lists:max(Ys)}]), %% io:format("Size: ~p\n", [{SizeX, SizeY}]), %% {XM - (XS / 2), YM - (YS / 2)} %% {0 - lists:min(Xs) + 20, 0 - lists:min(Ys) + 20} {0 - MeanX + (SizeX / 2), 0 - MeanY + (SizeY / 2)} end, %% io:format("After: ~p\n", [Offset]), - loop(S, G#graph{vs = Vs2, es = Es2, offset = Offset, offset_state = false}); + loop(S, G#graph{vs = Vs2, + es = Es2, + offset = Offset, + offset_state = false}); #wx{id = ?freeze, event = #wxCommand{type=command_button_clicked}} -> %% Start/stop redraw of screen IsFrozen = @@ -354,10 +376,15 @@ loop(S, G) -> loop(S, G#graph{ vs = Vs }); #wx{id = ?delete, event = #wxCommand{type=command_button_clicked}} -> %% Delete all selected nodes - {Vs1, Keys} = reltool_fgraph:foldl(fun - ({Key, #fg_v{ selected = true}}, {Vs, Ks}) -> - {reltool_fgraph:del(Key,Vs), [Key|Ks]}; - (_, {Vs, Ks}) -> {Vs, Ks} + {Vs1, Keys} = + reltool_fgraph:foldl(fun + ({Key, + #fg_v{ selected = true}}, + {Vs, Ks}) -> + {reltool_fgraph:del(Key,Vs), + [Key|Ks]}; + (_, {Vs, Ks}) -> + {Vs, Ks} end, {G#graph.vs,[]}, G#graph.vs), Es = delete_edges(G#graph.es, Keys), loop(S, G#graph{ vs = Vs1, es = Es}); @@ -368,20 +395,26 @@ loop(S, G) -> #wx{id = ?move, event = #wxCommand{type=command_button_clicked}} -> loop(S#state{ mouse_act = ?move }, G); - #wx{id = ?q_slider, event = #wxCommand{type=command_slider_updated, commandInt = Q}} -> + #wx{id = ?q_slider, event = #wxCommand{type=command_slider_updated, + commandInt = Q}} -> loop(S, G#graph{ vs = set_charge(Q, G#graph.vs)}); - #wx{id = ?l_slider, event = #wxCommand{type=command_slider_updated, commandInt = L}} -> + #wx{id = ?l_slider, event = #wxCommand{type=command_slider_updated, + commandInt = L}} -> loop(S, G#graph{ es = set_length(L, G#graph.es)}); - #wx{id = ?k_slider, event = #wxCommand{type=command_slider_updated, commandInt = K}} -> + #wx{id = ?k_slider, event = #wxCommand{type=command_slider_updated, + commandInt = K}} -> loop(S, G#graph{ es = set_spring(K, G#graph.es)}); #wx{event=#wxKey{type=key_up, keyCode = 127}} -> % delete {Vs1, Keys} = - reltool_fgraph:foldl(fun({Key, #fg_v{ selected = true}}, {Vs, Ks}) -> - {reltool_fgraph:del(Key,Vs), [Key|Ks]}; - (_, {Vs, Ks}) -> - {Vs, Ks} - end, - {G#graph.vs,[]}, G#graph.vs), + reltool_fgraph:foldl(fun({Key, + #fg_v{ selected = true}}, + {Vs, Ks}) -> + {reltool_fgraph:del(Key,Vs), + [Key|Ks]}; + (_, {Vs, Ks}) -> + {Vs, Ks} + end, + {G#graph.vs,[]}, G#graph.vs), Es = delete_edges(G#graph.es, Keys), loop(S, G#graph{ vs = Vs1, es = Es}); #wx{event=#wxKey{type=key_up}} -> @@ -390,7 +423,11 @@ loop(S, G) -> loop(S, G); %% mouse - #wx{event=#wxMouse{type=left_down, shiftDown=Shift, controlDown=Ctrl, x=X, y=Y}} -> + #wx{event=#wxMouse{type=left_down, + shiftDown=Shift, + controlDown=Ctrl, + x=X, + y=Y}} -> if Shift -> loop(S, mouse_left_down_move(G, {X,Y})); @@ -401,7 +438,11 @@ loop(S, G) -> S#state.mouse_act =:= ?select -> loop(S, mouse_left_down_select(G, {X,Y})) end; - #wx{event=#wxMouse{type=motion, shiftDown=Shift, controlDown=Ctrl, x=X, y=Y}} -> + #wx{event=#wxMouse{type=motion, + shiftDown=Shift, + controlDown=Ctrl, + x=X, + y=Y}} -> if Shift -> loop(S, mouse_motion_move(G, {X,Y})); @@ -412,7 +453,9 @@ loop(S, G) -> S#state.mouse_act =:= ?select -> loop(S, mouse_motion_select(G, {X,Y})) end; - #wx{event=#wxMouse{type=left_up, shiftDown=Shift, controlDown=Ctrl, x=X, y=Y}} -> + #wx{event=#wxMouse{type=left_up, + shiftDown=Shift, + controlDown=Ctrl, x=X, y=Y}} -> if Shift -> loop(S, mouse_left_up_move(G, {X,Y}, Shift)); @@ -424,7 +467,7 @@ loop(S, G) -> loop(S, mouse_left_up_select(G, {X,Y})) end; - #wx{event=#wxMouse{type=right_down,x=_X,y=_Y}} -> + #wx{event=#wxMouse{type=right_down,x=_X,y=_Y}} -> loop(S, G); %% mouse wheel #wx{event=#wxMouse{type=mousewheel, wheelRotation=Rotation}} -> @@ -436,7 +479,7 @@ loop(S, G) -> Rotation < 0 -> wxSlider:setValue(S#state.q_slider, Q + 4), loop(S, G#graph{ vs = set_charge(Q + 4, G#graph.vs) }); - true -> + true -> loop(S, G) end; @@ -448,7 +491,7 @@ loop(S, G) -> redraw(S, G), loop(S, G); #wx{obj=Win,event=#wxMouse{type=enter_window}} -> - wxWindow:setFocus(Win), + wxWindow:setFocus(Win), loop(S, G); %% Graph manipulation @@ -465,9 +508,11 @@ loop(S, G) -> {Req, redraw} -> {SizeX, SizeY} = wxWindow:getSize(S#state.window), - Vs = reltool_fgraph:step(G#graph.vs, G#graph.es, {SizeX/2.0 - 20.0, SizeY/2.0}), + Vs = reltool_fgraph:step(G#graph.vs, + G#graph.es, + {SizeX/2.0 - 20.0, SizeY/2.0}), case S#state.is_frozen of - false -> + false -> Req ! {self(), ok}; true -> ignore @@ -481,7 +526,7 @@ loop(S, G) -> Other -> error_logger:format("~p~p got unexpected message:\n\t~p\n", - [?MODULE, self(), Other]), + [?MODULE, self(), Other]), loop(S, G) end. @@ -494,17 +539,22 @@ mouse_left_down_move(#graph{vs = Vs} = G, {X, Y}) -> false -> G#graph{ offset_state = {X,Y}}; {true, Key} -> - V = #fg_v{ type = Type} = reltool_fgraph:get(Key, Vs), - G#graph{ vs = reltool_fgraph:set(Key, V#fg_v{ type = moving}, Vs), select = {node, Key, Type, X, Y} } + V = #fg_v{ type = Type} = reltool_fgraph:get(Key, Vs), + G#graph{ vs = reltool_fgraph:set(Key, + V#fg_v{ type = moving}, Vs), + select = {node, Key, Type, X, Y} } end. coord_to_key(#graph{vs = Vs, offset = {Xo, Yo}}, {X, Y}) -> Xr = X - Xo, Yr = Y - Yo, - reltool_fgraph:foldl(fun({Key, #fg_v{ p = {Px, Py}}}, _) when abs(Px - Xr) < 10, - abs(Py - Yr) < 10 -> {true, Key}; - (_, Out) -> Out - end, false, Vs). + reltool_fgraph:foldl(fun({Key, #fg_v{ p = {Px, Py}}}, _) + when abs(Px - Xr) < 10, + abs(Py - Yr) < 10 -> + {true, Key}; + (_, Out) -> + Out + end, false, Vs). mouse_left_up_select(G, {_X,_Y}) -> case G#graph.select of @@ -524,7 +574,7 @@ mouse_left_up_select(G, {_X,_Y}) -> _ -> G#graph{ select = none} end. - + mouse_left_up_move(G = #graph{ select = Select, vs = Vs} = G, {X,Y}, Shift) -> case Select of {node, Key, _, X, Y} -> @@ -543,7 +593,7 @@ mouse_left_up_move(G = #graph{ select = Select, vs = Vs} = G, {X,Y}, Shift) -> _ -> G#graph{ select = none, offset_state = false } end. - + mouse_motion_select(G, {X,Y}) -> case G#graph.select of {P0, _P1} -> G#graph{ select = {P0, {X,Y}}}; @@ -557,11 +607,11 @@ mouse_motion_move(G = #graph{ select = {node, Key, _, _, _}, vs = Vs}, {X,Y}) -> G#graph{ vs = reltool_fgraph:set(Key, V2, Vs) }; mouse_motion_move(G, {X,Y}) -> case G#graph.offset_state of - {X1,Y1} -> + {X1,Y1} -> {X0, Y0} = G#graph.offset, G#graph{ offset_state = {X,Y}, offset = {X0 - (X1 - X), Y0 - (Y1 - Y)} }; - _ -> + _ -> G end. @@ -574,9 +624,9 @@ redraw(#state{window=Win}, G) -> wxClientDC:destroy(DC0), ok. -redraw(DC, _Size, G) -> - wx:batch(fun() -> - +redraw(DC, _Size, G) -> + wx:batch(fun() -> + Pen = G#graph.pen, Font = G#graph.font, Brush = G#graph.brush, @@ -587,7 +637,7 @@ redraw(DC, _Size, G) -> wxPen:setWidth(Pen, 1), wxDC:clear(DC), - % draw vertices and edges + % draw vertices and edges wxPen:setColour(Pen, ?color_fg), wxDC:setPen(DC,Pen), @@ -602,7 +652,9 @@ redraw(DC, _Size, G) -> % draw information text wxFont:setWeight(Font,?wxNORMAL), - draw_text(DC, reltool_fgraph:size(G#graph.vs), reltool_fgraph:size(G#graph.es), G#graph.ke), + draw_text(DC, + reltool_fgraph:'size'(G#graph.vs), + reltool_fgraph:'size'(G#graph.es), G#graph.ke), ok end). @@ -612,14 +664,14 @@ draw_select_box(DC, {{X0,Y0}, {X1,Y1}}) -> draw_line(DC, {X1,Y1}, {X0,Y1}, {0,0}), draw_line(DC, {X0,Y0}, {X0,Y1}, {0,0}), ok; -draw_select_box(_DC, _) -> +draw_select_box(_DC, _) -> ok. draw_es(DC, Vs, Es, Po, Pen, Brush) -> reltool_fgraph:foreach(fun ({{K1, K2}, _}) -> - #fg_v{ p = P1} = reltool_fgraph:get(K1, Vs), - #fg_v{ p = P2} = reltool_fgraph:get(K2, Vs), + #fg_v{ p = P1} = reltool_fgraph:'get'(K1, Vs), + #fg_v{ p = P2} = reltool_fgraph:'get'(K2, Vs), draw_arrow(DC, P1, P2, Po, Pen, Brush) end, Es). @@ -650,10 +702,15 @@ draw_arrow(DC, {X0,Y0}, {X1, Y1}, {X, Y}, Pen, Brush) -> wxDC:drawPolygon(DC, Points, []). draw_line(DC, {X0,Y0}, {X1, Y1}, {X, Y}) -> - wxDC:drawLine(DC, {round(X0 + X), round(Y0 + Y)}, {round(X1 + X), round(Y1 + Y)}). - + wxDC:drawLine(DC, + {round(X0 + X), round(Y0 + Y)}, + {round(X1 + X), round(Y1 + Y)}). + draw_vs(DC, Vs, {Xo, Yo}, Pen, Brush) -> - reltool_fgraph:foreach(fun({Key, #fg_v{ p ={X, Y}, color = Color, selected = Sel}}) -> + reltool_fgraph:foreach(fun({Key, + #fg_v{p ={X, Y}, + color = Color, + selected = Sel}}) -> String = s(Key), case Sel of true -> @@ -661,35 +718,49 @@ draw_vs(DC, Vs, {Xo, Yo}, Pen, Brush) -> wxBrush:setColour(Brush, ?color_bg), wxDC:setPen(DC,Pen), wxDC:setBrush(DC, Brush), - SelProps = {round(X-12 + Xo), round(Y-12 + Yo), 24, 24}, - wxDC:drawRoundedRectangle(DC, SelProps, float(?ARC_R)), + SelProps = {round(X-12 + Xo), + round(Y-12 + Yo), + 24, + 24}, + wxDC:drawRoundedRectangle(DC, + SelProps, + float(?ARC_R)), ok; false -> ok end, case Color of - default -> + default -> wxPen:setColour(Pen, ?color_default), - wxBrush:setColour(Brush, ?color_default_bg); - alternate -> - wxPen:setColour(Pen, ?color_alternate), - wxBrush:setColour(Brush, ?color_alternate_bg); + wxBrush:setColour(Brush, + ?color_default_bg); + alternate -> + wxPen:setColour(Pen, + ?color_alternate), + wxBrush:setColour(Brush, + ?color_alternate_bg); {FgColor, BgColor} -> wxPen:setColour(Pen, FgColor), - wxBrush:setColour(Brush, BgColor); + wxBrush:setColour(Brush, BgColor); Color -> wxPen:setColour(Pen, Color), wxBrush:setColour(Brush, Color) end, wxDC:setPen(DC,Pen), wxDC:setBrush(DC, Brush), - NodeProps = {round(X-8 + Xo),round(Y-8 + Yo),17,17}, - wxDC:drawRoundedRectangle(DC, NodeProps, float(?ARC_R)), - wxDC:drawText(DC, String, {round(X + Xo), round(Y + Yo)}), + NodeProps = {round(X-8 + Xo), + round(Y-8 + Yo),17,17}, + wxDC:drawRoundedRectangle(DC, + NodeProps, + float(?ARC_R)), + wxDC:drawText(DC, + String, + {round(X + Xo), + round(Y + Yo)}), ok; (_) -> ok - end, + end, Vs). draw_text(DC, Nvs, Nes, _KE) -> @@ -720,7 +791,7 @@ calc_point({X, Y}, Length, Radians) -> %% %% Convert from an angle in radians to degrees %% radians_to_degrees(Radians) -> %% Radians * 180 / math:pi(). -%% +%% %% %% Convert from an angle in degrees to radians %% degrees_to_radians(Degrees) -> %% Degrees * math:pi() / 180. diff --git a/lib/reltool/src/reltool_mod_win.erl b/lib/reltool/src/reltool_mod_win.erl index c05f73cde8..281d2c8ad4 100644 --- a/lib/reltool/src/reltool_mod_win.erl +++ b/lib/reltool/src/reltool_mod_win.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009. All Rights Reserved. -%% +%% +%% 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% -module(reltool_mod_win). @@ -34,7 +34,7 @@ -include_lib("wx/include/wx.hrl"). -include("reltool.hrl"). --record(state, +-record(state, {parent_pid, xref_pid, rel_pid, @@ -73,7 +73,7 @@ -define(WIN_HEIGHT, 600). -define(CLOSE_ITEM, ?wxID_EXIT). %% Use OS specific version if available --define(ABOUT_ITEM, ?wxID_ABOUT). %% Use OS specific +-define(ABOUT_ITEM, ?wxID_ABOUT). %% Use OS specific -define(CONTENTS_ITEM, 300). -define(SEARCH_ENTRY, 413). -define(GOTO_ENTRY, 414). @@ -87,7 +87,11 @@ %% Client start_link(WxEnv, Xref, RelPid, Common, ModName) -> - proc_lib:start_link(?MODULE, init, [self(), WxEnv, Xref, RelPid, Common, ModName], infinity, []). + proc_lib:start_link(?MODULE, + init, + [self(), WxEnv, Xref, RelPid, Common, ModName], + infinity, + []). raise(Pid) -> reltool_utils:cast(Pid, raise). @@ -127,10 +131,15 @@ loop(#state{xref_pid = Xref, common = C, mod = Mod} = S) -> receive Msg -> %% io:format("~s~p -> ~p\n", [S#state.name, self(), Msg]), - case Msg of + case Msg of {system, From, SysMsg} -> Dbg = C#common.sys_debug, - sys:handle_system_msg(SysMsg, From, S#state.parent_pid, ?MODULE, Dbg, S); + sys:handle_system_msg(SysMsg, + From, + S#state.parent_pid, + ?MODULE, + Dbg, + S); {cast, _From, raise} -> wxFrame:raise(S#state.frame), wxFrame:setFocus(S#state.frame), @@ -169,7 +178,7 @@ loop(#state{xref_pid = Xref, common = C, mod = Mod} = S) -> create_window(#state{mod = Mod, name = ModStr} = S) -> Title = atom_to_list(?APPLICATION) ++ " - " ++ - atom_to_list(Mod#mod.app_name) ++ " - " ++ + atom_to_list(Mod#mod.app_name) ++ " - " ++ ModStr ++ ".erl", Frame = wxFrame:new(wx:null(), ?wxID_ANY, Title, []), %% wxFrame:setSize(Frame, {?WIN_WIDTH, ?WIN_HEIGHT}), @@ -177,7 +186,7 @@ create_window(#state{mod = Mod, name = ModStr} = S) -> StatusBar = wxFrame:createStatusBar(Frame,[]), Book = wxNotebook:new(Panel, ?wxID_ANY, []), - + S2 = S#state{frame = Frame, panel = Panel, book = Book, @@ -204,11 +213,17 @@ create_deps_page(S) -> Panel = wxPanel:new(S#state.book, []), Main = wxBoxSizer:new(?wxHORIZONTAL), - UsedByCtrl = create_mods_list_ctrl(Panel, Main, "Modules used by others", " and their applications"), + UsedByCtrl = create_mods_list_ctrl(Panel, + Main, + "Modules used by others", + " and their applications"), wxSizer:add(Main, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]), [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]), - UsesCtrl = create_mods_list_ctrl(Panel, Main, "Used modules", " and their applications"), + UsesCtrl = create_mods_list_ctrl(Panel, + Main, + "Used modules", + " and their applications"), S2 = S#state{deps_used_by_ctrl = UsedByCtrl, deps_uses_ctrl = UsesCtrl}, redraw_mods(S2), @@ -242,8 +257,10 @@ create_mods_list_ctrl(Panel, Sizer, ModText, AppText) -> %% wxListCtrl:setColumnWidth(ListCtrl, ?MODS_APP_COL, ?MODS_APP_COL_WIDTH), wxListItem:destroy(ListItem), - wxEvtHandler:connect(ListCtrl, size, [{skip, true}, {userData, mods_list_ctrl}]), - wxListCtrl:connect(ListCtrl, command_list_item_activated, [{userData, open_app}]), + wxEvtHandler:connect(ListCtrl, size, + [{skip, true}, {userData, mods_list_ctrl}]), + wxListCtrl:connect(ListCtrl, command_list_item_activated, + [{userData, open_app}]), wxWindow:connect(ListCtrl, enter_window), wxSizer:add(Sizer, ListCtrl, @@ -252,7 +269,8 @@ create_mods_list_ctrl(Panel, Sizer, ModText, AppText) -> {proportion, 1}]), ListCtrl. -create_code_page(#state{book = Book, code_pages = Pages, name = ModStr} = S, PageName) -> +create_code_page(#state{book = Book, code_pages = Pages, name = ModStr} = S, + PageName) -> case find_page(S, PageName) of not_found -> Page = do_create_code_page(S, PageName), @@ -260,7 +278,7 @@ create_code_page(#state{book = Book, code_pages = Pages, name = ModStr} = S, Pag Pos = length(Pages2), wxNotebook:setSelection(Book, Pos), case find_page(S, ?INITIAL_CODE_PAGE_NAME) of - not_found -> + not_found -> ignore; {found, _, CodePos} -> %% Rename initial code page @@ -288,33 +306,37 @@ find_page([], _PageName, _Pos) -> do_create_code_page(#state{xref_pid = Xref, mod = M} = S, PageName) -> Panel = wxPanel:new(S#state.book, []), Editor = create_editor(Panel), - ToolTip = "Double click on a function call to search the function definition.", + ToolTip = "Double click on a function call to " + "search the function definition.", wxBitmapButton:setToolTip(Editor, ToolTip), {Objs, Data, SearchSz} = create_search_area(Panel), {ok, App} = reltool_server:get_app(Xref, M#mod.app_name), - ErlBin = + ErlBin = case App#app.is_escript of true -> find_escript_bin(App, M); false -> find_regular_bin(App, M) end, - + load_code(Editor, ErlBin), - + Sizer = wxBoxSizer:new(?wxVERTICAL), wxSizer:add(Sizer, Editor, [{flag, ?wxEXPAND}, {proportion, 1}]), wxSizer:add(Sizer, SearchSz, [{flag, ?wxEXPAND}]), wxPanel:setSizer(Panel, Sizer), wxNotebook:addPage(S#state.book, Panel, PageName, []), - #code_page{name = PageName, editor = Editor, find_objs = Objs, find_data = Data}. + #code_page{name = PageName, + editor = Editor, + find_objs = Objs, + find_data = Data}. find_regular_bin(App, Mod) -> ActiveDir = App#app.active_dir, SrcDir = filename:join([ActiveDir, "src"]), ModStr = atom_to_list(Mod#mod.name), - Base = ModStr ++ ".erl", - Find = fun(F, _Acc) -> file:read_file(F) end, - case filelib:fold_files(SrcDir, Base, true, Find, {error, enoent}) of + Base = "^" ++ ModStr ++ "\\.erl$", + Find = fun(F, _Acc) -> throw(file:read_file(F)) end, + case catch filelib:fold_files(SrcDir, Base, true, Find, {error, enoent}) of {ok, Bin} -> Bin; {error, enoent} -> @@ -322,9 +344,11 @@ find_regular_bin(App, Mod) -> BeamFile = filename:join([ActiveDir, "ebin", ModStr ++ ".beam"]), case beam_lib:chunks(BeamFile, [abstract_code]) of {ok,{_,[{abstract_code,{_,AC}}]}} -> - list_to_binary(erl_prettypr:format(erl_syntax:form_list(AC))); + IoList = erl_prettypr:format(erl_syntax:form_list(AC)), + list_to_binary(IoList); _ -> - list_to_binary(["%% Bad luck, cannot find any debug info in the file \"", BeamFile]) + list_to_binary(["%% Bad luck, cannot find any " + "debug info in the file \"", BeamFile]) end end. @@ -340,10 +364,17 @@ find_escript_bin(#app{active_dir = ActiveDir}, Mod) -> [_] -> Bin = GetBin(), case beam_lib:version(Bin) of - {ok,{M, _}} when M =:= ModName; FullName =:= "." -> - case beam_lib:chunks(Bin, [abstract_code]) of + {ok,{M, _}} when M =:= ModName; + FullName =:= "." -> + case beam_lib:chunks(Bin, + [abstract_code]) of {ok,{_,[{abstract_code,{_,AC}}]}} -> - {obj, list_to_binary(erl_prettypr:format(erl_syntax:form_list(AC)))}; + Form = + erl_syntax:form_list(AC), + IoList = + erl_prettypr:format(Form), + {obj, + list_to_binary(IoList)}; _ -> Acc end; @@ -363,10 +394,14 @@ find_escript_bin(#app{active_dir = ActiveDir}, Mod) -> {fun(FullName, _GetInfo, GetBin, Acc) -> io:format("", []), case filename:split(FullName) of - [_AppName, "ebin", F] when F =:= ObjFile, Acc =:= NotFound -> - case beam_lib:chunks(GetBin(), [abstract_code]) of + [_AppName, "ebin", F] + when F =:= ObjFile, Acc =:= NotFound -> + case beam_lib:chunks(GetBin(), + [abstract_code]) of {ok,{_,[{abstract_code,{_,AC}}]}} -> - {obj, list_to_binary(erl_prettypr:format(erl_syntax:form_list(AC)))}; + Form = erl_syntax:form_list(AC), + IoList = erl_prettypr:format(Form), + {obj, list_to_binary(IoList)}; _ -> Acc end; @@ -379,17 +414,19 @@ find_escript_bin(#app{active_dir = ActiveDir}, Mod) -> filename:dirname(ActiveDir)} end, try - case escript:foldl(Fun, NotFound, Escript) of + case reltool_utils:escript_foldl(Fun, NotFound, Escript) of {ok, {text, Bin}} -> Bin; {ok, {obj, Bin}} -> Bin; _ -> - list_to_binary(["%% Bad luck, cannot find the code in the escript ", Escript, "."]) + list_to_binary(["%% Bad luck, cannot find the " + "code in the escript ", Escript, "."]) end - catch + catch throw:Reason when is_list(Reason) -> - list_to_binary(["%% Bad luck, cannot find the code in the escript ", Escript, ": ", Reason]) + list_to_binary(["%% Bad luck, cannot find the code " + "in the escript ", Escript, ": ", Reason]) end. create_config_page(S) -> @@ -400,13 +437,16 @@ create_config_page(S) -> handle_event(#state{xref_pid = Xref} = S, Wx) -> %% io:format("wx: ~p\n", [Wx]), case Wx of - #wx{obj= ListCtrl, userData = mods_list_ctrl, event = #wxSize{type = size, size = {W, _H}}} -> + #wx{obj= ListCtrl, + userData = mods_list_ctrl, + event = #wxSize{type = size, size = {W, _H}}} -> wxListCtrl:setColumnWidth(ListCtrl, ?MODS_MOD_COL, (2 * W) div 3), wxListCtrl:setColumnWidth(ListCtrl, ?MODS_APP_COL, W div 3), S; #wx{userData = open_app, obj = ListCtrl, - event = #wxList{type = command_list_item_activated, itemIndex = Pos}} -> + event = #wxList{type = command_list_item_activated, + itemIndex = Pos}} -> ModStr = wxListCtrl:getItemText(ListCtrl, Pos), ModName = list_to_atom(ModStr), {ok, Mod} = reltool_server:get_mod(Xref, ModName), @@ -431,13 +471,15 @@ handle_event(#state{xref_pid = Xref} = S, Wx) -> Page = lists:nth(N, S#state.code_pages), S#state{active_page = Page} end; - #wx{event = #wxCommand{type = command_button_clicked}, userData = history_back} -> + #wx{event = #wxCommand{type = command_button_clicked}, + userData = history_back} -> goto_back(S); #wx{obj = ObjRef, event = #wxMouse{type = enter_window}} -> wxWindow:setFocus(ObjRef), S; _ -> - error_logger:format("~p~p got unexpected mod event from wx:\n\t~p\n", + error_logger:format("~p~p got unexpected mod event from " + "wx:\n\t~p\n", [?MODULE, self(), Wx]), S end. @@ -450,7 +492,7 @@ redraw_mods(#state{xref_pid = Xref, uses_mods = UsesModNames, used_by_mods = UsedByModNames}, status_bar = Bar}) -> - InclStatus = + InclStatus = case IsIncl of true when IsPre =:= true -> "Whitelist - "; true -> "Derived - "; @@ -458,8 +500,10 @@ redraw_mods(#state{xref_pid = Xref, undefined -> "Source - " end, Status = lists:concat([InclStatus, - " uses ", length(UsesModNames), " modules and ", - " is used by ", length(UsedByModNames), " modules."]), + " uses ", length(UsesModNames), + " modules and ", + " is used by ", length(UsedByModNames), + " modules."]), wxStatusBar:setStatusText(Bar, Status), UsesMods = [select_image(Xref, M) || M <- UsesModNames], UsedByMods = [select_image(Xref, M) || M <- UsedByModNames], @@ -470,7 +514,7 @@ select_image(Xref, ModName) -> {ok, M} = reltool_server:get_mod(Xref, ModName), Image = case M#mod.is_included of - _ when M#mod.app_name =:= ?MISSING_APP -> ?ERR_IMAGE; + _ when M#mod.app_name =:= ?MISSING_APP_NAME -> ?ERR_IMAGE; true -> ?TICK_IMAGE; false -> ?WARN_IMAGE; undefined -> ?ERR_IMAGE @@ -483,9 +527,11 @@ redraw_mods(ListCtrl, ImageMods) -> wxListCtrl:deleteAllItems(ListCtrl), Add = fun({ImageId, AppName, #mod{name = ModName}}, Row) -> - wxListCtrl:insertItem(ListCtrl, Row, ""), - if (Row rem 2) =:= 0 -> - wxListCtrl:setItemBackgroundColour(ListCtrl, Row, {240,240,255}); + wxListCtrl:insertItem(ListCtrl, Row, ""), + if (Row rem 2) =:= 0 -> + wxListCtrl:setItemBackgroundColour(ListCtrl, + Row, + {240,240,255}); true -> ignore end, @@ -515,16 +561,16 @@ goto_line(#state{active_page = P} = S, LineNo) when is_integer(LineNo) -> wxStyledTextCtrl:setSelection(Editor, Left, Right), S; goto_line(#state{active_page = P} =S, Str) when is_list(Str) -> - try + try LineNo = list_to_integer(Str), CurrentPos = wxStyledTextCtrl:getCurrentPos(P#code_page.editor), S2 = add_pos_to_history(S, CurrentPos), goto_line(S2, LineNo - 1) - catch + catch _:_ -> wxStatusBar:setStatusText(S#state.status_bar, "Not a line number"), S - end. + end. find_string(S, Str) -> find_string(S, Str, 0). @@ -535,19 +581,20 @@ find_regexp_forward(S, Str) -> wxTextCtrl:setValue(TextCtrl, Str), S2. -find_string(#state{active_page = #code_page{editor = Editor, - find_objs = #find_objs{radio={NextO,_,CaseO}}, - find_data = #find_data{found = Found} = Data} = P} = S, +find_string(#state{active_page = + #code_page{editor = Editor, + find_objs = #find_objs{radio={NextO,_,CaseO}}, + find_data = #find_data{found = Found} = Data} = P} = S, Str, Flag) -> wxStyledTextCtrl:hideSelection(Editor, true), Dir = wxRadioButton:getValue(NextO) xor wx_misc:getKeyState(?WXK_SHIFT), Case = wxCheckBox:getValue(CaseO), Pos = - if + if Found, Dir -> %% Forward Continuation wxStyledTextCtrl:getAnchor(Editor); - Found -> %% Backward Continuation + Found -> %% Backward Continuation wxStyledTextCtrl:getCurrentPos(Editor); Dir -> %% Forward wrap 0; @@ -556,18 +603,18 @@ find_string(#state{active_page = #code_page{editor = Editor, end, wxStyledTextCtrl:gotoPos(Editor,Pos), wxStyledTextCtrl:searchAnchor(Editor), - Flag2 = + Flag2 = if Case -> Flag bor ?wxSTC_FIND_MATCHCASE; true -> Flag end, - Res = - if + Res = + if Dir -> wxStyledTextCtrl:searchNext(Editor, Flag2, Str); true -> wxStyledTextCtrl:searchPrev(Editor, Flag2, Str) end, - Found2 = + Found2 = case Res >= 0 of - true -> + true -> wxStyledTextCtrl:hideSelection(Editor, false), %% io:format("Found ~p ~n",[Res]), LineNo = wxStyledTextCtrl:lineFromPosition(Editor,Res), @@ -576,11 +623,15 @@ find_string(#state{active_page = #code_page{editor = Editor, true; false -> wxStatusBar:setStatusText(S#state.status_bar, - "Not found (Hit Enter to wrap search)"), + "Not found (Hit Enter to " + "wrap search)"), false - end, + end, P2 = P#code_page{find_data = Data#find_data{found = Found2}}, - Pages = lists:keystore(P#code_page.name, #code_page.name, S#state.code_pages, P2), + Pages = lists:keystore(P#code_page.name, + #code_page.name, + S#state.code_pages, + P2), S#state{active_page = P2, code_pages = Pages}. goto_function(S, Editor) -> @@ -589,14 +640,14 @@ goto_function(S, Editor) -> Left = wxStyledTextCtrl:wordStartPosition(Editor, CurrentPos, true), Right = wxStyledTextCtrl:wordEndPosition(Editor, CurrentPos, true), ColonPos = Left - 1, - Left2 = + Left2 = case wxStyledTextCtrl:getCharAt(Editor, ColonPos) of $: -> wxStyledTextCtrl:wordStartPosition(Editor, ColonPos, true); _ -> Left end, - Right2 = + Right2 = case wxStyledTextCtrl:getCharAt(Editor, Right) of $: -> wxStyledTextCtrl:wordEndPosition(Editor, Right + 1, true); @@ -623,33 +674,41 @@ do_goto_function(#state{active_page = P} = S, [FunName]) -> find_regexp_forward(S, "^" ++ FunName ++ "("); do_goto_function(S, [ModStr, FunStr]) -> case reltool_server:get_mod(S#state.xref_pid, list_to_atom(ModStr)) of - {ok, Mod} when Mod#mod.app_name =/= ?MISSING_APP -> + {ok, Mod} when Mod#mod.app_name =/= ?MISSING_APP_NAME -> S2 = create_code_page(S#state{mod = Mod}, ModStr), find_regexp_forward(S2, "^" ++ FunStr ++ "("); {ok, _} -> - wxStatusBar:setStatusText(S#state.status_bar, "No such module: " ++ ModStr), + wxStatusBar:setStatusText(S#state.status_bar, + "No such module: " ++ ModStr), S end. -goto_back(#state{active_page = #code_page{editor = Editor, find_data = Data} = Page, +goto_back(#state{active_page = + #code_page{editor = Editor, find_data = Data} = Page, code_pages = Pages} = S) -> case Data#find_data.history of [PrevPos | History] -> LineNo = wxStyledTextCtrl:lineFromPosition(Editor, PrevPos), Data2 = Data#find_data{history = History}, Page2 = Page#code_page{find_data = Data2}, - Pages2 = lists:keystore(Page2#code_page.name, #code_page.name, Pages, Page2), - goto_line(S#state{active_page = Page2, code_pages = Pages2}, LineNo); + Pages2 = lists:keystore(Page2#code_page.name, + #code_page.name, + Pages, + Page2), + goto_line(S#state{active_page = Page2, code_pages = Pages2}, + LineNo); [] -> wxStatusBar:setStatusText(S#state.status_bar, "No history"), S end. -add_pos_to_history(#state{active_page = Page, code_pages = Pages} = S, CurrentPos) -> +add_pos_to_history(#state{active_page = Page, code_pages = Pages} = S, + CurrentPos) -> Data = Page#code_page.find_data, Data2 = Data#find_data{history = [CurrentPos | Data#find_data.history]}, Page2 = Page#code_page{find_data = Data2}, - Pages2 = lists:keystore(Page2#code_page.name, #code_page.name, Pages, Page2), + Pages2 = + lists:keystore(Page2#code_page.name, #code_page.name, Pages, Page2), S#state{active_page = Page2, code_pages = Pages2}. create_editor(Parent) -> @@ -690,19 +749,26 @@ create_editor(Parent) -> %% Margins Markers %% Breakpoint Should be a pixmap? - wxStyledTextCtrl:markerDefine(Ed, 0, ?wxSTC_MARK_CIRCLE, [{foreground, {170,20,20}}]), - wxStyledTextCtrl:markerDefine(Ed, 0, ?wxSTC_MARK_CIRCLE, [{background, {200,120,120}}]), - %% Disabled Breakpoint - wxStyledTextCtrl:markerDefine(Ed, 1, ?wxSTC_MARK_CIRCLE, [{foreground, {20,20,170}}]), - wxStyledTextCtrl:markerDefine(Ed, 1, ?wxSTC_MARK_CIRCLE, [{background, {120,120,200}}]), - + wxStyledTextCtrl:markerDefine(Ed, 0, ?wxSTC_MARK_CIRCLE, + [{foreground, {170,20,20}}]), + wxStyledTextCtrl:markerDefine(Ed, 0, ?wxSTC_MARK_CIRCLE, + [{background, {200,120,120}}]), + %% Disabled Breakpoint + wxStyledTextCtrl:markerDefine(Ed, 1, ?wxSTC_MARK_CIRCLE, + [{foreground, {20,20,170}}]), + wxStyledTextCtrl:markerDefine(Ed, 1, ?wxSTC_MARK_CIRCLE, + [{background, {120,120,200}}]), + %% Current Line - wxStyledTextCtrl:markerDefine(Ed, 2, ?wxSTC_MARK_ARROW, [{foreground, {20,170,20}}]), - wxStyledTextCtrl:markerDefine(Ed, 2, ?wxSTC_MARK_ARROW, [{background, {200,255,200}}]), - wxStyledTextCtrl:markerDefine(Ed, 3, ?wxSTC_MARK_BACKGROUND, [{background, {200,255,200}}]), + wxStyledTextCtrl:markerDefine(Ed, 2, ?wxSTC_MARK_ARROW, + [{foreground, {20,170,20}}]), + wxStyledTextCtrl:markerDefine(Ed, 2, ?wxSTC_MARK_ARROW, + [{background, {200,255,200}}]), + wxStyledTextCtrl:markerDefine(Ed, 3, ?wxSTC_MARK_BACKGROUND, + [{background, {200,255,200}}]), %% Scrolling - Policy = ?wxSTC_CARET_SLOP bor ?wxSTC_CARET_JUMPS bor ?wxSTC_CARET_EVEN, + Policy = ?wxSTC_CARET_SLOP bor ?wxSTC_CARET_JUMPS bor ?wxSTC_CARET_EVEN, wxStyledTextCtrl:setYCaretPolicy(Ed, Policy, 3), wxStyledTextCtrl:setVisiblePolicy(Ed, Policy, 3), @@ -714,9 +780,9 @@ create_editor(Parent) -> create_search_area(Parent) -> Sizer = wxBoxSizer:new(?wxHORIZONTAL), - wxSizer:add(Sizer, wxStaticText:new(Parent, ?wxID_ANY, "Find:"), + wxSizer:add(Sizer, wxStaticText:new(Parent, ?wxID_ANY, "Find:"), [{flag,?wxALIGN_CENTER_VERTICAL}]), - TC1 = wxTextCtrl:new(Parent, ?SEARCH_ENTRY, [{style, ?wxTE_PROCESS_ENTER}]), + TC1 = wxTextCtrl:new(Parent, ?SEARCH_ENTRY, [{style, ?wxTE_PROCESS_ENTER}]), wxSizer:add(Sizer, TC1, [{proportion,3}, {flag, ?wxEXPAND}]), Nbtn = wxRadioButton:new(Parent, ?wxID_ANY, "Next"), wxRadioButton:setValue(Nbtn, true), @@ -726,14 +792,15 @@ create_search_area(Parent) -> Cbtn = wxCheckBox:new(Parent, ?wxID_ANY, "Match Case"), wxSizer:add(Sizer,Cbtn,[{flag,?wxALIGN_CENTER_VERTICAL}]), wxSizer:add(Sizer, 15,15, [{proportion,1}, {flag, ?wxEXPAND}]), - wxSizer:add(Sizer, wxStaticText:new(Parent, ?wxID_ANY, "Goto Line:"), + wxSizer:add(Sizer, wxStaticText:new(Parent, ?wxID_ANY, "Goto Line:"), [{flag,?wxALIGN_CENTER_VERTICAL}]), - TC2 = wxTextCtrl:new(Parent, ?GOTO_ENTRY, [{style, ?wxTE_PROCESS_ENTER}]), + TC2 = wxTextCtrl:new(Parent, ?GOTO_ENTRY, [{style, ?wxTE_PROCESS_ENTER}]), wxSizer:add(Sizer, TC2, [{proportion,0}, {flag, ?wxEXPAND}]), Button = wxButton:new(Parent, ?wxID_ANY, [{label, "Back"}]), wxSizer:add(Sizer, Button, []), - wxEvtHandler:connect(Button, command_button_clicked, [{userData, history_back}]), + wxEvtHandler:connect(Button, command_button_clicked, + [{userData, history_back}]), %% wxTextCtrl:connect(TC1, command_text_updated), wxTextCtrl:connect(TC1, command_text_enter), %% wxTextCtrl:connect(TC1, kill_focus), @@ -748,7 +815,9 @@ load_code(Ed, Code) when is_binary(Code) -> wxStyledTextCtrl:setTextRaw(Ed, <<Code/binary, 0:8>>), Lines = wxStyledTextCtrl:getLineCount(Ed), Sz = trunc(math:log10(Lines))+1, - LW = wxStyledTextCtrl:textWidth(Ed, ?wxSTC_STYLE_LINENUMBER, lists:duplicate(Sz, $9)), + LW = wxStyledTextCtrl:textWidth(Ed, + ?wxSTC_STYLE_LINENUMBER, + lists:duplicate(Sz, $9)), %%io:format("~p ~p ~p~n", [Lines, Sz, LW]), wxStyledTextCtrl:setMarginWidth(Ed, 0, LW+5), wxStyledTextCtrl:setReadOnly(Ed, true), diff --git a/lib/reltool/src/reltool_server.erl b/lib/reltool/src/reltool_server.erl index 8d4530131f..039ad56aa8 100644 --- a/lib/reltool/src/reltool_server.erl +++ b/lib/reltool/src/reltool_server.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009. All Rights Reserved. -%% +%% +%% 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% -module(reltool_server). @@ -44,7 +44,7 @@ -include("reltool.hrl"). --record(state, +-record(state, {options, parent_pid, common, @@ -60,16 +60,20 @@ start_link() -> start_link([]). start_link(Options) -> - proc_lib:start_link(?MODULE, init, [[{parent, self()} | Options]], infinity, []). + proc_lib:start_link(?MODULE, + init, + [[{parent, self()} | Options]], + infinity, + []). -get_config(Pid, InclDefaults, InclDerivates) -> - reltool_utils:call(Pid, {get_config, InclDefaults, InclDerivates}). +get_config(Pid, InclDef, InclDeriv) -> + reltool_utils:call(Pid, {get_config, InclDef, InclDeriv}). load_config(Pid, FilenameOrConfig) -> reltool_utils:call(Pid, {load_config, FilenameOrConfig}). -save_config(Pid, Filename, InclDefaults, InclDerivates) -> - reltool_utils:call(Pid, {save_config, Filename, InclDefaults, InclDerivates}). +save_config(Pid, Filename, InclDef, InclDeriv) -> + reltool_utils:call(Pid, {save_config, Filename, InclDef, InclDeriv}). reset_config(Pid) -> reltool_utils:call(Pid, reset_config). @@ -128,18 +132,20 @@ init(Options) -> end. do_init(Options) -> - case parse_options(Options) of - {#state{parent_pid = ParentPid, common = C, sys = Sys} = S, Status} -> - %% process_flag(trap_exit, (S#state.common)#common.trap_exit), - proc_lib:init_ack(ParentPid, {ok, self(), C, Sys#sys{apps = undefined}}), - {S2, Status2} = refresh(S, true, Status), - {S3, Status3} = analyse(S2#state{old_sys = S2#state.sys}, Status2), - case Status3 of - {ok, _Warnings} -> - loop(S3#state{status = Status3, old_status = {ok, []}}); - {error, Reason} -> - exit(Reason) - end + {S, Status} = parse_options(Options), + #state{parent_pid = ParentPid, common = C, sys = Sys} = S, + + %% process_flag(trap_exit, (S#state.common)#common.trap_exit), + proc_lib:init_ack(ParentPid, + {ok, self(), C, Sys#sys{apps = undefined}}), + {S2, Status2} = refresh(S, true, Status), + {S3, Status3} = + analyse(S2#state{old_sys = S2#state.sys}, Status2), + case Status3 of + {ok, _Warnings} -> % BUGBUG: handle warnings + loop(S3#state{status = Status3, old_status = {ok, []}}); + {error, Reason} -> + exit(Reason) end. parse_options(Opts) -> @@ -156,15 +162,28 @@ parse_options(Opts) -> rels = reltool_utils:default_rels(), emu_name = ?DEFAULT_EMU_NAME, profile = ?DEFAULT_PROFILE, - incl_sys_filters = reltool_utils:decode_regexps(incl_sys_filters, ?DEFAULT_INCL_SYS_FILTERS, []), - excl_sys_filters = reltool_utils:decode_regexps(excl_sys_filters, ?DEFAULT_EXCL_SYS_FILTERS, []), - incl_app_filters = reltool_utils:decode_regexps(incl_app_filters, ?DEFAULT_INCL_APP_FILTERS, []), - excl_app_filters = reltool_utils:decode_regexps(excl_app_filters, ?DEFAULT_EXCL_APP_FILTERS, []), + incl_sys_filters = dec_re(incl_sys_filters, + ?DEFAULT_INCL_SYS_FILTERS, + []), + excl_sys_filters = dec_re(excl_sys_filters, + ?DEFAULT_EXCL_SYS_FILTERS, + []), + incl_app_filters = dec_re(incl_app_filters, + ?DEFAULT_INCL_APP_FILTERS, + []), + excl_app_filters = dec_re(excl_app_filters, + ?DEFAULT_EXCL_APP_FILTERS, + []), relocatable = ?DEFAULT_RELOCATABLE, - app_type = ?DEFAULT_APP_TYPE, + rel_app_type = ?DEFAULT_REL_APP_TYPE, + embedded_app_type = ?DEFAULT_EMBEDDED_APP_TYPE, app_file = ?DEFAULT_APP_FILE, - incl_archive_filters = reltool_utils:decode_regexps(incl_archive_filters, ?DEFAULT_INCL_ARCHIVE_FILTERS, []), - excl_archive_filters = reltool_utils:decode_regexps(excl_archive_filters, ?DEFAULT_EXCL_ARCHIVE_FILTERS, []), + incl_archive_filters = dec_re(incl_archive_filters, + ?DEFAULT_INCL_ARCHIVE_FILTERS, + []), + excl_archive_filters = dec_re(excl_archive_filters, + ?DEFAULT_EXCL_ARCHIVE_FILTERS, + []), archive_opts = ?DEFAULT_ARCHIVE_OPTS, debug_info = ?DEFAULT_DEBUG_INFO}, C2 = #common{sys_debug = [], @@ -176,6 +195,9 @@ parse_options(Opts) -> S = #state{options = Opts}, parse_options(Opts, S, C2, Sys, {ok, []}). +dec_re(Key, Regexps, Old) -> + reltool_utils:decode_regexps(Key, Regexps, Old). + parse_options([{Key, Val} | KeyVals], S, C, Sys, Status) -> case Key of parent -> @@ -194,30 +216,38 @@ parse_options([{Key, Val} | KeyVals], S, C, Sys, Status) -> parse_options(KeyVals, S, C, Sys2, Status2); _ -> Text = lists:flatten(io_lib:format("~p", [{Key, Val}])), - Status2 = reltool_utils:return_first_error(Status, "Illegal option: " ++ Text), + Status2 = + reltool_utils:return_first_error(Status, + "Illegal option: " ++ Text), parse_options(KeyVals, S, C, Sys, Status2) end; parse_options([], S, C, Sys, Status) -> {S#state{common = C, sys = Sys}, Status}; parse_options(KeyVals, S, C, Sys, Status) -> Text = lists:flatten(io_lib:format("~p", [KeyVals])), - Status2 = reltool_utils:return_first_error(Status, "Illegal options: " ++ Text), + Status2 = reltool_utils:return_first_error(Status, + "Illegal options: " ++ Text), {S#state{common = C, sys = Sys}, Status2}. loop(#state{common = C, sys = Sys} = S) -> receive {system, From, Msg} -> - sys:handle_system_msg(Msg, From, S#state.parent_pid, ?MODULE, C#common.sys_debug, S); - {call, ReplyTo, Ref, {get_config, InclDefaults, InclDerivates}} -> - Reply = do_get_config(S, InclDefaults, InclDerivates), + sys:handle_system_msg(Msg, + From, + S#state.parent_pid, + ?MODULE, + C#common.sys_debug, + S); + {call, ReplyTo, Ref, {get_config, InclDef, InclDeriv}} -> + Reply = do_get_config(S, InclDef, InclDeriv), reltool_utils:reply(ReplyTo, Ref, Reply), ?MODULE:loop(S); {call, ReplyTo, Ref, {load_config, SysConfig}} -> {S2, Reply} = do_load_config(S, SysConfig), reltool_utils:reply(ReplyTo, Ref, Reply), ?MODULE:loop(S2); - {call, ReplyTo, Ref, {save_config, Filename, InclDefaults, InclDerivates}} -> - Reply = do_save_config(S, Filename, InclDefaults, InclDerivates), + {call, ReplyTo, Ref, {save_config, Filename, InclDef, InclDeriv}} -> + Reply = do_save_config(S, Filename, InclDef, InclDeriv), reltool_utils:reply(ReplyTo, Ref, Reply), ?MODULE:loop(S); {call, ReplyTo, Ref, reset_config} -> @@ -225,43 +255,44 @@ loop(#state{common = C, sys = Sys} = S) -> S3 = shrink_sys(S2), {S4, Status2} = refresh(S3, true, Status), {S5, Status3} = analyse(S4#state{old_sys = S4#state.sys}, Status2), - S6 = + S6 = case Status3 of {ok, _Warnings} -> S5#state{status = Status3, old_status = S#state.status}; {error, _} -> + %% Keep old state S end, reltool_utils:reply(ReplyTo, Ref, Status3), ?MODULE:loop(S6); {call, ReplyTo, Ref, undo_config} -> reltool_utils:reply(ReplyTo, Ref, ok), - S2 = S#state{sys = S#state.old_sys, + S2 = S#state{sys = S#state.old_sys, old_sys = S#state.sys, status = S#state.old_status, old_status = S#state.status}, ?MODULE:loop(S2); {call, ReplyTo, Ref, {get_rel, RelName}} -> Sys = S#state.sys, - Reply = + Reply = case lists:keysearch(RelName, #rel.name, Sys#sys.rels) of {value, Rel} -> - {ok, reltool_target:gen_rel(Rel, Sys)}; + reltool_target:gen_rel(Rel, Sys); false -> - {error, "No such release"} + {error, "No such release: " ++ RelName} end, reltool_utils:reply(ReplyTo, Ref, Reply), ?MODULE:loop(S); {call, ReplyTo, Ref, {get_script, RelName}} -> Sys = S#state.sys, - Reply = + Reply = case lists:keysearch(RelName, #rel.name, Sys#sys.rels) of {value, Rel} -> PathFlag = true, - Variables = [], - reltool_target:gen_script(Rel, Sys, PathFlag, Variables); + Vars = [], + reltool_target:gen_script(Rel, Sys, PathFlag, Vars); false -> - {error, "No such release"} + {error, "No such release: " ++ RelName} end, reltool_utils:reply(ReplyTo, Ref, Reply), ?MODULE:loop(S); @@ -271,17 +302,18 @@ loop(#state{common = C, sys = Sys} = S) -> [M] -> {ok, M}; [] -> - {ok, missing_mod(ModName, ?MISSING_APP)} + {ok, missing_mod(ModName, ?MISSING_APP_NAME)} end, reltool_utils:reply(ReplyTo, Ref, Reply), ?MODULE:loop(S); {call, ReplyTo, Ref, {get_app, AppName}} when is_atom(AppName) -> - Reply = + Reply = case lists:keysearch(AppName, #app.name, Sys#sys.apps) of {value, App} -> {ok, App}; false -> - {error, enoent} + {error, "No such application: " ++ + atom_to_list(AppName)} end, reltool_utils:reply(ReplyTo, Ref, Reply), ?MODULE:loop(S); @@ -296,21 +328,22 @@ loop(#state{common = C, sys = Sys} = S) -> reltool_utils:reply(ReplyTo, Ref, {ok, App2, Warnings}), ?MODULE:loop(S3); {error, Reason} -> + %% Keep old state reltool_utils:reply(ReplyTo, Ref, {error, Reason}), ?MODULE:loop(S) end; {call, ReplyTo, Ref, {get_apps, Kind}} -> AppNames = case Kind of - whitelist -> + whitelist -> [A || A <- Sys#sys.apps, A#app.is_pre_included =:= true]; - blacklist -> + blacklist -> [A || A <- Sys#sys.apps, A#app.is_pre_included =:= false]; - source -> + source -> [A || A <- Sys#sys.apps, A#app.is_included =/= true, @@ -324,9 +357,10 @@ loop(#state{common = C, sys = Sys} = S) -> reltool_utils:reply(ReplyTo, Ref, {ok, AppNames}), ?MODULE:loop(S); {call, ReplyTo, Ref, {set_apps, Apps}} -> - {S2, Status} = lists:foldl(fun(A, {X, Y}) -> do_set_app(X, A, Y) end, - {S, {ok, []}}, - Apps), + {S2, Status} = + lists:foldl(fun(A, {X, Y}) -> do_set_app(X, A, Y) end, + {S, {ok, []}}, + Apps), {S3, Status2} = analyse(S2, Status), reltool_utils:reply(ReplyTo, Ref, Status2), ?MODULE:loop(S3); @@ -335,26 +369,30 @@ loop(#state{common = C, sys = Sys} = S) -> ?MODULE:loop(S); {call, ReplyTo, Ref, {set_sys, Sys2}} -> S2 = S#state{sys = Sys2#sys{apps = Sys#sys.apps}}, - Force = + Force = (Sys2#sys.root_dir =/= Sys#sys.root_dir) orelse (Sys2#sys.lib_dirs =/= Sys#sys.lib_dirs) orelse (Sys2#sys.escripts =/= Sys#sys.escripts), {S3, Status} = refresh(S2, Force, {ok, []}), - {S4, Status2} = analyse(S3#state{old_sys = S#state.sys}, Status), - S6 = - case Status2 of - {ok, _Warnings} -> - S4#state{status = Status2, old_status = S#state.status}; - {error, _} -> - S - end, - reltool_utils:reply(ReplyTo, Ref, Status2), - ?MODULE:loop(S6); + {S4, Status2} = + analyse(S3#state{old_sys = S#state.sys}, Status), + {S5, Status3} = + case Status2 of + {ok, _Warnings} -> % BUGBUG: handle warnings + {S4#state{status = Status2, + old_status = S#state.status}, + Status2}; + {error, _} -> + %% Keep old state + {S, Status2} + end, + reltool_utils:reply(ReplyTo, Ref, Status3), + ?MODULE:loop(S5); {call, ReplyTo, Ref, get_status} -> reltool_utils:reply(ReplyTo, Ref, S#state.status), ?MODULE:loop(S); {call, ReplyTo, Ref, {gen_rel_files, Dir}} -> - Status = + Status = case reltool_target:gen_rel_files(S#state.sys, Dir) of ok -> {ok, []}; @@ -395,16 +433,25 @@ do_set_app(#state{sys = Sys} = S, App, Status) -> Sys2 = Sys#sys{apps = Apps2, escripts = Escripts}, {S#state{sys = Sys2}, Status2}. -analyse(#state{common = C, sys = #sys{apps = Apps0} = Sys} = S, Status) -> - Apps = lists:keydelete(?MISSING_APP, #app.name, Apps0), +analyse(#state{common = C, + sys = #sys{apps = Apps0, rels = Rels} = Sys} = S, + Status) -> + Apps = lists:keydelete(?MISSING_APP_NAME, #app.name, Apps0), ets:delete_all_objects(C#common.app_tab), ets:delete_all_objects(C#common.mod_tab), ets:delete_all_objects(C#common.mod_used_by_tab), - MissingApp = default_app(?MISSING_APP, "missing"), + MissingApp = default_app(?MISSING_APP_NAME, "missing"), ets:insert(C#common.app_tab, MissingApp), - Apps2 = lists:map(fun(App) -> app_init_is_included(C, Sys, App) end, Apps), - Apps3 = + {RevRelApps, Status2} = apps_in_rels(Rels, Apps, Status), + RelApps2 = lists:reverse(RevRelApps), + {Apps2, Status3} = + lists:mapfoldl(fun(App, Acc) -> + app_init_is_included(C, Sys, App, RelApps2, Acc) + end, + Status2, + Apps), + Apps3 = case app_propagate_is_included(C, Sys, Apps2, []) of [] -> Apps2; @@ -412,25 +459,68 @@ analyse(#state{common = C, sys = #sys{apps = Apps0} = Sys} = S, Status) -> %% io:format("Missing mods: ~p\n", [MissingMods]), MissingApp2 = MissingApp#app{label = ?MISSING_APP_TEXT, info = missing_app_info(""), - mods = MissingMods, + mods = MissingMods, status = missing, uses_mods = []}, [MissingApp2 | Apps2] end, app_propagate_is_used_by(C, Apps3), Apps4 = read_apps(C, Sys, Apps3, []), - %% io:format("Missing app: ~p\n", [lists:keysearch(?MISSING_APP, #app.name, Apps4)]), + %% io:format("Missing app: ~p\n", + %% [lists:keysearch(?MISSING_APP_NAME, #app.name, Apps4)]), Sys2 = Sys#sys{apps = Apps4}, - try - Status2 = verify_config(Sys2, Status), - {S#state{sys = Sys2}, Status2} - catch - throw:{error, Status3} -> - {S, Status3} + + case verify_config(RelApps2, Sys2, Status3) of + {ok, _Warnings} = Status4 -> + {S#state{sys = Sys2}, Status4}; + {error, _} = Status4 -> + {S, Status4} end. -app_init_is_included(C, Sys, #app{mods = Mods} = A) -> - AppCond = +apps_in_rels(Rels, Apps, Status) -> + lists:foldl(fun(Rel, {RelApps, S}) -> + {MoreRelApps, S2} = apps_in_rel(Rel, Apps, S), + {MoreRelApps ++ RelApps, S2} + end, + {[], Status}, + Rels). + +apps_in_rel(#rel{name = RelName, rel_apps = RelApps}, Apps, Status) -> + Mandatory = [{RelName, kernel}, {RelName, stdlib}], + Other = [{RelName, AppName} || + RA <- RelApps, + AppName <- [RA#rel_app.name | RA#rel_app.incl_apps], + not lists:keymember(AppName, 2, Mandatory)], + more_apps_in_rels(Mandatory ++ Other, Apps, [], Status). + +more_apps_in_rels([{RelName, AppName} = RA | RelApps], Apps, Acc, Status) -> + case lists:member(RA, Acc) of + true -> + more_apps_in_rels(RelApps, Apps, Acc, Status); + false -> + case lists:keysearch(AppName, #app.name, Apps) of + {value, #app{info = #app_info{applications = InfoApps}}} -> + Extra = [{RelName, N} || N <- InfoApps], + {Acc2, Status2} = + more_apps_in_rels(Extra, Apps, [RA | Acc], Status), + more_apps_in_rels(RelApps, Apps, Acc2, Status2); + false -> + Text = lists:concat(["Release ", RelName, + " uses non existing application ", + AppName]), + Status2 = reltool_utils:return_first_error(Status, Text), + more_apps_in_rels(RelApps, Apps, Acc, Status2) + end + end; +more_apps_in_rels([], _Apps, Acc, Status) -> + {Acc, Status}. + +app_init_is_included(C, + Sys, + #app{name = AppName, mods = Mods} = A, + RelApps, + Status) -> + AppCond = case A#app.incl_cond of undefined -> Sys#sys.incl_cond; _ -> A#app.incl_cond @@ -440,17 +530,37 @@ app_init_is_included(C, Sys, #app{mods = Mods} = A) -> undefined -> Sys#sys.mod_cond; _ -> A#app.mod_cond end, - IsIncl = - case AppCond of - include -> true; - exclude -> false; - derived -> undefined + Rels = [RelName || {RelName, AN} <- RelApps, AN =:= AppName], + {Default, IsPreIncl, IsIncl, Status2} = + case {AppCond, Rels} of + {include, _} -> + {undefined, true, true, Status}; + {exclude, []} -> + {undefined, false, false, Status}; + {exclude, [RelName | _]} -> % App is included in at least one rel + Text = lists:concat(["Application ", AppName, " is used " + "in release ", RelName, " and cannot " + "be excluded"]), + TmpStatus = reltool_utils:return_first_error(Status, Text), + {undefined, false, false, TmpStatus}; + {derived, []} -> + {undefined, undefined, undefined, Status}; + {derived, [_ | _]} -> % App is included in at least one rel + {true, undefined, true, Status} end, - A2 = A#app{is_pre_included = IsIncl, is_included = IsIncl}, + A2 = A#app{is_pre_included = IsPreIncl, + is_included = IsIncl, + rels = Rels}, ets:insert(C#common.app_tab, A2), - lists:foreach(fun(Mod) -> mod_init_is_included(C, Mod, ModCond, AppCond, undefined) end, Mods), - %%app_mod_init_is_included(C, AppName, Info, ModCond, AppCond), - A2. + lists:foreach(fun(Mod) -> + mod_init_is_included(C, + Mod, + ModCond, + AppCond, + Default) + end, + Mods), + {A2, Status2}. mod_init_is_included(C, M, ModCond, AppCond, Default) -> %% print(M#mod.name, hipe, "incl_cond -> ~p\n", [AppCond]), @@ -463,7 +573,8 @@ mod_init_is_included(C, M, ModCond, AppCond, Default) -> exclude -> false; undefined -> - %% print(M#mod.name, hipe, "mod_cond -> ~p\n", [ModCond]), + %% print(M#mod.name, hipe, "mod_cond -> ~p\n", + %% [ModCond]), case ModCond of all -> true; app -> false_to_undefined(M#mod.is_app_mod); @@ -493,7 +604,7 @@ false_to_undefined(Bool) -> false -> undefined; _ -> Bool end. - + app_propagate_is_included(C, Sys, [#app{mods = Mods} = A | Apps], Acc) -> Acc2 = mod_propagate_is_included(C, Sys, A, Mods, Acc), app_propagate_is_included(C, Sys, Apps, Acc2); @@ -502,9 +613,11 @@ app_propagate_is_included(_C, _Sys, [], Acc) -> mod_propagate_is_included(C, Sys, A, [#mod{name = ModName} | Mods], Acc) -> [M2] = ets:lookup(C#common.mod_tab, ModName), - %% print(ModName, file, "Maybe Prop ~p -> ~p\n", [M2, M2#mod.is_included]), - %% print(ModName, filename, "Maybe Prop ~p -> ~p\n", [M2, M2#mod.is_included]), - Acc2 = + %% print(ModName, file, "Maybe Prop ~p -> ~p\n", + %% [M2, M2#mod.is_included]), + %% print(ModName, filename, "Maybe Prop ~p -> ~p\n", + %% [M2, M2#mod.is_included]), + Acc2 = case M2#mod.is_included of true -> %% Propagate include mark @@ -519,11 +632,13 @@ mod_propagate_is_included(_C, _Sys, _A, [], Acc) -> Acc. mod_mark_is_included(C, Sys, UsedByName, [ModName | ModNames], Acc) -> - Acc3 = + Acc3 = case ets:lookup(C#common.mod_tab, ModName) of - [M] -> - %% print(UsedByName, file, "Maybe Mark ~p -> ~p\n", [M, M#mod.is_included]), - %% print(UsedByName, filename, "Maybe Mark ~p -> ~p\n", [M, M#mod.is_included]), + [M] -> + %% print(UsedByName, file, "Maybe Mark ~p -> ~p\n", + %% [M, M#mod.is_included]), + %% print(UsedByName, filename, "Maybe Mark ~p -> ~p\n", + %% [M, M#mod.is_included]), case M#mod.is_included of true -> %% Already marked @@ -533,19 +648,22 @@ mod_mark_is_included(C, Sys, UsedByName, [ModName | ModNames], Acc) -> Acc; undefined -> %% Mark and propagate - M2 = + M2 = case M#mod.incl_cond of include -> - M#mod{is_pre_included = true, is_included = true}; + M#mod{is_pre_included = true, + is_included = true}; exclude -> - M#mod{is_pre_included = true, is_included = true}; + M#mod{is_pre_included = true, + is_included = true}; undefined -> M#mod{is_included = true} end, ets:insert(C#common.mod_tab, M2), - %% io:format("Propagate mod: ~p -> ~p (~p)\n", [UsedByName, ModName, M#mod.incl_cond]), + %% io:format("Propagate mod: ~p -> ~p (~p)\n", + %% [UsedByName, ModName, M#mod.incl_cond]), [A] = ets:lookup(C#common.app_tab, M2#mod.app_name), - Acc2 = + Acc2 = case A#app.is_included of true -> Acc; @@ -557,7 +675,7 @@ mod_mark_is_included(C, Sys, UsedByName, [ModName | ModNames], Acc) -> undefined -> Sys#sys.mod_cond; _ -> A#app.mod_cond end, - Filter = + Filter = fun(M3) -> case ModCond of all -> true; @@ -569,15 +687,25 @@ mod_mark_is_included(C, Sys, UsedByName, [ModName | ModNames], Acc) -> end, Mods = lists:filter(Filter, A#app.mods), %% io:format("Propagate app: ~p ~p -> ~p\n", - %% [UsedByName, A#app.name, [M3#mod.name || M3 <- Mods]]), + %% [UsedByName, A#app.name, + %% [M3#mod.name || M3 <- Mods]]), A2 = A#app{is_included = true}, - ets:insert(C#common.app_tab, A2), - mod_mark_is_included(C, Sys, ModName, [M3#mod.name || M3 <- Mods], Acc) + ets:insert(C#common.app_tab, A2), + mod_mark_is_included(C, + Sys, + ModName, + [M3#mod.name || + M3 <- Mods], + Acc) end, - mod_mark_is_included(C, Sys, ModName, M2#mod.uses_mods, Acc2) + mod_mark_is_included(C, + Sys, + ModName, + M2#mod.uses_mods, + Acc2) end; [] -> - M = missing_mod(ModName, ?MISSING_APP), + M = missing_mod(ModName, ?MISSING_APP_NAME), M2 = M#mod{is_included = true}, ets:insert(C#common.mod_tab, M2), ets:insert(C#common.mod_used_by_tab, {UsedByName, ModName}), @@ -588,7 +716,7 @@ mod_mark_is_included(_C, _Sys, _UsedByName, [], Acc) -> Acc. app_propagate_is_used_by(C, [#app{mods = Mods, name = Name} | Apps]) -> - case Name =:= ?MISSING_APP of + case Name =:= ?MISSING_APP_NAME of true -> ok; false -> ok end, @@ -614,21 +742,22 @@ mod_propagate_is_used_by(_C, []) -> read_apps(C, Sys, [#app{mods = Mods, is_included = IsIncl} = A | Apps], Acc) -> {Mods2, IsIncl2} = read_apps(C, Sys, A, Mods, [], IsIncl), - %% reltool_utils:print(A#app.name, stdlib, "Mods2: ~p\n", [[M#mod.status || M <- Mods2]]), - Status = + Status = case lists:keysearch(missing, #mod.status, Mods2) of {value, _} -> missing; false -> ok end, UsesMods = [M#mod.uses_mods || M <- Mods2, M#mod.is_included =:= true], UsesMods2 = lists:usort(lists:flatten(UsesMods)), - UsesApps = [M#mod.app_name || ModName <- UsesMods2, M <- ets:lookup(C#common.mod_tab, ModName)], + UsesApps = [M#mod.app_name || ModName <- UsesMods2, + M <- ets:lookup(C#common.mod_tab, ModName)], UsesApps2 = lists:usort(UsesApps), UsedByMods = [M#mod.used_by_mods || M <- Mods2, M#mod.is_included =:= true], UsedByMods2 = lists:usort(lists:flatten(UsedByMods)), - UsedByApps = [M#mod.app_name || ModName <- UsedByMods2, M <- ets:lookup(C#common.mod_tab, ModName)], + UsedByApps = [M#mod.app_name || ModName <- UsedByMods2, + M <- ets:lookup(C#common.mod_tab, ModName)], UsedByApps2 = lists:usort(UsedByApps), - + A2 = A#app{mods = Mods2, status = Status, uses_mods = UsesMods2, @@ -644,12 +773,14 @@ read_apps(C, Sys, A, [#mod{name = ModName} | Mods], Acc, IsIncl) -> [M2] = ets:lookup(C#common.mod_tab, ModName), Status = do_get_status(M2), %% print(M2#mod.name, hipe, "status -> ~p\n", [Status]), - {IsIncl2, M3} = + {IsIncl2, M3} = case M2#mod.is_included of true -> - UsedByMods = [N || {_, N} <- ets:lookup(C#common.mod_used_by_tab, ModName)], + UsedByMods = + [N || {_, N} <- ets:lookup(C#common.mod_used_by_tab, + ModName)], {true, M2#mod{status = Status, used_by_mods = UsedByMods}}; - _ -> + _ -> {IsIncl, M2#mod{status = Status, used_by_mods = []}} end, ets:insert(C#common.mod_tab, M3), @@ -669,14 +800,12 @@ shrink_sys(#state{sys = #sys{apps = Apps} = Sys} = S) -> Apps2 = lists:zf(fun filter_app/1, Apps), S#state{sys = Sys#sys{apps = Apps2}}. -filter_app(A) -> +filter_app(A) -> Mods = [M#mod{is_app_mod = undefined, is_ebin_mod = undefined, uses_mods = undefined, - exists = false, - is_pre_included = undefined, - is_included = undefined} || - M <- A#app.mods, + exists = false} || + M <- A#app.mods, M#mod.incl_cond =/= undefined], if A#app.is_escript -> @@ -684,17 +813,16 @@ filter_app(A) -> label = undefined, info = undefined, mods = [], - uses_mods = undefined, - is_included = undefined}}; + uses_mods = undefined}}; Mods =:= [], A#app.mod_cond =:= undefined, A#app.incl_cond =:= undefined, A#app.use_selected_vsn =:= undefined -> false; true -> - {Dir, Dirs} = + {Dir, Dirs} = case A#app.use_selected_vsn of - undefined -> + undefined -> {shrinked, []}; false -> {shrinked, []}; @@ -715,8 +843,7 @@ filter_app(A) -> label = undefined, info = undefined, mods = Mods, - uses_mods = undefined, - is_included = undefined}} + uses_mods = undefined}} end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -730,37 +857,45 @@ refresh_app(#app{name = AppName, Status) -> if Force; OptLabel =:= undefined -> - {AppInfo, EbinMods, Status3} = + {AppInfo, EbinMods, Status3} = case IsEscript of false -> - + %% Add info from .app file Base = get_base(AppName, ActiveDir), {_, DefaultVsn} = reltool_utils:split_app_name(Base), Ebin = filename:join([ActiveDir, "ebin"]), - AppFile = filename:join([Ebin, atom_to_list(AppName) ++ ".app"]), - {AI, Status2} = read_app_info(AppFile, AppFile, AppName, DefaultVsn, Status), + AppFile = + filename:join([Ebin, + atom_to_list(AppName) ++ ".app"]), + {AI, Status2} = + read_app_info(AppFile, + AppFile, + AppName, + DefaultVsn, + Status), {AI, read_ebin_mods(Ebin, AppName), Status2}; true -> {App#app.info, Mods, Status} end, - + %% Add non-existing modules + AppInfoMods = AppInfo#app_info.modules, AppModNames = case AppInfo#app_info.mod of {StartModName, _} -> - case lists:member(StartModName, AppInfo#app_info.modules) of - true -> AppInfo#app_info.modules; - false -> [StartModName | AppInfo#app_info.modules] + case lists:member(StartModName, AppInfoMods) of + true -> AppInfoMods; + false -> [StartModName | AppInfoMods] end; - undefined -> - AppInfo#app_info.modules + undefined -> + AppInfoMods end, MissingMods = add_missing_mods(AppName, EbinMods, AppModNames), - + %% Add optional user config for each module Mods2 = add_mod_config(MissingMods ++ EbinMods, Mods), - + %% Set app flag for each module in app file Mods3 = set_mod_flags(Mods2, AppModNames), AppVsn = AppInfo#app_info.vsn, @@ -770,7 +905,7 @@ refresh_app(#app{name = AppName, _ -> atom_to_list(AppName) ++ "-" ++ AppVsn end, App2 = App#app{vsn = AppVsn, - label = AppLabel, + label = AppLabel, info = AppInfo, mods = lists:keysort(#mod.name, Mods3)}, {App2, Status3}; @@ -790,30 +925,59 @@ read_app_info(AppFileOrBin, AppFile, AppName, DefaultVsn, Status) -> AI = #app_info{vsn = DefaultVsn}, parse_app_info(AppFile, Info, AI, Status); {ok, _BadApp} -> - Text = lists:concat([AppName, ": Illegal contents in app file ", AppFile]), - {missing_app_info(DefaultVsn), reltool_utils:add_warning(Status, Text)}; - {error, Text} when Text =:= EnoentText-> - {missing_app_info(DefaultVsn), Status}; + Text = lists:concat([AppName, + ": Illegal contents in app file ", AppFile, + ", application tuple with arity 3 expected."]), + {missing_app_info(DefaultVsn), + reltool_utils:add_warning(Status, Text)}; + {error, Text} when Text =:= EnoentText -> + Text2 = lists:concat([AppName, + ": Missing app file ", AppFile, "."]), + {missing_app_info(DefaultVsn), + reltool_utils:add_warning(Status, Text2)}; {error, Text} -> - Text2 = lists:concat([AppName, ": Cannot parse app file ", AppFile, " (", Text, ")."]), - {missing_app_info(DefaultVsn), reltool_utils:add_warning(Status, Text2)} + Text2 = lists:concat([AppName, + ": Cannot parse app file ", + AppFile, " (", Text, ")."]), + {missing_app_info(DefaultVsn), + reltool_utils:add_warning(Status, Text2)} end. parse_app_info(File, [{Key, Val} | KeyVals], AI, Status) -> case Key of - description -> parse_app_info(File, KeyVals, AI#app_info{description = Val}, Status); - id -> parse_app_info(File, KeyVals, AI#app_info{id = Val}, Status); - vsn -> parse_app_info(File, KeyVals, AI#app_info{vsn = Val}, Status); - modules -> parse_app_info(File, KeyVals, AI#app_info{modules = Val}, Status); - maxP -> parse_app_info(File, KeyVals, AI#app_info{maxP = Val}, Status); - maxT -> parse_app_info(File, KeyVals, AI#app_info{maxT = Val}, Status); - registered -> parse_app_info(File, KeyVals, AI#app_info{registered = Val}, Status); - included_applications -> parse_app_info(File, KeyVals, AI#app_info{incl_apps = Val}, Status); - applications -> parse_app_info(File, KeyVals, AI#app_info{applications = Val}, Status); - env -> parse_app_info(File, KeyVals, AI#app_info{env = Val}, Status); - mod -> parse_app_info(File, KeyVals, AI#app_info{mod = Val}, Status); - start_phases -> parse_app_info(File, KeyVals, AI#app_info{start_phases = Val}, Status); - _ -> parse_app_info(File, KeyVals, AI, reltool_utils:add_warning(Status, lists:concat(["Unexpected item ", Key, "in app file ", File]))) + description -> + parse_app_info(File, KeyVals, AI#app_info{description = Val}, + Status); + id -> + parse_app_info(File, KeyVals, AI#app_info{id = Val}, Status); + vsn -> + parse_app_info(File, KeyVals, AI#app_info{vsn = Val}, Status); + modules -> + parse_app_info(File, KeyVals, AI#app_info{modules = Val}, Status); + maxP -> + parse_app_info(File, KeyVals, AI#app_info{maxP = Val}, Status); + maxT -> + parse_app_info(File, KeyVals, AI#app_info{maxT = Val}, Status); + registered -> + parse_app_info(File, KeyVals, AI#app_info{registered = Val}, + Status); + included_applications -> + parse_app_info(File, KeyVals, AI#app_info{incl_apps = Val}, Status); + applications -> + parse_app_info(File, KeyVals, AI#app_info{applications = Val}, + Status); + env -> + parse_app_info(File, KeyVals, AI#app_info{env = Val}, Status); + mod -> + parse_app_info(File, KeyVals, AI#app_info{mod = Val}, Status); + start_phases -> + parse_app_info(File, KeyVals, AI#app_info{start_phases = Val}, + Status); + _ -> + String = lists:concat(["Unexpected item ", + Key, "in app file ", File]), + parse_app_info(File, KeyVals, AI, + reltool_utils:add_warning(Status, String)) end; parse_app_info(_, [], AI, Status) -> {AI, Status}. @@ -824,7 +988,7 @@ read_ebin_mods(Ebin, AppName) -> Ext = code:objfile_extension(), InitMod = fun(F) -> File = filename:join([Ebin, F]), - init_mod(AppName, File, File, Ext) + init_mod(AppName, File, File, Ext) end, Files2 = [F || F <- Files, filename:extension(F) =:= Ext], pmap(InitMod, Files2); @@ -839,7 +1003,7 @@ pmap(Fun, List) -> %% -record(pmap_res, {count, ref, res}). %% -record(pmap_wait, {count, ref, pid}). -%% +%% %% pmap(Fun, [H | T], N, Max, Count, WaitFor, Results) when N < Max -> %% Ref = make_ref(), %% Parent = self(), @@ -943,16 +1107,16 @@ set_mod_flags(Mods, AppModNames) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -do_get_config(S, InclDefaults, InclDerivates) -> +do_get_config(S, InclDef, InclDeriv) -> S2 = - case InclDerivates of + case InclDeriv of false -> shrink_sys(S); true -> S end, - {ok, reltool_target:gen_config(S2#state.sys, InclDefaults)}. + reltool_target:gen_config(S2#state.sys, InclDef). -do_save_config(S, Filename, InclDefaults, InclDerivates) -> - {ok, Config} = do_get_config(S, InclDefaults, InclDerivates), +do_save_config(S, Filename, InclDef, InclDeriv) -> + {ok, Config} = do_get_config(S, InclDef, InclDeriv), IoList = io_lib:format("%% config generated at ~w ~w\n~p.\n\n", [date(), time(), Config]), file:write_file(Filename, IoList). @@ -963,17 +1127,20 @@ do_load_config(S, SysConfig) -> OldSys = S#state.sys, S2 = shrink_sys(S), ShrinkedSys = S2#state.sys, - {NewSys, Status} = read_config(ShrinkedSys#sys{apps = []}, SysConfig, {ok, []}), + {NewSys, Status} = + read_config(ShrinkedSys#sys{apps = []}, SysConfig, {ok, []}), case Status of {ok, _Warnings} -> Force = false, {MergedSys, Status2} = merge_config(OldSys, NewSys, Force, Status), - {S3, Status3} = analyse(S2#state{sys = MergedSys, old_sys = OldSys}, Status2), - S4 = + {S3, Status3} = + analyse(S2#state{sys = MergedSys, old_sys = OldSys}, Status2), + S4 = case Status3 of {ok, _Warnings2} -> S3#state{status = Status3, old_status = S#state.status}; {error, _} -> + %% Keep old state S end, {S4, Status3}; @@ -988,37 +1155,51 @@ read_config(OldSys, Filename, Status) when is_list(Filename) -> read_config(OldSys, SysConfig, Status); {ok, Content} -> Text = lists:flatten(io_lib:format("~p", [Content])), - {OldSys, reltool_utils:return_first_error(Status, "Illegal file content: " ++ Text)}; + {OldSys, + reltool_utils:return_first_error(Status, + "Illegal file content: " ++ + Text)}; {error, Reason} -> Text = file:format_error(Reason), - {OldSys, reltool_utils:return_first_error(Status, "File access: " ++ Text)} + {OldSys, + reltool_utils:return_first_error(Status, + "Illegal config file " ++ + Filename ++ ": " ++ Text)} end; read_config(OldSys, {sys, KeyVals}, Status) -> {NewSys, Status2} = - try - decode(OldSys#sys{apps = [], rels = []}, KeyVals, Status) - catch - throw:{error, Text} -> - {OldSys, reltool_utils:return_first_error(Status, Text)} - end, - Apps = [A#app{mods = lists:sort(A#app.mods)} || A <- NewSys#sys.apps], - case NewSys#sys.rels of - [] -> Rels = reltool_utils:default_rels(); - Rels -> ok - end, - NewSys2 = NewSys#sys{apps = lists:sort(Apps), rels = lists:sort(Rels)}, - case lists:keysearch(NewSys2#sys.boot_rel, #rel.name, NewSys2#sys.rels) of - {value, _} -> - {NewSys2, Status2}; - false -> - Text2 = "Missing rel: " ++ NewSys2#sys.boot_rel, - {OldSys, reltool_utils:return_first_error(Status2, Text2)} + decode(OldSys#sys{apps = [], rels = []}, KeyVals, Status), + case Status2 of + {ok, _Warnings} -> % BUGBUG: handle warnings + Apps = [A#app{mods = lists:sort(A#app.mods)} || + A <- NewSys#sys.apps], + case NewSys#sys.rels of + [] -> Rels = reltool_utils:default_rels(); + Rels -> ok + end, + NewSys2 = NewSys#sys{apps = lists:sort(Apps), + rels = lists:sort(Rels)}, + case lists:keysearch(NewSys2#sys.boot_rel, + #rel.name, + NewSys2#sys.rels) of + {value, _} -> + {NewSys2, Status2}; + false -> + Text2 = lists:concat(["Release " ++ NewSys2#sys.boot_rel, + " is mandatory (used as boot_rel)"]), + {OldSys, reltool_utils:return_first_error(Status2, Text2)} + end; + {error, _} -> + %% Keep old state + {OldSys, Status2} end; read_config(OldSys, BadConfig, Status) -> Text = lists:flatten(io_lib:format("~p", [BadConfig])), - {OldSys, reltool_utils:return_first_error(Status, "Illegal content: " ++ Text)}. + {OldSys, + reltool_utils:return_first_error(Status, "Illegal content: " ++ Text)}. -decode(#sys{apps = Apps} = Sys, [{erts = Name, AppKeyVals} | SysKeyVals], Status) +decode(#sys{apps = Apps} = Sys, [{erts = Name, AppKeyVals} | SysKeyVals], + Status) when is_atom(Name), is_list(AppKeyVals) -> App = default_app(Name), {App2, Status2} = decode(App, AppKeyVals, Status), @@ -1028,7 +1209,8 @@ decode(#sys{apps = Apps} = Sys, [{app, Name, AppKeyVals} | SysKeyVals], Status) App = default_app(Name), {App2, Status2} = decode(App, AppKeyVals, Status), decode(Sys#sys{apps = [App2 | Apps]}, SysKeyVals, Status2); -decode(#sys{apps = Apps, escripts = Escripts} = Sys, [{escript, File, AppKeyVals} | SysKeyVals], Status) +decode(#sys{apps = Apps, escripts = Escripts} = Sys, + [{escript, File, AppKeyVals} | SysKeyVals], Status) when is_list(File), is_list(AppKeyVals) -> {Name, Label} = split_escript_name(File), App = default_app(Name, File), @@ -1038,149 +1220,201 @@ decode(#sys{apps = Apps, escripts = Escripts} = Sys, [{escript, File, AppKeyVals active_dir = File, sorted_dirs = [File]}, {App3, Status2} = decode(App2, AppKeyVals, Status), - decode(Sys#sys{apps = [App3 | Apps], escripts = [File | Escripts]}, SysKeyVals, Status2); -decode(#sys{rels = Rels} = Sys, [{rel, Name, Vsn, RelApps} | SysKeyVals], Status) + decode(Sys#sys{apps = [App3 | Apps], escripts = [File | Escripts]}, + SysKeyVals, + Status2); +decode(#sys{rels = Rels} = Sys, [{rel, Name, Vsn, RelApps} | SysKeyVals], + Status) when is_list(Name), is_list(Vsn), is_list(RelApps) -> Rel = #rel{name = Name, vsn = Vsn, rel_apps = []}, {Rel2, Status2} = decode(Rel, RelApps, Status), decode(Sys#sys{rels = [Rel2 | Rels]}, SysKeyVals, Status2); decode(#sys{} = Sys, [{Key, Val} | KeyVals], Status) -> - {Sys3, Status3} = + {Sys3, Status3} = case Key of root_dir when is_list(Val) -> {Sys#sys{root_dir = Val}, Status}; lib_dirs when is_list(Val) -> {Sys#sys{lib_dirs = Val}, Status}; - mod_cond when Val =:= all; Val =:= app; - Val =:= ebin; Val =:= derived; - Val =:= none -> + mod_cond when Val =:= all; + Val =:= app; + Val =:= ebin; + Val =:= derived; + Val =:= none -> {Sys#sys{mod_cond = Val}, Status}; - incl_cond when Val =:= include; Val =:= exclude; - Val =:= derived -> + incl_cond when Val =:= include; + Val =:= exclude; + Val =:= derived -> {Sys#sys{incl_cond = Val}, Status}; boot_rel when is_list(Val) -> {Sys#sys{boot_rel = Val}, Status}; emu_name when is_list(Val) -> {Sys#sys{emu_name = Val}, Status}; - profile when Val =:= development -> - Val = ?DEFAULT_PROFILE, % assert, - {Sys#sys{profile = Val, - incl_sys_filters = reltool_utils:decode_regexps(incl_sys_filters, - ?DEFAULT_INCL_SYS_FILTERS, - Sys#sys.incl_sys_filters), - excl_sys_filters = reltool_utils:decode_regexps(excl_sys_filters, - ?DEFAULT_EXCL_SYS_FILTERS, - Sys#sys.excl_sys_filters), - incl_app_filters = reltool_utils:decode_regexps(incl_app_filters, - ?DEFAULT_INCL_APP_FILTERS, - Sys#sys.incl_app_filters), - excl_app_filters = reltool_utils:decode_regexps(excl_app_filters, - ?DEFAULT_EXCL_APP_FILTERS, - Sys#sys.excl_app_filters)}, - Status}; - profile when Val =:= embedded -> - {Sys#sys{profile = Val, - incl_sys_filters = reltool_utils:decode_regexps(incl_sys_filters, - ?EMBEDDED_INCL_SYS_FILTERS, - Sys#sys.incl_sys_filters), - excl_sys_filters = reltool_utils:decode_regexps(excl_sys_filters, - ?EMBEDDED_EXCL_SYS_FILTERS, - Sys#sys.excl_sys_filters), - incl_app_filters = reltool_utils:decode_regexps(incl_app_filters, - ?EMBEDDED_INCL_APP_FILTERS, - Sys#sys.incl_app_filters), - excl_app_filters = reltool_utils:decode_regexps(excl_app_filters, - ?EMBEDDED_EXCL_APP_FILTERS, - Sys#sys.excl_app_filters)}, - Status}; - profile when Val =:= standalone -> - {Sys#sys{profile = Val, - incl_sys_filters = reltool_utils:decode_regexps(incl_sys_filters, - ?STANDALONE_INCL_SYS_FILTERS, - Sys#sys.incl_sys_filters), - excl_sys_filters = reltool_utils:decode_regexps(excl_sys_filters, - ?STANDALONE_EXCL_SYS_FILTERS, - Sys#sys.excl_sys_filters), - incl_app_filters = reltool_utils:decode_regexps(incl_app_filters, - ?STANDALONE_INCL_APP_FILTERS, - Sys#sys.incl_app_filters), - excl_app_filters = reltool_utils:decode_regexps(excl_app_filters, - ?STANDALONE_EXCL_APP_FILTERS, - Sys#sys.excl_app_filters)}, + profile when Val =:= development; + Val =:= embedded; + Val =:= standalone -> + InclSys = reltool_utils:choose_default(incl_sys_filters, Val, false), + ExclSys = reltool_utils:choose_default(excl_sys_filters, Val, false), + InclApp = reltool_utils:choose_default(incl_app_filters, Val, false), + ExclApp = reltool_utils:choose_default(excl_app_filters, Val, false), + AppType = reltool_utils:choose_default(embedded_app_type, Val, false), + {Sys#sys{profile = Val, + incl_sys_filters = dec_re(incl_sys_filters, + InclSys, + Sys#sys.incl_sys_filters), + excl_sys_filters = dec_re(excl_sys_filters, + ExclSys, + Sys#sys.excl_sys_filters), + incl_app_filters = dec_re(incl_app_filters, + InclApp, + Sys#sys.incl_app_filters), + excl_app_filters = dec_re(excl_app_filters, + ExclApp, + Sys#sys.excl_app_filters), + embedded_app_type = AppType}, Status}; incl_sys_filters -> - {Sys#sys{incl_sys_filters = reltool_utils:decode_regexps(Key, Val, Sys#sys.incl_sys_filters)}, Status}; + {Sys#sys{incl_sys_filters = + dec_re(Key, + Val, + Sys#sys.incl_sys_filters)}, + Status}; excl_sys_filters -> - {Sys#sys{excl_sys_filters = reltool_utils:decode_regexps(Key, Val, Sys#sys.excl_sys_filters)}, Status}; + {Sys#sys{excl_sys_filters = + dec_re(Key, + Val, + Sys#sys.excl_sys_filters)}, + Status}; incl_app_filters -> - {Sys#sys{incl_app_filters = reltool_utils:decode_regexps(Key, Val, Sys#sys.incl_app_filters)}, Status}; + {Sys#sys{incl_app_filters = + dec_re(Key, + Val, + Sys#sys.incl_app_filters)}, + Status}; excl_app_filters -> - {Sys#sys{excl_app_filters = reltool_utils:decode_regexps(Key, Val, Sys#sys.excl_app_filters)}, Status}; + {Sys#sys{excl_app_filters = + dec_re(Key, + Val, + Sys#sys.excl_app_filters)}, + Status}; incl_archive_filters -> - {Sys#sys{incl_archive_filters = reltool_utils:decode_regexps(Key, Val, Sys#sys.incl_archive_filters)}, Status}; + {Sys#sys{incl_archive_filters = + dec_re(Key, + Val, + Sys#sys.incl_archive_filters)}, + Status}; excl_archive_filters -> - {Sys#sys{excl_archive_filters = reltool_utils:decode_regexps(Key, Val, Sys#sys.excl_archive_filters)}, Status}; + {Sys#sys{excl_archive_filters = + dec_re(Key, + Val, + Sys#sys.excl_archive_filters)}, + Status}; archive_opts when is_list(Val) -> {Sys#sys{archive_opts = Val}, Status}; relocatable when Val =:= true; Val =:= false -> {Sys#sys{relocatable = Val}, Status}; - app_type when Val =:= permanent; Val =:= transient; Val =:= temporary; - Val =:= load; Val =:= none -> - {Sys#sys{app_type = Val}, Status}; - app_file when Val =:= keep; Val =:= strip, Val =:= all -> + rel_app_type when Val =:= permanent; + Val =:= transient; + Val =:= temporary; + Val =:= load; + Val =:= none -> + {Sys#sys{rel_app_type = Val}, Status}; + embedded_app_type when Val =:= permanent; + Val =:= transient; + Val =:= temporary; + Val =:= load; + Val =:= none; + Val =:= undefined -> + {Sys#sys{embedded_app_type = Val}, Status}; + app_file when Val =:= keep; Val =:= strip, Val =:= all -> {Sys#sys{app_file = Val}, Status}; - debug_info when Val =:= keep; Val =:= strip -> + debug_info when Val =:= keep; Val =:= strip -> {Sys#sys{debug_info = Val}, Status}; _ -> Text = lists:flatten(io_lib:format("~p", [{Key, Val}])), - {Sys, reltool_utils:return_first_error(Status, "Illegal option: " ++ Text)} + {Sys, reltool_utils:return_first_error(Status, + "Illegal option: " ++ + Text)} end, decode(Sys3, KeyVals, Status3); decode(#app{} = App, [{Key, Val} | KeyVals], Status) -> - {App2, Status2} = + {App2, Status2} = case Key of - mod_cond when Val =:= all; Val =:= app; Val =:= ebin; Val =:= derived; Val =:= none -> + mod_cond when Val =:= all; + Val =:= app; + Val =:= ebin; + Val =:= derived; + Val =:= none -> {App#app{mod_cond = Val}, Status}; - incl_cond when Val =:= include; Val =:= exclude; Val =:= derived -> + incl_cond when Val =:= include; + Val =:= exclude; + Val =:= derived -> {App#app{incl_cond = Val}, Status}; - debug_info when Val =:= keep; Val =:= strip -> + debug_info when Val =:= keep; + Val =:= strip -> {App#app{debug_info = Val}, Status}; - app_file when Val =:= keep; Val =:= strip, Val =:= all -> + app_file when Val =:= keep; + Val =:= strip; + Val =:= all -> {App#app{app_file = Val}, Status}; - app_type when Val =:= permanent; Val =:= transient; Val =:= temporary; - Val =:= load; Val =:= none -> + app_type when Val =:= permanent; + Val =:= transient; + Val =:= temporary; + Val =:= load; + Val =:= none; + Val =:= undefined -> {App#app{app_type = Val}, Status}; incl_app_filters -> - {App#app{incl_app_filters = reltool_utils:decode_regexps(Key, Val, App#app.incl_app_filters)}, Status}; + {App#app{incl_app_filters = + dec_re(Key, + Val, + App#app.incl_app_filters)}, + Status}; excl_app_filters -> - {App#app{excl_app_filters = reltool_utils:decode_regexps(Key, Val, App#app.excl_app_filters)}, Status}; + {App#app{excl_app_filters = + dec_re(Key, + Val, + App#app.excl_app_filters)}, + Status}; incl_archive_filters -> - {App#app{incl_archive_filters = reltool_utils:decode_regexps(Key, Val, App#app.incl_archive_filters)}, Status}; + {App#app{incl_archive_filters = + dec_re(Key, + Val, + App#app.incl_archive_filters)}, + Status}; excl_archive_filters -> - {App#app{excl_archive_filters = reltool_utils:decode_regexps(Key, Val, App#app.excl_archive_filters)}, Status}; + {App#app{excl_archive_filters = + dec_re(Key, + Val, + App#app.excl_archive_filters)}, + Status}; archive_opts when is_list(Val) -> {App#app{archive_opts = Val}, Status}; - vsn when is_list(Val) -> + vsn when is_list(Val) -> {App#app{use_selected_vsn = true, vsn = Val}, Status}; _ -> Text = lists:flatten(io_lib:format("~p", [{Key, Val}])), - {App, reltool_utils:return_first_error(Status, "Illegal option: " ++ Text)} + {App, reltool_utils:return_first_error(Status, + "Illegal option: " ++ Text)} end, decode(App2, KeyVals, Status2); -decode(#app{mods = Mods} = App, [{mod, Name, ModKeyVals} | AppKeyVals], Status) -> +decode(#app{mods = Mods} = App, [{mod, Name, ModKeyVals} | AppKeyVals], + Status) -> {Mod, Status2} = decode(#mod{name = Name}, ModKeyVals, Status), decode(App#app{mods = [Mod | Mods]}, AppKeyVals, Status2); decode(#mod{} = Mod, [{Key, Val} | KeyVals], Status) -> - {Mod2, Status2} = + {Mod2, Status2} = case Key of - incl_cond when Val =:= include; Val =:= exclude; Val =:= derived -> + incl_cond when Val =:= include; Val =:= exclude; Val =:= derived -> {Mod#mod{incl_cond = Val}, Status}; - debug_info when Val =:= keep; Val =:= strip -> + debug_info when Val =:= keep; Val =:= strip -> {Mod#mod{debug_info = Val}, Status}; _ -> Text = lists:flatten(io_lib:format("~p", [{Key, Val}])), - {Mod, reltool_utils:return_first_error(Status, "Illegal option: " ++ Text)} + {Mod, + reltool_utils:return_first_error(Status, + "Illegal option: " ++ Text)} end, decode(Mod2, KeyVals, Status2); decode(#rel{rel_apps = RelApps} = Rel, [RelApp | KeyVals], Status) -> @@ -1191,7 +1425,9 @@ decode(#rel{rel_apps = RelApps} = Rel, [RelApp | KeyVals], Status) -> {Name, Type} when is_atom(Name) -> #rel_app{name = Name, app_type = Type, incl_apps = []}; {Name, InclApps} when is_atom(Name), is_list(InclApps) -> - #rel_app{name = Name, app_type = undefined, incl_apps = InclApps}; + #rel_app{name = Name, + app_type = undefined, + incl_apps = InclApps}; {Name, Type, InclApps} when is_atom(Name), is_list(InclApps) -> #rel_app{name = Name, app_type = Type, incl_apps = InclApps}; _ -> @@ -1204,7 +1440,9 @@ decode(#rel{rel_apps = RelApps} = Rel, [RelApp | KeyVals], Status) -> decode(Rel#rel{rel_apps = RelApps ++ [RA]}, KeyVals, Status); true -> Text = lists:flatten(io_lib:format("~p", [RelApp])), - Status2 = reltool_utils:return_first_error(Status, "Illegal option: " ++ Text), + Status2 = + reltool_utils:return_first_error(Status, + "Illegal option: " ++ Text), decode(Rel, KeyVals, Status2) end; decode(Acc, [], Status) -> @@ -1227,7 +1465,7 @@ is_type(Type) -> split_escript_name(File) when is_list(File) -> Label = filename:basename(File, ".escript"), {list_to_atom("*escript* " ++ Label), Label}. - + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% refresh(#state{sys = Sys} = S, Force, Status) -> @@ -1245,7 +1483,8 @@ merge_config(OldSys, NewSys, Force, Status) -> escripts_to_apps(Escripts, MergedApps, OldSys#sys.apps, Status2), {RefreshedApps, Status4} = refresh_apps(OldSys#sys.apps, AllApps, [], Force, Status3), - {PatchedApps, Status5} = patch_erts_version(RootDir, RefreshedApps, Status4), + {PatchedApps, Status5} = + patch_erts_version(RootDir, RefreshedApps, Status4), Escripts2 = [A#app.active_dir || A <- PatchedApps, A#app.is_escript], NewSys2 = NewSys#sys{root_dir = RootDir, lib_dirs = LibDirs, @@ -1253,47 +1492,53 @@ merge_config(OldSys, NewSys, Force, Status) -> apps = PatchedApps}, {NewSys2, Status5}. -verify_config(Sys, Status) -> - case lists:keymember(Sys#sys.boot_rel, #rel.name, Sys#sys.rels) of - true -> - lists:foreach(fun(Rel)-> check_rel(Rel, Sys, Status) end, Sys#sys.rels), - Status; +verify_config(RelApps, #sys{boot_rel = BootRel, rels = Rels, apps = Apps}, Status) -> + case lists:keymember(BootRel, #rel.name, Rels) of + true -> + Status2 = lists:foldl(fun(RA, Acc) -> + check_app(RA, Apps, Acc) end, + Status, + RelApps), + lists:foldl(fun(#rel{name = RelName}, Acc)-> + check_rel(RelName, RelApps, Acc) + end, + Status2, + Rels); false -> - Text = lists:concat([Sys#sys.boot_rel, ": release is mandatory"]), - Status2 = reltool_utils:return_first_error(Status, Text), - throw({error, Status2}) + Text = lists:concat(["Release ", BootRel, + " is mandatory (used as boot_rel)"]), + reltool_utils:return_first_error(Status, Text) end. -check_rel(#rel{name = RelName, rel_apps = RelApps}, #sys{apps = Apps}, Status) -> +check_app({RelName, AppName}, Apps, Status) -> + case lists:keysearch(AppName, #app.name, Apps) of + {value, App} when App#app.is_pre_included -> + Status; + {value, App} when App#app.is_included -> + Status; + _ -> + Text = lists:concat(["Release ", RelName, + " uses non included application ", + AppName]), + reltool_utils:return_first_error(Status, Text) + end. + +check_rel(RelName, RelApps, Status) -> EnsureApp = - fun(AppName) -> - case lists:keymember(AppName, #rel_app.name, RelApps) of + fun(AppName, Acc) -> + case lists:member({RelName, AppName}, RelApps) of true -> - ok; + Acc; false -> - Text = lists:concat([RelName, ": ", AppName, " is not included."]), - Status2 = reltool_utils:return_first_error(Status, Text), - throw({error, Status2}) - end - end, - EnsureApp(kernel), - EnsureApp(stdlib), - CheckRelApp = - fun(#rel_app{name = AppName}) -> - case lists:keysearch(AppName, #app.name, Apps) of - {value, App} when App#app.is_pre_included -> - ok; - {value, App} when App#app.is_included -> - ok; - _ -> - Text = lists:concat([RelName, ": uses application ", - AppName, " that not is included."]), - Status2 = reltool_utils:return_first_error(Status, Text), - %% throw BUGBUG: add throw - ({error, Status2}) + Text = lists:concat(["Mandatory application ", + AppName, + " is not included in release ", + RelName]), + reltool_utils:return_first_error(Acc, Text) end end, - lists:foreach(CheckRelApp, RelApps). + Mandatory = [kernel, stdlib], + lists:foldl(EnsureApp, Status, Mandatory). patch_erts_version(RootDir, Apps, Status) -> AppName = erts, @@ -1308,13 +1553,14 @@ patch_erts_version(RootDir, Apps, Status) -> Apps2 = lists:keystore(AppName, #app.name, Apps, Erts2), {Apps2, Status}; Vsn =:= "" -> - {Apps, reltool_utils:add_warning(Status, "erts has no version")}; + {Apps, reltool_utils:add_warning(Status, + "erts has no version")}; true -> {Apps, Status} end; false -> - Text = "erts cannnot be found in the root directory " ++ RootDir, - Status2 = reltool_utils:return_first_error(Status, Text), + Text = "erts cannot be found in the root directory " ++ RootDir, + Status2 = reltool_utils:return_first_error(Status, Text), {Apps, Status2} end. @@ -1327,21 +1573,31 @@ libs_to_dirs(RootDir, LibDirs, Status) -> [] -> Fun = fun(Base) -> AppDir = filename:join([RootLibDir, Base]), - case filelib:is_dir(filename:join([AppDir, "ebin"]), erl_prim_loader) of + case filelib:is_dir(filename:join([AppDir, + "ebin"]), + erl_prim_loader) of true -> AppDir; false -> - filename:join([RootDir, Base, "preloaded"]) + filename:join([RootDir, + Base, + "preloaded"]) end end, - ErtsFiles = [{erts, Fun(F)} || F <- RootFiles, lists:prefix("erts", F)], + ErtsFiles = [{erts, Fun(F)} || F <- RootFiles, + lists:prefix("erts", F)], app_dirs2(AllLibDirs, [ErtsFiles], Status); [Duplicate | _] -> - {[], reltool_utils:return_first_error(Status, "Duplicate library: " ++ Duplicate)} + {[], + reltool_utils:return_first_error(Status, + "Duplicate library: " ++ + Duplicate)} end; {error, Reason} -> Text = file:format_error(Reason), - {[], reltool_utils:return_first_error(Status, "Missing root library " ++ RootDir ++ ": " ++ Text)} + {[], reltool_utils:return_first_error(Status, + "Missing root library " ++ + RootDir ++ ": " ++ Text)} end. app_dirs2([Lib | Libs], Acc, Status) -> @@ -1352,8 +1608,9 @@ app_dirs2([Lib | Libs], Acc, Status) -> AppDir = filename:join([Lib, Base]), EbinDir = filename:join([AppDir, "ebin"]), case filelib:is_dir(EbinDir, erl_prim_loader) of - true -> - {Name, _Vsn} = reltool_utils:split_app_name(Base), + true -> + {Name, _Vsn} = + reltool_utils:split_app_name(Base), case Name of erts -> false; _ -> {true, {Name, AppDir}} @@ -1366,7 +1623,9 @@ app_dirs2([Lib | Libs], Acc, Status) -> app_dirs2(Libs, [Files2 | Acc], Status); {error, Reason} -> Text = file:format_error(Reason), - {[], reltool_utils:return_first_error(Status, "Illegal library " ++ Lib ++ ": " ++ Text)} + {[], reltool_utils:return_first_error(Status, + "Illegal library " ++ + Lib ++ ": " ++ Text)} end; app_dirs2([], Acc, Status) -> {lists:sort(lists:append(Acc)), Status}. @@ -1380,17 +1639,29 @@ escripts_to_apps([Escript | Escripts], Apps, OldApps, Status) -> [AppLabel, "ebin", File] -> case filename:extension(File) of ".app" -> - {AppName, DefaultVsn} = reltool_utils:split_app_name(AppLabel), - AppFileName = filename:join([Escript, FullName]), + {AppName, DefaultVsn} = + reltool_utils:split_app_name(AppLabel), + AppFileName = + filename:join([Escript, FullName]), {Info, StatusAcc2} = - read_app_info(GetBin(), AppFileName, AppName, DefaultVsn, Status), + read_app_info(GetBin(), + AppFileName, + AppName, + DefaultVsn, + Status), Dir = filename:join([Escript, AppName]), - {[{AppName, app, Dir, Info} | FileAcc], StatusAcc2}; + {[{AppName, app, Dir, Info} | FileAcc], + StatusAcc2}; E when E =:= Ext -> - {AppName, _} = reltool_utils:split_app_name(AppLabel), - Mod = init_mod(AppName, File, {File, GetBin()}, Ext), + {AppName, _} = + reltool_utils:split_app_name(AppLabel), + Mod = init_mod(AppName, + File, + {File, GetBin()}, + Ext), Dir = filename:join([Escript, AppName]), - {[{AppName, mod, Dir, Mod} | FileAcc], StatusAcc}; + {[{AppName, mod, Dir, Mod} | FileAcc], + StatusAcc}; _ -> {FileAcc, StatusAcc} end; @@ -1398,13 +1669,21 @@ escripts_to_apps([Escript | Escripts], Apps, OldApps, Status) -> Bin = GetBin(), {ok, {ModName, _}} = beam_lib:version(Bin), ModStr = atom_to_list(ModName) ++ Ext, - Mod = init_mod(EscriptAppName, ModStr, {ModStr, GetBin()}, Ext), - {[{EscriptAppName, mod, Escript, Mod} | FileAcc], StatusAcc}; + Mod = init_mod(EscriptAppName, + ModStr, + {ModStr, GetBin()}, + Ext), + {[{EscriptAppName, mod, Escript, Mod} | FileAcc], + StatusAcc}; [File] -> case filename:extension(File) of E when E =:= Ext -> - Mod = init_mod(EscriptAppName, File, {File, GetBin()}, Ext), - {[{EscriptAppName, mod, File, Mod} | FileAcc], StatusAcc}; + Mod = init_mod(EscriptAppName, + File, + {File, GetBin()}, + Ext), + {[{EscriptAppName, mod, File, Mod} | FileAcc], + StatusAcc}; _ -> {FileAcc, StatusAcc} end; @@ -1412,43 +1691,82 @@ escripts_to_apps([Escript | Escripts], Apps, OldApps, Status) -> {FileAcc, StatusAcc} end end, - try - case escript:foldl(Fun, {[], Status}, Escript) of - {ok, {Files, Status2}} -> - {Apps2, Status3} = files_to_apps(Escript, lists:sort(Files), Apps, Apps, OldApps, Status2), - escripts_to_apps(Escripts, Apps2, OldApps, Status3); - {error, Reason} -> - Text = lists:flatten(io_lib:format("~p", [Reason])), - {[], reltool_utils:return_first_error(Status, "Illegal escript " ++ Escript ++ ": " ++ Text)} - end - catch - throw:Reason2 when is_list(Reason2) -> - {[], reltool_utils:return_first_error(Status, "Illegal escript " ++ Escript ++ ": " ++ Reason2)} + case reltool_utils:escript_foldl(Fun, {[], Status}, Escript) of + {ok, {Files, Status2}} -> + {Apps2, Status3} = + files_to_apps(Escript, + lists:sort(Files), + Apps, + Apps, + OldApps, + Status2), + escripts_to_apps(Escripts, Apps2, OldApps, Status3); + {error, Reason} -> + Text = lists:flatten(io_lib:format("~p", [Reason])), + {[], reltool_utils:return_first_error(Status, + "Illegal escript " ++ + Escript ++ ": " ++ Text)} end; escripts_to_apps([], Apps, _OldApps, Status) -> {Apps, Status}. %% Assume that all files for an app are in consecutive order %% Assume the app info is before the mods -files_to_apps(Escript, [{AppName, Type, Dir, ModOrInfo} | Files] = AllFiles, Acc, Apps, OldApps, Status) -> +files_to_apps(Escript, + [{AppName, Type, Dir, ModOrInfo} | Files] = AllFiles, + Acc, + Apps, + OldApps, + Status) -> case Type of mod -> case Acc of [] -> Info = missing_app_info(""), - {NewApp, Status2} = merge_escript_app(AppName, Dir, Info, [ModOrInfo], Apps, OldApps, Status), - files_to_apps(Escript, AllFiles, [NewApp | Acc], Apps, OldApps, Status2); + {NewApp, Status2} = + merge_escript_app(AppName, + Dir, + Info, + [ModOrInfo], + Apps, + OldApps, + Status), + files_to_apps(Escript, + AllFiles, + [NewApp | Acc], + Apps, + OldApps, Status2); [App | Acc2] when App#app.name =:= ModOrInfo#mod.app_name -> App2 = App#app{mods = [ModOrInfo | App#app.mods]}, - files_to_apps(Escript, Files, [App2 | Acc2], Apps, OldApps, Status); + files_to_apps(Escript, + Files, + [App2 | Acc2], + Apps, + OldApps, + Status); [App | Acc2] -> - PrevApp = App#app{mods = lists:keysort(#mod.name, App#app.mods)}, + PrevApp = App#app{mods = lists:keysort(#mod.name, + App#app.mods)}, Info = missing_app_info(""), - {NewApp, Status2} = merge_escript_app(AppName, Dir, Info, [ModOrInfo], Apps, OldApps, Status), - files_to_apps(Escript, Files, [NewApp, PrevApp | Acc2], Apps, OldApps, Status2) + {NewApp, Status2} = + merge_escript_app(AppName, + Dir, + Info, + [ModOrInfo], + Apps, + OldApps, + Status), + files_to_apps(Escript, + Files, + [NewApp, PrevApp | Acc2], + Apps, + OldApps, + Status2) end; app -> - {App, Status2} = merge_escript_app(AppName, Dir, ModOrInfo, [], Apps, OldApps, Status), + {App, Status2} = + merge_escript_app(AppName, Dir, ModOrInfo, [], Apps, OldApps, + Status), files_to_apps(Escript, Files, [App | Acc], Apps, OldApps, Status2) end; files_to_apps(_Escript, [], Acc, _Apps, _OldApps, Status) -> @@ -1470,13 +1788,14 @@ merge_escript_app(AppName, Dir, Info, Mods, Apps, OldApps, Status) -> case lists:keysearch(AppName, #app.name, Apps) of {value, _} -> Error = lists:concat([AppName, ": Application name clash. ", - "Escript ", Dir," contains application ", AppName, "."]), + "Escript ", Dir," contains application ", + AppName, "."]), {App2, reltool_utils:return_first_error(Status, Error)}; false -> {App2, Status} end. -merge_app_dirs([{Name, Dir} | Rest], [App | Apps], OldApps) +merge_app_dirs([{Name, Dir} | Rest], [App | Apps], OldApps) when App#app.name =:= Name -> %% Add new dir to app App2 = App#app{sorted_dirs = [Dir | App#app.sorted_dirs]}, @@ -1491,10 +1810,11 @@ merge_app_dirs([{Name, Dir} | Rest], Apps, OldApps) -> {value, OldApp} when OldApp#app.active_dir =:= Dir -> [OldApp | Apps2]; {value, OldApp} -> - App = + App = case filter_app(OldApp) of {true, NewApp} -> - NewApp#app{active_dir = Dir, sorted_dirs = [Dir]}; + NewApp#app{active_dir = Dir, + sorted_dirs = [Dir]}; false -> default_app(Name, Dir) end, @@ -1545,12 +1865,14 @@ default_app(Name) -> status = missing, uses_mods = undefined, is_pre_included = undefined, - is_included = undefined}. + is_included = undefined, + rels = undefined}. -%% Assume that the application are sorted -refresh_apps([Old | OldApps], [New | NewApps], Acc, Force, Status) when New#app.name =:= Old#app.name -> +%% Assume that the application are sorted +refresh_apps([Old | OldApps], [New | NewApps], Acc, Force, Status) + when New#app.name =:= Old#app.name -> {Info, ActiveDir, Status2} = ensure_app_info(New, Status), - OptLabel = + OptLabel = case Info#app_info.vsn =:= New#app.vsn of true -> New#app.label; false -> undefined % Cause refresh @@ -1559,23 +1881,28 @@ refresh_apps([Old | OldApps], [New | NewApps], Acc, Force, Status) when New#app. refresh_app(New#app{label = OptLabel, active_dir = ActiveDir, vsn = Info#app_info.vsn, - info = Info}, + info = Info}, Force, Status2), refresh_apps(OldApps, NewApps, [Refreshed | Acc], Force, Status3); -refresh_apps([Old | OldApps], [New | NewApps], Acc, Force, Status) when New#app.name < Old#app.name -> +refresh_apps([Old | OldApps], [New | NewApps], Acc, Force, Status) + when New#app.name < Old#app.name -> %% No old app version exists. Use new as is. %% BUGBUG: Issue warning if the active_dir is not defined {New2, Status2} = refresh_app(New, Force, Status), refresh_apps([Old | OldApps], NewApps, [New2 | Acc], Force, Status2); -refresh_apps([Old | OldApps], [New | NewApps], Acc, Force, Status) when New#app.name > Old#app.name -> +refresh_apps([Old | OldApps], [New | NewApps], Acc, Force, Status) + when New#app.name > Old#app.name -> %% No new version. Remove the old. Status2 = - case Old#app.name =:= ?MISSING_APP of + case Old#app.name =:= ?MISSING_APP_NAME of true -> Status; false -> - Warning = lists:concat([Old#app.name, ": The source dirs does not contain the application anymore."]), + Warning = + lists:concat([Old#app.name, + ": The source dirs does not ", + "contain the application anymore."]), reltool_utils:add_warning(Status, Warning) end, refresh_apps(OldApps, [New | NewApps], Acc, Force, Status2); @@ -1586,25 +1913,32 @@ refresh_apps([], [New | NewApps], Acc, Force, Status) -> refresh_apps([Old | OldApps], [], Acc, Force, Status) -> %% No new version. Remove the old. Status2 = - case Old#app.name =:= ?MISSING_APP of + case Old#app.name =:= ?MISSING_APP_NAME of true -> Status; false -> - Warning = lists:concat([Old#app.name, ": The source dirs ", - "does not contain the application anymore."]), + Warning = + lists:concat([Old#app.name, + ": The source dirs does not " + "contain the application anymore."]), reltool_utils:add_warning(Status, Warning) end, refresh_apps(OldApps, [], Acc, Force, Status2); refresh_apps([], [], Acc, _Force, Status) -> {lists:reverse(Acc), Status}. -ensure_app_info(#app{is_escript = true, active_dir = Dir, info = Info}, Status) -> +ensure_app_info(#app{is_escript = true, active_dir = Dir, info = Info}, + Status) -> {Info, Dir, Status}; ensure_app_info(#app{name = Name, sorted_dirs = []}, Status) -> Error = lists:concat([Name, ": Missing application directory."]), Status2 = reltool_utils:return_first_error(Status, Error), {missing_app_info(""), undefined, Status2}; -ensure_app_info(#app{name = Name, vsn = Vsn, sorted_dirs = Dirs, info = undefined}, Status) -> +ensure_app_info(#app{name = Name, + vsn = Vsn, + sorted_dirs = Dirs, + info = undefined}, + Status) -> ReadInfo = fun(Dir, StatusAcc) -> Base = get_base(Name, Dir), @@ -1621,8 +1955,10 @@ ensure_app_info(#app{name = Name, vsn = Vsn, sorted_dirs = Dirs, info = undefine %% No redundant info Status2; [BadVsn | _] -> - Error2 = lists:concat([Name, ": Application version clash. ", - "Multiple directories contains version \"", BadVsn, "\"."]), + Error2 = + lists:concat([Name, ": Application version clash. ", + "Multiple directories contains version \"", + BadVsn, "\"."]), reltool_utils:return_first_error(Status2, Error2) end, FirstInfo = hd(AllInfo), @@ -1637,7 +1973,11 @@ ensure_app_info(#app{name = Name, vsn = Vsn, sorted_dirs = Dirs, info = undefine {Info, VsnDir} -> {Info, VsnDir, Status3}; false -> - Error3 = lists:concat([Name, ": No application directory contains selected version \"", Vsn, "\"."]), + Error3 = + lists:concat([Name, + ": No application directory contains ", + "selected version \"", + Vsn, "\"."]), Status4 = reltool_utils:return_first_error(Status3, Error3), {FirstInfo, FirstDir, Status4} end diff --git a/lib/reltool/src/reltool_sys_win.erl b/lib/reltool/src/reltool_sys_win.erl index ea80ab7e85..dbb8e32aa2 100644 --- a/lib/reltool/src/reltool_sys_win.erl +++ b/lib/reltool/src/reltool_sys_win.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009. All Rights Reserved. -%% +%% +%% 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% -module(reltool_sys_win). @@ -34,7 +34,7 @@ -include_lib("wx/include/wx.hrl"). -include("reltool.hrl"). --record(state, +-record(state, {parent_pid, server_pid, app_wins, @@ -61,7 +61,7 @@ -define(WIN_HEIGHT, 600). -define(CLOSE_ITEM, ?wxID_EXIT). %% Use OS specific version if available --define(ABOUT_ITEM, ?wxID_ABOUT). %% Use OS specific +-define(ABOUT_ITEM, ?wxID_ABOUT). %% Use OS specific -define(CONTENTS_ITEM, 300). -define(APP_GRAPH_ITEM, 301). -define(MOD_GRAPH_ITEM, 302). @@ -100,7 +100,11 @@ %% Client start_link(Opts) -> - proc_lib:start_link(?MODULE, init, [[{parent, self()} | Opts]], infinity, []). + proc_lib:start_link(?MODULE, + init, + [[{parent, self()} | Opts]], + infinity, + []). get_server(Pid) -> reltool_utils:call(Pid, get_server). @@ -146,9 +150,13 @@ do_init([{parent, Parent} | Options]) -> S3 = S2#state{sys = Sys2}, S5 = wx:batch(fun() -> Title = atom_to_list(?APPLICATION), - wxFrame:setTitle(S3#state.frame, Title), - %% wxFrame:setMinSize(Frame, {?WIN_WIDTH, ?WIN_HEIGHT}), - wxStatusBar:setStatusText(S3#state.status_bar, "Done."), + wxFrame:setTitle(S3#state.frame, + Title), + %% wxFrame:setMinSize(Frame, + %% {?WIN_WIDTH, ?WIN_HEIGHT}), + wxStatusBar:setStatusText( + S3#state.status_bar, + "Done."), S4 = redraw_apps(S3), redraw_libs(S4) end), @@ -182,7 +190,12 @@ loop(S) -> receive {system, From, Msg} -> Common = S#state.common, - sys:handle_system_msg(Msg, From, S#state.parent_pid, ?MODULE, Common#common.sys_debug, S); + sys:handle_system_msg(Msg, + From, + S#state.parent_pid, + ?MODULE, + Common#common.sys_debug, + S); #wx{obj = ObjRef, event = #wxClose{type = close_window}} = Msg -> if @@ -193,17 +206,22 @@ loop(S) -> FWs = S#state.fgraph_wins, case lists:keysearch(ObjRef, #fgraph_win.frame, FWs) of {value, FW} -> - reltool_fgraph_win:stop(FW#fgraph_win.pid, shutdown), + reltool_fgraph_win:stop(FW#fgraph_win.pid, + shutdown), wxFrame:destroy(ObjRef), - FWs2 = lists:keydelete(ObjRef, #fgraph_win.frame, FWs), + FWs2 = + lists:keydelete(ObjRef, #fgraph_win.frame, FWs), ?MODULE:loop(S#state{fgraph_wins = FWs2}); false -> - error_logger:format("~p~p got unexpected message:\n\t~p\n", - [?MODULE, self(), Msg]), + error_logger:format("~p~p got unexpected " + "message:\n\t~p\n", + [?MODULE, self(), Msg]), ?MODULE:loop(S) end end; - #wx{id = ?CLOSE_ITEM, event = #wxCommand{type = command_menu_selected}, userData = main_window} -> + #wx{id = ?CLOSE_ITEM, + event = #wxCommand{type = command_menu_selected}, + userData = main_window} -> wxFrame:destroy(S#state.frame), exit(shutdown); #wx{event = #wxSize{}} = Wx -> @@ -222,14 +240,18 @@ loop(S) -> ?MODULE:loop(S2); {call, ReplyTo, Ref, {open_app, AppName}} -> S2 = do_open_app(S, AppName), - {value, #app_win{pid = AppPid}} = lists:keysearch(AppName, #app_win.name, S2#state.app_wins), + {value, #app_win{pid = AppPid}} = + lists:keysearch(AppName, #app_win.name, S2#state.app_wins), reltool_utils:reply(ReplyTo, Ref, {ok, AppPid}), ?MODULE:loop(S2); {'EXIT', Pid, Reason} when Pid =:= S#state.parent_pid -> - [reltool_fgraph_win:stop(FW#fgraph_win.pid, Reason) || FW <- S#state.fgraph_wins], + [reltool_fgraph_win:stop(FW#fgraph_win.pid, Reason) || + FW <- S#state.fgraph_wins], exit(Reason); {'EXIT', _Pid, _Reason} = Exit -> - {FWs, AWs} = handle_child_exit(Exit, S#state.fgraph_wins, S#state.app_wins), + {FWs, AWs} = handle_child_exit(Exit, + S#state.fgraph_wins, + S#state.app_wins), ?MODULE:loop(S#state{fgraph_wins = FWs, app_wins = AWs}); Msg -> error_logger:format("~p~p got unexpected message:\n\t~p\n", @@ -261,7 +283,8 @@ msg_warning(Exit, Type) -> create_window(S) -> Title = lists:concat([?APPLICATION, " - starting up"]), - Frame = wxFrame:new(wx:null(), ?wxID_ANY, Title, [{size, {?WIN_WIDTH, ?WIN_HEIGHT}}]), + Frame = wxFrame:new(wx:null(), ?wxID_ANY, Title, + [{size, {?WIN_WIDTH, ?WIN_HEIGHT}}]), %%wxFrame:setSize(Frame, {?WIN_WIDTH, ?WIN_HEIGHT}), %% wxFrame:setMinSize(Frame, {?WIN_WIDTH, ?WIN_HEIGHT}), Bar = wxFrame:createStatusBar(Frame,[]), @@ -306,21 +329,29 @@ create_menubar(Frame) -> File = wxMenu:new([]), Help = wxMenu:new([]), wxMenuBar:append(MenuBar, File, "File" ), - wxMenu:append(File, ?APP_GRAPH_ITEM, "Display application dependency graph" ), - wxMenu:append(File, ?MOD_GRAPH_ITEM, "Display module dependency graph" ), + wxMenu:append(File, ?APP_GRAPH_ITEM, + "Display application dependency graph" ), + wxMenu:append(File, ?MOD_GRAPH_ITEM, + "Display module dependency graph" ), wxMenu:appendSeparator(File), wxMenu:append(File, ?RESET_CONFIG_ITEM, "Reset configuration to default" ), wxMenu:append(File, ?UNDO_CONFIG_ITEM, "Undo configuration (toggle)" ), wxMenu:append(File, ?LOAD_CONFIG_ITEM, "Load configuration" ), Save = wxMenu:new(), - wxMenu:append(Save, ?SAVE_CONFIG_NODEF_NODER_ITEM, "Save explicit configuration (neither defaults nor derivates)"), - wxMenu:append(Save, ?SAVE_CONFIG_DEF_NODER_ITEM , "Save configuration defaults (defaults only)"), - wxMenu:append(Save, ?SAVE_CONFIG_NODEF_DER_ITEM, "Save configuration derivates (derivates only))"), - wxMenu:append(Save, ?SAVE_CONFIG_DEF_DER_ITEM, "Save extended configuration (both defaults and derivates)"), + wxMenu:append(Save, ?SAVE_CONFIG_NODEF_NODER_ITEM, + "Save explicit configuration " + "(neither defaults nor derivates)"), + wxMenu:append(Save, ?SAVE_CONFIG_DEF_NODER_ITEM, + "Save configuration defaults (defaults only)"), + wxMenu:append(Save, ?SAVE_CONFIG_NODEF_DER_ITEM, + "Save configuration derivates (derivates only))"), + wxMenu:append(Save, ?SAVE_CONFIG_DEF_DER_ITEM, + "Save extended configuration (both defaults and derivates)"), wxMenu:append(File, ?wxID_ANY, "Save configuration", Save), wxMenu:appendSeparator(File), - wxMenu:append(File, ?GEN_REL_FILES_ITEM, "Generate rel, script and boot files" ), + wxMenu:append(File, ?GEN_REL_FILES_ITEM, + "Generate rel, script and boot files" ), wxMenu:append(File, ?GEN_TARGET_ITEM, "Generate target system" ), wxMenu:appendSeparator(File), wxMenu:append(File, ?CLOSE_ITEM, "Close" ), @@ -375,12 +406,13 @@ create_app_list_ctrl(Panel, OuterSz, Title, Tick, Cross) -> %% ?wxLC_SINGLE_SEL bor ?wxVSCROLL}, {size, {Width, Height}}]), - ToolTip = "Select application(s) or open separate application window with a double click.", + ToolTip = "Select application(s) or open separate " + "application window with a double click.", wxListCtrl:setToolTip(ListCtrl, ToolTip), %% Prep images reltool_utils:assign_image_list(ListCtrl), - + %% Prep column label ListItem = wxListItem:new(), wxListItem:setAlign(ListItem, ?wxLIST_FORMAT_LEFT), @@ -395,7 +427,7 @@ create_app_list_ctrl(Panel, OuterSz, Title, Tick, Cross) -> InnerSz = wxBoxSizer:new(?wxVERTICAL), - wxSizer:add(InnerSz, + wxSizer:add(InnerSz, ListCtrl, [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}, @@ -408,9 +440,10 @@ create_app_list_ctrl(Panel, OuterSz, Title, Tick, Cross) -> [{flag, ?wxEXPAND}, {proportion, 1}]), %% Subscribe on events - wxEvtHandler:connect(ListCtrl, size, [{skip, true}, {userData, app_list_ctrl}]), + wxEvtHandler:connect(ListCtrl, size, + [{skip, true}, {userData, app_list_ctrl}]), wxEvtHandler:connect(ListCtrl, command_list_item_activated), - wxWindow:connect(ListCtrl, enter_window), + wxWindow:connect(ListCtrl, enter_window), ListCtrl. @@ -423,7 +456,7 @@ create_button(Panel, Sizer, ListCtrl, Title, BitMapName, Action) -> wxBitmapButton:setToolTip(Button, ToolTip), Options = [{userData, {app_button, Action, ListCtrl}}], wxEvtHandler:connect(Button, command_button_clicked, Options), - wxSizer:add(Sizer, + wxSizer:add(Sizer, Button, [{border, 2}, {flag, ?wxALL}, @@ -439,7 +472,7 @@ action_to_tool_tip(Label, Action) -> "Remove selected application(s)from whitelist."; blacklist_add when Label =:= ?blacklist -> "Remove selected application(s) from blacklist."; - blacklist_add -> + blacklist_add -> "Add selected application(s) to blacklist."; blacklist_del -> "Remove selected application(s) from blacklist." @@ -448,8 +481,9 @@ action_to_tool_tip(Label, Action) -> create_lib_page(#state{book = Book} = S) -> Panel = wxPanel:new(Book, []), Sizer = wxBoxSizer:new(?wxHORIZONTAL), - - Tree = wxTreeCtrl:new(Panel, [{style , ?wxTR_HAS_BUTTONS bor ?wxTR_HIDE_ROOT}]), + + Tree = wxTreeCtrl:new(Panel, + [{style , ?wxTR_HAS_BUTTONS bor ?wxTR_HIDE_ROOT}]), ToolTip = "Edit application sources.", wxBitmapButton:setToolTip(Tree, ToolTip), @@ -478,7 +512,9 @@ redraw_libs(#state{lib_tree = Tree, sys = Sys} = S) -> [append_lib(Tree, LibItem, Dir) || Dir <- Sys#sys.lib_dirs], EscriptItem = append_item(Tree, Top, "Escript files", undefined), - EscriptData = #escript_data{file = undefined, tree = Tree, item = EscriptItem}, + EscriptData = #escript_data{file = undefined, + tree = Tree, + item = EscriptItem}, wxTreeCtrl:setItemData(Tree,EscriptItem, EscriptData), [append_escript(Tree, EscriptItem, File) || File <- Sys#sys.escripts], wxTreeCtrl:expand(Tree, LibItem), @@ -529,9 +565,9 @@ create_config_page(#state{sys = Sys, book = Book} = S) -> Panel = wxPanel:new(Book, []), Sizer = wxBoxSizer:new(?wxHORIZONTAL), AppConds = reltool_utils:incl_conds(), - AppBox = wxRadioBox:new(Panel, + AppBox = wxRadioBox:new(Panel, ?wxID_ANY, - "Application inclusion policy", + "Application inclusion policy", ?wxDefaultPosition, ?wxDefaultSize, AppConds, @@ -543,9 +579,9 @@ create_config_page(#state{sys = Sys, book = Book} = S) -> wxEvtHandler:connect(AppBox, command_radiobox_selected, [{userData, config_incl_cond}]), ModConds = reltool_utils:mod_conds(), - ModBox = wxRadioBox:new(Panel, + ModBox = wxRadioBox:new(Panel, ?wxID_ANY, - "Module inclusion policy", + "Module inclusion policy", ?wxDefaultPosition, ?wxDefaultSize, ModConds, @@ -582,19 +618,19 @@ create_main_release_page(#state{book = Book} = S) -> wxButton:setToolTip(Create, "Create a new release."), wxButton:connect(Create, command_button_clicked, [{userData, create_rel}]), wxSizer:add(ButtonSizer, Create), - + Delete = wxButton:new(Panel, ?wxID_ANY, [{label, "Delete"}]), wxButton:setToolTip(Delete, "Delete a release."), wxButton:connect(Delete, command_button_clicked, [{userData, delete_rel}]), wxSizer:add(ButtonSizer, Delete), - + View = wxButton:new(Panel, ?wxID_ANY, [{label, "View script"}]), wxButton:setToolTip(View, "View generated script file."), wxButton:connect(View, command_button_clicked, [{userData, view_script}]), wxSizer:add(ButtonSizer, View), [add_release_page(RelBook, Rel) || Rel <- (S#state.sys)#sys.rels], - + wxSizer:add(Sizer, RelBook, [{flag, ?wxEXPAND}, {proportion, 1}]), wxSizer:add(Sizer, ButtonSizer, [{flag, ?wxEXPAND}]), wxPanel:setSizer(Panel, Sizer), @@ -604,16 +640,18 @@ create_main_release_page(#state{book = Book} = S) -> add_release_page(Book, #rel{name = RelName, rel_apps = RelApps}) -> Panel = wxPanel:new(Book, []), Sizer = wxBoxSizer:new(?wxHORIZONTAL), - RelBox = wxRadioBox:new(Panel, + RelBox = wxRadioBox:new(Panel, ?wxID_ANY, - "Applications included in the release " ++ RelName, + "Applications included in the release " ++ RelName, ?wxDefaultPosition, ?wxDefaultSize, [atom_to_list(RA#rel_app.name) || RA <- RelApps], []), %% wxRadioBox:setSelection(RelBox, 2), % mandatory - wxEvtHandler:connect(RelBox, command_radiobox_selected, [{userData, {config_rel_cond, RelName}}]), - RelToolTip = "Choose which applications that shall be included in the release resource file.", + wxEvtHandler:connect(RelBox, command_radiobox_selected, + [{userData, {config_rel_cond, RelName}}]), + RelToolTip = "Choose which applications that shall " + "be included in the release resource file.", wxBitmapButton:setToolTip(RelBox, RelToolTip), wxSizer:add(Sizer, @@ -629,11 +667,14 @@ do_open_app(S, AppBase) when is_list(AppBase) -> do_open_app(S, AppName); do_open_app(S, '') -> S; -do_open_app(#state{server_pid = ServerPid, common = C, app_wins = AppWins} = S, AppName) when is_atom(AppName) -> +do_open_app(#state{server_pid = ServerPid, common = C, app_wins = AppWins} = S, + AppName) + when is_atom(AppName) -> case lists:keysearch(AppName, #app_win.name, AppWins) of false -> WxEnv = wx:get_env(), - {ok, Pid} = reltool_app_win:start_link(WxEnv, ServerPid, C, AppName), + {ok, Pid} = + reltool_app_win:start_link(WxEnv, ServerPid, C, AppName), AW = #app_win{name = AppName, pid = Pid}, S#state{app_wins = [AW | AppWins]}; {value, AW} -> @@ -651,7 +692,10 @@ root_popup(S, Root, Tree, Item) -> wxEvtHandler:connect(PopupMenu, menu_close), wxWindow:popupMenu(S#state.frame, PopupMenu), - Popup = #root_popup{dir = Root, choices = Choices, tree = Tree, item = Item}, + Popup = #root_popup{dir = Root, + choices = Choices, + tree = Tree, + item = Item}, S#state{popup_menu = Popup}. lib_popup(S, Lib, Tree, Item) -> @@ -693,7 +737,10 @@ escript_popup(S, File, Tree, Item) -> wxEvtHandler:connect(PopupMenu, menu_close), wxWindow:popupMenu(S#state.frame, PopupMenu), - Popup = #escript_popup{file = File, choices = Choices, tree = Tree, item = Item}, + Popup = #escript_popup{file = File, + choices = Choices, + tree = Tree, + item = Item}, S#state{popup_menu = Popup}. @@ -705,29 +752,40 @@ handle_event(S, #wx{id = Id, obj= ObjRef, userData = UserData, event = Event} = #wxSize{type = size, size = {W, _H}} when UserData =:= app_list_ctrl -> wxListCtrl:setColumnWidth(ObjRef, ?APPS_APP_COL, W), S; - #wxCommand{type = command_menu_selected} when Id =:= ?APP_GRAPH_ITEM -> + #wxCommand{type = command_menu_selected} + when Id =:= ?APP_GRAPH_ITEM -> update_app_graph(S); - #wxCommand{type = command_menu_selected} when Id =:= ?MOD_GRAPH_ITEM -> + #wxCommand{type = command_menu_selected} + when Id =:= ?MOD_GRAPH_ITEM -> update_mod_graph(S); - #wxCommand{type = command_menu_selected} when Id =:= ?RESET_CONFIG_ITEM -> + #wxCommand{type = command_menu_selected} + when Id =:= ?RESET_CONFIG_ITEM -> reset_config(S); - #wxCommand{type = command_menu_selected} when Id =:= ?UNDO_CONFIG_ITEM -> + #wxCommand{type = command_menu_selected} + when Id =:= ?UNDO_CONFIG_ITEM -> undo_config(S); - #wxCommand{type = command_menu_selected} when Id =:= ?LOAD_CONFIG_ITEM -> + #wxCommand{type = command_menu_selected} + when Id =:= ?LOAD_CONFIG_ITEM -> load_config(S); - #wxCommand{type = command_menu_selected} when Id =:= ?SAVE_CONFIG_NODEF_NODER_ITEM -> + #wxCommand{type = command_menu_selected} + when Id =:= ?SAVE_CONFIG_NODEF_NODER_ITEM -> save_config(S, false, false); - #wxCommand{type = command_menu_selected} when Id =:= ?SAVE_CONFIG_NODEF_DER_ITEM -> + #wxCommand{type = command_menu_selected} + when Id =:= ?SAVE_CONFIG_NODEF_DER_ITEM -> save_config(S, false, true); #wxCommand{type = command_menu_selected} when Id =:= ?SAVE_CONFIG_DEF_NODER_ITEM -> save_config(S, true, false); - #wxCommand{type = command_menu_selected} when Id =:= ?SAVE_CONFIG_DEF_DER_ITEM -> + #wxCommand{type = command_menu_selected} + when Id =:= ?SAVE_CONFIG_DEF_DER_ITEM -> save_config(S, true, true); - #wxCommand{type = command_menu_selected} when Id =:= ?GEN_REL_FILES_ITEM -> + #wxCommand{type = command_menu_selected} + when Id =:= ?GEN_REL_FILES_ITEM -> gen_rel_files(S); - #wxCommand{type = command_menu_selected} when Id =:= ?GEN_TARGET_ITEM -> + #wxCommand{type = command_menu_selected} + when Id =:= ?GEN_TARGET_ITEM -> gen_target(S); - #wxCommand{type = command_menu_selected} when UserData =:= main_window, Id =:= ?CONTENTS_ITEM -> + #wxCommand{type = command_menu_selected} + when UserData =:= main_window, Id =:= ?CONTENTS_ITEM -> {file, BeamFile} = code:is_loaded(?MODULE), EbinDir = filename:dirname(BeamFile), AppDir = filename:dirname(EbinDir), @@ -735,16 +793,17 @@ handle_event(S, #wx{id = Id, obj= ObjRef, userData = UserData, event = Event} = Url = "file://" ++ filename:absname(HelpFile), wx_misc:launchDefaultBrowser(Url), S; - #wxCommand{type = command_menu_selected} when UserData =:= main_window, Id =:= ?ABOUT_ITEM -> - AboutStr = "Reltool is a release management tool. It analyses a given" - " Erlang/OTP installation and determines various dependencies" - " between applications. The graphical frontend depicts the" - " dependencies and enables interactive customization of a" - " target system. The backend provides a batch interface" - " for generation of customized target systems.", - MD = wxMessageDialog:new(S#state.frame, + #wxCommand{type = command_menu_selected} + when UserData =:= main_window, Id =:= ?ABOUT_ITEM -> + AboutStr = "Reltool is a release management tool. It analyses a " + " given Erlang/OTP installation and determines various " + " dependencies between applications. The graphical frontend " + " depicts the dependencies and enables interactive " + " customization of a target system. The backend provides a " + " batch interface for generation of customized target systems.", + MD = wxMessageDialog:new(S#state.frame, AboutStr, - [{style, ?wxOK bor ?wxICON_INFORMATION}, + [{style, ?wxOK bor ?wxICON_INFORMATION}, {caption, "About Reltool"}]), wxMessageDialog:showModal(MD), wxMessageDialog:destroy(MD), @@ -758,7 +817,8 @@ handle_event(S, #wx{id = Id, obj= ObjRef, userData = UserData, event = Event} = wxWindow:setFocus(ObjRef), S; _ -> - case wxNotebook:getPageText(S#state.book, wxNotebook:getSelection(S#state.book)) of + case wxNotebook:getPageText(S#state.book, + wxNotebook:getSelection(S#state.book)) of ?APP_PAGE -> handle_app_event(S, Event, ObjRef, UserData); ?LIB_PAGE -> handle_source_event(S, Event, ObjRef, UserData); ?SYS_PAGE -> handle_system_event(S, Event, ObjRef, UserData); @@ -768,13 +828,17 @@ handle_event(S, #wx{id = Id, obj= ObjRef, userData = UserData, event = Event} = handle_popup_event(S, _Type, 0, _ObjRef, _UserData, _Str) -> S#state{popup_menu = undefined}; -handle_popup_event(#state{popup_menu = #root_popup{dir = OldDir, choices = Choices}, +handle_popup_event(#state{popup_menu = #root_popup{dir = OldDir, + choices = Choices}, sys = Sys} = S, _Type, Pos, _ObjRef, _UserData, _Str) -> case lists:nth(Pos, Choices) of edit -> Style = ?wxFD_OPEN bor ?wxFD_FILE_MUST_EXIST, - case select_dir(S#state.frame, "Change root directory", OldDir, Style) of + case select_dir(S#state.frame, + "Change root directory", + OldDir, + Style) of {ok, NewDir} when NewDir =:= OldDir -> %% Same dir.Ignore. S#state{popup_menu = undefined}; @@ -785,7 +849,8 @@ handle_popup_event(#state{popup_menu = #root_popup{dir = OldDir, choices = Choic S#state{popup_menu = undefined} end end; -handle_popup_event(#state{popup_menu = #lib_popup{dir = OldDir, choices = Choices}, +handle_popup_event(#state{popup_menu = #lib_popup{dir = OldDir, + choices = Choices}, sys = Sys} = S, _Type, Pos, _ObjRef, _UserData, _Str) -> case lists:nth(Pos, Choices) of @@ -801,14 +866,18 @@ handle_popup_event(#state{popup_menu = #lib_popup{dir = OldDir, choices = Choice false -> LibDirs = Sys#sys.lib_dirs ++ [NewDir], Sys2 = Sys#sys{lib_dirs = LibDirs}, - do_set_sys(S#state{popup_menu = undefined, sys = Sys2}) + do_set_sys(S#state{popup_menu = undefined, + sys = Sys2}) end; cancel -> S#state{popup_menu = undefined} end; edit -> Style = ?wxFD_OPEN bor ?wxFD_FILE_MUST_EXIST, - case select_dir(S#state.frame, "Change library directory", OldDir, Style) of + case select_dir(S#state.frame, + "Change library directory", + OldDir, + Style) of {ok, NewDir} -> case lists:member(NewDir, Sys#sys.lib_dirs) of true -> @@ -820,7 +889,8 @@ handle_popup_event(#state{popup_menu = #lib_popup{dir = OldDir, choices = Choice lists:splitwith(Pred, Sys#sys.lib_dirs), LibDirs2 = Before ++ [NewDir | After], Sys2 = Sys#sys{lib_dirs = LibDirs2}, - do_set_sys(S#state{popup_menu = undefined, sys = Sys2}) + do_set_sys(S#state{popup_menu = undefined, + sys = Sys2}) end; cancel -> S#state{popup_menu = undefined} @@ -828,14 +898,15 @@ handle_popup_event(#state{popup_menu = #lib_popup{dir = OldDir, choices = Choice delete -> LibDirs = Sys#sys.lib_dirs -- [OldDir], Sys2 = Sys#sys{lib_dirs = LibDirs}, - do_set_sys(S#state{popup_menu = undefined, sys = Sys2}) + do_set_sys(S#state{popup_menu = undefined, sys = Sys2}) end; -handle_popup_event(#state{popup_menu = #escript_popup{file = OldFile, choices = Choices}, +handle_popup_event(#state{popup_menu = #escript_popup{file = OldFile, + choices = Choices}, sys = Sys} = S, _Type, Pos, _ObjRef, _UserData, _Str) -> case lists:nth(Pos, Choices) of add -> - OldFile2 = + OldFile2 = case OldFile of undefined -> {ok, Cwd} = file:get_cwd(), @@ -844,7 +915,10 @@ handle_popup_event(#state{popup_menu = #escript_popup{file = OldFile, choices = OldFile end, Style = ?wxFD_OPEN bor ?wxFD_FILE_MUST_EXIST, - case select_file(S#state.frame, "Select an escript file to add", OldFile2, Style) of + case select_file(S#state.frame, + "Select an escript file to add", + OldFile2, + Style) of {ok, NewFile} -> case lists:member(NewFile, Sys#sys.escripts) of true -> @@ -860,7 +934,10 @@ handle_popup_event(#state{popup_menu = #escript_popup{file = OldFile, choices = end; edit -> Style = ?wxFD_OPEN bor ?wxFD_FILE_MUST_EXIST, - case select_file(S#state.frame, "Change escript file name", OldFile, Style) of + case select_file(S#state.frame, + "Change escript file name", + OldFile, + Style) of {ok, NewFile} -> case lists:member(NewFile, Sys#sys.escripts) of true -> @@ -868,10 +945,12 @@ handle_popup_event(#state{popup_menu = #escript_popup{file = OldFile, choices = S#state{popup_menu = undefined}; false -> Pred = fun(E) -> E =/= OldFile end, - {Before, [_| After]} = lists:splitwith(Pred, Sys#sys.escripts), + {Before, [_| After]} = + lists:splitwith(Pred, Sys#sys.escripts), Escripts2 = Before ++ [NewFile | After], Sys2 = Sys#sys{escripts = Escripts2}, - do_set_sys(S#state{popup_menu = undefined, sys = Sys2}) + do_set_sys(S#state{popup_menu = undefined, + sys = Sys2}) end; cancel -> S#state{popup_menu = undefined} @@ -879,25 +958,28 @@ handle_popup_event(#state{popup_menu = #escript_popup{file = OldFile, choices = delete -> Escripts = Sys#sys.escripts -- [OldFile], Sys2 = Sys#sys{escripts = Escripts}, - do_set_sys(S#state{popup_menu = undefined, sys = Sys2}) + do_set_sys(S#state{popup_menu = undefined, sys = Sys2}) end. handle_system_event(#state{sys = Sys} = S, - #wxCommand{type = command_radiobox_selected, cmdString = Choice}, + #wxCommand{type = command_radiobox_selected, + cmdString = Choice}, _ObjRef, config_mod_cond) -> ModCond = reltool_utils:list_to_mod_cond(Choice), Sys2 = Sys#sys{mod_cond = ModCond}, do_set_sys(S#state{sys = Sys2}); handle_system_event(#state{sys = Sys} = S, - #wxCommand{type = command_radiobox_selected, cmdString = Choice}, + #wxCommand{type = command_radiobox_selected, + cmdString = Choice}, _ObjRef, config_incl_cond) -> AppCond = reltool_utils:list_to_incl_cond(Choice), Sys2 = Sys#sys{incl_cond = AppCond}, do_set_sys(S#state{sys = Sys2}); handle_system_event(S, Event, ObjRef, UserData) -> - error_logger:format("~p~p got unexpected wx sys event to ~p with user data: ~p\n\t ~p\n", + error_logger:format("~p~p got unexpected wx sys event to ~p " + "with user data: ~p\n\t ~p\n", [?MODULE, self(), ObjRef, UserData, Event]), S. @@ -905,7 +987,11 @@ handle_release_event(S, _Event, _ObjRef, UserData) -> io:format("Release data: ~p\n", [UserData]), S. -handle_source_event(S, #wxTree{type = command_tree_item_activated, item = Item}, ObjRef, _UserData) -> +handle_source_event(S, + #wxTree{type = command_tree_item_activated, + item = Item}, + ObjRef, + _UserData) -> case wxTreeCtrl:getItemData(ObjRef, Item) of #root_data{dir = _Dir} -> %% io:format("Root dialog: ~p\n", [Dir]), @@ -921,7 +1007,11 @@ handle_source_event(S, #wxTree{type = command_tree_item_activated, item = Item}, undefined -> S end; -handle_source_event(S, #wxTree{type = command_tree_item_right_click, item = Item}, Tree, _UserData) -> +handle_source_event(S, + #wxTree{type = command_tree_item_right_click, + item = Item}, + Tree, + _UserData) -> case wxTreeCtrl:getItemData(Tree, Item) of #root_data{dir = Dir} -> wx:batch(fun() -> root_popup(S, Dir, Tree, Item) end); @@ -936,18 +1026,28 @@ handle_source_event(S, #wxTree{type = command_tree_item_right_click, item = Item S end. -handle_app_event(S, #wxList{type = command_list_item_activated, itemIndex = Pos}, ListCtrl, _UserData) -> +handle_app_event(S, + #wxList{type = command_list_item_activated, + itemIndex = Pos}, + ListCtrl, + _UserData) -> AppName = wxListCtrl:getItemText(ListCtrl, Pos), do_open_app(S, AppName); -handle_app_event(S, #wxCommand{type = command_button_clicked}, _ObjRef, {app_button, Action, ListCtrl}) -> +handle_app_event(S, + #wxCommand{type = command_button_clicked}, + _ObjRef, + {app_button, Action, ListCtrl}) -> Items = reltool_utils:get_items(ListCtrl), handle_app_button(S, Items, Action); handle_app_event(S, Event, ObjRef, UserData) -> - error_logger:format("~p~p got unexpected wx app event to ~p with user data: ~p\n\t ~p\n", + error_logger:format("~p~p got unexpected wx app event to " + "~p with user data: ~p\n\t ~p\n", [?MODULE, self(), ObjRef, UserData, Event]), S. -handle_app_button(#state{server_pid = ServerPid, app_wins = AppWins} = S, Items, Action) -> +handle_app_button(#state{server_pid = ServerPid, app_wins = AppWins} = S, + Items, + Action) -> NewApps = [move_app(S, Item, Action) || Item <- Items], case reltool_server:set_apps(ServerPid, NewApps) of {ok, []} -> @@ -967,9 +1067,9 @@ do_set_sys(#state{sys = Sys, server_pid = ServerPid, status_bar = Bar} = S) -> check_and_refresh(S, Status). move_app(S, {_ItemNo, AppBase}, Action) -> - {AppName, _Vsn} = reltool_utils:split_app_name(AppBase), + {AppName, _Vsn} = reltool_utils:split_app_name(AppBase), {ok, OldApp} = reltool_server:get_app(S#state.server_pid, AppName), - AppCond = + AppCond = case Action of whitelist_add -> case OldApp#app.incl_cond of @@ -979,12 +1079,13 @@ move_app(S, {_ItemNo, AppBase}, Action) -> end; whitelist_del -> undefined; - blacklist_add -> + blacklist_add -> exclude; blacklist_del -> undefined; _ -> - error_logger:format("~p~p got unexpected app button event: ~p ~p\n", + error_logger:format("~p~p got unexpected app " + "button event: ~p ~p\n", [?MODULE, self(), Action, AppBase]), OldApp#app.incl_cond end, @@ -1047,14 +1148,21 @@ do_redraw_apps(ListCtrl, Apps, OkImage, ErrImage) -> ImageApps = lists:map(AddImage, Apps), Show = fun({ImageId, Text, App}, {Row, ModCount, Items}) -> - wxListCtrl:insertItem(ListCtrl, Row, ""), - if (Row rem 2) =:= 0 -> - wxListCtrl:setItemBackgroundColour(ListCtrl, Row, {240,240,255}); + wxListCtrl:insertItem(ListCtrl, Row, ""), + if (Row rem 2) =:= 0 -> + wxListCtrl:setItemBackgroundColour(ListCtrl, + Row, + {240,240,255}); true -> ignore end, - wxListCtrl:setItem(ListCtrl, Row, ?APPS_APP_COL, Text, [{imageId, ImageId}]), - N = length([M || M <- App#app.mods, M#mod.is_included =:= true]), + wxListCtrl:setItem(ListCtrl, + Row, + ?APPS_APP_COL, + Text, + [{imageId, ImageId}]), + N = length([M || M <- App#app.mods, + M#mod.is_included =:= true]), {Row + 1, ModCount + N, [{Row, Text} | Items]} end, {_, N, NewItems} = wx:foldl(Show, {0, 0, []}, lists:sort(ImageApps)), @@ -1068,8 +1176,10 @@ update_app_graph(S) -> WhiteNames = [A#app.name || A <- WhiteApps], DerivedNames = [A#app.name || A <- DerivedApps], Nodes = WhiteNames ++ DerivedNames, - %% WhiteUses = [N || A <- WhiteApps, N <- A#app.uses_apps, lists:member(N, Nodes)], - %% DerivedUses = [N || A <- DerivedApps, N <- A#app.uses_apps, lists:member(N, Nodes)], + %% WhiteUses = [N || A <- WhiteApps, + %% N <- A#app.uses_apps, lists:member(N, Nodes)], + %% DerivedUses = [N || A <- DerivedApps, + %% N <- A#app.uses_apps, lists:member(N, Nodes)], WhiteLinks = [[A#app.name, U] || A <- WhiteApps, U <- A#app.uses_apps, @@ -1078,7 +1188,7 @@ update_app_graph(S) -> DerivedLinks = [[A#app.name, U] || A <- DerivedApps, U <- A#app.uses_apps, U =/= A#app.name, - lists:member(U, Nodes)], + lists:member(U, Nodes)], Links = lists:usort(WhiteLinks ++ DerivedLinks), %% io:format("Links: ~p\n", [Links]), Title = lists:concat([?APPLICATION, " - application graph"]), @@ -1087,8 +1197,12 @@ update_app_graph(S) -> update_mod_graph(S) -> {ok, WhiteApps} = reltool_server:get_apps(S#state.server_pid, whitelist), {ok, DerivedApps} = reltool_server:get_apps(S#state.server_pid, derived), - WhiteMods = lists:usort([M || A <- WhiteApps, M <- A#app.mods, M#mod.is_included =:= true]), - DerivedMods = lists:usort([M || A <- DerivedApps, M <- A#app.mods, M#mod.is_included =:= true]), + WhiteMods = lists:usort([M || A <- WhiteApps, + M <- A#app.mods, + M#mod.is_included =:= true]), + DerivedMods = lists:usort([M || A <- DerivedApps, + M <- A#app.mods, + M#mod.is_included =:= true]), WhiteNames = [M#mod.name || M <- WhiteMods], DerivedNames = [M#mod.name || M <- DerivedMods], @@ -1113,7 +1227,7 @@ create_fgraph_window(S, Title, Nodes, Links) -> Panel = wxPanel:new(Frame, []), Options = [{size, {lists:max([100, ?WIN_WIDTH - 100]), ?WIN_HEIGHT}}], {Server, Fgraph} = reltool_fgraph_win:new(Panel, Options), - Choose = fun(?MISSING_APP) -> alternate; + Choose = fun(?MISSING_APP_NAME) -> alternate; (_) -> default end, [reltool_fgraph_win:add_node(Server, N, Choose(N)) || N <- Nodes], @@ -1141,7 +1255,10 @@ undo_config(#state{status_bar = Bar} = S) -> load_config(#state{status_bar = Bar, config_file = OldFile} = S) -> Style = ?wxFD_OPEN bor ?wxFD_FILE_MUST_EXIST, - case select_file(S#state.frame, "Select a file to load the configuration from", OldFile, Style) of + case select_file(S#state.frame, + "Select a file to load the configuration from", + OldFile, + Style) of {ok, NewFile} -> wxStatusBar:setStatusText(Bar, "Processing libraries..."), Status = reltool_server:load_config(S#state.server_pid, NewFile), @@ -1151,18 +1268,27 @@ load_config(#state{status_bar = Bar, config_file = OldFile} = S) -> end. save_config(#state{config_file = OldFile} = S, InclDefaults, InclDerivates) -> - Style = ?wxFD_SAVE bor ?wxFD_OVERWRITE_PROMPT, - case select_file(S#state.frame, "Select a file to save the configuration to", OldFile, Style) of + Style = ?wxFD_SAVE bor ?wxFD_OVERWRITE_PROMPT, + case select_file(S#state.frame, + "Select a file to save the configuration to", + OldFile, + Style) of {ok, NewFile} -> - Status = reltool_server:save_config(S#state.server_pid, NewFile, InclDefaults, InclDerivates), + Status = reltool_server:save_config(S#state.server_pid, + NewFile, + InclDefaults, + InclDerivates), check_and_refresh(S#state{config_file = NewFile}, Status); cancel -> S end. gen_rel_files(#state{target_dir = OldDir} = S) -> - Style = ?wxFD_SAVE bor ?wxFD_OVERWRITE_PROMPT, - case select_dir(S#state.frame, "Select a directory to generate rel, script and boot files to", OldDir, Style) of + Style = ?wxFD_SAVE bor ?wxFD_OVERWRITE_PROMPT, + case select_dir(S#state.frame, + "Select a directory to generate rel, script and boot files to", + OldDir, + Style) of {ok, NewDir} -> Status = reltool_server:gen_rel_files(S#state.server_pid, NewDir), check_and_refresh(S, Status); @@ -1171,8 +1297,11 @@ gen_rel_files(#state{target_dir = OldDir} = S) -> end. gen_target(#state{target_dir = OldDir} = S) -> - Style = ?wxFD_SAVE bor ?wxFD_OVERWRITE_PROMPT, - case select_dir(S#state.frame, "Select a directory to generate a target system to", OldDir, Style) of + Style = ?wxFD_SAVE bor ?wxFD_OVERWRITE_PROMPT, + case select_dir(S#state.frame, + "Select a directory to generate a target system to", + OldDir, + Style) of {ok, NewDir} -> Status = reltool_server:gen_target(S#state.server_pid, NewDir), check_and_refresh(S#state{target_dir = NewDir}, Status); @@ -1186,7 +1315,7 @@ select_file(Frame, Message, DefaultFile, Style) -> {defaultDir, filename:dirname(DefaultFile)}, {defaultFile, filename:basename(DefaultFile)}, {style, Style}]), - Choice = + Choice = case wxMessageDialog:showModal(Dialog) of ?wxID_CANCEL -> cancel; ?wxID_OK -> {ok, wxFileDialog:getPath(Dialog)} @@ -1199,7 +1328,7 @@ select_dir(Frame, Message, DefaultDir, Style) -> [{title, Message}, {defaultPath, DefaultDir}, {style, Style}]), - Choice = + Choice = case wxMessageDialog:showModal(Dialog) of ?wxID_CANCEL -> cancel; ?wxID_OK -> {ok, wxDirDialog:getPath(Dialog)} @@ -1229,28 +1358,34 @@ refresh(S) -> S2 = S#state{sys = Sys}, S3 = redraw_libs(S2), redraw_apps(S3). - + question_dialog(Question, Details) -> %% Parent = S#state.frame, Parent = wx:typeCast(wx:null(), wxWindow), %% [{style, ?wxYES_NO bor ?wxICON_ERROR bor ?wx}]), DialogStyle = ?wxRESIZE_BORDER bor ?wxCAPTION bor ?wxSYSTEM_MENU bor ?wxMINIMIZE_BOX bor ?wxMAXIMIZE_BOX bor ?wxCLOSE_BOX, - Dialog = wxDialog:new(Parent, ?wxID_ANY, "Undo dialog", [{style, DialogStyle}]), + Dialog = wxDialog:new(Parent, ?wxID_ANY, "Undo dialog", + [{style, DialogStyle}]), Color = wxWindow:getBackgroundColour(Dialog), TextStyle = ?wxTE_READONLY bor ?wxTE_MULTILINE bor ?wxHSCROLL, - Text1 = wxTextCtrl:new(Dialog, ?wxID_ANY, [{style, ?wxTE_READONLY bor ?wxBORDER_NONE}]), + Text1 = wxTextCtrl:new(Dialog, ?wxID_ANY, + [{style, ?wxTE_READONLY bor ?wxBORDER_NONE}]), wxWindow:setBackgroundColour(Text1, Color), wxTextCtrl:appendText(Text1, Question), - Text2 = wxTextCtrl:new(Dialog, ?wxID_ANY, [{size, {600, 400}}, {style, TextStyle}]), + Text2 = wxTextCtrl:new(Dialog, ?wxID_ANY, + [{size, {600, 400}}, {style, TextStyle}]), wxWindow:setBackgroundColour(Text2, Color), wxTextCtrl:appendText(Text2, Details), %% wxDialog:setAffirmativeId(Dialog, ?wxID_YES), %% wxDialog:setEscapeId(Dialog, ?wxID_NO), Sizer = wxBoxSizer:new(?wxVERTICAL), wxSizer:add(Sizer, Text1, [{border, 2}, {flag, ?wxEXPAND}]), - wxSizer:add(Sizer, Text2, [{border, 2}, {flag, ?wxEXPAND}, {proportion, 1}]), - ButtSizer = wxDialog:createStdDialogButtonSizer(Dialog, ?wxOK bor ?wxCANCEL), + wxSizer:add(Sizer, Text2, [{border, 2}, + {flag, ?wxEXPAND}, + {proportion, 1}]), + ButtSizer = wxDialog:createStdDialogButtonSizer(Dialog, + ?wxOK bor ?wxCANCEL), wxSizer:add(Sizer, ButtSizer, [{border, 2}, {flag, ?wxEXPAND}]), wxPanel:setSizer(Dialog, Sizer), wxSizer:fit(Sizer, Dialog), diff --git a/lib/reltool/src/reltool_target.erl b/lib/reltool/src/reltool_target.erl index 6d85a98d9f..dd6f75b9fc 100644 --- a/lib/reltool/src/reltool_target.erl +++ b/lib/reltool/src/reltool_target.erl @@ -22,7 +22,7 @@ -export([ gen_config/2, gen_app/1, - gen_rel/2, + gen_rel/2, gen_rel_files/2, gen_boot/1, gen_script/4, @@ -31,7 +31,7 @@ gen_target/2, install/2 ]). --compile(export_all). + -include("reltool.hrl"). -include_lib("kernel/include/file.hrl"). @@ -55,147 +55,186 @@ kernel_processes(KernelApp) -> [ {kernelProcess, heart, {heart, start, []}}, {kernelProcess, error_logger , {error_logger, start_link, []}}, - {kernelProcess, application_controller, {application_controller, start, [KernelApp]}} + {kernelProcess, + application_controller, + {application_controller, start, [KernelApp]}} ]. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Generate the contents of a config file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -gen_config(#sys{root_dir = RootDir, - lib_dirs = LibDirs, - mod_cond = ModCond, - incl_cond = AppCond, - apps = Apps, - boot_rel = BootRel, - rels = Rels, - emu_name = EmuName, - profile = Profile, - incl_sys_filters = InclSysFiles, - excl_sys_filters = ExclSysFiles, - incl_app_filters = InclAppFiles, - excl_app_filters = ExclAppFiles, - incl_archive_filters = InclArchiveDirs, - excl_archive_filters = ExclArchiveDirs, - archive_opts = ArchiveOpts, - relocatable = Relocatable, - app_type = AppType, - app_file = AppFile, - debug_info = DebugInfo}, - InclDefaults) -> - ErtsItems = +gen_config(Sys, InclDefs) -> + {ok, do_gen_config(Sys, InclDefs)}. + +do_gen_config(#sys{root_dir = RootDir, + lib_dirs = LibDirs, + mod_cond = ModCond, + incl_cond = AppCond, + apps = Apps, + boot_rel = BootRel, + rels = Rels, + emu_name = EmuName, + profile = Profile, + incl_sys_filters = InclSysFiles, + excl_sys_filters = ExclSysFiles, + incl_app_filters = InclAppFiles, + excl_app_filters = ExclAppFiles, + incl_archive_filters = InclArchiveDirs, + excl_archive_filters = ExclArchiveDirs, + archive_opts = ArchiveOpts, + relocatable = Relocatable, + rel_app_type = RelAppType, + embedded_app_type = InclAppType, + app_file = AppFile, + debug_info = DebugInfo}, + InclDefs) -> + ErtsItems = case lists:keysearch(erts, #app.name, Apps) of {value, Erts} -> - [{erts, gen_config(Erts, InclDefaults)}]; + [{erts, do_gen_config(Erts, InclDefs)}]; false -> [] end, AppsItems = - [{app, A#app.name, gen_config(A, InclDefaults)} - || A <- Apps, - A#app.name =/= ?MISSING_APP, + [do_gen_config(A, InclDefs) + || A <- Apps, + A#app.name =/= ?MISSING_APP_NAME, A#app.name =/= erts, - A#app.is_included =:= true, - A#app.is_escript =/= true], - EscriptItems = [{escript, A#app.active_dir, emit(incl_cond, A#app.incl_cond, undefined, InclDefaults)} - || A <- Apps, A#app.is_escript], + not A#app.is_escript], + EscriptItems = [{escript, + A#app.active_dir, + emit(incl_cond, A#app.incl_cond, undefined, InclDefs)} + || A <- Apps, A#app.is_escript], DefaultRels = reltool_utils:default_rels(), RelsItems = - case {[{rel, R#rel.name, R#rel.vsn, gen_config(R, InclDefaults)} || R <- Rels], - [{rel, R#rel.name, R#rel.vsn, gen_config(R, InclDefaults)} || R <- DefaultRels]} of - {RI, RI} -> []; - {RI, _} -> RI - end, + [{rel, R#rel.name, R#rel.vsn, do_gen_config(R, InclDefs)} || + R <- Rels], + DefaultRelsItems = + [{rel, R#rel.name, R#rel.vsn, do_gen_config(R, InclDefs)} || + R <- DefaultRels], + RelsItems2 = + case InclDefs of + true -> RelsItems; + false -> RelsItems -- DefaultRelsItems + end, X = fun(List) -> [Re || #regexp{source = Re} <- List] end, {sys, - emit(root_dir, RootDir, code:root_dir(), InclDefaults) ++ - emit(lib_dirs, LibDirs, ?DEFAULT_LIBS, InclDefaults) ++ + emit(root_dir, RootDir, code:root_dir(), InclDefs) ++ + emit(lib_dirs, LibDirs, ?DEFAULT_LIBS, InclDefs) ++ EscriptItems ++ - emit(mod_cond, ModCond, ?DEFAULT_MOD_COND, InclDefaults) ++ - emit(incl_cond, AppCond, ?DEFAULT_INCL_COND, InclDefaults) ++ + emit(mod_cond, ModCond, ?DEFAULT_MOD_COND, InclDefs) ++ + emit(incl_cond, AppCond, ?DEFAULT_INCL_COND, InclDefs) ++ ErtsItems ++ - AppsItems ++ - emit(boot_rel, BootRel, ?DEFAULT_REL_NAME, InclDefaults) ++ - RelsItems ++ - emit(emu_name, EmuName, ?DEFAULT_EMU_NAME, InclDefaults) ++ - emit(relocatable, Relocatable, ?DEFAULT_RELOCATABLE, InclDefaults) ++ - emit(profile, Profile, ?DEFAULT_PROFILE, InclDefaults) ++ - emit(incl_sys_filters, X(InclSysFiles), ?DEFAULT_INCL_SYS_FILTERS, InclDefaults) ++ - emit(excl_sys_filters, X(ExclSysFiles), ?DEFAULT_EXCL_SYS_FILTERS, InclDefaults) ++ - emit(incl_app_filters, X(InclAppFiles), ?DEFAULT_INCL_APP_FILTERS, InclDefaults) ++ - emit(excl_app_filters, X(ExclAppFiles), ?DEFAULT_EXCL_APP_FILTERS, InclDefaults) ++ - emit(incl_archive_filters, X(InclArchiveDirs), ?DEFAULT_INCL_ARCHIVE_FILTERS, InclDefaults) ++ - emit(excl_archive_filters, X(ExclArchiveDirs), ?DEFAULT_EXCL_ARCHIVE_FILTERS, InclDefaults) ++ - emit(archive_opts, ArchiveOpts, ?DEFAULT_ARCHIVE_OPTS, InclDefaults) ++ - emit(app_type, AppType, ?DEFAULT_APP_TYPE, InclDefaults) ++ - emit(app_file, AppFile, ?DEFAULT_APP_FILE, InclDefaults) ++ - emit(debug_info, DebugInfo, ?DEFAULT_DEBUG_INFO, InclDefaults)}; -gen_config(#app{name = _Name, - mod_cond = ModCond, - incl_cond = AppCond, - debug_info = DebugInfo, - app_file = AppFile, - incl_app_filters = InclAppFiles, - excl_app_filters = ExclAppFiles, - incl_archive_filters = InclArchiveDirs, - excl_archive_filters = ExclArchiveDirs, - archive_opts = ArchiveOpts, - use_selected_vsn = UseSelected, - vsn = Vsn, - mods = Mods}, - InclDefaults) -> - emit(mod_cond, ModCond, undefined, InclDefaults) ++ - emit(incl_cond, AppCond, undefined, InclDefaults) ++ - emit(debug_info, DebugInfo, undefined, InclDefaults) ++ - emit(app_file, AppFile, undefined, InclDefaults) ++ - emit(incl_app_filters, InclAppFiles, undefined, InclDefaults) ++ - emit(excl_app_filters, ExclAppFiles, undefined, InclDefaults) ++ - emit(incl_archive_filters, InclArchiveDirs, undefined, InclDefaults) ++ - emit(excl_archive_filters, ExclArchiveDirs, undefined, InclDefaults) ++ - emit(archive_opts, ArchiveOpts, undefined, InclDefaults) ++ - emit(vsn, Vsn, undefined, InclDefaults orelse UseSelected =/= true) ++ - [{mod, M#mod.name, gen_config(M, InclDefaults)} || M <- Mods, M#mod.is_included =:= true]; -gen_config(#mod{name = _Name, - incl_cond = AppCond, - debug_info = DebugInfo}, - InclDefaults) -> - emit(incl_cond, AppCond, undefined, InclDefaults) ++ - emit(debug_info, DebugInfo, undefined, InclDefaults); -gen_config(#rel{name = _Name, - vsn = _Vsn, - rel_apps = RelApps}, - InclDefaults) -> - [gen_config(RA, InclDefaults) || RA <- RelApps]; -gen_config(#rel_app{name = Name, - app_type = Type, - incl_apps = InclApps}, - _InclDefaults) -> + lists:flatten(AppsItems) ++ + emit(boot_rel, BootRel, ?DEFAULT_REL_NAME, InclDefs) ++ + RelsItems2 ++ + emit(emu_name, EmuName, ?DEFAULT_EMU_NAME, InclDefs) ++ + emit(relocatable, Relocatable, ?DEFAULT_RELOCATABLE, InclDefs) ++ + emit(profile, Profile, ?DEFAULT_PROFILE, InclDefs) ++ + emit(incl_sys_filters, X(InclSysFiles), reltool_utils:choose_default(incl_sys_filters, Profile, InclDefs), InclDefs) ++ + emit(excl_sys_filters, X(ExclSysFiles), reltool_utils:choose_default(excl_sys_filters, Profile, InclDefs), InclDefs) ++ + emit(incl_app_filters, X(InclAppFiles), reltool_utils:choose_default(incl_app_filters, Profile, InclDefs), InclDefs) ++ + emit(excl_app_filters, X(ExclAppFiles), reltool_utils:choose_default(excl_app_filters, Profile, InclDefs), InclDefs) ++ + emit(incl_archive_filters, X(InclArchiveDirs), ?DEFAULT_INCL_ARCHIVE_FILTERS, InclDefs) ++ + emit(excl_archive_filters, X(ExclArchiveDirs), ?DEFAULT_EXCL_ARCHIVE_FILTERS, InclDefs) ++ + emit(archive_opts, ArchiveOpts, ?DEFAULT_ARCHIVE_OPTS, InclDefs) ++ + emit(rel_app_type, RelAppType, ?DEFAULT_REL_APP_TYPE, InclDefs) ++ + emit(embedded_app_type, InclAppType, reltool_utils:choose_default(embedded_app_type, Profile, InclDefs), InclDefs) ++ + emit(app_file, AppFile, ?DEFAULT_APP_FILE, InclDefs) ++ + emit(debug_info, DebugInfo, ?DEFAULT_DEBUG_INFO, InclDefs)}; +do_gen_config(#app{name = Name, + mod_cond = ModCond, + incl_cond = AppCond, + debug_info = DebugInfo, + app_file = AppFile, + incl_app_filters = InclAppFiles, + excl_app_filters = ExclAppFiles, + incl_archive_filters = InclArchiveDirs, + excl_archive_filters = ExclArchiveDirs, + archive_opts = ArchiveOpts, + use_selected_vsn = UseSelected, + vsn = Vsn, + mods = Mods, + is_included = IsIncl}, + InclDefs) -> + AppConfig = + [ + emit(mod_cond, ModCond, undefined, InclDefs), + emit(incl_cond, AppCond, undefined, InclDefs), + emit(debug_info, DebugInfo, undefined, InclDefs), + emit(app_file, AppFile, undefined, InclDefs), + emit(incl_app_filters, InclAppFiles, undefined, InclDefs), + emit(excl_app_filters, ExclAppFiles, undefined, InclDefs), + emit(incl_archive_filters, InclArchiveDirs, undefined, InclDefs), + emit(excl_archive_filters, ExclArchiveDirs, undefined, InclDefs), + emit(archive_opts, ArchiveOpts, undefined, InclDefs), + if + IsIncl, InclDefs -> [{vsn, Vsn}]; + UseSelected -> [{vsn, Vsn}]; + true -> [] + end, + [do_gen_config(M, InclDefs) || M <- Mods] + ], + case lists:flatten(AppConfig) of + FlatAppConfig when FlatAppConfig =/= []; IsIncl -> + [{app, Name, FlatAppConfig}]; + [] -> + [] + end; +do_gen_config(#mod{name = Name, + incl_cond = AppCond, + debug_info = DebugInfo, + is_included = IsIncl}, + InclDefs) -> + ModConfig = + [ + emit(incl_cond, AppCond, undefined, InclDefs), + emit(debug_info, DebugInfo, undefined, InclDefs) + ], + case lists:flatten(ModConfig) of + FlatModConfig when FlatModConfig =/= []; IsIncl -> + [{mod, Name, FlatModConfig}]; + _ -> + [] + end; +do_gen_config(#rel{name = _Name, + vsn = _Vsn, + rel_apps = RelApps}, + InclDefs) -> + [do_gen_config(RA, InclDefs) || RA <- RelApps]; +do_gen_config(#rel_app{name = Name, + app_type = Type, + incl_apps = InclApps}, + _InclDefs) -> case {Type, InclApps} of {undefined, []} -> Name; {undefined, _} -> {Name, InclApps}; {_, []} -> {Name, Type}; {_, _} -> {Name, Type, InclApps} end; -gen_config({Tag, Val}, InclDefaults) -> - emit(Tag, Val, undefined, InclDefaults); -gen_config([], _InclDefaults) -> +do_gen_config({Tag, Val}, InclDefs) -> + emit(Tag, Val, undefined, InclDefs); +do_gen_config([], _InclDefs) -> []; -gen_config([H | T], InclDefaults) -> - lists:flatten([gen_config(H, InclDefaults), gen_config(T, InclDefaults)]). +do_gen_config([H | T], InclDefs) -> + lists:flatten([do_gen_config(H, InclDefs), do_gen_config(T, InclDefs)]). -emit(Tag, Val, Default, InclDefaults) -> +emit(Tag, Val, Default, InclDefs) -> + %% io:format("~p(~p):\n\t~p\n\t~p\n", + %% [Tag, Val =/= Default, Val, Default]), if Val == undefined -> []; - InclDefaults -> [{Tag, Val}]; + InclDefs -> [{Tag, Val}]; Val =/= Default -> [{Tag, Val}]; true -> [] - end. + end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Generate the contents of an app file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -gen_app(#app{name = Name, +gen_app(#app{name = Name, info = #app_info{description = Desc, id = Id, vsn = Vsn, @@ -231,22 +270,126 @@ gen_app(#app{name = Name, %% Generate the contents of a rel file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -gen_rel(#rel{name = RelName, vsn = RelVsn, rel_apps = RelApps}, - #sys{apps = Apps}) -> - {value, Erts} = lists:keysearch(erts, #app.name, Apps), - {release, - {RelName, RelVsn}, - {erts, Erts#app.vsn}, - [app_to_rel(RA, Apps ) || RA <- RelApps]}. +gen_rel(Rel, Sys) -> + try + MergedApps = merge_apps(Rel, Sys), + {ok, do_gen_rel(Rel, Sys, MergedApps)} + catch + throw:{error, Text} -> + {error, Text} + end. -app_to_rel(#rel_app{name = Name, app_type = Type, incl_apps = InclApps}, Apps) -> - {value, #app{vsn = Vsn}} = lists:keysearch(Name, #app.name, Apps), +do_gen_rel(#rel{name = RelName, vsn = RelVsn}, + #sys{apps = Apps}, + MergedApps) -> + ErtsName = erts, + case lists:keysearch(ErtsName, #app.name, Apps) of + {value, Erts} -> + {release, + {RelName, RelVsn}, + {ErtsName, Erts#app.vsn}, + [strip_rel_info(App) || App <- MergedApps]}; + false -> + reltool_utils:throw_error("Mandatory application ~p is " + "not included", + [ErtsName]) + end. + +strip_rel_info(#app{name = Name, + vsn = Vsn, + app_type = Type, + info = #app_info{incl_apps = InclApps}}) + when Type =/= undefined -> case {Type, InclApps} of - {undefined, []} -> {Name, Vsn}; - {undefined, _} -> {Name, Vsn, InclApps}; + {permanent, []} -> {Name, Vsn}; + {permanent, _} -> {Name, Vsn, InclApps}; {_, []} -> {Name, Vsn, Type}; {_, _} -> {Name, Vsn, Type, InclApps} - end. + end. + +merge_apps(#rel{name = RelName, + rel_apps = RelApps}, + #sys{apps = Apps, + rel_app_type = RelAppType, + embedded_app_type = EmbAppType}) -> + Mandatory = [kernel, stdlib], + MergedApps = do_merge_apps(RelName, Mandatory, Apps, permanent, []), + MergedApps2 = do_merge_apps(RelName, RelApps, Apps, RelAppType, MergedApps), + Embedded = + [A#app.name || A <- Apps, + EmbAppType =/= undefined, + A#app.is_included, + A#app.name =/= erts, + A#app.name =/= ?MISSING_APP_NAME, + not lists:keymember(A#app.name, #app.name, MergedApps2)], + MergedApps3 = do_merge_apps(RelName, Embedded, Apps, EmbAppType, MergedApps2), + sort_apps(MergedApps3). + +do_merge_apps(RelName, [#rel_app{name = Name} = RA | RelApps], Apps, RelAppType, Acc) -> + case is_already_merged(Name, RelApps, Acc) of + true -> + do_merge_apps(RelName, RelApps, Apps, RelAppType, Acc); + false -> + {value, App} = lists:keysearch(Name, #app.name, Apps), + MergedApp = merge_app(RelName, RA, RelAppType, App), + MoreNames = (MergedApp#app.info)#app_info.applications, + Acc2 = [MergedApp | Acc], + do_merge_apps(RelName, MoreNames ++ RelApps, Apps, RelAppType, Acc2) + end; +do_merge_apps(RelName, [Name | RelApps], Apps, RelAppType, Acc) -> + case is_already_merged(Name, RelApps, Acc) of + true -> + do_merge_apps(RelName, RelApps, Apps, RelAppType, Acc); + false -> + RelApp = init_rel_app(Name, Apps), + do_merge_apps(RelName, [RelApp | RelApps], Apps, RelAppType, Acc) + end; +do_merge_apps(_RelName, [], _Apps, _RelAppType, Acc) -> + lists:reverse(Acc). + +init_rel_app(Name, Apps) -> + {value, App} = lists:keysearch(Name, #app.name, Apps), + Info = App#app.info, + #rel_app{name = Name, + app_type = undefined, + incl_apps = Info#app_info.incl_apps}. + +merge_app(RelName, + #rel_app{name = Name, + app_type = Type, + incl_apps = InclApps}, + RelAppType, + App) -> + Type2 = + case {Type, App#app.app_type} of + {undefined, undefined} -> RelAppType; + {undefined, AppAppType} -> AppAppType; + {_, _} -> Type + end, + Info = App#app.info, + case InclApps -- Info#app_info.incl_apps of + [] -> + App#app{app_type = Type2, info = Info#app_info{incl_apps = InclApps}}; + BadIncl -> + reltool_utils:throw_error("~p: These applications are " + "used by release ~s but are " + "missing as included_applications " + "in the app file: ~p", + [Name, RelName, BadIncl]) + end. + +is_already_merged(Name, [Name | _], _MergedApps) -> + true; +is_already_merged(Name, [#rel_app{name = Name} | _], _MergedApps) -> + true; +is_already_merged(Name, [_ | RelApps], MergedApps) -> + is_already_merged(Name, RelApps, MergedApps); +is_already_merged(Name, [], [#app{name = Name} | _MergedApps]) -> + true; +is_already_merged(Name, [] = RelApps, [_ | MergedApps]) -> + is_already_merged(Name, RelApps, MergedApps); +is_already_merged(_Name, [], []) -> + false. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Generate the contents of a boot file @@ -261,25 +404,24 @@ gen_boot({script, {_, _}, _} = Script) -> gen_script(Rel, Sys, PathFlag, Variables) -> try - do_gen_script(Rel, Sys, PathFlag, Variables) - catch + MergedApps = merge_apps(Rel, Sys), + do_gen_script(Rel, Sys, MergedApps, PathFlag, Variables) + catch throw:{error, Text} -> {error, Text} end. -do_gen_script(#rel{name = RelName, vsn = RelVsn, rel_apps = RelApps}, - #sys{apps = Apps, app_type = DefaultType}, +do_gen_script(#rel{name = RelName, vsn = RelVsn}, + #sys{apps = Apps}, + MergedApps, PathFlag, Variables) -> {value, Erts} = lists:keysearch(erts, #app.name, Apps), Preloaded = [Mod#mod.name || Mod <- Erts#app.mods], Mandatory = mandatory_modules(), Early = Mandatory ++ Preloaded, - MergedApps = [merge_app(RA, Apps, DefaultType) || RA <- RelApps], - SortedApps = sort_apps(MergedApps), - {value, KernelApp} = lists:keysearch(kernel, #app.name, SortedApps), - - InclApps = lists:append([I || #app{info = #app_info{incl_apps = I}} <- SortedApps]), + {value, KernelApp} = lists:keysearch(kernel, #app.name, MergedApps), + InclApps = [I || #app{info = #app_info{incl_apps = I}} <- MergedApps], %% Create the script DeepList = @@ -289,32 +431,32 @@ do_gen_script(#rel{name = RelName, vsn = RelVsn, rel_apps = RelApps}, {progress, preloaded}, %% Load mandatory modules - {path, create_mandatory_path(SortedApps, PathFlag, Variables)}, + {path, create_mandatory_path(MergedApps, PathFlag, Variables)}, {primLoad, lists:sort(Mandatory)}, {kernel_load_completed}, {progress, kernel_load_completed}, %% Load remaining modules - [load_app_mods(A, Early, PathFlag, Variables) || A <- SortedApps], + [load_app_mods(A, Early, PathFlag, Variables) || A <- MergedApps], {progress, modules_loaded}, %% Start kernel processes - {path, create_path(SortedApps, PathFlag, Variables)}, + {path, create_path(MergedApps, PathFlag, Variables)}, kernel_processes(gen_app(KernelApp)), {progress, init_kernel_started}, %% Load applications [{apply, {application, load, [gen_app(A)]}} || - A = #app{name = Name, app_type = Type} <- SortedApps, + A = #app{name = Name, app_type = Type} <- MergedApps, Name =/= kernel, Type =/= none], {progress, applications_loaded}, %% Start applications [{apply, {application, start_boot, [Name, Type]}} || - #app{name = Name, app_type = Type} <- SortedApps, - Type =/= none, - Type =/= load, + #app{name = Name, app_type = Type} <- MergedApps, + Type =/= none, + Type =/= load, not lists:member(Name, InclApps)], %% Apply user specific customizations @@ -323,24 +465,6 @@ do_gen_script(#rel{name = RelName, vsn = RelVsn, rel_apps = RelApps}, ], {ok, {script, {RelName, RelVsn}, lists:flatten(DeepList)}}. -merge_app(#rel_app{name = Name, app_type = Type, incl_apps = RelIncl}, Apps, DefaultType) -> - {value, App} = lists:keysearch(Name, #app.name, Apps), - Type2 = - case {Type, App#app.app_type} of - {undefined, undefined} -> DefaultType; - {undefined, AppType} -> AppType; - {_, _} -> Type - end, - Info = App#app.info, - case RelIncl -- Info#app_info.incl_apps of - [] -> - App#app{app_type = Type2, info = Info#app_info{incl_apps = RelIncl}}; - BadIncl -> - reltool_utils:throw_error("~p: These applications are missing as " - "included_applications in the app file: ~p\n", - [Name, BadIncl]) - end. - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% load_app_mods(#app{mods = Mods} = App, Mand, PathFlag, Variables) -> @@ -359,7 +483,7 @@ load_app_mods(#app{mods = Mods} = App, Mand, PathFlag, Variables) -> Subs -> [{Subs, [M]}|[{Last,Acc}|Rest]] end - end, + end, [{[], []}], PartNames), @@ -381,17 +505,26 @@ load_app_mods(#app{mods = Mods} = App, Mand, PathFlag, Variables) -> %% Mod. by mbj %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -sort_apps(Apps) -> +sort_apps(Apps) -> sort_apps(Apps, [], [], []). -sort_apps([#app{name = Name, info = Info} = App | Apps], Missing, Circular, Visited) -> - {Uses, Apps1, NotFnd1} = find_all(Name, Info#app_info.applications, Apps, Visited, [], []), - {Incs, Apps2, NotFnd2} = find_all(Name, lists:reverse(Info#app_info.incl_apps), - Apps1, Visited, [], []), - +sort_apps([#app{name = Name, info = Info} = App | Apps], + Missing, + Circular, + Visited) -> + {Uses, Apps1, NotFnd1} = + find_all(Name, Info#app_info.applications, Apps, Visited, [], []), + {Incs, Apps2, NotFnd2} = + find_all(Name, + lists:reverse(Info#app_info.incl_apps), + Apps1, + Visited, + [], + []), + Missing1 = NotFnd1 ++ NotFnd2 ++ Missing, case Uses ++ Incs of - [] -> + [] -> %% No more app that must be started before this one is %% found; they are all already taken care of (and present %% in Visited list) @@ -401,8 +534,8 @@ sort_apps([#app{name = Name, info = Info} = App | Apps], Missing, Circular, Visi %% Check if we have already taken care of some app in L, %% in that case we have a circular dependency. NewCircular = [N1 || N1 <- L, N2 <- Visited, N1 =:= N2], - Circular1 = case NewCircular of - [] -> Circular; + Circular1 = case NewCircular of + [] -> Circular; _ -> [Name | NewCircular] ++ Circular end, %% L must be started before N, try again, with all apps @@ -414,11 +547,13 @@ sort_apps([], [], [], _) -> []; sort_apps([], Missing, [], _) -> %% this has already been checked before, but as we have the info... - reltool_utils:throw_error("Undefined applications: ~p\n", [make_set(Missing)]); + reltool_utils:throw_error("Undefined applications: ~p", + [make_set(Missing)]); sort_apps([], [], Circular, _) -> - reltool_utils:throw_error("Circular dependencies: ~p\n", [make_set(Circular)]); + reltool_utils:throw_error("Circular dependencies: ~p", + [make_set(Circular)]); sort_apps([], Missing, Circular, _) -> - reltool_utils:throw_error("Circular dependencies: ~p\n" + reltool_utils:throw_error("Circular dependencies: ~p" "Undefined applications: ~p\n", [make_set(Circular), make_set(Missing)]). @@ -431,24 +566,49 @@ find_all(CheckingApp, [Name | Names], Apps, Visited, Found, NotFound) -> true -> case lists:member(Name, Visited) of true -> - find_all(CheckingApp, Names, Apps, Visited, Found, NotFound); + find_all(CheckingApp, + Names, + Apps, + Visited, + Found, + NotFound); false -> - find_all(CheckingApp, Names, Apps, Visited, Found, [Name | NotFound]) + find_all(CheckingApp, + Names, + Apps, + Visited, + Found, + [Name | NotFound]) end; false -> - find_all(CheckingApp, Names, Apps -- [App], Visited, [App|Found], NotFound) + find_all(CheckingApp, + Names, + Apps -- [App], + Visited, + [App|Found], + NotFound) end; false -> case lists:member(Name, Visited) of true -> - find_all(CheckingApp, Names, Apps, Visited, Found, NotFound); + find_all(CheckingApp, + Names, + Apps, + Visited, + Found, + NotFound); false -> - find_all(CheckingApp, Names, Apps, Visited, Found, [Name|NotFound]) + find_all(CheckingApp, + Names, + Apps, + Visited, + Found, + [Name|NotFound]) end end; find_all(_CheckingApp, [], Apps, _Visited, Found, NotFound) -> {Found, Apps, NotFound}. - + del_apps([Name | Names], Apps) -> del_apps(Names, lists:keydelete(Name, #app.name, Apps)); del_apps([], Apps) -> @@ -470,7 +630,9 @@ create_path(Apps, PathFlag, Variables) -> %% (The otp_build flag is only used for OTP internal system make) cr_path(#app{label = Label}, true, []) -> filename:join(["$ROOT", "lib", Label, "ebin"]); -cr_path(#app{name = Name, vsn = Vsn, label = Label, active_dir = Dir}, true, Variables) -> +cr_path(#app{name = Name, vsn = Vsn, label = Label, active_dir = Dir}, + true, + Variables) -> Tail = [Label, "ebin"], case variable_dir(Dir, atom_to_list(Name), Vsn, Variables) of {ok, VarDir} -> @@ -542,7 +704,7 @@ gen_rel_files(Sys, TargetDir) -> try Spec = spec_rel_files(Sys), eval_spec(Spec, Sys#sys.root_dir, TargetDir) - catch + catch throw:{error, Text} -> {error, Text} end. @@ -550,14 +712,15 @@ gen_rel_files(Sys, TargetDir) -> spec_rel_files(#sys{rels = Rels} = Sys) -> lists:append([do_spec_rel_files(R, Sys) || R <- Rels]). -do_spec_rel_files(#rel{name = Name} = Rel, Sys) -> - RelFile = Name ++ ".rel", - ScriptFile = Name ++ ".script", - BootFile = Name ++ ".boot", - GenRel = gen_rel(Rel, Sys), +do_spec_rel_files(#rel{name = RelName} = Rel, Sys) -> + RelFile = RelName ++ ".rel", + ScriptFile = RelName ++ ".script", + BootFile = RelName ++ ".boot", + MergedApps = merge_apps(Rel, Sys), + GenRel = do_gen_rel(Rel, Sys, MergedApps), PathFlag = true, Variables = [], - {ok, Script} = do_gen_script(Rel, Sys, PathFlag, Variables), + {ok, Script} = do_gen_script(Rel, Sys, MergedApps, PathFlag, Variables), {ok, BootBin} = gen_boot(Script), Date = date(), Time = time(), @@ -579,15 +742,15 @@ gen_target(Sys, TargetDir) -> try Spec = do_gen_spec(Sys), eval_spec(Spec, Sys#sys.root_dir, TargetDir) - catch + catch throw:{error, Text} -> {error, Text} end. - + gen_spec(Sys) -> try {ok, do_gen_spec(Sys)} - catch + catch throw:{error, Text} -> {error, Text} end. @@ -598,20 +761,20 @@ do_gen_spec(#sys{root_dir = RootDir, relocatable = Relocatable, apps = Apps} = Sys) -> {create_dir, _, SysFiles} = spec_dir(RootDir), - {ExclRegexps2, SysFiles2} = strip_sys_files(Relocatable, SysFiles, Apps, ExclRegexps), + {ExclRegexps2, SysFiles2} = + strip_sys_files(Relocatable, SysFiles, Apps, ExclRegexps), RelFiles = spec_rel_files(Sys), - {InclRegexps2, BinFiles} = spec_bin_files(Sys, SysFiles, SysFiles2, RelFiles, InclRegexps), + {InclRegexps2, BinFiles} = + spec_bin_files(Sys, SysFiles, SysFiles2, RelFiles, InclRegexps), LibFiles = spec_lib_files(Sys), {BootVsn, StartFile} = spec_start_file(Sys), SysFiles3 = [ - {create_dir, "releases", + {create_dir, "releases", [StartFile, {create_dir,BootVsn, RelFiles}]}, {create_dir, "bin", BinFiles} ] ++ SysFiles2, - %% io:format("InclRegexps2: ~p\n", [InclRegexps2]), - %% io:format("ExclRegexps2: ~p\n", [ExclRegexps2]), SysFiles4 = filter_spec(SysFiles3, InclRegexps2, ExclRegexps2), SysFiles5 = SysFiles4 ++ [{create_dir, "lib", LibFiles}], check_sys(["bin", "erts", "lib"], SysFiles5), @@ -621,24 +784,27 @@ strip_sys_files(Relocatable, SysFiles, Apps, ExclRegexps) -> ExclRegexps2 = case Relocatable of true -> - ExtraExcl = ["^erts.*/bin/.*src$"], - reltool_utils:decode_regexps(excl_sys_filters, {add, ExtraExcl}, ExclRegexps); + ExtraExcl = ["^erts.*/bin/.*src\$"], + reltool_utils:decode_regexps(excl_sys_filters, + {add, ExtraExcl}, + ExclRegexps); false -> ExclRegexps end, {value, Erts} = lists:keysearch(erts, #app.name, Apps), FilterErts = - fun(Spec) -> - File = element(2, Spec), - case lists:prefix("erts", File) of - true -> - if - File =:= Erts#app.label -> - replace_dyn_erl(Relocatable, Spec); - true -> - false - end; - false -> + fun(Spec) -> + File = element(2, Spec), + case File of + "erts" -> + reltool_utils:throw_error("This system is not installed. " + "The directory ~s is missing.", + [Erts#app.label]); + _ when File =:= Erts#app.label -> + replace_dyn_erl(Relocatable, Spec); + "erts-" ++ _ -> + false; + _ -> true end end, @@ -651,7 +817,8 @@ strip_sys_files(Relocatable, SysFiles, Apps, ExclRegexps) -> replace_dyn_erl(false, _ErtsSpec) -> true; replace_dyn_erl(true, {create_dir, ErtsDir, ErtsFiles}) -> - [{create_dir, _, BinFiles}] = safe_lookup_spec("bin", ErtsFiles), + [{create_dir, _, BinFiles}] = + safe_lookup_spec("bin", ErtsFiles), case lookup_spec("dyn_erl", BinFiles) of [] -> case lookup_spec("erl.ini", BinFiles) of @@ -660,7 +827,11 @@ replace_dyn_erl(true, {create_dir, ErtsDir, ErtsFiles}) -> [{copy_file, ErlIni}] -> %% Remove Windows .ini file BinFiles2 = lists:keydelete(ErlIni, 2, BinFiles), - ErtsFiles2 = lists:keyreplace("bin", 2, ErtsFiles, {create_dir, "bin", BinFiles2}), + ErtsFiles2 = + lists:keyreplace("bin", + 2, + ErtsFiles, + {create_dir, "bin", BinFiles2}), {true, {create_dir, ErtsDir, ErtsFiles2}} end; [{copy_file, DynErlExe}] -> @@ -668,42 +839,62 @@ replace_dyn_erl(true, {create_dir, ErtsDir, ErtsFiles}) -> ErlExe = "erl" ++ filename:extension(DynErlExe), BinFiles2 = lists:keydelete(DynErlExe, 2, BinFiles), DynErlExe2 = filename:join([ErtsDir, "bin", DynErlExe]), - BinFiles3 = lists:keyreplace(ErlExe, 2, BinFiles2, {copy_file, ErlExe, DynErlExe2}), - ErtsFiles2 = lists:keyreplace("bin", 2, ErtsFiles, {create_dir, "bin", BinFiles3}), + BinFiles3 = lists:keyreplace(ErlExe, + 2, + BinFiles2, + {copy_file, ErlExe, DynErlExe2}), + ErtsFiles2 = lists:keyreplace("bin", + 2, + ErtsFiles, + {create_dir, "bin", BinFiles3}), {true, {create_dir, ErtsDir, ErtsFiles2}} end. spec_bin_files(Sys, AllSysFiles, StrippedSysFiles, RelFiles, InclRegexps) -> - [{create_dir, ErtsLabel, ErtsFiles}] = safe_lookup_spec("erts", StrippedSysFiles), + [{create_dir, ErtsLabel, ErtsFiles}] = + safe_lookup_spec("erts", StrippedSysFiles), [{create_dir, _, BinFiles}] = safe_lookup_spec("bin", ErtsFiles), ErtsBin = filename:join([ErtsLabel, "bin"]), Escripts = spec_escripts(Sys, ErtsBin, BinFiles), Map = fun({copy_file, File}) -> {copy_file, File, filename:join([ErtsBin, File])}; ({copy_file, NewFile, OldFile}) -> - {_, OldFile2} = abs_to_rel_path(ErtsBin, filename:join([ErtsBin, OldFile])), + {_, OldFile2} = + abs_to_rel_path(ErtsBin, + filename:join([ErtsBin, OldFile])), {copy_file, NewFile, OldFile2} end, %% Do only copy those bin files from erts/bin that also exists in bin [{create_dir, _, OldBinFiles}] = safe_lookup_spec("bin", AllSysFiles), GoodNames = [F || {copy_file, F} <- OldBinFiles, - not lists:suffix(".boot", F), + not lists:suffix(".boot", F), not lists:suffix(".script", F)], - BinFiles2 = [Map(S) || S <- BinFiles, lists:member(element(2, S), GoodNames)], + BinFiles2 = [Map(S) || S <- BinFiles, + lists:member(element(2, S), GoodNames)], BootFiles = [F || F <- RelFiles, lists:suffix(".boot", element(2, F))], - [{write_file, _, BootRel}] = safe_lookup_spec(Sys#sys.boot_rel ++ ".boot", BootFiles), - BootFiles2 = lists:keystore("start.boot", 2, BootFiles, {write_file, "start.boot", BootRel}), - MakeRegexp = fun(File) -> "^bin/" ++ element(2, File) ++ "(|.escript)$" end, + [{write_file, _, BootRel}] = + safe_lookup_spec(Sys#sys.boot_rel ++ ".boot", BootFiles), + BootFiles2 = lists:keystore("start.boot", + 2, + BootFiles, + {write_file, "start.boot", BootRel}), + MakeRegexp = + fun(File) -> "^bin/" ++ element(2, File) ++ "(|.escript)\$" end, ExtraIncl = lists:map(MakeRegexp, Escripts), - InclRegexps2 = reltool_utils:decode_regexps(incl_sys_filters, {add, ExtraIncl}, InclRegexps), + InclRegexps2 = reltool_utils:decode_regexps(incl_sys_filters, + {add, ExtraIncl}, + InclRegexps), {InclRegexps2, Escripts ++ BinFiles2 ++ BootFiles2}. spec_escripts(#sys{apps = Apps}, ErtsBin, BinFiles) -> - Filter = fun(#app{is_escript = IsEscript, is_included = IsIncl, - is_pre_included = IsPre, name = Name, active_dir = File}) -> + Filter = fun(#app{is_escript = IsEscript, + is_included = IsIncl, + is_pre_included = IsPre, + name = Name, + active_dir = File}) -> if - Name =:= ?MISSING_APP -> + Name =:= ?MISSING_APP_NAME -> false; not IsEscript -> false; @@ -722,15 +913,15 @@ do_spec_escript(File, ErtsBin, BinFiles) -> ExeExt = filename:extension(EscriptExe), [{copy_file, Base ++ EscriptExt, File}, {copy_file, Base ++ ExeExt, filename:join([ErtsBin, EscriptExe])}]. - + check_sys(Mandatory, SysFiles) -> lists:foreach(fun(M) -> do_check_sys(M, SysFiles) end, Mandatory). do_check_sys(Prefix, Specs) -> - %%io:format("Prefix: ~p\n", [Prefix]), case lookup_spec(Prefix, Specs) of [] -> - reltool_utils:throw_error("Mandatory system directory ~s is not included", + reltool_utils:throw_error("Mandatory system directory ~s " + "is not included", [Prefix]); _ -> ok @@ -750,7 +941,9 @@ lookup_spec(Prefix, Specs) -> safe_lookup_spec(Prefix, Specs) -> case lookup_spec(Prefix, Specs) of [] -> - reltool_utils:throw_error("Mandatory system file ~s is not included", [Prefix]); + %% io:format("lookup fail ~s:\n\t~p\n", [Prefix, Specs]), + reltool_utils:throw_error("Mandatory system file ~s is " + "not included", [Prefix]); Match -> Match end. @@ -763,7 +956,7 @@ spec_lib_files(#sys{apps = Apps} = Sys) -> Filter = fun(#app{is_escript = IsEscript, is_included = IsIncl, is_pre_included = IsPre, name = Name}) -> if - Name =:= ?MISSING_APP -> + Name =:= ?MISSING_APP_NAME -> false; IsEscript -> false; @@ -780,7 +973,8 @@ spec_lib_files(#sys{apps = Apps} = Sys) -> check_apps([Mandatory | Names], Apps) -> case lists:keymember(Mandatory, #app.name, Apps) of false -> - reltool_utils:throw_error("Mandatory application ~p is not included in ~p", + reltool_utils:throw_error("Mandatory application ~p is " + "not included in ~p", [Mandatory, Apps]); true -> check_apps(Names, Apps) @@ -791,10 +985,10 @@ check_apps([], _) -> spec_app(#app{name = Name, mods = Mods, active_dir = SourceDir, - incl_app_filters = AppInclRegexps, - excl_app_filters = AppExclRegexps} = App, - #sys{incl_app_filters = SysInclRegexps, - excl_app_filters = SysExclRegexps, + incl_app_filters = AppInclRegexps, + excl_app_filters = AppExclRegexps} = App, + #sys{incl_app_filters = SysInclRegexps, + excl_app_filters = SysExclRegexps, debug_info = SysDebugInfo} = Sys) -> %% List files recursively {create_dir, _, AppFiles} = spec_dir(SourceDir), @@ -804,8 +998,12 @@ spec_app(#app{name = Name, EbinDir = filename:join([SourceDir, "ebin"]), OptAppUpFileSpec = spec_opt_copy_file(EbinDir, AppUpFilename), OptAppFileSpec = spec_app_file(App, Sys, EbinDir), - ModSpecs = [spec_mod(M, SysDebugInfo) || M <- Mods, M#mod.is_included, M#mod.exists], - NewEbin = {create_dir, "ebin", OptAppUpFileSpec ++ OptAppFileSpec ++ ModSpecs}, + ModSpecs = [spec_mod(M, SysDebugInfo) || M <- Mods, + M#mod.is_included, + M#mod.exists], + NewEbin = {create_dir, + "ebin", + OptAppUpFileSpec ++ OptAppFileSpec ++ ModSpecs}, AppFiles2 = lists:keystore("ebin", 2, AppFiles, NewEbin), %% Apply file filter @@ -826,24 +1024,32 @@ spec_archive(#app{label = Label, excl_archive_filters = SysExclArchiveDirs, archive_opts = SysArchiveOpts}, Files) -> - InclArchiveDirs = reltool_utils:default_val(AppInclArchiveDirs, SysInclArchiveDirs), - ExclArchiveDirs = reltool_utils:default_val(AppExclArchiveDirs, SysExclArchiveDirs), - ArchiveOpts = reltool_utils:default_val(AppArchiveOpts, SysArchiveOpts), + InclArchiveDirs = + reltool_utils:default_val(AppInclArchiveDirs, SysInclArchiveDirs), + ExclArchiveDirs = + reltool_utils:default_val(AppExclArchiveDirs, SysExclArchiveDirs), + ArchiveOpts = + reltool_utils:default_val(AppArchiveOpts, SysArchiveOpts), Match = fun(F) -> match(element(2, F), InclArchiveDirs, ExclArchiveDirs) end, case lists:filter(Match, Files) of [] -> %% Nothing to archive [spec_create_dir(RootDir, SourceDir, Label, Files)]; ArchiveFiles -> - OptDir = + OptDir = case Files -- ArchiveFiles of [] -> []; ExternalFiles -> - [spec_create_dir(RootDir, SourceDir, Label, ExternalFiles)] + [spec_create_dir(RootDir, + SourceDir, + Label, + ExternalFiles)] end, - ArchiveOpts = reltool_utils:default_val(AppArchiveOpts, SysArchiveOpts), - ArchiveDir = spec_create_dir(RootDir, SourceDir, Label, ArchiveFiles), + ArchiveOpts = + reltool_utils:default_val(AppArchiveOpts, SysArchiveOpts), + ArchiveDir = + spec_create_dir(RootDir, SourceDir, Label, ArchiveFiles), [{archive, Label ++ ".ez", ArchiveOpts, [ArchiveDir]} | OptDir] end. @@ -854,15 +1060,17 @@ spec_dir(Dir) -> case erl_prim_loader:list_dir(Dir) of {ok, Files} -> %% Directory - {create_dir, Base, [spec_dir(filename:join([Dir, F])) || F <- Files]}; + {create_dir, + Base, + [spec_dir(filename:join([Dir, F])) || F <- Files]}; error -> - reltool_utils:throw_error("list dir ~s failed\n", [Dir]) + reltool_utils:throw_error("list dir ~s failed", [Dir]) end; {ok, #file_info{type = regular}} -> %% Plain file {copy_file, Base}; _ -> - reltool_utils:throw_error("read file info ~s failed\n", [Dir]) + reltool_utils:throw_error("read file info ~s failed", [Dir]) end. spec_mod(Mod, DebugInfo) -> @@ -895,7 +1103,7 @@ spec_app_file(#app{name = Name, App2 = App#app{info = Info#app_info{modules = ModNames}}, Contents = gen_app(App2), AppIoList = io_lib:format("%% app generated at ~w ~w\n~p.\n\n", - [date(), time(), Contents]), + [date(), time(), Contents]), [{write_file, AppFilename, AppIoList}]; all -> %% Include all included modules @@ -904,13 +1112,14 @@ spec_app_file(#app{name = Name, App2 = App#app{info = Info#app_info{modules = ModNames}}, Contents = gen_app(App2), AppIoList = io_lib:format("%% app generated at ~w ~w\n~p.\n\n", - [date(), time(), Contents]), + [date(), time(), Contents]), [{write_file, AppFilename, AppIoList}] - + end. spec_opt_copy_file(DirName, BaseName) -> - case filelib:is_regular(filename:join([DirName, BaseName]), erl_prim_loader) of + case filelib:is_regular(filename:join([DirName, BaseName]), + erl_prim_loader) of true -> [{copy_file, BaseName}]; false -> [] end. @@ -949,14 +1158,17 @@ eval_spec(Spec, SourceDir, TargetDir) -> false -> {error, TargetDir2 ++ ": " ++ file:format_error(enoent)} end - catch + catch throw:{error, Text} -> cleanup_spec(Spec, TargetDir2), {error, Text} end. do_eval_spec(List, OrigSourceDir, SourceDir, TargetDir) when is_list(List) -> - lists:foreach(fun(F) -> do_eval_spec(F, OrigSourceDir, SourceDir, TargetDir) end, List); + lists:foreach(fun(F) -> + do_eval_spec(F, OrigSourceDir, SourceDir, TargetDir) + end, + List); %% do_eval_spec({source_dir, SourceDir2, Spec}, OrigSourceDir, _SourceDir, TargetDir) -> %% %% Source dir is absolute or relative the original source dir %% SourceDir3 = filename:join([OrigSourceDir, SourceDir2]), @@ -966,12 +1178,18 @@ do_eval_spec({create_dir, Dir, Files}, OrigSourceDir, SourceDir, TargetDir) -> TargetDir2 = filename:join([TargetDir, Dir]), reltool_utils:create_dir(TargetDir2), do_eval_spec(Files, OrigSourceDir, SourceDir2, TargetDir2); -do_eval_spec({create_dir, Dir, OldDir, Files}, OrigSourceDir, _SourceDir, TargetDir) -> +do_eval_spec({create_dir, Dir, OldDir, Files}, + OrigSourceDir, + _SourceDir, + TargetDir) -> SourceDir2 = filename:join([OrigSourceDir, OldDir]), TargetDir2 = filename:join([TargetDir, Dir]), reltool_utils:create_dir(TargetDir2), do_eval_spec(Files, SourceDir2, SourceDir2, TargetDir2); -do_eval_spec({archive, Archive, Options, Files}, OrigSourceDir, SourceDir, TargetDir) -> +do_eval_spec({archive, Archive, Options, Files}, + OrigSourceDir, + SourceDir, + TargetDir) -> TmpSpec = {create_dir, "tmp", Files}, TmpDir = filename:join([TargetDir, "tmp"]), reltool_utils:create_dir(TmpDir), @@ -986,17 +1204,24 @@ do_eval_spec({archive, Archive, Options, Files}, OrigSourceDir, SourceDir, Targe {ok, _} -> ok; {error, Reason} -> - reltool_utils:throw_error("create archive ~s: ~p\n", [ArchiveFile, Reason]) + reltool_utils:throw_error("create archive ~s failed: ~p", + [ArchiveFile, Reason]) end; do_eval_spec({copy_file, File}, _OrigSourceDir, SourceDir, TargetDir) -> SourceFile = filename:join([SourceDir, File]), TargetFile = filename:join([TargetDir, File]), reltool_utils:copy_file(SourceFile, TargetFile); -do_eval_spec({copy_file, File, OldFile}, OrigSourceDir, _SourceDir, TargetDir) -> +do_eval_spec({copy_file, File, OldFile}, + OrigSourceDir, + _SourceDir, + TargetDir) -> SourceFile = filename:join([OrigSourceDir, OldFile]), TargetFile = filename:join([TargetDir, File]), reltool_utils:copy_file(SourceFile, TargetFile); -do_eval_spec({write_file, File, IoList}, _OrigSourceDir, _SourceDir, TargetDir) -> +do_eval_spec({write_file, File, IoList}, + _OrigSourceDir, + _SourceDir, + TargetDir) -> TargetFile = filename:join([TargetDir, File]), reltool_utils:write_file(TargetFile, IoList); do_eval_spec({strip_beam, File}, _OrigSourceDir, SourceDir, TargetDir) -> @@ -1039,9 +1264,12 @@ cleanup_spec({strip_beam, File}, TargetDir) -> filter_spec(List, InclRegexps, ExclRegexps) -> do_filter_spec("", List, InclRegexps, ExclRegexps). - + do_filter_spec(Path, List, InclRegexps, ExclRegexps) when is_list(List) -> - lists:zf(fun(File) -> do_filter_spec(Path, File, InclRegexps, ExclRegexps) end, List); + lists:zf(fun(File) -> + do_filter_spec(Path, File, InclRegexps, ExclRegexps) + end, + List); %% do_filter_spec(Path, {source_dir, _SourceDir, Spec}, InclRegexps, ExclRegexps) -> %% do_filter_spec(Path, Spec, InclRegexps, ExclRegexps); do_filter_spec(Path, {create_dir, Dir, Files}, InclRegexps, ExclRegexps) -> @@ -1057,7 +1285,10 @@ do_filter_spec(Path, {create_dir, Dir, Files}, InclRegexps, ExclRegexps) -> Files2 when is_list(Files2) -> {true, {create_dir, Dir, Files2}} end; -do_filter_spec(Path, {create_dir, NewDir, OldDir, Files}, InclRegexps, ExclRegexps) -> +do_filter_spec(Path, + {create_dir, NewDir, OldDir, Files}, + InclRegexps, + ExclRegexps) -> Path2 = opt_join(Path, NewDir), case do_filter_spec(Path2, Files, InclRegexps, ExclRegexps) of [] -> @@ -1070,7 +1301,10 @@ do_filter_spec(Path, {create_dir, NewDir, OldDir, Files}, InclRegexps, ExclRegex Files2 when is_list(Files2) -> {true, {create_dir, NewDir, OldDir, Files2}} end; -do_filter_spec(Path, {archive, Archive, Options, Files}, InclRegexps, ExclRegexps) -> +do_filter_spec(Path, + {archive, Archive, Options, Files}, + InclRegexps, + ExclRegexps) -> case do_filter_spec(Path, Files, InclRegexps, ExclRegexps) of [] -> case match(Path, InclRegexps, ExclRegexps) of @@ -1085,7 +1319,10 @@ do_filter_spec(Path, {archive, Archive, Options, Files}, InclRegexps, ExclRegexp do_filter_spec(Path, {copy_file, File}, InclRegexps, ExclRegexps) -> Path2 = opt_join(Path, File), match(Path2, InclRegexps, ExclRegexps); -do_filter_spec(Path, {copy_file, NewFile, _OldFile}, InclRegexps, ExclRegexps) -> +do_filter_spec(Path, + {copy_file, NewFile, _OldFile}, + InclRegexps, + ExclRegexps) -> Path2 = opt_join(Path, NewFile), match(Path2, InclRegexps, ExclRegexps); do_filter_spec(Path, {write_file, File, _IoList}, InclRegexps, ExclRegexps) -> @@ -1101,18 +1338,7 @@ opt_join(Path, File) -> filename:join([Path, File]). match(String, InclRegexps, ExclRegexps) -> - %%case - match(String, InclRegexps) andalso not match(String, ExclRegexps). -%% of -%% true -> -%% true; -%% false -> -%% io:format("no match: ~p\n" -%% " incl: ~p\n" -%% " excl: ~p\n", -%% [String, InclRegexps, ExclRegexps]), -%% false -%% end. + match(String, InclRegexps) andalso not match(String, ExclRegexps). %% Match at least one regexp match(_String, []) -> @@ -1131,7 +1357,7 @@ match(String, [#regexp{source = _, compiled = MP} | Regexps]) -> install(RelName, TargetDir) -> try do_install(RelName, TargetDir) - catch + catch throw:{error, Text} -> {error, Text} end. @@ -1148,7 +1374,8 @@ do_install(RelName, TargetDir) -> case os:type() of {win32, _} -> NativeRootDir = filename:nativename(TargetDir2), - %% NativeBinDir = filename:nativename(filename:join([BinDir, "win32"])), + %% NativeBinDir = + %% filename:nativename(filename:join([BinDir, "win32"])), NativeBinDir = filename:nativename(BinDir), IniData = ["[erlang]\r\n", "Bindir=", NativeBinDir, "\r\n", @@ -1157,25 +1384,30 @@ do_install(RelName, TargetDir) -> IniFile = filename:join([BinDir, "erl.ini"]), ok = file:write_file(IniFile, IniData); _ -> - subst_src_scripts(start_scripts(), ErtsBinDir, BinDir, - [{"FINAL_ROOTDIR", TargetDir2}, {"EMU", "beam"}], + subst_src_scripts(start_scripts(), + ErtsBinDir, + BinDir, + [{"FINAL_ROOTDIR", TargetDir2}, + {"EMU", "beam"}], [preserve]) end, RelFile = filename:join([RelDir, RelVsn, RelName ++ ".rel"]), ok = release_handler:create_RELEASES(TargetDir2, RelFile), ok; _ -> - reltool_utils:throw_error("~s: Illegal syntax.\n", [DataFile]) + reltool_utils:throw_error("~s: Illegal data file syntax", [DataFile]) end. subst_src_scripts(Scripts, SrcDir, DestDir, Vars, Opts) -> - Fun = fun(Script) -> subst_src_script(Script, SrcDir, DestDir, Vars, Opts) end, + Fun = fun(Script) -> + subst_src_script(Script, SrcDir, DestDir, Vars, Opts) + end, lists:foreach(Fun, Scripts). -subst_src_script(Script, SrcDir, DestDir, Vars, Opts) -> +subst_src_script(Script, SrcDir, DestDir, Vars, Opts) -> subst_file(filename:join([SrcDir, Script ++ ".src"]), filename:join([DestDir, Script]), - Vars, + Vars, Opts). subst_file(Src, Dest, Vars, Opts) -> diff --git a/lib/reltool/src/reltool_utils.erl b/lib/reltool/src/reltool_utils.erl index 8d52ade9be..39d057d994 100644 --- a/lib/reltool/src/reltool_utils.erl +++ b/lib/reltool/src/reltool_utils.erl @@ -1,25 +1,48 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009. All Rights Reserved. -%% +%% +%% 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% -module(reltool_utils). %% Public --compile([export_all]). +-export([root_dir/0, erl_libs/0, lib_dirs/1, + split_app_name/1, prim_consult/1, + default_rels/0, choose_default/3, + + assign_image_list/1, get_latest_resize/1, + mod_conds/0, list_to_mod_cond/1, mod_cond_to_index/1, + incl_conds/0, list_to_incl_cond/1, incl_cond_to_index/1, elem_to_index/2, + app_dir_test/2, split_app_dir/1, + get_item/1, get_items/1, get_selected_items/3, + select_items/3, select_item/2, + + safe_keysearch/5, print/4, return_first_error/2, add_warning/2, + + create_dir/1, list_dir/1, read_file_info/1, + write_file_info/2, read_file/1, write_file/2, + recursive_delete/1, delete/2, recursive_copy_file/2, copy_file/2, + + throw_error/2, + + decode_regexps/3, + default_val/2, + escript_foldl/3, + + call/2, cast/2, reply/3]). -include_lib("kernel/include/file.hrl"). -include_lib("wx/include/wx.hrl"). @@ -30,11 +53,11 @@ root_dir() -> erl_libs() -> case os:getenv("ERL_LIBS") of - false -> + false -> []; LibStr -> string:tokens(LibStr, ":;") - end. + end. lib_dirs(Dir) -> case erl_prim_loader:list_dir(Dir) of @@ -42,7 +65,7 @@ lib_dirs(Dir) -> [F || F <- Files, filelib:is_dir(filename:join([Dir, F]), erl_prim_loader)]; - error -> + error -> [] end. @@ -55,7 +78,7 @@ split_app_name(Name) -> Elem >= $0, Elem =< $9 -> true; true -> false end - end, + end, case lists:splitwith(Pred, lists:reverse(Name)) of {Vsn, [$- | App]} -> {list_to_atom(lists:reverse(App)), lists:reverse(Vsn)}; @@ -103,23 +126,51 @@ prim_parse(Tokens, Acc) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% default_rels() -> - Kernel = #rel_app{name = kernel, incl_apps = []}, - Stdlib = #rel_app{name = stdlib, incl_apps = []}, - Sasl = #rel_app{name = sasl, incl_apps = []}, + %%Kernel = #rel_app{name = kernel, incl_apps = []}, + %%Stdlib = #rel_app{name = stdlib, incl_apps = []}, + Sasl = #rel_app{name = sasl, incl_apps = []}, [ #rel{name = ?DEFAULT_REL_NAME, vsn = "1.0", - rel_apps = [Kernel, Stdlib]}, + rel_apps = []}, + %%rel_apps = [Kernel, Stdlib]}, #rel{name = "start_sasl", vsn = "1.0", - rel_apps = [Kernel, Sasl, Stdlib]} + rel_apps = [Sasl]} + %%rel_apps = [Kernel, Sasl, Stdlib]} ]. +choose_default(Tag, Profile, InclDefs) + when Profile =:= ?DEFAULT_PROFILE; InclDefs -> + case Tag of + incl_sys_filters -> ?DEFAULT_INCL_SYS_FILTERS; + excl_sys_filters -> ?DEFAULT_EXCL_SYS_FILTERS; + incl_app_filters -> ?DEFAULT_INCL_APP_FILTERS; + excl_app_filters -> ?DEFAULT_EXCL_APP_FILTERS; + embedded_app_type -> ?DEFAULT_EMBEDDED_APP_TYPE + end; +choose_default(Tag, standalone, _InclDefs) -> + case Tag of + incl_sys_filters -> ?STANDALONE_INCL_SYS_FILTERS; + excl_sys_filters -> ?STANDALONE_EXCL_SYS_FILTERS; + incl_app_filters -> ?STANDALONE_INCL_APP_FILTERS; + excl_app_filters -> ?STANDALONE_EXCL_APP_FILTERS; + embedded_app_type -> ?DEFAULT_EMBEDDED_APP_TYPE + end; +choose_default(Tag, embedded, _InclDefs) -> + case Tag of + incl_sys_filters -> ?EMBEDDED_INCL_SYS_FILTERS; + excl_sys_filters -> ?EMBEDDED_EXCL_SYS_FILTERS; + incl_app_filters -> ?EMBEDDED_INCL_APP_FILTERS; + excl_app_filters -> ?EMBEDDED_EXCL_APP_FILTERS; + embedded_app_type -> ?EMBEDDED_APP_TYPE + end. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% assign_image_list(ListCtrl) -> Art = wxImageList:new(16,16), - [wxImageList:add(Art, wxArtProvider:getBitmap(Image, [{size, {16,16}}])) + [wxImageList:add(Art, wxArtProvider:getBitmap(Image, [{size, {16,16}}])) || Image <- ["wxART_ERROR", "wxART_WARNING", "wxART_QUESTION", @@ -206,7 +257,7 @@ split_app_dir(Dir) -> ParentDir = filename:dirname(Dir), Base = filename:basename(Dir), {Name, Vsn} = split_app_name(Base), - Vsn2 = + Vsn2 = try [list_to_integer(N) || N <- string:tokens(Vsn, ".")] catch @@ -276,7 +327,9 @@ get_selected_items(ListCtrl, PrevItem, Acc) -> ItemNo -> case wxListCtrl:getItemText(ListCtrl, ItemNo) of Text when Text =/= ?MISSING_APP_TEXT -> - get_selected_items(ListCtrl, ItemNo, [{ItemNo, Text} | Acc]); + get_selected_items(ListCtrl, + ItemNo, + [{ItemNo, Text} | Acc]); _Text -> get_selected_items(ListCtrl, ItemNo, Acc) end @@ -306,7 +359,8 @@ select_items(ListCtrl, OldItems, NewItems) -> select_item(ListCtrl, NewItems); ValidItems -> %% Some old selections are still valid. Select them again. - lists:foreach(fun(Item) -> select_item(ListCtrl, [Item]) end, ValidItems) + lists:foreach(fun(Item) -> select_item(ListCtrl, [Item]) end, + ValidItems) end. select_item(ListCtrl, [{ItemNo, Text} | Items]) -> @@ -339,7 +393,7 @@ print(_, _, _, _) -> ok. %% -define(SAFE(M,F,A), safe(M, F, A, ?MODULE, ?LINE)). -%% +%% %% safe(M, F, A, Mod, Line) -> %% case catch apply(M, F, A) of %% {'EXIT', Reason} -> @@ -356,7 +410,7 @@ return_first_error(Status, NewError) when is_list(NewError) -> {error, OldError} -> {error, OldError} end. - + add_warning(Status, Warning) -> case Status of {ok, Warnings} -> @@ -376,7 +430,7 @@ create_dir(Dir) -> ok; {error, Reason} -> Text = file:format_error(Reason), - throw_error("create dir ~s: ~s\n", [Dir, Text]) + throw_error("create dir ~s: ~s", [Dir, Text]) end. list_dir(Dir) -> @@ -385,7 +439,7 @@ list_dir(Dir) -> Files; error -> Text = file:format_error(enoent), - throw_error("list dir ~s: ~s\n", [Dir, Text]) + throw_error("list dir ~s: ~s", [Dir, Text]) end. read_file_info(File) -> @@ -394,7 +448,7 @@ read_file_info(File) -> Info; {error, Reason} -> Text = file:format_error(Reason), - throw_error("read file info ~s: ~s\n", [File, Text]) + throw_error("read file info ~s: ~s", [File, Text]) end. write_file_info(File, Info) -> @@ -403,7 +457,7 @@ write_file_info(File, Info) -> ok; {error, Reason} -> Text = file:format_error(Reason), - throw_error("write file info ~s: ~s\n", [File, Text]) + throw_error("write file info ~s: ~s", [File, Text]) end. read_file(File) -> @@ -412,7 +466,7 @@ read_file(File) -> Bin; {error, Reason} -> Text = file:format_error(Reason), - throw_error("read file ~s: ~s\n", [File, Text]) + throw_error("read file ~s: ~s", [File, Text]) end. write_file(File, IoList) -> @@ -421,7 +475,7 @@ write_file(File, IoList) -> ok; {error, Reason} -> Text = file:format_error(Reason), - throw_error("write file ~s: ~s\n", [File, Text]) + throw_error("write file ~s: ~s", [File, Text]) end. recursive_delete(Dir) -> @@ -429,7 +483,8 @@ recursive_delete(Dir) -> true -> case file:list_dir(Dir) of {ok, Files} -> - Fun = fun(F) -> recursive_delete(filename:join([Dir, F])) end, + Fun = + fun(F) -> recursive_delete(filename:join([Dir, F])) end, lists:foreach(Fun, Files), delete(Dir, directory); {error, enoent} -> @@ -514,7 +569,9 @@ decode_regexps(Key, Regexps, _Old) when is_list(Regexps) -> do_decode_regexps(Key, [Regexp | Regexps], Acc) -> case catch re:compile(Regexp, []) of {ok, MP} -> - do_decode_regexps(Key, Regexps, [#regexp{source = Regexp, compiled = MP} | Acc]); + do_decode_regexps(Key, + Regexps, + [#regexp{source = Regexp, compiled = MP} | Acc]); _ -> Text = lists:flatten(io_lib:format("~p", [{Key, Regexp}])), throw({error, "Illegal option: " ++ Text}) @@ -532,8 +589,34 @@ default_val(Val, Default) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +escript_foldl(Fun, Acc, File) -> + case escript:extract(File, [compile_source]) of + {ok, [_Shebang, _Comment, _EmuArgs, Body]} -> + case Body of + {source, BeamCode} -> + GetInfo = fun() -> file:read_file_info(File) end, + GetBin = fun() -> BeamCode end, + {ok, Fun(".", GetInfo, GetBin, Acc)}; + {beam, BeamCode} -> + GetInfo = fun() -> file:read_file_info(File) end, + GetBin = fun() -> BeamCode end, + {ok, Fun(".", GetInfo, GetBin, Acc)}; + {archive, ArchiveBin} -> + zip:foldl(Fun, Acc, {File, ArchiveBin}) + end; + {error, Reason} -> + {error, Reason} + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + call(Name, Msg) when is_atom(Name) -> - call(whereis(Name), Msg); + case whereis(Name) of + undefined -> + {error, {noproc, Name}}; + Pid -> + call(Pid, Msg) + end; call(Pid, Msg) when is_pid(Pid) -> Ref = erlang:monitor(process, Pid), Pid ! {call, self(), Ref, Msg}, diff --git a/lib/reltool/test/Makefile b/lib/reltool/test/Makefile index 00d2add3e5..5109058797 100644 --- a/lib/reltool/test/Makefile +++ b/lib/reltool/test/Makefile @@ -1,19 +1,19 @@ # # %CopyrightBegin% -# -# Copyright Ericsson AB 2009. All Rights Reserved. -# +# +# 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% include $(ERL_TOP)/make/target.mk @@ -25,6 +25,7 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk MODULES= \ rtt \ + reltool_app_SUITE \ reltool_wx_SUITE \ reltool_server_SUITE \ reltool_test_lib @@ -73,7 +74,8 @@ release_spec: opt release_tests_spec: opt $(INSTALL_DIR) $(RELSYSDIR) $(INSTALL_DATA) reltool.spec $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR) - $(INSTALL_PROGRAM) rtt $(INSTALL_PROGS) $(RELSYSDIR) + $(INSTALL_SCRIPT) rtt $(INSTALL_PROGS) $(RELSYSDIR) + $(INSTALL_DATA) $(INSTALL_PROGS) $(RELSYSDIR) # chmod -f -R u+w $(RELSYSDIR) # @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) diff --git a/lib/reltool/test/reltool_app_SUITE.erl b/lib/reltool/test/reltool_app_SUITE.erl new file mode 100644 index 0000000000..f8433f73d0 --- /dev/null +++ b/lib/reltool/test/reltool_app_SUITE.erl @@ -0,0 +1,291 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% +%% + +%% +%%---------------------------------------------------------------------- +%% Purpose: Verify the application specifics of the Reltool application +%%---------------------------------------------------------------------- +-module(reltool_app_SUITE). + +-compile(export_all). + +-include("reltool_test_lib.hrl"). + + +t() -> reltool_test_lib:t(?MODULE). +t(Case) -> reltool_test_lib:t({?MODULE, Case}). + +%% Test server callbacks +init_per_suite(Config) -> + Config2 = reltool_test_lib:init_per_suite(Config), + case is_app(reltool) of + {ok, AppFile} -> + %% io:format("AppFile: ~n~p~n", [AppFile]), + [{app_file, AppFile} | Config2]; + {error, Reason} -> + fail(Reason) + end. + +end_per_suite(Config) -> + reltool_test_lib:end_per_suite(Config). + +init_per_testcase(Case, Config) -> + Config2 = + case Case of + undef_funcs -> + [{tc_timeout, timer:minutes(10)} | Config]; + _ -> + Config + end, + reltool_test_lib:init_per_testcase(Case, Config2). + +end_per_testcase(Func,Config) -> + reltool_test_lib:end_per_testcase(Func,Config). + +fin_per_testcase(Case, Config) -> + reltool_test_lib:end_per_testcase(Case, Config). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +all() -> + all(suite). + +all(suite) -> + [ + fields, + modules, + export_all, + app_depend, + undef_funcs + ]. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +is_app(App) -> + LibDir = code:lib_dir(App), + File = filename:join([LibDir, "ebin", atom_to_list(App) ++ ".app"]), + case file:consult(File) of + {ok, [{application, App, AppFile}]} -> + {ok, AppFile}; + {error, {LineNo, Mod, Code}} -> + IoList = lists:concat([File, ":", LineNo, ": ", + Mod:format_error(Code)]), + {error, list_to_atom(lists:flatten(IoList))} + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +fields(suite) -> + []; +fields(doc) -> + []; +fields(Config) when is_list(Config) -> + AppFile = key1search(app_file, Config), + Fields = [vsn, description, modules, registered, applications], + case check_fields(Fields, AppFile, []) of + [] -> + ok; + Missing -> + fail({missing_fields, Missing}) + end. + +check_fields([], _AppFile, Missing) -> + Missing; +check_fields([Field|Fields], AppFile, Missing) -> + check_fields(Fields, AppFile, check_field(Field, AppFile, Missing)). + +check_field(Name, AppFile, Missing) -> + io:format("checking field: ~p~n", [Name]), + case lists:keymember(Name, 1, AppFile) of + true -> + Missing; + false -> + [Name|Missing] + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +modules(suite) -> + []; +modules(doc) -> + []; +modules(Config) when is_list(Config) -> + AppFile = key1search(app_file, Config), + Mods = key1search(modules, AppFile), + EbinList = get_ebin_mods(reltool), + case missing_modules(Mods, EbinList, []) of + [] -> + ok; + Missing -> + throw({error, {missing_modules, Missing}}) + end, + case extra_modules(Mods, EbinList, []) of + [] -> + ok; + Extra -> + throw({error, {extra_modules, Extra}}) + end, + {ok, Mods}. + +get_ebin_mods(App) -> + LibDir = code:lib_dir(App), + EbinDir = filename:join([LibDir,"ebin"]), + {ok, Files0} = file:list_dir(EbinDir), + Files1 = [lists:reverse(File) || File <- Files0], + [list_to_atom(lists:reverse(Name)) || [$m,$a,$e,$b,$.|Name] <- Files1]. + +missing_modules([], _Ebins, Missing) -> + Missing; +missing_modules([Mod|Mods], Ebins, Missing) -> + case lists:member(Mod, Ebins) of + true -> + missing_modules(Mods, Ebins, Missing); + false -> + io:format("missing module: ~p~n", [Mod]), + missing_modules(Mods, Ebins, [Mod|Missing]) + end. + + +extra_modules(_Mods, [], Extra) -> + Extra; +extra_modules(Mods, [Mod|Ebins], Extra) -> + case lists:member(Mod, Mods) of + true -> + extra_modules(Mods, Ebins, Extra); + false -> + io:format("supefluous module: ~p~n", [Mod]), + extra_modules(Mods, Ebins, [Mod|Extra]) + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +export_all(suite) -> + []; +export_all(doc) -> + []; +export_all(Config) when is_list(Config) -> + AppFile = key1search(app_file, Config), + Mods = key1search(modules, AppFile), + check_export_all(Mods). + + +check_export_all([]) -> + ok; +check_export_all([Mod|Mods]) -> + case (catch apply(Mod, module_info, [compile])) of + {'EXIT', {undef, _}} -> + check_export_all(Mods); + O -> + case lists:keysearch(options, 1, O) of + false -> + check_export_all(Mods); + {value, {options, List}} -> + case lists:member(export_all, List) of + true -> + throw({error, {export_all, Mod}}); + false -> + check_export_all(Mods) + end + end + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +app_depend(suite) -> + []; +app_depend(doc) -> + []; +app_depend(Config) when is_list(Config) -> + AppFile = key1search(app_file, Config), + Apps = key1search(applications, AppFile), + check_apps(Apps). + +check_apps([]) -> + ok; +check_apps([App|Apps]) -> + case is_app(App) of + {ok, _} -> + check_apps(Apps); + Error -> + throw({error, {missing_app, {App, Error}}}) + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +undef_funcs(suite) -> + []; +undef_funcs(doc) -> + []; +undef_funcs(Config) when is_list(Config) -> + App = reltool, + AppFile = key1search(app_file, Config), + Mods = key1search(modules, AppFile), + Root = code:root_dir(), + LibDir = code:lib_dir(App), + EbinDir = filename:join([LibDir,"ebin"]), + XRefTestName = undef_funcs_make_name(App, xref_test_name), + {ok, XRef} = xref:start(XRefTestName), + ok = xref:set_default(XRef, + [{verbose,false},{warnings,false}]), + XRefName = undef_funcs_make_name(App, xref_name), + {ok, XRefName} = xref:add_release(XRef, Root, {name,XRefName}), + {ok, App} = xref:replace_application(XRef, App, EbinDir), + {ok, Undefs} = xref:analyze(XRef, undefined_function_calls), + xref:stop(XRef), + analyze_undefined_function_calls(Undefs, Mods, []). + +analyze_undefined_function_calls([], _, []) -> + ok; +analyze_undefined_function_calls([], _, AppUndefs) -> + exit({suite_failed, {undefined_function_calls, AppUndefs}}); +analyze_undefined_function_calls([{{Mod, _F, _A}, _C} = AppUndef|Undefs], + AppModules, AppUndefs) -> + %% Check that this module is our's + case lists:member(Mod,AppModules) of + true -> + {Calling,Called} = AppUndef, + {Mod1,Func1,Ar1} = Calling, + {Mod2,Func2,Ar2} = Called, + io:format("undefined function call: " + "~n ~w:~w/~w calls ~w:~w/~w~n", + [Mod1,Func1,Ar1,Mod2,Func2,Ar2]), + analyze_undefined_function_calls(Undefs, AppModules, + [AppUndef|AppUndefs]); + false -> + io:format("dropping ~p~n", [Mod]), + analyze_undefined_function_calls(Undefs, AppModules, AppUndefs) + end. + +%% This function is used simply to avoid cut-and-paste errors later... +undef_funcs_make_name(App, PostFix) -> + list_to_atom(atom_to_list(App) ++ "_" ++ atom_to_list(PostFix)). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +fail(Reason) -> + exit({suite_failed, Reason}). + +key1search(Key, L) -> + case lists:keysearch(Key, 1, L) of + false -> + fail({not_found, Key, L}); + {value, {Key, Value}} -> + Value + end. diff --git a/lib/reltool/test/reltool_server_SUITE.erl b/lib/reltool/test/reltool_server_SUITE.erl index cf951191a0..faf1bdbba2 100644 --- a/lib/reltool/test/reltool_server_SUITE.erl +++ b/lib/reltool/test/reltool_server_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009. All Rights Reserved. -%% +%% +%% 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% -module(reltool_server_SUITE). @@ -26,11 +26,13 @@ -include("reltool_test_lib.hrl"). -define(NODE_NAME, '__RELTOOL__TEMPORARY_TEST__NODE__'). +-define(WORK_DIR, "reltool_work_dir"). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Initialization functions. init_per_suite(Config) -> + ?ignore(file:make_dir(?WORK_DIR)), reltool_test_lib:init_per_suite(Config). end_per_suite(Config) -> @@ -128,8 +130,7 @@ create_release(_Config) -> {value, {_, _, StdlibVsn}} = lists:keysearch(stdlib, 1, Apps), Rel = {release, {RelName, RelVsn}, {erts, ErtsVsn}, - [{kernel, KernelVsn}, - {stdlib, StdlibVsn}]}, + [{kernel, KernelVsn}, {stdlib, StdlibVsn}]}, ?m({ok, Rel}, reltool:get_rel([{config, Config}], RelName)), ok. @@ -159,15 +160,17 @@ create_script(_Config) -> Rel = {release, {RelName, RelVsn}, {erts, ErtsVsn}, - [{stdlib, StdlibVsn}, {kernel, KernelVsn}]}, + [{kernel, KernelVsn}, {stdlib, StdlibVsn}]}, ?m({ok, Rel}, reltool:get_rel(Pid, RelName)), - RelFile = RelName ++ ".rel", - ?m(ok, file:write_file(RelFile, io_lib:format("~p.\n", [Rel]))), + ?m(ok, file:write_file(filename:join([?WORK_DIR, RelName ++ ".rel"]), + io_lib:format("~p.\n", [Rel]))), %% Generate script file + {ok, Cwd} = file:get_cwd(), + ?m(ok, file:set_cwd(?WORK_DIR)), ?m(ok, systools:make_script(RelName, [])), - ScriptFile = RelName ++ ".script", - {ok, [OrigScript]} = ?msym({ok, [_]}, file:consult(ScriptFile)), + {ok, [OrigScript]} = ?msym({ok, [_]}, file:consult(RelName ++ ".script")), + ?m(ok, file:set_cwd(Cwd)), {ok, Script} = ?msym({ok, _}, reltool:get_script(Pid, RelName)), %% OrigScript2 = sort_script(OrigScript), %% Script2 = sort_script(Script), @@ -201,9 +204,10 @@ create_target(_Config) -> ]}, %% Generate target file - TargetDir = "reltool_target_dir_development", + TargetDir = filename:join([?WORK_DIR, "target_development"]), ?m(ok, reltool_utils:recursive_delete(TargetDir)), ?m(ok, file:make_dir(TargetDir)), + ?log("SPEC: ~p\n", [reltool:get_target_spec([{config, Config}])]), ?m(ok, reltool:create_target([{config, Config}], TargetDir)), Erl = filename:join([TargetDir, "bin", "erl"]), @@ -234,7 +238,7 @@ create_embedded(_Config) -> ]}, %% Generate target file - TargetDir = "reltool_target_dir_embedded", + TargetDir = filename:join([?WORK_DIR, "target_embedded"]), ?m(ok, reltool_utils:recursive_delete(TargetDir)), ?m(ok, file:make_dir(TargetDir)), ?m(ok, reltool:create_target([{config, Config}], TargetDir)), @@ -264,7 +268,7 @@ create_standalone(_Config) -> ]}, %% Generate target file - TargetDir = "reltool_target_dir_standalone", + TargetDir = filename:join([?WORK_DIR, "target_standalone"]), ?m(ok, reltool_utils:recursive_delete(TargetDir)), ?m(ok, file:make_dir(TargetDir)), ?m(ok, reltool:create_target([{config, Config}], TargetDir)), @@ -290,6 +294,8 @@ create_standalone(_Config) -> create_old_target(TestInfo) when is_atom(TestInfo) -> reltool_test_lib:tc_info(TestInfo); create_old_target(_Config) -> + ?skip("Old style of target", []), + %% Configure the server RelName1 = "Just testing", RelName2 = "Just testing with SASL", @@ -306,7 +312,7 @@ create_old_target(_Config) -> ]}, %% Generate target file - TargetDir = "reltool_target_dir_old", + TargetDir = filename:join([?WORK_DIR, "target_old_style"]), ?m(ok, reltool_utils:recursive_delete(TargetDir)), ?m(ok, file:make_dir(TargetDir)), ?m(ok, reltool:create_target([{config, Config}], TargetDir)), diff --git a/lib/reltool/test/reltool_test_lib.erl b/lib/reltool/test/reltool_test_lib.erl index 25978294ee..5390b0a75e 100644 --- a/lib/reltool/test/reltool_test_lib.erl +++ b/lib/reltool/test/reltool_test_lib.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009. All Rights Reserved. -%% +%% +%% 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% -module(reltool_test_lib). @@ -24,9 +24,11 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% init_per_suite(Config) when is_list(Config)-> + global:register_name(reltool_global_logger, group_leader()), incr_timetrap(Config, 5). end_per_suite(Config) when is_list(Config)-> + global:unregister_name(reltool_global_logger), ok. incr_timetrap(Config, Times) -> @@ -130,11 +132,9 @@ wx_end_per_suite(Config) -> init_per_testcase(_Func, Config) when is_list(Config) -> set_kill_timer(Config), - global:register_name(reltool_global_logger, group_leader()), Config. end_per_testcase(_Func, Config) when is_list(Config) -> - global:unregister_name(reltool_global_logger), reset_kill_timer(Config), Config. diff --git a/lib/reltool/test/reltool_test_lib.hrl b/lib/reltool/test/reltool_test_lib.hrl index 93134144ea..b592ebb2f0 100644 --- a/lib/reltool/test/reltool_test_lib.hrl +++ b/lib/reltool/test/reltool_test_lib.hrl @@ -1,23 +1,24 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009. All Rights Reserved. -%% +%% +%% 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% -include_lib("wx/include/wx.hrl"). +-define(flat_format(Format,Args), lists:flatten(io_lib:format(Format,Args))). -define(log(Format,Args), reltool_test_lib:log(Format,Args,?FILE,?LINE)). -define(warning(Format,Args), ?log("<WARNING>\n " ++ Format,Args)). -define(error(Format,Args), reltool_test_lib:error(Format,Args,?FILE,?LINE)). diff --git a/lib/reltool/test/rtt b/lib/reltool/test/rtt index 2411195338..1f93396196 100755 --- a/lib/reltool/test/rtt +++ b/lib/reltool/test/rtt @@ -1,19 +1,19 @@ #! /bin/sh -f # %CopyrightBegin% -# -# Copyright Ericsson AB 2009. All Rights Reserved. -# +# +# 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% # Usage: rtt [-cerl] <args to erlang startup script> @@ -23,7 +23,7 @@ while [ $# -gt 0 ]; do case "$1" in "-cerl") shift - emu=cerl + emu="$ERL_TOP/bin/cerl" ;; *) break diff --git a/lib/reltool/vsn.mk b/lib/reltool/vsn.mk index 118827a449..9e0bce1d01 100644 --- a/lib/reltool/vsn.mk +++ b/lib/reltool/vsn.mk @@ -1,9 +1 @@ -RELTOOL_VSN = 0.5.3 - -TICKETS = 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 +RELTOOL_VSN = 0.5.4 diff --git a/lib/runtime_tools/c_src/trace_file_drv.c b/lib/runtime_tools/c_src/trace_file_drv.c index 482fcc0288..cd54f36af0 100644 --- a/lib/runtime_tools/c_src/trace_file_drv.c +++ b/lib/runtime_tools/c_src/trace_file_drv.c @@ -520,7 +520,7 @@ static int do_write(FILETYPE fd, unsigned char *buff, int siz) { */ static int my_write(TraceFileData *data, unsigned char *buff, int siz) { - int wrote, w; + int wrote; if (data->buff_siz - data->buff_pos >= siz) { memcpy(data->buff + data->buff_pos, buff, siz); diff --git a/lib/runtime_tools/doc/src/erts_alloc_config.xml b/lib/runtime_tools/doc/src/erts_alloc_config.xml index 5e7cbe4172..6acf498411 100644 --- a/lib/runtime_tools/doc/src/erts_alloc_config.xml +++ b/lib/runtime_tools/doc/src/erts_alloc_config.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>2007</year><year>2009</year> + <year>2007</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>erts_alloc_config</title> @@ -68,7 +68,7 @@ command-line flag to the Erlang runtime system you are going to use for creation of the allocator configuration. It will disable features that prevent <c>erts_alloc_config</c> from - doing it's job. Note, you should <em>not</em> use this flag + doing its job. Note, you should <em>not</em> use this flag when using the created configuration. Also note that it is important that you use the same <seealso marker="erts:erl#+S">amount of schedulers</seealso> diff --git a/lib/runtime_tools/doc/src/notes.xml b/lib/runtime_tools/doc/src/notes.xml index 9eb13727c7..92629c18e5 100644 --- a/lib/runtime_tools/doc/src/notes.xml +++ b/lib/runtime_tools/doc/src/notes.xml @@ -31,6 +31,42 @@ <p>This document describes the changes made to the Runtime_Tools application.</p> +<section><title>Runtime_Tools 1.8.4.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Minor corrections and removal of a temporary workaround.</p> + <p> + Own Id: OTP-8755 Aux Id: seq-11628, seq-11639 </p> + </item> + <item> + <p> + Small fix in inviso_autostart_server.</p> + <p> + Own Id: OTP-8783 Aux Id: seq11628 </p> + </item> + </list> + </section> + +</section> + +<section><title>Runtime_Tools 1.8.4</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Miscellaneous updates.</p> + <p> + Own Id: OTP-8705</p> + </item> + </list> + </section> + +</section> + <section><title>Runtime_Tools 1.8.3</title> <section><title>Improvements and New Features</title> diff --git a/lib/runtime_tools/src/dbg.erl b/lib/runtime_tools/src/dbg.erl index 66ac0422eb..56283f4d3d 100644 --- a/lib/runtime_tools/src/dbg.erl +++ b/lib/runtime_tools/src/dbg.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(dbg). @@ -945,7 +945,7 @@ dhandler(end_of_trace, Out) -> dhandler(Trace, Out) when element(1, Trace) == trace, tuple_size(Trace) >= 3 -> dhandler1(Trace, tuple_size(Trace), Out); dhandler(Trace, Out) when element(1, Trace) == trace_ts, tuple_size(Trace) >= 4 -> - dhandler1(Trace, tuple_size(Trace)-1, Out); + dhandler1(Trace, tuple_size(Trace)-1, element(tuple_size(Trace),Trace), Out); dhandler(Trace, Out) when element(1, Trace) == drop, tuple_size(Trace) =:= 2 -> io:format(Out, "*** Dropped ~p messages.~n", [element(2,Trace)]), Out; @@ -978,24 +978,18 @@ dhandler(_Trace, Out) -> Out. dhandler1(Trace, Size, Out) -> -%%%! Self = self(), From = element(2, Trace), case element(3, Trace) of 'receive' -> case element(4, Trace) of {dbg,ok} -> ok; - Message -> io:format(Out, "(~p) << ~p~n", [From,Message]) + Message -> + io:format(Out, "(~p) << ~p~n", [From,Message]) end; 'send' -> Message = element(4, Trace), - case element(5, Trace) of -%%%! This causes messages to disappear when used by ttb (observer). Tests -%%%! so far show that there is no difference in results with dbg even if I -%%%! comment it out, so I hope this is only some old code which isn't -%%%! needed anymore... /siri -%%%! Self -> ok; - To -> io:format(Out, "(~p) ~p ! ~p~n", [From,To,Message]) - end; + To = element(5, Trace), + io:format(Out, "(~p) ~p ! ~p~n", [From,To,Message]); call -> case element(4, Trace) of MFA when Size == 5 -> @@ -1028,6 +1022,51 @@ dhandler1(Trace, Size, Out) -> end, Out. +dhandler1(Trace, Size, TS, Out) -> + From = element(2, Trace), + case element(3, Trace) of + 'receive' -> + case element(4, Trace) of + {dbg,ok} -> ok; + Message -> + io:format(Out, "(~p) << ~p (Timestamp: ~p)~n", [From,Message,TS]) + end; + 'send' -> + Message = element(4, Trace), + To = element(5, Trace), + io:format(Out, "(~p) ~p ! ~p (Timestamp: ~p)~n", [From,To,Message,TS]); + call -> + case element(4, Trace) of + MFA when Size == 5 -> + Message = element(5, Trace), + io:format(Out, "(~p) call ~s (~p) (Timestamp: ~p)~n", [From,ffunc(MFA),Message,TS]); + MFA -> + io:format(Out, "(~p) call ~s (Timestamp: ~p)~n", [From,ffunc(MFA),TS]) + end; + return -> %% To be deleted... + case element(4, Trace) of + MFA when Size == 5 -> + Ret = element(5, Trace), + io:format(Out, "(~p) old_ret ~s -> ~p (Timestamp: ~p)~n", [From,ffunc(MFA),Ret,TS]); + MFA -> + io:format(Out, "(~p) old_ret ~s (Timestamp: ~p)~n", [From,ffunc(MFA),TS]) + end; + return_from -> + MFA = element(4, Trace), + Ret = element(5, Trace), + io:format(Out, "(~p) returned from ~s -> ~p (Timestamp: ~p)~n", [From,ffunc(MFA),Ret,TS]); + return_to -> + MFA = element(4, Trace), + io:format(Out, "(~p) returning to ~s (Timestamp: ~p)~n", [From,ffunc(MFA),TS]); + spawn when Size == 5 -> + Pid = element(4, Trace), + MFA = element(5, Trace), + io:format(Out, "(~p) spawn ~p as ~s (Timestamp: ~p)~n", [From,Pid,ffunc(MFA),TS]); + Op -> + io:format(Out, "(~p) ~p ~s (Timestamp: ~p)~n", [From,Op,ftup(Trace,4,Size),TS]) + end, + Out. + %%% These f* functions returns non-flat strings diff --git a/lib/runtime_tools/src/inviso_autostart.erl b/lib/runtime_tools/src/inviso_autostart.erl index 134133ad1f..787292e244 100644 --- a/lib/runtime_tools/src/inviso_autostart.erl +++ b/lib/runtime_tools/src/inviso_autostart.erl @@ -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 @@ -59,17 +59,10 @@ autostart(_AutoModArgs) -> case try_load_module(FileNames) of ok -> autostart_apply(M,F); + false -> % No such module available "inviso_autostart.config" end; - {ok,{gettia_asc,asc_file}} -> % Uggly hack to not have to change in GSN-CPS. - case try_load_module(["/tmp/DPE_COMMONLOG/gettia_asc", - "/tmp/DPE_COMMONLOG/gettia_overload"]) of - ok -> - autostart_apply(gettia_asc,asc_file); - false -> % No such module available - false - end; {ok,{M,F}} -> % Use M:F(node()) autostart_apply(M,F); {ok,no_autostart} -> diff --git a/lib/runtime_tools/src/inviso_autostart_server.erl b/lib/runtime_tools/src/inviso_autostart_server.erl index 5af96e4e39..1e352822f4 100644 --- a/lib/runtime_tools/src/inviso_autostart_server.erl +++ b/lib/runtime_tools/src/inviso_autostart_server.erl @@ -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 @@ -84,7 +84,7 @@ init(ArgsFromConfig) -> case get_tracerdata_opts(ArgsFromConfig) of {ok,TracerData} -> % Otherwise we can not start a trace! case inviso_rt:init_tracing(TracerData) of - {ok,_} -> % Ok, tracing has been initiated. + {ok,_Response} -> % Ok, tracing has been initiated. case get_cmdfiles_opts(ArgsFromConfig) of {ok,CmdFiles} -> % List of cmd-files. Bindings=get_initialbindings_opts(ArgsFromConfig), @@ -164,11 +164,11 @@ interpret_cmd_files([{FileName,LocalBindings}|Rest],GlobalBindings,Translations, Bindings=join_local_and_global_vars(LocalBindings,GlobalBindings), interpret_cmd_files_1(FileName,Bindings,Translations,Dbg), interpret_cmd_files(Rest,GlobalBindings,Translations,Dbg); -interpret_cmd_files([FileName|Rest],GlobalBindings,Translations,Dbg) -> - interpret_cmd_files_1(FileName,GlobalBindings,Translations,Dbg), - interpret_cmd_files(Rest,GlobalBindings,Translations,Dbg); interpret_cmd_files([],_,_,_) -> % Done, return nothing significant! - true. + true; +interpret_cmd_files(FileName,GlobalBindings,Translations,Dbg) -> + interpret_cmd_files_1(FileName,GlobalBindings,Translations,Dbg). +% interpret_cmd_files(Rest,GlobalBindings,Translations,Dbg). %% This is "inline" inviso calls. interpret_cmd_files_1({inviso,F,Args},Bindings,Translations,Dbg) -> diff --git a/lib/runtime_tools/vsn.mk b/lib/runtime_tools/vsn.mk index 4bbdef19de..8be4ae613b 100644 --- a/lib/runtime_tools/vsn.mk +++ b/lib/runtime_tools/vsn.mk @@ -1 +1 @@ -RUNTIME_TOOLS_VSN = 1.8.3 +RUNTIME_TOOLS_VSN = 1.8.4.1 diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml index d5d6605b64..493e7aa092 100644 --- a/lib/snmp/doc/src/notes.xml +++ b/lib/snmp/doc/src/notes.xml @@ -32,7 +32,23 @@ <file>notes.xml</file> </header> - <section> + <section><title>SNMP 4.18</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <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> + +<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> diff --git a/lib/snmp/doc/src/snmpa.xml b/lib/snmp/doc/src/snmpa.xml index 1be6abe6dd..f546724a78 100644 --- a/lib/snmp/doc/src/snmpa.xml +++ b/lib/snmp/doc/src/snmpa.xml @@ -1233,7 +1233,7 @@ snmp_agent:register_subagent(SA1,[1,2,3], SA2). </type> <desc> <p>Restart the worker process of a multi-threaded agent.</p> - <p>This is a utility function, that can be usefull when + <p>This is a utility function, that can be useful when e.g. debugging instrumentation functions.</p> <marker id="restart_set_worker"></marker> @@ -1249,7 +1249,7 @@ snmp_agent:register_subagent(SA1,[1,2,3], SA2). </type> <desc> <p>Restart the set worker process of a multi-threaded agent.</p> - <p>This is a utility function, that can be usefull when + <p>This is a utility function, that can be useful when e.g. debugging instrumentation functions.</p> <marker id="verbosity"></marker> diff --git a/lib/snmp/examples/ex2/snmp_ex2_manager.erl b/lib/snmp/examples/ex2/snmp_ex2_manager.erl index 79cfd94469..ff873327bc 100644 --- a/lib/snmp/examples/ex2/snmp_ex2_manager.erl +++ b/lib/snmp/examples/ex2/snmp_ex2_manager.erl @@ -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 @@ -25,6 +25,8 @@ -behaviour(gen_server). -behaviour(snmpm_user). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([start_link/0, start_link/1, stop/0, agent/2, sync_get/2, diff --git a/lib/snmp/examples/ex2/snmp_ex2_simple_standard_test.erl b/lib/snmp/examples/ex2/snmp_ex2_simple_standard_test.erl index 16fe79d1a5..81939dd614 100644 --- a/lib/snmp/examples/ex2/snmp_ex2_simple_standard_test.erl +++ b/lib/snmp/examples/ex2/snmp_ex2_simple_standard_test.erl @@ -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 @@ -22,6 +22,8 @@ -module(snmp_ex2_simple_standard_test). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([start/0, start/1, start/3]). -include_lib("snmp/include/snmp_types.hrl"). diff --git a/lib/snmp/src/agent/snmp_community_mib.erl b/lib/snmp/src/agent/snmp_community_mib.erl index a2ee7bf0c9..8f0f4cad73 100644 --- a/lib/snmp/src/agent/snmp_community_mib.erl +++ b/lib/snmp/src/agent/snmp_community_mib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. +%% 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 @@ -18,6 +18,8 @@ %% -module(snmp_community_mib). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([configure/1, reconfigure/1, snmpCommunityTable/1, snmpCommunityTable/3, snmpTargetAddrExtTable/3, diff --git a/lib/snmp/src/agent/snmp_framework_mib.erl b/lib/snmp/src/agent/snmp_framework_mib.erl index 0916e2ec74..d9bf7e8551 100644 --- a/lib/snmp/src/agent/snmp_framework_mib.erl +++ b/lib/snmp/src/agent/snmp_framework_mib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. +%% 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 @@ -37,6 +37,8 @@ %%% over all known contexts. %%%----------------------------------------------------------------- %% External exports +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([init/0, configure/1]). -export([intContextTable/1, intContextTable/3, intAgentUDPPort/1, intAgentIpAddress/1, diff --git a/lib/snmp/src/agent/snmp_generic.erl b/lib/snmp/src/agent/snmp_generic.erl index 508aa090d9..06afa68d96 100644 --- a/lib/snmp/src/agent/snmp_generic.erl +++ b/lib/snmp/src/agent/snmp_generic.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. +%% Copyright Ericsson AB 1996-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 @@ -18,6 +18,8 @@ %% -module(snmp_generic). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([variable_func/2, variable_func/3, variable_get/1, variable_set/2]). -export([table_func/2, table_func/4, table_set_row/5, table_set_cols/3, table_set_cols/4, diff --git a/lib/snmp/src/agent/snmp_notification_mib.erl b/lib/snmp/src/agent/snmp_notification_mib.erl index 16e43f05d7..1cd69b430f 100644 --- a/lib/snmp/src/agent/snmp_notification_mib.erl +++ b/lib/snmp/src/agent/snmp_notification_mib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% Copyright Ericsson AB 1998-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 @@ -18,6 +18,8 @@ %% -module(snmp_notification_mib). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([configure/1, reconfigure/1, invalidate_cache/0, snmpNotifyTable/1, snmpNotifyTable/3, snmpNotifyFilterTable/3, snmpNotifyFilterProfileTable/3, diff --git a/lib/snmp/src/agent/snmp_standard_mib.erl b/lib/snmp/src/agent/snmp_standard_mib.erl index 3928a8afe6..639172401d 100644 --- a/lib/snmp/src/agent/snmp_standard_mib.erl +++ b/lib/snmp/src/agent/snmp_standard_mib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. +%% Copyright Ericsson AB 1996-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 @@ -33,6 +33,8 @@ -define(disabled, 2). %% External exports +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([configure/1, reconfigure/1, reset/0, sys_up_time/0, sys_up_time/1, snmp_enable_authen_traps/1, snmp_enable_authen_traps/2, sys_object_id/1, sys_object_id/2, sys_or_table/3, diff --git a/lib/snmp/src/agent/snmp_target_mib.erl b/lib/snmp/src/agent/snmp_target_mib.erl index a3ac67b533..3c32d1f59f 100644 --- a/lib/snmp/src/agent/snmp_target_mib.erl +++ b/lib/snmp/src/agent/snmp_target_mib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% Copyright Ericsson AB 1998-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 @@ -18,6 +18,8 @@ %% -module(snmp_target_mib). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([configure/1, reconfigure/1, snmpTargetSpinLock/1, snmpTargetSpinLock/2, snmpTargetAddrTable/1, snmpTargetAddrTable/3, diff --git a/lib/snmp/src/agent/snmp_user_based_sm_mib.erl b/lib/snmp/src/agent/snmp_user_based_sm_mib.erl index 7b881f888c..f40bb1a5b9 100644 --- a/lib/snmp/src/agent/snmp_user_based_sm_mib.erl +++ b/lib/snmp/src/agent/snmp_user_based_sm_mib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. +%% 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 @@ -18,6 +18,8 @@ %% -module(snmp_user_based_sm_mib). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([configure/1, reconfigure/1, usmUserSpinLock/1, usmUserSpinLock/2, usmUserTable/1, usmUserTable/3, diff --git a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl index 873ab00545..657207b36e 100644 --- a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl +++ b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. +%% 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 @@ -18,6 +18,8 @@ %% -module(snmp_view_based_acm_mib). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([configure/1, reconfigure/1, table_next/2, get/3]). -export([vacmAccessTable/1, vacmAccessTable/3, diff --git a/lib/snmp/src/agent/snmpa_conf.erl b/lib/snmp/src/agent/snmpa_conf.erl index b14a0c806c..b4fc716b3e 100644 --- a/lib/snmp/src/agent/snmpa_conf.erl +++ b/lib/snmp/src/agent/snmpa_conf.erl @@ -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 @@ -19,6 +19,8 @@ -module(snmpa_conf). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([ %% agent.conf agent_entry/2, diff --git a/lib/snmp/src/agent/snmpa_target_cache.erl b/lib/snmp/src/agent/snmpa_target_cache.erl index 6fdecacc68..2aa35aa46a 100644 --- a/lib/snmp/src/agent/snmpa_target_cache.erl +++ b/lib/snmp/src/agent/snmpa_target_cache.erl @@ -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 @@ -21,6 +21,8 @@ -behaviour(gen_server). %% External exports +%% Avoid warning for local function demonitor/1 clashing with autoimported BIF. +-compile({no_auto_import,[demonitor/1]}). -export([start_link/2, stop/0, verbosity/1]). -export([ diff --git a/lib/snmp/src/agent/snmpa_usm.erl b/lib/snmp/src/agent/snmpa_usm.erl index ae584bb3c1..f35d1f1916 100644 --- a/lib/snmp/src/agent/snmpa_usm.erl +++ b/lib/snmp/src/agent/snmpa_usm.erl @@ -18,6 +18,10 @@ %% -module(snmpa_usm). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). +%% Avoid warning for local function error/2 clashing with autoimported BIF. +-compile({no_auto_import,[error/2]}). -export([ process_incoming_msg/4, process_incoming_msg/5, generate_outgoing_msg/5, generate_outgoing_msg/6, diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src index 2bd26e11db..2375e3df70 100644 --- a/lib/snmp/src/app/snmp.appup.src +++ b/lib/snmp/src/app/snmp.appup.src @@ -22,134 +22,43 @@ %% ----- U p g r a d e ------------------------------------------------------- [ - {"4.17", - [ - {load_module, snmpa_net_if, soft_purge, soft_purge, []} - ] - }, - {"4.16.2", + {"4.17.1", [ - {load_module, snmp_log, soft_purge, soft_purge, []}, - {load_module, snmpa, soft_purge, soft_purge, [snmpa_agent]}, - {load_module, snmpa_mpd, soft_purge, soft_purge, [snmpa_usm]}, + {load_module, snmp_community_mib, soft_purge, soft_purge, []}, + {load_module, snmp_framework_mib, soft_purge, soft_purge, []}, + {load_module, snmp_generic, soft_purge, soft_purge, []}, + {load_module, snmp_notification_mib, soft_purge, soft_purge, []}, + {load_module, snmp_standard_mib, soft_purge, soft_purge, []}, + {load_module, snmp_target_mib, soft_purge, soft_purge, []}, + {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, []}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmpa_conf, soft_purge, soft_purge, []}, + {update, snmpa_target_cache, soft, soft_purge, soft_purge, []}, {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, []} - ] - }, - {"4.16.1", - [ - {load_module, snmp_log, soft_purge, soft_purge, []}, - {load_module, snmp_pdus, soft_purge, soft_purge, []}, - {load_module, snmp_usm, soft_purge, soft_purge, []}, - - {load_module, snmpa, soft_purge, soft_purge, [snmpa_agent]}, - {load_module, snmpa_mpd, soft_purge, soft_purge, [snmpa_usm]}, - {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, []} - ] - }, - {"4.16", - [ - {load_module, snmp_log, soft_purge, soft_purge, []}, - {load_module, snmp_pdus, soft_purge, soft_purge, []}, - {load_module, snmp_usm, soft_purge, soft_purge, []}, - - {load_module, snmpa, soft_purge, soft_purge, [snmpa_agent]}, - {load_module, snmpa_general_db, soft_purge, soft_purge, []}, - {load_module, snmpa_mpd, soft_purge, soft_purge, [snmpa_usm]}, - {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, []}, - {update, snmpm_server, soft, soft_purge, soft_purge, []} - ] - }, - {"4.15", - [ - {load_module, snmp_config, soft_purge, soft_purge, []}, - {load_module, snmp_log, soft_purge, soft_purge, []}, - {load_module, snmp_pdus, soft_purge, soft_purge, []}, - {load_module, snmp_usm, soft_purge, soft_purge, []}, - - {load_module, snmpa, soft_purge, soft_purge, [snmp_log, snmpa_agent]}, - {load_module, snmpa_general_db, soft_purge, soft_purge, []}, - {load_module, snmpa_mpd, soft_purge, soft_purge, [snmpa_usm]}, - {load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]}, - {update, snmpa_net_if, {advanced, upgrade_from_pre_4_16}, - soft_purge, soft_purge, [snmpa_agent, snmp_log]}, - {update, snmpa_mib, soft, soft_purge, soft_purge, []}, - {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mib]}, - - {load_module, snmpm_mpd, soft_purge, soft_purge, []}, - {update, snmpm_net_if, {advanced, upgrade_from_pre_4_16}, - soft_purge, soft_purge, [snmpm_config, snmp_log]}, + {load_module, snmpm, soft_purge, soft_purge, []}, + {load_module, snmpm_conf, soft_purge, soft_purge, []}, {update, snmpm_config, soft, soft_purge, soft_purge, []}, - {update, snmpm_server, soft, soft_purge, soft_purge, []} + {load_module, snmpm_usm, soft_purge, soft_purge, []} ] - }, - {"4.14", + }, + {"4.17", [ - {load_module, snmp_config, soft_purge, soft_purge, []}, - {load_module, snmp_log, soft_purge, soft_purge, []}, - {load_module, snmp_pdus, soft_purge, soft_purge, []}, - {load_module, snmp_usm, soft_purge, soft_purge, []}, - - {load_module, snmpa, soft_purge, soft_purge, [snmp_log, snmpa_agent]}, - {load_module, snmpa_general_db, soft_purge, soft_purge, []}, - {load_module, snmpa_mpd, soft_purge, soft_purge, [snmpa_usm]}, - {load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]}, - {update, snmpa_net_if, {advanced, upgrade_from_pre_4_16}, - soft_purge, soft_purge, [snmp_log, snmpa_agent]}, - {update, snmpa_mib, soft, soft_purge, soft_purge, []}, - {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mib]}, - - {load_module, snmpm_mpd, soft_purge, soft_purge, []}, - {load_module, snmpm_user, soft_purge, soft_purge, []}, - {load_module, snmpm_user_default, soft_purge, soft_purge, [snmpm_user]}, - {update, snmpm_net_if, {advanced, upgrade_from_pre_4_16}, - soft_purge, soft_purge, [snmpm_config, snmp_log]}, + {load_module, snmp_community_mib, soft_purge, soft_purge, []}, + {load_module, snmp_framework_mib, soft_purge, soft_purge, []}, + {load_module, snmp_generic, soft_purge, soft_purge, []}, + {load_module, snmp_notification_mib, soft_purge, soft_purge, []}, + {load_module, snmp_standard_mib, soft_purge, soft_purge, []}, + {load_module, snmp_target_mib, soft_purge, soft_purge, []}, + {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, []}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmpa_conf, soft_purge, soft_purge, []}, + {update, snmpa_target_cache, soft, soft_purge, soft_purge, []}, + {load_module, snmpa_usm, soft_purge, soft_purge, []}, + {load_module, snmpm, soft_purge, soft_purge, []}, + {load_module, snmpm_conf, soft_purge, soft_purge, []}, {update, snmpm_config, soft, soft_purge, soft_purge, []}, - {update, snmpm_server, soft, soft_purge, soft_purge, - [snmpm_user_default]} - ] - }, - {"4.13.5", - [ - {load_module, snmp_config, soft_purge, soft_purge, []}, - {load_module, snmp_log, soft_purge, soft_purge, []}, - {load_module, snmp_pdus, soft_purge, soft_purge, []}, - {load_module, snmp_usm, soft_purge, soft_purge, []}, - - {load_module, snmpa, soft_purge, soft_purge, [snmp_log, snmpa_agent]}, - {load_module, snmpa_general_db, soft_purge, soft_purge, []}, - {load_module, snmpa_mib_data, soft_purge, soft_purge, []}, - {load_module, snmpa_mpd, soft_purge, soft_purge, [snmpa_usm]}, - {load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]}, - {update, snmpa_net_if, {advanced, upgrade_from_pre_4_16}, - soft_purge, soft_purge, [snmpa_agent, snmp_log]}, - {update, snmpa_mib, soft, soft_purge, soft_purge, [snmpa_mib_data]}, - {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mib]}, - - {load_module, snmpm_mpd, soft_purge, soft_purge, []}, - {load_module, snmpm_user, soft_purge, soft_purge, []}, - {load_module, snmpm_user_default, soft_purge, soft_purge, [snmpm_user]}, - {update, snmpm_net_if, {advanced, upgrade_from_pre_4_14}, - soft_purge, soft_purge, [snmpm_config, snmp_log]}, - {update, snmpm_config, soft, soft_purge, soft_purge, []}, - {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_user_default]}, - {add_module, snmpm_net_if_filter}, - {add_module, snmpm_network_interface_filter} + {load_module, snmpm_usm, soft_purge, soft_purge, []}, + {load_module, snmpa_net_if, soft_purge, soft_purge, []} ] } ], @@ -157,136 +66,43 @@ %% ------D o w n g r a d e --------------------------------------------------- [ - {"4.17", + {"4.17.1", [ - {load_module, snmpa_net_if, soft_purge, soft_purge, []} - ] - }, - {"4.16.2", - [ - {load_module, snmp_log, soft_purge, soft_purge, []}, - - {load_module, snmpa, soft_purge, soft_purge, [snmpa_agent]}, - {load_module, snmpa_mpd, soft_purge, soft_purge, [snmpa_usm]}, + {load_module, snmp_community_mib, soft_purge, soft_purge, []}, + {load_module, snmp_framework_mib, soft_purge, soft_purge, []}, + {load_module, snmp_generic, soft_purge, soft_purge, []}, + {load_module, snmp_notification_mib, soft_purge, soft_purge, []}, + {load_module, snmp_standard_mib, soft_purge, soft_purge, []}, + {load_module, snmp_target_mib, soft_purge, soft_purge, []}, + {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, []}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmpa_conf, soft_purge, soft_purge, []}, + {update, snmpa_target_cache, soft, soft_purge, soft_purge, []}, {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, []} - ] - }, - {"4.16.1", - [ - {load_module, snmp_log, soft_purge, soft_purge, []}, - {load_module, snmp_pdus, soft_purge, soft_purge, []}, - {load_module, snmp_usm, soft_purge, soft_purge, []}, - - {load_module, snmpa, soft_purge, soft_purge, [snmpa_agent]}, - {load_module, snmpa_mpd, soft_purge, soft_purge, [snmpa_usm]}, - {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, []} - ] - }, - {"4.16", - [ - {load_module, snmp_log, soft_purge, soft_purge, []}, - {load_module, snmp_pdus, soft_purge, soft_purge, []}, - {load_module, snmp_usm, soft_purge, soft_purge, []}, - - {load_module, snmpa, soft_purge, soft_purge, [snmpa_agent]}, - {load_module, snmpa_general_db, soft_purge, soft_purge, []}, - {load_module, snmpa_mpd, soft_purge, soft_purge, [snmpa_usm]}, - {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, []}, - {update, snmpm_server, soft, soft_purge, soft_purge, []} - ] - }, - {"4.15", - [ - {load_module, snmp_config, soft_purge, soft_purge, []}, - {load_module, snmp_log, soft_purge, soft_purge, []}, - {load_module, snmp_pdus, soft_purge, soft_purge, []}, - {load_module, snmp_usm, soft_purge, soft_purge, []}, - - {load_module, snmpa, soft_purge, soft_purge, [snmpa_agent, snmp_log]}, - {load_module, snmpa_general_db, soft_purge, soft_purge, []}, - {load_module, snmpa_mpd, soft_purge, soft_purge, [snmpa_usm]}, - {load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]}, - {update, snmpa_net_if, {advanced, downgrade_to_pre_4_16}, - soft_purge, soft_purge, [snmpa_agent, snmp_log]}, - {update, snmpa_mib, soft, soft_purge, soft_purge, []}, - {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mib]}, - - {load_module, snmpm_mpd, soft_purge, soft_purge, []}, - {update, snmpm_net_if, {advanced, downgrade_to_pre_4_16}, - soft_purge, soft_purge, [snmpm_config, snmp_log]}, + {load_module, snmpm, soft_purge, soft_purge, []}, + {load_module, snmpm_conf, soft_purge, soft_purge, []}, {update, snmpm_config, soft, soft_purge, soft_purge, []}, - {update, snmpm_server, soft, soft_purge, soft_purge, []} + {load_module, snmpm_usm, soft_purge, soft_purge, []} ] }, - {"4.14", + {"4.17", [ - {load_module, snmp_config, soft_purge, soft_purge, []}, - {load_module, snmp_log, soft_purge, soft_purge, []}, - {load_module, snmp_pdus, soft_purge, soft_purge, []}, - {load_module, snmp_usm, soft_purge, soft_purge, []}, - - {load_module, snmpa, soft_purge, soft_purge, [snmpa_agent, snmp_log]}, - {load_module, snmpa_general_db, soft_purge, soft_purge, []}, - {load_module, snmpa_mpd, soft_purge, soft_purge, [snmpa_usm]}, - {load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]}, - {update, snmpa_net_if, {advanced, downgrade_to_pre_4_16}, - soft_purge, soft_purge, [snmpa_agent, snmp_log]}, - {update, snmpa_mib, soft, soft_purge, soft_purge, []}, - {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mib]}, - - {load_module, snmpm_mpd, soft_purge, soft_purge, []}, - {load_module, snmpm_user, soft_purge, soft_purge, []}, - {load_module, snmpm_user_default, soft_purge, soft_purge, [snmpm_user]}, - {update, snmpm_net_if, {advanced, downgrade_to_pre_4_16}, - soft_purge, soft_purge, [snmpm_config, snmp_log]}, + {load_module, snmp_community_mib, soft_purge, soft_purge, []}, + {load_module, snmp_framework_mib, soft_purge, soft_purge, []}, + {load_module, snmp_generic, soft_purge, soft_purge, []}, + {load_module, snmp_notification_mib, soft_purge, soft_purge, []}, + {load_module, snmp_standard_mib, soft_purge, soft_purge, []}, + {load_module, snmp_target_mib, soft_purge, soft_purge, []}, + {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, []}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmpa_conf, soft_purge, soft_purge, []}, + {update, snmpa_target_cache, soft, soft_purge, soft_purge, []}, + {load_module, snmpa_usm, soft_purge, soft_purge, []}, + {load_module, snmpm, soft_purge, soft_purge, []}, + {load_module, snmpm_conf, soft_purge, soft_purge, []}, {update, snmpm_config, soft, soft_purge, soft_purge, []}, - {update, snmpm_server, soft, soft_purge, soft_purge, - [snmpm_user_default]} - ] - }, - {"4.13.5", - [ - {load_module, snmp_config, soft_purge, soft_purge, []}, - {load_module, snmp_log, soft_purge, soft_purge, []}, - {load_module, snmp_pdus, soft_purge, soft_purge, []}, - {load_module, snmp_usm, soft_purge, soft_purge, []}, - - {load_module, snmpa, soft_purge, soft_purge, [snmp_log, snmpa_agent]}, - {load_module, snmpa_general_db, soft_purge, soft_purge, []}, - {load_module, snmpa_mib_data, soft_purge, soft_purge, []}, - {load_module, snmpa_mpd, soft_purge, soft_purge, [snmpa_usm]}, - {load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]}, - {update, snmpa_net_if, {advanced, downgrade_to_pre_4_16}, - soft_purge, soft_purge, [snmpa_agent, snmp_log]}, - {update, snmpa_mib, soft, soft_purge, soft_purge, [snmpa_mib_data]}, - {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mib]}, - - {load_module, snmpm_mpd, soft_purge, soft_purge, []}, - {load_module, snmpm_user, soft_purge, soft_purge, []}, - {load_module, snmpm_user_default, soft_purge, soft_purge, [snmpm_user]}, - {update, snmpm_net_if, {advanced, downgrade_to_pre_4_14}, - soft_purge, soft_purge, [snmpm_config, snmp_log]}, - {update, snmpm_config, soft, soft_purge, soft_purge, []}, - {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_user_default]}, - - {remove, {snmpm_net_if_filter, soft_purge, brutal_purge}}, - {remove, {snmpm_network_interface_filter, soft_purge, brutal_purge}} + {load_module, snmpm_usm, soft_purge, soft_purge, []}, + {load_module, snmpa_net_if, soft_purge, soft_purge, []} ] } ] diff --git a/lib/snmp/src/compile/snmpc_lib.erl b/lib/snmp/src/compile/snmpc_lib.erl index 4e5bc69f81..4490412e84 100644 --- a/lib/snmp/src/compile/snmpc_lib.erl +++ b/lib/snmp/src/compile/snmpc_lib.erl @@ -20,6 +20,8 @@ -module(snmpc_lib). %% API +%% Avoid warning for local function error/2 clashing with autoimported BIF. +-compile({no_auto_import,[error/2]}). -export([test_father/4, make_ASN1type/1, import/1, makeInternalNode2/2, is_consistent/1, resolve_defval/1, make_variable_info/1, check_trap_name/3, make_table_info/4, get_final_mib/2, set_dir/2, diff --git a/lib/snmp/src/manager/snmpm.erl b/lib/snmp/src/manager/snmpm.erl index 141addf440..5b6321b4c3 100644 --- a/lib/snmp/src/manager/snmpm.erl +++ b/lib/snmp/src/manager/snmpm.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% 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 @@ -24,6 +24,8 @@ %%---------------------------------------------------------------------- %% User interface +%% Avoid warning for local function demonitor/1 clashing with autoimported BIF. +-compile({no_auto_import,[demonitor/1]}). -export([ %% %% Management API diff --git a/lib/snmp/src/manager/snmpm_conf.erl b/lib/snmp/src/manager/snmpm_conf.erl index 75f9c09477..e50508c489 100644 --- a/lib/snmp/src/manager/snmpm_conf.erl +++ b/lib/snmp/src/manager/snmpm_conf.erl @@ -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 @@ -21,6 +21,8 @@ -include_lib("kernel/include/file.hrl"). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([ %% manager.conf manager_entry/2, diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl index b976e8f568..fd6da3e71a 100644 --- a/lib/snmp/src/manager/snmpm_config.erl +++ b/lib/snmp/src/manager/snmpm_config.erl @@ -28,6 +28,8 @@ -behaviour(gen_server). %% External exports +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([start_link/1, stop/0, is_started/0]). -export([register_user/4, unregister_user/1, which_users/0, diff --git a/lib/snmp/src/manager/snmpm_usm.erl b/lib/snmp/src/manager/snmpm_usm.erl index 8cb3062d4b..449127844a 100644 --- a/lib/snmp/src/manager/snmpm_usm.erl +++ b/lib/snmp/src/manager/snmpm_usm.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% 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 @@ -23,6 +23,10 @@ -module(snmpm_usm). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). +%% Avoid warning for local function error/2 clashing with autoimported BIF. +-compile({no_auto_import,[error/2]}). -export([init/0, reset/0, process_incoming_msg/4, generate_outgoing_msg/5]). diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl index 63762ac17b..4d2f5d8f92 100644 --- a/lib/snmp/src/misc/snmp_conf.erl +++ b/lib/snmp/src/misc/snmp_conf.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. +%% Copyright Ericsson AB 1996-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 @@ -23,6 +23,8 @@ %% External exports +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([read_files/2, read/2]). %% Basic (type) check functions diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl index c066680160..25350e08cb 100644 --- a/lib/snmp/src/misc/snmp_config.erl +++ b/lib/snmp/src/misc/snmp_config.erl @@ -22,6 +22,8 @@ -include_lib("kernel/include/file.hrl"). -include("snmp_types.hrl"). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([config/0]). -export([write_config_file/4, append_config_file/4, read_config_file/3]). diff --git a/lib/snmp/src/misc/snmp_usm.erl b/lib/snmp/src/misc/snmp_usm.erl index 3508f9e1c2..df2c1f0b18 100644 --- a/lib/snmp/src/misc/snmp_usm.erl +++ b/lib/snmp/src/misc/snmp_usm.erl @@ -19,6 +19,8 @@ -module(snmp_usm). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([passwd2localized_key/3, localize_key/3]). -export([auth_in/4, auth_out/4, set_msg_auth_params/3]). -export([des_encrypt/3, des_decrypt/3]). diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk index 60eee87974..1229b12ae2 100644 --- a/lib/snmp/vsn.mk +++ b/lib/snmp/vsn.mk @@ -1,40 +1,3 @@ -SNMP_VSN = 4.17.1 +SNMP_VSN = 4.18 PRE_VSN = APP_VSN = "snmp-$(SNMP_VSN)$(PRE_VSN)" - -TICKETS = OTP-8761 - -TICKETS_4_17 = 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/Makefile b/lib/ssh/Makefile index 1ad69a9ca1..b8c7eebcc1 100644 --- a/lib/ssh/Makefile +++ b/lib/ssh/Makefile @@ -1,19 +1,19 @@ # # %CopyrightBegin% -# -# Copyright Ericsson AB 2004-2009. All Rights Reserved. -# +# +# 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% # diff --git a/lib/ssh/doc/src/book.xml b/lib/ssh/doc/src/book.xml index 0375c441af..fcec1d6f70 100644 --- a/lib/ssh/doc/src/book.xml +++ b/lib/ssh/doc/src/book.xml @@ -4,7 +4,7 @@ <book xmlns:xi="http://www.w3.org/2001/XInclude"> <header titlestyle="normal"> <copyright> - <year>2005</year><year>2009</year> + <year>2005</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>SSH</title> diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml index ce18cabfb5..950c249e72 100644 --- a/lib/ssh/doc/src/notes.xml +++ b/lib/ssh/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>SSH Release Notes</title> @@ -29,39 +29,37 @@ <file>notes.xml</file> </header> - <section><title>Ssh 1.1.11</title> + <section><title>Ssh 2.0.1</title> <section><title>Fixed Bugs and Malfunctions</title> <list> <item> <p> - SSH in some cases generated a crash report when a channel - was closed in a normal way.</p> + SSH in some cases terminated channels with reason normal + when it should have been shutdown.</p> <p> - Own Id: OTP-8735 Aux Id: seq11615</p> + Own Id: OTP-8714</p> + </item> + <item> + <p> + SSH in some cases generated a crash report when a channel + was closed in a normal way.</p> + <p> + Own Id: OTP-8735 Aux Id: seq11615 </p> </item> - </list> - </section> - - </section> - - <section><title>Ssh 1.1.10</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> <item> <p> - SSH in some cases terminated channels with reason - normal when it should have been shutdown.</p> + The processes ssh_subsystem_sup and one ssh_channel_sup + was not terminated when a connection was closed.</p> <p> - Own Id: OTP-8714 Aux Id:</p> + Own Id: OTP-8807</p> </item> </list> </section> - </section> +</section> - <section><title>Ssh 1.1.9</title> +<section><title>Ssh 2.0</title> <section><title>Fixed Bugs and Malfunctions</title> <list> @@ -70,7 +68,7 @@ <p>Own Id: OTP-8550 Aux Id:</p> </item> <item> - <p>Aligned error message with used version (SSH_FX_FAILURE vs + <p>Aligned error message with used version (SSH_FX_FAILURE vs SSH_FX_NOT_A_DIRECTORY, the latter introduced in version 6).</p> <p> *** POTENTIAL INCOMPATIBILITY ***</p> @@ -103,6 +101,13 @@ message is not handled correctly.</p> <p>Own Id: OTP-8524 Aux Id:</p> </item> + <item> + <p>Removed deprecated modules (ssh_ssh, ssh_sshd and ssh_cm) and + functions (ssh_sftp:connect and ssh_sftp:stop).</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p>Own Id: OTP-8596 Aux Id:</p> + </item> </list> </section> diff --git a/lib/ssh/doc/src/ref_man.xml b/lib/ssh/doc/src/ref_man.xml index c05c3051b0..9ab56b28ec 100644 --- a/lib/ssh/doc/src/ref_man.xml +++ b/lib/ssh/doc/src/ref_man.xml @@ -4,7 +4,7 @@ <application xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>2004</year><year>2009</year> + <year>2004</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>SSH Reference Manual</title> diff --git a/lib/ssh/doc/src/ssh_sftp.xml b/lib/ssh/doc/src/ssh_sftp.xml index 208b2b4e72..c1f75461b1 100644 --- a/lib/ssh/doc/src/ssh_sftp.xml +++ b/lib/ssh/doc/src/ssh_sftp.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>2005</year><year>2009</year> + <year>2005</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>ssh_sftp</title> diff --git a/lib/ssh/doc/src/ssh_sftpd.xml b/lib/ssh/doc/src/ssh_sftpd.xml index c857983565..b3d64e72b4 100644 --- a/lib/ssh/doc/src/ssh_sftpd.xml +++ b/lib/ssh/doc/src/ssh_sftpd.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>2005</year><year>2009</year> + <year>2005</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>ssh_sftpd</title> diff --git a/lib/ssh/examples/Makefile b/lib/ssh/examples/Makefile index cd8b3c797a..5f17542fb8 100644 --- a/lib/ssh/examples/Makefile +++ b/lib/ssh/examples/Makefile @@ -1,19 +1,19 @@ # # %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 # 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% # diff --git a/lib/ssh/src/Makefile b/lib/ssh/src/Makefile index 7abf06e52b..42880fa80b 100644 --- a/lib/ssh/src/Makefile +++ b/lib/ssh/src/Makefile @@ -1,19 +1,19 @@ # # %CopyrightBegin% -# -# Copyright Ericsson AB 2004-2009. All Rights Reserved. -# +# +# 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% # @@ -56,7 +56,6 @@ MODULES= \ ssh_auth\ ssh_bits \ ssh_cli \ - ssh_cm \ ssh_dsa \ ssh_file \ ssh_io \ @@ -67,8 +66,6 @@ MODULES= \ ssh_sftpd \ ssh_sftpd_file\ ssh_sftpd_file_api \ - ssh_ssh \ - ssh_sshd \ ssh_transport \ ssh_userreg \ ssh_xfer diff --git a/lib/ssh/src/ssh.app.src b/lib/ssh/src/ssh.app.src index 9319f39591..8a3e15841f 100644 --- a/lib/ssh/src/ssh.app.src +++ b/lib/ssh/src/ssh.app.src @@ -14,7 +14,6 @@ ssh_cli, ssh_channel, ssh_channel_sup, - ssh_cm, ssh_connection, ssh_connection_handler, ssh_connection_manager, @@ -32,8 +31,6 @@ ssh_sftpd, ssh_sftpd_file, ssh_sftpd_file_api, - ssh_ssh, - ssh_sshd, ssh_subsystem_sup, ssh_sup, ssh_system_sup, diff --git a/lib/ssh/src/ssh.appup.src b/lib/ssh/src/ssh.appup.src index 82114c9afd..21f7508555 100644 --- a/lib/ssh/src/ssh.appup.src +++ b/lib/ssh/src/ssh.appup.src @@ -1,46 +1,26 @@ %% %% %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% %% {"%VSN%", [ - {"1.1.10", [{load_module, ssh_connection_manager, soft_purge, soft_purge, []}]}, - {"1.1.9", [{load_module, ssh_channel, soft_purge, soft_purge, []}, - {load_module, ssh_connection_manager, soft_purge, soft_purge, []}]}, - {"1.1.8", [{restart_application, ssh}]}, - {"1.1.7", [{restart_application, ssh}]}, - {"1.1.6", [{restart_application, ssh}]}, - {"1.1.5", [{restart_application, ssh}]}, - {"1.1.4", [{restart_application, ssh}]}, - {"1.1.3", [{restart_application, ssh}]}, - {"1.1.2", [{restart_application, ssh}]} ], [ - {"1.1.10", [{load_module, ssh_connection_manager, soft_purge, soft_purge, []}]}, - {"1.1.9", [{load_module, ssh_channel, soft_purge, soft_purge, []}, - {load_module, ssh_connection_manager, soft_purge, soft_purge, []}]}, - {"1.1.8", [{restart_application, ssh}]}, - {"1.1.7", [{restart_application, ssh}]}, - {"1.1.6", [{restart_application, ssh}]}, - {"1.1.5", [{restart_application, ssh}]}, - {"1.1.4", [{restart_application, ssh}]}, - {"1.1.3", [{restart_application, ssh}]}, - {"1.1.2", [{restart_application, ssh}]} ] }. diff --git a/lib/ssh/src/ssh.hrl b/lib/ssh/src/ssh.hrl index 0e4285295c..ac249b05e3 100644 --- a/lib/ssh/src/ssh.hrl +++ b/lib/ssh/src/ssh.hrl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% 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% %% diff --git a/lib/ssh/src/ssh_acceptor_sup.erl b/lib/ssh/src/ssh_acceptor_sup.erl index 707e3d3a5e..f37e1fe4ff 100644 --- a/lib/ssh/src/ssh_acceptor_sup.erl +++ b/lib/ssh/src/ssh_acceptor_sup.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% diff --git a/lib/ssh/src/ssh_app.erl b/lib/ssh/src/ssh_app.erl index 5793d3a321..38659b1a2d 100644 --- a/lib/ssh/src/ssh_app.erl +++ b/lib/ssh/src/ssh_app.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% 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% %% diff --git a/lib/ssh/src/ssh_auth.erl b/lib/ssh/src/ssh_auth.erl index aa74528544..9dbd95886e 100644 --- a/lib/ssh/src/ssh_auth.erl +++ b/lib/ssh/src/ssh_auth.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% diff --git a/lib/ssh/src/ssh_auth.hrl b/lib/ssh/src/ssh_auth.hrl index 80c5a6819b..7d7bad4436 100644 --- a/lib/ssh/src/ssh_auth.hrl +++ b/lib/ssh/src/ssh_auth.hrl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% diff --git a/lib/ssh/src/ssh_bits.erl b/lib/ssh/src/ssh_bits.erl index 21ddc5e8fe..399581a0fd 100755 --- a/lib/ssh/src/ssh_bits.erl +++ b/lib/ssh/src/ssh_bits.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% diff --git a/lib/ssh/src/ssh_channel_sup.erl b/lib/ssh/src/ssh_channel_sup.erl index c184fed627..0093bce9c2 100644 --- a/lib/ssh/src/ssh_channel_sup.erl +++ b/lib/ssh/src/ssh_channel_sup.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% diff --git a/lib/ssh/src/ssh_cli.erl b/lib/ssh/src/ssh_cli.erl index 2764ea2e43..cb78acb84c 100644 --- a/lib/ssh/src/ssh_cli.erl +++ b/lib/ssh/src/ssh_cli.erl @@ -327,7 +327,7 @@ window_change(Tty, OldTty, Buf) {[], Buf}; window_change(Tty, OldTty, {Buf, BufTail, Col}) -> M1 = move_cursor(Col, 0, OldTty), - N = max(Tty#ssh_pty.width - OldTty#ssh_pty.width, 0) * 2, + N = erlang:max(Tty#ssh_pty.width - OldTty#ssh_pty.width, 0) * 2, S = lists:reverse(Buf, [BufTail | lists:duplicate(N, $ )]), M2 = move_cursor(length(Buf) + length(BufTail) + N, Col, Tty), {[M1, S | M2], {Buf, BufTail, Col}}. @@ -398,10 +398,6 @@ nthtail(0, A) -> A; nthtail(N, [_ | A]) when N > 0 -> nthtail(N-1, A); nthtail(_, _) -> []. -%%% utils -max(A, B) when A > B -> A; -max(_A, B) -> B. - ifelse(Cond, A, B) -> case Cond of true -> A; @@ -419,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; @@ -441,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_cm.erl b/lib/ssh/src/ssh_cm.erl deleted file mode 100755 index c4d535df9a..0000000000 --- a/lib/ssh/src/ssh_cm.erl +++ /dev/null @@ -1,237 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-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 : Backwards compatibility wrapper - --module(ssh_cm). - --include("ssh.hrl"). --include("ssh_connect.hrl"). - -%% -define(DEFAULT_PACKET_SIZE, 32768). -%% -define(DEFAULT_WINDOW_SIZE, 2*?DEFAULT_PACKET_SIZE). -%%-define(DEFAULT_TIMEOUT, 5000). - --export([connect/1, connect/2, connect/3]). --export([listen/2, listen/3, listen/4, stop_listener/1]). --export([stop/1]). - --deprecated({connect, 1, next_major_release}). --deprecated({connect, 2, next_major_release}). --deprecated({connect, 3, next_major_release}). --deprecated({listen, 2, next_major_release}). --deprecated({listen, 3, next_major_release}). --deprecated({listen, 4, next_major_release}). --deprecated({stop_listener, 1, next_major_release}). --deprecated({stop, 1, next_major_release}). - --export([adjust_window/3, attach/2, attach/3, detach/2, - tcpip_forward/3, cancel_tcpip_forward/3, direct_tcpip/6, - direct_tcpip/8, close/2, shell/2, exec/4, - send/3, send/4, - send_ack/3, send_ack/4, send_ack/5, send_eof/2, - session_open/2, session_open/4, subsystem/4, - open_pty/3, open_pty/7, open_pty/9, - set_user_ack/4, - setenv/5, signal/3, winch/4]). - --deprecated({adjust_window, 3, next_major_release}). --deprecated({attach, 2, next_major_release}). --deprecated({attach, 3, next_major_release}). --deprecated({detach, 2, next_major_release}). --deprecated({tcpip_forward, 3, next_major_release}). --deprecated({cancel_tcpip_forward, 3, next_major_release}). --deprecated({direct_tcpip, 6, next_major_release}). --deprecated({direct_tcpip, 8, next_major_release}). --deprecated({close, 2, next_major_release}). --deprecated({shell, 2, next_major_release}). --deprecated({exec, 4, next_major_release}). --deprecated({send, 3, next_major_release}). --deprecated({send, 4, next_major_release}). --deprecated({send_ack, 3, next_major_release}). --deprecated({send_ack, 4, next_major_release}). --deprecated({send_ack, 5, next_major_release}). --deprecated({send_eof, 2, next_major_release}). --deprecated({session_open, 2, next_major_release}). --deprecated({session_open, 4, next_major_release}). --deprecated({subsystem, 4, next_major_release}). --deprecated({open_pty, 3, next_major_release}). --deprecated({open_pty, 7, next_major_release}). --deprecated({open_pty, 9, next_major_release}). --deprecated({set_user_ack, 4, next_major_release}). --deprecated({setenv, 5, next_major_release}). --deprecated({signal, 3, next_major_release}). --deprecated({winch, 4, next_major_release}). - --export([info/1, info/2, recv_window/3, - send_window/3, renegotiate/1, renegotiate/2, - get_peer_addr/1]). - -%%==================================================================== -%% API -%%==================================================================== -connect(Host) -> - connect(Host, []). -connect(Host, Opts) -> - connect(Host, ?SSH_DEFAULT_PORT, Opts). -connect(Host, Port, Opts) -> - ssh:connect(Host, Port, Opts). - -listen(ChannelSpec, Port) -> - listen(ChannelSpec, Port, []). -listen(ChannelSpec, Port, Opts) -> - listen(ChannelSpec, any, Port, Opts). -listen(ChannelSpec, "localhost", Port, Opts) -> - listen(ChannelSpec, any, Port, Opts); -listen(_ChannelSpec, Host, Port, Opts) -> - ssh:daemon(Host, Port, Opts). - -stop_listener(SysSup) -> - ssh_system_sup:stop_listener(SysSup). -stop(Cm) -> - ssh:close(Cm). - -%% CM Client commands -session_open(Cm, Timeout) -> - session_open(Cm, ?DEFAULT_WINDOW_SIZE, ?DEFAULT_PACKET_SIZE, Timeout). - -session_open(Cm, InitialWindowSize, MaxPacketSize, Timeout) -> - ssh_connection:session_channel(Cm, InitialWindowSize, MaxPacketSize, - Timeout). - - -setenv(Cm, Channel, Var, Value, Timeout) -> - ssh_connection:setenv(Cm, Channel, Var, Value, Timeout). - -shell(Cm, Channel) -> - ssh_connection:shell(Cm, Channel). - -exec(Cm, Channel, Command, Timeout) -> - ssh_connection:exec(Cm, Channel, Command, Timeout). - -subsystem(Cm, Channel, SubSystem, Timeout) -> - ssh_connection:subsystem(Cm, Channel, SubSystem, Timeout). - -%% Not needed for backwards compatibility for now -attach(_Cm, _Timeout) -> - ok. - -attach(_Cm, _ChannelPid, _Timeout) -> - ok. - -detach(_Cm, _Timeout) -> - ok. - -%% Not needed, send_ack is now call! Temp backwardcompability -set_user_ack(_, _, _, _) -> - ok. - -adjust_window(Cm, Channel, Bytes) -> - ssh_connection:adjust_window(Cm, Channel, Bytes). - -close(Cm, Channel) -> - ssh_connection:close(Cm, Channel). - -send_eof(Cm, Channel) -> - ssh_connection:send_eof(Cm, Channel). - -send(Cm, Channel, Data) -> - ssh_connection:send(Cm, Channel, 0, Data). - -send(Cm, Channel, Type, Data) -> - ssh_connection:send(Cm, Channel, Type, Data). - -%% Send ack is not needed -send_ack(Cm, Channel, Data) -> - send_ack(Cm, Channel, 0, Data, infinity). - -send_ack(Cm, Channel, Type, Data) -> - send_ack(Cm, Channel, Type, Data, infinity). - -send_ack(Cm, Channel, Type, Data, Timeout) -> - ssh_connection:send(Cm, Channel, Type, Data, Timeout). - -%% ---------------------------------------------------------------------- -%% These functions replacers are not officially supported but proably will be -%% when we had time to test them. -%% ---------------------------------------------------------------------- -direct_tcpip(Cm, RemoteHost, RemotePort, OrigIP, OrigPort, Timeout) -> - direct_tcpip(Cm, RemoteHost, RemotePort, OrigIP, OrigPort, - ?DEFAULT_WINDOW_SIZE, ?DEFAULT_PACKET_SIZE, Timeout). - -direct_tcpip(Cm, RemoteIP, RemotePort, OrigIP, OrigPort, - InitialWindowSize, MaxPacketSize, Timeout) -> - ssh_connection:direct_tcpip(Cm, RemoteIP, RemotePort, - OrigIP, OrigPort, - InitialWindowSize, - MaxPacketSize, Timeout). - -tcpip_forward(Cm, BindIP, BindPort) -> - ssh_connection:tcpip_forward(Cm, BindIP, BindPort). - -cancel_tcpip_forward(Cm, BindIP, Port) -> - ssh_connection:cancel_tcpip_forward(Cm, BindIP, Port). - -open_pty(Cm, Channel, Timeout) -> - open_pty(Cm, Channel, os:getenv("TERM"), 80, 24, [], Timeout). - -open_pty(Cm, Channel, Term, Width, Height, PtyOpts, Timeout) -> - open_pty(Cm, Channel, Term, Width, Height, 0, 0, PtyOpts, Timeout). - -open_pty(Cm, Channel, Term, Width, Height, PixWidth, PixHeight, - PtyOpts, Timeout) -> - ssh_connection:open_pty(Cm, Channel, Term, - Width, Height, PixWidth, - PixHeight, PtyOpts, Timeout). -winch(Cm, Channel, Width, Height) -> - winch(Cm, Channel, Width, Height, 0, 0). -winch(Cm, Channel, Width, Height, PixWidth, PixHeight) -> - ssh_connection:window_change(Cm, Channel, Width, - Height, PixWidth, PixHeight). -signal(Cm, Channel, Sig) -> - ssh_connection:signal(Cm, Channel, Sig). - -%% ---------------------------------------------------------------------- -%% These functions replacers are not officially supported and -%% the format of them will proably change when and -%% if they get supported. -%% ---------------------------------------------------------------------- -info(Cm) -> - info(Cm, all). - -info(Cm, ChannelPid) -> - ssh_connection_manager:info(Cm, ChannelPid). - -send_window(Cm, Channel, Timeout) -> - ssh_connection_manager:send_window(Cm, Channel, Timeout). - -recv_window(Cm, Channel, Timeout) -> - ssh_connection_manager:recv_window(Cm, Channel, Timeout). - -renegotiate(Cm) -> - renegotiate(Cm, []). -renegotiate(Cm, _Opts) -> - %%TODO: How should this work, backwards compat? - ssh_connection_manager:renegotiate(Cm). - -get_peer_addr(Cm) -> - ssh_connection_manager:peer_addr(Cm). - 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_handler.erl b/lib/ssh/src/ssh_connection_handler.erl index 822ef8f8f9..d46002c494 100644 --- a/lib/ssh/src/ssh_connection_handler.erl +++ b/lib/ssh/src/ssh_connection_handler.erl @@ -527,7 +527,7 @@ handle_info({Protocol, Socket, Data}, Statename, %% Implementations SHOULD decrypt the length after receiving the %% first 8 (or cipher block size, whichever is larger) bytes of a %% packet. (RFC 4253: Section 6 - Binary Packet Protocol) - case size(EncData0) + size(Data) >= max(8, BlockSize) of + case size(EncData0) + size(Data) >= erlang:max(8, BlockSize) of true -> {Ssh, SshPacketLen, DecData, EncData} = @@ -758,11 +758,6 @@ after_new_keys(#state{renegotiate = false, ssh_params = #ssh{role = server}} = State) -> {userauth, State}. -max(N, M) when N > M -> - N; -max(_, M) -> - M. - handle_ssh_packet_data(RemainingSshPacketLen, DecData, EncData, StateName, State) -> EncSize = size(EncData), diff --git a/lib/ssh/src/ssh_connection_manager.erl b/lib/ssh/src/ssh_connection_manager.erl index 9e55312e5f..6bf89224cf 100644 --- a/lib/ssh/src/ssh_connection_manager.erl +++ b/lib/ssh/src/ssh_connection_manager.erl @@ -560,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. %%-------------------------------------------------------------------- diff --git a/lib/ssh/src/ssh_dsa.erl b/lib/ssh/src/ssh_dsa.erl index ec24fbcd01..1b9a396f0c 100755 --- a/lib/ssh/src/ssh_dsa.erl +++ b/lib/ssh/src/ssh_dsa.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% diff --git a/lib/ssh/src/ssh_file.erl b/lib/ssh/src/ssh_file.erl index 8a3c903e51..5572349fe7 100755 --- a/lib/ssh/src/ssh_file.erl +++ b/lib/ssh/src/ssh_file.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% diff --git a/lib/ssh/src/ssh_io.erl b/lib/ssh/src/ssh_io.erl index 0e343c20b4..915fd63e4f 100755 --- a/lib/ssh/src/ssh_io.erl +++ b/lib/ssh/src/ssh_io.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% diff --git a/lib/ssh/src/ssh_math.erl b/lib/ssh/src/ssh_math.erl index efe7f56979..510eb16aa6 100755 --- a/lib/ssh/src/ssh_math.erl +++ b/lib/ssh/src/ssh_math.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% diff --git a/lib/ssh/src/ssh_no_io.erl b/lib/ssh/src/ssh_no_io.erl index 5f363ae6c2..2c8dd92ee2 100644 --- a/lib/ssh/src/ssh_no_io.erl +++ b/lib/ssh/src/ssh_no_io.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% diff --git a/lib/ssh/src/ssh_rsa.erl b/lib/ssh/src/ssh_rsa.erl index 7c2bf9a2bf..e27cdcf7bd 100755 --- a/lib/ssh/src/ssh_rsa.erl +++ b/lib/ssh/src/ssh_rsa.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% diff --git a/lib/ssh/src/ssh_sftp.erl b/lib/ssh/src/ssh_sftp.erl index cbfa208f6f..59e09fdd0f 100755 --- a/lib/ssh/src/ssh_sftp.erl +++ b/lib/ssh/src/ssh_sftp.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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,14 +46,6 @@ recv_window/1, list_dir/2, read_file/2, write_file/3, recv_window/2, list_dir/3, read_file/3, write_file/4]). -%% Deprecated --export([connect/1, connect/2, connect/3, stop/1]). - --deprecated({connect, 1, next_major_release}). --deprecated({connect, 2, next_major_release}). --deprecated({connect, 3, next_major_release}). --deprecated({stop, 1, next_major_release}). - %% ssh_channel callbacks -export([init/1, handle_call/3, handle_msg/2, handle_ssh_msg/2, terminate/2]). %% TODO: Should be placed elsewhere ssh_sftpd should not call functions in ssh_sftp! @@ -1116,33 +1108,3 @@ lseek_pos(_, _, _) -> {error, einval}. -%%%%%% Deprecated %%%% -connect(Cm) when is_pid(Cm) -> - connect(Cm, []); -connect(Host) when is_list(Host) -> - connect(Host, []). -connect(Cm, Opts) when is_pid(Cm) -> - Timeout = proplists:get_value(timeout, Opts, infinity), - case ssh_xfer:attach(Cm, []) of - {ok, ChannelId, Cm} -> - ssh_channel:start(Cm, ChannelId, ?MODULE, [Cm, ChannelId, - Timeout]); - Error -> - Error - end; -connect(Host, Opts) -> - connect(Host, 22, Opts). -connect(Host, Port, Opts) -> - Timeout = proplists:get_value(timeout, Opts, infinity), - case ssh_xfer:connect(Host, Port, proplists:delete(timeout, Opts)) of - {ok, ChannelId, Cm} -> - ssh_channel:start(Cm, ChannelId, ?MODULE, [Cm, - ChannelId, Timeout]); - Error -> - Error - end. - - -stop(Pid) -> - call(Pid, stop, infinity). - diff --git a/lib/ssh/src/ssh_sftpd_file.erl b/lib/ssh/src/ssh_sftpd_file.erl index f0b6bb4de5..91ba228e38 100644 --- a/lib/ssh/src/ssh_sftpd_file.erl +++ b/lib/ssh/src/ssh_sftpd_file.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% diff --git a/lib/ssh/src/ssh_sftpd_file_api.erl b/lib/ssh/src/ssh_sftpd_file_api.erl index 8decfb38d9..176aa98194 100644 --- a/lib/ssh/src/ssh_sftpd_file_api.erl +++ b/lib/ssh/src/ssh_sftpd_file_api.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% diff --git a/lib/ssh/src/ssh_shell.erl b/lib/ssh/src/ssh_shell.erl index f81b949119..6590486a4c 100644 --- a/lib/ssh/src/ssh_shell.erl +++ b/lib/ssh/src/ssh_shell.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009. All Rights Reserved. -%% +%% +%% 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% %% diff --git a/lib/ssh/src/ssh_ssh.erl b/lib/ssh/src/ssh_ssh.erl deleted file mode 100644 index 6be8bf7a5a..0000000000 --- a/lib/ssh/src/ssh_ssh.erl +++ /dev/null @@ -1,65 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-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: THIS MODULE IS DEPRECATD AND SHOULD BE REMOVED IN R14 - --module(ssh_ssh). - --export([connect/1, connect/2, connect/3]). --deprecated({connect, 1, next_major_release}). --deprecated({connect, 2, next_major_release}). --deprecated({connect, 3, next_major_release}). - --include("ssh.hrl"). --include("ssh_connect.hrl"). - --define(default_timeout, 10000). - -%%% Backwards compatibility -connect(A) -> - connect(A, []). - -connect(Host, Opts) when is_list(Host) -> - connect(Host, 22, Opts); -connect(CM, Opts) -> - Timeout = proplists:get_value(connect_timeout, Opts, ?default_timeout), - session(CM, Timeout). - -connect(Host, Port, Opts) -> - case ssh:connect(Host, Port, Opts) of - {ok, CM} -> - session(CM, proplists:get_value(connect_timeout, - Opts, ?default_timeout)); - Error -> - Error - end. - -session(CM, Timeout) -> - case ssh_connection:session_channel(CM, Timeout) of - {ok, ChannelId} -> - Args = [{channel_cb, ssh_shell}, - {init_args,[CM, ChannelId]}, - {cm, CM}, {channel_id, ChannelId}], - {ok, State} = ssh_channel:init([Args]), - ssh_channel:enter_loop(State); - Error -> - Error - end. diff --git a/lib/ssh/src/ssh_sshd.erl b/lib/ssh/src/ssh_sshd.erl deleted file mode 100644 index 4bc0469061..0000000000 --- a/lib/ssh/src/ssh_sshd.erl +++ /dev/null @@ -1,48 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-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: This module uses the erlang shell and -%% ssh_cli to make an erlang sshd - --module(ssh_sshd). - -%% API --export([listen/0, listen/1, listen/2, listen/3, stop/1]). - --deprecated({listen, 0, next_major_release}). --deprecated({listen, 1, next_major_release}). --deprecated({listen, 2, next_major_release}). --deprecated({listen, 3, next_major_release}). --deprecated({stop, 1, next_major_release}). - -listen() -> - listen(22). - -listen(Port) -> - listen(Port, []). - -listen(Port, Opts) -> - listen(any, Port, Opts). - -listen(Addr, Port, Opts) -> - ssh:daemon(Addr, Port, Opts). - -stop(Pid) -> - ssh:stop_daemon(Pid). diff --git a/lib/ssh/src/ssh_subsystem_sup.erl b/lib/ssh/src/ssh_subsystem_sup.erl index 17d47a91d5..d71b6bbc56 100644 --- a/lib/ssh/src/ssh_subsystem_sup.erl +++ b/lib/ssh/src/ssh_subsystem_sup.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% diff --git a/lib/ssh/src/ssh_sup.erl b/lib/ssh/src/ssh_sup.erl index 4c46b1586b..f307d1f833 100644 --- a/lib/ssh/src/ssh_sup.erl +++ b/lib/ssh/src/ssh_sup.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% diff --git a/lib/ssh/src/ssh_system_sup.erl b/lib/ssh/src/ssh_system_sup.erl index 477f60f993..f4570b8a48 100644 --- a/lib/ssh/src/ssh_system_sup.erl +++ b/lib/ssh/src/ssh_system_sup.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -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/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl index 5617231c60..e79ccdda0c 100644 --- a/lib/ssh/src/ssh_transport.erl +++ b/lib/ssh/src/ssh_transport.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% 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% %% diff --git a/lib/ssh/src/ssh_transport.hrl b/lib/ssh/src/ssh_transport.hrl index 18a23f0533..27d3e32355 100644 --- a/lib/ssh/src/ssh_transport.hrl +++ b/lib/ssh/src/ssh_transport.hrl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% diff --git a/lib/ssh/src/ssh_userauth.hrl b/lib/ssh/src/ssh_userauth.hrl index 39cc032ca5..8eb2d46ed1 100755 --- a/lib/ssh/src/ssh_userauth.hrl +++ b/lib/ssh/src/ssh_userauth.hrl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% diff --git a/lib/ssh/src/ssh_userreg.erl b/lib/ssh/src/ssh_userreg.erl index 06f4076b51..33c801f490 100644 --- a/lib/ssh/src/ssh_userreg.erl +++ b/lib/ssh/src/ssh_userreg.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% diff --git a/lib/ssh/src/ssh_xfer.erl b/lib/ssh/src/ssh_xfer.erl index a347a9c095..c9631a73b1 100644 --- a/lib/ssh/src/ssh_xfer.erl +++ b/lib/ssh/src/ssh_xfer.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% diff --git a/lib/ssh/src/ssh_xfer.hrl b/lib/ssh/src/ssh_xfer.hrl index f32ec5f774..4a4f1a4291 100755 --- a/lib/ssh/src/ssh_xfer.hrl +++ b/lib/ssh/src/ssh_xfer.hrl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% diff --git a/lib/ssh/src/sshc_sup.erl b/lib/ssh/src/sshc_sup.erl index 265d1a1cd6..7c29c669e4 100644 --- a/lib/ssh/src/sshc_sup.erl +++ b/lib/ssh/src/sshc_sup.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% diff --git a/lib/ssh/src/sshd_sup.erl b/lib/ssh/src/sshd_sup.erl index 9c9ba5958c..747906b2cf 100644 --- a/lib/ssh/src/sshd_sup.erl +++ b/lib/ssh/src/sshd_sup.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk index 8e31851a8e..79fd36cd83 100644 --- a/lib/ssh/vsn.mk +++ b/lib/ssh/vsn.mk @@ -1,87 +1,4 @@ #-*-makefile-*- ; force emacs to enter makefile-mode -SSH_VSN = 1.1.11 +SSH_VSN = 2.0.1 APP_VSN = "ssh-$(SSH_VSN)" - -TICKETS = OTP-8735 - -TICKETS_1.1.10 = OTP-8714 - -TICKETS_1.1.9 = OTP-8524 \ - OTP-8534 \ - OTP-8535 \ - OTP-8550 \ - 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 a3dec8da38..daad7dc3e6 100644 --- a/lib/ssl/Makefile +++ b/lib/ssl/Makefile @@ -1,19 +1,19 @@ # # %CopyrightBegin% -# -# Copyright Ericsson AB 1999-2009. All Rights Reserved. -# +# +# 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% # @@ -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 = pkix src c_src doc/src -else -SUB_DIRECTORIES = pkix src c_src doc/src examples/certs examples/src -endif + +SUB_DIRECTORIES = src c_src doc/src examples/certs examples/src include vsn.mk VSN = $(SSL_VSN) diff --git a/lib/ssl/doc/src/Makefile b/lib/ssl/doc/src/Makefile index fa263d28ab..3119d37af0 100644 --- a/lib/ssl/doc/src/Makefile +++ b/lib/ssl/doc/src/Makefile @@ -37,7 +37,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN) # Target Specs # ---------------------------------------------------- XML_APPLICATION_FILES = refman.xml -XML_REF3_FILES = ssl.xml new_ssl.xml +XML_REF3_FILES = ssl.xml old_ssl.xml ssl_session_cache_api.xml XML_REF6_FILES = ssl_app.xml XML_PART_FILES = release_notes.xml usersguide.xml @@ -45,9 +45,7 @@ XML_CHAPTER_FILES = \ ssl_protocol.xml \ using_ssl.xml \ pkix_certs.xml \ - create_certs.xml \ ssl_distribution.xml \ - licenses.xml \ notes.xml BOOK_FILES = book.xml diff --git a/lib/ssl/doc/src/book.xml b/lib/ssl/doc/src/book.xml index 9122addb74..85d6b56b26 100644 --- a/lib/ssl/doc/src/book.xml +++ b/lib/ssl/doc/src/book.xml @@ -28,9 +28,6 @@ <rev>A</rev> <file>book.sgml</file> </header> - <insidecover> - <include file="insidecover"></include> - </insidecover> <pagetext>SSL Application</pagetext> <preamble> <contents level="2"></contents> diff --git a/lib/ssl/doc/src/create_certs.xml b/lib/ssl/doc/src/create_certs.xml deleted file mode 100644 index 79cc8a0537..0000000000 --- a/lib/ssl/doc/src/create_certs.xml +++ /dev/null @@ -1,148 +0,0 @@ -<?xml version="1.0" encoding="latin1" ?> -<!DOCTYPE chapter SYSTEM "chapter.dtd"> - -<chapter> - <header> - <copyright> - <year>2003</year><year>2009</year> - <holder>Ericsson AB. All Rights Reserved.</holder> - </copyright> - <legalnotice> - The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved online at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - the License for the specific language governing rights and limitations - under the License. - - </legalnotice> - - <title>Creating Certificates</title> - <prepared>UAB/F/P Peter Högfeldt</prepared> - <docno></docno> - <date>2003-06-16</date> - <rev>A</rev> - <file>create_certs.xml</file> - </header> - <p>Here we consider the creation of example certificates. - </p> - - <section> - <title>The openssl Command</title> - <p>The <c>openssl</c> command is a utility that comes with the - OpenSSL distribution. It provides a variety of subcommands. Each - subcommand is invoked as</p> - <code type="none"><![CDATA[ - openssl subcmd <options and arguments> ]]></code> - <p>where <c>subcmd</c> denotes the subcommand in question. - </p> - <p>We shall use the following subcommands to create certificates for - the purpose of testing Erlang/OTP SSL: - </p> - <list type="bulleted"> - <item><em>req</em> to create certificate requests and a - self-signed certificates, - </item> - <item><em>ca</em> to create certificates from certificate requests.</item> - </list> - <p>We create the following certificates: - </p> - <list type="bulleted"> - <item>the <em>erlangCA</em> root certificate (a self-signed - certificate), </item> - <item>the <em>otpCA</em> certificate signed by the <em>erlangCA</em>, </item> - <item>a client certificate signed by the <em>otpCA</em>, and</item> - <item>a server certificate signed by the <em>otpCA</em>.</item> - </list> - - <section> - <title>The openssl configuration file</title> - <p>An <c>openssl</c> configuration file consist of a number of - sections, where each section starts with one line containing - <c>[ section_name ]</c>, where <c>section_name</c> is the name - of the section. The first section of the file is either - unnamed, or is named <c>[ default ]</c>. For further details - see the OpenSSL config(5) manual page. - </p> - <p>The required sections for the subcommands we are going to - use are as follows: - </p> - <table> - <row> - <cell align="left" valign="middle">subcommand</cell> - <cell align="left" valign="middle">required/default section</cell> - <cell align="left" valign="middle">override command line option</cell> - <cell align="left" valign="middle">configuration file option</cell> - </row> - <row> - <cell align="left" valign="middle">req</cell> - <cell align="left" valign="middle">[req]</cell> - <cell align="left" valign="middle">-</cell> - <cell align="left" valign="middle"><c>-config FILE</c></cell> - </row> - <row> - <cell align="left" valign="middle">ca</cell> - <cell align="left" valign="middle">[ca]</cell> - <cell align="left" valign="middle"><c>-name section</c></cell> - <cell align="left" valign="middle"><c>-config FILE</c></cell> - </row> - <tcaption>openssl subcommands to use</tcaption> - </table> - </section> - - <section> - <title>Creating the Erlang root CA</title> - <p>The Erlang root CA is created with the command</p> - <code type="none"> - openssl req -new -x509 -config /some/path/req.cnf \\ - -keyout /some/path/key.pem -out /some/path/cert.pem </code> - <p>where the option <c>-new</c> indicates that we want to create - a new certificate request and the option <c>-x509</c> implies - that a self-signed certificate is created. - </p> - </section> - - <section> - <title>Creating the OTP CA</title> - <p>The OTP CA is created by first creating a certificate request - with the command</p> - <code type="none"> - openssl req -new -config /some/path/req.cnf \\ - -keyout /some/path/key.pem -out /some/path/req.pem </code> - <p>and the ask the Erlang CA to sign it:</p> - <code type="none"> - openssl ca -batch -notext -config /some/path/req.cnf \\ - -extensions ca_cert -in /some/path/req.pem -out /some/path/cert.pem </code> - <p>where the option <c>-extensions</c> refers to a section in the - configuration file saying that it should create a CA certificate, - and not a plain user certificate. - </p> - <p>The <c>client</c> and <c>server</c> certificates are created - similarly, except that the option <c>-extensions</c> then has the - value <c>user_cert</c>. - </p> - </section> - </section> - - <section> - <title>An Example</title> - <p>The following module <c>create_certs</c> is used by the Erlang/OTP - SSL application for generating certificates to be used in tests. The - source code is also found in <c>ssl-X.Y.Z/examples/certs/src</c>. - </p> - <p>The purpose of the <c>create_certs:all/1</c> function is to make - it possible to provide from the <c>erl</c> command line, the - full path name of the <c>openssl</c> command. - </p> - <p>Note that the module creates temporary OpenSSL configuration files - for the <c>req</c> and <c>ca</c> subcommands. - </p> - <codeinclude file="../../examples/certs/src/make_certs.erl" tag="" type="erl"></codeinclude> - </section> -</chapter> - - diff --git a/lib/ssl/doc/src/insidecover.xml b/lib/ssl/doc/src/insidecover.xml deleted file mode 100644 index 4f3f5e5951..0000000000 --- a/lib/ssl/doc/src/insidecover.xml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="latin1" ?> -<!DOCTYPE bookinsidecover SYSTEM "bookinsidecover.dtd"> - -<bookinsidecover> -The Erlang/OTP SSL application includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/). Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. <br></br> -This product includes cryptographic software written by Eric Young ([email protected]). This product includes software written by Tim Hudson ([email protected]). Copyright (C) 1995-1998 Eric Young ([email protected]). All rights reserved. <br></br> -For further OpenSSL and SSLeay license information se the chapter <bold>Licenses</bold> -. <vfill></vfill> - <br></br> - <tt>http://www.erlang.org</tt> - <br></br> -</bookinsidecover> - - diff --git a/lib/ssl/doc/src/licenses.xml b/lib/ssl/doc/src/licenses.xml deleted file mode 100644 index 0969f9ad6e..0000000000 --- a/lib/ssl/doc/src/licenses.xml +++ /dev/null @@ -1,156 +0,0 @@ -<?xml version="1.0" encoding="latin1" ?> -<!DOCTYPE chapter SYSTEM "chapter.dtd"> - -<chapter> - <header> - <copyright> - <year>2003</year><year>2009</year> - <holder>Ericsson AB. All Rights Reserved.</holder> - </copyright> - <legalnotice> - The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved online at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - the License for the specific language governing rights and limitations - under the License. - - </legalnotice> - - <title>Licenses</title> - <prepared>Peter Högfeldt</prepared> - <docno></docno> - <date>2003-05-26</date> - <rev>A</rev> - <file>licenses.xml</file> - </header> - <p> <marker id="licenses"></marker> -This chapter contains in extenso versions - of the OpenSSL and SSLeay licenses. - </p> - - <section> - <title>OpenSSL License</title> - <code type="none"> -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * [email protected]. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * ([email protected]). This product includes software written by Tim - * Hudson ([email protected]). - * - */ </code> - </section> - - <section> - <title>SSLeay License</title> - <code type="none"> -/* Copyright (C) 1995-1998 Eric Young ([email protected]) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young ([email protected]). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson ([email protected]). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young ([email protected])" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson ([email protected])" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ </code> - </section> -</chapter> - - diff --git a/lib/ssl/doc/src/make.dep b/lib/ssl/doc/src/make.dep deleted file mode 100644 index 2ff81bee1f..0000000000 --- a/lib/ssl/doc/src/make.dep +++ /dev/null @@ -1,30 +0,0 @@ -# ---------------------------------------------------- -# >>>> Do not edit this file <<<< -# This file was automaticly generated by -# /home/otp/bin/docdepend -# ---------------------------------------------------- - - -# ---------------------------------------------------- -# TeX files that the DVI file depend on -# ---------------------------------------------------- - -book.dvi: book.tex create_certs.tex licenses.tex new_ssl.tex \ - pkix_certs.tex refman.tex ssl.tex ssl_app.tex \ - ssl_distribution.tex ssl_protocol.tex usersguide.tex \ - using_ssl.tex - -# ---------------------------------------------------- -# Source inlined when transforming from source to LaTeX -# ---------------------------------------------------- - -book.tex: refman.xml - -create_certs.tex: ../../examples/certs/src/make_certs.erl - -using_ssl.tex: ../../examples/src/client_server.erl - -pkix_certs.tex: ../../../../system/doc/definitions/cite.defs - -ssl_protocol.tex: ../../../../system/doc/definitions/cite.defs - diff --git a/lib/ssl/doc/src/new_ssl.xml b/lib/ssl/doc/src/new_ssl.xml deleted file mode 100644 index 08868a1b3c..0000000000 --- a/lib/ssl/doc/src/new_ssl.xml +++ /dev/null @@ -1,681 +0,0 @@ -<?xml version="1.0" encoding="latin1" ?> -<!DOCTYPE erlref SYSTEM "erlref.dtd"> - -<erlref> - <header> - <copyright> - <year>1999</year> - <year>2007</year> - <holder>Ericsson AB, All Rights Reserved</holder> - </copyright> - <legalnotice> - The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved aniline's 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. - - The Initial Developer of the Original Code is Ericsson AB. - </legalnotice> - - <title>ssl</title> - <prepared>Ingela Anderton Andin</prepared> - <responsible>Ingela Anderton Andin</responsible> - <docno></docno> - <approved></approved> - <checked></checked> - <date>2003-03-25</date> - <rev></rev> - <file>new_ssl.xml</file> - </header> - <module>new_ssl</module> - <modulesummary>Interface Functions for Secure Socket Layer</modulesummary> - <description> - <p>This module contains interface functions to the Secure Socket - Layer. - </p> - </description> - - <section> - <title>NEW SSL</title> - - <p>This manual page describes functions that are defined - in the ssl module and represents the new ssl implementation - that coexists with the old one, as the new implementation - is not yet complete enough to replace the old one.</p> - - <p>The new implementation can be - accessed by providing the option {ssl_imp, new} to the - ssl:connect and ssl:listen functions.</p> - - <p>The new implementation is Erlang based and all logic - is in Erlang and only payload encryption calculations are - done in C via the crypto application. The main reason for - making a new implementation is that the old solution was - very crippled as the control of the ssl-socket was deep - down in openssl making it hard if not impossible to - support all inet options, ipv6 and upgrade of a tcp - connection to a ssl connection. This version has a - few limitations that will be removed before the ssl-4.0 - release. Main differences and limitations are listed below.</p> - - <list type="bulleted"> - <item>New ssl requires the crypto - application.</item> - <item>The option reuseaddr is - supported and the default value is false as in gen_tcp. - Old ssl is patched to accept that the option is set to - true to provide a smoother migration between the - versions. In old ssl the option is hard coded to - true.</item> - <item>ssl:version/0 is replaced by - ssl:versions/0</item> - <item>ssl:ciphers/0 is replaced by - ssl:cipher_suites/0</item> - <item>ssl:pid/1 is a - meaningless function in new ssl and will be deprecated in - ssl-4.0 until it is removed it will return a valid but - meaningless pid.</item> - <item>New API functions are - ssl:shutdown/2, ssl:cipher_suites/[0,1] and - ssl:versions/0</item> - <item>CRL and policy certificate - extensions are not supported yet. </item> - <item>Supported SSL/TLS-versions are SSL-3.0 and TLS-1.0 </item> - <item>For security reasons sslv2 is not supported.</item> - </list> - - </section> - - <section> - <title>COMMON DATA TYPES</title> - <p>The following data types are used in the functions below: - </p> - - <p><c>boolean() = true | false</c></p> - - <p><c>property() = atom()</c></p> - - <p><c>option() = socketoption() | ssloption() | transportoption()</c></p> - - <p><c>socketoption() = [{property(), term()}] - defaults to - [{mode,list},{packet, 0},{header, 0},{active, true}]. - </c></p> - - <p>For valid options - see <seealso marker="kernel:inet">inet(3) </seealso> and - <seealso marker="kernel:gen_tcp">gen_tcp(3) </seealso>. - </p> - - <p> <c>ssloption() = {verify, verify_type()} | - {fail_if_no_peer_cert, boolean()} - {depth, integer()} | - {certfile, path()} | {keyfile, path()} | {password, string()} | - {cacertfile, path()} | {dhfile, path()} | {ciphers, ciphers()} | - {ssl_imp, ssl_imp()} | {reuse_sessions, boolean()} | {reuse_session, fun()} - </c></p> - - <p><c>transportoption() = {CallbackModule, DataTag, ClosedTag} - - defaults to {gen_tcp, tcp, tcp_closed}. Ssl may be - run over any reliable transport protocol that has - an equivalent API to gen_tcp's.</c></p> - - <p><c> CallbackModule = - atom()</c> - </p> <p><c> DataTag = - atom() - tag used in socket data message.</c></p> - <p><c> ClosedTag = atom() - tag used in - socket close message.</c></p> - - <p><c>verify_type() = verify_none | verify_peer</c></p> - - <p><c>path() = string() - representing a file path.</c></p> - - <p><c>host() = hostname() | ipaddress()</c></p> - - <p><c>hostname() = string()</c></p> - - <p><c> - ip_address() = {N1,N2,N3,N4} % IPv4 - | {K1,K2,K3,K4,K5,K6,K7,K8} % IPv6 </c></p> - - <p><c>sslsocket() - opaque to the user. </c></p> - - <p><c>protocol() = sslv3 | tlsv1 </c></p> - - <p><c>ciphers() = [ciphersuite()] | sting() (according to old API)</c></p> - - <p><c>ciphersuite() = - {key_exchange(), cipher(), hash(), exportable()}</c></p> - - <p><c>key_exchange() = rsa | dh_dss | dh_rsa | dh_anon | dhe_dss - | dhe_rsa | krb5 | KeyExchange_export - </c></p> - - <p><c>cipher() = rc4_128 | idea_cbc | des_cbc | '3des_ede_cbc' - des40_cbc | dh_dss | aes_128_cbc | aes_256_cbc | - rc2_cbc_40 | rc4_40 </c></p> - - <p> <c>hash() = md5 | sha - </c></p> - - <p> <c>exportable() = export | no_export | ignore - </c></p> - - <p><c>ssl_imp() = new | old - default is old.</c></p> - - </section> - -<section> - <title>SSL OPTION DESCRIPTIONS</title> - - <taglist> - <tag>{verify, verify_type()}</tag> - <item> If <c>verify_none</c> is specified x509-certificate - path validation errors at the client side - will not automatically cause the connection to fail, as - it will if the verify type is <c>verify_peer</c>. See also - the option verify_fun. - Servers only do the path validation if <c>verify_peer</c> is set to - true, as it then will - send a certificate request to - the client (this message is not sent if the verify option is - <c>verify_none</c>) and you may then also want to specify - the option <c>fail_if_no_peer_cert</c>. - </item> - - <tag>{fail_if_no_peer_cert, boolean()}</tag> - <item>Used together with {verify, verify_peer} by a ssl server. - If set to true, - the server will fail if the client does not have a certificate - to send, e.i sends a empty certificate, if set to false it will - only fail if the client sends a invalid certificate (an empty - certificate is considered valid). - </item> - - <tag>{verify_fun, fun(ErrorList) -> boolean()}</tag> - <item>Used by the ssl client to determine if - x509-certificate path validations errors are acceptable or - if the connection should fail. Defaults to: - -<code> -fun(ErrorList) -> - case lists:foldl(fun({bad_cert,unknown_ca}, Acc) -> - Acc; - (Other, Acc) -> - [Other | Acc] - end, [], ErrorList) of - [] -> - true; - [_|_] -> - false - end -end -</code> - I.e. by default if the only error found was that the CA-certificate - holder was unknown this will be accepted. - - Possible errors in the error list are: - {bad_cert, cert_expired}, {bad_cert, invalid_issuer}, - {bad_cert, invalid_signature}, {bad_cert, name_not_permitted}, - {bad_cert, unknown_ca}, - {bad_cert, cert_expired}, {bad_cert, invalid_issuer}, - {bad_cert, invalid_signature}, {bad_cert, name_not_permitted}, - {bad_cert, cert_revoked} (not implemented yet), - {bad_cert, unknown_critical_extension} or {bad_cert, term()} (Will - be relevant later when an option is added for the user to be able to verify application specific extensions.) - </item> - - <tag>{depth, integer()}</tag> - <item>Specifies the maximum - verification depth, i.e. how far in a chain of certificates the - verification process can proceed before the verification is - considered to fail. Peer certificate = 0, CA certificate = 1, - higher level CA certificate = 2, etc. The value 2 thus means - that a chain can at most contain peer cert, CA cert, next CA - cert, and an additional CA cert. The default value is 1. - </item> - - <tag>{certfile, path()}</tag> - <item>Path to a file containing the - user's certificate. Optional for clients but note - that some servers requires that the client can certify - itself. </item> - <tag>{keyfile, path()}</tag> - <item>Path to file containing user's - private PEM encoded key. As PEM-files may contain several - entries this option defaults to the same file as given by - certfile option.</item> - <tag>{password, string()}</tag> - <item>String containing the user's password. - Only used if the private keyfile is password protected. - </item> - <tag>{cacertfile, path()}</tag> - <item>Path to file containing PEM encoded - CA certificates (trusted certificates used for verifying a peer - certificate). May be omitted if you do not want to verify - the peer.</item> - - <tag>{dhfile, path()}</tag> - <item>Path to file containing PEM encoded Diffie Hellman parameters, - for the server to use if a cipher suite using Diffie Hellman key exchange - is negotiated. If not specified hardcode parameters will be used. - </item> - - <tag>{ciphers, ciphers()}</tag> - <item>The function <c>ciphers_suites/0</c> can - be used to find all available ciphers. - </item> - - <tag>{ssl_imp, ssl_imp()}</tag> - <item>Specify which ssl implementation you want to use. - </item> - - <tag>{reuse_sessions, boolean()}</tag> - <item>Specifies if ssl sessions should be reused - when possible. - </item> - - <tag>{reuse_session, fun(SuggestedSessionId, - PeerCert, Compression, CipherSuite) -> boolean()}</tag> - <item>Enables the ssl server to have a local policy - for deciding if a session should be reused or not, - only meaning full if <c>reuse_sessions</c> is set to true. - SuggestedSessionId is a binary(), PeerCert is a DER encoded - certificate, Compression is an enumeration integer - and CipherSuite of type ciphersuite(). - </item> - </taglist> - </section> - - <section> - <title>General</title> - - <p>When a ssl socket is in active mode (the default), data from the - socket is delivered to the owner of the socket in the form of - messages: - </p> - <list type="bulleted"> - <item>{ssl, Socket, Data} - </item> - <item>{ssl_closed, Socket} - </item> - <item> - {ssl_error, Socket, Reason} - </item> - </list> - - <p>A <c>Timeout</c> argument specifies a timeout in milliseconds. The - default value for a <c>Timeout</c> argument is <c>infinity</c>. - </p> - </section> - - <funcs> - <func> - <name>cipher_suites() -></name> - <name>cipher_suites(Type) -> ciphers()</name> - <fsummary> Returns a list of supported cipher suites</fsummary> - <type> - <v>Type = erlang | openssl</v> - - </type> - <desc><p>Returns a list of supported cipher suites. - cipher_suites() is equivalent to cipher_suites(erlang). - Type openssl is provided for backwards compatibility with - old ssl that used openssl. - </p> - </desc> - </func> - - <func> - <name>connect(Socket, SslOptions) -> </name> - <name>connect(Socket, SslOptions, Timeout) -> {ok, SslSocket} - | {error, Reason}</name> - <fsummary> Upgrades a gen_tcp, or - equivalent, connected socket to a ssl socket. </fsummary> - <type> - <v>Socket = socket()</v> - <v>SslOptions = [ssloption()]</v> - <v>Timeout = integer() | infinity</v> - <v>SslSocket = sslsocket()</v> - <v>Reason = term()</v> - </type> - <desc> <p>Upgrades a gen_tcp, or equivalent, - connected socket to a ssl socket e.i performs the - client-side ssl handshake.</p> - </desc> - </func> - - <func> - <name>connect(Host, Port, Options) -></name> - <name>connect(Host, Port, Options, Timeout) -> - {ok, SslSocket} | {error, Reason}</name> - <fsummary>Opens an ssl connection to Host, Port. </fsummary> - <type> - <v>Host = host()</v> - <v>Port = integer()</v> - <v>Options = [option()]</v> - <v>Timeout = integer() | infinity</v> - <v>SslSocket = sslsocket()</v> - <v>Reason = term()</v> - </type> - <desc> <p>Opens an ssl connection to Host, Port.</p> </desc> - </func> - - <func> - <name>close(SslSocket) -> ok | {error, Reason}</name> - <fsummary>Close a ssl connection</fsummary> - <type> - <v>SslSocket = sslsocket()</v> - <v>Reason = term()</v> - </type> - <desc><p>Close a ssl connection.</p> - </desc> - </func> - - <func> - <name>controlling_process(SslSocket, NewOwner) -> - ok | {error, Reason}</name> - - <fsummary>Assigns a new controlling process to the - ssl-socket.</fsummary> - - <type> - <v>SslSocket = sslsocket()</v> - <v>NewOwner = pid()</v> - <v>Reason = term()</v> - </type> - <desc><p>Assigns a new controlling process to the ssl-socket. A - controlling process is the owner of a ssl-socket, and receives - all messages from the socket.</p> - </desc> - </func> - - <func> - <name>connection_info(SslSocket) -> - {ok, {ProtocolVersion, CipherSuite}} | {error, Reason} </name> - <fsummary>Returns the negotiated protocol version and cipher suite. - </fsummary> - <type> - <v>CipherSuite = ciphersuite()</v> - <v>ProtocolVersion = protocol()</v> - </type> - <desc><p>Returns the negotiated protocol version and cipher suite.</p> - </desc> - </func> - - <func> - <name>getopts(Socket) -> </name> - <name>getopts(Socket, OptionNames) -> - {ok, [socketoption()]} | {error, Reason}</name> - <fsummary>Get the value of the specified options.</fsummary> - <type> - <v>Socket = sslsocket()</v> - <v>OptionNames = [property()]</v> - </type> - <desc> - <p>Get the value of the specified socket options, if no - options are specified all options are returned. - </p> - </desc> - </func> - - <func> - <name>listen(Port, Options) -> - {ok, ListenSocket} | {error, Reason}</name> - <fsummary>Creates a ssl listen socket.</fsummary> - <type> - <v>Port = integer()</v> - <v>Options = options()</v> - <v>ListenSocket = sslsocket()</v> - </type> - <desc> - <p>Creates a ssl listen socket.</p> - </desc> - </func> - - <func> - <name>peercert(Socket) -> {ok, Cert} | {error, Reason}</name> - <fsummary>Return the peer certificate.</fsummary> - <type> - <v>Socket = sslsocket()</v> - <v>Cert = binary()</v> - <v>Subject = term()</v> - </type> - <desc> - <p>The peer certificate is returned as a DER encoded binary. - The certificate can be decoded with <c>public_key:pkix_decode_cert/2</c>. - </p> - </desc> - </func> - <func> - <name>peername(Socket) -> {ok, {Address, Port}} | - {error, Reason}</name> - <fsummary>Return peer address and port.</fsummary> - <type> - <v>Socket = sslsocket()</v> - <v>Address = ipaddress()</v> - <v>Port = integer()</v> - </type> - <desc> - <p>Returns the address and port number of the peer.</p> - </desc> - </func> - - <func> - <name>recv(Socket, Length) -> </name> - <name>recv(Socket, Length, Timeout) -> {ok, Data} | {error, - Reason}</name> - <fsummary>Receive data on a socket.</fsummary> - <type> - <v>Socket = sslsocket()</v> - <v>Length = integer()</v> - <v>Timeout = integer()</v> - <v>Data = [char()] | binary()</v> - </type> - <desc> - <p>This function receives a packet from a socket in passive - mode. A closed socket is indicated by a return value - <c>{error, closed}</c>.</p> - <p>The <c>Length</c> argument is only meaningful when - the socket is in <c>raw</c> mode and denotes the number of - bytes to read. If <c>Length</c> = 0, all available bytes are - returned. If <c>Length</c> > 0, exactly <c>Length</c> - bytes are returned, or an error; possibly discarding less - than <c>Length</c> bytes of data when the socket gets closed - from the other side.</p> - <p>The optional <c>Timeout</c> parameter specifies a timeout in - milliseconds. The default value is <c>infinity</c>.</p> - </desc> - </func> - - <func> - <name>renegotiate(Socket) -> ok | {error, Reason}</name> - <fsummary> Initiates a new handshake.</fsummary> - <type> - <v>Socket = sslsocket()</v> - </type> - <desc><p>Initiates a new handshake. A notable return value is - <c>{error, renegotiation_rejected}</c> indicating that the peer - refused to go through with the renegotiation but the connection - is still active using the previously negotiated session.</p> - </desc> - </func> - - <func> - <name>send(Socket, Data) -> ok | {error, Reason}</name> - <fsummary>Write data to a socket.</fsummary> - <type> - <v>Socket = sslsocket()</v> - <v>Data = iolist() | binary()</v> - </type> - <desc> - <p>Writes <c>Data</c> to <c>Socket</c>. </p> - <p>A notable return value is <c>{error, closed}</c> indicating that - the socket is closed.</p> - </desc> - </func> - <func> - <name>setopts(Socket, Options) -> ok | {error, Reason}</name> - <fsummary>Set socket options.</fsummary> - <type> - <v>Socket = sslsocket()</v> - <v>Options = [socketoption]()</v> - </type> - <desc> - <p>Sets options according to <c>Options</c> for the socket - <c>Socket</c>. </p> - </desc> - </func> - - <func> - <name>shutdown(Socket, How) -> ok | {error, Reason}</name> - <fsummary>Immediately close a socket</fsummary> - <type> - <v>Socket = sslsocket()</v> - <v>How = read | write | read_write</v> - <v>Reason = reason()</v> - </type> - <desc> - <p>Immediately close a socket in one or two directions.</p> - <p><c>How == write</c> means closing the socket for writing, - reading from it is still possible.</p> - <p>To be able to handle that the peer has done a shutdown on - the write side, the <c>{exit_on_close, false}</c> option - is useful.</p> - </desc> - </func> - - <func> - <name>ssl_accept(ListenSocket) -> </name> - <name>ssl_accept(ListenSocket, Timeout) -> ok | {error, Reason}</name> - <fsummary>Perform server-side SSL handshake</fsummary> - <type> - <v>ListenSocket = sslsocket()</v> - <v>Timeout = integer()</v> - <v>Reason = term()</v> - </type> - <desc> - <p>The <c>ssl_accept</c> function establish the SSL connection - on the server side. It should be called directly after - <c>transport_accept</c>, in the spawned server-loop.</p> - </desc> - </func> - - <func> - <name>ssl_accept(ListenSocket, SslOptions) -> </name> - <name>ssl_accept(ListenSocket, SslOptions, Timeout) -> {ok, Socket} | {error, Reason}</name> - <fsummary>Perform server-side SSL handshake</fsummary> - <type> - <v>ListenSocket = socket()</v> - <v>SslOptions = ssloptions()</v> - <v>Timeout = integer()</v> - <v>Reason = term()</v> - </type> - <desc> - <p> Upgrades a gen_tcp, or - equivalent, socket to a ssl socket e.i performs the - ssl server-side handshake.</p> - </desc> - </func> - - <func> - <name>sockname(Socket) -> {ok, {Address, Port}} | - {error, Reason}</name> - <fsummary>Return the local address and port.</fsummary> - <type> - <v>Socket = sslsocket()</v> - <v>Address = ipaddress()</v> - <v>Port = integer()</v> - </type> - <desc> - <p>Returns the local address and port number of the socket - <c>Socket</c>.</p> - </desc> - </func> - - <func> - <name>start() -> </name> - <name>start(Type) -> ok | {error, Reason}</name> - <fsummary>Starts the Ssl application. </fsummary> - <type> - <v>Type = permanent | transient | temporary</v> - </type> - <desc> - <p>Starts the Ssl application. Default type - is temporary. - <seealso marker="kernel:application">application(3)</seealso></p> - </desc> - </func> - <func> - <name>stop() -> ok </name> - <fsummary>Stops the Ssl application.</fsummary> - <desc> - <p>Stops the Ssl application. - <seealso marker="kernel:application">application(3)</seealso></p> - </desc> - </func> - - <func> - <name>transport_accept(Socket) -></name> - <name>transport_accept(Socket, Timeout) -> - {ok, NewSocket} | {error, Reason}</name> - <fsummary>Accept an incoming connection and - prepare for <c>ssl_accept</c></fsummary> - <type> - <v>Socket = NewSocket = sslsocket()</v> - <v>Timeout = integer()</v> - <v>Reason = reason()</v> - </type> - <desc> - <p>Accepts an incoming connection request on a listen socket. - <c>ListenSocket</c> must be a socket returned from - <c>listen/2</c>. The socket returned should be passed to - <c>ssl_accept</c> to complete ssl handshaking and - establishing the connection.</p> - <warning> - <p>The socket returned can only be used with <c>ssl_accept</c>, - no traffic can be sent or received before that call.</p> - </warning> - <p>The accepted socket inherits the options set for - <c>ListenSocket</c> in <c>listen/2</c>.</p> - <p>The default - value for <c>Timeout</c> is <c>infinity</c>. If - <c>Timeout</c> is specified, and no connection is accepted - within the given time, <c>{error, timeout}</c> is - returned.</p> - </desc> - </func> - - <func> - <name>versions() -> - [{SslAppVer, SupportedSslVer, AvailableSslVsn}]</name> - <fsummary>Returns version information relevant for the - ssl application.</fsummary> - <type> - <v>SslAppVer = string()</v> - <v>SupportedSslVer = [protocol()]</v> - <v>AvailableSslVsn = [protocol()]</v> - </type> - <desc> - <p> - Returns version information relevant for the - ssl application.</p> - </desc> - </func> - </funcs> - - <section> - <title>SEE ALSO</title> - <p><seealso marker="kernel:inet">inet(3) </seealso> and - <seealso marker="kernel:gen_tcp">gen_tcp(3) </seealso> - </p> - </section> - -</erlref> - diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml index 9d13427677..756c0d1b1f 100644 --- a/lib/ssl/doc/src/notes.xml +++ b/lib/ssl/doc/src/notes.xml @@ -30,6 +30,241 @@ </header> <p>This document describes the changes made to the SSL application. </p> + + <section><title>SSL 4.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Updated ssl to ignore CA certs that violate the asn1-spec + for a certificate, and updated public key asn1 spec to + handle inherited DSS-params.</p> + <p> + Own Id: OTP-7884</p> + </item> + <item> + <p> + Changed ssl implementation to retain backwards + compatibility for old option {verify, 0} that shall be + equivalent to {verify, verify_none}, also separate the + cases unknown ca and selfsigned peer cert, and restored + return value of deprecated function + public_key:pem_to_der/1.</p> + <p> + Own Id: OTP-8858</p> + </item> + <item> + <p> + Changed the verify fun so that it differentiate between + the peer certificate and CA certificates by using + valid_peer or valid as the second argument to the verify + fun. It may not always be trivial or even possible to + know when the peer certificate is reached otherwise.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-8873</p> + </item> + </list> + </section> + +</section> + +<section><title>SSL 4.0.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + The server now verifies the client certificate verify + message correctly, instead of causing a case-clause.</p> + <p> + Own Id: OTP-8721</p> + </item> + <item> + <p> + The client hello message now always include ALL available + cipher suites (or those specified by the ciphers option). + Previous implementation would filter them based on the + client certificate key usage extension (such filtering + only makes sense for the server certificate).</p> + <p> + Own Id: OTP-8772</p> + </item> + <item> + <p> + Fixed handling of the option {mode, list} that was broken + for some packet types for instance line.</p> + <p> + Own Id: OTP-8785</p> + </item> + <item> + <p> + Empty packets were not delivered to the client.</p> + <p> + Own Id: OTP-8790</p> + </item> + <item> + <p> Building in a source tree without prebuilt platform + independent build results failed on the SSL examples + when: </p> <list><item> cross building. This has been + solved by not building the SSL examples during a cross + build. </item><item> building on Windows. </item></list> + <p> + Own Id: OTP-8791</p> + </item> + <item> + <p> + Fixed a handshake error which occurred on some ssl + implementations.</p> + <p> + Own Id: OTP-8793</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Revise the public_key API - Cleaned up and documented the + public_key API to make it useful for general use, also + changed ssl to use the new API.</p> + <p> + Own Id: OTP-8722</p> + </item> + <item> + <p> + Added support for inputing certificates and keys directly + in DER format these options will override the pem-file + options if specified.</p> + <p> + Own Id: OTP-8723</p> + </item> + <item> + <p> + To gain interoperability ssl will not check for padding + errors when using TLS 1.0. It is first in TLS 1.1 that + checking the padding is an requirement.</p> + <p> + Own Id: OTP-8740</p> + </item> + <item> + <p> + Changed the semantics of the verify_fun option in the + ssl-application so that it takes care of both application + handling of path validation errors and verification of + application specific extensions. This means that it is + now possible for the server application in verify_peer + mode to handle path validation errors. This change moved + some functionality earlier in ssl to the public_key + application.</p> + <p> + Own Id: OTP-8770</p> + </item> + <item> + <p> + Added the functionality so that the verification fun will + be called when a certificate is considered valid by the + path validation to allow access to each certificate in + the path to the user application. Also try to verify + subject-AltName, if unable to verify it let the + application verify it.</p> + <p> + Own Id: OTP-8825</p> + </item> + </list> + </section> + +</section> + +<section><title>SSL 4.0</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + New ssl now support client/server-certificates signed by + dsa keys.</p> + <p> + Own Id: OTP-8587</p> + </item> + <item> + <p> + Ssl has now switched default implementation and removed + deprecated certificate handling. All certificate handling + is done by the public_key application.</p> + <p> + Own Id: OTP-8695</p> + </item> + </list> + </section> + + </section> + + + <section><title>SSL 3.11.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed handling of several ssl/tls packets arriving at the + same time. This was broken during a refactoring of the + code.</p> + <p> + Own Id: OTP-8679</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Added missing checks for padding and Mac value. Removed + code for export ciphers and DH certificates as we decided + not to support them.</p> + <p> + Own Id: OTP-7047</p> + </item> + <item> + <p> + New ssl will no longer return esslerrssl to be backwards + compatible with old ssl as this hids infomation from the + user. format_error/1 has been updated to support new ssl.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-7049</p> + </item> + <item> + <p> + New ssl now supports secure renegotiation as described by + RFC 5746.</p> + <p> + Own Id: OTP-8568</p> + </item> + <item> + <p> + Alert handling has been improved to better handle + unexpected but valid messages and the implementation is + also changed to avoid timing related issues that could + cause different error messages depending on network + latency. Packet handling was sort of broken but would + mostly work as expected when socket was in binary mode. + This has now been fixed.</p> + <p> + Own Id: OTP-8588</p> + </item> + </list> + </section> + +</section> + <section><title>SSL 3.11</title> <section><title>Fixed Bugs and Malfunctions</title> @@ -733,7 +968,7 @@ <title>Fixed Bugs and Malfunctions</title> <list type="bulleted"> <item> - <p>When a file descriptor was marked for closing, and and + <p>When a file descriptor was marked for closing, and end-of-file condition had already been detected, the file descriptor was never closed.</p> <p>Own Id: OTP-5093 Aux Id: seq8806 </p> diff --git a/lib/ssl/doc/src/old_ssl.xml b/lib/ssl/doc/src/old_ssl.xml new file mode 100644 index 0000000000..0d2e1afdbd --- /dev/null +++ b/lib/ssl/doc/src/old_ssl.xml @@ -0,0 +1,709 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1999</year><year>2010</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>ssl</title> + <prepared>Peter Högfeldt</prepared> + <responsible>Peter Högfeldt</responsible> + <docno></docno> + <approved>Peter Högfeldt</approved> + <checked></checked> + <date>2003-03-25</date> + <rev>D</rev> + <file>old_ssl.xml</file> + </header> + <module>old_ssl</module> + <modulesummary>Interface Functions for Secure Socket Layer</modulesummary> + <description> + <p>This module contains interface functions to the Secure Socket Layer.</p> + </description> + + <section> + <title>General</title> + + <p>This manual page describes functions that are defined + in the ssl module and represents the old ssl implementation + that coexists with the new one until it has been + totally phased out. </p> + + <p>The old implementation can be + accessed by providing the option {ssl_imp, old} to the + ssl:connect and ssl:listen functions.</p> + + <p>The reader is advised to also read the <c>ssl(6)</c> manual page + describing the SSL application. + </p> + <warning> + <p>It is strongly advised to seed the random generator after + the ssl application has been started (see <c>seed/1</c> + below), and before any connections are established. Although + the port program interfacing to the ssl libraries does a + "random" seeding of its own in order to make everything work + properly, that seeding is by no means random for the world + since it has a constant value which is known to everyone + reading the source code of the port program.</p> + </warning> + </section> + + <section> + <title>Common data types</title> + <p>The following datatypes are used in the functions below: + </p> + <list type="bulleted"> + <item> + <p><c>options() = [option()]</c></p> + </item> + <item> + <p><c>option() = socketoption() | ssloption()</c></p> + </item> + <item> + <p><c>socketoption() = {mode, list} | {mode, binary} | binary | {packet, packettype()} | {header, integer()} | {nodelay, boolean()} | {active, activetype()} | {backlog, integer()} | {ip, ipaddress()} | {port, integer()}</c></p> + </item> + <item> + <p><c>ssloption() = {verify, code()} | {depth, depth()} | {certfile, path()} | {keyfile, path()} | {password, string()} | {cacertfile, path()} | {ciphers, string()}</c></p> + </item> + <item> + <p><c>packettype()</c> (see inet(3))</p> + </item> + <item> + <p><c>activetype()</c> (see inet(3))</p> + </item> + <item> + <p><c>reason() = atom() | {atom(), string()}</c></p> + </item> + <item> + <p><c>bytes() = [byte()]</c></p> + </item> + <item> + <p><c>string() = [byte()]</c></p> + </item> + <item> + <p><c>byte() = 0 | 1 | 2 | ... | 255</c></p> + </item> + <item> + <p><c>code() = 0 | 1 | 2</c></p> + </item> + <item> + <p><c>depth() = byte()</c></p> + </item> + <item> + <p><c>address() = hostname() | ipstring() | ipaddress()</c></p> + </item> + <item> + <p><c>ipaddress() = ipstring() | iptuple()</c></p> + </item> + <item> + <p><c>hostname() = string()</c></p> + </item> + <item> + <p><c>ipstring() = string()</c></p> + </item> + <item> + <p><c>iptuple() = {byte(), byte(), byte(), byte()}</c></p> + </item> + <item> + <p><c>sslsocket()</c></p> + </item> + <item> + <p><c>protocol() = sslv2 | sslv3 | tlsv1</c></p> + </item> + <item> + <p><c></c></p> + </item> + </list> + <p>The socket option <c>{backlog, integer()}</c> is for + <c>listen/2</c> only, and the option <c>{port, integer()}</c> + is for <c>connect/3/4</c> only. + </p> + <p>The following socket options are set by default: <c>{mode, list}</c>, <c>{packet, 0}</c>, <c>{header, 0}</c>, <c>{nodelay, false}</c>, <c>{active, true}</c>, <c>{backlog, 5}</c>, + <c>{ip, {0,0,0,0}}</c>, and <c>{port, 0}</c>. + </p> + <p>Note that the options <c>{mode, binary}</c> and <c>binary</c> + are equivalent. Similarly <c>{mode, list}</c> and the absence of + option <c>binary</c> are equivalent. + </p> + <p>The ssl options are for setting specific SSL parameters as follows: + </p> + <list type="bulleted"> + <item> + <p><c>{verify, code()}</c> Specifies type of verification: + 0 = do not verify peer; 1 = verify peer, 2 = verify peer, + fail if no peer certificate. The default value is 0. + </p> + </item> + <item> + <p><c>{depth, depth()}</c> Specifies the maximum + verification depth, i.e. how far in a chain of certificates + the verification process can proceed before the verification + is considered to fail. + </p> + <p>Peer certificate = 0, CA certificate = 1, higher level CA + certificate = 2, etc. The value 2 thus means that a chain + can at most contain peer cert, CA cert, next CA cert, and an + additional CA cert. + </p> + <p>The default value is 1. + </p> + </item> + <item> + <p><c>{certfile, path()}</c> Path to a file containing the + user's certificate. + chain of PEM encoded certificates.</p> + </item> + <item> + <p><c>{keyfile, path()}</c> Path to file containing user's + private PEM encoded key.</p> + </item> + <item> + <p><c>{password, string()}</c> String containing the user's + password. Only used if the private keyfile is password protected.</p> + </item> + <item> + <p><c>{cacertfile, path()}</c> Path to file containing PEM encoded + CA certificates (trusted certificates used for verifying a peer + certificate).</p> + </item> + <item> + <p><c>{ciphers, string()}</c> String of ciphers as a colon + separated list of ciphers. The function <c>ciphers/0</c> can + be used to find all available ciphers.</p> + </item> + </list> + <p>The type <c>sslsocket()</c> is opaque to the user. + </p> + <p>The owner of a socket is the one that created it by a call to + <c>transport_accept/[1,2]</c>, <c>connect/[3,4]</c>, + or <c>listen/2</c>. + </p> + <p>When a socket is in active mode (the default), data from the + socket is delivered to the owner of the socket in the form of + messages: + </p> + <list type="bulleted"> + <item> + <p><c>{ssl, Socket, Data}</c></p> + </item> + <item> + <p><c>{ssl_closed, Socket}</c></p> + </item> + <item> + <p><c>{ssl_error, Socket, Reason}</c></p> + </item> + </list> + <p>A <c>Timeout</c> argument specifies a timeout in milliseconds. The + default value for a <c>Timeout</c> argument is <c>infinity</c>. + </p> + <p>Functions listed below may return the value <c>{error, closed}</c>, which only indicates that the SSL socket is + considered closed for the operation in question. It is for + instance possible to have <c>{error, closed}</c> returned from + an call to <c>send/2</c>, and a subsequent call to <c>recv/3</c> + returning <c>{ok, Data}</c>. + </p> + <p>Hence a return value of <c>{error, closed}</c> must not be + interpreted as if the socket was completely closed. On the + contrary, in order to free all resources occupied by an SSL + socket, <c>close/1</c> must be called, or else the process owning + the socket has to terminate. + </p> + <p>For each SSL socket there is an Erlang process representing the + socket. When a socket is opened, that process links to the + calling client process. Implementations that want to detect + abnormal exits from the socket process by receiving <c>{'EXIT', Pid, Reason}</c> messages, should use the function <c>pid/1</c> + to retrieve the process identifier from the socket, in order to + be able to match exit messages properly.</p> + </section> + <funcs> + <func> + <name>ciphers() -> {ok, string()} | {error, enotstarted}</name> + <fsummary>Get supported ciphers.</fsummary> + <desc> + <p>Returns a string consisting of colon separated cipher + designations that are supported by the current SSL library + implementation. + </p> + <p>The SSL application has to be started to return the string + of ciphers.</p> + </desc> + </func> + <func> + <name>close(Socket) -> ok | {error, Reason}</name> + <fsummary>Close a socket returned by <c>transport_accept/[1,2]</c>, <c>connect/3/4</c>, or <c>listen/2</c>.</fsummary> + <type> + <v>Socket = sslsocket()</v> + </type> + <desc> + <p>Closes a socket returned by <c>transport_accept/[1,2]</c>, + <c>connect/[3,4]</c>, or <c>listen/2</c></p> + </desc> + </func> + <func> + <name>connect(Address, Port, Options) -> {ok, Socket} | {error, Reason}</name> + <name>connect(Address, Port, Options, Timeout) -> {ok, Socket} | {error, Reason}</name> + <fsummary>Connect to <c>Port</c>at <c>Address</c>.</fsummary> + <type> + <v>Address = address()</v> + <v>Port = integer()</v> + <v>Options = [connect_option()]</v> + <v>connect_option() = {mode, list} | {mode, binary} | binary | {packet, packettype()} | {header, integer()} | {nodelay, boolean()} | {active, activetype()} | {ip, ipaddress()} | {port, integer()} | {verify, code()} | {depth, depth()} | {certfile, path()} | {keyfile, path()} | {password, string()} | {cacertfile, path()} | {ciphers, string()}</v> + <v>Timeout = integer()</v> + <v>Socket = sslsocket()</v> + </type> + <desc> + <p>Connects to <c>Port</c> at <c>Address</c>. If the optional + <c>Timeout</c> argument is specified, and a connection could not + be established within the given time, <c>{error, timeout}</c> is + returned. The default value for <c>Timeout</c> is <c>infinity</c>. + </p> + <p>The <c>ip</c> and <c>port</c> options are for binding to a + particular <em>local</em> address and port, respectively.</p> + </desc> + </func> + <func> + <name>connection_info(Socket) -> {ok, {Protocol, Cipher}} | {error, Reason}</name> + <fsummary>Get current protocol version and cipher.</fsummary> + <type> + <v>Socket = sslsocket()</v> + <v>Protocol = protocol()</v> + <v>Cipher = string()</v> + </type> + <desc> + <p>Gets the chosen protocol version and cipher for an established + connection (accepted och connected). </p> + </desc> + </func> + <func> + <name>controlling_process(Socket, NewOwner) -> ok | {error, Reason}</name> + <fsummary>Assign a new controlling process to the socket.</fsummary> + <type> + <v>Socket = sslsocket()</v> + <v>NewOwner = pid()</v> + </type> + <desc> + <p>Assigns a new controlling process to <c>Socket</c>. A controlling + process is the owner of a socket, and receives all messages from + the socket.</p> + </desc> + </func> + <func> + <name>format_error(ErrorCode) -> string()</name> + <fsummary>Return an error string.</fsummary> + <type> + <v>ErrorCode = term()</v> + </type> + <desc> + <p>Returns a diagnostic string describing an error.</p> + </desc> + </func> + <func> + <name>getopts(Socket, OptionsTags) -> {ok, Options} | {error, Reason}</name> + <fsummary>Get options set for socket</fsummary> + <type> + <v>Socket = sslsocket()</v> + <v>OptionTags = [optiontag()]()</v> + </type> + <desc> + <p>Returns the options the tags of which are <c>OptionTags</c> for + for the socket <c>Socket</c>. </p> + </desc> + </func> + <func> + <name>listen(Port, Options) -> {ok, ListenSocket} | {error, Reason}</name> + <fsummary>Set up a socket to listen on a port on the local host.</fsummary> + <type> + <v>Port = integer()</v> + <v>Options = [listen_option()]</v> + <v>listen_option() = {mode, list} | {mode, binary} | binary | {packet, packettype()} | {header, integer()} | {active, activetype()} | {backlog, integer()} | {ip, ipaddress()} | {verify, code()} | {depth, depth()} | {certfile, path()} | {keyfile, path()} | {password, string()} | {cacertfile, path()} | {ciphers, string()}</v> + <v>ListenSocket = sslsocket()</v> + </type> + <desc> + <p>Sets up a socket to listen on port <c>Port</c> at the local host. + If <c>Port</c> is zero, <c>listen/2</c> picks an available port + number (use <c>port/1</c> to retrieve it). + </p> + <p>The listen queue size defaults to 5. If a different value is + wanted, the option <c>{backlog, Size}</c> should be added to the + list of options. + </p> + <p>An empty <c>Options</c> list is considered an error, and + <c>{error, enooptions}</c> is returned. + </p> + <p>The returned <c>ListenSocket</c> can only be used in calls to + <c>transport_accept/[1,2]</c>.</p> + </desc> + </func> + <func> + <name>peercert(Socket) -> {ok, Cert} | {error, Reason}</name> + <fsummary>Return the peer certificate.</fsummary> + <type> + <v>Socket = sslsocket()</v> + <v>Cert = binary()()</v> + <v>Subject = term()()</v> + </type> + <desc> + <p>Returns the DER encoded peer certificate, the certificate can be decoded with + <c>public_key:pkix_decode_cert/2</c>. + </p> + </desc> + </func> + <func> + <name>peername(Socket) -> {ok, {Address, Port}} | {error, Reason}</name> + <fsummary>Return peer address and port.</fsummary> + <type> + <v>Socket = sslsocket()</v> + <v>Address = ipaddress()</v> + <v>Port = integer()</v> + </type> + <desc> + <p>Returns the address and port number of the peer.</p> + </desc> + </func> + <func> + <name>pid(Socket) -> pid()</name> + <fsummary>Return the pid of the socket process.</fsummary> + <type> + <v>Socket = sslsocket()</v> + </type> + <desc> + <p>Returns the pid of the socket process. The returned pid should + only be used for receiving exit messages.</p> + </desc> + </func> + <func> + <name>recv(Socket, Length) -> {ok, Data} | {error, Reason}</name> + <name>recv(Socket, Length, Timeout) -> {ok, Data} | {error, Reason}</name> + <fsummary>Receive data on socket.</fsummary> + <type> + <v>Socket = sslsocket()</v> + <v>Length = integer() >= 0</v> + <v>Timeout = integer()</v> + <v>Data = bytes() | binary()</v> + </type> + <desc> + <p>Receives data on socket <c>Socket</c> when the socket is in + passive mode, i.e. when the option <c>{active, false}</c> + has been specified. + </p> + <p>A notable return value is <c>{error, closed}</c> which + indicates that the socket is closed. + </p> + <p>A positive value of the <c>Length</c> argument is only + valid when the socket is in raw mode (option <c>{packet, 0}</c> is set, and the option <c>binary</c> is <em>not</em> + set); otherwise it should be set to 0, whence all available + bytes are returned. + </p> + <p>If the optional <c>Timeout</c> parameter is specified, and + no data was available within the given time, <c>{error, timeout}</c> is returned. The default value for + <c>Timeout</c> is <c>infinity</c>.</p> + </desc> + </func> + <func> + <name>seed(Data) -> ok | {error, Reason}</name> + <fsummary>Seed the ssl random generator.</fsummary> + <type> + <v>Data = iolist() | binary()</v> + </type> + <desc> + <p>Seeds the ssl random generator. + </p> + <p>It is strongly advised to seed the random generator after + the ssl application has been started, and before any + connections are established. Although the port program + interfacing to the OpenSSL libraries does a "random" seeding + of its own in order to make everything work properly, that + seeding is by no means random for the world since it has a + constant value which is known to everyone reading the source + code of the seeding. + </p> + <p>A notable return value is <c>{error, edata}}</c> indicating that + <c>Data</c> was not a binary nor an iolist.</p> + </desc> + </func> + <func> + <name>send(Socket, Data) -> ok | {error, Reason}</name> + <fsummary>Write data to a socket.</fsummary> + <type> + <v>Socket = sslsocket()</v> + <v>Data = iolist() | binary()</v> + </type> + <desc> + <p>Writes <c>Data</c> to <c>Socket</c>. </p> + <p>A notable return value is <c>{error, closed}</c> indicating that + the socket is closed.</p> + </desc> + </func> + <func> + <name>setopts(Socket, Options) -> ok | {error, Reason}</name> + <fsummary>Set socket options.</fsummary> + <type> + <v>Socket = sslsocket()</v> + <v>Options = [socketoption]()</v> + </type> + <desc> + <p>Sets options according to <c>Options</c> for the socket + <c>Socket</c>. </p> + </desc> + </func> + <func> + <name>ssl_accept(Socket) -> ok | {error, Reason}</name> + <name>ssl_accept(Socket, Timeout) -> ok | {error, Reason}</name> + <fsummary>Perform server-side SSL handshake and key exchange</fsummary> + <type> + <v>Socket = sslsocket()</v> + <v>Timeout = integer()</v> + <v>Reason = atom()</v> + </type> + <desc> + <p>The <c>ssl_accept</c> function establish the SSL connection + on the server side. It should be called directly after + <c>transport_accept</c>, in the spawned server-loop.</p> + <p>Note that the ssl connection is not complete until <c>ssl_accept</c> + has returned <c>true</c>, and if an error is returned, the socket + is unavailable and for instance <c>close/1</c> will crash.</p> + </desc> + </func> + <func> + <name>sockname(Socket) -> {ok, {Address, Port}} | {error, Reason}</name> + <fsummary>Return the local address and port.</fsummary> + <type> + <v>Socket = sslsocket()</v> + <v>Address = ipaddress()</v> + <v>Port = integer()</v> + </type> + <desc> + <p>Returns the local address and port number of the socket + <c>Socket</c>.</p> + </desc> + </func> + <func> + <name>transport_accept(Socket) -> {ok, NewSocket} | {error, Reason}</name> + <name>transport_accept(Socket, Timeout) -> {ok, NewSocket} | {error, Reason}</name> + <fsummary>Accept an incoming connection and prepare for <c>ssl_accept</c></fsummary> + <type> + <v>Socket = NewSocket = sslsocket()</v> + <v>Timeout = integer()</v> + <v>Reason = atom()</v> + </type> + <desc> + <p>Accepts an incoming connection request on a listen socket. + <c>ListenSocket</c> must be a socket returned from <c>listen/2</c>. + The socket returned should be passed to <c>ssl_accept</c> to + complete ssl handshaking and establishing the connection.</p> + <warning> + <p>The socket returned can only be used with <c>ssl_accept</c>, + no traffic can be sent or received before that call.</p> + </warning> + <p>The accepted socket inherits the options set for <c>ListenSocket</c> + in <c>listen/2</c>.</p> + <p>The default value for <c>Timeout</c> is <c>infinity</c>. If + <c>Timeout</c> is specified, and no connection is accepted within + the given time, <c>{error, timeout}</c> is returned.</p> + </desc> + </func> + <func> + <name>version() -> {ok, {SSLVsn, CompVsn, LibVsn}}</name> + <fsummary>Return the version of SSL.</fsummary> + <type> + <v>SSLVsn = CompVsn = LibVsn = string()()</v> + </type> + <desc> + <p>Returns the SSL application version (<c>SSLVsn</c>), the library + version used when compiling the SSL application port program + (<c>CompVsn</c>), and the actual library version used when + dynamically linking in runtime (<c>LibVsn</c>). + </p> + <p>If the SSL application has not been started, <c>CompVsn</c> and + <c>LibVsn</c> are empty strings. + </p> + </desc> + </func> + </funcs> + + <section> + <title>ERRORS</title> + <p>The possible error reasons and the corresponding diagnostic strings + returned by <c>format_error/1</c> are either the same as those defined + in the <c>inet(3)</c> reference manual, or as follows: + </p> + <taglist> + <tag><c>closed</c></tag> + <item> + <p>Connection closed for the operation in question. + </p> + </item> + <tag><c>ebadsocket</c></tag> + <item> + <p>Connection not found (internal error). + </p> + </item> + <tag><c>ebadstate</c></tag> + <item> + <p>Connection not in connect state (internal error). + </p> + </item> + <tag><c>ebrokertype</c></tag> + <item> + <p>Wrong broker type (internal error). + </p> + </item> + <tag><c>ecacertfile</c></tag> + <item> + <p>Own CA certificate file is invalid. + </p> + </item> + <tag><c>ecertfile</c></tag> + <item> + <p>Own certificate file is invalid. + </p> + </item> + <tag><c>echaintoolong</c></tag> + <item> + <p>The chain of certificates provided by peer is too long. + </p> + </item> + <tag><c>ecipher</c></tag> + <item> + <p>Own list of specified ciphers is invalid. + </p> + </item> + <tag><c>ekeyfile</c></tag> + <item> + <p>Own private key file is invalid. + </p> + </item> + <tag><c>ekeymismatch</c></tag> + <item> + <p>Own private key does not match own certificate. + </p> + </item> + <tag><c>enoissuercert</c></tag> + <item> + <p>Cannot find certificate of issuer of certificate provided + by peer. + </p> + </item> + <tag><c>enoservercert</c></tag> + <item> + <p>Attempt to do accept without having set own certificate. + </p> + </item> + <tag><c>enotlistener</c></tag> + <item> + <p>Attempt to accept on a non-listening socket. + </p> + </item> + <tag><c>enoproxysocket</c></tag> + <item> + <p>No proxy socket found (internal error). + </p> + </item> + <tag><c>enooptions</c></tag> + <item> + <p>The list of options is empty. + </p> + </item> + <tag><c>enotstarted</c></tag> + <item> + <p>The SSL application has not been started. + </p> + </item> + <tag><c>eoptions</c></tag> + <item> + <p>Invalid list of options. + </p> + </item> + <tag><c>epeercert</c></tag> + <item> + <p>Certificate provided by peer is in error. + </p> + </item> + <tag><c>epeercertexpired</c></tag> + <item> + <p>Certificate provided by peer has expired. + </p> + </item> + <tag><c>epeercertinvalid</c></tag> + <item> + <p>Certificate provided by peer is invalid. + </p> + </item> + <tag><c>eselfsignedcert</c></tag> + <item> + <p>Certificate provided by peer is self signed. + </p> + </item> + <tag><c>esslaccept</c></tag> + <item> + <p>Server SSL handshake procedure between client and server failed. + </p> + </item> + <tag><c>esslconnect</c></tag> + <item> + <p>Client SSL handshake procedure between client and server failed. + </p> + </item> + <tag><c>esslerrssl</c></tag> + <item> + <p>SSL protocol failure. Typically because of a fatal alert + from peer. + </p> + </item> + <tag><c>ewantconnect</c></tag> + <item> + <p>Protocol wants to connect, which is not supported in + this version of the SSL application. + </p> + </item> + <tag><c>ex509lookup</c></tag> + <item> + <p>Protocol wants X.509 lookup, which is not supported in + this version of the SSL application. + </p> + </item> + <tag><c>{badcall, Call}</c></tag> + <item> + <p>Call not recognized for current mode (active or passive) and + state of socket. + </p> + </item> + <tag><c>{badcast, Cast}</c></tag> + <item> + <p>Call not recognized for current mode (active or passive) and + state of socket. + </p> + </item> + <tag><c>{badinfo, Info}</c></tag> + <item> + <p>Call not recognized for current mode (active or passive) and + state of socket. + </p> + </item> + </taglist> + </section> + + <section> + <title>SEE ALSO</title> + <p>gen_tcp(3), inet(3) public_key(3) </p> + </section> + +</erlref> + + diff --git a/lib/ssl/doc/src/refman.xml b/lib/ssl/doc/src/refman.xml index 3ad5a01b46..68f84660f3 100644 --- a/lib/ssl/doc/src/refman.xml +++ b/lib/ssl/doc/src/refman.xml @@ -4,7 +4,7 @@ <application xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>1999</year><year>2009</year> + <year>1999</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>SSL Reference Manual</title> @@ -45,7 +45,8 @@ </description> <xi:include href="ssl_app.xml"/> <xi:include href="ssl.xml"/> - <xi:include href="new_ssl.xml"/> + <xi:include href="old_ssl.xml"/> + <xi:include href="ssl_session_cache_api.xml"/> </application> diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml index 217eb791d0..413703deca 100644 --- a/lib/ssl/doc/src/ssl.xml +++ b/lib/ssl/doc/src/ssl.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE erlref SYSTEM "erlref.dtd"> <erlref> <header> <copyright> - <year>1999</year><year>2009</year> + <year>1999</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -13,355 +13,508 @@ 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> + </legalnotice> <title>ssl</title> - <prepared>Peter Högfeldt</prepared> - <responsible>Peter Högfeldt</responsible> - <docno></docno> - <approved>Peter Högfeldt</approved> - <checked></checked> - <date>2003-03-25</date> - <rev>D</rev> - <file>ssl.sgml</file> + <file>ssl.xml</file> </header> <module>ssl</module> <modulesummary>Interface Functions for Secure Socket Layer</modulesummary> <description> - <p>This module contains interface functions to the Secure Socket Layer.</p> + <p>This module contains interface functions to the Secure Socket + Layer. + </p> </description> + + <section> + <title>SSL</title> + <list type="bulleted"> + <item>ssl requires the crypto an public_key applications.</item> + <item>Supported SSL/TLS-versions are SSL-3.0 and TLS-1.0 </item> + <item>For security reasons sslv2 is not supported.</item> + <item>Ephemeral Diffie-Hellman cipher suites are supported + but not Diffie Hellman Certificates cipher suites.</item> + <item>Export cipher suites are not supported as the + U.S. lifted its export restrictions in early 2000.</item> + <item>CRL and policy certificate + extensions are not supported yet. </item> + </list> + + </section> + <section> - <title>General</title> + <title>COMMON DATA TYPES</title> + <p>The following data types are used in the functions below: + </p> + + <p><c>boolean() = true | false</c></p> + + <p><c>property() = atom()</c></p> + + <p><c>option() = socketoption() | ssloption() | transportoption()</c></p> + + <p><c>socketoption() = [{property(), term()}] - defaults to + [{mode,list},{packet, 0},{header, 0},{active, true}]. + </c></p> + + <p>For valid options + see <seealso marker="kernel:inet">inet(3) </seealso> and + <seealso marker="kernel:gen_tcp">gen_tcp(3) </seealso>. + </p> + + <p> <c>ssloption() = {verify, verify_type()} | + {verify_fun, {fun(), term()}} | + {fail_if_no_peer_cert, boolean()} + {depth, integer()} | + {cert, der_bin()}| {certfile, path()} | + {key, der_bin()} | {keyfile, path()} | {password, string()} | + {cacerts, [der_bin()]} | {cacertfile, path()} | + |{dh, der_bin()} | {dhfile, path()} | {ciphers, ciphers()} | + {ssl_imp, ssl_imp()} | {reuse_sessions, boolean()} | {reuse_session, fun()} + </c></p> - <p>There is a new implementation of ssl available in - this module but until it is 100 % complete, so that it can replace - the old implementation in all aspects it will be - described here <seealso marker="new_ssl"> new ssl API </seealso></p> + <p><c>transportoption() = {CallbackModule, DataTag, ClosedTag} + - defaults to {gen_tcp, tcp, tcp_closed}. Ssl may be + run over any reliable transport protocol that has + an equivalent API to gen_tcp's.</c></p> + + <p><c> CallbackModule = + atom()</c> + </p> <p><c> DataTag = + atom() - tag used in socket data message.</c></p> + <p><c> ClosedTag = atom() - tag used in + socket close message.</c></p> + + <p><c>verify_type() = verify_none | verify_peer</c></p> + + <p><c>path() = string() - representing a file path.</c></p> + + <p><c>der_bin() = binary() -Asn1 DER encoded entity as an erlang binary.</c></p> + + <p><c>host() = hostname() | ipaddress()</c></p> + + <p><c>hostname() = string()</c></p> + + <p><c> + ip_address() = {N1,N2,N3,N4} % IPv4 + | {K1,K2,K3,K4,K5,K6,K7,K8} % IPv6 </c></p> + + <p><c>sslsocket() - opaque to the user. </c></p> + + <p><c>protocol() = sslv3 | tlsv1 </c></p> + + <p><c>ciphers() = [ciphersuite()] | string() (according to old API)</c></p> + + <p><c>ciphersuite() = + {key_exchange(), cipher(), hash()}</c></p> + + <p><c>key_exchange() = rsa | dhe_dss | dhe_rsa + </c></p> + + <p><c>cipher() = rc4_128 | des_cbc | '3des_ede_cbc' + | aes_128_cbc | aes_256_cbc </c></p> + + <p> <c>hash() = md5 | sha + </c></p> + + <p><c>ssl_imp() = new | old - default is new.</c></p> - <p>The reader is advised to also read the <c>ssl(6)</c> manual page - describing the SSL application. - </p> - <warning> - <p>It is strongly advised to seed the random generator after - the ssl application has been started (see <c>seed/1</c> - below), and before any connections are established. Although - the port program interfacing to the ssl libraries does a - "random" seeding of its own in order to make everything work - properly, that seeding is by no means random for the world - since it has a constant value which is known to everyone - reading the source code of the port program.</p> - </warning> </section> <section> - <title>Common data types</title> - <p>The following datatypes are used in the functions below: - </p> - <list type="bulleted"> - <item> - <p><c>options() = [option()]</c></p> - </item> - <item> - <p><c>option() = socketoption() | ssloption()</c></p> - </item> - <item> - <p><c>socketoption() = {mode, list} | {mode, binary} | binary | {packet, packettype()} | {header, integer()} | {nodelay, boolean()} | {active, activetype()} | {backlog, integer()} | {ip, ipaddress()} | {port, integer()}</c></p> - </item> - <item> - <p><c>ssloption() = {verify, code()} | {depth, depth()} | {certfile, path()} | {keyfile, path()} | {password, string()} | {cacertfile, path()} | {ciphers, string()}</c></p> - </item> - <item> - <p><c>packettype()</c> (see inet(3))</p> - </item> - <item> - <p><c>activetype()</c> (see inet(3))</p> - </item> - <item> - <p><c>reason() = atom() | {atom(), string()}</c></p> - </item> - <item> - <p><c>bytes() = [byte()]</c></p> - </item> - <item> - <p><c>string() = [byte()]</c></p> - </item> - <item> - <p><c>byte() = 0 | 1 | 2 | ... | 255</c></p> - </item> - <item> - <p><c>code() = 0 | 1 | 2</c></p> - </item> - <item> - <p><c>depth() = byte()</c></p> - </item> - <item> - <p><c>address() = hostname() | ipstring() | ipaddress()</c></p> - </item> - <item> - <p><c>ipaddress() = ipstring() | iptuple()</c></p> + <title>SSL OPTION DESCRIPTIONS - COMMON for SERVER and CLIENT</title> + + <p>Options described here are options that are have the same + meaning in the client and the server. + </p> + + <taglist> + + <tag>{cert, der_bin()}</tag> + <item> The DER encoded users certificate. If this option + is supplied it will override the certfile option.</item> + + <tag>{certfile, path()}</tag> + <item>Path to a file containing the user's certificate.</item> + + <tag>{key, der_bin()}</tag> + <item> The DER encoded users private key. If this option + is supplied it will override the keyfile option.</item> + + <tag>{keyfile, path()}</tag> + <item>Path to file containing user's + private PEM encoded key. As PEM-files may contain several + entries this option defaults to the same file as given by + certfile option.</item> + + <tag>{password, string()}</tag> + <item>String containing the user's password. + Only used if the private keyfile is password protected. </item> - <item> - <p><c>hostname() = string()</c></p> + + <tag>{cacerts, [der_bin()]}</tag> + <item> The DER encoded trusted certificates. If this option + is supplied it will override the cacertfile option.</item> + + <tag>{cacertfile, path()}</tag> + <item>Path to file containing PEM encoded + CA certificates (trusted certificates used for verifying a peer + certificate). May be omitted if you do not want to verify + the peer.</item> + + <tag>{ciphers, ciphers()}</tag> + <item>The cipher suites that should be supported. The function + <c>ciphers_suites/0</c> can be used to find all available + ciphers. </item> - <item> - <p><c>ipstring() = string()</c></p> + + <tag>{ssl_imp, ssl_imp()}</tag> + <item>Specify which ssl implementation you want to use. Defaults to + new. </item> - <item> - <p><c>iptuple() = {byte(), byte(), byte(), byte()}</c></p> + + <tag>{secure_renegotiate, boolean()}</tag> + <item>Specifies if to reject renegotiation attempt that does + not live up to RFC 5746. By default secure_renegotiate is + set to false i.e. secure renegotiation will be used if possible + but it will fallback to unsecure renegotiation if the peer + does not support RFC 5746. </item> - <item> - <p><c>sslsocket()</c></p> + + <tag>{depth, integer()}</tag> + <item>Specifies the maximum + verification depth, i.e. how far in a chain of certificates the + verification process can proceed before the verification is + considered to fail. Peer certificate = 0, CA certificate = 1, + higher level CA certificate = 2, etc. The value 2 thus means + that a chain can at most contain peer cert, CA cert, next CA + cert, and an additional CA cert. The default value is 1. </item> + + <tag>{verify_fun, {Verifyfun :: fun(), InitialUserState :: term()}}</tag> <item> - <p><c>protocol() = sslv2 | sslv3 | tlsv1</c></p> + <p>The verification fun should be defined as:</p> + + <code> +fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} | + {extension, #'Extension'{}}, InitialUserState :: term()) -> + {valid, UserState :: term()} | {valid_peer, UserState :: term()} | + {fail, Reason :: term()} | {unknown, UserState :: term()}. + </code> + + <p>The verify fun will be called during the X509-path + validation when an error or an extension unknown to the ssl + application is encountered. Additionally it will be called + when a certificate is considered valid by the path validation + to allow access to each certificate in the path to the user + application. Note that the it will differentiate between + the peer certificate and CA certificates by using valid_peer + or valid as the second argument to the verify fun. + See + <seealso marker="public_key:application">public_key(3)</seealso> + for definition of #'OTPCertificate'{} and #'Extension'{}.</p> + + <p>If the verify callback fun returns {fail, Reason}, the + verification process is immediately stopped and an alert is + sent to the peer and the TLS/SSL handshake is terminated. If + the verify callback fun returns {valid, UserState}, the + verification process is continued. If the verify callback fun + always returns {valid, UserState}, the TLS/SSL handshake will + not be terminated with respect to verification failures and + the connection will be established. If called with an + extension unknown to the user application the return value + {unknown, UserState} should be used.</p> + + <p>The default verify_fun option in verify_peer mode:</p> + + <code> +{fun(_,{bad_cert, _} = Reason, _) -> + {fail, Reason}; + (_,{extension, _}, UserState) -> + {unknown, UserState}; + (_, valid, UserState) -> + {valid, UserState}; + (_, valid_peer, UserState) -> + {valid, UserState} + end, []} + </code> + + <p>The default verify_fun option in verify_none mode:</p> + + <code> +{fun(_,{bad_cert, _}, UserState) -> + {valid, UserState}; + (_,{extension, _}, UserState) -> + {unknown, UserState}; + (_, valid, UserState) -> + {valid, UserState}; + (_, valid_peer, UserState) -> + {valid, UserState} + end, []} + </code> + +<p>Possible path validation errors: </p> + +<p> {bad_cert, cert_expired}, {bad_cert, invalid_issuer}, {bad_cert, invalid_signature}, {bad_cert, unknown_ca}, {bad_cert, name_not_permitted}, {bad_cert, missing_basic_constraint}, {bad_cert, invalid_key_usage}</p> </item> - <item> - <p><c></c></p> + + </taglist> + + </section> + + <section> + <title>SSL OPTION DESCRIPTIONS - CLIENT SIDE</title> + + <p>Options described here are client specific or has a slightly different + meaning in the client than in the server.</p> + + <taglist> + <tag>{verify, verify_type()}</tag> + <item> In verify_none mode the default behavior will be to + allow all x509-path validation errors. See also the verify_fun + option. </item> - </list> - <p>The socket option <c>{backlog, integer()}</c> is for - <c>listen/2</c> only, and the option <c>{port, integer()}</c> - is for <c>connect/3/4</c> only. - </p> - <p>The following socket options are set by default: <c>{mode, list}</c>, <c>{packet, 0}</c>, <c>{header, 0}</c>, <c>{nodelay, false}</c>, <c>{active, true}</c>, <c>{backlog, 5}</c>, - <c>{ip, {0,0,0,0}}</c>, and <c>{port, 0}</c>. - </p> - <p>Note that the options <c>{mode, binary}</c> and <c>binary</c> - are equivalent. Similarly <c>{mode, list}</c> and the absence of - option <c>binary</c> are equivalent. - </p> - <p>The ssl options are for setting specific SSL parameters as follows: - </p> - <list type="bulleted"> - <item> - <p><c>{verify, code()}</c> Specifies type of verification: - 0 = do not verify peer; 1 = verify peer, 2 = verify peer, - fail if no peer certificate. The default value is 0. - </p> + <tag>{reuse_sessions, boolean()}</tag> + <item>Specifies if client should try to reuse sessions + when possible. </item> - <item> - <p><c>{depth, depth()}</c> Specifies the maximum - verification depth, i.e. how far in a chain of certificates - the verification process can proceed before the verification - is considered to fail. - </p> - <p>Peer certificate = 0, CA certificate = 1, higher level CA - certificate = 2, etc. The value 2 thus means that a chain - can at most contain peer cert, CA cert, next CA cert, and an - additional CA cert. - </p> - <p>The default value is 1. - </p> + + </taglist> + </section> + + <section> + <title>SSL OPTION DESCRIPTIONS - SERVER SIDE</title> + + <p>Options described here are server specific or has a slightly different + meaning in the server than in the client.</p> + + <taglist> + + <tag>{dh, der_bin()}</tag> + <item>The DER encoded Diffie Hellman parameters. If this option + is supplied it will override the dhfile option. </item> - <item> - <p><c>{certfile, path()}</c> Path to a file containing the - user's certificate. - chain of PEM encoded certificates.</p> + + <tag>{dhfile, path()}</tag> + <item>Path to file containing PEM encoded Diffie Hellman parameters, + for the server to use if a cipher suite using Diffie Hellman key exchange + is negotiated. If not specified default parameters will be used. </item> - <item> - <p><c>{keyfile, path()}</c> Path to file containing user's - private PEM encoded key.</p> + + <tag>{verify, verify_type()}</tag> + <item>Servers only do the x509-path validation in verify_peer + mode, as it then will send a certificate request to the client + (this message is not sent if the verify option is verify_none) + and you may then also want to specify the option + fail_if_no_peer_cert. </item> - <item> - <p><c>{password, string()}</c> String containing the user's - password. Only used if the private keyfile is password protected.</p> + + <tag>{fail_if_no_peer_cert, boolean()}</tag> + <item>Used together with {verify, verify_peer} by a ssl server. + If set to true, the server will fail if the client does not have + a certificate to send, i.e. sends a empty certificate, if set to + false it will only fail if the client sends a invalid + certificate (an empty certificate is considered valid). </item> - <item> - <p><c>{cacertfile, path()}</c> Path to file containing PEM encoded - CA certificates (trusted certificates used for verifying a peer - certificate).</p> + + <tag>{reuse_sessions, boolean()}</tag> + <item>Specifies if the server should agree to reuse sessions + when the clients request to do so. See also the reuse_session + option. </item> - <item> - <p><c>{ciphers, string()}</c> String of ciphers as a colon - separated list of ciphers. The function <c>ciphers/0</c> can - be used to find all available ciphers.</p> + + <tag>{reuse_session, fun(SuggestedSessionId, + PeerCert, Compression, CipherSuite) -> boolean()}</tag> + <item>Enables the ssl server to have a local policy + for deciding if a session should be reused or not, + only meaning full if <c>reuse_sessions</c> is set to true. + SuggestedSessionId is a binary(), PeerCert is a DER encoded + certificate, Compression is an enumeration integer + and CipherSuite of type ciphersuite(). </item> - </list> - <p>The type <c>sslsocket()</c> is opaque to the user. - </p> - <p>The owner of a socket is the one that created it by a call to - <c>transport_accept/[1,2]</c>, <c>connect/[3,4]</c>, - or <c>listen/2</c>. - </p> - <p>When a socket is in active mode (the default), data from the + + </taglist> + </section> + + <section> + <title>General</title> + + <p>When a ssl socket is in active mode (the default), data from the socket is delivered to the owner of the socket in the form of messages: - </p> + </p> <list type="bulleted"> - <item> - <p><c>{ssl, Socket, Data}</c></p> + <item>{ssl, Socket, Data} </item> - <item> - <p><c>{ssl_closed, Socket}</c></p> + <item>{ssl_closed, Socket} </item> <item> - <p><c>{ssl_error, Socket, Reason}</c></p> + {ssl_error, Socket, Reason} </item> </list> + <p>A <c>Timeout</c> argument specifies a timeout in milliseconds. The default value for a <c>Timeout</c> argument is <c>infinity</c>. - </p> - <p>Functions listed below may return the value <c>{error, closed}</c>, which only indicates that the SSL socket is - considered closed for the operation in question. It is for - instance possible to have <c>{error, closed}</c> returned from - an call to <c>send/2</c>, and a subsequent call to <c>recv/3</c> - returning <c>{ok, Data}</c>. - </p> - <p>Hence a return value of <c>{error, closed}</c> must not be - interpreted as if the socket was completely closed. On the - contrary, in order to free all resources occupied by an SSL - socket, <c>close/1</c> must be called, or else the process owning - the socket has to terminate. - </p> - <p>For each SSL socket there is an Erlang process representing the - socket. When a socket is opened, that process links to the - calling client process. Implementations that want to detect - abnormal exits from the socket process by receiving <c>{'EXIT', Pid, Reason}</c> messages, should use the function <c>pid/1</c> - to retrieve the process identifier from the socket, in order to - be able to match exit messages properly.</p> + </p> </section> + <funcs> <func> - <name>ciphers() -> {ok, string()} | {error, enotstarted}</name> - <fsummary>Get supported ciphers.</fsummary> - <desc> - <p>Returns a string consisting of colon separated cipher - designations that are supported by the current SSL library - implementation. - </p> - <p>The SSL application has to be started to return the string - of ciphers.</p> - </desc> + <name>cipher_suites() -></name> + <name>cipher_suites(Type) -> ciphers()</name> + <fsummary> Returns a list of supported cipher suites</fsummary> + <type> + <v>Type = erlang | openssl</v> + + </type> + <desc><p>Returns a list of supported cipher suites. + cipher_suites() is equivalent to cipher_suites(erlang). + Type openssl is provided for backwards compatibility with + old ssl that used openssl. + </p> + </desc> </func> + <func> - <name>close(Socket) -> ok | {error, Reason}</name> - <fsummary>Close a socket returned by <c>transport_accept/[1,2]</c>, <c>connect/3/4</c>, or <c>listen/2</c>.</fsummary> + <name>connect(Socket, SslOptions) -> </name> + <name>connect(Socket, SslOptions, Timeout) -> {ok, SslSocket} + | {error, Reason}</name> + <fsummary> Upgrades a gen_tcp, or + equivalent, connected socket to a ssl socket. </fsummary> <type> - <v>Socket = sslsocket()</v> + <v>Socket = socket()</v> + <v>SslOptions = [ssloption()]</v> + <v>Timeout = integer() | infinity</v> + <v>SslSocket = sslsocket()</v> + <v>Reason = term()</v> </type> - <desc> - <p>Closes a socket returned by <c>transport_accept/[1,2]</c>, - <c>connect/[3,4]</c>, or <c>listen/2</c></p> - </desc> + <desc> <p>Upgrades a gen_tcp, or equivalent, + connected socket to a ssl socket i.e. performs the + client-side ssl handshake.</p> + </desc> </func> + <func> - <name>connect(Address, Port, Options) -> {ok, Socket} | {error, Reason}</name> - <name>connect(Address, Port, Options, Timeout) -> {ok, Socket} | {error, Reason}</name> - <fsummary>Connect to <c>Port</c>at <c>Address</c>.</fsummary> + <name>connect(Host, Port, Options) -></name> + <name>connect(Host, Port, Options, Timeout) -> + {ok, SslSocket} | {error, Reason}</name> + <fsummary>Opens an ssl connection to Host, Port. </fsummary> <type> - <v>Address = address()</v> - <v>Port = integer()</v> - <v>Options = [connect_option()]</v> - <v>connect_option() = {mode, list} | {mode, binary} | binary | {packet, packettype()} | {header, integer()} | {nodelay, boolean()} | {active, activetype()} | {ip, ipaddress()} | {port, integer()} | {verify, code()} | {depth, depth()} | {certfile, path()} | {keyfile, path()} | {password, string()} | {cacertfile, path()} | {ciphers, string()}</v> - <v>Timeout = integer()</v> - <v>Socket = sslsocket()</v> + <v>Host = host()</v> + <v>Port = integer()</v> + <v>Options = [option()]</v> + <v>Timeout = integer() | infinity</v> + <v>SslSocket = sslsocket()</v> + <v>Reason = term()</v> </type> - <desc> - <p>Connects to <c>Port</c> at <c>Address</c>. If the optional - <c>Timeout</c> argument is specified, and a connection could not - be established within the given time, <c>{error, timeout}</c> is - returned. The default value for <c>Timeout</c> is <c>infinity</c>. - </p> - <p>The <c>ip</c> and <c>port</c> options are for binding to a - particular <em>local</em> address and port, respectively.</p> - </desc> + <desc> <p>Opens an ssl connection to Host, Port.</p> </desc> </func> + <func> - <name>connection_info(Socket) -> {ok, {Protocol, Cipher}} | {error, Reason}</name> - <fsummary>Get current protocol version and cipher.</fsummary> + <name>close(SslSocket) -> ok | {error, Reason}</name> + <fsummary>Close a ssl connection</fsummary> <type> - <v>Socket = sslsocket()</v> - <v>Protocol = protocol()</v> - <v>Cipher = string()</v> + <v>SslSocket = sslsocket()</v> + <v>Reason = term()</v> </type> - <desc> - <p>Gets the chosen protocol version and cipher for an established - connection (accepted och connected). </p> + <desc><p>Close a ssl connection.</p> </desc> </func> + <func> - <name>controlling_process(Socket, NewOwner) -> ok | {error, Reason}</name> - <fsummary>Assign a new controlling process to the socket.</fsummary> + <name>controlling_process(SslSocket, NewOwner) -> + ok | {error, Reason}</name> + + <fsummary>Assigns a new controlling process to the + ssl-socket.</fsummary> + + <type> + <v>SslSocket = sslsocket()</v> + <v>NewOwner = pid()</v> + <v>Reason = term()</v> + </type> + <desc><p>Assigns a new controlling process to the ssl-socket. A + controlling process is the owner of a ssl-socket, and receives + all messages from the socket.</p> + </desc> + </func> + + <func> + <name>connection_info(SslSocket) -> + {ok, {ProtocolVersion, CipherSuite}} | {error, Reason} </name> + <fsummary>Returns the negotiated protocol version and cipher suite. + </fsummary> <type> - <v>Socket = sslsocket()</v> - <v>NewOwner = pid()</v> + <v>CipherSuite = ciphersuite()</v> + <v>ProtocolVersion = protocol()</v> </type> - <desc> - <p>Assigns a new controlling process to <c>Socket</c>. A controlling - process is the owner of a socket, and receives all messages from - the socket.</p> + <desc><p>Returns the negotiated protocol version and cipher suite.</p> </desc> </func> - <func> - <name>format_error(ErrorCode) -> string()</name> + + <func> + <name>format_error(Reason) -> string()</name> <fsummary>Return an error string.</fsummary> <type> - <v>ErrorCode = term()</v> + <v>Reason = term()</v> </type> <desc> - <p>Returns a diagnostic string describing an error.</p> + <p>Presents the error returned by an ssl function as a printable string.</p> </desc> </func> + <func> - <name>getopts(Socket, OptionsTags) -> {ok, Options} | {error, Reason}</name> - <fsummary>Get options set for socket</fsummary> + <name>getopts(Socket) -> </name> + <name>getopts(Socket, OptionNames) -> + {ok, [socketoption()]} | {error, Reason}</name> + <fsummary>Get the value of the specified options.</fsummary> <type> - <v>Socket = sslsocket()</v> - <v>OptionTags = [optiontag()]()</v> + <v>Socket = sslsocket()</v> + <v>OptionNames = [property()]</v> </type> <desc> - <p>Returns the options the tags of which are <c>OptionTags</c> for - for the socket <c>Socket</c>. </p> + <p>Get the value of the specified socket options, if no + options are specified all options are returned. + </p> </desc> </func> + <func> - <name>listen(Port, Options) -> {ok, ListenSocket} | {error, Reason}</name> - <fsummary>Set up a socket to listen on a port on the local host.</fsummary> + <name>listen(Port, Options) -> + {ok, ListenSocket} | {error, Reason}</name> + <fsummary>Creates a ssl listen socket.</fsummary> <type> - <v>Port = integer()</v> - <v>Options = [listen_option()]</v> - <v>listen_option() = {mode, list} | {mode, binary} | binary | {packet, packettype()} | {header, integer()} | {active, activetype()} | {backlog, integer()} | {ip, ipaddress()} | {verify, code()} | {depth, depth()} | {certfile, path()} | {keyfile, path()} | {password, string()} | {cacertfile, path()} | {ciphers, string()}</v> - <v>ListenSocket = sslsocket()</v> + <v>Port = integer()</v> + <v>Options = options()</v> + <v>ListenSocket = sslsocket()</v> </type> <desc> - <p>Sets up a socket to listen on port <c>Port</c> at the local host. - If <c>Port</c> is zero, <c>listen/2</c> picks an available port - number (use <c>port/1</c> to retrieve it). - </p> - <p>The listen queue size defaults to 5. If a different value is - wanted, the option <c>{backlog, Size}</c> should be added to the - list of options. - </p> - <p>An empty <c>Options</c> list is considered an error, and - <c>{error, enooptions}</c> is returned. - </p> - <p>The returned <c>ListenSocket</c> can only be used in calls to - <c>transport_accept/[1,2]</c>.</p> + <p>Creates a ssl listen socket.</p> </desc> </func> + <func> - <name>peercert(Socket) -> {ok, Cert} | {error, Reason}</name> + <name>peercert(Socket) -> {ok, Cert} | {error, Reason}</name> <fsummary>Return the peer certificate.</fsummary> - <type> + <type> <v>Socket = sslsocket()</v> - <v>Cert = binary()()</v> - <v>Subject = term()()</v> + <v>Cert = binary()</v> </type> <desc> - <p>Returns the DER encoded peer certificate, the certificate can be decoded with - <c>public_key:pkix_decode_cert/2</c>. - </p> + <p>The peer certificate is returned as a DER encoded binary. + The certificate can be decoded with <c>public_key:pkix_decode_cert/2</c>. + </p> </desc> </func> <func> - <name>peername(Socket) -> {ok, {Address, Port}} | {error, Reason}</name> + <name>peername(Socket) -> {ok, {Address, Port}} | + {error, Reason}</name> <fsummary>Return peer address and port.</fsummary> <type> <v>Socket = sslsocket()</v> @@ -372,67 +525,47 @@ <p>Returns the address and port number of the peer.</p> </desc> </func> + <func> - <name>pid(Socket) -> pid()</name> - <fsummary>Return the pid of the socket process.</fsummary> - <type> - <v>Socket = sslsocket()</v> - </type> - <desc> - <p>Returns the pid of the socket process. The returned pid should - only be used for receiving exit messages.</p> - </desc> - </func> - <func> - <name>recv(Socket, Length) -> {ok, Data} | {error, Reason}</name> - <name>recv(Socket, Length, Timeout) -> {ok, Data} | {error, Reason}</name> - <fsummary>Receive data on socket.</fsummary> + <name>recv(Socket, Length) -> </name> + <name>recv(Socket, Length, Timeout) -> {ok, Data} | {error, + Reason}</name> + <fsummary>Receive data on a socket.</fsummary> <type> <v>Socket = sslsocket()</v> - <v>Length = integer() >= 0</v> + <v>Length = integer()</v> <v>Timeout = integer()</v> - <v>Data = bytes() | binary()</v> + <v>Data = [char()] | binary()</v> </type> <desc> - <p>Receives data on socket <c>Socket</c> when the socket is in - passive mode, i.e. when the option <c>{active, false}</c> - has been specified. - </p> - <p>A notable return value is <c>{error, closed}</c> which - indicates that the socket is closed. - </p> - <p>A positive value of the <c>Length</c> argument is only - valid when the socket is in raw mode (option <c>{packet, 0}</c> is set, and the option <c>binary</c> is <em>not</em> - set); otherwise it should be set to 0, whence all available - bytes are returned. - </p> - <p>If the optional <c>Timeout</c> parameter is specified, and - no data was available within the given time, <c>{error, timeout}</c> is returned. The default value for - <c>Timeout</c> is <c>infinity</c>.</p> + <p>This function receives a packet from a socket in passive + mode. A closed socket is indicated by a return value + <c>{error, closed}</c>.</p> + <p>The <c>Length</c> argument is only meaningful when + the socket is in <c>raw</c> mode and denotes the number of + bytes to read. If <c>Length</c> = 0, all available bytes are + returned. If <c>Length</c> > 0, exactly <c>Length</c> + bytes are returned, or an error; possibly discarding less + than <c>Length</c> bytes of data when the socket gets closed + from the other side.</p> + <p>The optional <c>Timeout</c> parameter specifies a timeout in + milliseconds. The default value is <c>infinity</c>.</p> </desc> </func> + <func> - <name>seed(Data) -> ok | {error, Reason}</name> - <fsummary>Seed the ssl random generator.</fsummary> + <name>renegotiate(Socket) -> ok | {error, Reason}</name> + <fsummary> Initiates a new handshake.</fsummary> <type> - <v>Data = iolist() | binary()</v> + <v>Socket = sslsocket()</v> </type> - <desc> - <p>Seeds the ssl random generator. - </p> - <p>It is strongly advised to seed the random generator after - the ssl application has been started, and before any - connections are established. Although the port program - interfacing to the OpenSSL libraries does a "random" seeding - of its own in order to make everything work properly, that - seeding is by no means random for the world since it has a - constant value which is known to everyone reading the source - code of the seeding. - </p> - <p>A notable return value is <c>{error, edata}}</c> indicating that - <c>Data</c> was not a binary nor an iolist.</p> + <desc><p>Initiates a new handshake. A notable return value is + <c>{error, renegotiation_rejected}</c> indicating that the peer + refused to go through with the renegotiation but the connection + is still active using the previously negotiated session.</p> </desc> </func> + <func> <name>send(Socket, Data) -> ok | {error, Reason}</name> <fsummary>Write data to a socket.</fsummary> @@ -458,26 +591,65 @@ <c>Socket</c>. </p> </desc> </func> + <func> - <name>ssl_accept(Socket) -> ok | {error, Reason}</name> - <name>ssl_accept(Socket, Timeout) -> ok | {error, Reason}</name> - <fsummary>Perform server-side SSL handshake and key exchange</fsummary> + <name>shutdown(Socket, How) -> ok | {error, Reason}</name> + <fsummary>Immediately close a socket</fsummary> <type> <v>Socket = sslsocket()</v> + <v>How = read | write | read_write</v> + <v>Reason = reason()</v> + </type> + <desc> + <p>Immediately close a socket in one or two directions.</p> + <p><c>How == write</c> means closing the socket for writing, + reading from it is still possible.</p> + <p>To be able to handle that the peer has done a shutdown on + the write side, the <c>{exit_on_close, false}</c> option + is useful.</p> + </desc> + </func> + + <func> + <name>ssl_accept(ListenSocket) -> </name> + <name>ssl_accept(ListenSocket, Timeout) -> ok | {error, Reason}</name> + <fsummary>Perform server-side SSL handshake</fsummary> + <type> + <v>ListenSocket = sslsocket()</v> <v>Timeout = integer()</v> - <v>Reason = atom()</v> + <v>Reason = term()</v> </type> <desc> <p>The <c>ssl_accept</c> function establish the SSL connection on the server side. It should be called directly after <c>transport_accept</c>, in the spawned server-loop.</p> - <p>Note that the ssl connection is not complete until <c>ssl_accept</c> - has returned <c>true</c>, and if an error is returned, the socket - is unavailable and for instance <c>close/1</c> will crash.</p> </desc> </func> + + <func> + <name>ssl_accept(ListenSocket, SslOptions) -> </name> + <name>ssl_accept(ListenSocket, SslOptions, Timeout) -> {ok, Socket} | {error, Reason}</name> + <fsummary>Perform server-side SSL handshake</fsummary> + <type> + <v>ListenSocket = socket()</v> + <v>SslOptions = ssloptions()</v> + <v>Timeout = integer()</v> + <v>Reason = term()</v> + </type> + <desc> + <p> Upgrades a gen_tcp, or + equivalent, socket to a ssl socket i.e. performs the + ssl server-side handshake.</p> + <p><warning>Note that the listen socket should be in {active, false} mode + before telling the client that the server is ready to upgrade + and calling this function, otherwise the upgrade may + or may not succeed depending on timing.</warning></p> + </desc> + </func> + <func> - <name>sockname(Socket) -> {ok, {Address, Port}} | {error, Reason}</name> + <name>sockname(Socket) -> {ok, {Address, Port}} | + {error, Reason}</name> <fsummary>Return the local address and port.</fsummary> <type> <v>Socket = sslsocket()</v> @@ -489,217 +661,84 @@ <c>Socket</c>.</p> </desc> </func> + + <func> + <name>start() -> </name> + <name>start(Type) -> ok | {error, Reason}</name> + <fsummary>Starts the Ssl application. </fsummary> + <type> + <v>Type = permanent | transient | temporary</v> + </type> + <desc> + <p>Starts the Ssl application. Default type + is temporary. + <seealso marker="kernel:application">application(3)</seealso></p> + </desc> + </func> + <func> + <name>stop() -> ok </name> + <fsummary>Stops the Ssl application.</fsummary> + <desc> + <p>Stops the Ssl application. + <seealso marker="kernel:application">application(3)</seealso></p> + </desc> + </func> + <func> - <name>transport_accept(Socket) -> {ok, NewSocket} | {error, Reason}</name> - <name>transport_accept(Socket, Timeout) -> {ok, NewSocket} | {error, Reason}</name> - <fsummary>Accept an incoming connection and prepare for <c>ssl_accept</c></fsummary> + <name>transport_accept(Socket) -></name> + <name>transport_accept(Socket, Timeout) -> + {ok, NewSocket} | {error, Reason}</name> + <fsummary>Accept an incoming connection and + prepare for <c>ssl_accept</c></fsummary> <type> <v>Socket = NewSocket = sslsocket()</v> <v>Timeout = integer()</v> - <v>Reason = atom()</v> + <v>Reason = reason()</v> </type> <desc> <p>Accepts an incoming connection request on a listen socket. - <c>ListenSocket</c> must be a socket returned from <c>listen/2</c>. - The socket returned should be passed to <c>ssl_accept</c> to - complete ssl handshaking and establishing the connection.</p> + <c>ListenSocket</c> must be a socket returned from + <c>listen/2</c>. The socket returned should be passed to + <c>ssl_accept</c> to complete ssl handshaking and + establishing the connection.</p> <warning> <p>The socket returned can only be used with <c>ssl_accept</c>, no traffic can be sent or received before that call.</p> </warning> - <p>The accepted socket inherits the options set for <c>ListenSocket</c> - in <c>listen/2</c>.</p> - <p>The default value for <c>Timeout</c> is <c>infinity</c>. If - <c>Timeout</c> is specified, and no connection is accepted within - the given time, <c>{error, timeout}</c> is returned.</p> + <p>The accepted socket inherits the options set for + <c>ListenSocket</c> in <c>listen/2</c>.</p> + <p>The default + value for <c>Timeout</c> is <c>infinity</c>. If + <c>Timeout</c> is specified, and no connection is accepted + within the given time, <c>{error, timeout}</c> is + returned.</p> </desc> </func> + <func> - <name>version() -> {ok, {SSLVsn, CompVsn, LibVsn}}</name> - <fsummary>Return the version of SSL.</fsummary> + <name>versions() -> + [{SslAppVer, SupportedSslVer, AvailableSslVsn}]</name> + <fsummary>Returns version information relevant for the + ssl application.</fsummary> <type> - <v>SSLVsn = CompVsn = LibVsn = string()()</v> + <v>SslAppVer = string()</v> + <v>SupportedSslVer = [protocol()]</v> + <v>AvailableSslVsn = [protocol()]</v> </type> <desc> - <p>Returns the SSL application version (<c>SSLVsn</c>), the library - version used when compiling the SSL application port program - (<c>CompVsn</c>), and the actual library version used when - dynamically linking in runtime (<c>LibVsn</c>). - </p> - <p>If the SSL application has not been started, <c>CompVsn</c> and - <c>LibVsn</c> are empty strings. - </p> + <p> + Returns version information relevant for the + ssl application.</p> </desc> </func> - </funcs> - - <section> - <title>ERRORS</title> - <p>The possible error reasons and the corresponding diagnostic strings - returned by <c>format_error/1</c> are either the same as those defined - in the <c>inet(3)</c> reference manual, or as follows: - </p> - <taglist> - <tag><c>closed</c></tag> - <item> - <p>Connection closed for the operation in question. - </p> - </item> - <tag><c>ebadsocket</c></tag> - <item> - <p>Connection not found (internal error). - </p> - </item> - <tag><c>ebadstate</c></tag> - <item> - <p>Connection not in connect state (internal error). - </p> - </item> - <tag><c>ebrokertype</c></tag> - <item> - <p>Wrong broker type (internal error). - </p> - </item> - <tag><c>ecacertfile</c></tag> - <item> - <p>Own CA certificate file is invalid. - </p> - </item> - <tag><c>ecertfile</c></tag> - <item> - <p>Own certificate file is invalid. - </p> - </item> - <tag><c>echaintoolong</c></tag> - <item> - <p>The chain of certificates provided by peer is too long. - </p> - </item> - <tag><c>ecipher</c></tag> - <item> - <p>Own list of specified ciphers is invalid. - </p> - </item> - <tag><c>ekeyfile</c></tag> - <item> - <p>Own private key file is invalid. - </p> - </item> - <tag><c>ekeymismatch</c></tag> - <item> - <p>Own private key does not match own certificate. - </p> - </item> - <tag><c>enoissuercert</c></tag> - <item> - <p>Cannot find certificate of issuer of certificate provided - by peer. - </p> - </item> - <tag><c>enoservercert</c></tag> - <item> - <p>Attempt to do accept without having set own certificate. - </p> - </item> - <tag><c>enotlistener</c></tag> - <item> - <p>Attempt to accept on a non-listening socket. - </p> - </item> - <tag><c>enoproxysocket</c></tag> - <item> - <p>No proxy socket found (internal error). - </p> - </item> - <tag><c>enooptions</c></tag> - <item> - <p>The list of options is empty. - </p> - </item> - <tag><c>enotstarted</c></tag> - <item> - <p>The SSL application has not been started. - </p> - </item> - <tag><c>eoptions</c></tag> - <item> - <p>Invalid list of options. - </p> - </item> - <tag><c>epeercert</c></tag> - <item> - <p>Certificate provided by peer is in error. - </p> - </item> - <tag><c>epeercertexpired</c></tag> - <item> - <p>Certificate provided by peer has expired. - </p> - </item> - <tag><c>epeercertinvalid</c></tag> - <item> - <p>Certificate provided by peer is invalid. - </p> - </item> - <tag><c>eselfsignedcert</c></tag> - <item> - <p>Certificate provided by peer is self signed. - </p> - </item> - <tag><c>esslaccept</c></tag> - <item> - <p>Server SSL handshake procedure between client and server failed. - </p> - </item> - <tag><c>esslconnect</c></tag> - <item> - <p>Client SSL handshake procedure between client and server failed. - </p> - </item> - <tag><c>esslerrssl</c></tag> - <item> - <p>SSL protocol failure. Typically because of a fatal alert - from peer. - </p> - </item> - <tag><c>ewantconnect</c></tag> - <item> - <p>Protocol wants to connect, which is not supported in - this version of the SSL application. - </p> - </item> - <tag><c>ex509lookup</c></tag> - <item> - <p>Protocol wants X.509 lookup, which is not supported in - this version of the SSL application. - </p> - </item> - <tag><c>{badcall, Call}</c></tag> - <item> - <p>Call not recognized for current mode (active or passive) and - state of socket. - </p> - </item> - <tag><c>{badcast, Cast}</c></tag> - <item> - <p>Call not recognized for current mode (active or passive) and - state of socket. - </p> - </item> - <tag><c>{badinfo, Info}</c></tag> - <item> - <p>Call not recognized for current mode (active or passive) and - state of socket. - </p> - </item> - </taglist> - </section> - + </funcs> + <section> <title>SEE ALSO</title> - <p>gen_tcp(3), inet(3) public_key(3) </p> + <p><seealso marker="kernel:inet">inet(3) </seealso> and + <seealso marker="kernel:gen_tcp">gen_tcp(3) </seealso> + </p> </section> - -</erlref> +</erlref> diff --git a/lib/ssl/doc/src/ssl_app.xml b/lib/ssl/doc/src/ssl_app.xml index ae8bd87781..2ba6f48611 100644 --- a/lib/ssl/doc/src/ssl_app.xml +++ b/lib/ssl/doc/src/ssl_app.xml @@ -4,7 +4,7 @@ <appref> <header> <copyright> - <year>1999</year><year>2009</year> + <year>1999</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -13,45 +13,20 @@ 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>ssl</title> - <prepared>Peter Högfeldt</prepared> - <responsible>Peter Högfeldt</responsible> - <docno></docno> - <approved>Peter Högfeldt</approved> - <checked>Peter Högfeldt</checked> - <date>2005-03-10</date> - <rev>E</rev> <file>ssl_app.sgml</file> </header> <app>ssl</app> - <appsummary>The SSL Application</appsummary> - <description> - <p>The Secure Socket Layer (SSL) application provides secure - socket communication over TCP/IP. - </p> - </description> - - <section> - <title>Warning</title> - <p>In previous versions of Erlang/OTP SSL it was advised, as a - work-around, to set the operating system environment variable - <c>SSL_CERT_FILE</c> to point at a file containing CA - certificates. That variable is no longer needed, and is not - recognised by Erlang/OTP SSL any more. - </p> - <p>However, the OpenSSL package does interpret that environment - variable. Hence a setting of that variable might have - unpredictable effects on the Erlang/OTP SSL application. It is - therefore adviced to not used that environment variable at all.</p> - </section> + <appsummary>The SSL application provides secure communication over + sockets.</appsummary> <section> <title>Environment</title> @@ -61,115 +36,43 @@ </p> <p>Note that the environment parameters can be set on the command line, for instance,</p> - <p><c>erl ... -ssl protocol_version '[sslv2,sslv3]' ...</c>. + <p><c>erl ... -ssl protocol_version '[sslv3, tlsv1]' ...</c>. </p> <taglist> - <tag><c><![CDATA[ephemeral_rsa = true | false <optional>]]></c></tag> - <item> - <p>Enables all SSL servers (those that listen and accept) - to use ephemeral RSA key generation when a clients connect with - weak handshake cipher specifications, that need equally weak - ciphers from the server (i.e. obsolete restrictions on export - ciphers). Default is <c>false</c>. - </p> - </item> - <tag><c><![CDATA[debug = true | false <optional>]]></c></tag> - <item> - <p>Causes debug information to be written to standard - output. Default is <c>false</c>. - </p> - </item> - <tag><c><![CDATA[debugdir = path() | false <optional>]]></c></tag> - <item> - <p>Causes debug information output controlled by <c>debug</c> - and <c>msgdebug</c> to be printed to a file named - <c><![CDATA[ssl_esock.<pid>.log]]></c> in the directory specified by - <c>debugdir</c>, where <c><![CDATA[<pid>]]></c> is the operating system - specific textual representation of the process identifier - of the external port program of the SSL application. Default - is <c>false</c>, i.e. no log file is produced. - </p> - </item> - <tag><c><![CDATA[msgdebug = true | false <optional>]]></c></tag> + <tag><c><![CDATA[protocol_version = [sslv3|tlsv1] <optional>]]></c>.</tag> <item> - <p>Sets <c>debug = true</c> and causes also the contents - of low level messages to be printed to standard output. - Default is <c>false</c>. - </p> + <p>Protocol that will be supported by started clients and + servers. If this option is not set it will default to all + protocols currently supported by the erlang ssl application. + Note that this option may be overridden by the version option + to ssl:connect/[2,3] and ssl:listen/2. + </p> </item> - <tag><c><![CDATA[port_program = string() | false <optional>]]></c></tag> - <item> - <p>Name of port program. The default is <c>ssl_esock</c>. - </p> - </item> - <tag><c><![CDATA[protocol_version = [sslv2|sslv3|tlsv1] <optional>]]></c>.</tag> + + <tag><c><![CDATA[session_lifetime = integer() <optional>]]></c></tag> <item> - <p>Name of protocols to use. If this option is not set, - all protocols are assumed, i.e. the default value is - <c>[sslv2, sslv3, tlsv1]</c>. - </p> + <p>The lifetime of session data in seconds. + </p> </item> - <tag><c><![CDATA[proxylsport = integer() | false <optional>]]></c></tag> + + <tag><c><![CDATA[session_cb = atom() <optional>]]></c></tag> <item> - <p>Define the port number of the listen port of the - SSL port program. Almost never is this option needed. + <p> + Name of session cache callback module that implements + the ssl_session_cache_api behavior, defaults to + ssl_session_cache.erl. </p> </item> - <tag><c><![CDATA[proxylsbacklog = integer() | false <optional>]]></c></tag> + + <tag><c><![CDATA[session_cb_init_args = list() <optional>]]></c></tag> <item> - <p>Set the listen queue size of the listen port of the - SSL port program. The default is 128. - </p> + <p> + List of arguments to the init function in session cache + callback module, defaults to []. + </p> </item> - </taglist> - </section> - <section> - <title>OpenSSL libraries</title> - <p>The current implementation of the Erlang SSL application is - based on the <em>OpenSSL</em> package version 0.9.7 or higher. - There are source and binary releases on the web. - </p> - <p>Source releases of OpenSSL can be downloaded from the <url href="http://www.openssl.org">OpenSSL</url> project home page, - or mirror sites listed there. - </p> - <p>The same URL also contains links to some compiled binaries and - libraries of OpenSSL (see the <c>Related/Binaries</c> menu) of - which the <url href="http://www.shininglightpro.com/search.php?searchname=Win32+OpenSSL">Shining Light Productions Win32 and OpenSSL</url> pages are of - interest for the Win32 user. - </p> - <p>For some Unix flavours there are binary packages available - on the net. - </p> - <p>If you cannot find a suitable binary OpenSSL package, you - have to fetch an OpenSSL source release and compile it. - </p> - <p>You then have to compile and install the libraries - <c>libcrypto.so</c> and <c>libssl.so</c> (Unix), or the - libraries <c>libeay32.dll</c> and <c>ssleay32.dll</c> (Win32). - </p> - <p>For Unix The <c>ssl_esock</c> port program is delivered linked - to OpenSSL libraries in <c>/usr/local/lib</c>, but the default - dynamic linking will also accept libraries in <c>/lib</c> and - <c>/usr/lib</c>. - </p> - <p>If that is not applicable to the particular Unix operating - system used, the example <c>Makefile</c> in the SSL - <c>priv/obj</c> directory, should be used as a guide to - relinking the final version of the port program. - </p> - <p>For <c>Win32</c> it is only required that the libraries can be - found from the <c>PATH</c> environment variable, or that they - reside in the appropriate <c>SYSTEM32</c> directory; hence no - particular relinking is need. Hence no example <c>Makefile</c> - for Win32 is provided.</p> - </section> - - <section> - <title>Restrictions</title> - <p>Users must be aware of export restrictions and patent rights - concerning cryptographic software. - </p> + </taglist> </section> <section> @@ -178,5 +81,3 @@ </section> </appref> - - diff --git a/lib/ssl/doc/src/ssl_distribution.xml b/lib/ssl/doc/src/ssl_distribution.xml index c743cd67a3..7bcc12eb5f 100644 --- a/lib/ssl/doc/src/ssl_distribution.xml +++ b/lib/ssl/doc/src/ssl_distribution.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE chapter SYSTEM "chapter.dtd"> <chapter> <header> <copyright> - <year>2000</year><year>2009</year> + <year>2000</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -32,7 +32,13 @@ <file>ssl_distribution.xml</file> </header> <p>This chapter describes how the Erlang distribution can use - SSL to get additional verification and security.</p> + SSL to get additional verification and security. + + <note><p>Note this + documentation is written for the old ssl implementation and + will be updated for the new one once this functionality is + supported by the new implementation.</p></note> + </p> <section> <title>Introduction</title> @@ -49,7 +55,7 @@ all participating Erlang nodes in a distributed system must use this distribution module.</p> <p>The security depends on how the connections are set up, one can - use key files or certificates to just get a crypted + use key files or certificates to just get a encrypted connection. One can also make the SSL package verify the certificates of other nodes to get additional security. Cookies are however always used as they can be used to @@ -173,7 +179,7 @@ Eshell V5.0 (abort with ^G) <c>certfile</c> can (and usually needs to) be specified as <c>client_certfile</c> and <c>server_certfile</c>. The <c>client_certfile</c> is used when the distribution initiates a - connection to another node and the <c>server_cerfile</c> is used + connection to another node and the <c>server_certfile</c> is used when accepting a connection from a remote node. </p> <p>The command line argument for specifying the SSL options is named <c>-ssl_dist_opt</c> and should be followed by an even number of diff --git a/lib/ssl/doc/src/ssl_protocol.xml b/lib/ssl/doc/src/ssl_protocol.xml index 3dc2332795..6936408881 100644 --- a/lib/ssl/doc/src/ssl_protocol.xml +++ b/lib/ssl/doc/src/ssl_protocol.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE chapter SYSTEM "chapter.dtd"> <chapter> <header> <copyright> - <year>2003</year><year>2009</year> + <year>2003</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -13,337 +13,138 @@ 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>The SSL Protocol</title> - <prepared>Peter Högfeldt</prepared> - <docno></docno> - <date>2003-04-28</date> - <rev>PA2</rev> + <title>Transport Layer Security (TLS) and its predecessor, Secure Socket Layer (SSL)</title> <file>ssl_protocol.xml</file> </header> - <p>Here we provide a short introduction to the SSL protocol. We only - consider those part of the protocol that are important from a - programming point of view. - </p> - <p>For a very good general introduction to SSL and TLS see the book - <cite id="rescorla"></cite>. - </p> - <p><em>Outline:</em></p> - <list type="bulleted"> - <item>Two types of connections - connection: handshake, data transfer, and - shutdown - - SSL/TLS protocol - server must have certificate - what the the - server sends to the client - client may verify the server - - server may ask client for certificate - what the client sends to - the server - server may then verify the client - verification - - certificate chains - root certificates - public keys - key - agreement - purpose of certificate - references</item> - </list> + + <p>The erlang ssl application currently supports SSL 3.0 and TLS 1.0 + RFC 2246, and will in the future also support later versions of TLS. + SSL 2.0 is not supported. + </p> - <section> - <title>SSL Connections</title> - <p>The SSL protocol is implemented on top of the TCP/IP protocol. - From an endpoint view it also has the same type of connections - as that protocol, almost always created by calls to socket - interface functions <em>listen</em>, <em>accept</em> and - <em>connect</em>. The endpoints are <em>servers</em> and - <em>clients</em>. - </p> - <p>A <em>server</em><em>listen</em>s for connections on a - specific address and port. This is done once. The server then - <em>accept</em>s each connections on that same address and - port. This is typically done indefinitely many times. - </p> - <p>A <em>client</em> connects to a server on a specific address - and port. For each purpose this is done once. - </p> - <p>For a plain TCP/IP connection the establishment of a connection - (through an accept or a connect) is followed by data transfer between - the client and server, finally ended by a connection close. - </p> - <p>An SSL connection also consists of data transfer and connection - close, However, the data transfer contains encrypted data, and - in order to establish the encryption parameters, the data - transfer is preceded by an SSL <em>handshake</em>. In this - handshake the server plays a dominant role, and the main - instrument used in achieving a valid SSL connection is the - server's <em>certificate</em>. We consider certificates in the - next section, and the SSL handshake in a subsequent section.</p> - </section> + <p>By default erlang ssl is run over the TCP/IP protocol even + though you could plug in an other reliable transport protocol + with the same API as gen_tcp.</p> + + <p>If a client and server wants to use an upgrade mechanism, such as + defined by RFC2817, to upgrade a regular TCP/IP connection to a ssl + connection the erlang ssl API supports this. This can be useful for + things such as supporting HTTP and HTTPS on the same port and + implementing virtual hosting. + </p> <section> - <title>Certificates</title> - <p>A certificate is similar to a driver's license, or a - passport. The holder of the certificate is called the - <em>subject</em>. First of all the certificate identifies the - subject in terms of the name of the subject, its postal address, - country name, company name (if applicable), etc. - </p> - <p>Although a driver's license is always issued by a well-known and - distinct authority, a certificate may have an <em>issuer</em> - that is not so well-known. Therefore a certificate also always - contains information on the issuer of the certificate. That - information is of the same type as the information on the - subject. The issuer of a certificate also signs the certificate - with a <em>digital signature</em> (the signature is an inherent - part of the certificate), which allow others to verify that the - issuer really is the issuer of the certificate. - </p> - <p>Now that a certificate can be checked by verifying the - signature of the issuer, the question is how to trust the - issuer. The answer to this question is to require that there is - a certificate for the issuer as well. That issuer has in turn an - issuer, which must also have a certificate, and so on. This - <em>certificate chain</em> has to have en end, which then must - be a certificate that is trusted by other means. We shall cover - this problem of <em>authentication</em> in a subsequent - section. - </p> + <title>Security overview</title> + + <p>To achieve authentication and privacy the client and server will + perform a TLS Handshake procedure before transmitting or receiving + any data. During the handshake they agree on a protocol version and + cryptographic algorithms, they generate shared secrets using public + key cryptographics and optionally authenticate each other with + digital certificates.</p> </section> - + <section> - <title>Encryption Algorithms</title> - <p>An encryption algorithm is a mathematical algorithm for - encryption and decryption of messages (arrays of bytes, - say). The algorithm as such is always required to be publicly - known, otherwise its strength cannot be evaluated, and hence it - cannot be used reliably. The secrecy of an encrypted message is - not achieved by the secrecy of the algorithm used, but by the - secrecy of the <em>keys</em> used as input to the encryption and - decryption algorithms. For an account of cryptography in general - see <cite id="schneier"></cite>. - </p> - <p>There are two classes of encryption algorithms: <em>symmetric key</em> algorithms and <em>public key</em> algorithms. Both - types of algorithms are used in the SSL protocol. - </p> - <p>In the sequel we assume holders of keys keep them secret (except - public keys) and that they in that sense are trusted. How a - holder of a secret key is proved to be the one it claims to be - is a question of <em>authentication</em>, which, in the context - of the SSL protocol, is described in a section further below. - </p> - - <section> - <title>Symmetric Key Algorithms</title> - <p>A <em>symmetric key</em> algorithm has one key only. The key - is used for both encryption and decryption. Obviously the key - of a symmetric key algorithm must always be kept secret by the - users of the key. DES is an example of a symmetric key - algorithm. - </p> - <p>Symmetric key algorithms are fast compared to public key - algorithms. They are therefore typically used for encrypting - bulk data. - </p> - </section> - - <section> - <title>Public Key Algorithms</title> - <p>A <em>public key</em> algorithm has two keys. Any of the two - keys can be used for encryption. A message encrypted with one - of the keys, can only be decrypted with the other key. One of - the keys is public (known to the world), while the other key - is private (i.e. kept secret) by the owner of the two keys. - </p> - <p>RSA is an example of a public key algorithm. - </p> - <p>Public key algorithms are slow compared to symmetric key - algorithms, and they are therefore seldom used for bulk data - encryption. They are therefore only used in cases where the - fact that one key is public and the other is private, provides - features that cannot be provided by symmetric algorithms. - </p> - </section> - - <section> - <title>Digital Signature Algorithms</title> - <p>An interesting feature of a public key algorithm is that its - public and private keys can both be used for encryption. - Anyone can use the public key to encrypt a message, and send - that message to the owner of the private key, and be sure of - that only the holder of the private key can decrypt the - message. - </p> - <p>On the other hand, the owner of the private key can encrypt a - message with the private key, thus obtaining an encrypted - message that can decrypted by anyone having the public key. - </p> - <p>The last approach can be used as a digital signature - algorithm. The holder of the private key signs an array of - bytes by performing a specified well-known <em>message digest algorithm</em> to compute a hash of the array, encrypts the - hash value with its private key, an then presents the original - array, the name of the digest algorithm, and the encryption of - the hash value as a <em>signed array of bytes</em>. - </p> - <p>Now anyone having the public key, can decrypt the encrypted - hash value with that key, compute the hash with the specified - digest algorithm, and check that the hash values compare equal - in order to verify that the original array was indeed signed - by the holder of the private key. - </p> - <p>What we have accounted for so far is by no means all that can - be said about digital signatures (see <cite id="schneier"></cite>for - further details). - </p> - </section> - - <section> - <title>Message Digests Algorithms</title> - <p>A message digest algorithm is a hash function that accepts - an array bytes of arbitrary but finite length of input, and - outputs an array of bytes of fixed length. Such an algorithm - is also required to be very hard to invert. - </p> - <p>MD5 (16 bytes output) and SHA1 (20 bytes output) are examples - of message digest algorithms. - </p> - </section> + <title>Data Privacy and Integrity</title> + + <p>A <em>symmetric key</em> algorithm has one key only. The key is + used for both encryption and decryption. These algorithms are fast + compared to public key algorithms (using two keys, a public and a + private one) and are therefore typically used for encrypting bulk + data. + </p> + + <p>The keys for the symmetric encryption are generated uniquely + for each connection and are based on a secret negotiated + in the TLS handshake. </p> + + <p>The TLS handshake protocol and data transfer is run on top of + the TLS Record Protocol that uses a keyed-hash MAC (Message + Authenticity Code), or HMAC, to protect the message's data + integrity. From the TLS RFC "A Message Authentication Code is a + one-way hash computed from a message and some secret data. It is + difficult to forge without knowing the secret data. Its purpose is + to detect if the message has been altered." + </p> + </section> - <section> - <title>SSL Handshake</title> - <p>The main purpose of the handshake performed before an an SSL - connection is established is to negotiate the encryption - algorithm and key to be used for the bulk data transfer between - the client and the server. We are writing <em>the</em> key, - since the algorithm to choose for bulk encryption one of the - symmetric algorithms. - </p> - <p>There is thus only one key to agree upon, and obviously that - key has to be kept secret between the client and the server. To - obtain that the handshake has to be encrypted as well. - </p> - <p>The SSL protocol requires that the server always sends its - certificate to the client in the beginning of the handshake. The - client then retrieves the server's public key from the - certificate, which means that the client can use the server's - public key to encrypt messages to the server, and the server can - decrypt those messages with its private key. Similarly, the - server can encrypt messages to the client with its private key, - and the client can decrypt messages with the server's public - key. It is thus is with the server's public and private keys - that messages in the handshake are encrypted and decrypted, and - hence the key agreed upon for symmetric encryption of bulk data - can be kept secret (there are more things to consider to really - keep it secret, see <cite id="rescorla"></cite>). - </p> - <p>The above indicates that the server does not care who is - connecting, and that only the client has the possibility to - properly identify the server based on the server's certificate. - That is indeed true in the minimal use of the protocol, but it - is possible to instruct the server to request the certificate of - the client, in order to have a means to identify the client, but - it is by no means required to establish an SSL connection. - </p> - <p>If a server request the client certificate, it verifies, as a - part of the protocol, that the client really holds the private - key of the certificate by sending the client a string of bytes - to encrypt with its private key, which the server then decrypts - with the client's public key, the result of which is compared - with the original string of bytes (a similar procedure is always - performed by the client when it has received the server's - certificate). - </p> - <p>The way clients and servers <em>authenticate</em> each other, - i.e. proves that their respective peers are what they claim to - be, is the topic of the next section. - </p> - </section> + <section> + <title>Digital Certificates</title> + <p>A certificate is similar to a driver's license, or a + passport. The holder of the certificate is called the + <em>subject</em>. The certificate is signed + with the private key of the issuer of the certificate. A chain + of trust is build by having the issuer in its turn being + certified by an other certificate and so on until you reach the + so called root certificate that is self signed i.e. issued + by itself.</p> + + <p>Certificates are issued by <em>certification + authorities</em> (<em>CA</em>s) only. There are a handful of + top CAs in the world that issue root certificates. You can + examine the certificates of several of them by clicking + through the menus of your web browser. + </p> + </section> + + <section> + <title>Authentication of Sender</title> + + <p>Authentication of the sender is done by public key path + validation as defined in RFC 3280. Simplified that means that + each certificate in the certificate chain is issued by the one + before, the certificates attributes are valid ones, and the + root cert is a trusted cert that is present in the trusted + certs database kept by the peer.</p> + + <p>The server will always send a certificate chain as part of + the TLS handshake, but the client will only send one if + the server requests it. If the client does not have + an appropriate certificate it may send an "empty" certificate + to the server.</p> + + <p>The client may choose to accept some path evaluation errors + for instance a web browser may ask the user if they want to + accept an unknown CA root certificate. The server, if it request + a certificate, will on the other hand not accept any path validation + errors. It is configurable if the server should accept + or reject an "empty" certificate as response to + a certificate request.</p> + </section> + + <section> + <title>TLS Sessions</title> + + <p>From the TLS RFC "A TLS session is an association between a + client and a server. Sessions are created by the handshake + protocol. Sessions define a set of cryptographic security + parameters, which can be shared among multiple + connections. Sessions are used to avoid the expensive negotiation + of new security parameters for each connection."</p> - <section> - <title>Authentication</title> - <p>As we have already seen the reception of a certificate from a - peer is not enough to prove that the peer is authentic. More - certificates are needed, and we have to consider how certificates - are issued and on what grounds. - </p> - <p>Certificates are issued by <em>certification authorities</em> - (<em>CA</em>s) only. They issue certificates both for other CAs - and ordinary users (which are not CAs). - </p> - <p>Certain CAs are <em>top CAs</em>, i.e. they do not have a - certificate issued by another CA. Instead they issue their own - certificate, where the subject and issuer part of the - certificate are identical (such a certificate is called a - self-signed certificate). A top CA has to be well-known, and has - to have a publicly available policy telling on what grounds it - issues certificates. - </p> - <p>There are a handful of top CAs in the world. You can examine the - certificates of several of them by clicking through the menus of - your web browser. - </p> - <p>A top CA typically issues certificates for other CAs, called - <em>intermediate CAs</em>, but possibly also to ordinary users. Thus - the certificates derivable from a top CA constitute a tree, where - the leaves of the tree are ordinary user certificates. - </p> - <p>A <em>certificate chain</em> is an ordered sequence of - certificates, <c>C1, C2, ..., Cn</c>, say, where <c>C1</c> is a - top CA certificate, and where <c>Cn</c> is an ordinary user - certificate, and where the holder of <c>C1</c> is the issuer of - <c>C2</c>, the holder of <c>C2</c> is the issuer of <c>C3</c>, - ..., and the holder of <c>Cn-1</c> is the issuer of <c>Cn</c>, - the ordinary user certificate. The holders of <c>C2, C3, ..., Cn-1</c> are then intermediate CAs. - </p> - <p>Now to verify that a certificate chain is unbroken we have to - take the public key from each certificate <c>Ck</c>, and apply - that key to decrypt the signature of certificate <c>Ck-1</c>, - thus obtaining the message digest computed by the holder of the - <c>Ck</c> certificate, compute the real message digest of the - <c>Ck-1</c> certificate and compare the results. If they compare - equal the link of the chain between <c>Ck</c> and <c>Ck-1</c> is - considered to unbroken. This is done for each link k = 1, 2, - ..., n-1. If all links are found to be unbroken, the user - certificate <c>Cn</c> is considered authenticated. - </p> + <p>Session data is by default kept by the ssl application in a + memory storage hence session data will be lost at application + restart or takeover. Users may define their own callback module + to handle session data storage if persistent data storage is + required. Session data will also be invalidated after 24 hours + from it was saved, for security reasons. It is of course + possible to configure the amount of time the session data should be + saved.</p> - <section> - <title>Trusted Certificates</title> - <p>Now that there is a way to authenticate a certificate by - checking that all links of a certificate chain are unbroken, - the question is how you can be sure to trust the certificates - in the chain, and in particular the top CA certificate of the - chain. - </p> - <p>To provide an answer to that question consider the - perspective of a client, which have just received the - certificate of the server. In order to authenticate the server - the client has to construct a certificate chain and to prove - that the chain is unbroken. The client has to have a set of CA - certificates (top CA or intermediate CA certificates) not - obtained from the server, but obtained by other means. Those - certificates are kept <c>locally</c> by the client, and are - trusted by the client. - </p> - <p>More specifically, the client does not really have to have - top CA certificates in its local storage. In order to - authenticate a server it is sufficient for the client to - posses the trusted certificate of the issuer of the server - certificate. - </p> - <p>Now that is not the whole story. A server can send an - (incomplete) certificate chain to its client, and then the - task of the client is to construct a certificate chain that - begins with a trusted certificate and ends with the server's - certificate. (A client can also send a chain to its server, - provided the server requested the client's certificate.) - </p> - <p>All this means that an unbroken certificate chain begins with - a trusted certificate (top CA or not), and ends with the peer - certificate. That is the end of the chain is obtained from the - peer, but the beginning of the chain is obtained from local - storage, which is considered trusted. - </p> - </section> - </section> -</chapter> + <p>Ssl clients will by default try to reuse an available session, + ssl servers will by default agree to reuse sessions when clients + ask to do so.</p> + + </section> + </chapter> diff --git a/lib/ssl/doc/src/ssl_session_cache_api.xml b/lib/ssl/doc/src/ssl_session_cache_api.xml new file mode 100644 index 0000000000..e0b07961fb --- /dev/null +++ b/lib/ssl/doc/src/ssl_session_cache_api.xml @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="iso-8859-1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1999</year><year>2010</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + <title>ssl</title> + <file>ssl_session_cache_api.xml</file> + </header> + <module>ssl_session_cache_api</module> + <modulesummary>Defines the API for the TLS session cache so + that the data storage scheme can be replaced by + defining a new callback module implementing this API.</modulesummary> + + <section> + <title>Common Data Types</title> + + <p>The following data types are used in the functions below: + </p> + + <p><c>cache_ref() = opaque()</c></p> + + <p><c>key() = {partialkey(), session_id()}</c></p> + + <p><c>partialkey() = opaque()</c></p> + + <p><c>session_id() = binary()</c></p> + + <p><c>session() = opaque()</c></p> + + </section> + + <funcs> + + <func> + <name>delete(Cache, Key) -> _</name> + <fsummary></fsummary> + <type> + <v> Cache = cache_ref()</v> + <v> Key = key()</v> + </type> + <desc> + <p> Deletes a cache entry. Will only be called from the cache + handling process. + </p> + </desc> + </func> + + <func> + <name>foldl(Fun, Acc0, Cache) -> Acc</name> + <fsummary></fsummary> + <type> + <v></v> + </type> + <desc> + <p>Calls Fun(Elem, AccIn) on successive elements of the + cache, starting with AccIn == Acc0. Fun/2 must return a new + accumulator which is passed to the next call. The function returns + the final value of the accumulator. Acc0 is returned if the cache is + empty. + </p> + </desc> + </func> + + <func> + <name>init() -> opaque() </name> + <fsummary>Return cache reference</fsummary> + <type> + <v></v> + </type> + <desc> + <p>Performs possible initializations of the cache and returns + a reference to it that will be used as parameter to the other + api functions. Will be called by the cache handling processes + init function, hence putting the same requirements on it as + a normal process init function. + </p> + </desc> + </func> + + <func> + <name>lookup(Cache, Key) -> Entry</name> + <fsummary> Looks up a cache entry.</fsummary> + <type> + <v> Cache = cache_ref()</v> + <v> Key = key()</v> + <v> Entry = session() | undefined </v> + </type> + <desc> + <p>Looks up a cache entry. Should be callable from any + process. + </p> + </desc> + </func> + + <func> + <name>select_session(Cache, PartialKey) -> [session()]</name> + <fsummary>>Selects sessions that could be reused.</fsummary> + <type> + <v> Cache = cache_ref()</v> + <v> PartialKey = partialkey()</v> + <v> Session = session()</v> + </type> + <desc> + <p>Selects sessions that could be reused. Should be callable + from any process. + </p> + </desc> + </func> + + <func> + <name>terminate(Cache) -> _</name> + <fsummary>Called by the process that handles the cache when it + is about to terminate.</fsummary> + <type> + <v>Cache = term() - as returned by init/0</v> + </type> + <desc> + <p>Takes care of possible cleanup that is needed when the + cache handling process terminates. + </p> + </desc> + </func> + + <func> + <name>update(Cache, Key, Session) -> _</name> + <fsummary> Caches a new session or updates a already cached one.</fsummary> + <type> + <v> Cache = cache_ref()</v> + <v> Key = key()</v> + <v> Session = session()</v> + </type> + <desc> + <p> Caches a new session or updates a already cached one. Will + only be called from the cache handling process. + </p> + </desc> + </func> + + </funcs> + +</erlref> diff --git a/lib/ssl/doc/src/usersguide.xml b/lib/ssl/doc/src/usersguide.xml index 98071f5742..6528c00a0b 100644 --- a/lib/ssl/doc/src/usersguide.xml +++ b/lib/ssl/doc/src/usersguide.xml @@ -4,7 +4,7 @@ <part xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>2000</year><year>2009</year> + <year>2000</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -13,43 +13,27 @@ 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>SSL User's Guide</title> <prepared>OTP Team</prepared> - <docno></docno> <date>2003-05-26</date> - <rev>B</rev> <file>usersguide.sgml</file> </header> <description> <p>The <em>SSL</em> application provides secure communication over sockets. </p> - <p>This product includes software developed by the OpenSSL Project for - use in the OpenSSL Toolkit (http://www.openssl.org/). - </p> - <p>This product includes cryptographic software written by Eric Young - ([email protected]). - </p> - <p>This product includes software written by Tim Hudson - ([email protected]). - </p> - <p>For full OpenSSL and SSLeay license texts, see <seealso marker="licenses#licenses">Licenses</seealso>. - </p> </description> <xi:include href="ssl_protocol.xml"/> <xi:include href="using_ssl.xml"/> - <xi:include href="pkix_certs.xml"/> - <xi:include href="create_certs.xml"/> <xi:include href="ssl_distribution.xml"/> - <xi:include href="licenses.xml"/> </part> diff --git a/lib/ssl/doc/src/using_ssl.xml b/lib/ssl/doc/src/using_ssl.xml index ba74dcfef4..4bdd8f97b4 100644 --- a/lib/ssl/doc/src/using_ssl.xml +++ b/lib/ssl/doc/src/using_ssl.xml @@ -21,93 +21,129 @@ </legalnotice> - <title>Using the SSL application</title> - <prepared>Peter Högfeldt</prepared> - <docno></docno> - <date>2003-04-23</date> - <rev>PA2</rev> + <title>Using the SSL API</title> <file>using_ssl.xml</file> </header> - <p>Here we provide an introduction to using the Erlang/OTP SSL - application, which is accessed through the <c>ssl</c> interface - module. - </p> - <p>We also present example code in the Erlang module - <c>client_server</c>, also provided in the directory - <c>ssl-X.Y.Z/examples</c>, with source code in <c>src</c> and the - compiled module in <c>ebin</c> of that directory. - </p> <section> - <title>The ssl Module</title> - <p>The <c>ssl</c> module provides the user interface to the Erlang/OTP - SSL application. The interface functions provided are very similar - to those provided by the <c>gen_tcp</c> and <c>inet</c> modules. - </p> - <p>Servers use the interface functions <c>listen</c> and - <c>accept</c>. The <c>listen</c> function specifies a TCP port - to to listen to, and each call to the <c>accept</c> function - establishes an incoming connection. - </p> - <p>Clients use the <c>connect</c> function which specifies the address - and port of a server to connect to, and a successful call establishes - such a connection. - </p> - <p>The <c>listen</c> and <c>connect</c> functions have almost all - the options that the corresponding functions in <c>gen_tcp/</c> have, - but there are also additional options specific to the SSL protocol. - </p> - <p>The most important SSL specific option is the <c>cacertfile</c> - option which specifies a local file containing trusted CA - certificates which are and used for peer authentication. This - option is used by clients and servers in case they want to - authenticate their peers. - </p> - <p>The <c>certfile</c> option specifies a local path to a file - containing the certificate of the holder of the connection - endpoint. In case of a server endpoint this option is mandatory - since the contents of the sever certificate is needed in the - the handshake preceding the establishment of a connection. - </p> - <p>Similarly, the <c>keyfile</c> option points to a local file - containing the private key of the holder of the endpoint. If the - <c>certfile</c> option is present, this option has to be - specified as well, unless the private key is provided in the - same file as specified by the <c>certfile</c> option (a - certificate and a private key can thus coexist in the same file). - </p> - <p>The <c>verify</c> option specifies how the peer should be verified: - </p> - <taglist> - <tag>0</tag> - <item>Do not verify the peer,</item> - <tag>1</tag> - <item>Verify peer,</item> - <tag>2</tag> - <item>Verify peer, fail the verification if the peer has no - certificate. </item> - </taglist> - <p>The <c>depth</c> option specifies the maximum length of the - verification certificate chain. Depth = 0 means the peer - certificate, depth = 1 the CA certificate, depth = 2 the next CA - certificate etc. If the verification process does not find a - trusted CA certificate within the maximum length, the verification - fails. - </p> - <p>The <c>ciphers</c> option specifies which ciphers to use (a - string of colon separated cipher names). To obtain a list of - available ciphers, evaluate the <c>ssl:ciphers/0</c> function - (the SSL application has to be running). - </p> - </section> + <title>General information</title> + <p>To see relevant version information for ssl you can + call ssl:versions/0</p> + + <p>To see all supported cipher suites + call ssl:cipher_suites/0. Note that available cipher suites + for a connection will depend on your certificate. It is also + possible to specify a specific cipher suite(s) that you + want your connection to use. Default is to use the strongest + available.</p> - <section> - <title>A Client-Server Example</title> - <p>Here is a simple client server example. - </p> - <codeinclude file="../../examples/src/client_server.erl" tag="" type="erl"></codeinclude> </section> -</chapter> - - + + <section> + <title>Setting up connections</title> + + <p>Here follows some small example of how to set up client/server connections + using the erlang shell. The returned value of the sslsocket has been abbreviated with + <c>[...]</c> as it can be fairly large and is opaque.</p> + + <section> + <title>Minmal example</title> + + <note><p> The minimal setup is not the most secure setup of ssl.</p> + </note> + + <p> Start server side</p> + <code type="erl">1 server> ssl:start(). +ok</code> + + <p>Create a ssl listen socket</p> + <code type="erl">2 server> {ok, ListenSocket} = +ssl:listen(9999, [{certfile, "cert.pem"}, {keyfile, "key.pem"},{reuseaddr, true}]). +{ok,{sslsocket, [...]}}</code> + + <p>Do a transport accept on the ssl listen socket</p> + <code type="erl">3 server> {ok, Socket} = ssl:transport_accept(ListenSocket). +{ok,{sslsocket, [...]}}</code> + <p>Start client side</p> + <code type="erl">1 client> ssl:start(). +ok</code> + + <code type="erl">2 client> {ok, Socket} = ssl:connect("localhost", 9999, [], infinity). +{ok,{sslsocket, [...]}}</code> + + <p>Do the ssl handshake</p> + <code type="erl">4 server> ok = ssl:ssl_accept(Socket). +ok</code> + + <p>Send a messag over ssl</p> + <code type="erl">5 server> ssl:send(Socket, "foo"). +ok</code> + + <p>Flush the shell message queue to see that we got the message + sent on the server side</p> + <code type="erl">3 client> flush(). +Shell got {ssl,{sslsocket,[...]},"foo"} +ok</code> + </section> + + <section> + <title>Upgrade example</title> + + <note><p> To upgrade a TCP/IP connection to a ssl connection the + client and server have to aggre to do so. Agreement + may be accompliced by using a protocol such the one used by HTTP + specified in RFC 2817.</p> </note> + + <p>Start server side</p> + <code type="erl">1 server> ssl:start(). +ok</code> + + <p>Create a normal tcp listen socket</p> + <code type="erl">2 server> {ok, ListenSocket} = gen_tcp:listen(9999, [{reuseaddr, true}]). +{ok, #Port<0.475>}</code> + + <p>Accept client connection</p> + <code type="erl">3 server> {ok, Socket} = gen_tcp:accept(ListenSocket). +{ok, #Port<0.476>}</code> + + <p>Start client side</p> + <code type="erl">1 client> ssl:start(). +ok</code> + + <code type="erl">2 client> {ok, Socket} = gen_tcp:connect("localhost", 9999, [], infinity).</code> + + <p>Make sure active is set to false before trying + to upgrade a connection to a ssl connection, otherwhise + ssl handshake messages may be deliverd to the wrong process.</p> + <code type="erl">4 server> inet:setopts(Socket, [{active, false}]). +ok</code> + + <p>Do the ssl handshake.</p> + <code type="erl">5 server> {ok, SSLSocket} = ssl:ssl_accept(Socket, [{cacertfile, "cacerts.pem"}, +{certfile, "cert.pem"}, {keyfile, "key.pem"}]). +{ok,{sslsocket,[...]}}</code> + + <p> Upgrade to a ssl connection. Note that the client and server + must agree upon the upgrade and the server must call + ssl:accept/2 before the client calls ssl:connect/3.</p> + <code type="erl">3 client>{ok, SSLSocket} = ssl:connect(Socket, [{cacertfile, "cacerts.pem"}, +{certfile, "cert.pem"}, {keyfile, "key.pem"}], infinity). +{ok,{sslsocket,[...]}}</code> + + <p>Send a messag over ssl</p> + <code type="erl">4 client> ssl:send(SSLSocket, "foo"). +ok</code> + + <p>Set active true on the ssl socket</p> + <code type="erl">4 server> ssl:setopts(SSLSocket, [{active, true}]). +ok</code> + + <p>Flush the shell message queue to see that we got the message + sent on the client side</p> + <code type="erl">5 server> flush(). +Shell got {ssl,{sslsocket,[...]},"foo"} +ok</code> + </section> + </section> + </chapter> 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/pkix/Makefile b/lib/ssl/pkix/Makefile deleted file mode 100644 index 260361c025..0000000000 --- a/lib/ssl/pkix/Makefile +++ /dev/null @@ -1,121 +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 - -# ---------------------------------------------------- -# Application version -# ---------------------------------------------------- -include ../vsn.mk -VSN=$(SSL_VSN) - -# ---------------------------------------------------- -# Release directory specification -# ---------------------------------------------------- -RELSYSDIR = $(RELEASE_PATH)/lib/ssl-$(VSN) - -# ---------------------------------------------------- -# Common Macros -# ---------------------------------------------------- - -.SUFFIXES: .asn1 -.PRECIOUS: %.erl - -ASN_TOP = OTP-PKIX -ASN_MODULES = PKIX1Explicit88 PKIX1Implicit88 PKIX1Algorithms88 \ - PKIXAttributeCertificate SSL-PKIX -ASN_ASNS = $(ASN_MODULES:%=%.asn1) -ASN_ERLS = $(ASN_TOP).erl -ASN_HRLS = $(ASN_TOP).hrl -ASN_CONFIGS = OTP-PKIX.asn1config -ASN_DBS = $(ASN_MODULES:%=%.asn1db) -ASN_TABLES = $(ASN_MODULES:%=%.table) - -GEN_MODULES = ssl_pkix_oid $(ORBER_TMP_FIX_ERL) -GEN_ERLS = $(GEN_MODULES:%=%.erl) -ERL_MODULES = $(ASN_TOP) $(GEN_MODULES) - -TARGET_FILES= $(ERL_MODULES:%=$(EBIN)/%.$(EMULATOR)) - -HRL_FILES = $(ASN_HRLS:%=$(INCLUDE)/%) - -ORBER_TMP_FIX_HRL = PKIX1Algorithms88.hrl PKIX1Explicit88.hrl \ - PKIX1Implicit88.hrl PKIXAttributeCertificate.hrl - -INCLUDE = ../include -EBIN = ../ebin - -# ---------------------------------------------------- -# FLAGS -# ---------------------------------------------------- -EXTRA_ERLC_FLAGS = -ERL_COMPILE_FLAGS += $(EXTRA_ERLC_FLAGS) - -ASN_FLAGS = -bber_bin +der +compact_bit_string +optimize +noobj +asn1config +inline - -# ---------------------------------------------------- -# Targets -# ---------------------------------------------------- - -debug opt: $(TARGET_FILES) $(HRL_FILES) - -clean: - -rm -f $(ASN_ERLS) $(GEN_ERLS) $(ASN_HRLS) $(HRL_FILES) $(ASN_DBS) \ - $(ASN_TABLES) $(TARGET_FILES) *.beam *~ - -docs: - -%.erl: %.set.asn - erlc $(ASN_FLAGS) $< - -ssl_pkix_oid.erl: mk_ssl_pkix_oid.beam $(EBIN)/OTP-PKIX.beam - erl -pa $(EBIN) -noshell -s mk_ssl_pkix_oid make -s erlang halt - -$(HRL_FILES): $(ASN_HRLS) - cp -p $(ASN_HRLS) $(INCLUDE) - -# ---------------------------------------------------- -# Release Target -# ---------------------------------------------------- -include $(ERL_TOP)/make/otp_release_targets.mk - -release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(HRL_FILES) $(RELSYSDIR)/include - $(INSTALL_DIR) $(RELSYSDIR)/pkix - $(INSTALL_DATA) $(ASN_ASNS) $(ASN_ERLS) $(ASN_HRLS) $(ASN_CONFIGS) \ - $(ORBER_TMP_FIX_HRL) $(GEN_ERLS) mk_ssl_pkix_oid.erl $(RELSYSDIR)/pkix - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin - -release_docs_spec: - -# -# Dependencies - -$(EBIN)/OTP-PKIX.beam: OTP-PKIX.erl OTP-PKIX.hrl -OTP-PKIX.erl OTP-PKIX.hrl: OTP-PKIX.asn1db -OTP-PKIX.asn1db: PKIX1Algorithms88.asn1 \ - PKIX1Explicit88.asn1 \ - PKIX1Implicit88.asn1 \ - PKIXAttributeCertificate.asn1 \ - SSL-PKIX.asn1 diff --git a/lib/ssl/pkix/OTP-PKIX.asn1config b/lib/ssl/pkix/OTP-PKIX.asn1config deleted file mode 100644 index 0caa158f52..0000000000 --- a/lib/ssl/pkix/OTP-PKIX.asn1config +++ /dev/null @@ -1,2 +0,0 @@ -{exclusive_decode,{'OTP-PKIX', - [{decode_TBSCert_exclusive,['Certificate',[{tbsCertificate,undecoded}]]}]}}. diff --git a/lib/ssl/pkix/OTP-PKIX.set.asn b/lib/ssl/pkix/OTP-PKIX.set.asn deleted file mode 100644 index 1c3483d519..0000000000 --- a/lib/ssl/pkix/OTP-PKIX.set.asn +++ /dev/null @@ -1,6 +0,0 @@ -SSL-PKIX.asn1 -PKIX1Explicit88.asn1 -PKIX1Implicit88.asn1 -PKIXAttributeCertificate.asn1 -PKIX1Algorithms88.asn1 -PKCS-1.asn1 diff --git a/lib/ssl/pkix/PKCS-1.asn1 b/lib/ssl/pkix/PKCS-1.asn1 deleted file mode 100755 index 547cc2e072..0000000000 --- a/lib/ssl/pkix/PKCS-1.asn1 +++ /dev/null @@ -1,54 +0,0 @@ -PKCS-1 { - iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1) - modules(0) pkcs-1(1) -} - - -DEFINITIONS IMPLICIT TAGS ::= BEGIN - --- EXPORTS ALL -- - -IMPORTS - AlgorithmIdentifier - FROM PKIX1Explicit88 {iso(1) identified-organization(3) - dod(6) internet(1) security(5) mechanisms(5) - pkix(7) id-mod(0) id-pkix1-explicit-88(1)} ; - -pkcs-1 OBJECT IDENTIFIER ::= { - iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 } - -RSAPrivateKey ::= SEQUENCE { - version Version, - modulus INTEGER, -- n - publicExponent INTEGER, -- e - privateExponent INTEGER, -- d - prime1 INTEGER, -- p - prime2 INTEGER, -- q - exponent1 INTEGER, -- d mod (p-1) - exponent2 INTEGER, -- d mod (q-1) - coefficient INTEGER, -- (inverse of q) mod p - otherPrimeInfos OtherPrimeInfos OPTIONAL -} - -Version ::= INTEGER { two-prime(0), multi(1) } - (CONSTRAINED BY { - -- version must be multi if otherPrimeInfos present -- - }) - -OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo - -OtherPrimeInfo ::= SEQUENCE { - prime INTEGER, -- ri - exponent INTEGER, -- di - coefficient INTEGER -- ti -} - -DigestInfo ::= SEQUENCE { - digestAlgorithm DigestAlgorithmIdentifier, - digest OCTET STRING -} - -DigestAlgorithmIdentifier ::= AlgorithmIdentifier - -END -- PKCS1Definitions - diff --git a/lib/ssl/pkix/PKIX1Algorithms88.asn1 b/lib/ssl/pkix/PKIX1Algorithms88.asn1 deleted file mode 100644 index e78de69b0e..0000000000 --- a/lib/ssl/pkix/PKIX1Algorithms88.asn1 +++ /dev/null @@ -1,274 +0,0 @@ - PKIX1Algorithms88 { iso(1) identified-organization(3) dod(6) - internet(1) security(5) mechanisms(5) pkix(7) id-mod(0) - id-mod-pkix1-algorithms(17) } - - DEFINITIONS EXPLICIT TAGS ::= BEGIN - - -- EXPORTS All; - - -- IMPORTS NONE; - - -- - -- One-way Hash Functions - -- - - md2 OBJECT IDENTIFIER ::= { - iso(1) member-body(2) us(840) rsadsi(113549) - digestAlgorithm(2) 2 } - - md5 OBJECT IDENTIFIER ::= { - iso(1) member-body(2) us(840) rsadsi(113549) - digestAlgorithm(2) 5 } - - id-sha1 OBJECT IDENTIFIER ::= { - iso(1) identified-organization(3) oiw(14) secsig(3) - algorithms(2) 26 } - - -- - -- DSA Keys and Signatures - -- - - -- OID for DSA public key - - id-dsa OBJECT IDENTIFIER ::= { - iso(1) member-body(2) us(840) x9-57(10040) x9algorithm(4) 1 } - - -- encoding for DSA public key - - DSAPublicKey ::= INTEGER -- public key, y - - Dss-Parms ::= SEQUENCE { - p INTEGER, - q INTEGER, - g INTEGER } - - -- OID for DSA signature generated with SHA-1 hash - - id-dsa-with-sha1 OBJECT IDENTIFIER ::= { - iso(1) member-body(2) us(840) x9-57 (10040) x9algorithm(4) 3 } - - -- encoding for DSA signature generated with SHA-1 hash - - Dss-Sig-Value ::= SEQUENCE { - r INTEGER, - s INTEGER } - - -- - -- RSA Keys and Signatures - -- - - -- arc for RSA public key and RSA signature OIDs - - pkcs-1 OBJECT IDENTIFIER ::= { - iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 } - - -- OID for RSA public keys - - rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 } - - -- OID for RSA signature generated with MD2 hash - - md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 } - - -- OID for RSA signature generated with MD5 hash - - md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 } - - -- OID for RSA signature generated with SHA-1 hash - - sha1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 } - - -- encoding for RSA public key - - RSAPublicKey ::= SEQUENCE { - modulus INTEGER, -- n - publicExponent INTEGER } -- e - - -- - -- Diffie-Hellman Keys - -- - - dhpublicnumber OBJECT IDENTIFIER ::= { - iso(1) member-body(2) us(840) ansi-x942(10046) - number-type(2) 1 } - - -- encoding for DSA public key - - DHPublicKey ::= INTEGER -- public key, y = g^x mod p - - DomainParameters ::= SEQUENCE { - p INTEGER, -- odd prime, p=jq +1 - g INTEGER, -- generator, g - q INTEGER, -- factor of p-1 - j INTEGER OPTIONAL, -- subgroup factor, j>= 2 - validationParms ValidationParms OPTIONAL } - - ValidationParms ::= SEQUENCE { - seed BIT STRING, - pgenCounter INTEGER } - - -- - -- KEA Keys - -- - - id-keyExchangeAlgorithm OBJECT IDENTIFIER ::= - { 2 16 840 1 101 2 1 1 22 } - - KEA-Parms-Id ::= OCTET STRING - - -- - -- Elliptic Curve Keys, Signatures, and Curves - -- - - ansi-X9-62 OBJECT IDENTIFIER ::= { - iso(1) member-body(2) us(840) 10045 } - - FieldID ::= SEQUENCE { -- Finite field - fieldType OBJECT IDENTIFIER, - parameters ANY DEFINED BY fieldType } - - -- Arc for ECDSA signature OIDS - - id-ecSigType OBJECT IDENTIFIER ::= { ansi-X9-62 signatures(4) } - - -- OID for ECDSA signatures with SHA-1 - - ecdsa-with-SHA1 OBJECT IDENTIFIER ::= { id-ecSigType 1 } - - -- OID for an elliptic curve signature - -- format for the value of an ECDSA signature value - - ECDSA-Sig-Value ::= SEQUENCE { - r INTEGER, - s INTEGER } - - -- recognized field type OIDs are defined in the following arc - - id-fieldType OBJECT IDENTIFIER ::= { ansi-X9-62 fieldType(1) } - - -- where fieldType is prime-field, the parameters are of type Prime-p - - prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 } - - Prime-p ::= INTEGER -- Finite field F(p), where p is an odd prime - - -- where fieldType is characteristic-two-field, the parameters are - -- of type Characteristic-two - - characteristic-two-field OBJECT IDENTIFIER ::= { id-fieldType 2 } - - Characteristic-two ::= SEQUENCE { - m INTEGER, -- Field size 2^m - basis OBJECT IDENTIFIER, - parameters ANY DEFINED BY basis } - - -- recognized basis type OIDs are defined in the following arc - - id-characteristic-two-basis OBJECT IDENTIFIER ::= { - characteristic-two-field basisType(3) } - - -- gnbasis is identified by OID gnBasis and indicates - -- parameters are NULL - - gnBasis OBJECT IDENTIFIER ::= { id-characteristic-two-basis 1 } - - -- parameters for this basis are NULL - - -- trinomial basis is identified by OID tpBasis and indicates - -- parameters of type Pentanomial - - tpBasis OBJECT IDENTIFIER ::= { id-characteristic-two-basis 2 } - - -- Trinomial basis representation of F2^m - -- Integer k for reduction polynomial xm + xk + 1 - - Trinomial ::= INTEGER - - -- for pentanomial basis is identified by OID ppBasis and indicates - -- parameters of type Pentanomial - - ppBasis OBJECT IDENTIFIER ::= { id-characteristic-two-basis 3 } - - -- Pentanomial basis representation of F2^m - -- reduction polynomial integers k1, k2, k3 - -- f(x) = x**m + x**k3 + x**k2 + x**k1 + 1 - - Pentanomial ::= SEQUENCE { - k1 INTEGER, - k2 INTEGER, - k3 INTEGER } - - -- The object identifiers gnBasis, tpBasis and ppBasis name - -- three kinds of basis for characteristic-two finite fields - - FieldElement ::= OCTET STRING -- Finite field element - - ECPoint ::= OCTET STRING -- Elliptic curve point - - -- Elliptic Curve parameters may be specified explicitly, - -- specified implicitly through a "named curve", or - -- inherited from the CA - - EcpkParameters ::= CHOICE { - ecParameters ECParameters, - namedCurve OBJECT IDENTIFIER, - implicitlyCA NULL } - - ECParameters ::= SEQUENCE { -- Elliptic curve parameters - version ECPVer, - fieldID FieldID, - curve Curve, - base ECPoint, -- Base point G - order INTEGER, -- Order n of the base point - cofactor INTEGER OPTIONAL } -- The integer h = #E(Fq)/n - - ECPVer ::= INTEGER {ecpVer1(1)} - - Curve ::= SEQUENCE { - a FieldElement, -- Elliptic curve coefficient a - b FieldElement, -- Elliptic curve coefficient b - seed BIT STRING OPTIONAL } - - id-publicKeyType OBJECT IDENTIFIER ::= { ansi-X9-62 keyType(2) } - - id-ecPublicKey OBJECT IDENTIFIER ::= { id-publicKeyType 1 } - - -- Named Elliptic Curves in ANSI X9.62. - - ellipticCurve OBJECT IDENTIFIER ::= { ansi-X9-62 curves(3) } - - c-TwoCurve OBJECT IDENTIFIER ::= { - ellipticCurve characteristicTwo(0) } - - c2pnb163v1 OBJECT IDENTIFIER ::= { c-TwoCurve 1 } - c2pnb163v2 OBJECT IDENTIFIER ::= { c-TwoCurve 2 } - c2pnb163v3 OBJECT IDENTIFIER ::= { c-TwoCurve 3 } - c2pnb176w1 OBJECT IDENTIFIER ::= { c-TwoCurve 4 } - c2tnb191v1 OBJECT IDENTIFIER ::= { c-TwoCurve 5 } - c2tnb191v2 OBJECT IDENTIFIER ::= { c-TwoCurve 6 } - c2tnb191v3 OBJECT IDENTIFIER ::= { c-TwoCurve 7 } - c2onb191v4 OBJECT IDENTIFIER ::= { c-TwoCurve 8 } - c2onb191v5 OBJECT IDENTIFIER ::= { c-TwoCurve 9 } - c2pnb208w1 OBJECT IDENTIFIER ::= { c-TwoCurve 10 } - c2tnb239v1 OBJECT IDENTIFIER ::= { c-TwoCurve 11 } - c2tnb239v2 OBJECT IDENTIFIER ::= { c-TwoCurve 12 } - c2tnb239v3 OBJECT IDENTIFIER ::= { c-TwoCurve 13 } - c2onb239v4 OBJECT IDENTIFIER ::= { c-TwoCurve 14 } - c2onb239v5 OBJECT IDENTIFIER ::= { c-TwoCurve 15 } - c2pnb272w1 OBJECT IDENTIFIER ::= { c-TwoCurve 16 } - c2pnb304w1 OBJECT IDENTIFIER ::= { c-TwoCurve 17 } - c2tnb359v1 OBJECT IDENTIFIER ::= { c-TwoCurve 18 } - c2pnb368w1 OBJECT IDENTIFIER ::= { c-TwoCurve 19 } - c2tnb431r1 OBJECT IDENTIFIER ::= { c-TwoCurve 20 } - - primeCurve OBJECT IDENTIFIER ::= { ellipticCurve prime(1) } - - prime192v1 OBJECT IDENTIFIER ::= { primeCurve 1 } - prime192v2 OBJECT IDENTIFIER ::= { primeCurve 2 } - prime192v3 OBJECT IDENTIFIER ::= { primeCurve 3 } - prime239v1 OBJECT IDENTIFIER ::= { primeCurve 4 } - prime239v2 OBJECT IDENTIFIER ::= { primeCurve 5 } - prime239v3 OBJECT IDENTIFIER ::= { primeCurve 6 } - prime256v1 OBJECT IDENTIFIER ::= { primeCurve 7 } - - END diff --git a/lib/ssl/pkix/PKIX1Algorithms88.hrl b/lib/ssl/pkix/PKIX1Algorithms88.hrl deleted file mode 100644 index a11793618d..0000000000 --- a/lib/ssl/pkix/PKIX1Algorithms88.hrl +++ /dev/null @@ -1,94 +0,0 @@ -%% Generated by the Erlang ASN.1 compiler version:1.4.4.8 -%% Purpose: Erlang record definitions for each named and unnamed -%% SEQUENCE and SET, and macro definitions for each value -%% definition,in module PKIX1Algorithms88 - - - --record('Dss-Parms',{ -p, q, g}). - --record('Dss-Sig-Value',{ -r, s}). - --record('RSAPublicKey',{ -modulus, publicExponent}). - --record('DomainParameters',{ -p, g, q, j = asn1_NOVALUE, validationParms = asn1_NOVALUE}). - --record('ValidationParms',{ -seed, pgenCounter}). - --record('FieldID',{ -fieldType, parameters}). - --record('ECDSA-Sig-Value',{ -r, s}). - --record('Characteristic-two',{ -m, basis, parameters}). - --record('Pentanomial',{ -k1, k2, k3}). - --record('ECParameters',{ -version, fieldID, curve, base, order, cofactor = asn1_NOVALUE}). - --record('Curve',{ -a, b, seed = asn1_NOVALUE}). - --define('md2', {1,2,840,113549,2,2}). --define('md5', {1,2,840,113549,2,5}). --define('id-sha1', {1,3,14,3,2,26}). --define('id-dsa', {1,2,840,10040,4,1}). --define('id-dsa-with-sha1', {1,2,840,10040,4,3}). --define('pkcs-1', {1,2,840,113549,1,1}). --define('rsaEncryption', {1,2,840,113549,1,1,1}). --define('md2WithRSAEncryption', {1,2,840,113549,1,1,2}). --define('md5WithRSAEncryption', {1,2,840,113549,1,1,4}). --define('sha1WithRSAEncryption', {1,2,840,113549,1,1,5}). --define('dhpublicnumber', {1,2,840,10046,2,1}). --define('id-keyExchangeAlgorithm', {2,16,840,1,101,2,1,1,22}). --define('ansi-X9-62', {1,2,840,10045}). --define('id-ecSigType', {1,2,840,10045,4}). --define('ecdsa-with-SHA1', {1,2,840,10045,4,1}). --define('id-fieldType', {1,2,840,10045,1}). --define('prime-field', {1,2,840,10045,1,1}). --define('characteristic-two-field', {1,2,840,10045,1,2}). --define('id-characteristic-two-basis', {1,2,840,10045,1,2,3}). --define('gnBasis', {1,2,840,10045,1,2,3,1}). --define('tpBasis', {1,2,840,10045,1,2,3,2}). --define('ppBasis', {1,2,840,10045,1,2,3,3}). --define('id-publicKeyType', {1,2,840,10045,2}). --define('id-ecPublicKey', {1,2,840,10045,2,1}). --define('ellipticCurve', {1,2,840,10045,3}). --define('c-TwoCurve', {1,2,840,10045,3,0}). --define('c2pnb163v1', {1,2,840,10045,3,0,1}). --define('c2pnb163v2', {1,2,840,10045,3,0,2}). --define('c2pnb163v3', {1,2,840,10045,3,0,3}). --define('c2pnb176w1', {1,2,840,10045,3,0,4}). --define('c2tnb191v1', {1,2,840,10045,3,0,5}). --define('c2tnb191v2', {1,2,840,10045,3,0,6}). --define('c2tnb191v3', {1,2,840,10045,3,0,7}). --define('c2onb191v4', {1,2,840,10045,3,0,8}). --define('c2onb191v5', {1,2,840,10045,3,0,9}). --define('c2pnb208w1', {1,2,840,10045,3,0,10}). --define('c2tnb239v1', {1,2,840,10045,3,0,11}). --define('c2tnb239v2', {1,2,840,10045,3,0,12}). --define('c2tnb239v3', {1,2,840,10045,3,0,13}). --define('c2onb239v4', {1,2,840,10045,3,0,14}). --define('c2onb239v5', {1,2,840,10045,3,0,15}). --define('c2pnb272w1', {1,2,840,10045,3,0,16}). --define('c2pnb304w1', {1,2,840,10045,3,0,17}). --define('c2tnb359v1', {1,2,840,10045,3,0,18}). --define('c2pnb368w1', {1,2,840,10045,3,0,19}). --define('c2tnb431r1', {1,2,840,10045,3,0,20}). --define('primeCurve', {1,2,840,10045,3,1}). --define('prime192v1', {1,2,840,10045,3,1,1}). --define('prime192v2', {1,2,840,10045,3,1,2}). --define('prime192v3', {1,2,840,10045,3,1,3}). --define('prime239v1', {1,2,840,10045,3,1,4}). --define('prime239v2', {1,2,840,10045,3,1,5}). --define('prime239v3', {1,2,840,10045,3,1,6}). --define('prime256v1', {1,2,840,10045,3,1,7}). diff --git a/lib/ssl/pkix/PKIX1Explicit88.asn1 b/lib/ssl/pkix/PKIX1Explicit88.asn1 deleted file mode 100644 index 9b8068fed0..0000000000 --- a/lib/ssl/pkix/PKIX1Explicit88.asn1 +++ /dev/null @@ -1,619 +0,0 @@ -PKIX1Explicit88 { iso(1) identified-organization(3) dod(6) internet(1) - security(5) mechanisms(5) pkix(7) id-mod(0) id-pkix1-explicit(18) } - -DEFINITIONS EXPLICIT TAGS ::= - -BEGIN - --- EXPORTS ALL -- - --- IMPORTS NONE -- - --- UNIVERSAL Types defined in 1993 and 1998 ASN.1 --- and required by this specification - --- UniversalString ::= [UNIVERSAL 28] IMPLICIT OCTET STRING - -- UniversalString is defined in ASN.1:1993 - --- BMPString ::= [UNIVERSAL 30] IMPLICIT OCTET STRING - -- BMPString is the subtype of UniversalString and models - -- the Basic Multilingual Plane of ISO/IEC/ITU 10646-1 - --- UTF8String ::= [UNIVERSAL 12] IMPLICIT OCTET STRING - -- The content of this type conforms to RFC 2279. - --- PKIX specific OIDs - -id-pkix OBJECT IDENTIFIER ::= - { iso(1) identified-organization(3) dod(6) internet(1) - security(5) mechanisms(5) pkix(7) } - --- PKIX arcs - -id-pe OBJECT IDENTIFIER ::= { id-pkix 1 } - -- arc for private certificate extensions -id-qt OBJECT IDENTIFIER ::= { id-pkix 2 } - -- arc for policy qualifier types -id-kp OBJECT IDENTIFIER ::= { id-pkix 3 } - -- arc for extended key purpose OIDS -id-ad OBJECT IDENTIFIER ::= { id-pkix 48 } - -- arc for access descriptors - --- policyQualifierIds for Internet policy qualifiers - -id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 } - -- OID for CPS qualifier -id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 } - -- OID for user notice qualifier - --- access descriptor definitions - -id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 } -id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 } -id-ad-timeStamping OBJECT IDENTIFIER ::= { id-ad 3 } -id-ad-caRepository OBJECT IDENTIFIER ::= { id-ad 5 } - --- attribute data types - -Attribute ::= SEQUENCE { - type AttributeType, - values SET OF AttributeValue } - -- at least one value is required - -AttributeType ::= OBJECT IDENTIFIER - -AttributeValue ::= ANY - -AttributeTypeAndValue ::= SEQUENCE { - type AttributeType, - value AttributeValue } - --- suggested naming attributes: Definition of the following --- information object set may be augmented to meet local --- requirements. Note that deleting members of the set may --- prevent interoperability with conforming implementations. --- presented in pairs: the AttributeType followed by the --- type definition for the corresponding AttributeValue ---Arc for standard naming attributes -id-at OBJECT IDENTIFIER ::= { joint-iso-ccitt(2) ds(5) 4 } - --- Naming attributes of type X520name - -id-at-name AttributeType ::= { id-at 41 } -id-at-surname AttributeType ::= { id-at 4 } -id-at-givenName AttributeType ::= { id-at 42 } -id-at-initials AttributeType ::= { id-at 43 } -id-at-generationQualifier AttributeType ::= { id-at 44 } - -X520name ::= CHOICE { - teletexString TeletexString (SIZE (1..ub-name)), - printableString PrintableString (SIZE (1..ub-name)), - universalString UniversalString (SIZE (1..ub-name)), - utf8String UTF8String (SIZE (1..ub-name)), - bmpString BMPString (SIZE (1..ub-name)) } - --- Naming attributes of type X520CommonName - -id-at-commonName AttributeType ::= { id-at 3 } - -X520CommonName ::= CHOICE { - teletexString TeletexString (SIZE (1..ub-common-name)), - printableString PrintableString (SIZE (1..ub-common-name)), - universalString UniversalString (SIZE (1..ub-common-name)), - utf8String UTF8String (SIZE (1..ub-common-name)), - bmpString BMPString (SIZE (1..ub-common-name)) } - --- Naming attributes of type X520LocalityName - -id-at-localityName AttributeType ::= { id-at 7 } - -X520LocalityName ::= CHOICE { - teletexString TeletexString (SIZE (1..ub-locality-name)), - printableString PrintableString (SIZE (1..ub-locality-name)), - universalString UniversalString (SIZE (1..ub-locality-name)), - utf8String UTF8String (SIZE (1..ub-locality-name)), - bmpString BMPString (SIZE (1..ub-locality-name)) } - --- Naming attributes of type X520StateOrProvinceName - -id-at-stateOrProvinceName AttributeType ::= { id-at 8 } - -X520StateOrProvinceName ::= CHOICE { - teletexString TeletexString (SIZE (1..ub-state-name)), - printableString PrintableString (SIZE (1..ub-state-name)), - universalString UniversalString (SIZE (1..ub-state-name)), - utf8String UTF8String (SIZE (1..ub-state-name)), - bmpString BMPString (SIZE(1..ub-state-name)) } - --- Naming attributes of type X520OrganizationName - -id-at-organizationName AttributeType ::= { id-at 10 } - -X520OrganizationName ::= CHOICE { - teletexString TeletexString - (SIZE (1..ub-organization-name)), - printableString PrintableString - (SIZE (1..ub-organization-name)), - universalString UniversalString - (SIZE (1..ub-organization-name)), - utf8String UTF8String - (SIZE (1..ub-organization-name)), - bmpString BMPString - (SIZE (1..ub-organization-name)) } - --- Naming attributes of type X520OrganizationalUnitName - -id-at-organizationalUnitName AttributeType ::= { id-at 11 } - -X520OrganizationalUnitName ::= CHOICE { - teletexString TeletexString - (SIZE (1..ub-organizational-unit-name)), - printableString PrintableString - (SIZE (1..ub-organizational-unit-name)), - universalString UniversalString - (SIZE (1..ub-organizational-unit-name)), - utf8String UTF8String - (SIZE (1..ub-organizational-unit-name)), - bmpString BMPString - (SIZE (1..ub-organizational-unit-name)) } - --- Naming attributes of type X520Title - -id-at-title AttributeType ::= { id-at 12 } - -X520Title ::= CHOICE { - teletexString TeletexString (SIZE (1..ub-title)), - printableString PrintableString (SIZE (1..ub-title)), - universalString UniversalString (SIZE (1..ub-title)), - utf8String UTF8String (SIZE (1..ub-title)), - bmpString BMPString (SIZE (1..ub-title)) } - --- Naming attributes of type X520dnQualifier - -id-at-dnQualifier AttributeType ::= { id-at 46 } - -X520dnQualifier ::= PrintableString - --- Naming attributes of type X520countryName (digraph from IS 3166) - -id-at-countryName AttributeType ::= { id-at 6 } - -X520countryName ::= PrintableString (SIZE (2)) - --- Naming attributes of type X520SerialNumber - -id-at-serialNumber AttributeType ::= { id-at 5 } - -X520SerialNumber ::= PrintableString (SIZE (1..ub-serial-number)) - --- Naming attributes of type X520Pseudonym - -id-at-pseudonym AttributeType ::= { id-at 65 } - -X520Pseudonym ::= CHOICE { - teletexString TeletexString (SIZE (1..ub-pseudonym)), - printableString PrintableString (SIZE (1..ub-pseudonym)), - universalString UniversalString (SIZE (1..ub-pseudonym)), - utf8String UTF8String (SIZE (1..ub-pseudonym)), - bmpString BMPString (SIZE (1..ub-pseudonym)) } - --- Naming attributes of type DomainComponent (from RFC 2247) - -id-domainComponent AttributeType ::= - { 0 9 2342 19200300 100 1 25 } - -DomainComponent ::= IA5String - --- Legacy attributes - -pkcs-9 OBJECT IDENTIFIER ::= - { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 } - -id-emailAddress AttributeType ::= { pkcs-9 1 } - -EmailAddress ::= IA5String (SIZE (1..ub-emailaddress-length)) - --- naming data types -- - -Name ::= CHOICE { -- only one possibility for now -- - rdnSequence RDNSequence } - -RDNSequence ::= SEQUENCE OF RelativeDistinguishedName - -DistinguishedName ::= RDNSequence - -RelativeDistinguishedName ::= - SET SIZE (1 .. MAX) OF AttributeTypeAndValue - --- Directory string type -- - -DirectoryString ::= CHOICE { - teletexString TeletexString (SIZE (1..MAX)), - printableString PrintableString (SIZE (1..MAX)), - universalString UniversalString (SIZE (1..MAX)), - utf8String UTF8String (SIZE (1..MAX)), - bmpString BMPString (SIZE (1..MAX)) } - --- certificate and CRL specific structures begin here - -Certificate ::= SEQUENCE { - tbsCertificate TBSCertificate, - signatureAlgorithm AlgorithmIdentifier, - signature BIT STRING } - -TBSCertificate ::= SEQUENCE { - version [0] Version DEFAULT v1, - serialNumber CertificateSerialNumber, - signature AlgorithmIdentifier, - issuer Name, - validity Validity, - subject Name, - subjectPublicKeyInfo SubjectPublicKeyInfo, - issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, - -- If present, version MUST be v2 or v3 - subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, - -- If present, version MUST be v2 or v3 - extensions [3] Extensions OPTIONAL - -- If present, version MUST be v3 -- } - -Version ::= INTEGER { v1(0), v2(1), v3(2) } - -CertificateSerialNumber ::= INTEGER - -Validity ::= SEQUENCE { - notBefore Time, - notAfter Time } - -Time ::= CHOICE { - utcTime UTCTime, - generalTime GeneralizedTime } - -UniqueIdentifier ::= BIT STRING - -SubjectPublicKeyInfo ::= SEQUENCE { - algorithm AlgorithmIdentifier, - subjectPublicKey BIT STRING } - -Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension - -Extension ::= SEQUENCE { - extnID OBJECT IDENTIFIER, - critical BOOLEAN DEFAULT FALSE, - extnValue OCTET STRING } - --- CRL structures - -CertificateList ::= SEQUENCE { - tbsCertList TBSCertList, - signatureAlgorithm AlgorithmIdentifier, - signature BIT STRING } - -TBSCertList ::= SEQUENCE { - version Version OPTIONAL, - -- if present, MUST be v2 - signature AlgorithmIdentifier, - issuer Name, - thisUpdate Time, - nextUpdate Time OPTIONAL, - revokedCertificates SEQUENCE OF SEQUENCE { - userCertificate CertificateSerialNumber, - revocationDate Time, - crlEntryExtensions Extensions OPTIONAL - -- if present, MUST be v2 - } OPTIONAL, - crlExtensions [0] Extensions OPTIONAL } - -- if present, MUST be v2 - --- Version, Time, CertificateSerialNumber, and Extensions were --- defined earlier for use in the certificate structure - -AlgorithmIdentifier ::= SEQUENCE { - algorithm OBJECT IDENTIFIER, - parameters ANY DEFINED BY algorithm OPTIONAL } - -- contains a value of the type - -- registered for use with the - -- algorithm object identifier value - --- X.400 address syntax starts here - -ORAddress ::= SEQUENCE { - built-in-standard-attributes BuiltInStandardAttributes, - built-in-domain-defined-attributes - BuiltInDomainDefinedAttributes OPTIONAL, - -- see also teletex-domain-defined-attributes - extension-attributes ExtensionAttributes OPTIONAL } - --- Built-in Standard Attributes - -BuiltInStandardAttributes ::= SEQUENCE { - country-name CountryName OPTIONAL, - administration-domain-name AdministrationDomainName OPTIONAL, - network-address [0] IMPLICIT NetworkAddress OPTIONAL, - -- see also extended-network-address - terminal-identifier [1] IMPLICIT TerminalIdentifier OPTIONAL, - private-domain-name [2] PrivateDomainName OPTIONAL, - organization-name [3] IMPLICIT OrganizationName OPTIONAL, - -- see also teletex-organization-name - numeric-user-identifier [4] IMPLICIT NumericUserIdentifier - OPTIONAL, - personal-name [5] IMPLICIT PersonalName OPTIONAL, - -- see also teletex-personal-name - organizational-unit-names [6] IMPLICIT OrganizationalUnitNames - OPTIONAL } - -- see also teletex-organizational-unit-names - -CountryName ::= [APPLICATION 1] CHOICE { - x121-dcc-code NumericString - (SIZE (ub-country-name-numeric-length)), - iso-3166-alpha2-code PrintableString - (SIZE (ub-country-name-alpha-length)) } - -AdministrationDomainName ::= [APPLICATION 2] CHOICE { - numeric NumericString (SIZE (0..ub-domain-name-length)), - printable PrintableString (SIZE (0..ub-domain-name-length)) } - -NetworkAddress ::= X121Address -- see also extended-network-address - -X121Address ::= NumericString (SIZE (1..ub-x121-address-length)) - -TerminalIdentifier ::= PrintableString (SIZE -(1..ub-terminal-id-length)) - -PrivateDomainName ::= CHOICE { - numeric NumericString (SIZE (1..ub-domain-name-length)), - printable PrintableString (SIZE (1..ub-domain-name-length)) } - -OrganizationName ::= PrintableString - (SIZE (1..ub-organization-name-length)) - -- see also teletex-organization-name - -NumericUserIdentifier ::= NumericString - (SIZE (1..ub-numeric-user-id-length)) - -PersonalName ::= SET { - surname [0] IMPLICIT PrintableString - (SIZE (1..ub-surname-length)), - given-name [1] IMPLICIT PrintableString - (SIZE (1..ub-given-name-length)) OPTIONAL, - initials [2] IMPLICIT PrintableString - (SIZE (1..ub-initials-length)) OPTIONAL, - generation-qualifier [3] IMPLICIT PrintableString - (SIZE (1..ub-generation-qualifier-length)) - OPTIONAL } - -- see also teletex-personal-name - -OrganizationalUnitNames ::= SEQUENCE SIZE (1..ub-organizational-units) - OF OrganizationalUnitName - -- see also teletex-organizational-unit-names - -OrganizationalUnitName ::= PrintableString (SIZE - (1..ub-organizational-unit-name-length)) - --- Built-in Domain-defined Attributes - -BuiltInDomainDefinedAttributes ::= SEQUENCE SIZE - (1..ub-domain-defined-attributes) OF - BuiltInDomainDefinedAttribute - -BuiltInDomainDefinedAttribute ::= SEQUENCE { - type PrintableString (SIZE - (1..ub-domain-defined-attribute-type-length)), - value PrintableString (SIZE - (1..ub-domain-defined-attribute-value-length)) } - --- Extension Attributes - -ExtensionAttributes ::= SET SIZE (1..ub-extension-attributes) OF - ExtensionAttribute - -ExtensionAttribute ::= SEQUENCE { - extension-attribute-type [0] IMPLICIT INTEGER - (0..ub-extension-attributes), - extension-attribute-value [1] - ANY DEFINED BY extension-attribute-type } - --- Extension types and attribute values - -common-name INTEGER ::= 1 - -CommonName ::= PrintableString (SIZE (1..ub-common-name-length)) - -teletex-common-name INTEGER ::= 2 - -TeletexCommonName ::= TeletexString (SIZE (1..ub-common-name-length)) - -teletex-organization-name INTEGER ::= 3 - -TeletexOrganizationName ::= - TeletexString (SIZE (1..ub-organization-name-length)) - -teletex-personal-name INTEGER ::= 4 - -TeletexPersonalName ::= SET { - surname [0] IMPLICIT TeletexString - (SIZE (1..ub-surname-length)), - given-name [1] IMPLICIT TeletexString - (SIZE (1..ub-given-name-length)) OPTIONAL, - initials [2] IMPLICIT TeletexString - (SIZE (1..ub-initials-length)) OPTIONAL, - generation-qualifier [3] IMPLICIT TeletexString - (SIZE (1..ub-generation-qualifier-length)) - OPTIONAL } - -teletex-organizational-unit-names INTEGER ::= 5 - -TeletexOrganizationalUnitNames ::= SEQUENCE SIZE - (1..ub-organizational-units) OF TeletexOrganizationalUnitName - -TeletexOrganizationalUnitName ::= TeletexString - (SIZE (1..ub-organizational-unit-name-length)) - -pds-name INTEGER ::= 7 - -PDSName ::= PrintableString (SIZE (1..ub-pds-name-length)) - -physical-delivery-country-name INTEGER ::= 8 - -PhysicalDeliveryCountryName ::= CHOICE { - x121-dcc-code NumericString (SIZE -(ub-country-name-numeric-length)), - iso-3166-alpha2-code PrintableString - (SIZE (ub-country-name-alpha-length)) } - -postal-code INTEGER ::= 9 - -PostalCode ::= CHOICE { - numeric-code NumericString (SIZE (1..ub-postal-code-length)), - printable-code PrintableString (SIZE (1..ub-postal-code-length)) } - -physical-delivery-office-name INTEGER ::= 10 - -PhysicalDeliveryOfficeName ::= PDSParameter - -physical-delivery-office-number INTEGER ::= 11 - -PhysicalDeliveryOfficeNumber ::= PDSParameter - -extension-OR-address-components INTEGER ::= 12 - -ExtensionORAddressComponents ::= PDSParameter - -physical-delivery-personal-name INTEGER ::= 13 - -PhysicalDeliveryPersonalName ::= PDSParameter - -physical-delivery-organization-name INTEGER ::= 14 - -PhysicalDeliveryOrganizationName ::= PDSParameter - -extension-physical-delivery-address-components INTEGER ::= 15 - -ExtensionPhysicalDeliveryAddressComponents ::= PDSParameter - -unformatted-postal-address INTEGER ::= 16 - -UnformattedPostalAddress ::= SET { - printable-address SEQUENCE SIZE (1..ub-pds-physical-address-lines) - OF PrintableString (SIZE (1..ub-pds-parameter-length)) - OPTIONAL, - teletex-string TeletexString - (SIZE (1..ub-unformatted-address-length)) OPTIONAL } - -street-address INTEGER ::= 17 - -StreetAddress ::= PDSParameter - -post-office-box-address INTEGER ::= 18 - -PostOfficeBoxAddress ::= PDSParameter - -poste-restante-address INTEGER ::= 19 - -PosteRestanteAddress ::= PDSParameter - -unique-postal-name INTEGER ::= 20 - -UniquePostalName ::= PDSParameter - -local-postal-attributes INTEGER ::= 21 - -LocalPostalAttributes ::= PDSParameter - -PDSParameter ::= SET { - printable-string PrintableString - (SIZE(1..ub-pds-parameter-length)) OPTIONAL, - teletex-string TeletexString - (SIZE(1..ub-pds-parameter-length)) OPTIONAL } - -extended-network-address INTEGER ::= 22 - -ExtendedNetworkAddress ::= CHOICE { - e163-4-address SEQUENCE { - number [0] IMPLICIT NumericString - (SIZE (1..ub-e163-4-number-length)), - sub-address [1] IMPLICIT NumericString - (SIZE (1..ub-e163-4-sub-address-length)) - OPTIONAL }, - psap-address [0] IMPLICIT PresentationAddress } - -PresentationAddress ::= SEQUENCE { - pSelector [0] EXPLICIT OCTET STRING OPTIONAL, - sSelector [1] EXPLICIT OCTET STRING OPTIONAL, - tSelector [2] EXPLICIT OCTET STRING OPTIONAL, - nAddresses [3] EXPLICIT SET SIZE (1..MAX) OF OCTET STRING } - -terminal-type INTEGER ::= 23 - -TerminalType ::= INTEGER { - telex (3), - teletex (4), - g3-facsimile (5), - g4-facsimile (6), - ia5-terminal (7), - videotex (8) } (0..ub-integer-options) - --- Extension Domain-defined Attributes - -teletex-domain-defined-attributes INTEGER ::= 6 - -TeletexDomainDefinedAttributes ::= SEQUENCE SIZE - (1..ub-domain-defined-attributes) OF TeletexDomainDefinedAttribute - -TeletexDomainDefinedAttribute ::= SEQUENCE { - type TeletexString - (SIZE (1..ub-domain-defined-attribute-type-length)), - value TeletexString - (SIZE (1..ub-domain-defined-attribute-value-length)) } - --- specifications of Upper Bounds MUST be regarded as mandatory --- from Annex B of ITU-T X.411 Reference Definition of MTS Parameter --- Upper Bounds - --- Upper Bounds -ub-name INTEGER ::= 32768 -ub-common-name INTEGER ::= 64 -ub-locality-name INTEGER ::= 128 -ub-state-name INTEGER ::= 128 -ub-organization-name INTEGER ::= 64 -ub-organizational-unit-name INTEGER ::= 64 -ub-title INTEGER ::= 64 -ub-serial-number INTEGER ::= 64 -ub-match INTEGER ::= 128 -ub-emailaddress-length INTEGER ::= 128 -ub-common-name-length INTEGER ::= 64 -ub-country-name-alpha-length INTEGER ::= 2 -ub-country-name-numeric-length INTEGER ::= 3 -ub-domain-defined-attributes INTEGER ::= 4 -ub-domain-defined-attribute-type-length INTEGER ::= 8 -ub-domain-defined-attribute-value-length INTEGER ::= 128 -ub-domain-name-length INTEGER ::= 16 -ub-extension-attributes INTEGER ::= 256 -ub-e163-4-number-length INTEGER ::= 15 -ub-e163-4-sub-address-length INTEGER ::= 40 -ub-generation-qualifier-length INTEGER ::= 3 -ub-given-name-length INTEGER ::= 16 -ub-initials-length INTEGER ::= 5 -ub-integer-options INTEGER ::= 256 -ub-numeric-user-id-length INTEGER ::= 32 -ub-organization-name-length INTEGER ::= 64 -ub-organizational-unit-name-length INTEGER ::= 32 -ub-organizational-units INTEGER ::= 4 -ub-pds-name-length INTEGER ::= 16 -ub-pds-parameter-length INTEGER ::= 30 -ub-pds-physical-address-lines INTEGER ::= 6 -ub-postal-code-length INTEGER ::= 16 -ub-pseudonym INTEGER ::= 128 -ub-surname-length INTEGER ::= 40 -ub-terminal-id-length INTEGER ::= 24 -ub-unformatted-address-length INTEGER ::= 180 -ub-x121-address-length INTEGER ::= 16 - --- Note - upper bounds on string types, such as TeletexString, are --- measured in characters. Excepting PrintableString or IA5String, a --- significantly greater number of octets will be required to hold --- such a value. As a minimum, 16 octets, or twice the specified --- upper bound, whichever is the larger, should be allowed for --- TeletexString. For UTF8String or UniversalString at least four --- times the upper bound should be allowed. - -END diff --git a/lib/ssl/pkix/PKIX1Explicit88.hrl b/lib/ssl/pkix/PKIX1Explicit88.hrl deleted file mode 100644 index 5940c1e245..0000000000 --- a/lib/ssl/pkix/PKIX1Explicit88.hrl +++ /dev/null @@ -1,163 +0,0 @@ -%% Generated by the Erlang ASN.1 compiler version:1.4.4.8 -%% Purpose: Erlang record definitions for each named and unnamed -%% SEQUENCE and SET, and macro definitions for each value -%% definition,in module PKIX1Explicit88 - - - --record('Attribute',{ -type, values}). - --record('AttributeTypeAndValue',{ -type, value}). - --record('Certificate',{ -tbsCertificate, signatureAlgorithm, signature}). - --record('TBSCertificate',{ -version = asn1_DEFAULT, serialNumber, signature, issuer, validity, subject, subjectPublicKeyInfo, issuerUniqueID = asn1_NOVALUE, subjectUniqueID = asn1_NOVALUE, extensions = asn1_NOVALUE}). - --record('Validity',{ -notBefore, notAfter}). - --record('SubjectPublicKeyInfo',{ -algorithm, subjectPublicKey}). - --record('Extension',{ -extnID, critical = asn1_DEFAULT, extnValue}). - --record('CertificateList',{ -tbsCertList, signatureAlgorithm, signature}). - --record('TBSCertList',{ -version = asn1_NOVALUE, signature, issuer, thisUpdate, nextUpdate = asn1_NOVALUE, revokedCertificates = asn1_NOVALUE, crlExtensions = asn1_NOVALUE}). - --record('TBSCertList_revokedCertificates_SEQOF',{ -userCertificate, revocationDate, crlEntryExtensions = asn1_NOVALUE}). - --record('AlgorithmIdentifier',{ -algorithm, parameters = asn1_NOVALUE}). - --record('ORAddress',{ -'built-in-standard-attributes', 'built-in-domain-defined-attributes' = asn1_NOVALUE, 'extension-attributes' = asn1_NOVALUE}). - --record('BuiltInStandardAttributes',{ -'country-name' = asn1_NOVALUE, 'administration-domain-name' = asn1_NOVALUE, 'network-address' = asn1_NOVALUE, 'terminal-identifier' = asn1_NOVALUE, 'private-domain-name' = asn1_NOVALUE, 'organization-name' = asn1_NOVALUE, 'numeric-user-identifier' = asn1_NOVALUE, 'personal-name' = asn1_NOVALUE, 'organizational-unit-names' = asn1_NOVALUE}). - --record('PersonalName',{ -surname, 'given-name' = asn1_NOVALUE, initials = asn1_NOVALUE, 'generation-qualifier' = asn1_NOVALUE}). - --record('BuiltInDomainDefinedAttribute',{ -type, value}). - --record('ExtensionAttribute',{ -'extension-attribute-type', 'extension-attribute-value'}). - --record('TeletexPersonalName',{ -surname, 'given-name' = asn1_NOVALUE, initials = asn1_NOVALUE, 'generation-qualifier' = asn1_NOVALUE}). - --record('UnformattedPostalAddress',{ -'printable-address' = asn1_NOVALUE, 'teletex-string' = asn1_NOVALUE}). - --record('PDSParameter',{ -'printable-string' = asn1_NOVALUE, 'teletex-string' = asn1_NOVALUE}). - --record('ExtendedNetworkAddress_e163-4-address',{ -number, 'sub-address' = asn1_NOVALUE}). - --record('PresentationAddress',{ -pSelector = asn1_NOVALUE, sSelector = asn1_NOVALUE, tSelector = asn1_NOVALUE, nAddresses}). - --record('TeletexDomainDefinedAttribute',{ -type, value}). - --define('id-pkix', {1,3,6,1,5,5,7}). --define('id-pe', {1,3,6,1,5,5,7,1}). --define('id-qt', {1,3,6,1,5,5,7,2}). --define('id-kp', {1,3,6,1,5,5,7,3}). --define('id-ad', {1,3,6,1,5,5,7,48}). --define('id-qt-cps', {1,3,6,1,5,5,7,2,1}). --define('id-qt-unotice', {1,3,6,1,5,5,7,2,2}). --define('id-ad-ocsp', {1,3,6,1,5,5,7,48,1}). --define('id-ad-caIssuers', {1,3,6,1,5,5,7,48,2}). --define('id-ad-timeStamping', {1,3,6,1,5,5,7,48,3}). --define('id-ad-caRepository', {1,3,6,1,5,5,7,48,5}). --define('id-at', {2,5,4}). --define('id-at-name', {2,5,4,41}). --define('id-at-surname', {2,5,4,4}). --define('id-at-givenName', {2,5,4,42}). --define('id-at-initials', {2,5,4,43}). --define('id-at-generationQualifier', {2,5,4,44}). --define('id-at-commonName', {2,5,4,3}). --define('id-at-localityName', {2,5,4,7}). --define('id-at-stateOrProvinceName', {2,5,4,8}). --define('id-at-organizationName', {2,5,4,10}). --define('id-at-organizationalUnitName', {2,5,4,11}). --define('id-at-title', {2,5,4,12}). --define('id-at-dnQualifier', {2,5,4,46}). --define('id-at-countryName', {2,5,4,6}). --define('id-at-serialNumber', {2,5,4,5}). --define('id-at-pseudonym', {2,5,4,65}). --define('id-domainComponent', {0,9,2342,19200300,100,1,25}). --define('pkcs-9', {1,2,840,113549,1,9}). --define('id-emailAddress', {1,2,840,113549,1,9,1}). --define('common-name', 1). --define('teletex-common-name', 2). --define('teletex-organization-name', 3). --define('teletex-personal-name', 4). --define('teletex-organizational-unit-names', 5). --define('pds-name', 7). --define('physical-delivery-country-name', 8). --define('postal-code', 9). --define('physical-delivery-office-name', 10). --define('physical-delivery-office-number', 11). --define('extension-OR-address-components', 12). --define('physical-delivery-personal-name', 13). --define('physical-delivery-organization-name', 14). --define('extension-physical-delivery-address-components', 15). --define('unformatted-postal-address', 16). --define('street-address', 17). --define('post-office-box-address', 18). --define('poste-restante-address', 19). --define('unique-postal-name', 20). --define('local-postal-attributes', 21). --define('extended-network-address', 22). --define('terminal-type', 23). --define('teletex-domain-defined-attributes', 6). --define('ub-name', 32768). --define('ub-common-name', 64). --define('ub-locality-name', 128). --define('ub-state-name', 128). --define('ub-organization-name', 64). --define('ub-organizational-unit-name', 64). --define('ub-title', 64). --define('ub-serial-number', 64). --define('ub-match', 128). --define('ub-emailaddress-length', 128). --define('ub-common-name-length', 64). --define('ub-country-name-alpha-length', 2). --define('ub-country-name-numeric-length', 3). --define('ub-domain-defined-attributes', 4). --define('ub-domain-defined-attribute-type-length', 8). --define('ub-domain-defined-attribute-value-length', 128). --define('ub-domain-name-length', 16). --define('ub-extension-attributes', 256). --define('ub-e163-4-number-length', 15). --define('ub-e163-4-sub-address-length', 40). --define('ub-generation-qualifier-length', 3). --define('ub-given-name-length', 16). --define('ub-initials-length', 5). --define('ub-integer-options', 256). --define('ub-numeric-user-id-length', 32). --define('ub-organization-name-length', 64). --define('ub-organizational-unit-name-length', 32). --define('ub-organizational-units', 4). --define('ub-pds-name-length', 16). --define('ub-pds-parameter-length', 30). --define('ub-pds-physical-address-lines', 6). --define('ub-postal-code-length', 16). --define('ub-pseudonym', 128). --define('ub-surname-length', 40). --define('ub-terminal-id-length', 24). --define('ub-unformatted-address-length', 180). --define('ub-x121-address-length', 16). diff --git a/lib/ssl/pkix/PKIX1Implicit88.asn1 b/lib/ssl/pkix/PKIX1Implicit88.asn1 deleted file mode 100644 index ced270baf6..0000000000 --- a/lib/ssl/pkix/PKIX1Implicit88.asn1 +++ /dev/null @@ -1,349 +0,0 @@ -PKIX1Implicit88 { iso(1) identified-organization(3) dod(6) internet(1) - security(5) mechanisms(5) pkix(7) id-mod(0) id-pkix1-implicit(19) } - -DEFINITIONS IMPLICIT TAGS ::= - -BEGIN - --- EXPORTS ALL -- - -IMPORTS - id-pe, id-kp, id-qt-unotice, id-qt-cps, - -- delete following line if "new" types are supported -- - -- BMPString, - -- UTF8String, end "new" types -- - ORAddress, Name, RelativeDistinguishedName, - CertificateSerialNumber, Attribute, DirectoryString - FROM PKIX1Explicit88 { iso(1) identified-organization(3) - dod(6) internet(1) security(5) mechanisms(5) pkix(7) - id-mod(0) id-pkix1-explicit(18) }; - - --- ISO arc for standard certificate and CRL extensions - -id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29} - --- authority key identifier OID and syntax - -id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 } - -AuthorityKeyIdentifier ::= SEQUENCE { - keyIdentifier [0] KeyIdentifier OPTIONAL, - authorityCertIssuer [1] GeneralNames OPTIONAL, - authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL } - -- authorityCertIssuer and authorityCertSerialNumber MUST both - -- be present or both be absent - -KeyIdentifier ::= OCTET STRING - --- subject key identifier OID and syntax - -id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 } - -SubjectKeyIdentifier ::= KeyIdentifier - --- key usage extension OID and syntax - -id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 } - -KeyUsage ::= BIT STRING { - digitalSignature (0), - nonRepudiation (1), - keyEncipherment (2), - dataEncipherment (3), - keyAgreement (4), - keyCertSign (5), - cRLSign (6), - encipherOnly (7), - decipherOnly (8) } - --- private key usage period extension OID and syntax - -id-ce-privateKeyUsagePeriod OBJECT IDENTIFIER ::= { id-ce 16 } - -PrivateKeyUsagePeriod ::= SEQUENCE { - notBefore [0] GeneralizedTime OPTIONAL, - notAfter [1] GeneralizedTime OPTIONAL } - -- either notBefore or notAfter MUST be present - --- certificate policies extension OID and syntax - -id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 } - -anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 } - -CertificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation - -PolicyInformation ::= SEQUENCE { - policyIdentifier CertPolicyId, - policyQualifiers SEQUENCE SIZE (1..MAX) OF - PolicyQualifierInfo OPTIONAL } - -CertPolicyId ::= OBJECT IDENTIFIER - -PolicyQualifierInfo ::= SEQUENCE { - policyQualifierId PolicyQualifierId, - qualifier ANY DEFINED BY policyQualifierId } - --- Implementations that recognize additional policy qualifiers MUST --- augment the following definition for PolicyQualifierId - -PolicyQualifierId ::= - OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice ) - --- CPS pointer qualifier - -CPSuri ::= IA5String - --- user notice qualifier - -UserNotice ::= SEQUENCE { - noticeRef NoticeReference OPTIONAL, - explicitText DisplayText OPTIONAL} - -NoticeReference ::= SEQUENCE { - organization DisplayText, - noticeNumbers SEQUENCE OF INTEGER } - -DisplayText ::= CHOICE { - ia5String IA5String (SIZE (1..200)), - visibleString VisibleString (SIZE (1..200)), - bmpString BMPString (SIZE (1..200)), - utf8String UTF8String (SIZE (1..200)) } - --- policy mapping extension OID and syntax - -id-ce-policyMappings OBJECT IDENTIFIER ::= { id-ce 33 } - -PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE { - issuerDomainPolicy CertPolicyId, - subjectDomainPolicy CertPolicyId } - --- subject alternative name extension OID and syntax - -id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 } - -SubjectAltName ::= GeneralNames - -GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName - -GeneralName ::= CHOICE { - otherName [0] AnotherName, - rfc822Name [1] IA5String, - dNSName [2] IA5String, - x400Address [3] ORAddress, - directoryName [4] Name, - ediPartyName [5] EDIPartyName, - uniformResourceIdentifier [6] IA5String, - iPAddress [7] OCTET STRING, - registeredID [8] OBJECT IDENTIFIER } - --- AnotherName replaces OTHER-NAME ::= TYPE-IDENTIFIER, as --- TYPE-IDENTIFIER is not supported in the '88 ASN.1 syntax - -AnotherName ::= SEQUENCE { - type-id OBJECT IDENTIFIER, - value [0] EXPLICIT ANY DEFINED BY type-id } - -EDIPartyName ::= SEQUENCE { - nameAssigner [0] DirectoryString OPTIONAL, - partyName [1] DirectoryString } - --- issuer alternative name extension OID and syntax - -id-ce-issuerAltName OBJECT IDENTIFIER ::= { id-ce 18 } - -IssuerAltName ::= GeneralNames - -id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 } - -SubjectDirectoryAttributes ::= SEQUENCE SIZE (1..MAX) OF Attribute - --- basic constraints extension OID and syntax - -id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 } - -BasicConstraints ::= SEQUENCE { - cA BOOLEAN DEFAULT FALSE, - pathLenConstraint INTEGER (0..MAX) OPTIONAL } - --- name constraints extension OID and syntax - -id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 } - -NameConstraints ::= SEQUENCE { - permittedSubtrees [0] GeneralSubtrees OPTIONAL, - excludedSubtrees [1] GeneralSubtrees OPTIONAL } - -GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree - -GeneralSubtree ::= SEQUENCE { - base GeneralName, - minimum [0] BaseDistance DEFAULT 0, - maximum [1] BaseDistance OPTIONAL } - -BaseDistance ::= INTEGER (0..MAX) - --- policy constraints extension OID and syntax - -id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 } - -PolicyConstraints ::= SEQUENCE { - requireExplicitPolicy [0] SkipCerts OPTIONAL, - inhibitPolicyMapping [1] SkipCerts OPTIONAL } - -SkipCerts ::= INTEGER (0..MAX) - --- CRL distribution points extension OID and syntax - -id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= {id-ce 31} - -CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint - -DistributionPoint ::= SEQUENCE { - distributionPoint [0] DistributionPointName OPTIONAL, - reasons [1] ReasonFlags OPTIONAL, - cRLIssuer [2] GeneralNames OPTIONAL } - -DistributionPointName ::= CHOICE { - fullName [0] GeneralNames, - nameRelativeToCRLIssuer [1] RelativeDistinguishedName } - -ReasonFlags ::= BIT STRING { - unused (0), - keyCompromise (1), - cACompromise (2), - affiliationChanged (3), - superseded (4), - cessationOfOperation (5), - certificateHold (6), - privilegeWithdrawn (7), - aACompromise (8) } - --- extended key usage extension OID and syntax - -id-ce-extKeyUsage OBJECT IDENTIFIER ::= {id-ce 37} - -ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId - - -KeyPurposeId ::= OBJECT IDENTIFIER - --- permit unspecified key uses - -anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 } - --- extended key purpose OIDs - -id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 } -id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 } -id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 } -id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 } -id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 } -id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 } - --- inhibit any policy OID and syntax - -id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 } - -InhibitAnyPolicy ::= SkipCerts - --- freshest (delta)CRL extension OID and syntax - -id-ce-freshestCRL OBJECT IDENTIFIER ::= { id-ce 46 } - -FreshestCRL ::= CRLDistributionPoints - --- authority info access - -id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 } - -AuthorityInfoAccessSyntax ::= - SEQUENCE SIZE (1..MAX) OF AccessDescription - -AccessDescription ::= SEQUENCE { - accessMethod OBJECT IDENTIFIER, - accessLocation GeneralName } - --- subject info access - -id-pe-subjectInfoAccess OBJECT IDENTIFIER ::= { id-pe 11 } - -SubjectInfoAccessSyntax ::= - SEQUENCE SIZE (1..MAX) OF AccessDescription - --- CRL number extension OID and syntax - -id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 } - -CRLNumber ::= INTEGER (0..MAX) - --- issuing distribution point extension OID and syntax - -id-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= { id-ce 28 } - -IssuingDistributionPoint ::= SEQUENCE { - distributionPoint [0] DistributionPointName OPTIONAL, - onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE, - onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE, - onlySomeReasons [3] ReasonFlags OPTIONAL, - indirectCRL [4] BOOLEAN DEFAULT FALSE, - onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE } - -id-ce-deltaCRLIndicator OBJECT IDENTIFIER ::= { id-ce 27 } - -BaseCRLNumber ::= CRLNumber - --- CRL reasons extension OID and syntax - -id-ce-cRLReasons OBJECT IDENTIFIER ::= { id-ce 21 } - -CRLReason ::= ENUMERATED { - unspecified (0), - keyCompromise (1), - cACompromise (2), - affiliationChanged (3), - superseded (4), - cessationOfOperation (5), - certificateHold (6), - removeFromCRL (8), - privilegeWithdrawn (9), - aACompromise (10) } - --- certificate issuer CRL entry extension OID and syntax - -id-ce-certificateIssuer OBJECT IDENTIFIER ::= { id-ce 29 } - -CertificateIssuer ::= GeneralNames - --- hold instruction extension OID and syntax - -id-ce-holdInstructionCode OBJECT IDENTIFIER ::= { id-ce 23 } - -HoldInstructionCode ::= OBJECT IDENTIFIER - --- ANSI x9 holdinstructions - --- ANSI x9 arc holdinstruction arc - -holdInstruction OBJECT IDENTIFIER ::= - {joint-iso-itu-t(2) member-body(2) us(840) x9cm(10040) 2} - --- ANSI X9 holdinstructions referenced by this standard - -id-holdinstruction-none OBJECT IDENTIFIER ::= - {holdInstruction 1} -- deprecated - -id-holdinstruction-callissuer OBJECT IDENTIFIER ::= - {holdInstruction 2} - -id-holdinstruction-reject OBJECT IDENTIFIER ::= - {holdInstruction 3} - --- invalidity date CRL entry extension OID and syntax - -id-ce-invalidityDate OBJECT IDENTIFIER ::= { id-ce 24 } - -InvalidityDate ::= GeneralizedTime - -END diff --git a/lib/ssl/pkix/PKIX1Implicit88.hrl b/lib/ssl/pkix/PKIX1Implicit88.hrl deleted file mode 100644 index 8fa1836284..0000000000 --- a/lib/ssl/pkix/PKIX1Implicit88.hrl +++ /dev/null @@ -1,93 +0,0 @@ -%% Generated by the Erlang ASN.1 compiler version:1.4.4.8 -%% Purpose: Erlang record definitions for each named and unnamed -%% SEQUENCE and SET, and macro definitions for each value -%% definition,in module PKIX1Implicit88 - - - --record('AuthorityKeyIdentifier',{ -keyIdentifier = asn1_NOVALUE, authorityCertIssuer = asn1_NOVALUE, authorityCertSerialNumber = asn1_NOVALUE}). - --record('PrivateKeyUsagePeriod',{ -notBefore = asn1_NOVALUE, notAfter = asn1_NOVALUE}). - --record('PolicyInformation',{ -policyIdentifier, policyQualifiers = asn1_NOVALUE}). - --record('PolicyQualifierInfo',{ -policyQualifierId, qualifier}). - --record('UserNotice',{ -noticeRef = asn1_NOVALUE, explicitText = asn1_NOVALUE}). - --record('NoticeReference',{ -organization, noticeNumbers}). - --record('PolicyMappings_SEQOF',{ -issuerDomainPolicy, subjectDomainPolicy}). - --record('AnotherName',{ -'type-id', value}). - --record('EDIPartyName',{ -nameAssigner = asn1_NOVALUE, partyName}). - --record('BasicConstraints',{ -cA = asn1_DEFAULT, pathLenConstraint = asn1_NOVALUE}). - --record('NameConstraints',{ -permittedSubtrees = asn1_NOVALUE, excludedSubtrees = asn1_NOVALUE}). - --record('GeneralSubtree',{ -base, minimum = asn1_DEFAULT, maximum = asn1_NOVALUE}). - --record('PolicyConstraints',{ -requireExplicitPolicy = asn1_NOVALUE, inhibitPolicyMapping = asn1_NOVALUE}). - --record('DistributionPoint',{ -distributionPoint = asn1_NOVALUE, reasons = asn1_NOVALUE, cRLIssuer = asn1_NOVALUE}). - --record('AccessDescription',{ -accessMethod, accessLocation}). - --record('IssuingDistributionPoint',{ -distributionPoint = asn1_NOVALUE, onlyContainsUserCerts = asn1_DEFAULT, onlyContainsCACerts = asn1_DEFAULT, onlySomeReasons = asn1_NOVALUE, indirectCRL = asn1_DEFAULT, onlyContainsAttributeCerts = asn1_DEFAULT}). - --define('id-ce', {2,5,29}). --define('id-ce-authorityKeyIdentifier', {2,5,29,35}). --define('id-ce-subjectKeyIdentifier', {2,5,29,14}). --define('id-ce-keyUsage', {2,5,29,15}). --define('id-ce-privateKeyUsagePeriod', {2,5,29,16}). --define('id-ce-certificatePolicies', {2,5,29,32}). --define('anyPolicy', {2,5,29,32,0}). --define('id-ce-policyMappings', {2,5,29,33}). --define('id-ce-subjectAltName', {2,5,29,17}). --define('id-ce-issuerAltName', {2,5,29,18}). --define('id-ce-subjectDirectoryAttributes', {2,5,29,9}). --define('id-ce-basicConstraints', {2,5,29,19}). --define('id-ce-nameConstraints', {2,5,29,30}). --define('id-ce-policyConstraints', {2,5,29,36}). --define('id-ce-cRLDistributionPoints', {2,5,29,31}). --define('id-ce-extKeyUsage', {2,5,29,37}). --define('anyExtendedKeyUsage', {2,5,29,37,0}). --define('id-kp-serverAuth', {1,3,6,1,5,5,7,3,1}). --define('id-kp-clientAuth', {1,3,6,1,5,5,7,3,2}). --define('id-kp-codeSigning', {1,3,6,1,5,5,7,3,3}). --define('id-kp-emailProtection', {1,3,6,1,5,5,7,3,4}). --define('id-kp-timeStamping', {1,3,6,1,5,5,7,3,8}). --define('id-kp-OCSPSigning', {1,3,6,1,5,5,7,3,9}). --define('id-ce-inhibitAnyPolicy', {2,5,29,54}). --define('id-ce-freshestCRL', {2,5,29,46}). --define('id-pe-authorityInfoAccess', {1,3,6,1,5,5,7,1,1}). --define('id-pe-subjectInfoAccess', {1,3,6,1,5,5,7,1,11}). --define('id-ce-cRLNumber', {2,5,29,20}). --define('id-ce-issuingDistributionPoint', {2,5,29,28}). --define('id-ce-deltaCRLIndicator', {2,5,29,27}). --define('id-ce-cRLReasons', {2,5,29,21}). --define('id-ce-certificateIssuer', {2,5,29,29}). --define('id-ce-holdInstructionCode', {2,5,29,23}). --define('holdInstruction', {2,2,840,10040,2}). --define('id-holdinstruction-none', {2,2,840,10040,2,1}). --define('id-holdinstruction-callissuer', {2,2,840,10040,2,2}). --define('id-holdinstruction-reject', {2,2,840,10040,2,3}). --define('id-ce-invalidityDate', {2,5,29,24}). diff --git a/lib/ssl/pkix/PKIXAttributeCertificate.asn1 b/lib/ssl/pkix/PKIXAttributeCertificate.asn1 deleted file mode 100644 index 7d93e6b37e..0000000000 --- a/lib/ssl/pkix/PKIXAttributeCertificate.asn1 +++ /dev/null @@ -1,189 +0,0 @@ - PKIXAttributeCertificate {iso(1) identified-organization(3) dod(6) - internet(1) security(5) mechanisms(5) pkix(7) id-mod(0) - id-mod-attribute-cert(12)} - - DEFINITIONS IMPLICIT TAGS ::= - - BEGIN - - -- EXPORTS ALL -- - - IMPORTS - - -- IMPORTed module OIDs MAY change if [PKIXPROF] changes - -- PKIX Certificate Extensions - Attribute, AlgorithmIdentifier, CertificateSerialNumber, - Extensions, UniqueIdentifier, - id-pkix, id-pe, id-kp, id-ad, id-at - FROM PKIX1Explicit88 {iso(1) identified-organization(3) - dod(6) internet(1) security(5) mechanisms(5) - pkix(7) id-mod(0) id-pkix1-explicit-88(1)} - - GeneralName, GeneralNames, id-ce - FROM PKIX1Implicit88 {iso(1) identified-organization(3) - dod(6) internet(1) security(5) mechanisms(5) - pkix(7) id-mod(0) id-pkix1-implicit-88(2)} ; - - id-pe-ac-auditIdentity OBJECT IDENTIFIER ::= { id-pe 4 } - id-pe-aaControls OBJECT IDENTIFIER ::= { id-pe 6 } - id-pe-ac-proxying OBJECT IDENTIFIER ::= { id-pe 10 } - id-ce-targetInformation OBJECT IDENTIFIER ::= { id-ce 55 } - - id-aca OBJECT IDENTIFIER ::= { id-pkix 10 } - id-aca-authenticationInfo OBJECT IDENTIFIER ::= { id-aca 1 } - id-aca-accessIdentity OBJECT IDENTIFIER ::= { id-aca 2 } - id-aca-chargingIdentity OBJECT IDENTIFIER ::= { id-aca 3 } - id-aca-group OBJECT IDENTIFIER ::= { id-aca 4 } - -- { id-aca 5 } is reserved - id-aca-encAttrs OBJECT IDENTIFIER ::= { id-aca 6 } - - id-at-role OBJECT IDENTIFIER ::= { id-at 72} - id-at-clearance OBJECT IDENTIFIER ::= - { joint-iso-ccitt(2) ds(5) module(1) - selected-attribute-types(5) clearance (55) } - - -- Uncomment this if using a 1988 level ASN.1 compiler - -- UTF8String ::= [UNIVERSAL 12] IMPLICIT OCTET STRING - - AttributeCertificate ::= SEQUENCE { - acinfo AttributeCertificateInfo, - signatureAlgorithm AlgorithmIdentifier, - signatureValue BIT STRING - } - - AttributeCertificateInfo ::= SEQUENCE { - version AttCertVersion, -- version is v2 - holder Holder, - issuer AttCertIssuer, - signature AlgorithmIdentifier, - serialNumber CertificateSerialNumber, - attrCertValidityPeriod AttCertValidityPeriod, - attributes SEQUENCE OF Attribute, - issuerUniqueID UniqueIdentifier OPTIONAL, - extensions Extensions OPTIONAL - } - - AttCertVersion ::= INTEGER { v2(1) } - - Holder ::= SEQUENCE { - baseCertificateID [0] IssuerSerial OPTIONAL, - -- the issuer and serial number of - -- the holder's Public Key Certificate - entityName [1] GeneralNames OPTIONAL, - -- the name of the claimant or role - objectDigestInfo [2] ObjectDigestInfo OPTIONAL - -- used to directly authenticate the - -- holder, for example, an executable - } - - ObjectDigestInfo ::= SEQUENCE { - digestedObjectType ENUMERATED { - publicKey (0), - publicKeyCert (1), - otherObjectTypes (2) }, - -- otherObjectTypes MUST NOT - -- MUST NOT be used in this profile - otherObjectTypeID OBJECT IDENTIFIER OPTIONAL, - digestAlgorithm AlgorithmIdentifier, - objectDigest BIT STRING - } - - AttCertIssuer ::= CHOICE { - v1Form GeneralNames, -- MUST NOT be used in this - -- profile - v2Form [0] V2Form -- v2 only - } - - V2Form ::= SEQUENCE { - issuerName GeneralNames OPTIONAL, - baseCertificateID [0] IssuerSerial OPTIONAL, - objectDigestInfo [1] ObjectDigestInfo OPTIONAL - -- issuerName MUST be present in this profile - -- baseCertificateID and objectDigestInfo MUST - -- NOT be present in this profile - } - - IssuerSerial ::= SEQUENCE { - issuer GeneralNames, - serial CertificateSerialNumber, - issuerUID UniqueIdentifier OPTIONAL - } - - AttCertValidityPeriod ::= SEQUENCE { - notBeforeTime GeneralizedTime, - notAfterTime GeneralizedTime - } - - Targets ::= SEQUENCE OF Target - - Target ::= CHOICE { - targetName [0] GeneralName, - targetGroup [1] GeneralName, - targetCert [2] TargetCert - } - - TargetCert ::= SEQUENCE { - targetCertificate IssuerSerial, - targetName GeneralName OPTIONAL, - certDigestInfo ObjectDigestInfo OPTIONAL - } - - IetfAttrSyntax ::= SEQUENCE { - policyAuthority[0] GeneralNames OPTIONAL, - values SEQUENCE OF CHOICE { - octets OCTET STRING, - oid OBJECT IDENTIFIER, - string UTF8String - } - } - - SvceAuthInfo ::= SEQUENCE { - service GeneralName, - ident GeneralName, - authInfo OCTET STRING OPTIONAL - } - - RoleSyntax ::= SEQUENCE { - roleAuthority [0] GeneralNames OPTIONAL, - roleName [1] GeneralName - } - - Clearance ::= SEQUENCE { - policyId [0] OBJECT IDENTIFIER, - classList [1] ClassList DEFAULT {unclassified}, - securityCategories - [2] SET OF SecurityCategory OPTIONAL - } - - ClassList ::= BIT STRING { - unmarked (0), - unclassified (1), - restricted (2), - confidential (3), - secret (4), - topSecret (5) - } - - SecurityCategory ::= SEQUENCE { - type [0] IMPLICIT OBJECT IDENTIFIER, - value [1] ANY DEFINED BY type - } - - AAControls ::= SEQUENCE { - pathLenConstraint INTEGER (0..MAX) OPTIONAL, - permittedAttrs [0] AttrSpec OPTIONAL, - excludedAttrs [1] AttrSpec OPTIONAL, - permitUnSpecified BOOLEAN DEFAULT TRUE - } - - AttrSpec::= SEQUENCE OF OBJECT IDENTIFIER - - ACClearAttrs ::= SEQUENCE { - acIssuer GeneralName, - acSerial INTEGER, - attrs SEQUENCE OF Attribute - } - - ProxyInfo ::= SEQUENCE OF Targets - - END diff --git a/lib/ssl/pkix/PKIXAttributeCertificate.hrl b/lib/ssl/pkix/PKIXAttributeCertificate.hrl deleted file mode 100644 index 99389c4852..0000000000 --- a/lib/ssl/pkix/PKIXAttributeCertificate.hrl +++ /dev/null @@ -1,64 +0,0 @@ -%% Generated by the Erlang ASN.1 compiler version:1.4.4.8 -%% Purpose: Erlang record definitions for each named and unnamed -%% SEQUENCE and SET, and macro definitions for each value -%% definition,in module PKIXAttributeCertificate - - - --record('AttributeCertificate',{ -acinfo, signatureAlgorithm, signatureValue}). - --record('AttributeCertificateInfo',{ -version, holder, issuer, signature, serialNumber, attrCertValidityPeriod, attributes, issuerUniqueID = asn1_NOVALUE, extensions = asn1_NOVALUE}). - --record('Holder',{ -baseCertificateID = asn1_NOVALUE, entityName = asn1_NOVALUE, objectDigestInfo = asn1_NOVALUE}). - --record('ObjectDigestInfo',{ -digestedObjectType, otherObjectTypeID = asn1_NOVALUE, digestAlgorithm, objectDigest}). - --record('V2Form',{ -issuerName = asn1_NOVALUE, baseCertificateID = asn1_NOVALUE, objectDigestInfo = asn1_NOVALUE}). - --record('IssuerSerial',{ -issuer, serial, issuerUID = asn1_NOVALUE}). - --record('AttCertValidityPeriod',{ -notBeforeTime, notAfterTime}). - --record('TargetCert',{ -targetCertificate, targetName = asn1_NOVALUE, certDigestInfo = asn1_NOVALUE}). - --record('IetfAttrSyntax',{ -policyAuthority = asn1_NOVALUE, values}). - --record('SvceAuthInfo',{ -service, ident, authInfo = asn1_NOVALUE}). - --record('RoleSyntax',{ -roleAuthority = asn1_NOVALUE, roleName}). - --record('Clearance',{ -policyId, classList = asn1_DEFAULT, securityCategories = asn1_NOVALUE}). - --record('SecurityCategory',{ -type, value}). - --record('AAControls',{ -pathLenConstraint = asn1_NOVALUE, permittedAttrs = asn1_NOVALUE, excludedAttrs = asn1_NOVALUE, permitUnSpecified = asn1_DEFAULT}). - --record('ACClearAttrs',{ -acIssuer, acSerial, attrs}). - --define('id-pe-ac-auditIdentity', {1,3,6,1,5,5,7,1,4}). --define('id-pe-aaControls', {1,3,6,1,5,5,7,1,6}). --define('id-pe-ac-proxying', {1,3,6,1,5,5,7,1,10}). --define('id-ce-targetInformation', {2,5,29,55}). --define('id-aca', {1,3,6,1,5,5,7,10}). --define('id-aca-authenticationInfo', {1,3,6,1,5,5,7,10,1}). --define('id-aca-accessIdentity', {1,3,6,1,5,5,7,10,2}). --define('id-aca-chargingIdentity', {1,3,6,1,5,5,7,10,3}). --define('id-aca-group', {1,3,6,1,5,5,7,10,4}). --define('id-aca-encAttrs', {1,3,6,1,5,5,7,10,6}). --define('id-at-role', {2,5,4,72}). --define('id-at-clearance', {2,5,1,5,55}). diff --git a/lib/ssl/pkix/README b/lib/ssl/pkix/README deleted file mode 100644 index 8be2c15de5..0000000000 --- a/lib/ssl/pkix/README +++ /dev/null @@ -1,49 +0,0 @@ -The files - - PKIX1Algorithms88.asn1 - PKIX1Explicit88.asn1 - PKIX1Implicit88.asn1 - PKIXAttributeCertificate.asn1 - -are from RFCs 3279, 3280 and 3281. - -We have edited PKIX1Explicit88.asn1, PKIX1Implicit88.asn1, and -PKIXAttributeCertificate.asn1 as follows: - - -1. Removal of definition of UniversalString and BMPString: - -diff -r1.1 PKIX1Explicit88.asn1 -15c15 -< UniversalString ::= [UNIVERSAL 28] IMPLICIT OCTET STRING ---- -> -- UniversalString ::= [UNIVERSAL 28] IMPLICIT OCTET STRING -18c18 -< BMPString ::= [UNIVERSAL 30] IMPLICIT OCTET STRING ---- -> -- BMPString ::= [UNIVERSAL 30] IMPLICIT OCTET STRING - - -2. Removal of definition of BMPString: - -diff -r1.1 PKIX1Implicit88.asn1 -13c13,14 -< BMPString, UTF8String, -- end "new" types -- ---- -> -- BMPString, -> UTF8String, -- end "new" types -- - - -3. Addition of definition of UTF8String, and correction of a typo. - -diff -r1.1 PKIXAttributeCertificate.asn1 -46c46 -< -- UTF8String ::= [UNIVERSAL 12] IMPLICIT OCTET STRING ---- -> UTF8String ::= [UNIVERSAL 12] IMPLICIT OCTET STRING -55c55 -< version AttCertVersion -- version is v2, ---- -> version AttCertVersion, -- version is v2 - -PKIX1Algorithms88.asn1 is unchanged. diff --git a/lib/ssl/pkix/SSL-PKIX.asn1 b/lib/ssl/pkix/SSL-PKIX.asn1 deleted file mode 100644 index ea6333f953..0000000000 --- a/lib/ssl/pkix/SSL-PKIX.asn1 +++ /dev/null @@ -1,704 +0,0 @@ -SSL-PKIX {iso(1) identified-organization(3) dod(6) internet(1) - private(4) enterprices(1) ericsson(193) otp(19) ssl(10) - pkix1(1)} - -DEFINITIONS EXPLICIT TAGS ::= - -BEGIN - --- EXPORTS ALL - -IMPORTS - -- Certificate (parts of) - Version, - CertificateSerialNumber, - --AlgorithmIdentifier, - Validity, - UniqueIdentifier, - - -- AttribyteTypeAndValue - Name, - AttributeType, - id-at-name, - id-at-surname, - id-at-givenName, - id-at-initials, - id-at-generationQualifier, X520name, - id-at-commonName, X520CommonName, - id-at-localityName, X520LocalityName, - id-at-stateOrProvinceName, X520StateOrProvinceName, - id-at-organizationName, X520OrganizationName, - id-at-organizationalUnitName, X520OrganizationalUnitName, - id-at-title, X520Title, - id-at-dnQualifier, X520dnQualifier, - id-at-countryName, X520countryName, - id-at-serialNumber, X520SerialNumber, - id-at-pseudonym, X520Pseudonym, - id-domainComponent, DomainComponent, - id-emailAddress, EmailAddress, - - -- Extension Attributes - common-name, CommonName, - teletex-common-name, TeletexCommonName, - teletex-personal-name, TeletexPersonalName, - pds-name, PDSName, - physical-delivery-country-name, PhysicalDeliveryCountryName, - postal-code, PostalCode, - physical-delivery-office-name, PhysicalDeliveryOfficeName, - physical-delivery-office-number, PhysicalDeliveryOfficeNumber, - extension-OR-address-components, ExtensionORAddressComponents, - physical-delivery-personal-name, PhysicalDeliveryPersonalName, - physical-delivery-organization-name, PhysicalDeliveryOrganizationName, - extension-physical-delivery-address-components, - ExtensionPhysicalDeliveryAddressComponents, - unformatted-postal-address, UnformattedPostalAddress, - street-address, StreetAddress, - post-office-box-address, PostOfficeBoxAddress, - poste-restante-address, PosteRestanteAddress, - unique-postal-name, UniquePostalName, - local-postal-attributes, LocalPostalAttributes, - extended-network-address, ExtendedNetworkAddress, - terminal-type, TerminalType, - teletex-domain-defined-attributes, TeletexDomainDefinedAttributes - - FROM PKIX1Explicit88 { iso(1) identified-organization(3) dod(6) - internet(1) security(5) mechanisms(5) pkix(7) id-mod(0) - id-pkix1-explicit(18) } - - -- Extensions - id-ce-authorityKeyIdentifier, AuthorityKeyIdentifier, - id-ce-subjectKeyIdentifier, SubjectKeyIdentifier, - id-ce-keyUsage, KeyUsage, - id-ce-privateKeyUsagePeriod, PrivateKeyUsagePeriod, - id-ce-certificatePolicies, CertificatePolicies, - id-ce-policyMappings, PolicyMappings, - id-ce-subjectAltName, SubjectAltName, - id-ce-issuerAltName, IssuerAltName, - id-ce-subjectDirectoryAttributes, SubjectDirectoryAttributes, - id-ce-basicConstraints, BasicConstraints, - id-ce-nameConstraints, NameConstraints, - id-ce-policyConstraints, PolicyConstraints, - id-ce-cRLDistributionPoints, CRLDistributionPoints, - id-ce-extKeyUsage, ExtKeyUsageSyntax, - id-ce-inhibitAnyPolicy, InhibitAnyPolicy, - id-ce-freshestCRL, FreshestCRL, - id-pe-authorityInfoAccess, AuthorityInfoAccessSyntax, - id-pe-subjectInfoAccess, SubjectInfoAccessSyntax, - id-ce-cRLNumber, CRLNumber, - id-ce-issuingDistributionPoint, IssuingDistributionPoint, - id-ce-deltaCRLIndicator, BaseCRLNumber, - id-ce-cRLReasons, CRLReason, - id-ce-certificateIssuer, CertificateIssuer, - id-ce-holdInstructionCode, HoldInstructionCode, - id-ce-invalidityDate, InvalidityDate - - FROM PKIX1Implicit88 { iso(1) identified-organization(3) dod(6) - internet(1) security(5) mechanisms(5) pkix(7) id-mod(0) - id-pkix1-implicit(19) } - - --Keys and Signatures - id-dsa, Dss-Parms, DSAPublicKey, - id-dsa-with-sha1, - md2WithRSAEncryption, - md5WithRSAEncryption, - sha1WithRSAEncryption, - rsaEncryption, RSAPublicKey, - dhpublicnumber, DomainParameters, DHPublicKey, - id-keyExchangeAlgorithm, KEA-Parms-Id, --KEA-PublicKey, - ecdsa-with-SHA1, - prime-field, Prime-p, - characteristic-two-field, --Characteristic-two, - gnBasis, - tpBasis, Trinomial, - ppBasis, Pentanomial, - id-ecPublicKey, EcpkParameters, ECPoint - FROM PKIX1Algorithms88 { iso(1) identified-organization(3) dod(6) - internet(1) security(5) mechanisms(5) pkix(7) id-mod(0) - id-mod-pkix1-algorithms(17) }; - --- --- Certificate --- - -SSLCertificate ::= SEQUENCE { - tbsCertificate TBSCertificate, - signatureAlgorithm SignatureAlgorithm, - signature BIT STRING } - -SSLTBSCertificate ::= SEQUENCE { - version [0] Version DEFAULT v1, - serialNumber CertificateSerialNumber, - signature SignatureAlgorithm, - issuer Name, - validity Validity, - subject Name, - subjectPublicKeyInfo SubjectPublicKeyInfo, - issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, - -- If present, version MUST be v2 or v3 - subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, - -- If present, version MUST be v2 or v3 - extensions [3] Extensions OPTIONAL - -- If present, version MUST be v3 -- } - - --- Attribute type and values --- - -ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= CLASS { - &id AttributeType UNIQUE, - &Type } - WITH SYNTAX { - ID &id - TYPE &Type } - -SSLAttributeTypeAndValue ::= SEQUENCE { - type ATTRIBUTE-TYPE-AND-VALUE-CLASS.&id - ({SupportedAttributeTypeAndValues}), - value ATTRIBUTE-TYPE-AND-VALUE-CLASS.&Type - ({SupportedAttributeTypeAndValues}{@type}) } - -SupportedAttributeTypeAndValues ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= - { name | surname | givenName | initials | generationQualifier | - commonName | localityName | stateOrProvinceName | organizationName | - organizationalUnitName | title | dnQualifier | countryName | - serialNumber | pseudonym | domainComponent | emailAddress } - -name ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= { - ID id-at-name - TYPE X520name } - -surname ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= { - ID id-at-surname - TYPE X520name } - -givenName ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= { - ID id-at-givenName - TYPE X520name } - -initials ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= { - ID id-at-initials - TYPE X520name } - -generationQualifier ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= { - ID id-at-generationQualifier - TYPE X520name } - -commonName ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= { - ID id-at-commonName - TYPE X520CommonName } - -localityName ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= { - ID id-at-localityName - TYPE X520LocalityName } - -stateOrProvinceName ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= { - ID id-at-stateOrProvinceName - TYPE X520StateOrProvinceName } - -organizationName ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= { - ID id-at-organizationName - TYPE X520OrganizationName } - -organizationalUnitName ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= { - ID id-at-organizationalUnitName - TYPE X520OrganizationalUnitName } - -title ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= { - ID id-at-title - TYPE X520Title } - -dnQualifier ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= { - ID id-at-dnQualifier - TYPE X520dnQualifier } - -countryName ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= { - ID id-at-countryName - TYPE X520countryName } - -serialNumber ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= { - ID id-at-serialNumber - TYPE X520SerialNumber } - -pseudonym ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= { - ID id-at-pseudonym - TYPE X520Pseudonym } - -domainComponent ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= { - ID id-domainComponent - TYPE DomainComponent } - -emailAddress ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= { - ID id-emailAddress - TYPE EmailAddress } - --- --- Signature and Public Key Algorithms --- - -SSLSubjectPublicKeyInfo ::= SEQUENCE { - algorithm SEQUENCE { - algo PUBLIC-KEY-ALGORITHM-CLASS.&id - ({SupportedPublicKeyAlgorithms}), - parameters PUBLIC-KEY-ALGORITHM-CLASS.&Type - ({SupportedPublicKeyAlgorithms}{@.algo}) - OPTIONAL - }, - subjectPublicKey PUBLIC-KEY-ALGORITHM-CLASS.&PublicKeyType - ({SupportedPublicKeyAlgorithms}{@algorithm.algo}) } - --- The following is needed for conversion of SubjectPublicKeyInfo. - -SSLSubjectPublicKeyInfo-Any ::= SEQUENCE { - algorithm PublicKeyAlgorithm, - subjectPublicKey ANY } - - -SIGNATURE-ALGORITHM-CLASS ::= CLASS { - &id OBJECT IDENTIFIER UNIQUE, - &Type OPTIONAL } - WITH SYNTAX { - ID &id - [TYPE &Type] } - -PUBLIC-KEY-ALGORITHM-CLASS ::= CLASS { - &id OBJECT IDENTIFIER UNIQUE, - &Type OPTIONAL, - &PublicKeyType OPTIONAL } - WITH SYNTAX { - ID &id - [TYPE &Type] - [PUBLIC-KEY-TYPE &PublicKeyType] } - -SignatureAlgorithm ::= SEQUENCE { - algorithm SIGNATURE-ALGORITHM-CLASS.&id - ({SupportedSignatureAlgorithms}), - parameters SIGNATURE-ALGORITHM-CLASS.&Type - ({SupportedSignatureAlgorithms}{@algorithm}) - OPTIONAL } - -SignatureAlgorithm-Any ::= SEQUENCE { - algorithm OBJECT IDENTIFIER, - parameters ANY OPTIONAL } - -PublicKeyAlgorithm ::= SEQUENCE { - algorithm PUBLIC-KEY-ALGORITHM-CLASS.&id - ({SupportedPublicKeyAlgorithms}), - parameters PUBLIC-KEY-ALGORITHM-CLASS.&Type - ({SupportedPublicKeyAlgorithms}{@algorithm}) - OPTIONAL } - -SupportedSignatureAlgorithms SIGNATURE-ALGORITHM-CLASS ::= { - dsa-with-sha1 | md2-with-rsa-encryption | - md5-with-rsa-encryption | sha1-with-rsa-encryption | - ecdsa-with-sha1 } - -SupportedPublicKeyAlgorithms PUBLIC-KEY-ALGORITHM-CLASS ::= { - dsa | rsa-encryption | dh | kea | ec-public-key } - - -- DSA Keys and Signatures - - -- SubjectPublicKeyInfo: - - dsa PUBLIC-KEY-ALGORITHM-CLASS ::= { - ID id-dsa - TYPE Dss-Parms -- XXX Must be OPTIONAL - PUBLIC-KEY-TYPE DSAPublicKey } - - -- Certificate.signatureAlgorithm - - dsa-with-sha1 SIGNATURE-ALGORITHM-CLASS ::= { - ID id-dsa-with-sha1 - TYPE NULL } -- XXX Must be empty and not NULL - - -- - -- RSA Keys and Signatures - -- - - -- Certificate.signatureAlgorithm - - md2-with-rsa-encryption SIGNATURE-ALGORITHM-CLASS ::= { - ID md2WithRSAEncryption - TYPE NULL } - - md5-with-rsa-encryption SIGNATURE-ALGORITHM-CLASS ::= { - ID md5WithRSAEncryption - TYPE NULL } - - sha1-with-rsa-encryption SIGNATURE-ALGORITHM-CLASS ::= { - ID sha1WithRSAEncryption - TYPE NULL } - - -- Certificate.signature - -- See PKCS #1 (RFC 2313). XXX - - -- SubjectPublicKeyInfo: - - rsa-encryption PUBLIC-KEY-ALGORITHM-CLASS ::= { - ID rsaEncryption - TYPE NULL - PUBLIC-KEY-TYPE RSAPublicKey } - - -- - -- Diffie-Hellman Keys - -- - - -- SubjectPublicKeyInfo: - - dh PUBLIC-KEY-ALGORITHM-CLASS ::= { - ID dhpublicnumber - TYPE DomainParameters - PUBLIC-KEY-TYPE DHPublicKey } - - -- There are no Diffie-Hellman signature algorithms - - -- - -- KEA Keys - -- - - -- SubjectPublicKeyInfo: - - KEA-PublicKey ::= INTEGER - - kea PUBLIC-KEY-ALGORITHM-CLASS ::= { - ID id-keyExchangeAlgorithm - TYPE KEA-Parms-Id - PUBLIC-KEY-TYPE KEA-PublicKey } - - -- There are no KEA signature algorithms - - -- - -- Elliptic Curve Keys, Signatures, and Curves - -- - - -- Certificate.signatureAlgorithm - - ecdsa-with-sha1 SIGNATURE-ALGORITHM-CLASS ::= { - ID ecdsa-with-SHA1 - TYPE NULL } -- XXX Must be empty and not NULL - - FIELD-ID-CLASS ::= CLASS { - &id OBJECT IDENTIFIER UNIQUE, - &Type } - WITH SYNTAX { - ID &id - TYPE &Type } - - SSLFieldID ::= SEQUENCE { -- Finite field - fieldType FIELD-ID-CLASS.&id({SupportedFieldIds}), - parameters FIELD-ID-CLASS.&Type({SupportedFieldIds}{@fieldType}) } - - SupportedFieldIds FIELD-ID-CLASS ::= { - field-prime-field | field-characteristic-two } - - field-prime-field FIELD-ID-CLASS ::= { - ID prime-field - TYPE Prime-p } - - CHARACTERISTIC-TWO-CLASS ::= CLASS { - &id OBJECT IDENTIFIER UNIQUE, - &Type } - WITH SYNTAX { - ID &id - TYPE &Type } - - SSLCharacteristic-two ::= SEQUENCE { -- Finite field - m INTEGER, -- Field size 2^m - basis CHARACTERISTIC-TWO-CLASS.&id({SupportedCharacteristicTwos}), - parameters CHARACTERISTIC-TWO-CLASS.&Type - ({SupportedCharacteristicTwos}{@basis}) } - - SupportedCharacteristicTwos CHARACTERISTIC-TWO-CLASS ::= { - gn-basis | tp-basis | pp-basis } - - field-characteristic-two FIELD-ID-CLASS ::= { - ID characteristic-two-field - TYPE Characteristic-two } - - gn-basis CHARACTERISTIC-TWO-CLASS ::= { - ID gnBasis - TYPE NULL } - - tp-basis CHARACTERISTIC-TWO-CLASS ::= { - ID tpBasis - TYPE Trinomial } - - pp-basis CHARACTERISTIC-TWO-CLASS ::= { - ID ppBasis - TYPE Pentanomial } - - -- SubjectPublicKeyInfo.algorithm - - ec-public-key PUBLIC-KEY-ALGORITHM-CLASS ::= { - ID id-ecPublicKey - TYPE EcpkParameters - PUBLIC-KEY-TYPE ECPoint } - --- --- Extension Attributes --- - -EXTENSION-ATTRIBUTE-CLASS ::= CLASS { - &id INTEGER UNIQUE, - &Type } - WITH SYNTAX { - ID &id - TYPE &Type } - -SSLExtensionAttributes ::= SET SIZE (1..MAX) OF ExtensionAttribute - --- XXX Below we should have extension-attribute-type and extension- --- attribute-value but Erlang ASN1 does not like it. -SSLExtensionAttribute ::= SEQUENCE { - extensionAttributeType [0] IMPLICIT EXTENSION-ATTRIBUTE-CLASS.&id - ({SupportedExtensionAttributes}), - extensionAttributeValue [1] EXTENSION-ATTRIBUTE-CLASS.&Type - ({SupportedExtensionAttributes}{@extensionAttributeType}) } - -SupportedExtensionAttributes EXTENSION-ATTRIBUTE-CLASS ::= { - x400-common-name | - x400-teletex-common-name | - x400-teletex-personal-name | - x400-pds-name | - x400-physical-delivery-country-name | - x400-postal-code | - x400-physical-delivery-office-name | - x400-physical-delivery-office-number | - x400-extension-OR-address-components | - x400-physical-delivery-personal-name | - x400-physical-delivery-organization-name | - x400-extension-physical-delivery-address-components | - x400-unformatted-postal-address | - x400-street-address | - x400-post-office-box-address | - x400-poste-restante-address | - x400-unique-postal-name | - x400-local-postal-attributes | - x400-extended-network-address | - x400-terminal-type | - x400-teletex-domain-defined-attributes } - --- Extension types and attribute values - -x400-common-name EXTENSION-ATTRIBUTE-CLASS ::= { - ID common-name - TYPE CommonName } - -x400-teletex-common-name EXTENSION-ATTRIBUTE-CLASS ::= { - ID teletex-common-name - TYPE TeletexCommonName } - -x400-teletex-personal-name EXTENSION-ATTRIBUTE-CLASS ::= { - ID teletex-personal-name - TYPE TeletexPersonalName } - -x400-pds-name EXTENSION-ATTRIBUTE-CLASS ::= { - ID pds-name - TYPE PDSName } - -x400-physical-delivery-country-name EXTENSION-ATTRIBUTE-CLASS ::= { - ID physical-delivery-country-name - TYPE PhysicalDeliveryCountryName } - -x400-postal-code EXTENSION-ATTRIBUTE-CLASS ::= { - ID postal-code - TYPE PostalCode } - -x400-physical-delivery-office-name EXTENSION-ATTRIBUTE-CLASS ::= { - ID physical-delivery-office-name - TYPE PhysicalDeliveryOfficeName } - -x400-physical-delivery-office-number EXTENSION-ATTRIBUTE-CLASS ::= { - ID physical-delivery-office-number - TYPE PhysicalDeliveryOfficeNumber } - -x400-extension-OR-address-components EXTENSION-ATTRIBUTE-CLASS ::= { - ID extension-OR-address-components - TYPE ExtensionORAddressComponents } - -x400-physical-delivery-personal-name EXTENSION-ATTRIBUTE-CLASS ::= { - ID physical-delivery-personal-name - TYPE PhysicalDeliveryPersonalName } - -x400-physical-delivery-organization-name EXTENSION-ATTRIBUTE-CLASS ::= { - ID physical-delivery-organization-name - TYPE PhysicalDeliveryOrganizationName } - -x400-extension-physical-delivery-address-components - EXTENSION-ATTRIBUTE-CLASS ::= { - ID extension-physical-delivery-address-components - TYPE ExtensionPhysicalDeliveryAddressComponents } - -x400-unformatted-postal-address EXTENSION-ATTRIBUTE-CLASS ::= { - ID unformatted-postal-address - TYPE UnformattedPostalAddress } - -x400-street-address EXTENSION-ATTRIBUTE-CLASS ::= { - ID street-address - TYPE StreetAddress } - -x400-post-office-box-address EXTENSION-ATTRIBUTE-CLASS ::= { - ID post-office-box-address - TYPE PostOfficeBoxAddress } - -x400-poste-restante-address EXTENSION-ATTRIBUTE-CLASS ::= { - ID poste-restante-address - TYPE PosteRestanteAddress } - -x400-unique-postal-name EXTENSION-ATTRIBUTE-CLASS ::= { - ID unique-postal-name - TYPE UniquePostalName } - -x400-local-postal-attributes EXTENSION-ATTRIBUTE-CLASS ::= { - ID local-postal-attributes - TYPE LocalPostalAttributes } - -x400-extended-network-address EXTENSION-ATTRIBUTE-CLASS ::= { - ID extended-network-address - TYPE ExtendedNetworkAddress } - -x400-terminal-type EXTENSION-ATTRIBUTE-CLASS ::= { - ID terminal-type - TYPE TerminalType } - -x400-teletex-domain-defined-attributes EXTENSION-ATTRIBUTE-CLASS ::= { - ID teletex-domain-defined-attributes - TYPE TeletexDomainDefinedAttributes } - --- Extensions - -SSLExtensions ::= SEQUENCE SIZE (1..MAX) OF Extension - -EXTENSION-CLASS ::= CLASS { - &id OBJECT IDENTIFIER UNIQUE, - &Type OPTIONAL} - WITH SYNTAX { - ID &id - [TYPE &Type] } - -SSLExtension ::= SEQUENCE { - extnID EXTENSION-CLASS.&id({SupportedExtensions}), - critical BOOLEAN DEFAULT FALSE, - extnValue EXTENSION-CLASS.&Type({SupportedExtensions}{@extnID}) } - --- The following is needed for conversion between Extension and Extension-Cd - -ObjId ::= OBJECT IDENTIFIER -Boolean ::= BOOLEAN -Any ::= ANY - -Extension-Any ::= SEQUENCE { - extnID OBJECT IDENTIFIER, - critical BOOLEAN DEFAULT FALSE, - extnValue ANY } - -SupportedExtensions EXTENSION-CLASS ::= { authorityKeyIdentifier | - subjectKeyIdentifier | keyUsage | privateKeyUsagePeriod | - certificatePolicies | policyMappings | subjectAltName | - issuerAltName | subjectDirectoryAttributes | basicConstraints | - nameConstraints | policyConstraints | cRLDistributionPoints | - extKeyUsage | inhibitAnyPolicy | freshestCRL | authorityInfoAccess | - subjectInfoAccess | cRLNumber | issuingDistributionPoint | - deltaCRLIndicator | cRLReasons | certificateIssuer | - holdInstructionCode | invalidityDate } - -authorityKeyIdentifier EXTENSION-CLASS ::= { - ID id-ce-authorityKeyIdentifier - TYPE AuthorityKeyIdentifier } - -subjectKeyIdentifier EXTENSION-CLASS ::= { - ID id-ce-subjectKeyIdentifier - TYPE SubjectKeyIdentifier } - -keyUsage EXTENSION-CLASS ::= { - ID id-ce-keyUsage - TYPE KeyUsage } - -privateKeyUsagePeriod EXTENSION-CLASS ::= { - ID id-ce-privateKeyUsagePeriod - TYPE PrivateKeyUsagePeriod } - -certificatePolicies EXTENSION-CLASS ::= { - ID id-ce-certificatePolicies - TYPE CertificatePolicies } - -policyMappings EXTENSION-CLASS ::= { - ID id-ce-policyMappings - TYPE PolicyMappings } - -subjectAltName EXTENSION-CLASS ::= { - ID id-ce-subjectAltName - TYPE SubjectAltName } - -issuerAltName EXTENSION-CLASS ::= { - ID id-ce-issuerAltName - TYPE IssuerAltName } - -subjectDirectoryAttributes EXTENSION-CLASS ::= { - ID id-ce-subjectDirectoryAttributes - TYPE SubjectDirectoryAttributes } - -basicConstraints EXTENSION-CLASS ::= { - ID id-ce-basicConstraints - TYPE BasicConstraints } - -nameConstraints EXTENSION-CLASS ::= { - ID id-ce-nameConstraints - TYPE NameConstraints } - -policyConstraints EXTENSION-CLASS ::= { - ID id-ce-policyConstraints - TYPE PolicyConstraints } - -cRLDistributionPoints EXTENSION-CLASS ::= { - ID id-ce-cRLDistributionPoints - TYPE CRLDistributionPoints } - -extKeyUsage EXTENSION-CLASS ::= { - ID id-ce-extKeyUsage - TYPE ExtKeyUsageSyntax } - -inhibitAnyPolicy EXTENSION-CLASS ::= { - ID id-ce-inhibitAnyPolicy - TYPE InhibitAnyPolicy } - -freshestCRL EXTENSION-CLASS ::= { - ID id-ce-freshestCRL - TYPE FreshestCRL } - -authorityInfoAccess EXTENSION-CLASS ::= { - ID id-pe-authorityInfoAccess - TYPE AuthorityInfoAccessSyntax } - -subjectInfoAccess EXTENSION-CLASS ::= { - ID id-pe-subjectInfoAccess - TYPE SubjectInfoAccessSyntax } - -cRLNumber EXTENSION-CLASS ::= { - ID id-ce-cRLNumber - TYPE CRLNumber } - -issuingDistributionPoint EXTENSION-CLASS ::= { - ID id-ce-issuingDistributionPoint - TYPE IssuingDistributionPoint } - -deltaCRLIndicator EXTENSION-CLASS ::= { - ID id-ce-deltaCRLIndicator - TYPE BaseCRLNumber } - -cRLReasons EXTENSION-CLASS ::= { - ID id-ce-cRLReasons - TYPE CRLReason } - -certificateIssuer EXTENSION-CLASS ::= { - ID id-ce-certificateIssuer - TYPE CertificateIssuer } - -holdInstructionCode EXTENSION-CLASS ::= { - ID id-ce-holdInstructionCode - TYPE HoldInstructionCode } - -invalidityDate EXTENSION-CLASS ::= { - ID id-ce-invalidityDate - TYPE InvalidityDate } - -END diff --git a/lib/ssl/pkix/mk_ssl_pkix_oid.erl b/lib/ssl/pkix/mk_ssl_pkix_oid.erl deleted file mode 100644 index 06edc5113a..0000000000 --- a/lib/ssl/pkix/mk_ssl_pkix_oid.erl +++ /dev/null @@ -1,94 +0,0 @@ --module(mk_ssl_pkix_oid). - --export([make/0]). - --define(PKIX_MODULES, ['OTP-PKIX']). - -make() -> - {ok, Fd} = file:open("ssl_pkix_oid.erl", [write]), - io:fwrite(Fd, "%%% File: ssl_pkix_oid.erl\n" - "%%% NB This file has been automatically generated by " - "mk_ssl_pkix_oid.\n" - "%%% Do not edit it.\n\n", []), - io:fwrite(Fd, "-module(ssl_pkix_oid).\n", []), - io:fwrite(Fd, "-export([id2atom/1, atom2id/1, all_atoms/0, " - "all_ids/0]).\n\n", []), - - - AIds0 = get_atom_ids(?PKIX_MODULES), - - AIds1 = modify_atoms(AIds0), - gen_id2atom(Fd, AIds1), - gen_atom2id(Fd, AIds1), - gen_all(Fd, AIds1), - file:close(Fd). - -get_atom_ids(Ms) -> - get_atom_ids(Ms, []). - -get_atom_ids([], AIdss) -> - lists:flatten(AIdss); -get_atom_ids([M| Ms], AIdss) -> - {value, {exports, Exports}} = - lists:keysearch(exports, 1, M:module_info()), - As = lists:zf( - fun ({info, 0}) -> false; - ({module_info, 0}) -> false; - ({encoding_rule, 0}) -> false; - ({F, 0}) -> - case atom_to_list(F) of - %% Remove upper-bound (ub-) functions - "ub-" ++ _Rest -> - false; - _ -> - {true, F} - end; - (_) -> false - end, Exports), - AIds = lists:map(fun(F) -> {F, M:F()} end, As), - get_atom_ids(Ms, [AIds| AIdss]). - -modify_atoms(AIds) -> - F = fun({A, I}) -> - NAS = case atom_to_list(A) of - "id-" ++ Rest -> - Rest; - Any -> - Any - end, - {list_to_atom(NAS), I} end, - lists:map(F, AIds). - -gen_id2atom(Fd, AIds0) -> - AIds1 = lists:keysort(2, AIds0), - Txt = join(";\n", - lists:map( - fun({Atom, Id}) -> - io_lib:fwrite("id2atom(~p) ->\n ~p", [Id, Atom]) - end, AIds1)), - io:fwrite(Fd, "~s;\nid2atom(Any)->\n Any.\n\n", [Txt]). - -gen_atom2id(Fd, AIds0) -> - AIds1 = lists:keysort(1, AIds0), - Txt = join(";\n", - lists:map( - fun({Atom, Id}) -> - io_lib:fwrite("atom2id(~p) ->\n ~p", [Atom, Id]) - end, AIds1)), - io:fwrite(Fd, "~s;\natom2id(Any)->\n Any.\n\n", [Txt]). - -gen_all(Fd, AIds) -> - Atoms = lists:sort([A || {A, _} <- AIds]), - Ids = lists:sort([I || {_, I} <- AIds]), - F = fun(X) -> io_lib:fwrite(" ~w", [X]) end, - ATxt = "all_atoms() ->\n" ++ join(",\n", lists:map(F, Atoms)), - io:fwrite(Fd, "~s.\n\n", [ATxt]), - ITxt = "all_ids() ->\n" ++ join(",\n", lists:map(F, Ids)), - io:fwrite(Fd, "~s.\n\n", [ITxt]). - -join(Sep, [H1, H2| T]) -> - [H1, Sep| join(Sep, [H2| T])]; -join(_Sep, [H1]) -> - H1; -join(_, []) -> - []. diff --git a/lib/ssl/pkix/prebuild.skip b/lib/ssl/pkix/prebuild.skip deleted file mode 100644 index ffe82be68b..0000000000 --- a/lib/ssl/pkix/prebuild.skip +++ /dev/null @@ -1,5 +0,0 @@ -PKIX1Algorithms88.asn1db -PKIXAttributeCertificate.asn1db -PKIX1Explicit88.asn1db -SSL-PKIX.asn1db -PKIX1Implicit88.asn1db diff --git a/lib/ssl/src/Makefile b/lib/ssl/src/Makefile index fabf8a4e0d..7514ad2aa2 100644 --- a/lib/ssl/src/Makefile +++ b/lib/ssl/src/Makefile @@ -1,19 +1,19 @@ # # %CopyrightBegin% -# -# Copyright Ericsson AB 1999-2009. All Rights Reserved. -# +# +# 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% # @@ -46,9 +46,6 @@ MODULES= \ ssl_server \ ssl_sup \ ssl_prim \ - ssl_pkix \ - ssl_pem \ - ssl_base64 \ inet_ssl_dist \ ssl_certificate\ ssl_certificate_db\ @@ -71,8 +68,6 @@ INTERNAL_HRL_FILES = \ ssl_alert.hrl ssl_cipher.hrl ssl_handshake.hrl ssl_internal.hrl \ ssl_record.hrl -PUBLIC_HRL_FILES = ssl_pkix.hrl - ERL_FILES= $(MODULES:%=%.erl) TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) @@ -85,15 +80,12 @@ APP_TARGET= $(EBIN)/$(APP_FILE) APPUP_SRC= $(APPUP_FILE).src APPUP_TARGET= $(EBIN)/$(APPUP_FILE) -INCLUDE = ../include - # ---------------------------------------------------- # FLAGS # ---------------------------------------------------- EXTRA_ERLC_FLAGS = +warn_unused_vars ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/kernel/src \ -pz $(ERL_TOP)/lib/public_key/ebin \ - -I$(INCLUDE) \ $(EXTRA_ERLC_FLAGS) -DVSN=\"$(VSN)\" @@ -101,7 +93,7 @@ ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/kernel/src \ # Targets # ---------------------------------------------------- -debug opt: $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) $(PUBLIC_HRL_FILES) +debug opt: $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) clean: rm -f $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) @@ -113,9 +105,6 @@ $(APP_TARGET): $(APP_SRC) ../vsn.mk $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk sed -e 's;%VSN%;$(VSN);' $< > $@ -$(PUBLIC_HRL_FILES): - cp -f $(PUBLIC_HRL_FILES) $(INCLUDE) - docs: # ---------------------------------------------------- @@ -126,8 +115,6 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt $(INSTALL_DIR) $(RELSYSDIR)/src $(INSTALL_DATA) $(ERL_FILES) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(PUBLIC_HRL_FILES) $(RELSYSDIR)/include $(INSTALL_DIR) $(RELSYSDIR)/ebin $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) \ $(APPUP_TARGET) $(RELSYSDIR)/ebin diff --git a/lib/ssl/src/ssl.app.src b/lib/ssl/src/ssl.app.src index 2a7d451341..b9716786e6 100644 --- a/lib/ssl/src/ssl.app.src +++ b/lib/ssl/src/ssl.app.src @@ -7,10 +7,6 @@ ssl_server, ssl_broker, ssl_broker_sup, - ssl_base64, - ssl_pem, - ssl_pkix, - ssl_pkix_oid, ssl_prim, inet_ssl_dist, ssl_tls1, @@ -28,11 +24,10 @@ ssl_cipher, ssl_certificate_db, ssl_certificate, - ssl_alert, - 'OTP-PKIX' + ssl_alert ]}, {registered, [ssl_sup, ssl_server, ssl_broker_sup]}, - {applications, [kernel, stdlib]}, + {applications, [crypto, public_key, kernel, stdlib]}, {env, []}, {mod, {ssl_app, []}}]}. diff --git a/lib/ssl/src/ssl.appup.src b/lib/ssl/src/ssl.appup.src index e8ae6846aa..f4e6b59b6d 100644 --- a/lib/ssl/src/ssl.appup.src +++ b/lib/ssl/src/ssl.appup.src @@ -1,26 +1,9 @@ %% -*- erlang -*- {"%VSN%", [ - {"3.10", [{restart_application, ssl}]}, - {"3.10.1", [{restart_application, ssl}]}, - {"3.10.2", [{restart_application, ssl}]}, - {"3.10.3", [{restart_application, ssl}]}, - {"3.10.4", [{restart_application, ssl}]}, - {"3.10.5", [{restart_application, ssl}]}, - {"3.10.6", [{restart_application, ssl}]}, - {"3.10.7", [{restart_application, ssl}]}, - {"3.10.8", [{restart_application, ssl}]}, - {"3.10.9", [{restart_application, ssl}]} + {"4.0.1", [{restart_application, ssl}]} ], [ - {"3.10", [{restart_application, ssl}]}, - {"3.10.1", [{restart_application, ssl}]}, - {"3.10.2", [{restart_application, ssl}]}, - {"3.10.3", [{restart_application, ssl}]}, - {"3.10.4", [{restart_application, ssl}]}, - {"3.10.5", [{restart_application, ssl}]}, - {"3.10.6", [{restart_application, ssl}]}, - {"3.10.8", [{restart_application, ssl}]}, - {"3.10.9", [{restart_application, ssl}]} + {"4.0.1", [{restart_application, ssl}]} ]}. diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl index 3cd4c7fdbd..b4437628c3 100644 --- a/lib/ssl/src/ssl.erl +++ b/lib/ssl/src/ssl.erl @@ -34,10 +34,14 @@ %% Should be deprecated as soon as old ssl is removed %%-deprecated({pid, 1, next_major_release}). +-deprecated({peercert, 2, next_major_release}). -include("ssl_int.hrl"). -include("ssl_internal.hrl"). -include("ssl_record.hrl"). +-include("ssl_cipher.hrl"). + +-include_lib("public_key/include/public_key.hrl"). -record(config, {ssl, %% SSL parameters inet_user, %% User set inet options @@ -47,22 +51,25 @@ }). %%-------------------------------------------------------------------- -%% Function: start([, Type]) -> ok -%% -%% Type = permanent | transient | temporary -%% Vsns = [Vsn] -%% Vsn = ssl3 | tlsv1 | 'tlsv1.1' +-spec start() -> ok. +-spec start(permanent | transient | temporary) -> ok. %% -%% Description: Starts the ssl application. Default type +%% Description: Utility function that starts the ssl, +%% crypto and public_key applications. Default type %% is temporary. see application(3) %%-------------------------------------------------------------------- start() -> + application:start(crypto), + application:start(public_key), application:start(ssl). + start(Type) -> + application:start(crypto, Type), + application:start(public_key, Type), application:start(ssl, Type). %%-------------------------------------------------------------------- -%% Function: stop() -> ok +-spec stop() -> ok. %% %% Description: Stops the ssl application. %%-------------------------------------------------------------------- @@ -70,7 +77,10 @@ stop() -> application:stop(ssl). %%-------------------------------------------------------------------- -%% Function: connect(Address, Port, Options[, Timeout]) -> {ok, Socket} +-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. %%-------------------------------------------------------------------- @@ -96,13 +106,13 @@ connect(Socket, SslOptions0, Timeout) when is_port(Socket) -> {error, Reason} end; -connect(Address, Port, Options) -> - connect(Address, Port, Options, infinity). +connect(Host, Port, Options) -> + connect(Host, Port, Options, infinity). -connect(Address, Port, Options0, Timeout) -> - case proplists:get_value(ssl_imp, Options0, old) of +connect(Host, Port, Options0, Timeout) -> + case proplists:get_value(ssl_imp, Options0, new) of new -> - new_connect(Address, Port, Options0, Timeout); + new_connect(Host, Port, Options0, Timeout); old -> %% Allow the option reuseaddr to be present %% so that new and old ssl can be run by the same @@ -110,20 +120,21 @@ connect(Address, Port, Options0, Timeout) -> %% that hardcodes reuseaddr to true in its portprogram. Options1 = proplists:delete(reuseaddr, Options0), Options = proplists:delete(ssl_imp, Options1), - old_connect(Address, Port, Options, Timeout); + old_connect(Host, Port, Options, Timeout); Value -> {error, {eoptions, {ssl_imp, Value}}} end. %%-------------------------------------------------------------------- -%% Function: listen(Port, Options) -> {ok, ListenSock} | {error, Reason} +-spec listen(port_num(), list()) ->{ok, #sslsocket{}} | {error, reason()}. + %% %% Description: Creates a ssl listen socket. %%-------------------------------------------------------------------- listen(_Port, []) -> {error, enooptions}; listen(Port, Options0) -> - case proplists:get_value(ssl_imp, Options0, old) of + case proplists:get_value(ssl_imp, Options0, new) of new -> new_listen(Port, Options0); old -> @@ -139,7 +150,8 @@ listen(Port, Options0) -> end. %%-------------------------------------------------------------------- -%% Function: transport_accept(ListenSocket[, Timeout]) -> {ok, Socket}. +-spec transport_accept(#sslsocket{}) -> {ok, #sslsocket{}}. +-spec transport_accept(#sslsocket{}, timeout()) -> {ok, #sslsocket{}}. %% %% Description: Performs transport accept on a ssl listen socket %%-------------------------------------------------------------------- @@ -147,14 +159,14 @@ transport_accept(ListenSocket) -> transport_accept(ListenSocket, infinity). transport_accept(#sslsocket{pid = {ListenSocket, #config{cb=CbInfo, ssl=SslOpts}}, - fd = new_ssl} = SslSocket, Timeout) -> + fd = new_ssl}, Timeout) -> %% The setopt could have been invoked on the listen socket %% and options should be inherited. EmOptions = emulated_options(), {ok, InetValues} = inet:getopts(ListenSocket, EmOptions), ok = inet:setopts(ListenSocket, internal_inet_values()), - {CbModule,_,_} = CbInfo, + {CbModule,_,_, _} = CbInfo, case CbModule:accept(ListenSocket, Timeout) of {ok, Socket} -> ok = inet:setopts(ListenSocket, InetValues), @@ -163,8 +175,7 @@ transport_accept(#sslsocket{pid = {ListenSocket, #config{cb=CbInfo, ssl=SslOpts} {SslOpts, socket_options(InetValues)}, self(), CbInfo], case ssl_connection_sup:start_child(ConnArgs) of {ok, Pid} -> - CbModule:controlling_process(Socket, Pid), - {ok, SslSocket#sslsocket{pid = Pid}}; + ssl_connection:socket_control(Socket, Pid, CbModule); {error, Reason} -> {error, Reason} end; @@ -178,8 +189,8 @@ transport_accept(#sslsocket{} = ListenSocket, Timeout) -> ssl_broker:transport_accept(Pid, ListenSocket, Timeout). %%-------------------------------------------------------------------- -%% Function: ssl_accept(ListenSocket[, Timeout]) -> {ok, Socket} | -%% {error, Reason} +-spec ssl_accept(#sslsocket{}) -> {ok, #sslsocket{}} | {error, reason()}. +-spec ssl_accept(#sslsocket{}, timeout()) -> {ok, #sslsocket{}} | {error, reason()}. %% %% Description: Performs accept on a ssl listen socket. e.i. performs %% ssl handshake. @@ -187,22 +198,9 @@ transport_accept(#sslsocket{} = ListenSocket, Timeout) -> ssl_accept(ListenSocket) -> ssl_accept(ListenSocket, infinity). -ssl_accept(#sslsocket{pid = Pid, fd = new_ssl}, Timeout) -> - gen_fsm:send_event(Pid, socket_control), - try gen_fsm:sync_send_all_state_event(Pid, started, Timeout) of - connected -> - ok; - {error, _} = Error -> - Error - catch - exit:{noproc, _} -> - {error, closed}; - exit:{timeout, _} -> - {error, timeout}; - exit:{normal, _} -> - {error, closed} - end; - +ssl_accept(#sslsocket{fd = new_ssl} = Socket, Timeout) -> + ssl_connection:handshake(Socket, Timeout); + ssl_accept(ListenSocket, SslOptions) when is_port(ListenSocket) -> ssl_accept(ListenSocket, SslOptions, infinity); @@ -218,19 +216,19 @@ ssl_accept(Socket, SslOptions, Timeout) when is_port(Socket) -> try handle_options(SslOptions ++ InetValues, server) of {ok, #config{cb=CbInfo,ssl=SslOpts, emulated=EmOpts}} -> {ok, Port} = inet:port(Socket), - ssl_connection:accept(Port, Socket, - {SslOpts, EmOpts}, - self(), CbInfo, Timeout) + ssl_connection:ssl_accept(Port, Socket, + {SslOpts, EmOpts}, + self(), CbInfo, Timeout) catch Error = {error, _Reason} -> Error end. %%-------------------------------------------------------------------- -%% Function: close() -> ok +-spec close(#sslsocket{}) -> term(). %% %% Description: Close a ssl connection %%-------------------------------------------------------------------- -close(#sslsocket{pid = {ListenSocket, #config{cb={CbMod,_, _}}}, fd = new_ssl}) -> +close(#sslsocket{pid = {ListenSocket, #config{cb={CbMod,_, _, _}}}, fd = new_ssl}) -> CbMod:close(ListenSocket); close(#sslsocket{pid = Pid, fd = new_ssl}) -> ssl_connection:close(Pid); @@ -239,7 +237,7 @@ close(Socket = #sslsocket{}) -> ssl_broker:close(Socket). %%-------------------------------------------------------------------- -%% Function: send(Socket, Data) -> ok +-spec send(#sslsocket{}, iolist()) -> ok | {error, reason()}. %% %% Description: Sends data over the ssl connection %%-------------------------------------------------------------------- @@ -251,7 +249,8 @@ send(#sslsocket{} = Socket, Data) -> ssl_broker:send(Socket, Data). %%-------------------------------------------------------------------- -%% Function: recv(Socket, Length [,Timeout]) -> {ok, Data} | {error, reason} +-spec recv(#sslsocket{}, integer()) -> {ok, binary()| list()} | {error, reason()}. +-spec recv(#sslsocket{}, integer(), timeout()) -> {ok, binary()| list()} | {error, reason()}. %% %% Description: Receives data when active = false %%-------------------------------------------------------------------- @@ -265,8 +264,8 @@ recv(Socket = #sslsocket{}, Length, Timeout) -> ssl_broker:recv(Socket, Length, Timeout). %%-------------------------------------------------------------------- -%% Function: controlling_process(Socket, NewOwner) -> ok | {error, Reason} -%% +-spec controlling_process(#sslsocket{}, pid()) -> ok | {error, reason()}. +%% %% Description: Changes process that receives the messages when active = true %% or once. %%-------------------------------------------------------------------- @@ -279,11 +278,8 @@ controlling_process(Socket, NewOwner) when is_pid(NewOwner) -> ssl_broker:controlling_process(Socket, NewOwner). %%-------------------------------------------------------------------- -%% Function: connection_info(Socket) -> {ok, {Protocol, CipherSuite}} | -%% {error, Reason} -%% Protocol = sslv3 | tlsv1 | tlsv1.1 -%% CipherSuite = {KeyExchange, Chipher, Hash, Exportable} -%% +-spec connection_info(#sslsocket{}) -> {ok, {tls_atom_version(), erl_cipher_suite()}} | + {error, reason()}. %% %% Description: Returns ssl protocol and cipher used for the connection %%-------------------------------------------------------------------- @@ -295,9 +291,9 @@ connection_info(#sslsocket{} = Socket) -> ssl_broker:connection_info(Socket). %%-------------------------------------------------------------------- -%% Function: peercert(Socket[, Opts]) -> {ok, Cert} | {error, Reason} +-spec peercert(#sslsocket{}) ->{ok, der_cert()} | {error, reason()}. %% -%% Description: +%% Description: Returns the peercert. %%-------------------------------------------------------------------- peercert(Socket) -> peercert(Socket, []). @@ -307,14 +303,7 @@ peercert(#sslsocket{pid = Pid, fd = new_ssl}, Opts) -> {ok, undefined} -> {error, no_peercert}; {ok, BinCert} -> - PKOpts = [case Opt of ssl -> otp; pkix -> plain end || - Opt <- Opts, Opt =:= ssl orelse Opt =:= pkix], - case PKOpts of - [Opt] -> - public_key:pkix_decode_cert(BinCert, Opt); - [] -> - {ok, BinCert} - end; + decode_peercert(BinCert, Opts); {error, Reason} -> {error, Reason} end; @@ -323,15 +312,44 @@ peercert(#sslsocket{} = Socket, Opts) -> ensure_old_ssl_started(), case ssl_broker:peercert(Socket) of {ok, Bin} -> - ssl_pkix:decode_cert(Bin, Opts); + decode_peercert(Bin, Opts); {error, Reason} -> {error, Reason} end. + +decode_peercert(BinCert, Opts) -> + PKOpts = [case Opt of ssl -> otp; pkix -> plain end || + Opt <- Opts, Opt =:= ssl orelse Opt =:= pkix], + case PKOpts of + [Opt] -> + select_part(Opt, public_key:pkix_decode_cert(BinCert, Opt), Opts); + [] -> + {ok, BinCert} + end. + +select_part(otp, Cert, Opts) -> + case lists:member(subject, Opts) of + true -> + TBS = Cert#'OTPCertificate'.tbsCertificate, + {ok, TBS#'OTPTBSCertificate'.subject}; + false -> + {ok, Cert} + end; + +select_part(plain, Cert, Opts) -> + case lists:member(subject, Opts) of + true -> + TBS = Cert#'Certificate'.tbsCertificate, + {ok, TBS#'TBSCertificate'.subject}; + false -> + {ok, Cert} + end. + %%-------------------------------------------------------------------- -%% Function: peername(Socket) -> {ok, {Address, Port}} | {error, Reason} +-spec peername(#sslsocket{}) -> {ok, {tuple(), port_num()}} | {error, reason()}. %% -%% Description: +%% Description: same as inet:peername/1. %%-------------------------------------------------------------------- peername(#sslsocket{fd = new_ssl, pid = Pid}) -> ssl_connection:peername(Pid); @@ -341,9 +359,10 @@ peername(#sslsocket{} = Socket) -> ssl_broker:peername(Socket). %%-------------------------------------------------------------------- -%% Function: cipher_suites() -> -%% -%% Description: +-spec cipher_suites() -> [erl_cipher_suite()]. +-spec cipher_suites(erlang | openssl) -> [erl_cipher_suite()] | [string()]. + +%% Description: Returns all supported cipher suites. %%-------------------------------------------------------------------- cipher_suites() -> cipher_suites(erlang). @@ -357,7 +376,7 @@ cipher_suites(openssl) -> [ssl_cipher:openssl_suite_name(S) || S <- ssl_cipher:suites(Version)]. %%-------------------------------------------------------------------- -%% Function: getopts(Socket, OptTags) -> {ok, Options} | {error, Reason} +-spec getopts(#sslsocket{}, [atom()]) -> {ok, [{atom(), term()}]}| {error, reason()}. %% %% Description: %%-------------------------------------------------------------------- @@ -370,7 +389,7 @@ getopts(#sslsocket{} = Socket, Options) -> ssl_broker:getopts(Socket, Options). %%-------------------------------------------------------------------- -%% Function: setopts(Socket, Options) -> ok | {error, Reason} +-spec setopts(#sslsocket{}, [{atom(), term()}]) -> ok | {error, reason()}. %% %% Description: %%-------------------------------------------------------------------- @@ -385,18 +404,18 @@ setopts(#sslsocket{} = Socket, Options) -> ssl_broker:setopts(Socket, Options). %%--------------------------------------------------------------- -%% Function: shutdown(Socket, How) -> ok | {error, Reason} -%% +-spec shutdown(#sslsocket{}, read | write | read_write) -> ok | {error, reason()}. +%% %% Description: Same as gen_tcp:shutdown/2 %%-------------------------------------------------------------------- -shutdown(#sslsocket{pid = {ListenSocket, #config{cb={CbMod,_, _}}}, fd = new_ssl}, How) -> +shutdown(#sslsocket{pid = {ListenSocket, #config{cb={CbMod,_, _, _}}}, fd = new_ssl}, How) -> CbMod:shutdown(ListenSocket, How); shutdown(#sslsocket{pid = Pid, fd = new_ssl}, How) -> ssl_connection:shutdown(Pid, How). %%-------------------------------------------------------------------- -%% Function: sockname(Socket) -> {ok, {Address, Port}} | {error, Reason} -%% +-spec sockname(#sslsocket{}) -> {ok, {tuple(), port_num()}} | {error, reason()}. +%% %% Description: Same as inet:sockname/1 %%-------------------------------------------------------------------- sockname(#sslsocket{fd = new_ssl, pid = {ListenSocket, _}}) -> @@ -410,9 +429,9 @@ sockname(#sslsocket{} = Socket) -> ssl_broker:sockname(Socket). %%--------------------------------------------------------------- -%% Function: seed(Data) -> ok | {error, edata} +-spec seed(term()) ->term(). %% -%% Description: +%% Description: Only used by old ssl. %%-------------------------------------------------------------------- %% TODO: crypto:seed ? seed(Data) -> @@ -420,20 +439,17 @@ seed(Data) -> ssl_server:seed(Data). %%--------------------------------------------------------------- -%% Function: session_id(Socket) -> {ok, PropList} | {error, Reason} +-spec session_info(#sslsocket{}) -> {ok, list()} | {error, reason()}. %% -%% Description: +%% Description: Returns list of session info currently [{session_id, session_id(), +%% {cipher_suite, cipher_suite()}] %%-------------------------------------------------------------------- session_info(#sslsocket{pid = Pid, fd = new_ssl}) -> ssl_connection:session_info(Pid). %%--------------------------------------------------------------- -%% Function: versions() -> [{SslAppVer, SupportedSslVer, AvailableSslVsn}] -%% -%% SslAppVer = string() - t.ex: ssl-4.0 -%% SupportedSslVer = [SslVer] -%% AvailableSslVsn = [SSLVer] -%% SSLVer = sslv3 | tlsv1 | 'tlsv1.1' +-spec versions() -> [{ssl_app, string()} | {supported, [tls_atom_version()]} | + {available, [tls_atom_version()]}]. %% %% Description: Returns a list of relevant versions. %%-------------------------------------------------------------------- @@ -444,6 +460,11 @@ versions() -> [{ssl_app, ?VSN}, {supported, SupportedVsns}, {available, AvailableVsns}]. +%%--------------------------------------------------------------- +-spec renegotiate(#sslsocket{}) -> ok | {error, reason()}. +%% +%% Description: +%%-------------------------------------------------------------------- renegotiate(#sslsocket{pid = Pid, fd = new_ssl}) -> ssl_connection:renegotiation(Pid). @@ -463,7 +484,7 @@ do_new_connect(Address, Port, #config{cb=CbInfo, inet_user=UserOpts, ssl=SslOpts, emulated=EmOpts,inet_ssl=SocketOpts}, Timeout) -> - {CbModule, _, _} = CbInfo, + {CbModule, _, _, _} = CbInfo, try CbModule:connect(Address, Port, SocketOpts, Timeout) of {ok, Socket} -> ssl_connection:connect(Address, Port, Socket, {SslOpts,EmOpts}, @@ -485,7 +506,7 @@ old_connect(Address, Port, Options, Timeout) -> new_listen(Port, Options0) -> try {ok, Config} = handle_options(Options0, server), - #config{cb={CbModule, _, _},inet_user=Options} = Config, + #config{cb={CbModule, _, _, _},inet_user=Options} = Config, case CbModule:listen(Port, Options) of {ok, ListenSocket} -> {ok, #sslsocket{pid = {ListenSocket, Config}, fd = new_ssl}}; @@ -502,75 +523,85 @@ 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, + DefaultVerifyNoneFun = + {fun(_,{bad_cert, _}, UserState) -> + {valid, UserState}; + (_,{extension, _}, UserState) -> + {unknown, UserState}; + (_, valid, UserState) -> + {valid, UserState}; + (_, valid_peer, UserState) -> + {valid, UserState} + end, []}, + + VerifyNoneFun = handle_option(verify_fun, Opts, DefaultVerifyNoneFun), - 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), + dh = handle_option(dh, Opts, undefined), dhfile = handle_option(dhfile, Opts, undefined), ciphers = handle_option(ciphers, Opts, []), %% Server side option reuse_session = handle_option(reuse_session, Opts, ReuseSessionFun), reuse_sessions = handle_option(reuse_sessions, Opts, true), + secure_renegotiate = handle_option(secure_renegotiate, Opts, false), renegotiate_at = handle_option(renegotiate_at, Opts, ?DEFAULT_RENEGOTIATE_AT), debug = handle_option(debug, Opts, []) }, - CbInfo = proplists:get_value(cb_info, Opts, {gen_tcp, tcp, tcp_closed}), - SslOptions = [versions, verify, verify_fun, validate_extensions_fun, + CbInfo = proplists:get_value(cb_info, Opts, {gen_tcp, tcp, tcp_closed, tcp_error}), + 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, dh, dhfile, ciphers, debug, reuse_session, reuse_sessions, ssl_imp, - cb_info, renegotiate_at], + cb_info, renegotiate_at, secure_renegotiate], SockOpts = lists:foldl(fun(Key, PropList) -> proplists:delete(Key, PropList) @@ -592,7 +623,25 @@ 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}; + (_, valid, UserState) -> + {valid, UserState}; + (_, valid_peer, UserState) -> + {valid, 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 -> @@ -600,29 +649,38 @@ 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) -> ""; validate_option(cacertfile, Value) when is_list(Value), Value =/= "" -> Value; +validate_option(dh, Value) when Value == undefined; + is_binary(Value) -> + Value; validate_option(dhfile, undefined = Value) -> Value; validate_option(dhfile, Value) when is_list(Value), Value =/= "" -> @@ -641,8 +699,12 @@ validate_option(reuse_session, Value) when is_function(Value) -> validate_option(reuse_sessions, Value) when Value == true; Value == false -> Value; + +validate_option(secure_renegotiate, Value) when Value == true; + Value == false -> + Value; validate_option(renegotiate_at, Value) when is_integer(Value) -> - min(Value, ?DEFAULT_RENEGOTIATE_AT); + erlang:min(Value, ?DEFAULT_RENEGOTIATE_AT); validate_option(debug, Value) when is_list(Value); Value == true -> Value; @@ -676,14 +738,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() -> @@ -727,7 +791,10 @@ emulated_options([], Inet,Emulated) -> cipher_suites(Version, []) -> ssl_cipher:suites(Version); -cipher_suites(Version, [{_,_,_,_}| _] = Ciphers0) -> +cipher_suites(Version, [{_,_,_,_}| _] = Ciphers0) -> %% Backwards compatibility + Ciphers = [{KeyExchange, Cipher, Hash} || {KeyExchange, Cipher, Hash, _} <- Ciphers0], + cipher_suites(Version, Ciphers); +cipher_suites(Version, [{_,_,_}| _] = Ciphers0) -> Ciphers = [ssl_cipher:suite(C) || C <- Ciphers0], cipher_suites(Version, Ciphers); cipher_suites(Version, [Cipher0 | _] = Ciphers0) when is_binary(Cipher0) -> @@ -749,24 +816,34 @@ cipher_suites(Version, Ciphers0) -> format_error({error, Reason}) -> format_error(Reason); +format_error(Reason) when is_list(Reason) -> + Reason; format_error(closed) -> - "Connection closed for the operation in question."; + "The connection is closed"; +format_error(ecacertfile) -> + "Own CA certificate file is invalid."; +format_error(ecertfile) -> + "Own certificate file is invalid."; +format_error(ekeyfile) -> + "Own private key file is invalid."; +format_error(esslaccept) -> + "Server SSL handshake procedure between client and server failed."; +format_error(esslconnect) -> + "Client SSL handshake procedure between client and server failed."; +format_error({eoptions, Options}) -> + lists:flatten(io_lib:format("Error in options list: ~p~n", [Options])); + +%%%%%%%%%%%% START OLD SSL format_error %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% format_error(ebadsocket) -> "Connection not found (internal error)."; format_error(ebadstate) -> "Connection not in connect state (internal error)."; format_error(ebrokertype) -> "Wrong broker type (internal error)."; -format_error(ecacertfile) -> - "Own CA certificate file is invalid."; -format_error(ecertfile) -> - "Own certificate file is invalid."; format_error(echaintoolong) -> "The chain of certificates provided by peer is too long."; format_error(ecipher) -> "Own list of specified ciphers is invalid."; -format_error(ekeyfile) -> - "Own private key file is invalid."; format_error(ekeymismatch) -> "Own private key does not match own certificate."; format_error(enoissuercert) -> @@ -792,10 +869,6 @@ format_error(epeercertinvalid) -> "Certificate provided by peer is invalid."; format_error(eselfsignedcert) -> "Certificate provided by peer is self signed."; -format_error(esslaccept) -> - "Server SSL handshake procedure between client and server failed."; -format_error(esslconnect) -> - "Client SSL handshake procedure between client and server failed."; format_error(esslerrssl) -> "SSL protocol failure. Typically because of a fatal alert from peer."; format_error(ewantconnect) -> @@ -814,6 +887,9 @@ format_error({badcast, _Cast}) -> format_error({badinfo, _Info}) -> "Call not recognized for current mode (active or passive) and state " "of socket."; + +%%%%%%%%%%%%%%%%%% END OLD SSL format_error %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + format_error(Error) -> case (catch inet:format_error(Error)) of "unkknown POSIX" ++ _ -> @@ -825,7 +901,7 @@ format_error(Error) -> end. no_format(Error) -> - io_lib:format("No format string for error: \"~p\" available.", [Error]). + lists:flatten(io_lib:format("No format string for error: \"~p\" available.", [Error])). %% Start old ssl port program if needed. ensure_old_ssl_started() -> @@ -860,10 +936,6 @@ version() -> end, {ok, {SSLVsn, CompVsn, LibVsn}}. -min(N,M) when N < M -> - N; -min(_, M) -> - M. %% Only used to remove exit messages from old ssl %% First is a nonsense clause to provide some diff --git a/lib/ssl/src/ssl_alert.erl b/lib/ssl/src/ssl_alert.erl index d3f9c833f1..eb1228afa4 100644 --- a/lib/ssl/src/ssl_alert.erl +++ b/lib/ssl/src/ssl_alert.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -32,76 +32,87 @@ -export([alert_txt/1, reason_code/2]). +%%==================================================================== +%% Internal application API +%%==================================================================== +%%-------------------------------------------------------------------- +-spec reason_code(#alert{}, client | server) -> closed | esslconnect | + esslaccept | string(). +%% +%% Description: Returns the error reason that will be returned to the +%% user. +%%-------------------------------------------------------------------- + reason_code(#alert{description = ?CLOSE_NOTIFY}, _) -> closed; reason_code(#alert{description = ?HANDSHAKE_FAILURE}, client) -> esslconnect; reason_code(#alert{description = ?HANDSHAKE_FAILURE}, server) -> esslaccept; -reason_code(#alert{description = ?CERTIFICATE_EXPIRED}, _) -> - epeercertexpired; -reason_code(#alert{level = ?FATAL}, _) -> - esslerrssl; reason_code(#alert{description = Description}, _) -> description_txt(Description). +%%-------------------------------------------------------------------- +-spec alert_txt(#alert{}) -> string(). +%% +%% Description: Returns the error string for given alert. +%%-------------------------------------------------------------------- + alert_txt(#alert{level = Level, description = Description, where = {Mod,Line}}) -> Mod ++ ":" ++ integer_to_list(Line) ++ ":" ++ level_txt(Level) ++" "++ description_txt(Description). +%%-------------------------------------------------------------------- +%%% Internal functions +%%-------------------------------------------------------------------- level_txt(?WARNING) -> "Warning:"; level_txt(?FATAL) -> "Fatal error:". description_txt(?CLOSE_NOTIFY) -> - "close_notify"; + "close notify"; description_txt(?UNEXPECTED_MESSAGE) -> - "unexpected_message"; + "unexpected message"; description_txt(?BAD_RECORD_MAC) -> - "bad_record_mac"; + "bad record mac"; description_txt(?DECRYPTION_FAILED) -> - "decryption_failed"; + "decryption failed"; description_txt(?RECORD_OVERFLOW) -> - "record_overflow"; + "record overflow"; description_txt(?DECOMPRESSION_FAILURE) -> - "decompression_failure"; + "decompression failure"; description_txt(?HANDSHAKE_FAILURE) -> - "handshake_failure"; + "handshake failure"; description_txt(?BAD_CERTIFICATE) -> - "bad_certificate"; + "bad certificate"; description_txt(?UNSUPPORTED_CERTIFICATE) -> - "unsupported_certificate"; + "unsupported certificate"; description_txt(?CERTIFICATE_REVOKED) -> - "certificate_revoked"; + "certificate revoked"; description_txt(?CERTIFICATE_EXPIRED) -> - "certificate_expired"; + "certificate expired"; description_txt(?CERTIFICATE_UNKNOWN) -> - "certificate_unknown"; + "certificate unknown"; description_txt(?ILLEGAL_PARAMETER) -> - "illegal_parameter"; + "illegal parameter"; description_txt(?UNKNOWN_CA) -> - "unknown_ca"; + "unknown ca"; description_txt(?ACCESS_DENIED) -> - "access_denied"; + "access denied"; description_txt(?DECODE_ERROR) -> - "decode_error"; + "decode error"; description_txt(?DECRYPT_ERROR) -> - "decrypt_error"; + "decrypt error"; description_txt(?EXPORT_RESTRICTION) -> - "export_restriction"; + "export restriction"; description_txt(?PROTOCOL_VERSION) -> - "protocol_version"; + "protocol version"; description_txt(?INSUFFICIENT_SECURITY) -> - "insufficient_security"; + "insufficient security"; description_txt(?INTERNAL_ERROR) -> - "internal_error"; + "internal error"; description_txt(?USER_CANCELED) -> - "user_canceled"; + "user canceled"; description_txt(?NO_RENEGOTIATION) -> - "no_renegotiation". - - - - - + "no renegotiation". diff --git a/lib/ssl/src/ssl_app.erl b/lib/ssl/src/ssl_app.erl index 6ca1c42631..8d50fd7bdb 100644 --- a/lib/ssl/src/ssl_app.erl +++ b/lib/ssl/src/ssl_app.erl @@ -27,14 +27,16 @@ -export([start/2, stop/1]). -%% start/2(Type, StartArgs) -> {ok, Pid} | {ok, Pid, State} | -%% {error, Reason} -%% +%%-------------------------------------------------------------------- +-spec start(normal | {takeover, node()} | {failover, node()}, list()) -> + ignore | {ok, pid()} | {error, term()}. +%%-------------------------------------------------------------------- start(_Type, _StartArgs) -> ssl_sup:start_link(). -%% stop(State) -> void() -%% +%-------------------------------------------------------------------- +-spec stop(term())-> ok. +%%-------------------------------------------------------------------- stop(_State) -> ok. diff --git a/lib/ssl/src/ssl_base64.erl b/lib/ssl/src/ssl_base64.erl deleted file mode 100644 index cfc42407e8..0000000000 --- a/lib/ssl/src/ssl_base64.erl +++ /dev/null @@ -1,129 +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% -%% - -%% - -%%% Purpose : Base 64 encoding and decoding. - --module(ssl_base64). - --export([encode/1, encode_split/1, decode/1, join_decode/1]). - --define(st(X,A), ((X-A+256) div 256)). --define(CHARS, 64). - -%% A PEM encoding consists of characters A-Z, a-z, 0-9, +, / and -%% =. Each character encodes a 6 bits value from 0 to 63 (A = 0, / = -%% 63); = is a padding character. -%% - -%% -%% encode(Bytes|Binary) -> Chars -%% -%% Take 3 bytes a time (3 x 8 = 24 bits), and make 4 characters out of -%% them (4 x 6 = 24 bits). -%% -encode(Bs) when is_list(Bs) -> - encode(list_to_binary(Bs)); -encode(<<B:3/binary, Bs/binary>>) -> - <<C1:6, C2:6, C3:6, C4:6>> = B, - [enc(C1), enc(C2), enc(C3), enc(C4)| encode(Bs)]; -encode(<<B:2/binary>>) -> - <<C1:6, C2:6, C3:6, _:6>> = <<B/binary, 0>>, - [enc(C1), enc(C2), enc(C3), $=]; -encode(<<B:1/binary>>) -> - <<C1:6, C2:6, _:12>> = <<B/binary, 0, 0>>, - [enc(C1), enc(C2), $=, $=]; -encode(<<>>) -> - []. - -%% -%% encode_split(Bytes|Binary) -> Lines -%% -%% The encoding is divided into lines separated by <NL>, and each line -%% is precisely 64 characters long (excluding the <NL> characters, -%% except the last line which 64 characters long or shorter. <NL> may -%% follow the last line. -%% -encode_split(Bs) -> - split(encode(Bs)). - -%% -%% decode(Chars) -> Binary -%% -decode(Cs) -> - list_to_binary(decode1(Cs)). - -decode1([C1, C2, $=, $=]) -> - <<B1, _:16>> = <<(dec(C1)):6, (dec(C2)):6, 0:12>>, - [B1]; -decode1([C1, C2, C3, $=]) -> - <<B1, B2, _:8>> = <<(dec(C1)):6, (dec(C2)):6, (dec(C3)):6, (dec(0)):6>>, - [B1, B2]; -decode1([C1, C2, C3, C4| Cs]) -> - Bin = <<(dec(C1)):6, (dec(C2)):6, (dec(C3)):6, (dec(C4)):6>>, - [Bin| decode1(Cs)]; -decode1([]) -> - []. - -%% -%% join_decode(Lines) -> Binary -%% -%% Remove <NL> before decoding. -%% -join_decode(Cs) -> - decode(join(Cs)). - -%% -%% Locals -%% - -%% enc/1 and dec/1 -%% -%% Mapping: 0-25 -> A-Z, 26-51 -> a-z, 52-61 -> 0-9, 62 -> +, 63 -> / -%% -enc(C) -> - 65 + C + 6*?st(C,26) - 75*?st(C,52) -15*?st(C,62) + 3*?st(C,63). - -dec(C) -> - 62*?st(C,43) + ?st(C,47) + (C-59)*?st(C,48) - 69*?st(C,65) - 6*?st(C,97). - -%% split encoding into lines -%% -split(Cs) -> - split(Cs, ?CHARS). - -split([], _N) -> - [$\n]; -split(Cs, 0) -> - [$\n| split(Cs, ?CHARS)]; -split([C| Cs], N) -> - [C| split(Cs, N-1)]. - -%% join lines of encodings -%% -join([$\r, $\n| Cs]) -> - join(Cs); -join([$\n| Cs]) -> - join(Cs); -join([C| Cs]) -> - [C| join(Cs)]; -join([]) -> - []. - diff --git a/lib/ssl/src/ssl_certificate.erl b/lib/ssl/src/ssl_certificate.erl index 686e90a70c..a4c54afb27 100644 --- a/lib/ssl/src/ssl_certificate.erl +++ b/lib/ssl/src/ssl_certificate.erl @@ -31,88 +31,152 @@ -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_extension/3, + is_valid_extkey_usage/2, + is_valid_key_usage/2, + select_extension/2, + extensions_list/1, + signature_type/1 + ]). %%==================================================================== %% Internal application API %%==================================================================== -trusted_cert_and_path(CertChain, CertDbRef, Verify) -> - [Cert | RestPath] = lists:reverse(CertChain), - {ok, OtpCert} = public_key:pkix_decode_cert(Cert, otp), - IssuerAnPath = +%%-------------------------------------------------------------------- +-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) -> + Path = [Cert | _] = lists:reverse(CertChain), + OtpCert = public_key:pkix_decode_cert(Cert, otp), + SignedAndIssuerID = case public_key:pkix_is_self_signed(OtpCert) of true -> {ok, IssuerId} = public_key:pkix_issuer_id(OtpCert, self), - {IssuerId, RestPath}; - false -> + {self, IssuerId}; + false -> case public_key:pkix_issuer_id(OtpCert, other) of {ok, IssuerId} -> - {IssuerId, [Cert | RestPath]}; + {other, IssuerId}; {error, issuer_not_found} -> case find_issuer(OtpCert, no_candidate) of {ok, IssuerId} -> - {IssuerId, [Cert | RestPath]}; + {other, 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_certificate_db:lookup_trusted_cert(CertDbRef, - SerialNr, Issuer) of + case SignedAndIssuerID of + {error, issuer_not_found} -> + %% The root CA was not sent and can not be found. + {unknown_ca, Path}; + {self, _} when length(Path) == 1 -> + {selfsigned_peer, 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} | {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]). - -file_to_certificats(File) -> +%%-------------------------------------------------------------------- +-spec file_to_certificats(string()) -> [der_cert()]. +%% +%% Description: Return list of DER encoded certificates. +%%-------------------------------------------------------------------- +file_to_certificats(File) -> {ok, List} = ssl_manager:cache_pem_file(File), - [Bin || {cert, Bin, not_encrypted} <- List]. - - -%% 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) -> + [Bin || {'Certificate', Bin, not_encrypted} <- List]. +%%-------------------------------------------------------------------- +-spec validate_extension(term(), #'Extension'{}, term()) -> {valid, term()} | + {fail, tuple()} | + {unknown, term()}. +%% +%% Description: Validates ssl/tls specific extensions +%%-------------------------------------------------------------------- +validate_extension(_,{extension, #'Extension'{extnID = ?'id-ce-extKeyUsage', + extnValue = KeyUse}}, 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_extension(_, {bad_cert, _} = Reason, _) -> + {fail, Reason}; +validate_extension(_, {extension, _}, Role) -> + {unknown, Role}; +validate_extension(_, valid, Role) -> + {valid, Role}; +validate_extension(_, valid_peer, Role) -> + {valid, Role}. + +%%-------------------------------------------------------------------- +-spec is_valid_key_usage(list(), term()) -> boolean(). +%% +%% Description: Checks if Use is a valid key usage. +%%-------------------------------------------------------------------- +is_valid_key_usage(KeyUse, Use) -> + lists:member(Use, KeyUse). + +%%-------------------------------------------------------------------- +-spec select_extension(term(), list()) -> undefined | #'Extension'{}. +%% +%% Description: Selects the extension identified by Id if present in +%% a list of extensions. +%%-------------------------------------------------------------------- +select_extension(_, []) -> + undefined; +select_extension(Id, [#'Extension'{extnID = Id} = Extension | _]) -> + Extension; +select_extension(Id, [_ | Extensions]) -> + select_extension(Id, Extensions). + +%%-------------------------------------------------------------------- +-spec extensions_list(asn1_NOVALUE | list()) -> list(). +%% +%% Description: Handles that +%%-------------------------------------------------------------------- +extensions_list(asn1_NOVALUE) -> + []; +extensions_list(Extensions) -> + Extensions. + +%%-------------------------------------------------------------------- +-spec signature_type(term()) -> rsa | dsa . +%% +%% Description: +%%-------------------------------------------------------------------- +signature_type(RSA) when RSA == ?sha1WithRSAEncryption; + RSA == ?md5WithRSAEncryption -> + rsa; +signature_type(?'id-dsa-with-sha1') -> + dsa. -validate_extensions([Extension | Rest], ValidationState, UnknownExtensions, - Verify, AccErr, Role) -> - validate_extensions(Rest, ValidationState, [Extension | UnknownExtensions], - Verify, AccErr, Role). - %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- @@ -148,10 +212,10 @@ certificate_chain(_CertsDbRef, Chain, _SerialNr, _Issuer, true) -> {ok, lists:reverse(Chain)}; certificate_chain(CertsDbRef, Chain, SerialNr, Issuer, _SelfSigned) -> - case ssl_certificate_db:lookup_trusted_cert(CertsDbRef, + 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]); _ -> @@ -164,7 +228,7 @@ certificate_chain(CertsDbRef, Chain, SerialNr, Issuer, _SelfSigned) -> end. find_issuer(OtpCert, PrevCandidateKey) -> - case ssl_certificate_db:issuer_candidate(PrevCandidateKey) of + case ssl_manager:issuer_candidate(PrevCandidateKey) of no_more_candidates -> {error, issuer_not_found}; {Key, {_Cert, ErlCertCandidate}} -> @@ -176,22 +240,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'). - -is_valid_key_usage(KeyUse, Use) -> - lists:member(Use, KeyUse). - -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 b8c3c6f6b7..7d50c30d47 100644 --- a/lib/ssl/src/ssl_certificate_db.erl +++ b/lib/ssl/src/ssl_certificate_db.erl @@ -22,7 +22,7 @@ %%---------------------------------------------------------------------- -module(ssl_certificate_db). - +-include("ssl_internal.hrl"). -include_lib("public_key/include/public_key.hrl"). -export([create/0, remove/1, add_trusted_certs/3, @@ -34,8 +34,7 @@ %%==================================================================== %%-------------------------------------------------------------------- -%% Function: create() -> Db -%% Db = term() - Reference to the crated database +-spec create() -> certdb_ref(). %% %% Description: Creates a new certificate db. %% Note: lookup_trusted_cert/3 may be called from any process but only @@ -47,8 +46,7 @@ create() -> ets:new(ssl_pid_to_file, [bag, private])]. %%-------------------------------------------------------------------- -%% Function: delete(Db) -> _ -%% Db = Database refererence as returned by create/0 +-spec remove(certdb_ref()) -> term(). %% %% Description: Removes database db %%-------------------------------------------------------------------- @@ -56,11 +54,9 @@ remove(Dbs) -> lists:foreach(fun(Db) -> true = ets:delete(Db) end, Dbs). %%-------------------------------------------------------------------- -%% Function: lookup_trusted_cert(Ref, SerialNumber, Issuer) -> {BinCert,DecodedCert} -%% Ref = ref() -%% SerialNumber = integer() -%% Issuer = {rdnSequence, IssuerAttrs} -%% BinCert = binary() +-spec lookup_trusted_cert(reference(), serialnumber(), issuer()) -> + undefined | {ok, {der_cert(), #'OTPCertificate'{}}}. + %% %% Description: Retrives the trusted certificate identified by %% <SerialNumber, Issuer>. Ref is used as it is specified @@ -78,16 +74,16 @@ lookup_cached_certs(File) -> ets:lookup(certificate_db_name(), {file, File}). %%-------------------------------------------------------------------- -%% Function: add_trusted_certs(Pid, File, Db) -> {ok, Ref} -%% Pid = pid() -%% File = string() -%% Db = Database refererence as returned by create/0 -%% Ref = 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 -> @@ -101,20 +97,21 @@ add_trusted_certs(Pid, File, [CertsDb, FileToRefDb, PidToFileDb]) -> end, insert(Pid, File, PidToFileDb), {ok, Ref}. - %%-------------------------------------------------------------------- -%% Function: cache_pem_file(Pid, File, Db) -> FileContent +-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}. %%-------------------------------------------------------------------- -%% Function: remove_trusted_certs(Pid, Db) -> _ +-spec remove_trusted_certs(pid(), certdb_ref()) -> term(). + %% %% Description: Removes trusted certs originating from %% the file associated to Pid from the runtime database. @@ -144,15 +141,13 @@ remove_trusted_certs(Pid, [CertsDb, FileToRefDb, PidToFileDb]) -> end. %%-------------------------------------------------------------------- -%% Function: issuer_candidate() -> {Key, Candidate} | no_more_candidates +-spec issuer_candidate(no_candidate | cert_key() | {file, term()}) -> + {cert_key(),{der_cert(), #'OTPCertificate'{}}} | no_more_candidates. %% -%% Candidate -%% -%% %% 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(), @@ -210,15 +205,27 @@ 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) -> + try 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) + catch + error:_ -> + Report = io_lib:format("SSL WARNING: Ignoring a CA cert as " + "it could not be correctly decoded.~n", []), + error_logger:info_report(Report) + end. + diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl index 3d3d11b7f3..8230149304 100644 --- a/lib/ssl/src/ssl_cipher.erl +++ b/lib/ssl/src/ssl_cipher.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -28,27 +28,26 @@ -include("ssl_internal.hrl"). -include("ssl_record.hrl"). -include("ssl_cipher.hrl"). +-include("ssl_alert.hrl"). -include("ssl_debug.hrl"). +-include_lib("public_key/include/public_key.hrl"). -export([security_parameters/2, suite_definition/1, - decipher/4, cipher/4, + decipher/5, cipher/4, suite/1, suites/1, - openssl_suite/1, openssl_suite_name/1]). + openssl_suite/1, openssl_suite_name/1, filter/2]). -compile(inline). %%-------------------------------------------------------------------- -%% Function: security_parameters(CipherSuite, SecParams) -> -%% #security_parameters{} -%% -%% CipherSuite - as defined in ssl_cipher.hrl -%% SecParams - #security_parameters{} +-spec security_parameters(cipher_suite(), #security_parameters{}) -> + #security_parameters{}. %% %% Description: Returns a security parameters record where the %% cipher values has been updated according to <CipherSuite> %%------------------------------------------------------------------- security_parameters(CipherSuite, SecParams) -> - { _, Cipher, Hash, Exportable} = suite_definition(CipherSuite), + { _, Cipher, Hash} = suite_definition(CipherSuite), SecParams#security_parameters{ cipher_suite = CipherSuite, bulk_cipher_algorithm = bulk_cipher_algorithm(Cipher), @@ -58,19 +57,14 @@ security_parameters(CipherSuite, SecParams) -> key_material_length = key_material(Cipher), iv_size = iv_size(Cipher), mac_algorithm = mac_algorithm(Hash), - hash_size = hash_size(Hash), - exportable = Exportable}. + hash_size = hash_size(Hash)}. %%-------------------------------------------------------------------- -%% Function: cipher(Method, CipherState, Mac, Data) -> -%% {Encrypted, UpdateCipherState} +-spec cipher(cipher_enum(), #cipher_state{}, binary(), binary()) -> + {binary(), #cipher_state{}}. %% -%% Method - integer() (as defined in ssl_cipher.hrl) -%% CipherState, UpdatedCipherState - #cipher_state{} -%% Data, Encrypted - binary() -%% -%% Description: Encrypts the data and the mac using method, updating -%% the cipher state +%% Description: Encrypts the data and the MAC using chipher described +%% by cipher_enum() and updating the cipher state %%------------------------------------------------------------------- cipher(?NULL, CipherState, <<>>, Fragment) -> GenStreamCipherList = [Fragment, <<>>], @@ -91,10 +85,10 @@ cipher(?DES, CipherState, Mac, Fragment) -> block_cipher(fun(Key, IV, T) -> crypto:des_cbc_encrypt(Key, IV, T) end, block_size(des_cbc), CipherState, Mac, Fragment); -cipher(?DES40, CipherState, Mac, Fragment) -> - block_cipher(fun(Key, IV, T) -> - crypto:des_cbc_encrypt(Key, IV, T) - end, block_size(des_cbc), CipherState, Mac, Fragment); +%% cipher(?DES40, CipherState, Mac, Fragment) -> +%% block_cipher(fun(Key, IV, T) -> +%% crypto:des_cbc_encrypt(Key, IV, T) +%% end, block_size(des_cbc), CipherState, Mac, Fragment); cipher(?'3DES', CipherState, Mac, Fragment) -> block_cipher(fun(<<K1:8/binary, K2:8/binary, K3:8/binary>>, IV, T) -> crypto:des3_cbc_encrypt(K1, K2, K3, IV, T) @@ -104,15 +98,11 @@ cipher(?AES, CipherState, Mac, Fragment) -> crypto:aes_cbc_128_encrypt(Key, IV, T); (Key, IV, T) when byte_size(Key) =:= 32 -> crypto:aes_cbc_256_encrypt(Key, IV, T) - end, block_size(aes_128_cbc), CipherState, Mac, Fragment); + end, block_size(aes_128_cbc), CipherState, Mac, Fragment). %% cipher(?IDEA, CipherState, Mac, Fragment) -> %% block_cipher(fun(Key, IV, T) -> %% crypto:idea_cbc_encrypt(Key, IV, T) %% end, block_size(idea_cbc), CipherState, Mac, Fragment); -cipher(?RC2, CipherState, Mac, Fragment) -> - block_cipher(fun(Key, IV, T) -> - crypto:rc2_40_cbc_encrypt(Key, IV, T) - end, block_size(rc2_cbc_40), CipherState, Mac, Fragment). block_cipher(Fun, BlockSz, #cipher_state{key=Key, iv=IV} = CS0, Mac, Fragment) -> @@ -128,19 +118,15 @@ block_cipher(Fun, BlockSz, #cipher_state{key=Key, iv=IV} = CS0, {T, CS0#cipher_state{iv=NextIV}}. %%-------------------------------------------------------------------- -%% Function: decipher(Method, CipherState, Mac, Data) -> -%% {Decrypted, UpdateCipherState} +-spec decipher(cipher_enum(), integer(), #cipher_state{}, binary(), tls_version()) -> + {binary(), binary(), #cipher_state{}} | #alert{}. %% -%% Method - integer() (as defined in ssl_cipher.hrl) -%% CipherState, UpdatedCipherState - #cipher_state{} -%% Data, Encrypted - binary() -%% -%% Description: Decrypts the data and the mac using method, updating -%% the cipher state +%% Description: Decrypts the data and the MAC using cipher described +%% by cipher_enum() and updating the cipher state. %%------------------------------------------------------------------- -decipher(?NULL, _HashSz, CipherState, Fragment) -> +decipher(?NULL, _HashSz, CipherState, Fragment, _) -> {Fragment, <<>>, CipherState}; -decipher(?RC4, HashSz, CipherState, Fragment) -> +decipher(?RC4, HashSz, CipherState, Fragment, _) -> ?DBG_TERM(CipherState#cipher_state.key), State0 = case CipherState#cipher_state.state of undefined -> crypto:rc4_set_key(CipherState#cipher_state.key); @@ -153,52 +139,49 @@ decipher(?RC4, HashSz, CipherState, Fragment) -> GSC = generic_stream_cipher_from_bin(T, HashSz), #generic_stream_cipher{content=Content, mac=Mac} = GSC, {Content, Mac, CipherState#cipher_state{state=State1}}; -decipher(?DES, HashSz, CipherState, Fragment) -> - block_decipher(fun(Key, IV, T) -> - crypto:des_cbc_decrypt(Key, IV, T) - end, CipherState, HashSz, Fragment); -decipher(?DES40, HashSz, CipherState, Fragment) -> +decipher(?DES, HashSz, CipherState, Fragment, Version) -> block_decipher(fun(Key, IV, T) -> crypto:des_cbc_decrypt(Key, IV, T) - end, CipherState, HashSz, Fragment); -decipher(?'3DES', HashSz, CipherState, Fragment) -> + end, CipherState, HashSz, Fragment, Version); +%% decipher(?DES40, HashSz, CipherState, Fragment, Version) -> +%% block_decipher(fun(Key, IV, T) -> +%% crypto:des_cbc_decrypt(Key, IV, T) +%% end, CipherState, HashSz, Fragment, Version); +decipher(?'3DES', HashSz, CipherState, Fragment, Version) -> block_decipher(fun(<<K1:8/binary, K2:8/binary, K3:8/binary>>, IV, T) -> crypto:des3_cbc_decrypt(K1, K2, K3, IV, T) - end, CipherState, HashSz, Fragment); -decipher(?AES, HashSz, CipherState, Fragment) -> + end, CipherState, HashSz, Fragment, Version); +decipher(?AES, HashSz, CipherState, Fragment, Version) -> block_decipher(fun(Key, IV, T) when byte_size(Key) =:= 16 -> crypto:aes_cbc_128_decrypt(Key, IV, T); (Key, IV, T) when byte_size(Key) =:= 32 -> crypto:aes_cbc_256_decrypt(Key, IV, T) - end, CipherState, HashSz, Fragment); -%% decipher(?IDEA, HashSz, CipherState, Fragment) -> + end, CipherState, HashSz, Fragment, Version). +%% decipher(?IDEA, HashSz, CipherState, Fragment, Version) -> %% block_decipher(fun(Key, IV, T) -> %% crypto:idea_cbc_decrypt(Key, IV, T) -%% end, CipherState, HashSz, Fragment); -decipher(?RC2, HashSz, CipherState, Fragment) -> - block_decipher(fun(Key, IV, T) -> - crypto:rc2_40_cbc_decrypt(Key, IV, T) - end, CipherState, HashSz, Fragment). +%% end, CipherState, HashSz, Fragment, Version); block_decipher(Fun, #cipher_state{key=Key, iv=IV} = CipherState0, - HashSz, Fragment) -> + HashSz, Fragment, Version) -> ?DBG_HEX(Key), ?DBG_HEX(IV), ?DBG_HEX(Fragment), T = Fun(Key, IV, Fragment), ?DBG_HEX(T), GBC = generic_block_cipher_from_bin(T, HashSz), - ok = check_padding(GBC), %% TODO kolla ocks�... - Content = GBC#generic_block_cipher.content, - Mac = GBC#generic_block_cipher.mac, - CipherState1 = CipherState0#cipher_state{iv=next_iv(Fragment, IV)}, - {Content, Mac, CipherState1}. - + case is_correct_padding(GBC, Version) of + true -> + Content = GBC#generic_block_cipher.content, + Mac = GBC#generic_block_cipher.mac, + CipherState1 = CipherState0#cipher_state{iv=next_iv(Fragment, IV)}, + {Content, Mac, CipherState1}; + false -> + ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC) + end. + %%-------------------------------------------------------------------- -%% Function: suites(Version) -> [Suite] -%% -%% Version = version() -%% Suite = binary() from ssl_cipher.hrl +-spec suites(tls_version()) -> [cipher_suite()]. %% %% Description: Returns a list of supported cipher suites. %%-------------------------------------------------------------------- @@ -208,294 +191,112 @@ suites({3, N}) when N == 1; N == 2 -> ssl_tls1:suites(). %%-------------------------------------------------------------------- -%% Function: suite_definition(CipherSuite) -> -%% {KeyExchange, Cipher, Hash, Exportable} -%% -%% -%% CipherSuite - as defined in ssl_cipher.hrl -%% KeyExchange - rsa | dh_dss | dh_rsa | dh_anon | dhe_dss | dhe_rsa -%% krb5 | *_export (old ssl) -%% Cipher - null | rc4_128 | idea_cbc | des_cbc | '3des_ede_cbc' -%% des40_cbc | dh_dss | aes_128_cbc | aes_256_cbc | -%% rc2_cbc_40 | rc4_40 -%% Hash - null | md5 | sha -%% Exportable - export | no_export | ignore(?) +-spec suite_definition(cipher_suite()) -> erl_cipher_suite(). %% -%% Description: Returns a security parameters record where the -%% cipher values has been updated according to <CipherSuite> -%% Note: since idea is unsupported on the openssl version used by -%% crypto (as of OTP R12B), we've commented away the idea stuff +%% Description: Return erlang cipher suite definition. +%% Note: Currently not supported suites are commented away. +%% They should be supported or removed in the future. %%------------------------------------------------------------------- %% TLS v1.1 suites suite_definition(?TLS_NULL_WITH_NULL_NULL) -> - {null, null, null, ignore}; -suite_definition(?TLS_RSA_WITH_NULL_MD5) -> - {rsa, null, md5, ignore}; -suite_definition(?TLS_RSA_WITH_NULL_SHA) -> - {rsa, null, sha, ignore}; -suite_definition(?TLS_RSA_WITH_RC4_128_MD5) -> % ok - {rsa, rc4_128, md5, no_export}; -suite_definition(?TLS_RSA_WITH_RC4_128_SHA) -> % ok - {rsa, rc4_128, sha, no_export}; -%% suite_definition(?TLS_RSA_WITH_IDEA_CBC_SHA) -> % unsupported -%% {rsa, idea_cbc, sha, no_export}; -suite_definition(?TLS_RSA_WITH_DES_CBC_SHA) -> % ok - {rsa, des_cbc, sha, no_export}; + {null, null, null}; +%% suite_definition(?TLS_RSA_WITH_NULL_MD5) -> +%% {rsa, null, md5}; +%% suite_definition(?TLS_RSA_WITH_NULL_SHA) -> +%% {rsa, null, sha}; +suite_definition(?TLS_RSA_WITH_RC4_128_MD5) -> + {rsa, rc4_128, md5}; +suite_definition(?TLS_RSA_WITH_RC4_128_SHA) -> + {rsa, rc4_128, sha}; +%% suite_definition(?TLS_RSA_WITH_IDEA_CBC_SHA) -> +%% {rsa, idea_cbc, sha}; +suite_definition(?TLS_RSA_WITH_DES_CBC_SHA) -> + {rsa, des_cbc, sha}; suite_definition(?TLS_RSA_WITH_3DES_EDE_CBC_SHA) -> - {rsa, '3des_ede_cbc', sha, no_export}; -suite_definition(?TLS_DH_DSS_WITH_DES_CBC_SHA) -> - {dh_dss, des_cbc, sha, no_export}; -suite_definition(?TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA) -> - {dh_dss, '3des_ede_cbc', sha, no_export}; -suite_definition(?TLS_DH_RSA_WITH_DES_CBC_SHA) -> - {dh_rsa, des_cbc, sha, no_export}; -suite_definition(?TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA) -> - {dh_rsa, '3des_ede_cbc', sha, no_export}; + {rsa, '3des_ede_cbc', sha}; suite_definition(?TLS_DHE_DSS_WITH_DES_CBC_SHA) -> - {dhe_dss, des_cbc, sha, no_export}; + {dhe_dss, des_cbc, sha}; suite_definition(?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA) -> - {dhe_dss, '3des_ede_cbc', sha, no_export}; + {dhe_dss, '3des_ede_cbc', sha}; suite_definition(?TLS_DHE_RSA_WITH_DES_CBC_SHA) -> - {dhe_rsa, des_cbc, sha, no_export}; + {dhe_rsa, des_cbc, sha}; suite_definition(?TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA) -> - {dhe_rsa, '3des_ede_cbc', sha, no_export}; -suite_definition(?TLS_DH_anon_WITH_RC4_128_MD5) -> - {dh_anon, rc4_128, md5, no_export}; -suite_definition(?TLS_DH_anon_WITH_DES_CBC_SHA) -> - {dh_anon, des40_cbc, sha, no_export}; -suite_definition(?TLS_DH_anon_WITH_3DES_EDE_CBC_SHA) -> - {dh_anon, '3des_ede_cbc', sha, no_export}; + {dhe_rsa, '3des_ede_cbc', sha}; %%% TSL V1.1 AES suites -suite_definition(?TLS_RSA_WITH_AES_128_CBC_SHA) -> % ok - {rsa, aes_128_cbc, sha, ignore}; -suite_definition(?TLS_DH_DSS_WITH_AES_128_CBC_SHA) -> - {dh_dss, aes_128_cbc, sha, ignore}; -suite_definition(?TLS_DH_RSA_WITH_AES_128_CBC_SHA) -> - {dh_rsa, aes_128_cbc, sha, ignore}; +suite_definition(?TLS_RSA_WITH_AES_128_CBC_SHA) -> + {rsa, aes_128_cbc, sha}; suite_definition(?TLS_DHE_DSS_WITH_AES_128_CBC_SHA) -> - {dhe_dss, aes_128_cbc, sha, ignore}; + {dhe_dss, aes_128_cbc, sha}; suite_definition(?TLS_DHE_RSA_WITH_AES_128_CBC_SHA) -> - {dhe_rsa, aes_128_cbc, sha, ignore}; -suite_definition(?TLS_DH_anon_WITH_AES_128_CBC_SHA) -> - {dh_anon, aes_128_cbc, sha, ignore}; -suite_definition(?TLS_RSA_WITH_AES_256_CBC_SHA) -> % ok - {rsa, aes_256_cbc, sha, ignore}; -suite_definition(?TLS_DH_DSS_WITH_AES_256_CBC_SHA) -> - {dh_dss, aes_256_cbc, sha, ignore}; -suite_definition(?TLS_DH_RSA_WITH_AES_256_CBC_SHA) -> - {dh_rsa, aes_256_cbc, sha, ignore}; + {dhe_rsa, aes_128_cbc, sha}; +suite_definition(?TLS_RSA_WITH_AES_256_CBC_SHA) -> + {rsa, aes_256_cbc, sha}; suite_definition(?TLS_DHE_DSS_WITH_AES_256_CBC_SHA) -> - {dhe_dss, aes_256_cbc, sha, ignore}; + {dhe_dss, aes_256_cbc, sha}; suite_definition(?TLS_DHE_RSA_WITH_AES_256_CBC_SHA) -> - {dhe_rsa, aes_256_cbc, sha, ignore}; -suite_definition(?TLS_DH_anon_WITH_AES_256_CBC_SHA) -> - {dh_anon, aes_256_cbc, sha, ignore}; - -%% TSL V1.1 KRB SUITES -suite_definition(?TLS_KRB5_WITH_DES_CBC_SHA) -> - {krb5, des_cbc, sha, ignore}; -suite_definition(?TLS_KRB5_WITH_3DES_EDE_CBC_SHA) -> - {krb5, '3des_ede_cbc', sha, ignore}; -suite_definition(?TLS_KRB5_WITH_RC4_128_SHA) -> - {krb5, rc4_128, sha, ignore}; -%% suite_definition(?TLS_KRB5_WITH_IDEA_CBC_SHA) -> -%% {krb5, idea_cbc, sha, ignore}; -suite_definition(?TLS_KRB5_WITH_DES_CBC_MD5) -> - {krb5, des_cbc, md5, ignore}; -suite_definition(?TLS_KRB5_WITH_3DES_EDE_CBC_MD5) -> - {krb5, '3des_ede_cbc', md5, ignore}; -suite_definition(?TLS_KRB5_WITH_RC4_128_MD5) -> - {krb5, rc4_128, md5, ignore}; -%% suite_definition(?TLS_KRB5_WITH_IDEA_CBC_MD5) -> -%% {krb5, idea_cbc, md5, ignore}; - -suite_definition(?TLS_RSA_EXPORT1024_WITH_RC4_56_MD5) -> - {rsa, rc4_56, md5, export}; -suite_definition(?TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5) -> - {rsa, rc2_cbc_56, md5, export}; -suite_definition(?TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA) -> - {rsa, des_cbc, sha, export}; -suite_definition(?TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA) -> - {dhe_dss, des_cbc, sha, export}; -suite_definition(?TLS_RSA_EXPORT1024_WITH_RC4_56_SHA) -> - {rsa, rc4_56, sha, export}; -suite_definition(?TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA) -> - {dhe_dss, rc4_56, sha, export}; -suite_definition(?TLS_DHE_DSS_WITH_RC4_128_SHA) -> - {dhe_dss, rc4_128, sha, export}; - -%% Export suites TLS 1.0 OR SSLv3-only servers. -suite_definition(?TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA) -> - {krb5_export, des40_cbc, sha, export}; -suite_definition(?TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA) -> - {krb5_export, rc2_cbc_40, sha, export}; -suite_definition(?TLS_KRB5_EXPORT_WITH_RC4_40_SHA) -> - {krb5_export, des40_cbc, sha, export}; -suite_definition(?TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5) -> - {krb5_export, des40_cbc, md5, export}; -suite_definition(?TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5) -> - {krb5_export, rc2_cbc_40, md5, export}; -suite_definition(?TLS_KRB5_EXPORT_WITH_RC4_40_MD5) -> - {krb5_export, rc2_cbc_40, md5, export}; -suite_definition(?TLS_RSA_EXPORT_WITH_RC4_40_MD5) -> % ok - {rsa, rc4_40, md5, export}; -suite_definition(?TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5) -> % ok - {rsa, rc2_cbc_40, md5, export}; -suite_definition(?TLS_RSA_EXPORT_WITH_DES40_CBC_SHA) -> - {rsa, des40_cbc, sha, export}; -suite_definition(?TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA) -> - {dh_dss, des40_cbc, sha, export}; -suite_definition(?TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA) -> - {dh_rsa, des40_cbc, sha, export}; -suite_definition(?TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA) -> - {dhe_dss, des40_cbc, sha, export}; -suite_definition(?TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA) -> - {dhe_rsa, des40_cbc, sha, export}; -suite_definition(?TLS_DH_anon_EXPORT_WITH_RC4_40_MD5) -> - {dh_anon, rc4_40, md5, export}; -suite_definition(?TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA) -> - {dh_anon, des40_cbc, sha, export}. + {dhe_rsa, aes_256_cbc, sha}. + +%%-------------------------------------------------------------------- +-spec suite(erl_cipher_suite()) -> cipher_suite(). +%% +%% Description: Return TLS cipher suite definition. +%%-------------------------------------------------------------------- %% TLS v1.1 suites -suite({rsa, null, md5, ignore}) -> - ?TLS_RSA_WITH_NULL_MD5; -suite({rsa, null, sha, ignore}) -> - ?TLS_RSA_WITH_NULL_SHA; -suite({rsa, rc4_128, md5, no_export}) -> +%%suite({rsa, null, md5}) -> +%% ?TLS_RSA_WITH_NULL_MD5; +%%suite({rsa, null, sha}) -> +%% ?TLS_RSA_WITH_NULL_SHA; +suite({rsa, rc4_128, md5}) -> ?TLS_RSA_WITH_RC4_128_MD5; -suite({rsa, rc4_128, sha, no_export}) -> +suite({rsa, rc4_128, sha}) -> ?TLS_RSA_WITH_RC4_128_SHA; -%% suite({rsa, idea_cbc, sha, no_export}) -> +%% suite({rsa, idea_cbc, sha}) -> %% ?TLS_RSA_WITH_IDEA_CBC_SHA; -suite({rsa, des_cbc, sha, no_export}) -> +suite({rsa, des_cbc, sha}) -> ?TLS_RSA_WITH_DES_CBC_SHA; -suite({rsa, '3des_ede_cbc', sha, no_export}) -> +suite({rsa, '3des_ede_cbc', sha}) -> ?TLS_RSA_WITH_3DES_EDE_CBC_SHA; -suite({dh_dss, des_cbc, sha, no_export}) -> - ?TLS_DH_DSS_WITH_DES_CBC_SHA; -suite({dh_dss, '3des_ede_cbc', sha, no_export}) -> - ?TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA; -suite({dh_rsa, des_cbc, sha, no_export}) -> - ?TLS_DH_RSA_WITH_DES_CBC_SHA; -suite({dh_rsa, '3des_ede_cbc', sha, no_export}) -> - ?TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA; -suite({dhe_dss, des_cbc, sha, no_export}) -> +suite({dhe_dss, des_cbc, sha}) -> ?TLS_DHE_DSS_WITH_DES_CBC_SHA; -suite({dhe_dss, '3des_ede_cbc', sha, no_export}) -> +suite({dhe_dss, '3des_ede_cbc', sha}) -> ?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA; -suite({dhe_rsa, des_cbc, sha, no_export}) -> +suite({dhe_rsa, des_cbc, sha}) -> ?TLS_DHE_RSA_WITH_DES_CBC_SHA; -suite({dhe_rsa, '3des_ede_cbc', sha, no_export}) -> +suite({dhe_rsa, '3des_ede_cbc', sha}) -> ?TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA; -suite({dh_anon, rc4_128, md5, no_export}) -> - ?TLS_DH_anon_WITH_RC4_128_MD5; -suite({dh_anon, des40_cbc, sha, no_export}) -> - ?TLS_DH_anon_WITH_DES_CBC_SHA; -suite({dh_anon, '3des_ede_cbc', sha, no_export}) -> - ?TLS_DH_anon_WITH_3DES_EDE_CBC_SHA; +%% suite({dh_anon, rc4_128, md5}) -> +%% ?TLS_DH_anon_WITH_RC4_128_MD5; +%% suite({dh_anon, des40_cbc, sha}) -> +%% ?TLS_DH_anon_WITH_DES_CBC_SHA; +%% suite({dh_anon, '3des_ede_cbc', sha}) -> +%% ?TLS_DH_anon_WITH_3DES_EDE_CBC_SHA; %%% TSL V1.1 AES suites -suite({rsa, aes_128_cbc, sha, ignore}) -> +suite({rsa, aes_128_cbc, sha}) -> ?TLS_RSA_WITH_AES_128_CBC_SHA; -suite({dh_dss, aes_128_cbc, sha, ignore}) -> - ?TLS_DH_DSS_WITH_AES_128_CBC_SHA; -suite({dh_rsa, aes_128_cbc, sha, ignore}) -> - ?TLS_DH_RSA_WITH_AES_128_CBC_SHA; -suite({dhe_dss, aes_128_cbc, sha, ignore}) -> +suite({dhe_dss, aes_128_cbc, sha}) -> ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA; -suite({dhe_rsa, aes_128_cbc, sha, ignore}) -> +suite({dhe_rsa, aes_128_cbc, sha}) -> ?TLS_DHE_RSA_WITH_AES_128_CBC_SHA; -suite({dh_anon, aes_128_cbc, sha, ignore}) -> - ?TLS_DH_anon_WITH_AES_128_CBC_SHA; -suite({rsa, aes_256_cbc, sha, ignore}) -> +%% suite({dh_anon, aes_128_cbc, sha}) -> +%% ?TLS_DH_anon_WITH_AES_128_CBC_SHA; +suite({rsa, aes_256_cbc, sha}) -> ?TLS_RSA_WITH_AES_256_CBC_SHA; -suite({dh_dss, aes_256_cbc, sha, ignore}) -> - ?TLS_DH_DSS_WITH_AES_256_CBC_SHA; -suite({dh_rsa, aes_256_cbc, sha, ignore}) -> - ?TLS_DH_RSA_WITH_AES_256_CBC_SHA; -suite({dhe_dss, aes_256_cbc, sha, ignore}) -> +suite({dhe_dss, aes_256_cbc, sha}) -> ?TLS_DHE_DSS_WITH_AES_256_CBC_SHA; -suite({dhe_rsa, aes_256_cbc, sha, ignore}) -> - ?TLS_DHE_RSA_WITH_AES_256_CBC_SHA; -suite({dh_anon, aes_256_cbc, sha, ignore}) -> - ?TLS_DH_anon_WITH_AES_256_CBC_SHA; - -%% TSL V1.1 KRB SUITES -suite({krb5, des_cbc, sha, ignore}) -> - ?TLS_KRB5_WITH_DES_CBC_SHA; -suite({krb5_cbc, '3des_ede_cbc', sha, ignore}) -> - ?TLS_KRB5_WITH_3DES_EDE_CBC_SHA; -suite({krb5, rc4_128, sha, ignore}) -> - ?TLS_KRB5_WITH_RC4_128_SHA; -%% suite({krb5_cbc, idea_cbc, sha, ignore}) -> -%% ?TLS_KRB5_WITH_IDEA_CBC_SHA; -suite({krb5_cbc, md5, ignore}) -> - ?TLS_KRB5_WITH_DES_CBC_MD5; -suite({krb5_ede_cbc, des_cbc, md5, ignore}) -> - ?TLS_KRB5_WITH_3DES_EDE_CBC_MD5; -suite({krb5_128, rc4_128, md5, ignore}) -> - ?TLS_KRB5_WITH_RC4_128_MD5; -%% suite({krb5, idea_cbc, md5, ignore}) -> -%% ?TLS_KRB5_WITH_IDEA_CBC_MD5; - -%% Export suites TLS 1.0 OR SSLv3-only servers. -suite({rsa, rc4_40, md5, export}) -> - ?TLS_RSA_EXPORT_WITH_RC4_40_MD5; -suite({rsa, rc2_cbc_40, md5, export}) -> - ?TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5; -suite({rsa, des40_cbc, sha, export}) -> - ?TLS_RSA_EXPORT_WITH_DES40_CBC_SHA; -suite({rsa, rc4_56, md5, export}) -> - ?TLS_RSA_EXPORT1024_WITH_RC4_56_MD5; -suite({rsa, rc2_cbc_56, md5, export}) -> - ?TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5; -suite({rsa, des_cbc, sha, export}) -> - ?TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA; -suite({dhe_dss, des_cbc, sha, export}) -> - ?TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA; -suite({rsa, rc4_56, sha, export}) -> - ?TLS_RSA_EXPORT1024_WITH_RC4_56_SHA; -suite({dhe_dss, rc4_56, sha, export}) -> - ?TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA; -suite({dhe_dss, rc4_128, sha, export}) -> - ?TLS_DHE_DSS_WITH_RC4_128_SHA; -suite({krb5_export, des40_cbc, sha, export}) -> - ?TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA; -suite({krb5_export, rc2_cbc_40, sha, export}) -> - ?TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA; -suite({krb5_export, rc4_cbc_40, sha, export}) -> - ?TLS_KRB5_EXPORT_WITH_RC4_40_SHA; -suite({krb5_export, des40_cbc, md5, export}) -> - ?TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5; -suite({krb5_export, rc2_cbc_40, md5, export}) -> - ?TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5; -suite({krb5_export, rc4_cbc_40, md5, export}) -> - ?TLS_KRB5_EXPORT_WITH_RC4_40_MD5; -suite({rsa_export, rc4_cbc_40, md5, export}) -> - ?TLS_RSA_EXPORT_WITH_RC4_40_MD5; -suite({rsa_export, rc2_cbc_40, md5, export}) -> - ?TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5; -suite({rsa_export, des40_cbc, sha, export}) -> - ?TLS_RSA_EXPORT_WITH_DES40_CBC_SHA; -suite({dh_dss_export, des40_cbc, sha, export}) -> - ?TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA; -suite({dh_rsa_export, des40_cbc, sha, export}) -> - ?TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA; -suite({dhe_dss_export, des40_cbc, sha, export}) -> - ?TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA; -suite({dhe_rsa_export, des40_cbc, sha, export}) -> - ?TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA; -suite({dh_anon_export, rc4_40, md5, export}) -> - ?TLS_DH_anon_EXPORT_WITH_RC4_40_MD5; -suite({dh_anon_export, des40_cbc, sha, export}) -> - ?TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA. - +suite({dhe_rsa, aes_256_cbc, sha}) -> + ?TLS_DHE_RSA_WITH_AES_256_CBC_SHA. +%% suite({dh_anon, aes_256_cbc, sha}) -> +%% ?TLS_DH_anon_WITH_AES_256_CBC_SHA. +%%-------------------------------------------------------------------- +-spec openssl_suite(openssl_cipher_suite()) -> cipher_suite(). +%% +%% Description: Return TLS cipher suite definition. +%%-------------------------------------------------------------------- %% translate constants <-> openssl-strings -%% TODO: Is there a pattern in the nameing -%% that is useable to make a nicer function defention? - openssl_suite("DHE-RSA-AES256-SHA") -> ?TLS_DHE_RSA_WITH_AES_256_CBC_SHA; openssl_suite("DHE-DSS-AES256-SHA") -> @@ -514,46 +315,21 @@ openssl_suite("DHE-DSS-AES128-SHA") -> ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA; openssl_suite("AES128-SHA") -> ?TLS_RSA_WITH_AES_128_CBC_SHA; -%% TODO: Do we want to support this? -%% openssl_suite("DHE-DSS-RC4-SHA") -> -%% ?TLS_DHE_DSS_WITH_RC4_128_SHA; %%openssl_suite("IDEA-CBC-SHA") -> %% ?TLS_RSA_WITH_IDEA_CBC_SHA; openssl_suite("RC4-SHA") -> ?TLS_RSA_WITH_RC4_128_SHA; openssl_suite("RC4-MD5") -> ?TLS_RSA_WITH_RC4_128_MD5; -%% TODO: Do we want to support this? -openssl_suite("EXP1024-RC4-MD5") -> - ?TLS_RSA_EXPORT1024_WITH_RC4_56_MD5; -openssl_suite("EXP1024-RC2-CBC-MD5") -> - ?TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5; -openssl_suite("EXP1024-DES-CBC-SHA") -> - ?TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA; -openssl_suite("EXP1024-DHE-DSS-DES-CBC-SHA") -> - ?TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA; -openssl_suite("EXP1024-RC4-SHA") -> - ?TLS_RSA_EXPORT1024_WITH_RC4_56_SHA; -openssl_suite("EXP1024-DHE-DSS-RC4-SHA") -> - ?TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA; -openssl_suite("DHE-DSS-RC4-SHA") -> - ?TLS_DHE_DSS_WITH_RC4_128_SHA; - openssl_suite("EDH-RSA-DES-CBC-SHA") -> ?TLS_DHE_RSA_WITH_DES_CBC_SHA; openssl_suite("DES-CBC-SHA") -> - ?TLS_RSA_WITH_DES_CBC_SHA; -openssl_suite("EXP-EDH-RSA-DES-CBC-SHA") -> - ?TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA; -openssl_suite("EXP-EDH-DSS-DES-CBC-SHA") -> - ?TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA; -openssl_suite("EXP-DES-CBC-SHA") -> - ?TLS_RSA_EXPORT_WITH_DES40_CBC_SHA; -openssl_suite("EXP-RC2-CBC-MD5") -> - ?TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5; -openssl_suite("EXP-RC4-MD5") -> - ?TLS_RSA_EXPORT_WITH_RC4_40_MD5. - + ?TLS_RSA_WITH_DES_CBC_SHA. +%%-------------------------------------------------------------------- +-spec openssl_suite_name(cipher_suite()) -> openssl_cipher_suite(). +%% +%% Description: Return openssl cipher suite name. +%%------------------------------------------------------------------- openssl_suite_name(?TLS_DHE_RSA_WITH_AES_256_CBC_SHA) -> "DHE-RSA-AES256-SHA"; openssl_suite_name(?TLS_DHE_DSS_WITH_AES_256_CBC_SHA) -> @@ -582,37 +358,28 @@ openssl_suite_name(?TLS_DHE_RSA_WITH_DES_CBC_SHA) -> "EDH-RSA-DES-CBC-SHA"; openssl_suite_name(?TLS_RSA_WITH_DES_CBC_SHA) -> "DES-CBC-SHA"; -openssl_suite_name(?TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA) -> - "EXP-EDH-RSA-DES-CBC-SHA"; -openssl_suite_name(?TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA) -> - "EXP-EDH-DSS-DES-CBC-SHA"; -openssl_suite_name(?TLS_RSA_EXPORT_WITH_DES40_CBC_SHA) -> - "EXP-DES-CBC-SHA"; -openssl_suite_name(?TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5) -> - "EXP-RC2-CBC-MD5"; -openssl_suite_name(?TLS_RSA_EXPORT_WITH_RC4_40_MD5) -> - "EXP-RC4-MD5"; - -openssl_suite_name(?TLS_RSA_EXPORT1024_WITH_RC4_56_MD5) -> - "EXP1024-RC4-MD5"; -openssl_suite_name(?TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5) -> - "EXP1024-RC2-CBC-MD5"; -openssl_suite_name(?TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA) -> - "EXP1024-DES-CBC-SHA"; -openssl_suite_name(?TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA) -> - "EXP1024-DHE-DSS-DES-CBC-SHA"; -openssl_suite_name(?TLS_RSA_EXPORT1024_WITH_RC4_56_SHA) -> - "EXP1024-RC4-SHA"; -openssl_suite_name(?TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA) -> - "EXP1024-DHE-DSS-RC4-SHA"; -openssl_suite_name(?TLS_DHE_DSS_WITH_RC4_128_SHA) -> - "DHE-DSS-RC4-SHA"; - %% No oppenssl name openssl_suite_name(Cipher) -> suite_definition(Cipher). %%-------------------------------------------------------------------- +-spec filter(undefined | binary(), [cipher_suite()]) -> [cipher_suite()]. +%% +%% Description: . +%%------------------------------------------------------------------- +filter(undefined, Ciphers) -> + Ciphers; +filter(DerCert, Ciphers) -> + OtpCert = public_key:pkix_decode_cert(DerCert, otp), + SigAlg = OtpCert#'OTPCertificate'.signatureAlgorithm, + case ssl_certificate:signature_type(SigAlg#'SignatureAlgorithm'.algorithm) of + rsa -> + filter_rsa(OtpCert, Ciphers -- dsa_signed_suites()); + dsa -> + Ciphers -- rsa_signed_suites() + end. + +%%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- @@ -621,15 +388,10 @@ bulk_cipher_algorithm(null) -> %% Not supported yet %% bulk_cipher_algorithm(idea_cbc) -> %% ?IDEA; -bulk_cipher_algorithm(Cipher) when Cipher == rc2_cbc_40; - Cipher == rc2_cbc_56 -> - ?RC2; -bulk_cipher_algorithm(Cipher) when Cipher == rc4_40; - Cipher == rc4_56; - Cipher == rc4_128 -> +bulk_cipher_algorithm(rc4_128) -> ?RC4; -bulk_cipher_algorithm(des40_cbc) -> - ?DES40; +%% bulk_cipher_algorithm(des40_cbc) -> +%% ?DES40; bulk_cipher_algorithm(des_cbc) -> ?DES; bulk_cipher_algorithm('3des_ede_cbc') -> @@ -639,14 +401,10 @@ bulk_cipher_algorithm(Cipher) when Cipher == aes_128_cbc; ?AES. type(Cipher) when Cipher == null; - Cipher == rc4_40; - Cipher == rc4_56; Cipher == rc4_128 -> ?STREAM; type(Cipher) when Cipher == idea_cbc; - Cipher == rc2_cbc_40; - Cipher == rc2_cbc_56; Cipher == des40_cbc; Cipher == des_cbc; Cipher == '3des_ede_cbc'; @@ -659,13 +417,8 @@ key_material(null) -> key_material(Cipher) when Cipher == idea_cbc; Cipher == rc4_128 -> 16; -key_material(Cipher) when Cipher == rc2_cbc_56; - Cipher == rc4_56 -> - 7; -key_material(Cipher) when Cipher == rc2_cbc_40; - Cipher == rc4_40; - Cipher == des40_cbc -> - 5; +%%key_material(des40_cbc) -> +%% 5; key_material(des_cbc) -> 8; key_material('3des_ede_cbc') -> @@ -678,10 +431,6 @@ key_material(aes_256_cbc) -> expanded_key_material(null) -> 0; expanded_key_material(Cipher) when Cipher == idea_cbc; - Cipher == rc2_cbc_40; - Cipher == rc2_cbc_56; - Cipher == rc4_40; - Cipher == rc4_56; Cipher == rc4_128 -> 16; expanded_key_material(Cipher) when Cipher == des_cbc; @@ -696,13 +445,9 @@ expanded_key_material(Cipher) when Cipher == aes_128_cbc; effective_key_bits(null) -> 0; -effective_key_bits(Cipher) when Cipher == rc2_cbc_40; - Cipher == rc4_40; - Cipher == des40_cbc -> - 40; -effective_key_bits(Cipher) when Cipher == rc2_cbc_56; - Cipher == rc4_56; - Cipher == des_cbc -> +%%effective_key_bits(des40_cbc) -> +%% 40; +effective_key_bits(des_cbc) -> 56; effective_key_bits(Cipher) when Cipher == idea_cbc; Cipher == rc4_128; @@ -714,16 +459,12 @@ effective_key_bits(aes_256_cbc) -> 256. iv_size(Cipher) when Cipher == null; - Cipher == rc4_40; - Cipher == rc4_56; Cipher == rc4_128 -> 0; iv_size(Cipher) -> block_size(Cipher). block_size(Cipher) when Cipher == idea_cbc; - Cipher == rc2_cbc_40; - Cipher == rc2_cbc_56; Cipher == des40_cbc; Cipher == des_cbc; Cipher == '3des_ede_cbc' -> @@ -763,9 +504,18 @@ generic_stream_cipher_from_bin(T, HashSz) -> #generic_stream_cipher{content=Content, mac=Mac}. -check_padding(_GBC) -> - ok. - +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. + + get_padding(Length, BlockSize) -> get_padding_aux(BlockSize, Length rem BlockSize). @@ -782,3 +532,53 @@ next_iv(Bin, IV) -> <<_:FirstPart/binary, NextIV:IVSz/binary>> = Bin, NextIV. +rsa_signed_suites() -> + dhe_rsa_suites() ++ rsa_suites(). + +dhe_rsa_suites() -> + [?TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + ?TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, + ?TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + ?TLS_DHE_RSA_WITH_DES_CBC_SHA]. + +rsa_suites() -> + [?TLS_RSA_WITH_AES_256_CBC_SHA, + ?TLS_RSA_WITH_3DES_EDE_CBC_SHA, + ?TLS_RSA_WITH_AES_128_CBC_SHA, + %%?TLS_RSA_WITH_IDEA_CBC_SHA, + ?TLS_RSA_WITH_RC4_128_SHA, + ?TLS_RSA_WITH_RC4_128_MD5, + ?TLS_RSA_WITH_DES_CBC_SHA]. + +dsa_signed_suites() -> + dhe_dss_suites(). + +dhe_dss_suites() -> + [?TLS_DHE_DSS_WITH_AES_256_CBC_SHA, + ?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, + ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA, + ?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA]. + +filter_rsa(OtpCert, RsaCiphers) -> + TBSCert = OtpCert#'OTPCertificate'.tbsCertificate, + TBSExtensions = TBSCert#'OTPTBSCertificate'.extensions, + Extensions = ssl_certificate:extensions_list(TBSExtensions), + case ssl_certificate:select_extension(?'id-ce-keyUsage', Extensions) of + undefined -> + RsaCiphers; + #'Extension'{extnValue = KeyUse} -> + Result = filter_rsa_suites(keyEncipherment, + KeyUse, RsaCiphers, rsa_suites()), + filter_rsa_suites(digitalSignature, + KeyUse, Result, dhe_rsa_suites()) + end. + +filter_rsa_suites(Use, KeyUse, CipherSuits, RsaSuites) -> + case ssl_certificate:is_valid_key_usage(KeyUse, Use) of + true -> + CipherSuits; + false -> + CipherSuits -- RsaSuites + end. + + diff --git a/lib/ssl/src/ssl_cipher.hrl b/lib/ssl/src/ssl_cipher.hrl index 4304c501b7..8bd68cc190 100644 --- a/lib/ssl/src/ssl_cipher.hrl +++ b/lib/ssl/src/ssl_cipher.hrl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -26,6 +26,14 @@ -ifndef(ssl_cipher). -define(ssl_cipher, true). +-type cipher() :: null |rc4_128 | idea_cbc | des40_cbc | des_cbc | '3des_ede_cbc' + | aes_128_cbc | aes_256_cbc. +-type hash() :: null | sha | md5. +-type erl_cipher_suite() :: {key_algo(), cipher(), hash()}. +-type cipher_suite() :: binary(). +-type cipher_enum() :: integer(). +-type openssl_cipher_suite() :: string(). + %%% SSL cipher protocol %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -define(CHANGE_CIPHER_SPEC_PROTO, 1). % _PROTO to not clash with % SSL record protocol @@ -57,7 +65,7 @@ %% TLS_NULL_WITH_NULL_NULL = { 0x00,0x00 }; -define(TLS_NULL_WITH_NULL_NULL, <<?BYTE(16#00), ?BYTE(16#00)>>). -%%% The following CipherSuite definitions require that the server +%%% The following cipher suite definitions require that the server %%% provide an RSA certificate that can be used for key exchange. The %%% server may request either an RSA or a DSS signature-capable %%% certificate in the certificate request message. @@ -68,24 +76,15 @@ %% TLS_RSA_WITH_NULL_SHA = { 0x00,0x02 }; -define(TLS_RSA_WITH_NULL_SHA, <<?BYTE(16#00), ?BYTE(16#02)>>). -%% TLS_RSA_EXPORT_WITH_RC4_40_MD5 = { 0x00,0x03 }; --define(TLS_RSA_EXPORT_WITH_RC4_40_MD5, <<?BYTE(16#00), ?BYTE(16#03)>>). - %% TLS_RSA_WITH_RC4_128_MD5 = { 0x00,0x04 }; -define(TLS_RSA_WITH_RC4_128_MD5, <<?BYTE(16#00), ?BYTE(16#04)>>). %% TLS_RSA_WITH_RC4_128_SHA = { 0x00,0x05 }; -define(TLS_RSA_WITH_RC4_128_SHA, <<?BYTE(16#00), ?BYTE(16#05)>>). -%% TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = { 0x00,0x06 }; --define(TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5, <<?BYTE(16#00), ?BYTE(16#06)>>). - %% TLS_RSA_WITH_IDEA_CBC_SHA = { 0x00,0x07 }; -define(TLS_RSA_WITH_IDEA_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#07)>>). -%% TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x08 }; --define(TLS_RSA_EXPORT_WITH_DES40_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#08)>>). - %% TLS_RSA_WITH_DES_CBC_SHA = { 0x00,0x09 }; -define(TLS_RSA_WITH_DES_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#09)>>). @@ -106,51 +105,33 @@ %%% provided by the client must use the parameters (group and %%% generator) described by the server. -%% TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x0B }; --define(TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#0B)>>). - %% TLS_DH_DSS_WITH_DES_CBC_SHA = { 0x00,0x0C }; -define(TLS_DH_DSS_WITH_DES_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#0C)>>). %% TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00,0x0D }; -define(TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#0D)>>). -%% TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x0E }; --define(TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#0E)>>). - %% TLS_DH_RSA_WITH_DES_CBC_SHA = { 0x00,0x0F }; -define(TLS_DH_RSA_WITH_DES_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#0F)>>). %% TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00,0x10 }; -define(TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#10)>>). -%% TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x11 }; --define(TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#11)>>). - %% TLS_DHE_DSS_WITH_DES_CBC_SHA = { 0x00,0x12 }; -define(TLS_DHE_DSS_WITH_DES_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#12)>>). %% TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00,0x13 }; -define(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#13)>>). -%% TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x14 }; --define(TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#14)>>). - %% TLS_DHE_RSA_WITH_DES_CBC_SHA = { 0x00,0x15 }; -define(TLS_DHE_RSA_WITH_DES_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#15)>>). %% TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00,0x16 }; -define(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#16)>>). -%% TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = { 0x00,0x17 }; --define(TLS_DH_anon_EXPORT_WITH_RC4_40_MD5, <<?BYTE(16#00), ?BYTE(16#17)>>). - %% TLS_DH_anon_WITH_RC4_128_MD5 = { 0x00,0x18 }; -define(TLS_DH_anon_WITH_RC4_128_MD5, <<?BYTE(16#00),?BYTE(16#18)>>). -%% TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x19 }; --define(TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#19)>>). - %% TLS_DH_anon_WITH_DES_CBC_SHA = { 0x00,0x1A }; -define(TLS_DH_anon_WITH_DES_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#1A)>>). @@ -222,32 +203,9 @@ %% TLS_KRB5_WITH_IDEA_CBC_MD5 = { 0x00,0x25 }; -define(TLS_KRB5_WITH_IDEA_CBC_MD5, <<?BYTE(16#00), ?BYTE(16#25)>>). -%% TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA = { 0x00,0x26 }; --define(TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA, <<?BYTE(16#00), ?BYTE(16#26)>>). - -%% TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA = { 0x00,0x27 }; --define(TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA, <<?BYTE(16#00), ?BYTE(16#27)>>). - -%% TLS_KRB5_EXPORT_WITH_RC4_40_SHA = { 0x00,0x28 }; --define(TLS_KRB5_EXPORT_WITH_RC4_40_SHA, <<?BYTE(16#00), ?BYTE(16#28)>>). - -%% TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 = { 0x00,0x29 }; --define(TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5, <<?BYTE(16#00), ?BYTE(16#29)>>). - -%% TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 = { 0x00,0x2A }; --define(TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5, <<?BYTE(16#00), ?BYTE(16#2A)>>). - -%% TLS_KRB5_EXPORT_WITH_RC4_40_MD5 = { 0x00,0x2B }; --define(TLS_KRB5_EXPORT_WITH_RC4_40_MD5, <<?BYTE(16#00), ?BYTE(16#2B)>>). - -%% Additional TLS ciphersuites from draft-ietf-tls-56-bit-ciphersuites-00.txt - --define(TLS_RSA_EXPORT1024_WITH_RC4_56_MD5, <<?BYTE(16#00), ?BYTE(16#60)>>). --define(TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5, <<?BYTE(16#00), ?BYTE(16#61)>>). --define(TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#62)>>). --define(TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#63)>>). --define(TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, <<?BYTE(16#00), ?BYTE(16#64)>>). --define(TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA, <<?BYTE(16#00), ?BYTE(16#65)>>). --define(TLS_DHE_DSS_WITH_RC4_128_SHA, <<?BYTE(16#00), ?BYTE(16#66)>>). +%% RFC 5746 - Not a real cipher suite used to signal empty "renegotiation_info" extension +%% to avoid handshake failure from old servers that do not ignore +%% hello extension data as they should. +-define(TLS_EMPTY_RENEGOTIATION_INFO_SCSV, <<?BYTE(16#00), ?BYTE(16#FF)>>). -endif. % -ifdef(ssl_cipher). diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl index 8ff001b172..c94199c336 100644 --- a/lib/ssl/src/ssl_connection.erl +++ b/lib/ssl/src/ssl_connection.erl @@ -39,7 +39,8 @@ -include_lib("public_key/include/public_key.hrl"). %% Internal application API --export([send/2, send/3, recv/3, connect/7, accept/6, close/1, shutdown/2, +-export([send/2, recv/3, connect/7, ssl_accept/6, handshake/2, + socket_control/3, close/1, shutdown/2, new_user/2, get_opts/2, set_opts/2, info/1, session_info/1, peer_certificate/1, sockname/1, peername/1, renegotiation/1]). @@ -57,19 +58,21 @@ transport_cb, % atom() - callback module data_tag, % atom() - ex tcp. close_tag, % atom() - ex tcp_closed + error_tag, % atom() - ex tcp_error host, % string() | ipadress() port, % integer() socket, % socket() ssl_options, % #ssl_options{} socket_options, % #socket_options{} connection_states, % #connection_states{} from ssl_record.hrl + tls_packets = [], % Not yet handled decode ssl/tls packets. tls_record_buffer, % binary() buffer of incomplete records tls_handshake_buffer, % binary() buffer of incomplete handshakes %% {{md5_hash, sha_hash}, {prev_md5, prev_sha}} (binary()) tls_handshake_hashes, % see above tls_cipher_texts, % list() received but not deciphered yet own_cert, % binary() - session, % #session{} from ssl_handshake.erl + session, % #session{} from ssl_handshake.hrl session_cache, % session_cache_cb, % negotiated_version, % #protocol_version{} @@ -85,7 +88,6 @@ from, % term(), where to reply bytes_to_read, % integer(), # bytes to read in passive mode user_data_buffer, % binary() -%% tls_buffer, % Keeps a lookahead one packet if available log_alert, % boolean() renegotiation, % {boolean(), From | internal | peer} recv_during_renegotiation, %boolean() @@ -96,46 +98,92 @@ #'DHParameter'{prime = ?DEFAULT_DIFFIE_HELLMAN_PRIME, base = ?DEFAULT_DIFFIE_HELLMAN_GENERATOR}). +-type state_name() :: hello | abbreviated | certify | cipher | connection. +-type gen_fsm_state_return() :: {next_state, state_name(), #state{}} | + {next_state, state_name(), #state{}, timeout()} | + {stop, term(), #state{}}. + %%==================================================================== %% Internal application API %%==================================================================== %%-------------------------------------------------------------------- -%% Function: +-spec send(pid(), iolist()) -> ok | {error, reason()}. %% -%% Description: +%% Description: Sends data over the ssl connection %%-------------------------------------------------------------------- send(Pid, Data) -> - sync_send_all_state_event(Pid, {application_data, erlang:iolist_to_binary(Data)}, infinity). -send(Pid, Data, Timeout) -> - sync_send_all_state_event(Pid, {application_data, erlang:iolist_to_binary(Data)}, Timeout). + sync_send_all_state_event(Pid, {application_data, + erlang:iolist_to_binary(Data)}, infinity). + %%-------------------------------------------------------------------- -%% Function: +-spec recv(pid(), integer(), timeout()) -> + {ok, binary() | list()} | {error, reason()}. %% -%% Description: +%% Description: Receives data when active = false %%-------------------------------------------------------------------- recv(Pid, Length, Timeout) -> sync_send_all_state_event(Pid, {recv, Length}, Timeout). %%-------------------------------------------------------------------- -%% Function: +-spec connect(host(), port_num(), port(), {#ssl_options{}, #socket_options{}}, + pid(), tuple(), timeout()) -> + {ok, #sslsocket{}} | {error, reason()}. %% -%% Description: +%% Description: Connect to a ssl server. %%-------------------------------------------------------------------- connect(Host, Port, Socket, Options, User, CbInfo, Timeout) -> - start_fsm(client, Host, Port, Socket, Options, User, CbInfo, - Timeout). + try start_fsm(client, Host, Port, Socket, Options, User, CbInfo, + Timeout) + catch + exit:{noproc, _} -> + {error, ssl_not_started} + end. +%%-------------------------------------------------------------------- +-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 +%% ssl handshake. +%%-------------------------------------------------------------------- +ssl_accept(Port, Socket, Opts, User, CbInfo, Timeout) -> + try start_fsm(server, "localhost", Port, Socket, Opts, User, + CbInfo, Timeout) + catch + exit:{noproc, _} -> + {error, ssl_not_started} + end. + %%-------------------------------------------------------------------- -%% Function: +-spec handshake(#sslsocket{}, timeout()) -> ok | {error, reason()}. %% -%% Description: +%% Description: Starts ssl handshake. %%-------------------------------------------------------------------- -accept(Port, Socket, Opts, User, CbInfo, Timeout) -> - start_fsm(server, "localhost", Port, Socket, Opts, User, - CbInfo, Timeout). +handshake(#sslsocket{pid = Pid}, Timeout) -> + case sync_send_all_state_event(Pid, start, Timeout) of + connected -> + ok; + Error -> + Error + end. +%-------------------------------------------------------------------- +-spec socket_control(port(), pid(), atom()) -> + {ok, #sslsocket{}} | {error, reason()}. +%% +%% Description: Set the ssl process to own the accept socket +%%-------------------------------------------------------------------- +socket_control(Socket, Pid, CbModule) -> + case CbModule:controlling_process(Socket, Pid) of + ok -> + {ok, sslsocket(Pid)}; + {error, Reason} -> + {error, Reason} + end. + %%-------------------------------------------------------------------- -%% Function: +-spec close(pid()) -> ok | {error, reason()}. %% -%% Description: +%% Description: Close a ssl connection %%-------------------------------------------------------------------- close(ConnectionPid) -> case sync_send_all_state_event(ConnectionPid, close) of @@ -146,80 +194,78 @@ close(ConnectionPid) -> end. %%-------------------------------------------------------------------- -%% Function: +-spec shutdown(pid(), atom()) -> ok | {error, reason()}. %% -%% Description: +%% Description: Same as gen_tcp:shutdown/2 %%-------------------------------------------------------------------- shutdown(ConnectionPid, How) -> sync_send_all_state_event(ConnectionPid, {shutdown, How}). - %%-------------------------------------------------------------------- -%% Function: +-spec new_user(pid(), pid()) -> ok | {error, reason()}. %% -%% Description: +%% Description: Changes process that receives the messages when active = true +%% or once. %%-------------------------------------------------------------------- new_user(ConnectionPid, User) -> sync_send_all_state_event(ConnectionPid, {new_user, User}). %%-------------------------------------------------------------------- -%% Function: +-spec sockname(pid()) -> {ok, {tuple(), port_num()}} | {error, reason()}. %% -%% Description: +%% Description: Same as inet:sockname/1 %%-------------------------------------------------------------------- sockname(ConnectionPid) -> sync_send_all_state_event(ConnectionPid, sockname). %%-------------------------------------------------------------------- -%% Function: +-spec peername(pid()) -> {ok, {tuple(), port_num()}} | {error, reason()}. %% -%% Description: +%% Description: Same as inet:peername/1 %%-------------------------------------------------------------------- peername(ConnectionPid) -> sync_send_all_state_event(ConnectionPid, peername). %%-------------------------------------------------------------------- -%% Function: +-spec get_opts(pid(), list()) -> {ok, list()} | {error, reason()}. %% -%% Description: +%% Description: Same as inet:getopts/2 %%-------------------------------------------------------------------- -get_opts({ListenSocket, {_SslOpts, SockOpts}, _}, OptTags) -> - get_socket_opts(ListenSocket, OptTags, SockOpts, []); get_opts(ConnectionPid, OptTags) -> sync_send_all_state_event(ConnectionPid, {get_opts, OptTags}). %%-------------------------------------------------------------------- -%% Function: +-spec set_opts(pid(), list()) -> ok | {error, reason()}. %% -%% Description: +%% Description: Same as inet:setopts/2 %%-------------------------------------------------------------------- set_opts(ConnectionPid, Options) -> sync_send_all_state_event(ConnectionPid, {set_opts, Options}). %%-------------------------------------------------------------------- -%% Function: +-spec info(pid()) -> {ok, {atom(), tuple()}} | {error, reason()}. %% -%% Description: +%% Description: Returns ssl protocol and cipher used for the connection %%-------------------------------------------------------------------- info(ConnectionPid) -> sync_send_all_state_event(ConnectionPid, info). %%-------------------------------------------------------------------- -%% Function: +-spec session_info(pid()) -> {ok, list()} | {error, reason()}. %% -%% Description: +%% Description: Returns info about the ssl session %%-------------------------------------------------------------------- session_info(ConnectionPid) -> sync_send_all_state_event(ConnectionPid, session_info). %%-------------------------------------------------------------------- -%% Function: +-spec peer_certificate(pid()) -> {ok, binary()| undefined} | {error, reason()}. %% -%% Description: +%% Description: Returns the peer cert %%-------------------------------------------------------------------- peer_certificate(ConnectionPid) -> sync_send_all_state_event(ConnectionPid, peer_certificate). %%-------------------------------------------------------------------- -%% Function: +-spec renegotiation(pid()) -> ok | {error, reason()}. %% -%% Description: +%% Description: Starts a renegotiation of the ssl session. %%-------------------------------------------------------------------- renegotiation(ConnectionPid) -> sync_send_all_state_event(ConnectionPid, renegotiate). @@ -229,7 +275,8 @@ renegotiation(ConnectionPid) -> %%==================================================================== %%-------------------------------------------------------------------- -%% Function: start_link() -> {ok,Pid} | ignore | {error,Error} +-spec start_link(atom(), host(), port_num(), port(), list(), pid(), tuple()) -> + {ok, pid()} | ignore | {error, reason()}. %% %% Description: Creates a gen_fsm process which calls Module:init/1 to %% initialize. To ensure a synchronized start-up procedure, this function @@ -243,20 +290,20 @@ start_link(Role, Host, Port, Socket, Options, User, CbInfo) -> %% gen_fsm callbacks %%==================================================================== %%-------------------------------------------------------------------- -%% Function: init(Args) -> {ok, StateName, State} | -%% {ok, StateName, State, Timeout} | -%% ignore | -%% {stop, StopReason} +-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. %%-------------------------------------------------------------------- -init([Role, Host, Port, Socket, {SSLOpts, _} = Options, +init([Role, Host, Port, Socket, {SSLOpts0, _} = Options, User, CbInfo]) -> State0 = initial_state(Role, Host, Port, Socket, Options, User, CbInfo), Hashes0 = ssl_handshake:init_hashes(), - try ssl_init(SSLOpts, Role) of + try ssl_init(SSLOpts0, Role) of {ok, Ref, CacheRef, OwnCert, Key, DHParams} -> State = State0#state{tls_handshake_hashes = Hashes0, own_cert = OwnCert, @@ -269,101 +316,96 @@ init([Role, Host, Port, Socket, {SSLOpts, _} = Options, throw:Error -> {stop, Error} end. - + %%-------------------------------------------------------------------- -%% Function: -%% state_name(Event, State) -> {next_state, NextStateName, NextState}| -%% {next_state, NextStateName, -%% NextState, Timeout} | -%% {stop, Reason, NewState} +%% -spec state_name(event(), #state{}) -> gen_fsm_state_return() %% %% Description:There should be one instance of this function for each %% possible state name. Whenever a gen_fsm receives an event sent %% using gen_fsm:send_event/2, the instance of this function with the %% same name as the current state name StateName is called to handle %% the event. It is also called if a timeout occurs. +%% +%%-------------------------------------------------------------------- +-spec hello(start | #hello_request{} | #client_hello{} | #server_hello{} | term(), + #state{}) -> gen_fsm_state_return(). %%-------------------------------------------------------------------- -hello(socket_control, #state{host = Host, port = Port, role = client, - ssl_options = SslOpts, - transport_cb = Transport, socket = Socket, - connection_states = ConnectionStates} +hello(start, #state{host = Host, port = Port, role = client, + ssl_options = SslOpts, + transport_cb = Transport, socket = Socket, + connection_states = ConnectionStates, + renegotiation = {Renegotiation, _}} = State0) -> + Hello = ssl_handshake:client_hello(Host, Port, - ConnectionStates, SslOpts), + ConnectionStates, + SslOpts, Renegotiation), + Version = Hello#client_hello.client_version, Hashes0 = ssl_handshake:init_hashes(), {BinMsg, CS2, Hashes1} = encode_handshake(Hello, Version, ConnectionStates, Hashes0), Transport:send(Socket, BinMsg), - State = State0#state{connection_states = CS2, + State1 = State0#state{connection_states = CS2, negotiated_version = Version, %% Requested version session = #session{session_id = Hello#client_hello.session_id, is_resumable = false}, - tls_handshake_hashes = Hashes1}, - {next_state, hello, next_record(State)}; + tls_handshake_hashes = Hashes1}, + {Record, State} = next_record(State1), + next_state(hello, Record, State); -hello(socket_control, #state{role = server} = State) -> - {next_state, hello, next_record(State)}; +hello(start, #state{role = server} = State0) -> + {Record, State} = next_record(State0), + next_state(hello, Record, State); -hello(#hello_request{}, #state{role = client} = State) -> - {next_state, hello, State}; +hello(#hello_request{}, #state{role = client} = State0) -> + {Record, State} = next_record(State0), + next_state(hello, Record, State); hello(#server_hello{cipher_suite = CipherSuite, compression_method = Compression} = Hello, - #state{session = Session0 = #session{session_id = OldId}, + #state{session = #session{session_id = OldId}, connection_states = ConnectionStates0, role = client, negotiated_version = ReqVersion, - host = Host, port = Port, - session_cache = Cache, - session_cache_cb = CacheCb} = State0) -> - - {Version, NewId, ConnectionStates1} = - ssl_handshake:hello(Hello, ConnectionStates0), - - {KeyAlgorithm, _, _, _} = - ssl_cipher:suite_definition(CipherSuite), - - PremasterSecret = make_premaster_secret(ReqVersion, KeyAlgorithm), - - State = State0#state{key_algorithm = KeyAlgorithm, - negotiated_version = Version, - connection_states = ConnectionStates1, - premaster_secret = PremasterSecret}, - - case ssl_session:is_new(OldId, NewId) of - true -> - Session = Session0#session{session_id = NewId, - cipher_suite = CipherSuite, - compression_method = Compression}, - {next_state, certify, - next_record(State#state{session = Session})}; - false -> - Session = CacheCb:lookup(Cache, {{Host, Port}, NewId}), - case ssl_handshake:master_secret(Version, Session, - ConnectionStates1, client) of - {_, ConnectionStates2} -> - {next_state, abbreviated, - next_record(State#state{ - connection_states = ConnectionStates2, - session = Session})}; - #alert{} = Alert -> - handle_own_alert(Alert, Version, hello, State), - {stop, normal, State} - end + renegotiation = {Renegotiation, _}, + ssl_options = SslOptions} = State0) -> + + case ssl_handshake:hello(Hello, SslOptions, ConnectionStates0, Renegotiation) of + {Version, NewId, ConnectionStates} -> + {KeyAlgorithm, _, _} = + ssl_cipher:suite_definition(CipherSuite), + + PremasterSecret = make_premaster_secret(ReqVersion, KeyAlgorithm), + + State = State0#state{key_algorithm = KeyAlgorithm, + negotiated_version = Version, + connection_states = ConnectionStates, + premaster_secret = PremasterSecret}, + + case ssl_session:is_new(OldId, NewId) of + true -> + handle_new_session(NewId, CipherSuite, Compression, State); + false -> + handle_resumed_session(NewId, State#state{connection_states = ConnectionStates}) + end; + #alert{} = Alert -> + handle_own_alert(Alert, ReqVersion, hello, State0), + {stop, normal, State0} end; hello(Hello = #client_hello{client_version = ClientVersion}, State = #state{connection_states = ConnectionStates0, port = Port, session = Session0, - session_cache = Cache, + renegotiation = {Renegotiation, _}, + session_cache = Cache, session_cache_cb = CacheCb, - ssl_options = SslOpts}) -> + ssl_options = SslOpts, + own_cert = Cert}) -> - case ssl_handshake:hello(Hello, {Port, SslOpts, - Session0, Cache, CacheCb, - ConnectionStates0}) of + case ssl_handshake:hello(Hello, SslOpts, {Port, Session0, Cache, CacheCb, + ConnectionStates0, Cert}, Renegotiation) of {Version, {Type, Session}, ConnectionStates} -> do_server_hello(Type, State#state{connection_states = ConnectionStates, @@ -372,50 +414,67 @@ hello(Hello = #client_hello{client_version = ClientVersion}, #alert{} = Alert -> handle_own_alert(Alert, ClientVersion, hello, State), {stop, normal, State} - end. + end; -abbreviated(socket_control, #state{role = server} = State) -> - {next_state, abbreviated, State}; -abbreviated(#hello_request{}, State) -> - {next_state, certify, State}; +hello(Msg, State) -> + handle_unexpected_message(Msg, hello, State). +%%-------------------------------------------------------------------- +-spec abbreviated(#hello_request{} | #finished{} | term(), + #state{}) -> gen_fsm_state_return(). +%%-------------------------------------------------------------------- +abbreviated(#hello_request{}, State0) -> + {Record, State} = next_record(State0), + next_state(hello, Record, State); -abbreviated(Finished = #finished{}, +abbreviated(#finished{verify_data = Data} = Finished, #state{role = server, negotiated_version = Version, tls_handshake_hashes = Hashes, - session = #session{master_secret = MasterSecret}} = - State0) -> + session = #session{master_secret = MasterSecret}, + connection_states = ConnectionStates0} = + State) -> case ssl_handshake:verify_connection(Version, Finished, client, MasterSecret, Hashes) of - verified -> - State = ack_connection(State0), - next_state_connection(State); + verified -> + ConnectionStates = ssl_record:set_client_verify_data(current_both, Data, ConnectionStates0), + next_state_connection(abbreviated, + ack_connection(State#state{connection_states = ConnectionStates})); #alert{} = Alert -> - handle_own_alert(Alert, Version, abbreviated, State0), - {stop, normal, State0} + handle_own_alert(Alert, Version, abbreviated, State), + {stop, normal, State} end; -abbreviated(Finished = #finished{}, +abbreviated(#finished{verify_data = Data} = Finished, #state{role = client, tls_handshake_hashes = Hashes0, session = #session{master_secret = MasterSecret}, - negotiated_version = Version} = State0) -> + negotiated_version = Version, + connection_states = ConnectionStates0} = State) -> case ssl_handshake:verify_connection(Version, Finished, server, MasterSecret, Hashes0) of verified -> - {ConnectionStates, Hashes} = finalize_client_handshake(State0), - State = ack_connection(State0), - next_state_connection(State#state{tls_handshake_hashes = Hashes, - connection_states = - ConnectionStates}); + ConnectionStates1 = ssl_record:set_server_verify_data(current_read, Data, ConnectionStates0), + {ConnectionStates, Hashes} = + finalize_handshake(State#state{connection_states = ConnectionStates1}, abbreviated), + next_state_connection(abbreviated, + ack_connection(State#state{tls_handshake_hashes = Hashes, + connection_states = + ConnectionStates})); #alert{} = Alert -> - handle_own_alert(Alert, Version, abbreviated, State0), - {stop, normal, State0} - end. + handle_own_alert(Alert, Version, abbreviated, State), + {stop, normal, State} + end; -certify(socket_control, #state{role = server} = State) -> - {next_state, certify, State}; -certify(#hello_request{}, State) -> - {next_state, certify, State}; +abbreviated(Msg, State) -> + handle_unexpected_message(Msg, abbreviated, State). + +%%-------------------------------------------------------------------- +-spec certify(#hello_request{} | #certificate{} | #server_key_exchange{} | + #certificate_request{} | #server_hello_done{} | #client_key_exchange{} | term(), + #state{}) -> gen_fsm_state_return(). +%%-------------------------------------------------------------------- +certify(#hello_request{}, State0) -> + {Record, State} = next_record(State0), + next_state(hello, Record, State); certify(#certificate{asn1_certificates = []}, #state{role = server, negotiated_version = Version, @@ -430,9 +489,9 @@ certify(#certificate{asn1_certificates = []}, #state{role = server, ssl_options = #ssl_options{verify = verify_peer, fail_if_no_peer_cert = false}} = - State) -> - {next_state, certify, - next_record(State#state{client_certificate_requested = false})}; + State0) -> + {Record, State} = next_record(State0#state{client_certificate_requested = false}), + next_state(certify, Record, State); certify(#certificate{} = Cert, #state{negotiated_version = Version, @@ -441,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}); @@ -454,28 +512,24 @@ certify(#certificate{} = Cert, certify(#server_key_exchange{} = KeyExchangeMsg, #state{role = client, negotiated_version = Version, key_algorithm = Alg} = State0) - when Alg == dhe_dss; Alg == dhe_rsa ->%%Not imp:Alg == dh_anon;Alg == krb5 -> + when Alg == dhe_dss; Alg == dhe_rsa -> case handle_server_key(KeyExchangeMsg, State0) of - #state{} = State -> - {next_state, certify, next_record(State)}; + #state{} = State1 -> + {Record, State} = next_record(State1), + next_state(certify, Record, State); #alert{} = Alert -> handle_own_alert(Alert, Version, certify_server_keyexchange, State0), {stop, normal, State0} end; -certify(#server_key_exchange{}, - State = #state{role = client, negotiated_version = Version, - key_algorithm = Alg}) - when Alg == rsa; Alg == dh_dss; Alg == dh_rsa -> - Alert = ?ALERT_REC(?FATAL, ?UNEXPECTED_MESSAGE), - handle_own_alert(Alert, Version, certify_server_key_exchange, State), - {stop, normal, State}; - -certify(#certificate_request{}, State) -> - NewState = State#state{client_certificate_requested = true}, - {next_state, certify, next_record(NewState)}; +certify(#server_key_exchange{} = Msg, + #state{role = client, key_algorithm = rsa} = State) -> + handle_unexpected_message(Msg, certify_server_keyexchange, State); +certify(#certificate_request{}, State0) -> + {Record, State} = next_record(State0#state{client_certificate_requested = true}), + next_state(certify, Record, State); %% Master secret was determined with help of server-key exchange msg certify(#server_hello_done{}, @@ -515,80 +569,84 @@ certify(#server_hello_done{}, {stop, normal, State0} end; -certify(#client_key_exchange{}, - State = #state{role = server, - client_certificate_requested = true, - ssl_options = #ssl_options{fail_if_no_peer_cert = true}, - negotiated_version = Version}) -> +certify(#client_key_exchange{} = Msg, + #state{role = server, + client_certificate_requested = true, + ssl_options = #ssl_options{fail_if_no_peer_cert = true}} = State) -> %% We expect a certificate here - Alert = ?ALERT_REC(?FATAL, ?UNEXPECTED_MESSAGE), - handle_own_alert(Alert, Version, - certify_server_waiting_certificate, State), - {stop, normal, State}; - + 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}, - State = State0#state{connection_states = ConnectionStates, - session = Session}, - {next_state, cipher, next_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} -> - State = State0#state{session = - Session#session{master_secret - = MasterSecret}, - connection_states = ConnectionStates}, - {next_state, cipher, next_record(State)}; + State1 = State0#state{session = + Session#session{master_secret + = MasterSecret}, + connection_states = ConnectionStates}, + + {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. -cipher(socket_control, #state{role = server} = State) -> - {next_state, cipher, State}; -cipher(#hello_request{}, State) -> - {next_state, cipher, State}; +%%-------------------------------------------------------------------- +-spec cipher(#hello_request{} | #certificate_verify{} | #finished{} | term(), + #state{}) -> gen_fsm_state_return(). +%%-------------------------------------------------------------------- +cipher(#hello_request{}, State0) -> + {Record, State} = next_record(State0), + next_state(hello, Record, State); cipher(#certificate_verify{signature = Signature}, #state{role = server, @@ -597,198 +655,88 @@ cipher(#certificate_verify{signature = Signature}, session = #session{master_secret = MasterSecret}, key_algorithm = Algorithm, tls_handshake_hashes = Hashes - } = State) -> + } = State0) -> case ssl_handshake:certificate_verify(Signature, PublicKeyInfo, Version, MasterSecret, Algorithm, Hashes) of valid -> - {next_state, cipher, next_record(State)}; + {Record, State} = next_record(State0), + next_state(cipher, Record, State); #alert{} = Alert -> - handle_own_alert(Alert, Version, cipher, State), - {stop, normal, State} + handle_own_alert(Alert, Version, cipher, State0), + {stop, normal, State0} end; -cipher(#finished{} = Finished, +cipher(#finished{verify_data = Data} = Finished, #state{negotiated_version = Version, host = Host, port = Port, role = Role, session = #session{master_secret = MasterSecret} = Session0, - tls_handshake_hashes = Hashes} = State0) -> + tls_handshake_hashes = Hashes0} = State) -> case ssl_handshake:verify_connection(Version, Finished, opposite_role(Role), - MasterSecret, Hashes) of + MasterSecret, Hashes0) of verified -> - State = ack_connection(State0), Session = register_session(Role, Host, Port, Session0), - case Role of - client -> - next_state_connection(State#state{session = Session}); - server -> - {NewConnectionStates, NewHashes} = - finalize_server_handshake(State#state{ - session = Session}), - next_state_connection(State#state{connection_states = - NewConnectionStates, - session = Session, - tls_handshake_hashes = - NewHashes}) - end; + cipher_role(Role, Data, Session, State); #alert{} = Alert -> - handle_own_alert(Alert, Version, cipher, State0), - {stop, normal, State0} - end. + handle_own_alert(Alert, Version, cipher, State), + {stop, normal, State} + end; -connection(socket_control, #state{role = server} = State) -> - {next_state, connection, State}; -connection(#hello_request{}, State = #state{host = Host, port = Port, - socket = Socket, - ssl_options = SslOpts, - negotiated_version = Version, - transport_cb = Transport, - connection_states = ConnectionStates0, - tls_handshake_hashes = Hashes0}) -> +cipher(Msg, State) -> + handle_unexpected_message(Msg, cipher, State). - Hello = ssl_handshake:client_hello(Host, Port, - ConnectionStates0, SslOpts), +%%-------------------------------------------------------------------- +-spec connection(#hello_request{} | #client_hello{} | term(), + #state{}) -> gen_fsm_state_return(). +%%-------------------------------------------------------------------- +connection(#hello_request{}, #state{host = Host, port = Port, + socket = Socket, + ssl_options = SslOpts, + negotiated_version = Version, + transport_cb = Transport, + connection_states = ConnectionStates0, + renegotiation = {Renegotiation, _}, + tls_handshake_hashes = Hashes0} = State0) -> + + Hello = ssl_handshake:client_hello(Host, Port, ConnectionStates0, + SslOpts, Renegotiation), + {BinMsg, ConnectionStates1, Hashes1} = encode_handshake(Hello, Version, ConnectionStates0, Hashes0), Transport:send(Socket, BinMsg), - {next_state, hello, next_record(State#state{connection_states = - ConnectionStates1, - tls_handshake_hashes = Hashes1})}; + {Record, State} = next_record(State0#state{connection_states = + ConnectionStates1, + tls_handshake_hashes = Hashes1}), + next_state(hello, Record, State); connection(#client_hello{} = Hello, #state{role = server} = State) -> - hello(Hello, State). + hello(Hello, State); +connection(Msg, State) -> + handle_unexpected_message(Msg, connection, State). %%-------------------------------------------------------------------- -%% Function: -%% handle_event(Event, StateName, State) -> {next_state, NextStateName, -%% NextState} | -%% {next_state, NextStateName, -%% NextState, Timeout} | -%% {stop, Reason, NewState} +-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 -%% the event. +%% the event. Not currently used! %%-------------------------------------------------------------------- -handle_event(#ssl_tls{type = ?HANDSHAKE, fragment = Data}, - StateName, - State0 = #state{key_algorithm = KeyAlg, - 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 - %% message hashes. Starts new handshake (renegotiation) - Hs0 = ssl_handshake:init_hashes(), - ?MODULE:SName(Packet, State#state{tls_handshake_hashes=Hs0, - renegotiation = {true, peer}}); - ({#hello_request{} = Packet, _}, {next_state, SName, State}) -> - %% This message should not be included in handshake - %% message hashes. Already in negotiation so it will be ignored! - ?MODULE:SName(Packet, State); - ({#client_hello{} = Packet, Raw}, {next_state, connection = SName, State}) -> - Hs0 = ssl_handshake:init_hashes(), - Hs1 = ssl_handshake:update_hashes(Hs0, Raw), - ?MODULE:SName(Packet, State#state{tls_handshake_hashes=Hs1, - renegotiation = {true, peer}}); - ({Packet, Raw}, {next_state, SName, State = #state{tls_handshake_hashes=Hs0}}) -> - Hs1 = ssl_handshake:update_hashes(Hs0, Raw), - ?MODULE:SName(Packet, State#state{tls_handshake_hashes=Hs1}); - (_, StopState) -> StopState - end, - try - {Packets, Buf} = ssl_handshake:get_tls_handshake(Data,Buf0, KeyAlg,Version), - Start = {next_state, StateName, State0#state{tls_handshake_buffer = Buf}}, - lists:foldl(Handle, Start, Packets) - catch throw:#alert{} = Alert -> - handle_own_alert(Alert, Version, StateName, State0), - {stop, normal, State0} - end; - -handle_event(#ssl_tls{type = ?APPLICATION_DATA, fragment = Data}, - StateName, State0) -> - case application_data(Data, State0) of - Stop = {stop,_,_} -> - Stop; - State -> - {next_state, StateName, State} - end; - -handle_event(#ssl_tls{type = ?CHANGE_CIPHER_SPEC, fragment = <<1>>} = - _ChangeCipher, - StateName, - State = #state{connection_states = ConnectionStates0}) -> - ?DBG_TERM(_ChangeCipher), - ConnectionStates1 = - ssl_record:activate_pending_connection_state(ConnectionStates0, read), - {next_state, StateName, - next_record(State#state{connection_states = ConnectionStates1})}; - -handle_event(#ssl_tls{type = ?ALERT, fragment = Data}, StateName, State) -> - Alerts = decode_alerts(Data), - ?DBG_TERM(Alerts), - [alert_event(A) || A <- Alerts], - {next_state, StateName, State}; - -handle_event(#alert{level = ?FATAL} = Alert, connection, - #state{from = From, user_application = {_Mon, Pid}, - log_alert = Log, - host = Host, port = Port, session = Session, - role = Role, socket_options = Opts} = State) -> - invalidate_session(Role, Host, Port, Session), - log_alert(Log, connection, Alert), - alert_user(Opts#socket_options.active, Pid, From, Alert, Role), - {stop, normal, State}; -handle_event(#alert{level = ?WARNING, description = ?CLOSE_NOTIFY} = Alert, - connection, #state{from = From, - role = Role, - user_application = {_Mon, Pid}, - socket_options = Opts} = State) -> - alert_user(Opts#socket_options.active, Pid, From, Alert, Role), - {stop, normal, State}; - -handle_event(#alert{level = ?FATAL} = Alert, StateName, - #state{from = From, host = Host, port = Port, session = Session, - log_alert = Log, role = Role} = State) -> - invalidate_session(Role, Host, Port, Session), - log_alert(Log, StateName, Alert), - alert_user(From, Alert, Role), - {stop, normal, State}; -handle_event(#alert{level = ?WARNING, description = ?CLOSE_NOTIFY} = Alert, - _, #state{from = From, role = Role} = State) -> - alert_user(From, Alert, Role), - {stop, normal, State}; - -handle_event(#alert{level = ?WARNING, description = ?NO_RENEGOTIATION} = Alert, StateName, - #state{log_alert = Log, renegotiation = {true, internal}} = State) -> - log_alert(Log, StateName, Alert), - {stop, normal, State}; - -handle_event(#alert{level = ?WARNING, description = ?NO_RENEGOTIATION} = Alert, StateName, - #state{log_alert = Log, renegotiation = {true, From}} = State) -> - log_alert(Log, StateName, Alert), - gen_fsm:reply(From, {error, renegotiation_rejected}), - {next_state, connection, next_record(State)}; - -handle_event(#alert{level = ?WARNING, description = ?USER_CANCELED} = Alert, StateName, - #state{log_alert = Log} = State) -> - log_alert(Log, StateName, Alert), - {next_state, StateName, next_record(State)}. +handle_event(_Event, StateName, State) -> + {next_state, StateName, State}. %%-------------------------------------------------------------------- -%% Function: -%% handle_sync_event(Event, From, StateName, -%% State) -> {next_state, NextStateName, NextState} | -%% {next_state, NextStateName, NextState, -%% Timeout} | -%% {reply, Reply, NextStateName, NextState}| -%% {reply, Reply, NextStateName, NextState, -%% Timeout} | -%% {stop, Reason, NewState} | -%% {stop, Reason, Reply, NewState} +-spec handle_sync_event(term(), from(), state_name(), #state{}) -> + gen_fsm_state_return() | + {reply, reply(), state_name(), #state{}} | + {reply, reply(), state_name(), #state{}, timeout()} | + {stop, reason(), reply(), #state{}}. +%% %% Description: Whenever a gen_fsm receives an event sent using %% gen_fsm:sync_send_all_state_event/2,3, this function is called to handle %% the event. @@ -830,27 +778,53 @@ handle_sync_event({application_data, Data}, From, StateName, #state{send_queue = Queue} = State) -> %% In renegotiation priorities handshake, send data when handshake is finished {next_state, StateName, State#state{send_queue = queue:in({From, Data}, Queue)}}; -handle_sync_event(started, From, StateName, State) -> + +handle_sync_event(start, From, hello, State) -> + hello(start, State#state{from = From}); + +%% The two clauses below could happen if a server upgrades a socket in +%% active mode. Note that in this case we are lucky that +%% controlling_process has been evalueated before receiving handshake +%% messages from client. The server should put the socket in passive +%% mode before telling the client that it is willing to upgrade +%% and before calling ssl:ssl_accept/2. These clauses are +%% here to make sure it is the users problem and not owers if +%% they upgrade a active socket. +handle_sync_event(start, _, connection, State) -> + {reply, connected, connection, State}; +handle_sync_event(start, From, StateName, State) -> {next_state, StateName, State#state{from = From}}; -handle_sync_event(close, From, _StateName, State) -> - {stop, normal, ok, State#state{from = From}}; +handle_sync_event(close, _, _StateName, State) -> + {stop, normal, ok, State}; -handle_sync_event({shutdown, How}, From, StateName, - #state{transport_cb = CbModule, +handle_sync_event({shutdown, How0}, _, StateName, + #state{transport_cb = Transport, + negotiated_version = Version, + connection_states = ConnectionStates, socket = Socket} = State) -> - case CbModule:shutdown(Socket, How) of + case How0 of + How when How == write; How == both -> + Alert = ?ALERT_REC(?WARNING, ?CLOSE_NOTIFY), + {BinMsg, _} = + encode_alert(Alert, Version, ConnectionStates), + Transport:send(Socket, BinMsg); + _ -> + ok + end, + + case Transport:shutdown(Socket, How0) of ok -> {reply, ok, StateName, State}; Error -> - {stop, normal, Error, State#state{from = From}} + {stop, normal, Error, State} end; handle_sync_event({recv, N}, From, connection = StateName, State0) -> passive_receive(State0#state{bytes_to_read = N, from = From}, StateName); %% Doing renegotiate wait with handling request until renegotiate is -%% finished. Will be handled by next_state_connection/1. +%% finished. Will be handled by next_state_connection/2. handle_sync_event({recv, N}, From, StateName, State) -> {next_state, StateName, State#state{bytes_to_read = N, from = From, recv_during_renegotiation = true}}; @@ -888,7 +862,13 @@ handle_sync_event({set_opts, Opts0}, _From, StateName, {reply, ok, StateName, State1}; Buffer =:= <<>>, Opts1#socket_options.active =:= false -> %% Need data, set active once - {reply, ok, StateName, next_record_if_active(State1)}; + {Record, State2} = next_record_if_active(State1), + case next_state(StateName, Record, State2) of + {next_state, StateName, State} -> + {reply, ok, StateName, State}; + {stop, Reason, State} -> + {stop, Reason, State} + end; Buffer =:= <<>> -> %% Active once already set {reply, ok, StateName, State1}; @@ -896,10 +876,15 @@ handle_sync_event({set_opts, Opts0}, _From, StateName, case application_data(<<>>, State1) of Stop = {stop,_,_} -> Stop; - State -> - {reply, ok, StateName, State} + {Record, State2} -> + case next_state(StateName, Record, State2) of + {next_state, StateName, State} -> + {reply, ok, StateName, State}; + {stop, Reason, State} -> + {stop, Reason, State} + end end - end; + end; handle_sync_event(renegotiate, From, connection, State) -> renegotiate(State#state{renegotiation = {true, From}}); @@ -928,31 +913,26 @@ handle_sync_event(peer_certificate, _, StateName, {reply, {ok, Cert}, StateName, State}. %%-------------------------------------------------------------------- -%% Function: -%% handle_info(Info,StateName,State)-> {next_state, NextStateName, NextState}| -%% {next_state, NextStateName, NextState, -%% Timeout} | -%% {stop, Reason, NewState} +-spec handle_info(msg(),state_name(), #state{}) -> + {next_state, state_name(), #state{}}| + {next_state, state_name(), #state{}, timeout()} | + {stop, reason(), #state{}}. +%% %% Description: This function is called by a gen_fsm when it receives any %% other message than a synchronous or asynchronous event %% (or a system message). %%-------------------------------------------------------------------- %% raw data from TCP, unpack records -handle_info({Protocol, _, Data}, StateName, State = +handle_info({Protocol, _, Data}, StateName, #state{data_tag = Protocol, - negotiated_version = Version, - tls_record_buffer = Buf0, - tls_cipher_texts = CT0}) -> - case ssl_record:get_tls_records(Data, Buf0) of - {Records, Buf1} -> - CT1 = CT0 ++ Records, - {next_state, StateName, - next_record(State#state{tls_record_buffer = Buf1, - tls_cipher_texts = CT1})}; + negotiated_version = Version} = State0) -> + case next_tls_record(Data, State0) of + {Record, State} -> + next_state(StateName, Record, State); #alert{} = Alert -> - handle_own_alert(Alert, Version, StateName, State), - {stop, normal, State} + handle_own_alert(Alert, Version, StateName, State0), + {stop, normal, State0} end; handle_info({CloseTag, Socket}, _StateName, @@ -973,16 +953,32 @@ handle_info({CloseTag, Socket}, _StateName, ?ALERT_REC(?WARNING, ?CLOSE_NOTIFY), Role), {stop, normal, State}; +handle_info({ErrorTag, Socket, econnaborted}, StateName, + #state{socket = Socket, from = User, role = Role, + error_tag = ErrorTag} = State) when StateName =/= connection -> + alert_user(User, ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE), Role), + {stop, normal, State}; + +handle_info({ErrorTag, Socket, Reason}, _, + #state{socket = Socket, from = User, + role = Role, error_tag = ErrorTag} = State) -> + Report = io_lib:format("SSL: Socket error: ~p ~n", [Reason]), + error_logger:info_report(Report), + alert_user(User, ?ALERT_REC(?FATAL, ?CLOSE_NOTIFY), Role), + {stop, normal, State}; + handle_info({'DOWN', MonitorRef, _, _, _}, _, State = #state{user_application={MonitorRef,_Pid}}) -> {stop, normal, State}; -handle_info(A, StateName, State) -> - io:format("SSL: Bad info (state ~w): ~w\n", [StateName, A]), - {stop, bad_info, State}. +handle_info(Msg, StateName, State) -> + Report = io_lib:format("SSL: Got unexpected info: ~p ~n", [Msg]), + error_logger:info_report(Report), + {next_state, StateName, State}. %%-------------------------------------------------------------------- -%% Function: terminate(Reason, StateName, State) -> void() +-spec terminate(reason(), state_name(), #state{}) -> term(). +%% %% Description:This function is called by a gen_fsm when it is about %% to terminate. It should be the opposite of Module:init/1 and do any %% necessary cleaning up. When it returns, the gen_fsm terminates with @@ -998,16 +994,19 @@ terminate(_Reason, connection, #state{negotiated_version = Version, {BinAlert, _} = encode_alert(?ALERT_REC(?WARNING,?CLOSE_NOTIFY), Version, ConnectionStates), Transport:send(Socket, BinAlert), + workaround_transport_delivery_problems(Socket, Transport), Transport:close(Socket); terminate(_Reason, _StateName, #state{transport_cb = Transport, socket = Socket, send_queue = SendQueue, renegotiation = Renegotiate}) -> notify_senders(SendQueue), notify_renegotiater(Renegotiate), + workaround_transport_delivery_problems(Socket, Transport), Transport:close(Socket). %%-------------------------------------------------------------------- -%% Function: +-spec code_change(term(), state_name(), #state{}, list()) -> {ok, state_name(), #state{}}. +%% %% code_change(OldVsn, StateName, State, Extra) -> {ok, StateName, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- @@ -1017,126 +1016,124 @@ code_change(_OldVsn, StateName, State, _Extra) -> %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- -start_fsm(Role, Host, Port, Socket, Opts, User, {CbModule, _,_} = CbInfo, +start_fsm(Role, Host, Port, Socket, Opts, User, {CbModule, _,_, _} = CbInfo, Timeout) -> - case ssl_connection_sup:start_child([Role, Host, Port, Socket, - Opts, User, CbInfo]) of - {ok, Pid} -> - CbModule:controlling_process(Socket, Pid), - send_event(Pid, socket_control), - case sync_send_all_state_event(Pid, started, Timeout) of - connected -> - {ok, sslsocket(Pid)}; - {error, Reason} -> - {error, Reason} - end; - {error, Reason} -> - {error, Reason} + try + {ok, Pid} = ssl_connection_sup:start_child([Role, Host, Port, Socket, + Opts, User, CbInfo]), + {ok, SslSocket} = socket_control(Socket, Pid, CbModule), + ok = handshake(SslSocket, Timeout), + {ok, SslSocket} + catch + error:{badmatch, {error, _} = Error} -> + Error end. - + ssl_init(SslOpts, Role) -> {ok, CertDbRef, CacheRef, OwnCert} = init_certificates(SslOpts, Role), PrivateKey = init_private_key(SslOpts#ssl_options.key, SslOpts#ssl_options.keyfile, SslOpts#ssl_options.password, Role), - DHParams = init_diffie_hellman(SslOpts#ssl_options.dhfile, Role), + DHParams = init_diffie_hellman(SslOpts#ssl_options.dh, 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, {badmatch, _Error}} -> - Report = io_lib:format("SSL: Error ~p Initializing: ~p ~n", - [_Error, CACertFile]), - error_logger:error_report(Report), - throw(ecacertfile); - {error, _Error} -> - Report = io_lib:format("SSL: Error ~p Initializing: ~p ~n", - [_Error, CACertFile]), - error_logger:error_report(Report), - throw(ecacertfile) - end. -init_certificates(CertDbRef, CacheRef, CertFile, client) -> +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(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} catch - _E:{badmatch, _R={error,_}} -> - Report = io_lib:format("SSL: ~p: ~p:~p ~s~n ~p~n", - [?LINE, _E,_R, CertFile, - erlang:get_stacktrace()]), - error_logger:error_report(Report), - throw(ecertfile); - _E:_R -> - Report = io_lib:format("SSL: ~p: ~p:~p ~s~n ~p~n", - [?LINE, _E,_R, CertFile, - erlang:get_stacktrace()]), - error_logger:error_report(Report), - throw(ecertfile) - end. + Error:Reason -> + handle_file_error(?LINE, Error, Reason, CertFile, ecertfile, + erlang:get_stacktrace()) + end; +init_certificates(Cert, CertDbRef, CacheRef, _, _) -> + {ok, CertDbRef, CacheRef, Cert}. init_private_key(undefined, "", _Password, client) -> undefined; init_private_key(undefined, KeyFile, Password, _) -> - try - {ok, List} = ssl_manager:cache_pem_file(KeyFile), - [Der] = [Der || Der = {PKey, _ , _} <- List, - PKey =:= rsa_private_key orelse - PKey =:= dsa_private_key], - {ok, Decoded} = public_key:decode_private_key(Der,Password), - Decoded - catch - _E:{badmatch, _R={error,_}} -> - Report = io_lib:format("SSL: ~p: ~p:~p ~s~n ~p~n", - [?LINE, _E,_R, KeyFile, - erlang:get_stacktrace()]), - error_logger:error_report(Report), - throw(ekeyfile); - _E:_R -> - Report = io_lib:format("SSL: ~p: ~p:~p ~s~n ~p~n", - [?LINE, _E,_R, KeyFile, - erlang:get_stacktrace()]), - error_logger:error_report(Report), - throw(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_diffie_hellman(_, client) -> - undefined; -init_diffie_hellman(undefined, _) -> - ?DEFAULT_DIFFIE_HELLMAN_PARAMS; -init_diffie_hellman(DHParamFile, server) -> - {ok, List} = ssl_manager:cache_pem_file(DHParamFile), - case [Der || Der = {dh_params, _ , _} <- List] of - [Der] -> - {ok, Decoded} = public_key:decode_dhparams(Der), - Decoded; - [] -> - ?DEFAULT_DIFFIE_HELLMAN_PARAMS - end. +init_private_key({rsa, PrivateKey}, _, _,_) -> + public_key:der_decode('RSAPrivateKey', PrivateKey); +init_private_key({dsa, PrivateKey},_,_,_) -> + public_key:der_decode('DSAPrivateKey', PrivateKey). -send_event(FsmPid, Event) -> - gen_fsm:send_event(FsmPid, Event). +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]), + error_logger:error_report(Report), + throw(Throw). -send_all_state_event(FsmPid, Event) -> - gen_fsm:send_all_state_event(FsmPid, Event). +init_diffie_hellman(Params, _,_) when is_binary(Params)-> + public_key:der_decode('DHParameter', Params); +init_diffie_hellman(_,_, client) -> + undefined; +init_diffie_hellman(_,undefined, _) -> + ?DEFAULT_DIFFIE_HELLMAN_PARAMS; +init_diffie_hellman(_, DHParamFile, server) -> + 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) -> - sync_send_all_state_event(FsmPid, Event, ?DEFAULT_TIMEOUT). + sync_send_all_state_event(FsmPid, Event, infinity). sync_send_all_state_event(FsmPid, Event, Timeout) -> try gen_fsm:sync_send_all_state_event(FsmPid, Event, Timeout) @@ -1146,22 +1143,21 @@ sync_send_all_state_event(FsmPid, Event, Timeout) -> exit:{timeout, _} -> {error, timeout}; exit:{normal, _} -> + {error, closed}; + exit:{shutdown, _} -> {error, closed} end. -%% Events: #alert{} -alert_event(Alert) -> - send_all_state_event(self(), Alert). - %% We do currently not support cipher suites that use fixed DH. %% If we want to implement that we should add a code %% here to extract DH parameters form cert. handle_peer_cert(PeerCert, PublicKeyInfo, #state{session = Session} = State0) -> - State = State0#state{session = + State1 = State0#state{session = Session#session{peer_certificate = PeerCert}, public_key_info = PublicKeyInfo}, - {next_state, certify, next_record(State)}. + {Record, State} = next_record(State1), + next_state(certify, Record, State). certify_client(#state{client_certificate_requested = true, role = client, connection_states = ConnectionStates0, @@ -1193,82 +1189,117 @@ verify_client_cert(#state{client_certificate_requested = true, role = client, case ssl_handshake:client_certificate_verify(OwnCert, MasterSecret, Version, KeyAlg, PrivateKey, Hashes0) of - ignore -> %% No key or cert or fixed_diffie_hellman - State; - Verified -> + #certificate_verify{} = Verified -> {BinVerified, ConnectionStates1, Hashes1} = encode_handshake(Verified, KeyAlg, Version, ConnectionStates0, Hashes0), Transport:send(Socket, BinVerified), State#state{connection_states = ConnectionStates1, - tls_handshake_hashes = Hashes1} + tls_handshake_hashes = Hashes1}; + ignore -> + State; + #alert{} = Alert -> + handle_own_alert(Alert, Version, certify, State) + end; verify_client_cert(#state{client_certificate_requested = false} = State) -> State. do_server_hello(Type, #state{negotiated_version = Version, - session = Session, - connection_states = ConnectionStates0} + 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, - ConnectionStates0), - State = server_hello(ServerHello, State0), + ssl_handshake:server_hello(SessId, Version, + ConnectionStates0, Renegotiation), + State1 = server_hello(ServerHello, State0), case Type of new -> - do_server_hello(ServerHello, State); + new_server_hello(ServerHello, State1); resumed -> + ConnectionStates1 = State1#state.connection_states, case ssl_handshake:master_secret(Version, Session, - ConnectionStates0, server) of - {_, ConnectionStates1} -> - State1 = State#state{connection_states=ConnectionStates1, - session = Session}, + ConnectionStates1, server) of + {_, ConnectionStates2} -> + State2 = State1#state{connection_states=ConnectionStates2, + session = Session}, {ConnectionStates, Hashes} = - finalize_server_handshake(State1), - Resumed = State1#state{connection_states = - ConnectionStates, - tls_handshake_hashes = Hashes}, - {next_state, abbreviated, next_record(Resumed)}; + finalize_handshake(State2, abbreviated), + State3 = State2#state{connection_states = + ConnectionStates, + tls_handshake_hashes = Hashes}, + {Record, State} = next_record(State3), + next_state(abbreviated, Record, State); #alert{} = Alert -> - handle_own_alert(Alert, Version, hello, State), - {stop, normal, State} + 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, negotiated_version = Version} = State0) -> try server_certify_and_key_exchange(State0) of #state{} = State1 -> - State = server_hello_done(State1), + State2 = server_hello_done(State1), Session = Session0#session{session_id = SessionId, cipher_suite = CipherSuite, compression_method = Compression}, - {next_state, certify, State#state{session = Session}} + {Record, State} = next_record(State2#state{session = Session}), + next_state(certify, Record, State) catch #alert{} = Alert -> handle_own_alert(Alert, Version, hello, State0), {stop, normal, State0} end. +handle_new_session(NewId, CipherSuite, Compression, #state{session = Session0} = State0) -> + Session = Session0#session{session_id = NewId, + cipher_suite = CipherSuite, + compression_method = Compression}, + {Record, State} = next_record(State0#state{session = Session}), + next_state(certify, Record, State). + +handle_resumed_session(SessId, #state{connection_states = ConnectionStates0, + negotiated_version = Version, + host = Host, port = Port, + session_cache = Cache, + session_cache_cb = CacheCb} = State0) -> + Session = CacheCb:lookup(Cache, {{Host, Port}, SessId}), + case ssl_handshake:master_secret(Version, Session, + ConnectionStates0, client) of + {_, ConnectionStates1} -> + {Record, State} = + next_record(State0#state{ + connection_states = ConnectionStates1, + session = Session}), + next_state(abbreviated, Record, State); + #alert{} = Alert -> + handle_own_alert(Alert, Version, hello, State0), + {stop, normal, State0} + end. + + client_certify_and_key_exchange(#state{negotiated_version = Version} = State0) -> try do_client_certify_and_key_exchange(State0) of State1 = #state{} -> - {ConnectionStates, Hashes} = finalize_client_handshake(State1), - State = State1#state{connection_states = ConnectionStates, + {ConnectionStates, Hashes} = finalize_handshake(State1, certify), + State2 = State1#state{connection_states = ConnectionStates, %% Reinitialize client_certificate_requested = false, tls_handshake_hashes = Hashes}, - {next_state, cipher, next_record(State)} - + {Record, State} = next_record(State2), + next_state(cipher, Record, State) catch #alert{} = Alert -> - handle_own_alert(Alert, Version, certify_foo, State0), + handle_own_alert(Alert, Version, client_certify_and_key_exchange, State0), {stop, normal, State0} end. @@ -1288,8 +1319,7 @@ server_hello(ServerHello, #state{transport_cb = Transport, connection_states = ConnectionStates0, tls_handshake_hashes = Hashes0} = State) -> CipherSuite = ServerHello#server_hello.cipher_suite, - {KeyAlgorithm, _, _, _} = ssl_cipher:suite_definition(CipherSuite), - %% Version = ServerHello#server_hello.server_version, TODO ska kontrolleras + {KeyAlgorithm, _, _} = ssl_cipher:suite_definition(CipherSuite), {BinMsg, ConnectionStates1, Hashes1} = encode_handshake(ServerHello, Version, ConnectionStates0, Hashes0), Transport:send(Socket, BinMsg), @@ -1301,17 +1331,16 @@ server_hello_done(#state{transport_cb = Transport, socket = Socket, negotiated_version = Version, connection_states = ConnectionStates, - tls_handshake_hashes = Hashes} = State0) -> + tls_handshake_hashes = Hashes} = State) -> HelloDone = ssl_handshake:server_hello_done(), - + {BinHelloDone, NewConnectionStates, NewHashes} = encode_handshake(HelloDone, Version, ConnectionStates, Hashes), Transport:send(Socket, BinHelloDone), - State = State0#state{connection_states = NewConnectionStates, - tls_handshake_hashes = NewHashes}, - next_record(State). - + State#state{connection_states = NewConnectionStates, + tls_handshake_hashes = NewHashes}. + certify_server(#state{transport_cb = Transport, socket = Socket, negotiated_version = Version, @@ -1332,20 +1361,10 @@ certify_server(#state{transport_cb = Transport, throw(Alert) end. -key_exchange(#state{role = server, key_algorithm = Algo} = State) - when Algo == rsa; - Algo == dh_dss; - Algo == dh_rsa -> +key_exchange(#state{role = server, key_algorithm = rsa} = State) -> State; - -%key_exchange(#state{role = server, key_algorithm = rsa_export} = State) -> - %% TODO when the public key in the server certificate is - %% less than or equal to 512 bits in length dont send key_exchange - %% but do it otherwise -% 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,11 +1373,9 @@ key_exchange(#state{role = server, key_algorithm = Algo, transport_cb = Transport } = State) when Algo == dhe_dss; - Algo == dhe_dss_export; - Algo == dhe_rsa; - Algo == dhe_rsa_export -> + 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, @@ -1394,7 +1411,6 @@ key_exchange(#state{role = client, Transport:send(Socket, BinMsg), State#state{connection_states = ConnectionStates1, tls_handshake_hashes = Hashes1}; - key_exchange(#state{role = client, connection_states = ConnectionStates0, key_algorithm = Algorithm, @@ -1403,34 +1419,16 @@ key_exchange(#state{role = client, socket = Socket, transport_cb = Transport, tls_handshake_hashes = Hashes0} = State) when Algorithm == dhe_dss; - Algorithm == dhe_dss_export; - Algorithm == dhe_rsa; - Algorithm == dhe_rsa_export -> + Algorithm == dhe_rsa -> Msg = ssl_handshake:key_exchange(client, {dh, DhPubKey}), {BinMsg, ConnectionStates1, Hashes1} = encode_handshake(Msg, Version, ConnectionStates0, Hashes0), Transport:send(Socket, BinMsg), State#state{connection_states = ConnectionStates1, - tls_handshake_hashes = Hashes1}; - -key_exchange(#state{role = client, - connection_states = ConnectionStates0, - key_algorithm = Algorithm, - negotiated_version = Version, - client_certificate_requested = ClientCertReq, - own_cert = OwnCert, - diffie_hellman_keys = DhKeys, - socket = Socket, transport_cb = Transport, - tls_handshake_hashes = Hashes0} = State) - when Algorithm == dh_dss; - Algorithm == dh_rsa -> - Msg = dh_key_exchange(OwnCert, DhKeys, ClientCertReq), - {BinMsg, ConnectionStates1, Hashes1} = - encode_handshake(Msg, Version, ConnectionStates0, Hashes0), - Transport:send(Socket, BinMsg), - 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; @@ -1442,17 +1440,6 @@ rsa_key_exchange(PremasterSecret, PublicKeyInfo = {Algorithm, _, _}) rsa_key_exchange(_, _) -> throw (?ALERT_REC(?FATAL,?HANDSHAKE_FAILURE)). -dh_key_exchange(OwnCert, DhKeys, true) -> - case public_key:pkix_is_fixed_dh_cert(OwnCert) of - true -> - ssl_handshake:key_exchange(client, fixed_diffie_hellman); - false -> - {DhPubKey, _} = DhKeys, - ssl_handshake:key_exchange(client, {dh, DhPubKey}) - end; -dh_key_exchange(_, {DhPubKey, _}, false) -> - ssl_handshake:key_exchange(client, {dh, DhPubKey}). - request_client_cert(#state{ssl_options = #ssl_options{verify = verify_peer}, connection_states = ConnectionStates0, cert_db_ref = CertDbRef, @@ -1471,45 +1458,44 @@ request_client_cert(#state{ssl_options = #ssl_options{verify = verify_none}} = State) -> State. -finalize_client_handshake(#state{connection_states = ConnectionStates0} - = State) -> - ConnectionStates1 = - cipher_protocol(State#state{connection_states = - ConnectionStates0}), - ConnectionStates2 = - ssl_record:activate_pending_connection_state(ConnectionStates1, +finalize_handshake(State, StateName) -> + ConnectionStates0 = cipher_protocol(State), + ConnectionStates = + ssl_record:activate_pending_connection_state(ConnectionStates0, write), - finished(State#state{connection_states = ConnectionStates2}). + finished(State#state{connection_states = ConnectionStates}, StateName). - -finalize_server_handshake(State) -> - ConnectionStates0 = cipher_protocol(State), - ConnectionStates = - ssl_record:activate_pending_connection_state(ConnectionStates0, - write), - finished(State#state{connection_states = ConnectionStates}). - -cipher_protocol(#state{connection_states = ConnectionStates, +cipher_protocol(#state{connection_states = ConnectionStates0, socket = Socket, negotiated_version = Version, transport_cb = Transport}) -> - {BinChangeCipher, NewConnectionStates} = + {BinChangeCipher, ConnectionStates} = encode_change_cipher(#change_cipher_spec{}, - Version, ConnectionStates), + Version, ConnectionStates0), Transport:send(Socket, BinChangeCipher), - NewConnectionStates. + ConnectionStates. finished(#state{role = Role, socket = Socket, negotiated_version = Version, transport_cb = Transport, session = Session, - connection_states = ConnectionStates, - tls_handshake_hashes = Hashes}) -> + connection_states = ConnectionStates0, + tls_handshake_hashes = Hashes0}, StateName) -> MasterSecret = Session#session.master_secret, - Finished = ssl_handshake:finished(Version, Role, MasterSecret, Hashes), - {BinFinished, NewConnectionStates, NewHashes} = - encode_handshake(Finished, Version, ConnectionStates, Hashes), + Finished = ssl_handshake:finished(Version, Role, MasterSecret, Hashes0), + ConnectionStates1 = save_verify_data(Role, Finished, ConnectionStates0, StateName), + {BinFinished, ConnectionStates, Hashes} = + encode_handshake(Finished, Version, ConnectionStates1, Hashes0), Transport:send(Socket, BinFinished), - {NewConnectionStates, NewHashes}. + {ConnectionStates, Hashes}. + +save_verify_data(client, #finished{verify_data = Data}, ConnectionStates, certify) -> + ssl_record:set_client_verify_data(current_write, Data, ConnectionStates); +save_verify_data(server, #finished{verify_data = Data}, ConnectionStates, cipher) -> + ssl_record:set_server_verify_data(current_both, Data, ConnectionStates); +save_verify_data(client, #finished{verify_data = Data}, ConnectionStates, abbreviated) -> + ssl_record:set_client_verify_data(current_both, Data, ConnectionStates); +save_verify_data(server, #finished{verify_data = Data}, ConnectionStates, abbreviated) -> + ssl_record:set_server_verify_data(current_write, Data, ConnectionStates). handle_server_key( #server_key_exchange{params = @@ -1563,15 +1549,34 @@ handle_server_key( ?ALERT_REC(?FATAL,?HANDSHAKE_FAILURE) end. -verify_dh_params(Signed, Hash, {?rsaEncryption, PubKey, _PubKeyparams}) -> + +verify_dh_params(Signed, Hashes, {?rsaEncryption, PubKey, _PubKeyParams}) -> case public_key:decrypt_public(Signed, PubKey, [{rsa_pad, rsa_pkcs1_padding}]) of - Hash -> + Hashes -> true; _ -> false - end. + end; +verify_dh_params(Signed, Hash, {?'id-dsa', PublicKey, PublicKeyParams}) -> + public_key:verify(Hash, none, Signed, {PublicKey, PublicKeyParams}). + +cipher_role(client, Data, Session, #state{connection_states = ConnectionStates0} = State) -> + ConnectionStates = ssl_record:set_server_verify_data(current_both, Data, ConnectionStates0), + next_state_connection(cipher, ack_connection(State#state{session = Session, + connection_states = ConnectionStates})); + +cipher_role(server, Data, Session, #state{connection_states = ConnectionStates0} = State) -> + ConnectionStates1 = ssl_record:set_client_verify_data(current_read, Data, ConnectionStates0), + {ConnectionStates, Hashes} = + finalize_handshake(State#state{connection_states = ConnectionStates1, + session = Session}, cipher), + next_state_connection(cipher, ack_connection(State#state{connection_states = + ConnectionStates, + session = Session, + tls_handshake_hashes = + Hashes})). encode_alert(#alert{} = Alert, Version, ConnectionStates) -> ?DBG_TERM(Alert), ssl_record:encode_alert_record(Alert, Version, ConnectionStates). @@ -1581,7 +1586,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) -> @@ -1622,14 +1627,14 @@ decode_alerts(<<>>, Acc) -> passive_receive(State0 = #state{user_data_buffer = Buffer}, StateName) -> case Buffer of <<>> -> - State = next_record(State0), - {next_state, StateName, State}; + {Record, State} = next_record(State0), + next_state(StateName, Record, State); _ -> case application_data(<<>>, State0) of Stop = {stop, _, _} -> Stop; - State -> - {next_state, StateName, State} + {Record, State} -> + next_state(StateName, Record, State) end end. @@ -1644,8 +1649,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, @@ -1654,19 +1657,23 @@ application_data(Data, #state{user_application = {_Mon, Pid}, socket_options = SocketOpt }, if - SocketOpt#socket_options.active =:= false -> - State; %% Passive mode, wait for active once or recv - Buffer =:= <<>> -> %% Active and empty, get more data - next_record(State); - true -> %% We have more data - application_data(<<>>, State) + SocketOpt#socket_options.active =:= false; Buffer =:= <<>> -> + %% Passive mode, wait for active once or recv + %% Active and empty, get more data + next_record_if_active(State); + 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 @@ -1679,13 +1686,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. @@ -1727,33 +1734,42 @@ deliver_app_data(SOpts = #socket_options{active=Active, packet=Type}, SO end. -format_reply(#socket_options{active=false, mode=Mode, header=Header}, Data) -> - {ok, format_reply(Mode, Header, Data)}; -format_reply(#socket_options{active=_, mode=Mode, header=Header}, Data) -> - {ssl, sslsocket(), format_reply(Mode, Header, Data)}. +format_reply(#socket_options{active = false, mode = Mode, packet = Packet, + header = Header}, Data) -> + {ok, format_reply(Mode, Packet, Header, Data)}; +format_reply(#socket_options{active = _, mode = Mode, packet = Packet, + header = Header}, Data) -> + {ssl, sslsocket(), format_reply(Mode, Packet, Header, Data)}. -deliver_packet_error(SO= #socket_options{active=Active}, Data, Pid, From) -> +deliver_packet_error(SO= #socket_options{active = Active}, Data, Pid, From) -> send_or_reply(Active, Pid, From, format_packet_error(SO, Data)). -format_packet_error(#socket_options{active=false, mode=Mode}, Data) -> - {error, {invalid_packet, format_reply(Mode, raw, Data)}}; -format_packet_error(#socket_options{active=_, mode=Mode}, Data) -> - {ssl_error, sslsocket(), {invalid_packet, format_reply(Mode, raw, Data)}}. - -format_reply(list, _, Data) -> binary_to_list(Data); -format_reply(binary, 0, Data) -> Data; -format_reply(binary, raw, Data) -> Data; -format_reply(binary, N, Data) -> % Header mode - <<Header:N/binary, Rest/binary>> = Data, - [binary_to_list(Header), Rest]. - -%% tcp_closed -send_or_reply(false, _Pid, undefined, _Data) -> - Report = io_lib:format("SSL(debug): Unexpected Data ~p ~n",[_Data]), - error_logger:error_report(Report), - erlang:error({badarg, _Pid, undefined, _Data}), - ok; -send_or_reply(false, _Pid, From, Data) -> +format_packet_error(#socket_options{active = false, mode = Mode}, Data) -> + {error, {invalid_packet, format_reply(Mode, raw, 0, Data)}}; +format_packet_error(#socket_options{active = _, mode = Mode}, Data) -> + {ssl_error, sslsocket(), {invalid_packet, format_reply(Mode, raw, 0, 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 Packet == http; Packet == {http, headers}; Packet == http_bin; Packet == {http_bin, headers} -> + Data; +format_reply(list, _,_, Data) -> + binary_to_list(Data). + +header(0, <<>>) -> + <<>>; +header(_, <<>>) -> + []; +header(0, Binary) -> + Binary; +header(N, Binary) -> + <<?BYTE(ByteN), NewBinary/binary>> = Binary, + [ByteN | header(N-1, NewBinary)]. + +send_or_reply(false, _Pid, From, Data) when From =/= undefined -> gen_fsm:reply(From, Data); send_or_reply(_, Pid, _From, Data) -> send_user(Pid, Data). @@ -1766,40 +1782,132 @@ opposite_role(server) -> send_user(Pid, Msg) -> Pid ! Msg. -next_record(#state{tls_cipher_texts = [], socket = Socket} = State) -> +handle_tls_handshake(Handle, StateName, #state{tls_packets = [Packet]} = State) -> + FsmReturn = {next_state, StateName, State#state{tls_packets = []}}, + Handle(Packet, FsmReturn); + +handle_tls_handshake(Handle, StateName, #state{tls_packets = [Packet | Packets]} = State0) -> + FsmReturn = {next_state, StateName, State0#state{tls_packets = Packets}}, + case Handle(Packet, FsmReturn) of + {next_state, NextStateName, State} -> + handle_tls_handshake(Handle, NextStateName, State); + {stop, _,_} = Stop -> + Stop + end. + +next_state(_, #alert{} = Alert, #state{negotiated_version = Version} = State) -> + handle_own_alert(Alert, Version, decipher_error, State), + {stop, normal, State}; + +next_state(Next, no_record, State) -> + {next_state, Next, State}; + +next_state(Next, #ssl_tls{type = ?ALERT, fragment = EncAlerts}, State) -> + Alerts = decode_alerts(EncAlerts), + handle_alerts(Alerts, {next_state, Next, State}); + +next_state(StateName, #ssl_tls{type = ?HANDSHAKE, fragment = Data}, + 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 + %% message hashes. Starts new handshake (renegotiation) + Hs0 = ssl_handshake:init_hashes(), + ?MODULE:SName(Packet, State#state{tls_handshake_hashes=Hs0, + renegotiation = {true, peer}}); + ({#hello_request{} = Packet, _}, {next_state, SName, State}) -> + %% This message should not be included in handshake + %% message hashes. Already in negotiation so it will be ignored! + ?MODULE:SName(Packet, State); + ({#client_hello{} = Packet, Raw}, {next_state, connection = SName, State}) -> + Hs0 = ssl_handshake:init_hashes(), + Hs1 = ssl_handshake:update_hashes(Hs0, Raw), + ?MODULE:SName(Packet, State#state{tls_handshake_hashes=Hs1, + renegotiation = {true, peer}}); + ({Packet, Raw}, {next_state, SName, State = #state{tls_handshake_hashes=Hs0}}) -> + Hs1 = ssl_handshake:update_hashes(Hs0, Raw), + ?MODULE:SName(Packet, State#state{tls_handshake_hashes=Hs1}); + (_, StopState) -> StopState + end, + try + {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 -> + handle_own_alert(Alert, Version, StateName, State0), + {stop, normal, State0} + end; + +next_state(StateName, #ssl_tls{type = ?APPLICATION_DATA, fragment = Data}, State0) -> + case application_data(Data, State0) of + Stop = {stop,_,_} -> + Stop; + {Record, State} -> + next_state(StateName, Record, State) + end; +next_state(StateName, #ssl_tls{type = ?CHANGE_CIPHER_SPEC, fragment = <<1>>} = + _ChangeCipher, + #state{connection_states = ConnectionStates0} = State0) -> + ?DBG_TERM(_ChangeCipher), + ConnectionStates1 = + ssl_record:activate_pending_connection_state(ConnectionStates0, read), + {Record, State} = next_record(State0#state{connection_states = ConnectionStates1}), + next_state(StateName, Record, State); +next_state(StateName, #ssl_tls{type = _Unknown}, State0) -> + %% Ignore unknown type + {Record, State} = next_record(State0), + next_state(StateName, Record, State). + +next_tls_record(Data, #state{tls_record_buffer = Buf0, + tls_cipher_texts = CT0} = State0) -> + case ssl_record:get_tls_records(Data, Buf0) of + {Records, Buf1} -> + CT1 = CT0 ++ Records, + next_record(State0#state{tls_record_buffer = Buf1, + tls_cipher_texts = CT1}); + #alert{} = Alert -> + Alert + end. + +next_record(#state{tls_packets = [], tls_cipher_texts = [], socket = Socket} = State) -> inet:setopts(Socket, [{active,once}]), - State; -next_record(#state{tls_cipher_texts = [CT | Rest], + {no_record, State}; +next_record(#state{tls_packets = [], tls_cipher_texts = [CT | Rest], connection_states = ConnStates0} = State) -> - {Plain, ConnStates} = ssl_record:decode_cipher_text(CT, ConnStates0), - gen_fsm:send_all_state_event(self(), Plain), - State#state{tls_cipher_texts = Rest, connection_states = ConnStates}. - + case ssl_record:decode_cipher_text(CT, ConnStates0) of + {Plain, ConnStates} -> + {Plain, State#state{tls_cipher_texts = Rest, connection_states = ConnStates}}; + #alert{} = Alert -> + {Alert, State} + end; +next_record(State) -> + {no_record, State}. next_record_if_active(State = #state{socket_options = #socket_options{active = false}}) -> - State; + {no_record ,State}; next_record_if_active(State) -> next_record(State). -next_state_connection(#state{send_queue = Queue0, - negotiated_version = Version, - socket = Socket, - transport_cb = Transport, - connection_states = ConnectionStates0, - ssl_options = #ssl_options{renegotiate_at = RenegotiateAt} - } = State) -> +next_state_connection(StateName, #state{send_queue = Queue0, + negotiated_version = Version, + socket = Socket, + transport_cb = Transport, + connection_states = ConnectionStates0, + ssl_options = #ssl_options{renegotiate_at = RenegotiateAt} + } = State) -> %% Send queued up data case queue:out(Queue0) of {{value, {From, Data}}, Queue} -> case encode_data(Data, Version, ConnectionStates0, RenegotiateAt) of {Msgs, [], ConnectionStates} -> Result = Transport:send(Socket, Msgs), - gen_fsm:reply(From, Result), - next_state_connection(State#state{connection_states = ConnectionStates, - send_queue = Queue}); + gen_fsm:reply(From, Result), + next_state_connection(StateName, + State#state{connection_states = ConnectionStates, + send_queue = Queue}); %% This is unlikely to happen. User configuration of the %% undocumented test option renegotiation_at can make it more likely. {Msgs, RestData, ConnectionStates} -> @@ -1822,9 +1930,9 @@ next_state_is_connection(State = #socket_options{active = false}}) -> passive_receive(State#state{recv_during_renegotiation = false}, connection); -next_state_is_connection(State) -> - {next_state, connection, next_record_if_active(State)}. - +next_state_is_connection(State0) -> + {Record, State} = next_record_if_active(State0), + next_state(connection, Record, State). register_session(_, _, _, #session{is_resumable = true} = Session) -> Session; %% Already registered @@ -1843,7 +1951,7 @@ invalidate_session(server, _, Port, Session) -> ssl_manager:invalidate_session(Port, Session). initial_state(Role, Host, Port, Socket, {SSLOptions, SocketOptions}, User, - {CbModule, DataTag, CloseTag}) -> + {CbModule, DataTag, CloseTag, ErrorTag}) -> ConnectionStates = ssl_record:init_connection_states(Role), SessionCacheCb = case application:get_env(ssl, session_cb) of @@ -1863,6 +1971,7 @@ initial_state(Role, Host, Port, Socket, {SSLOptions, SocketOptions}, User, transport_cb = CbModule, data_tag = DataTag, close_tag = CloseTag, + error_tag = ErrorTag, role = Role, host = Host, port = Port, @@ -1934,10 +2043,61 @@ set_socket_opts(Socket, [{active, Active}| Opts], SockOpts, Other) -> set_socket_opts(Socket, [Opt | Opts], SockOpts, Other) -> set_socket_opts(Socket, Opts, SockOpts, [Opt | Other]). +handle_alerts([], Result) -> + Result; +handle_alerts(_, {stop, _, _} = Stop) -> + %% If it is a fatal alert immediately close + Stop; +handle_alerts([Alert | Alerts], {next_state, StateName, State}) -> + handle_alerts(Alerts, handle_alert(Alert, StateName, State)). + +handle_alert(#alert{level = ?FATAL} = Alert, StateName, + #state{from = From, host = Host, port = Port, session = Session, + user_application = {_Mon, Pid}, + log_alert = Log, role = Role, socket_options = Opts} = State) -> + invalidate_session(Role, Host, Port, Session), + log_alert(Log, StateName, Alert), + alert_user(StateName, Opts, Pid, From, Alert, Role), + {stop, normal, State}; + +handle_alert(#alert{level = ?WARNING, description = ?CLOSE_NOTIFY} = Alert, + StateName, #state{from = From, role = Role, + user_application = {_Mon, Pid}, socket_options = Opts} = State) -> + alert_user(StateName, Opts, Pid, From, Alert, Role), + {stop, normal, State}; + +handle_alert(#alert{level = ?WARNING, description = ?NO_RENEGOTIATION} = Alert, StateName, + #state{log_alert = Log, renegotiation = {true, internal}, from = From, + role = Role} = State) -> + log_alert(Log, StateName, Alert), + alert_user(From, Alert, Role), + {stop, normal, State}; + +handle_alert(#alert{level = ?WARNING, description = ?NO_RENEGOTIATION} = Alert, StateName, + #state{log_alert = Log, renegotiation = {true, From}} = State0) -> + log_alert(Log, StateName, Alert), + gen_fsm:reply(From, {error, renegotiation_rejected}), + {Record, State} = next_record(State0), + next_state(connection, Record, State); + +handle_alert(#alert{level = ?WARNING, description = ?USER_CANCELED} = Alert, StateName, + #state{log_alert = Log} = State0) -> + log_alert(Log, StateName, Alert), + {Record, State} = next_record(State0), + next_state(StateName, Record, State). + +alert_user(connection, Opts, Pid, From, Alert, Role) -> + alert_user(Opts#socket_options.active, Pid, From, Alert, Role); +alert_user(_, _, _, From, Alert, Role) -> + alert_user(From, Alert, Role). + alert_user(From, Alert, Role) -> alert_user(false, no_pid, From, Alert, Role). alert_user(false = Active, Pid, From, Alert, Role) -> + %% If there is an outstanding ssl_accept | recv + %% From will be defined and send_or_reply will + %% send the appropriate error message. ReasonCode = ssl_alert:reason_code(Alert, Role), send_or_reply(Active, Pid, From, {error, ReasonCode}); alert_user(Active, Pid, From, Alert, Role) -> @@ -1950,13 +2110,13 @@ alert_user(Active, Pid, From, Alert, Role) -> {ssl_error, sslsocket(), ReasonCode}) end. -log_alert(true, StateName, Alert) -> +log_alert(true, Info, Alert) -> Txt = ssl_alert:alert_txt(Alert), - error_logger:format("SSL: ~p: ~s\n", [StateName, Txt]); + error_logger:format("SSL: ~p: ~s\n", [Info, Txt]); log_alert(false, _, _) -> ok. -handle_own_alert(Alert, Version, StateName, +handle_own_alert(Alert, Version, Info, #state{transport_cb = Transport, socket = Socket, from = User, @@ -1965,20 +2125,25 @@ handle_own_alert(Alert, Version, StateName, log_alert = Log}) -> try %% Try to tell the other side {BinMsg, _} = - encode_alert(Alert, Version, ConnectionStates), + encode_alert(Alert, Version, ConnectionStates), + linux_workaround_transport_delivery_problems(Alert, Socket), Transport:send(Socket, BinMsg) catch _:_ -> %% Can crash if we are in a uninitialized state ignore end, try %% Try to tell the local user - log_alert(Log, StateName, Alert), + log_alert(Log, Info, Alert), alert_user(User, Alert, Role) catch _:_ -> ok end. -make_premaster_secret({MajVer, MinVer}, Alg) when Alg == rsa; - Alg == dh_dss; - Alg == dh_rsa -> + +handle_unexpected_message(Msg, Info, #state{negotiated_version = Version} = State) -> + Alert = ?ALERT_REC(?FATAL,?UNEXPECTED_MESSAGE), + handle_own_alert(Alert, Version, {Info, Msg}, State), + {stop, normal, State}. + +make_premaster_secret({MajVer, MinVer}, rsa) -> Rand = crypto:rand_bytes(?NUM_OF_PREMASTERSECRET_BYTES-2), <<?BYTE(MajVer), ?BYTE(MinVer), Rand/binary>>; make_premaster_secret(_, _) -> @@ -1996,9 +2161,12 @@ ack_connection(#state{renegotiation = {true, Initiater}} = State) ack_connection(#state{renegotiation = {true, From}} = State) -> gen_fsm:reply(From, ok), State#state{renegotiation = undefined}; -ack_connection(#state{renegotiation = {false, first}, from = From} = State) -> +ack_connection(#state{renegotiation = {false, first}, + from = From} = State) when From =/= undefined -> gen_fsm:reply(From, connected), - State#state{renegotiation = undefined}. + State#state{renegotiation = undefined}; +ack_connection(State) -> + State. renegotiate(#state{role = client} = State) -> %% Handle same way as if server requested @@ -2009,16 +2177,18 @@ renegotiate(#state{role = server, socket = Socket, transport_cb = Transport, negotiated_version = Version, - connection_states = ConnectionStates0} = State) -> + 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), Transport:send(Socket, BinMsg), - {next_state, hello, next_record(State#state{connection_states = - ConnectionStates, - tls_handshake_hashes = Hs0})}. + {Record, State} = next_record(State0#state{connection_states = + ConnectionStates, + tls_handshake_hashes = Hs0}), + next_state(hello, Record, State). + notify_senders(SendQueue) -> lists:foreach(fun({From, _}) -> gen_fsm:reply(From, {error, closed}) @@ -2028,3 +2198,21 @@ notify_renegotiater({true, From}) when not is_atom(From) -> gen_fsm:reply(From, {error, closed}); notify_renegotiater(_) -> ok. + +workaround_transport_delivery_problems(Socket, Transport) -> + %% Standard trick to try to make sure all + %% data sent to to tcp port is really sent + %% before tcp port is closed. + inet:setopts(Socket, [{active, false}]), + Transport:shutdown(Socket, write), + Transport:recv(Socket, 0). + +linux_workaround_transport_delivery_problems(#alert{level = ?FATAL}, Socket) -> + case os:type() of + {unix, linux} -> + inet:setopts(Socket, [{nodelay, true}]); + _ -> + ok + end; +linux_workaround_transport_delivery_problems(_, _) -> + ok. diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl index 9f5ac7106a..b9b1ccb134 100644 --- a/lib/ssl/src/ssl_handshake.erl +++ b/lib/ssl/src/ssl_handshake.erl @@ -31,33 +31,32 @@ -include("ssl_debug.hrl"). -include_lib("public_key/include/public_key.hrl"). --export([master_secret/4, client_hello/4, server_hello/3, hello/2, - 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]). +-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 %%==================================================================== %%-------------------------------------------------------------------- -%% Function: client_hello(Host, Port, ConnectionStates, SslOpts) -> -%% #client_hello{} -%% Host -%% Port -%% ConnectionStates = #connection_states{} -%% SslOpts = #ssl_options{} +-spec client_hello(host(), port_num(), #connection_states{}, + #ssl_options{}, boolean()) -> #client_hello{}. %% %% Description: Creates a client hello message. %%-------------------------------------------------------------------- client_hello(Host, Port, ConnectionStates, #ssl_options{versions = Versions, - ciphers = Ciphers} - = SslOpts) -> + ciphers = UserSuites} + = SslOpts, Renegotiation) -> Fun = fun(Version) -> ssl_record:protocol_version(Version) @@ -65,27 +64,26 @@ 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(UserSuites, Version), + Id = ssl_manager:client_session_id(Host, Port, SslOpts), #client_hello{session_id = Id, client_version = Version, - cipher_suites = Ciphers, + cipher_suites = cipher_suites(Ciphers, Renegotiation), compression_methods = ssl_record:compressions(), - random = SecParams#security_parameters.client_random + random = SecParams#security_parameters.client_random, + renegotiation_info = + renegotiation_info(client, ConnectionStates, Renegotiation) }. %%-------------------------------------------------------------------- -%% Function: server_hello(Host, Port, SessionId, -%% Version, ConnectionStates) -> #server_hello{} -%% SessionId -%% Version -%% ConnectionStates -%% +-spec server_hello(session_id(), tls_version(), #connection_states{}, + boolean()) -> #server_hello{}. %% %% Description: Creates a server hello message. %%-------------------------------------------------------------------- -server_hello(SessionId, Version, ConnectionStates) -> +server_hello(SessionId, Version, ConnectionStates, Renegotiation) -> Pending = ssl_record:pending_connection_state(ConnectionStates, read), SecParams = Pending#connection_state.security_parameters, #server_hello{server_version = Version, @@ -93,11 +91,13 @@ server_hello(SessionId, Version, ConnectionStates) -> compression_method = SecParams#security_parameters.compression_algorithm, random = SecParams#security_parameters.server_random, - session_id = SessionId + session_id = SessionId, + renegotiation_info = + renegotiation_info(server, ConnectionStates, Renegotiation) }. %%-------------------------------------------------------------------- -%% Function: hello_request() -> #hello_request{} +-spec hello_request() -> #hello_request{}. %% %% Description: Creates a hello request message sent by server to %% trigger renegotiation. @@ -106,116 +106,126 @@ hello_request() -> #hello_request{}. %%-------------------------------------------------------------------- -%% Function: hello(Hello, Info) -> -%% {Version, Id, NewConnectionStates} | -%% #alert{} -%% -%% Hello = #client_hello{} | #server_hello{} -%% Info = ConnectionStates | {Port, Session, ConnectionStates} -%% ConnectionStates = #connection_states{} +-spec hello(#server_hello{} | #client_hello{}, #ssl_options{}, + #connection_states{} | {port_num(), #session{}, cache_ref(), + atom(), #connection_states{}, binary()}, + boolean()) -> {tls_version(), session_id(), #connection_states{}}| + {tls_version(), {resumed | new, #session{}}, + #connection_states{}} | #alert{}. %% %% Description: Handles a recieved hello message %%-------------------------------------------------------------------- hello(#server_hello{cipher_suite = CipherSuite, server_version = Version, compression_method = Compression, random = Random, - session_id = SessionId}, ConnectionStates) -> - NewConnectionStates = - hello_pending_connection_states(client, CipherSuite, Random, - Compression, ConnectionStates), - {Version, SessionId, NewConnectionStates}; - -hello(#client_hello{client_version = ClientVersion, random = Random} = Hello, - {Port, #ssl_options{versions = Versions} = SslOpts, - Session0, Cache, CacheCb, ConnectionStates0}) -> + session_id = SessionId, renegotiation_info = Info}, + #ssl_options{secure_renegotiate = SecureRenegotation}, + ConnectionStates0, Renegotiation) -> + + case ssl_record:is_acceptable_version(Version) of + true -> + case handle_renegotiation_info(client, Info, ConnectionStates0, + Renegotiation, SecureRenegotation, []) of + {ok, ConnectionStates1} -> + ConnectionStates = + hello_pending_connection_states(client, CipherSuite, Random, + Compression, ConnectionStates1), + {Version, SessionId, ConnectionStates}; + #alert{} = Alert -> + Alert + end; + false -> + ?ALERT_REC(?FATAL, ?PROTOCOL_VERSION) + end; + +hello(#client_hello{client_version = ClientVersion, random = Random, + cipher_suites = CipherSuites, + renegotiation_info = Info} = Hello, + #ssl_options{versions = Versions, + secure_renegotiate = SecureRenegotation} = SslOpts, + {Port, Session0, Cache, CacheCb, ConnectionStates0, Cert}, Renegotiation) -> Version = select_version(ClientVersion, Versions), case ssl_record:is_acceptable_version(Version) of true -> {Type, #session{cipher_suite = CipherSuite, compression_method = Compression} = Session} = select_session(Hello, Port, Session0, Version, - SslOpts, Cache, CacheCb), + SslOpts, Cache, CacheCb, Cert), case CipherSuite of no_suite -> ?ALERT_REC(?FATAL, ?INSUFFICIENT_SECURITY); _ -> - ConnectionStates = - hello_pending_connection_states(server, - CipherSuite, - Random, - Compression, - ConnectionStates0), - {Version, {Type, Session}, ConnectionStates} + case handle_renegotiation_info(server, Info, ConnectionStates0, + Renegotiation, SecureRenegotation, + CipherSuites) of + {ok, ConnectionStates1} -> + ConnectionStates = + hello_pending_connection_states(server, + CipherSuite, + Random, + Compression, + ConnectionStates1), + {Version, {Type, Session}, ConnectionStates}; + #alert{} = Alert -> + Alert + end end; false -> ?ALERT_REC(?FATAL, ?PROTOCOL_VERSION) end. %%-------------------------------------------------------------------- -%% Function: certify(Certs, CertDbRef, MaxPathLen) -> -%% {PeerCert, PublicKeyInfo} | #alert{} -%% -%% Certs = #certificate{} -%% CertDbRef = reference() -%% MaxPathLen = integer() | nolimit +-spec certify(#certificate{}, term(), integer() | nolimit, + verify_peer | verify_none, {fun(), term}, + client | server) -> {der_cert(), public_key_info()} | #alert{}. %% %% Description: Handles a certificate handshake message %%-------------------------------------------------------------------- -certify(#certificate{asn1_certificates = ASN1Certs}, 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. - + %%-------------------------------------------------------------------- -%% Function: certificate(OwnCert, CertDbRef, Role) -> #certificate{} -%% -%% OwnCert = binary() -%% CertDbRef = term() as returned by ssl_certificate_db:create() +-spec certificate(der_cert(), term(), client | server) -> #certificate{} | #alert{}. %% %% Description: Creates a certificate message. %%-------------------------------------------------------------------- @@ -241,10 +251,10 @@ certificate(OwnCert, CertDbRef, server) -> end. %%-------------------------------------------------------------------- -%% Function: client_certificate_verify(Cert, ConnectionStates) -> -%% #certificate_verify{} | ignore -%% Cert = #'OTPcertificate'{} -%% ConnectionStates = #connection_states{} +-spec client_certificate_verify(undefined | der_cert(), binary(), + tls_version(), key_algo(), private_key(), + {{binary(), binary()},{binary(), binary()}}) -> + #certificate_verify{} | ignore | #alert{}. %% %% Description: Creates a certificate_verify message, called by the client. %%-------------------------------------------------------------------- @@ -256,7 +266,7 @@ client_certificate_verify(OwnCert, MasterSecret, Version, Algorithm, PrivateKey, {Hashes0, _}) -> case public_key:pkix_is_fixed_dh_cert(OwnCert) of true -> - ignore; + ?ALERT_REC(?FATAL, ?UNSUPPORTED_CERTIFICATE); false -> Hashes = calc_certificate_verify(Version, MasterSecret, @@ -266,17 +276,15 @@ client_certificate_verify(OwnCert, MasterSecret, Version, Algorithm, end. %%-------------------------------------------------------------------- -%% Function: certificate_verify(Signature, PublicKeyInfo) -> valid | #alert{} -%% -%% Signature = binary() -%% PublicKeyInfo = {Algorithm, PublicKey, PublicKeyParams} +%% -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. %%-------------------------------------------------------------------- certificate_verify(Signature, {_, PublicKey, _}, Version, MasterSecret, Algorithm, {_, Hashes0}) when Algorithm == rsa; - Algorithm == dh_rsa; Algorithm == dhe_rsa -> Hashes = calc_certificate_verify(Version, MasterSecret, Algorithm, Hashes0), @@ -286,12 +294,22 @@ certificate_verify(Signature, {_, PublicKey, _}, Version, valid; _ -> ?ALERT_REC(?FATAL, ?BAD_CERTIFICATE) + end; +certificate_verify(Signature, {_, PublicKey, PublicKeyParams}, Version, + MasterSecret, dhe_dss = Algorithm, {_, Hashes0}) -> + Hashes = calc_certificate_verify(Version, MasterSecret, + Algorithm, Hashes0), + case public_key:verify(Hashes, none, Signature, {PublicKey, PublicKeyParams}) of + true -> + valid; + false -> + ?ALERT_REC(?FATAL, ?BAD_CERTIFICATE) end. -%% TODO dsa clause + %%-------------------------------------------------------------------- -%% Function: certificate_request(ConnectionStates, CertDbRef) -> -%% #certificate_request{} +-spec certificate_request(#connection_states{}, certdb_ref()) -> + #certificate_request{}. %% %% Description: Creates a certificate_request message, called by the server. %%-------------------------------------------------------------------- @@ -307,11 +325,12 @@ certificate_request(ConnectionStates, CertDbRef) -> }. %%-------------------------------------------------------------------- -%% Function: key_exchange(Role, Secret, Params) -> -%% #client_key_exchange{} | #server_key_exchange{} -%% -%% Secret - -%% Params - +-spec key_exchange(client | server, + {premaster_secret, binary(), public_key_info()} | + {dh, binary()} | + {dh, {binary(), binary()}, #'DHParameter'{}, key_algo(), + binary(), binary(), private_key()}) -> + #client_key_exchange{} | #server_key_exchange{}. %% %% Description: Creates a keyexchange message. %%-------------------------------------------------------------------- @@ -319,18 +338,14 @@ key_exchange(client, {premaster_secret, Secret, {_, PublicKey, _}}) -> EncPremasterSecret = encrypted_premaster_secret(Secret, PublicKey), #client_key_exchange{exchange_keys = EncPremasterSecret}; -key_exchange(client, fixed_diffie_hellman) -> - #client_key_exchange{exchange_keys = - #client_diffie_hellman_public{ - dh_public = <<>> - }}; + key_exchange(client, {dh, <<?UINT32(Len), PublicKey:Len/binary>>}) -> #client_key_exchange{ exchange_keys = #client_diffie_hellman_public{ dh_public = PublicKey} }; -key_exchange(server, {dh, {<<?UINT32(_), PublicKey/binary>>, _}, +key_exchange(server, {dh, {<<?UINT32(Len), PublicKey:Len/binary>>, _}, #'DHParameter'{prime = P, base = G}, KeyAlgo, ClientRandom, ServerRandom, PrivateKey}) -> <<?UINT32(_), PBin/binary>> = crypto:mpint(P), @@ -339,31 +354,21 @@ key_exchange(server, {dh, {<<?UINT32(_), PublicKey/binary>>, _}, GLen = byte_size(GBin), YLen = byte_size(PublicKey), ServerDHParams = #server_dh_params{dh_p = PBin, - dh_g = GBin, dh_y = PublicKey}, - + dh_g = GBin, dh_y = PublicKey}, Hash = server_key_exchange_hash(KeyAlgo, <<ClientRandom/binary, - ServerRandom/binary, - ?UINT16(PLen), PBin/binary, - ?UINT16(GLen), GBin/binary, - ?UINT16(YLen), PublicKey/binary>>), + ServerRandom/binary, + ?UINT16(PLen), PBin/binary, + ?UINT16(GLen), GBin/binary, + ?UINT16(YLen), PublicKey/binary>>), Signed = digitally_signed(Hash, PrivateKey), #server_key_exchange{params = ServerDHParams, - signed_params = Signed}; -key_exchange(_, _) -> - %%TODO : Real imp - #server_key_exchange{}. - -%%-------------------------------------------------------------------- -%% Function: master_secret(Version, Session/PremasterSecret, -%% ConnectionStates, Role) -> -%% {MasterSecret, NewConnectionStates} | #alert{} -%% Version = #protocol_version{} -%% Session = #session{} (session contains master secret) -%% PremasterSecret = binary() -%% ConnectionStates = #connection_states{} -%% Role = client | server -%% + signed_params = Signed}. + +%%-------------------------------------------------------------------- +-spec master_secret(tls_version(), #session{} | binary(), #connection_states{}, + client | server) -> {binary(), #connection_states{}} | #alert{}. +%% %% Description: Sets or calculates the master secret and calculate keys, %% updating the pending connection states. The Mastersecret and the update %% connection states are returned or an alert if the calculation fails. @@ -400,9 +405,8 @@ master_secret(Version, PremasterSecret, ConnectionStates, Role) -> end. %%-------------------------------------------------------------------- -%% Function: finished(Version, Role, MacSecret, Hashes) -> #finished{} -%% -%% ConnectionStates = #connection_states{} +-spec finished(tls_version(), client | server, binary(), {{binary(), binary()},_}) -> + #finished{}. %% %% Description: Creates a handshake finished message %%------------------------------------------------------------------- @@ -411,15 +415,8 @@ finished(Version, Role, MasterSecret, {Hashes, _}) -> % use the current hashes calc_finished(Version, Role, MasterSecret, Hashes)}. %%-------------------------------------------------------------------- -%% Function: verify_connection(Finished, Role, -%% MasterSecret, Hashes) -> verified | #alert{} -%% -%% Finished = #finished{} -%% Role = client | server - the role of the process that sent the finished -%% message. -%% MasterSecret = binary() -%% Hashes = binary() - {md5_hash, sha_hash} -%% +-spec verify_connection(tls_version(), #finished{}, client | server, binary(), + {_, {binary(), binary()}}) -> verified | #alert{}. %% %% Description: Checks the ssl handshake finished message to verify %% the connection. @@ -435,17 +432,18 @@ verify_connection(Version, #finished{verify_data = Data}, _E -> ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE) end. - +%%-------------------------------------------------------------------- +-spec server_hello_done() -> #server_hello_done{}. +%% +%% Description: Creates a server hello done message. +%%-------------------------------------------------------------------- server_hello_done() -> #server_hello_done{}. %%-------------------------------------------------------------------- -%% Function: encode_handshake(HandshakeRec) -> BinHandshake -%% HandshakeRec = #client_hello | #server_hello{} | server_hello_done | -%% #certificate{} | #client_key_exchange{} | #finished{} | -%% #client_certify_request{} +-spec encode_handshake(tls_handshake(), tls_version(), key_algo()) -> iolist(). %% -%% encode a handshake packet to binary +%% Description: Encode a handshake packet to binary %%-------------------------------------------------------------------- encode_handshake(Package, Version, KeyAlg) -> SigAlg = sig_alg(KeyAlg), @@ -454,65 +452,64 @@ encode_handshake(Package, Version, KeyAlg) -> [MsgType, ?uint24(Len), Bin]. %%-------------------------------------------------------------------- -%% Function: get_tls_handshake(Data, Buffer) -> Result -%% Result = {[#handshake{}], [Raw], NewBuffer} -%% Data = Buffer = NewBuffer = Raw = 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, also returns leftover +%% 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]), []). -get_tls_handshake_aux(<<?BYTE(Type), ?UINT24(Length), - Body:Length/binary,Rest/binary>>, KeyAlg, - Version, 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) -> - {lists:reverse(Acc), 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 %%-------------------------------------------------------------------- -verify_bool(verify_peer) -> - true; -verify_bool(verify_none) -> - false. +get_tls_handshake_aux(<<?BYTE(Type), ?UINT24(Length), + Body:Length/binary,Rest/binary>>, Acc) -> + Raw = <<?BYTE(Type), ?UINT24(Length), Body/binary>>, + H = dec_hs(Type, Body), + get_tls_handshake_aux(Rest, [{H,Raw} | Acc]); +get_tls_handshake_aux(Data, Acc) -> + {lists:reverse(Acc), Data}. -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, selfsigned_peer}) -> + ?ALERT_REC(?FATAL, ?BAD_CERTIFICATE); +path_validation_alert({bad_cert, unknown_ca}) -> + ?ALERT_REC(?FATAL, ?UNKNOWN_CA); +path_validation_alert(_) -> ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE). select_session(Hello, Port, Session, Version, - #ssl_options{ciphers = UserSuites} = SslOpts, Cache, CacheCb) -> + #ssl_options{ciphers = UserSuites} = SslOpts, Cache, CacheCb, Cert) -> SuggestedSessionId = Hello#client_hello.session_id, SessionId = ssl_manager:server_session_id(Port, SuggestedSessionId, SslOpts), - Suites = case UserSuites of - [] -> - ssl_cipher:suites(Version); - _ -> - UserSuites - end, - + Suites = available_suites(Cert, UserSuites, Version), case ssl_session:is_new(SuggestedSessionId, SessionId) of true -> CipherSuite = @@ -525,7 +522,119 @@ select_session(Hello, Port, Session, Version, false -> {resumed, CacheCb:lookup(Cache, {Port, SessionId})} end. - + +available_suites(UserSuites, Version) -> + case UserSuites of + [] -> + ssl_cipher:suites(Version); + _ -> + UserSuites + end. + +available_suites(ServerCert, UserSuites, Version) -> + ssl_cipher:filter(ServerCert, available_suites(UserSuites, Version)). + +cipher_suites(Suites, false) -> + [?TLS_EMPTY_RENEGOTIATION_INFO_SCSV | Suites]; +cipher_suites(Suites, true) -> + Suites. + +renegotiation_info(client, _, false) -> + #renegotiation_info{renegotiated_connection = undefined}; +renegotiation_info(server, ConnectionStates, false) -> + CS = ssl_record:current_connection_state(ConnectionStates, read), + case CS#connection_state.secure_renegotiation of + true -> + #renegotiation_info{renegotiated_connection = ?byte(0)}; + false -> + #renegotiation_info{renegotiated_connection = undefined} + end; +renegotiation_info(client, ConnectionStates, true) -> + CS = ssl_record:current_connection_state(ConnectionStates, read), + case CS#connection_state.secure_renegotiation of + true -> + Data = CS#connection_state.client_verify_data, + #renegotiation_info{renegotiated_connection = Data}; + false -> + #renegotiation_info{renegotiated_connection = undefined} + end; + +renegotiation_info(server, ConnectionStates, true) -> + CS = ssl_record:current_connection_state(ConnectionStates, read), + case CS#connection_state.secure_renegotiation of + true -> + CData = CS#connection_state.client_verify_data, + SData =CS#connection_state.server_verify_data, + #renegotiation_info{renegotiated_connection = <<CData/binary, SData/binary>>}; + false -> + #renegotiation_info{renegotiated_connection = undefined} + end. + +handle_renegotiation_info(_, #renegotiation_info{renegotiated_connection = ?byte(0)}, + ConnectionStates, false, _, _) -> + {ok, ssl_record:set_renegotiation_flag(true, ConnectionStates)}; + +handle_renegotiation_info(server, undefined, ConnectionStates, _, _, CipherSuites) -> + case is_member(?TLS_EMPTY_RENEGOTIATION_INFO_SCSV, CipherSuites) of + true -> + {ok, ssl_record:set_renegotiation_flag(true, ConnectionStates)}; + false -> + {ok, ssl_record:set_renegotiation_flag(false, ConnectionStates)} + end; + +handle_renegotiation_info(_, undefined, ConnectionStates, false, _, _) -> + {ok, ssl_record:set_renegotiation_flag(false, ConnectionStates)}; + +handle_renegotiation_info(client, #renegotiation_info{renegotiated_connection = ClientServerVerify}, + ConnectionStates, true, _, _) -> + CS = ssl_record:current_connection_state(ConnectionStates, read), + CData = CS#connection_state.client_verify_data, + SData = CS#connection_state.server_verify_data, + case <<CData/binary, SData/binary>> == ClientServerVerify of + true -> + {ok, ConnectionStates}; + false -> + ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE) + end; +handle_renegotiation_info(server, #renegotiation_info{renegotiated_connection = ClientVerify}, + ConnectionStates, true, _, CipherSuites) -> + + case is_member(?TLS_EMPTY_RENEGOTIATION_INFO_SCSV, CipherSuites) of + true -> + ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE); + false -> + CS = ssl_record:current_connection_state(ConnectionStates, read), + Data = CS#connection_state.client_verify_data, + case Data == ClientVerify of + true -> + {ok, ConnectionStates}; + false -> + ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE) + end + end; + +handle_renegotiation_info(client, undefined, ConnectionStates, true, SecureRenegotation, _) -> + handle_renegotiation_info(ConnectionStates, SecureRenegotation); + +handle_renegotiation_info(server, undefined, ConnectionStates, true, SecureRenegotation, CipherSuites) -> + case is_member(?TLS_EMPTY_RENEGOTIATION_INFO_SCSV, CipherSuites) of + true -> + ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE); + false -> + handle_renegotiation_info(ConnectionStates, SecureRenegotation) + end. + +handle_renegotiation_info(ConnectionStates, SecureRenegotation) -> + CS = ssl_record:current_connection_state(ConnectionStates, read), + case {SecureRenegotation, CS#connection_state.secure_renegotiation} of + {_, true} -> + ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE); + {true, false} -> + ?ALERT_REC(?FATAL, ?NO_RENEGOTIATION); + {false, false} -> + {ok, ConnectionStates} + end. + %% Update pending connection states with parameters exchanged via %% hello messages %% NOTE : Role is the role of the receiver of the hello message @@ -597,12 +706,11 @@ master_secret(Version, MasterSecret, #security_parameters{ hash_size = HashSize, key_material_length = KML, expanded_key_material_length = EKML, - iv_size = IVS, - exportable = Exportable}, + iv_size = IVS}, ConnectionStates, Role) -> {ClientWriteMacSecret, ServerWriteMacSecret, ClientWriteKey, ServerWriteKey, ClientIV, ServerIV} = - setup_keys(Version, Exportable, MasterSecret, ServerRandom, + setup_keys(Version, MasterSecret, ServerRandom, ClientRandom, HashSize, KML, EKML, IVS), ?DBG_HEX(ClientWriteKey), ?DBG_HEX(ClientIV), @@ -618,7 +726,7 @@ master_secret(Version, MasterSecret, #security_parameters{ ServerCipherState, Role)}. -dec_hs(?HELLO_REQUEST, <<>>, _, _) -> +dec_hs(?HELLO_REQUEST, <<>>) -> #hello_request{}; %% Client hello v2. @@ -628,85 +736,120 @@ 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}, random = ssl_ssl2:client_random(ChallengeData, CDLength), session_id = 0, cipher_suites = from_3bytes(CipherSuites), - compression_methods = [?NULL] + compression_methods = [?NULL], + renegotiation_info = undefined }; 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, - _FutureCompatData/binary>>, - _, _) -> + Extensions/binary>>) -> + + RenegotiationInfo = proplists:get_value(renegotiation_info, dec_hello_extensions(Extensions), + undefined), #client_hello{ client_version = {Major,Minor}, random = Random, session_id = Session_ID, cipher_suites = from_2bytes(CipherSuites), - compression_methods = Comp_methods + compression_methods = Comp_methods, + renegotiation_info = RenegotiationInfo }; + 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, session_id = Session_ID, cipher_suite = Cipher_suite, - compression_method = Comp_method - }; -dec_hs(?CERTIFICATE, <<?UINT24(ACLen), ASN1Certs:ACLen/binary>>, _, _) -> + compression_method = Comp_method, + renegotiation_info = undefined}; + +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>>) -> + + RenegotiationInfo = proplists:get_value(renegotiation_info, dec_hello_extensions(Extensions, []), + undefined), + #server_hello{ + server_version = {Major,Minor}, + random = Random, + session_id = Session_ID, + cipher_suite = Cipher_suite, + compression_method = Comp_method, + renegotiation_info = RenegotiationInfo}; +dec_hs(?CERTIFICATE, <<?UINT24(ACLen), ASN1Certs:ACLen/binary>>) -> #certificate{asn1_certificates = certs_to_list(ASN1Certs)}; -dec_hs(?SERVER_KEY_EXCHANGE, <<?UINT16(ModLen), Mod:ModLen/binary, - ?UINT16(ExpLen), Exp:ExpLen/binary, - ?UINT16(_), Sig/binary>>, - ?KEY_EXCHANGE_RSA, _) -> - #server_key_exchange{params = #server_rsa_params{rsa_modulus = Mod, - rsa_exponent = Exp}, - signed_params = Sig}; + dec_hs(?SERVER_KEY_EXCHANGE, <<?UINT16(PLen), P:PLen/binary, ?UINT16(GLen), G:GLen/binary, ?UINT16(YLen), Y:YLen/binary, - ?UINT16(_), Sig/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>>, _, _) -> - %% TODO: maybe we should chop up CertAuths into a list? + ?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, _) -> - %% TODO: Should check whether the cert already contains a suitable DH-key (7.4.7.2) - throw(?ALERT_REC(?FATAL, implicit_public_value_encoding)); -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>>) -> + dec_hello_extensions(Extensions, []); +dec_hello_extensions(_) -> + []. + +dec_hello_extensions(<<>>, Acc) -> + Acc; +dec_hello_extensions(<<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len), Info:Len/binary, Rest/binary>>, Acc) -> + RenegotiateInfo = case Len of + 1 -> % Initial handshake + Info; % should be <<0>> will be matched in handle_renegotiation_info + _ -> + VerifyLen = Len - 1, + <<?BYTE(VerifyLen), VerifyInfo/binary>> = Info, + VerifyInfo + end, + dec_hello_extensions(Rest, [{renegotiation_info, + #renegotiation_info{renegotiated_connection = RenegotiateInfo}} | Acc]); +dec_hello_extensions(<<?UINT16(_), ?UINT16(Len), _Unknown:Len, Rest/binary>>, Acc) -> + dec_hello_extensions(Rest, Acc); +%% Need this clause? +dec_hello_extensions(_, Acc) -> + Acc. + encrypted_premaster_secret(Secret, RSAPublicKey) -> try PreMasterSecret = public_key:encrypt_public(Secret, RSAPublicKey, @@ -743,45 +886,40 @@ certs_from_list(ACList) -> enc_hs(#hello_request{}, _Version, _) -> {?HELLO_REQUEST, <<>>}; -enc_hs(#client_hello{ - client_version = {Major, Minor}, - random = Random, - session_id = SessionID, - cipher_suites = CipherSuites, - compression_methods = CompMethods}, _Version, _) -> +enc_hs(#client_hello{client_version = {Major, Minor}, + random = Random, + session_id = SessionID, + cipher_suites = CipherSuites, + compression_methods = CompMethods, + renegotiation_info = RenegotiationInfo}, _Version, _) -> SIDLength = byte_size(SessionID), BinCompMethods = list_to_binary(CompMethods), CmLength = byte_size(BinCompMethods), BinCipherSuites = list_to_binary(CipherSuites), CsLength = byte_size(BinCipherSuites), + Extensions = hello_extensions(RenegotiationInfo), + ExtensionsBin = enc_hello_extensions(Extensions), {?CLIENT_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary, ?BYTE(SIDLength), SessionID/binary, ?UINT16(CsLength), BinCipherSuites/binary, - ?BYTE(CmLength), BinCompMethods/binary>>}; -enc_hs(#server_hello{ - server_version = {Major, Minor}, - random = Random, - session_id = Session_ID, - cipher_suite = Cipher_suite, - compression_method = Comp_method}, _Version, _) -> + ?BYTE(CmLength), BinCompMethods/binary, ExtensionsBin/binary>>}; + +enc_hs(#server_hello{server_version = {Major, Minor}, + random = Random, + session_id = Session_ID, + cipher_suite = Cipher_suite, + compression_method = Comp_method, + renegotiation_info = RenegotiationInfo}, _Version, _) -> SID_length = byte_size(Session_ID), + Extensions = hello_extensions(RenegotiationInfo), + ExtensionsBin = enc_hello_extensions(Extensions), {?SERVER_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary, ?BYTE(SID_length), Session_ID/binary, - Cipher_suite/binary, ?BYTE(Comp_method)>>}; + Cipher_suite/binary, ?BYTE(Comp_method), ExtensionsBin/binary>>}; enc_hs(#certificate{asn1_certificates = ASN1CertList}, _Version, _) -> ASN1Certs = certs_from_list(ASN1CertList), ACLen = erlang:iolist_size(ASN1Certs), {?CERTIFICATE, <<?UINT24(ACLen), ASN1Certs:ACLen/binary>>}; -enc_hs(#server_key_exchange{params = #server_rsa_params{rsa_modulus = Mod, - rsa_exponent = Exp}, - signed_params = SignedParams}, _Version, _) -> - ModLen = byte_size(Mod), - ExpLen = byte_size(Exp), - SignedLen = byte_size(SignedParams), - {?SERVER_KEY_EXCHANGE, <<?UINT16(ModLen),Mod/binary, - ?UINT16(ExpLen), Exp/binary, - ?UINT16(SignedLen), SignedParams/binary>> - }; enc_hs(#server_key_exchange{params = #server_dh_params{ dh_p = P, dh_g = G, dh_y = Y}, signed_params = SignedParams}, _Version, _) -> @@ -826,6 +964,29 @@ enc_bin_sig(BinSig) -> Size = byte_size(BinSig), <<?UINT16(Size), BinSig/binary>>. +%% Renegotiation info, only current extension +hello_extensions(#renegotiation_info{renegotiated_connection = undefined}) -> + []; +hello_extensions(#renegotiation_info{} = Info) -> + [Info]. + +enc_hello_extensions(Extensions) -> + enc_hello_extensions(Extensions, <<>>). +enc_hello_extensions([], <<>>) -> + <<>>; +enc_hello_extensions([], Acc) -> + Size = byte_size(Acc), + <<?UINT16(Size), Acc/binary>>; + +enc_hello_extensions([#renegotiation_info{renegotiated_connection = ?byte(0) = Info} | Rest], Acc) -> + Len = byte_size(Info), + enc_hello_extensions(Rest, <<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len), Info/binary, Acc/binary>>); + +enc_hello_extensions([#renegotiation_info{renegotiated_connection = Info} | Rest], Acc) -> + InfoLen = byte_size(Info), + Len = InfoLen +1, + enc_hello_extensions(Rest, <<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len), ?BYTE(InfoLen), Info/binary, Acc/binary>>). + init_hashes() -> T = {crypto:md5_init(), crypto:sha_init()}, {T, T}. @@ -868,25 +1029,21 @@ from_2bytes(<<?UINT16(N), Rest/binary>>, Acc) -> certificate_types({KeyExchange, _, _, _}) when KeyExchange == rsa; - KeyExchange == dh_dss; - KeyExchange == dh_rsa; KeyExchange == dhe_dss; KeyExchange == dhe_rsa -> <<?BYTE(?RSA_SIGN), ?BYTE(?DSS_SIGN)>>; certificate_types(_) -> - %%TODO: Is this a good default, - %% is there a case where we like to request - %% a RSA_FIXED_DH or DSS_FIXED_DH <<?BYTE(?RSA_SIGN)>>. 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, @@ -896,7 +1053,7 @@ certificate_authorities_from_db(CertDbRef) -> certificate_authorities_from_db(CertDbRef, no_candidate, []). certificate_authorities_from_db(CertDbRef, PrevKey, Acc) -> - case ssl_certificate_db:issuer_candidate(PrevKey) of + case ssl_manager:issuer_candidate(PrevKey) of no_more_candidates -> lists:reverse(Acc); {{CertDbRef, _, _} = Key, Cert} -> @@ -906,13 +1063,12 @@ certificate_authorities_from_db(CertDbRef, PrevKey, Acc) -> certificate_authorities_from_db(CertDbRef, Key, Acc) end. -digitally_signed(Hashes, #'RSAPrivateKey'{} = Key) -> - public_key:encrypt_private(Hashes, Key, +digitally_signed(Hash, #'RSAPrivateKey'{} = Key) -> + public_key:encrypt_private(Hash, Key, [{rsa_pad, rsa_pkcs1_padding}]); -digitally_signed(Hashes, #'DSAPrivateKey'{} = Key) -> - public_key:sign(Hashes, Key). - - +digitally_signed(Hash, #'DSAPrivateKey'{} = Key) -> + public_key:sign(Hash, none, Key). + calc_master_secret({3,0}, PremasterSecret, ClientRandom, ServerRandom) -> ssl_ssl3:master_secret(PremasterSecret, ClientRandom, ServerRandom); @@ -920,20 +1076,15 @@ calc_master_secret({3,N},PremasterSecret, ClientRandom, ServerRandom) when N == 1; N == 2 -> ssl_tls1:master_secret(PremasterSecret, ClientRandom, ServerRandom). -setup_keys({3,0}, Exportable, MasterSecret, +setup_keys({3,0}, MasterSecret, ServerRandom, ClientRandom, HashSize, KML, EKML, IVS) -> - ssl_ssl3:setup_keys(Exportable, MasterSecret, ServerRandom, + ssl_ssl3:setup_keys(MasterSecret, ServerRandom, ClientRandom, HashSize, KML, EKML, IVS); -setup_keys({3,1}, _Exportable, MasterSecret, +setup_keys({3,1}, MasterSecret, ServerRandom, ClientRandom, HashSize, KML, _EKML, IVS) -> ssl_tls1:setup_keys(MasterSecret, ServerRandom, ClientRandom, HashSize, - KML, IVS); - -setup_keys({3,2}, _Exportable, MasterSecret, - ServerRandom, ClientRandom, HashSize, KML, _EKML, _IVS) -> - ssl_tls1:setup_keys(MasterSecret, ServerRandom, - ClientRandom, HashSize, KML). + KML, IVS). calc_finished({3, 0}, Role, MasterSecret, Hashes) -> ssl_ssl3:finished(Role, MasterSecret, Hashes); @@ -948,31 +1099,19 @@ calc_certificate_verify({3, N}, _, Algorithm, Hashes) ssl_tls1:certificate_verify(Algorithm, Hashes). server_key_exchange_hash(Algorithm, Value) when Algorithm == rsa; - Algorithm == dh_rsa; Algorithm == dhe_rsa -> - MD5Context = crypto:md5_init(), - NewMD5Context = crypto:md5_update(MD5Context, Value), - MD5 = crypto:md5_final(NewMD5Context), - - SHAContext = crypto:sha_init(), - NewSHAContext = crypto:sha_update(SHAContext, Value), - SHA = crypto:sha_final(NewSHAContext), - + MD5 = crypto:md5(Value), + SHA = crypto:sha(Value), <<MD5/binary, SHA/binary>>; -server_key_exchange_hash(Algorithm, Value) when Algorithm == dh_dss; - Algorithm == dhe_dss -> - - SHAContext = crypto:sha_init(), - NewSHAContext = crypto:sha_update(SHAContext, Value), - crypto:sha_final(NewSHAContext). - +server_key_exchange_hash(dhe_dss, Value) -> + crypto:sha(Value). sig_alg(dh_anon) -> ?SIGNATURE_ANONYMOUS; -sig_alg(Alg) when Alg == dhe_rsa; Alg == rsa; Alg == dh_rsa -> +sig_alg(Alg) when Alg == dhe_rsa; Alg == rsa -> ?SIGNATURE_RSA; -sig_alg(Alg) when Alg == dh_dss; Alg == dhe_dss -> +sig_alg(dhe_dss) -> ?SIGNATURE_DSA; sig_alg(_) -> ?NULL. @@ -980,7 +1119,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_handshake.hrl b/lib/ssl/src/ssl_handshake.hrl index 889d39f2af..74fba3786c 100644 --- a/lib/ssl/src/ssl_handshake.hrl +++ b/lib/ssl/src/ssl_handshake.hrl @@ -81,7 +81,8 @@ random, session_id, % opaque SessionID<0..32> cipher_suites, % cipher_suites<2..2^16-1> - compression_methods % compression_methods<1..2^8-1> + compression_methods, % compression_methods<1..2^8-1>, + renegotiation_info }). -record(server_hello, { @@ -89,7 +90,8 @@ random, session_id, % opaque SessionID<0..32> cipher_suite, % cipher_suites - compression_method % compression_method + compression_method, % compression_method + renegotiation_info }). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -195,6 +197,15 @@ verify_data %opaque verify_data[12] }). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Renegotiation info RFC 5746 section 3.2 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-define(RENEGOTIATION_EXT, 16#ff01). + +-record(renegotiation_info,{ + renegotiated_connection + }). + -endif. % -ifdef(ssl_handshake). diff --git a/lib/ssl/src/ssl_internal.hrl b/lib/ssl/src/ssl_internal.hrl index 8d19abfe1e..ddb05e70f6 100644 --- a/lib/ssl/src/ssl_internal.hrl +++ b/lib/ssl/src/ssl_internal.hrl @@ -23,6 +23,8 @@ -ifndef(ssl_internal). -define(ssl_internal, true). +-include_lib("public_key/include/public_key.hrl"). + %% basic binary constructors -define(BOOLEAN(X), X:8/unsigned-big-integer). -define(BYTE(X), X:8/unsigned-big-integer). @@ -61,10 +63,13 @@ validate_extensions_fun, depth, % integer() certfile, % file() + cert, % der_encoded() keyfile, % file() - key, % + key, % der_encoded() password, % + cacerts, % [der_encoded()] cacertfile, % file() + dh, % der_encoded() dhfile, % file() ciphers, % %% Local policy for the server if it want's to reuse the session @@ -75,6 +80,7 @@ %% will be reused if possible. reuse_sessions, % boolean() renegotiate_at, + secure_renegotiate, debug % }). @@ -87,6 +93,28 @@ active = true }). +-type reason() :: term(). +-type reply() :: term(). +-type msg() :: term(). +-type from() :: term(). +-type host() :: string() | tuple(). +-type port_num() :: integer(). +-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() :: null | rsa | dhe_rsa | dhe_dss. +-type enum_algo() :: integer(). +-type public_key() :: #'RSAPublicKey'{} | integer(). +-type public_key_params() :: #'Dss-Parms'{} | term(). +-type public_key_info() :: {enum_algo(), public_key(), public_key_params()}. +-type der_cert() :: binary(). +-type private_key() :: #'RSAPrivateKey'{} | #'DSAPrivateKey'{}. +-type issuer() :: tuple(). +-type serialnumber() :: integer(). +-type cert_key() :: {reference(), integer(), issuer()}. + -endif. % -ifdef(ssl_internal). diff --git a/lib/ssl/src/ssl_manager.erl b/lib/ssl/src/ssl_manager.erl index 0151426d43..0116466677 100644 --- a/lib/ssl/src/ssl_manager.erl +++ b/lib/ssl/src/ssl_manager.erl @@ -24,10 +24,13 @@ -module(ssl_manager). -behaviour(gen_server). +-include("ssl_internal.hrl"). + %% Internal application API --export([start_link/0, start_link/1, +-export([start_link/1, connection_init/2, cache_pem_file/1, - lookup_trusted_cert/3, 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]). @@ -58,21 +61,25 @@ %% API %%==================================================================== %%-------------------------------------------------------------------- -%% Function: start_link() -> {ok,Pid} | ignore | {error,Error} +-spec start_link(list()) -> {ok, pid()} | ignore | {error, term()}. +%% %% Description: Starts the server %%-------------------------------------------------------------------- -start_link() -> - gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). start_link(Opts) -> gen_server:start_link({local, ?MODULE}, ?MODULE, [Opts], []). %%-------------------------------------------------------------------- -%% Function: -%% Description: +-spec connection_init(string()| {der, list()}, client | server) -> {ok, reference(), cache_ref()}. +%% +%% Description: Do necessary initializations for a new connection. +%%-------------------------------------------------------------------- +connection_init(Trustedcerts, Role) -> + call({connection_init, Trustedcerts, Role}). +%%-------------------------------------------------------------------- +-spec cache_pem_file(string()) -> {ok, term()}. +%% +%% Description: Cach a pem file and %%-------------------------------------------------------------------- -connection_init(TrustedcertsFile, Role) -> - call({connection_init, TrustedcertsFile, Role}). - cache_pem_file(File) -> case ssl_certificate_db:lookup_cached_certs(File) of [{_,Content}] -> @@ -80,41 +87,54 @@ cache_pem_file(File) -> [] -> call({cache_pem, File}) end. - -%%-------------------------------------------------------------------- -%% Function: -%% Description: %%-------------------------------------------------------------------- -lookup_trusted_cert(SerialNumber, Issuer, Ref) -> +-spec lookup_trusted_cert(reference(), serialnumber(), issuer()) -> + undefined | + {ok, {der_cert(), #'OTPCertificate'{}}}. +%% +%% 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). - %%-------------------------------------------------------------------- -%% Function: -%% Description: +-spec issuer_candidate(cert_key() | no_candidate) -> + {cert_key(), {der_cert(), #'OTPCertificate'{}}} | no_more_candidates. +%% +%% Description: Return next issuer candidate. +%%-------------------------------------------------------------------- +issuer_candidate(PrevCandidateKey) -> + ssl_certificate_db:issuer_candidate(PrevCandidateKey). +%%-------------------------------------------------------------------- +-spec client_session_id(host(), port_num(), #ssl_options{}) -> session_id(). +%% +%% Description: Select a session id for the client. %%-------------------------------------------------------------------- client_session_id(Host, Port, SslOpts) -> call({client_session_id, Host, Port, SslOpts}). - + %%-------------------------------------------------------------------- -%% Function: -%% Description: +-spec server_session_id(host(), port_num(), #ssl_options{}) -> session_id(). +%% +%% Description: Select a session id for the server. %%-------------------------------------------------------------------- server_session_id(Port, SuggestedSessionId, SslOpts) -> call({server_session_id, Port, SuggestedSessionId, SslOpts}). %%-------------------------------------------------------------------- -%% Function: -%% Description: +-spec register_session(host(), port_num(), #session{}) -> ok. +%% +%% Description: Make the session available for reuse. %%-------------------------------------------------------------------- register_session(Host, Port, Session) -> cast({register_session, Host, Port, Session}). register_session(Port, Session) -> cast({register_session, Port, Session}). - %%-------------------------------------------------------------------- -%% Function: -%% Description: +-spec invalidate_session(host(), port_num(), #session{}) -> ok. +%% +%% Description: Make the session unavilable for reuse. %%-------------------------------------------------------------------- invalidate_session(Host, Port, Session) -> cast({invalidate_session, Host, Port, Session}). @@ -127,34 +147,36 @@ invalidate_session(Port, Session) -> %%==================================================================== %%-------------------------------------------------------------------- -%% Function: init(Args) -> {ok, State} | -%% {ok, State, Timeout} | -%% ignore | -%% {stop, Reason} +-spec init(list()) -> {ok, #state{}}. +%% Possible return values not used now. +%% | {ok, #state{}, timeout()} | ignore | {stop, term()}. +%% %% Description: Initiates the server %%-------------------------------------------------------------------- -init(Opts) -> +init([Opts]) -> process_flag(trap_exit, true), - CacheCb = proplists:get_value(session_cache, Opts, ssl_session_cache), + CacheCb = proplists:get_value(session_cb, Opts, ssl_session_cache), SessionLifeTime = proplists:get_value(session_lifetime, Opts, ?'24H_in_sec'), CertDb = ssl_certificate_db:create(), - SessionCache = CacheCb:init(), + SessionCache = CacheCb:init(proplists:get_value(session_cb_init_args, Opts, [])), Timer = erlang:send_after(SessionLifeTime * 1000, self(), validate_sessions), {ok, #state{certificate_db = CertDb, session_cache = SessionCache, session_cache_cb = CacheCb, - session_lifetime = SessionLifeTime , + session_lifetime = SessionLifeTime, session_validation_timer = Timer}}. %%-------------------------------------------------------------------- -%% Function: %% handle_call(Request, 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 %%-------------------------------------------------------------------- handle_call({{connection_init, "", _Role}, Pid}, _From, @@ -163,19 +185,17 @@ 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 - _:{badmatch, Error} -> - {error, Error}; - _E:_R -> - {error, {_R,erlang:get_stacktrace()}} + _:Reason -> + {error, Reason} end, {reply, Result, State}; @@ -197,18 +217,16 @@ handle_call({{cache_pem, File},Pid}, _, State = #state{certificate_db = Db}) -> try ssl_certificate_db:cache_pem_file(Pid,File,Db) of Result -> {reply, Result, State} - catch _:{badmatch, Reason} -> - {reply, Reason, State}; - _:Reason -> + catch + _:Reason -> {reply, {error, Reason}, State} - end; - -handle_call(_,_, State) -> - {reply, ok, State}. + end. %%-------------------------------------------------------------------- -%% Function: 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 %%-------------------------------------------------------------------- handle_cast({register_session, Host, Port, Session}, @@ -242,9 +260,11 @@ handle_cast({invalidate_session, Port, #session{session_id = ID}}, {noreply, State}. %%-------------------------------------------------------------------- -%% Function: handle_info(Info, 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 %%-------------------------------------------------------------------- handle_info(validate_sessions, #state{session_cache_cb = CacheCb, @@ -277,7 +297,8 @@ handle_info(_Info, State) -> {noreply, State}. %%-------------------------------------------------------------------- -%% Function: terminate(Reason, State) -> void() +-spec terminate(reason(), #state{}) -> term(). +%% %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. @@ -293,7 +314,8 @@ terminate(_Reason, #state{certificate_db = Db, ok. %%-------------------------------------------------------------------- -%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} +-spec code_change(term(), #state{}, list()) -> {ok, #state{}}. +%% %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> @@ -332,10 +354,9 @@ init_session_validator([Cache, CacheCb, LifeTime]) -> CacheCb:foldl(fun session_validation/2, LifeTime, Cache). -session_validation({{Host, Port, _}, Session}, LifeTime) -> +session_validation({{{Host, Port}, _}, Session}, LifeTime) -> validate_session(Host, Port, Session, LifeTime), LifeTime; session_validation({{Port, _}, Session}, LifeTime) -> validate_session(Port, Session, LifeTime), LifeTime. - diff --git a/lib/ssl/src/ssl_pem.erl b/lib/ssl/src/ssl_pem.erl deleted file mode 100644 index 0a1bf0f32a..0000000000 --- a/lib/ssl/src/ssl_pem.erl +++ /dev/null @@ -1,147 +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% -%% - -%% - --module(ssl_pem). - -%%% Purpose: Reading and writing of PEM type encoded files for SSL. - -%% NB write_file/2 is only preliminary. - -%% PEM encoded files have the following structure: -%% -%% <text> -%% -----BEGIN SOMETHING-----<CR><LF> -%% <Base64 encoding line><CR><LF> -%% <Base64 encoding line><CR><LF> -%% ... -%% -----END SOMETHING-----<CR><LF> -%% <text> -%% -%% A file can contain several BEGIN/END blocks. Text lines between -%% blocks are ignored. - --export([read_file/1, read_file/2, write_file/2]). - -%% Read a PEM file and return each decoding as a binary. - -read_file(File) -> - read_file(File, no_passwd). - -read_file(File, Passwd) -> - {ok, Fd} = file:open(File, [read]), - Result = decode_file(Fd, Passwd), - file:close(Fd), - Result. - -decode_file(Fd, Passwd) -> - decode_file(Fd, [], [], notag, [Passwd]). - -decode_file(Fd, _RLs, Ens, notag, Info) -> - case io:get_line(Fd, "") of - "-----BEGIN CERTIFICATE REQUEST-----" ++ _ -> - decode_file(Fd, [], Ens, cert_req, Info); - "-----BEGIN CERTIFICATE-----" ++ _ -> - decode_file(Fd, [], Ens, cert, Info); - "-----BEGIN RSA PRIVATE KEY-----" ++ _ -> - decode_file(Fd, [], Ens, rsa_private_key, Info); - eof -> - {ok, lists:reverse(Ens)}; - _ -> - decode_file(Fd, [], Ens, notag, Info) - end; -decode_file(Fd, RLs, Ens, Tag, Info0) -> - case io:get_line(Fd, "") of - "Proc-Type: 4,ENCRYPTED"++_ -> - Info = dek_info(Fd, Info0), - decode_file(Fd, RLs, Ens, Tag, Info); - "-----END" ++ _ -> % XXX sloppy - Cs = lists:flatten(lists:reverse(RLs)), - Bin = ssl_base64:join_decode(Cs), - case Info0 of - [Password, Cipher, SaltHex | Info1] -> - Decoded = decode_key(Bin, Password, Cipher, unhex(SaltHex)), - decode_file(Fd, [], [{Tag, Decoded}| Ens], notag, Info1); - _ -> - decode_file(Fd, [], [{Tag, Bin}| Ens], notag, Info0) - end; - eof -> - {ok, lists:reverse(Ens)}; - L -> - decode_file(Fd, [L|RLs], Ens, Tag, Info0) - end. - -dek_info(Fd, Info) -> - Line = io:get_line(Fd, ""), - [_, DekInfo0] = string:tokens(Line, ": "), - DekInfo1 = string:tokens(DekInfo0, ",\n"), - Info ++ DekInfo1. - -unhex(S) -> - unhex(S, []). - -unhex("", Acc) -> - lists:reverse(Acc); -unhex([D1, D2 | Rest], Acc) -> - unhex(Rest, [erlang:list_to_integer([D1, D2], 16) | Acc]). - -decode_key(Data, Password, "DES-CBC", Salt) -> - Key = password_to_key(Password, Salt, 8), - IV = Salt, - crypto:des_cbc_decrypt(Key, IV, Data); -decode_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_decrypt(Key1, Key2, Key3, IV, Data). - -write_file(File, Ds) -> - file:write_file(File, encode_file(Ds)). - -encode_file(Ds) -> - [encode_file_1(D) || D <- Ds]. - -encode_file_1({cert, Bin}) -> - %% PKIX (X.509) - ["-----BEGIN CERTIFICATE-----\n", - ssl_base64:encode_split(Bin), - "-----END CERTIFICATE-----\n\n"]; -encode_file_1({cert_req, Bin}) -> - %% PKCS#10 - ["-----BEGIN CERTIFICATE REQUEST-----\n", - ssl_base64:encode_split(Bin), - "-----END CERTIFICATE REQUEST-----\n\n"]; -encode_file_1({rsa_private_key, Bin}) -> - %% PKCS#? - ["XXX Following key assumed not encrypted\n", - "-----BEGIN RSA PRIVATE KEY-----\n", - ssl_base64:encode_split(Bin), - "-----END RSA PRIVATE KEY-----\n\n"]. - -password_to_key(Data, Salt, KeyLen) -> - <<Key:KeyLen/binary, _/binary>> = - password_to_key(<<>>, Data, Salt, KeyLen, <<>>), - Key. - -password_to_key(_, _, _, Len, Acc) when Len =< 0 -> - Acc; -password_to_key(Prev, Data, Salt, Len, Acc) -> - M = crypto:md5([Prev, Data, Salt]), - password_to_key(M, Data, Salt, Len - byte_size(M), <<Acc/binary, M/binary>>). diff --git a/lib/ssl/src/ssl_pkix.erl b/lib/ssl/src/ssl_pkix.erl deleted file mode 100644 index 8f540f74ad..0000000000 --- a/lib/ssl/src/ssl_pkix.erl +++ /dev/null @@ -1,307 +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% -%% - -%%% Purpose : API module for decoding of certificates. - --module(ssl_pkix). - --include("ssl_pkix.hrl"). - --export([decode_cert_file/1, decode_cert_file/2, - decode_cert/1, decode_cert/2, encode_cert/1, encoded_tbs_cert/1, - signature_digest/1, decode_rsa_keyfile/2]). - -%% The public API is dprecated by public_key and -%% the internal application API is no longer used ssl. -%% So this file can be compleatly removed in R14. --deprecated({decode_cert_file, 1, next_major_release}). --deprecated({decode_cert_file, 2, next_major_release}). --deprecated({decode_cert, 1, next_major_release}). --deprecated({decode_cert, 2, next_major_release}). - -%%==================================================================== -%% API -%%==================================================================== - -%%-------------------------------------------------------------------- -%% Function: decode_cert_file(File, <Opts>) -> {ok, Cert} | {ok, [Cert]} -%% -%% File = string() -%% Opts = [Opt] -%% Opt = pem | ssl | pkix - ssl and pkix are mutual exclusive -%% Cert = term() -%% -%% Description: Decodes certificats found in file <File>. -%% If the options list is empty the certificate is -%% returned as a DER encoded binary, i.e. {ok, Bin} is returned, where -%% Bin> is the provided input. The options pkix and ssl imply that the -%% certificate is returned as a parsed ASN.1 structure in the form of -%% an Erlang term. The ssl option gives a more elaborate return -%% structure, with more explicit information. In particular object -%% identifiers are replaced by atoms. The option subject implies that -%% only the subject's distinguished name part of the certificate is -%% returned. It can only be used together with the option pkix or the -%% option ssl. -%%-------------------------------------------------------------------- -decode_cert_file(File) -> - decode_cert_file(File, []). - -decode_cert_file(File, Opts) -> - case lists:member(pem, Opts) of - true -> - {ok, List} = ssl_pem:read_file(File), - Certs = [Bin || {cert, Bin} <- List], - NewOpts = lists:delete(pem, Opts), - Fun = fun(Cert) -> - {ok, Decoded} = decode_cert(Cert, NewOpts), - Decoded - end, - case lists:map(Fun, Certs) of - [DecodedCert] -> - {ok, DecodedCert}; - DecodedCerts -> - {ok, DecodedCerts} - end; - false -> - {ok, Bin} = file:read_file(File), - decode_cert(Bin, Opts) - end. -%%-------------------------------------------------------------------- -%% Function: decode_cert(Bin, <Opts>) -> {ok, Cert} -%% Bin - binary() -%% Opts = [Opt] -%% Opt = ssl | pkix | subject - ssl and pkix are mutual exclusive -%% Cert = term() -%% -%% Description: If the options list is empty the certificate is -%% returned as a DER encoded binary, i.e. {ok, Bin} is returned, where -%% Bin> is the provided input. The options pkix and ssl imply that the -%% certificate is returned as a parsed ASN.1 structure in the form of -%% an Erlang term. The ssl option gives a more elaborate return -%% structure, with more explicit information. In particular object -%% identifiers are replaced by atoms. The option subject implies that -%% only the subject's distinguished name part of the certificate is -%% returned. It can only be used together with the option pkix or the -%% option ssl. -%%-------------------------------------------------------------------- -decode_cert(Bin) -> - decode_cert(Bin, []). - -decode_cert(Bin, []) when is_binary(Bin) -> - {ok, Bin}; -decode_cert(Bin, Opts) when is_binary(Bin) -> - - {ok, Cert} = 'OTP-PKIX':decode('Certificate', Bin), - - case {lists:member(ssl, Opts), lists:member(pkix, Opts)} of - {true, false} -> - cert_return(transform(Cert, ssl), Opts); - {false, true} -> - cert_return(transform(Cert, pkix), Opts); - _ -> - {error, eoptions} - end. - -encode_cert(#'Certificate'{} = Cert) -> - {ok, List} = 'OTP-PKIX':encode('Certificate', Cert), - list_to_binary(List). - -decode_rsa_keyfile(KeyFile, Password) -> - {ok, List} = ssl_pem:read_file(KeyFile, Password), - [PrivatKey] = [Bin || {rsa_private_key, Bin} <- List], - 'OTP-PKIX':decode('RSAPrivateKey', PrivatKey). - -%%==================================================================== -%% Application internal API -%%==================================================================== - -%%-------------------------------------------------------------------- -%% Function: encoded_tbs_cert(Cert) -> PKXCert -%% -%% Cert = binary() - Der encoded -%% PKXCert = binary() - Der encoded -%% -%% Description: Extracts the binary TBSCert from the binary Certificate. -%%-------------------------------------------------------------------- -encoded_tbs_cert(Cert) -> - {ok, PKIXCert} = - 'OTP-PKIX':decode_TBSCert_exclusive(Cert), - {'Certificate', - {'Certificate_tbsCertificate', EncodedTBSCert}, _, _} = PKIXCert, - EncodedTBSCert. - -%%-------------------------------------------------------------------- -%%% Internal functions -%%-------------------------------------------------------------------- - -cert_return(Cert, Opts) -> - case lists:member(subject, Opts) of - true -> - {ok, get_subj(Cert)}; - false -> - {ok, Cert} - end. - - -%% Transfrom from PKIX1-Explicit88 to SSL-PKIX. - -transform(#'Certificate'{signature = Signature, - signatureAlgorithm = SignatureAlgorithm, - tbsCertificate = TbsCertificate} = Cert, Type) -> - Cert#'Certificate'{tbsCertificate = transform(TbsCertificate, Type), - signatureAlgorithm = transform(SignatureAlgorithm, Type), - signature = transform(Signature, Type)}; - -%% -record('TBSCertificate',{ -%% version = asn1_DEFAULT, serialNumber, signature, issuer, validity, subject, -%% subjectPublicKeyInfo, issuerUniqueID = asn1_NOVALUE, -%% subjectUniqueID = asn1_NOVALUE, extensions = asn1_NOVALUE}). - -transform(#'TBSCertificate'{signature = Signature, issuer = Issuer, - subject = Subject, extensions = Extensions, - subjectPublicKeyInfo = SPKInfo} = TBSCert, Type) -> - TBSCert#'TBSCertificate'{signature = transform(Signature, Type), - issuer = transform(Issuer, Type), - subject = transform(Subject, Type), - subjectPublicKeyInfo = transform(SPKInfo, Type), - extensions = transform_extensions(Extensions, Type) - }; - -transform(#'AlgorithmIdentifier'{algorithm = Algorithm, - parameters = Params}, ssl) -> - SignAlgAny = - #'SignatureAlgorithm-Any'{algorithm = Algorithm, parameters = Params}, - {ok, AnyEnc} = 'OTP-PKIX':encode('SignatureAlgorithm-Any', SignAlgAny), - {ok, SignAlgCd} = 'OTP-PKIX':decode('SignatureAlgorithm', - list_to_binary(AnyEnc)), - NAlgo = ssl_pkix_oid:id2atom(SignAlgCd#'SignatureAlgorithm'.algorithm), - SignAlgCd#'SignatureAlgorithm'{algorithm = NAlgo}; - -transform({rdnSequence, Lss}, Type) when is_list(Lss) -> - {rdnSequence, [[transform(L, Type) || L <- Ls] || Ls <- Lss]}; -transform({rdnSequence, Lss}, _) -> - {rdnSequence, Lss}; - -transform(#'AttributeTypeAndValue'{} = ATAV, ssl) -> - {ok, ATAVEnc} = - 'OTP-PKIX':encode('AttributeTypeAndValue', ATAV), - {ok, ATAVDec} = 'OTP-PKIX':decode('SSLAttributeTypeAndValue', - list_to_binary(ATAVEnc)), - AttrType = ATAVDec#'SSLAttributeTypeAndValue'.type, - #'AttributeTypeAndValue'{type = ssl_pkix_oid:id2atom(AttrType), - value = - ATAVDec#'SSLAttributeTypeAndValue'.value}; - -transform(#'AttributeTypeAndValue'{} = Att, pkix) -> - Att; - -%% -record('SubjectPublicKeyInfo',{ -%% algorithm, subjectPublicKey}). -%% -%% -record('SubjectPublicKeyInfo_algorithm',{ -%% algo, parameters = asn1_NOVALUE}). -%% -%% -record('SubjectPublicKeyInfo-Any',{ -%% algorithm, subjectPublicKey}). -%% -%% -record('PublicKeyAlgorithm',{ -%% algorithm, parameters = asn1_NOVALUE}). - -transform(#'SubjectPublicKeyInfo'{subjectPublicKey = SubjectPublicKey, - algorithm = Algorithm}, ssl) -> - %% Transform from SubjectPublicKeyInfo (PKIX1Explicit88) - %% to SubjectPublicKeyInfo-Any (SSL-PKIX). - Algo = Algorithm#'AlgorithmIdentifier'.algorithm, - Parameters = Algorithm#'AlgorithmIdentifier'.parameters, - AlgorithmAny = #'PublicKeyAlgorithm'{algorithm = Algo, - parameters = Parameters}, - {0, Bin} = SubjectPublicKey, - SInfoAny = #'SSLSubjectPublicKeyInfo-Any'{algorithm = AlgorithmAny, - subjectPublicKey = Bin}, - - %% Encode according to SubjectPublicKeyInfo-Any, and decode according - %% to SubjectPublicKeyInfo. - {ok, AnyEnc} = - 'OTP-PKIX':encode('SSLSubjectPublicKeyInfo-Any', SInfoAny), - {ok, SInfoCd} = 'OTP-PKIX':decode('SSLSubjectPublicKeyInfo', - list_to_binary(AnyEnc)), - %% Replace object identifier by atom - AlgorithmCd = SInfoCd#'SSLSubjectPublicKeyInfo'.algorithm, - AlgoCd = AlgorithmCd#'SSLSubjectPublicKeyInfo_algorithm'.algo, - Params = AlgorithmCd#'SSLSubjectPublicKeyInfo_algorithm'.parameters, - Key = SInfoCd#'SSLSubjectPublicKeyInfo'.subjectPublicKey, - NAlgoCd = ssl_pkix_oid:id2atom(AlgoCd), - NAlgorithmCd = - #'SubjectPublicKeyInfo_algorithm'{algorithm = NAlgoCd, - parameters = Params}, - #'SubjectPublicKeyInfo'{algorithm = NAlgorithmCd, - subjectPublicKey = Key - }; -transform(#'SubjectPublicKeyInfo'{} = SInfo, pkix) -> - SInfo; - -transform(#'Extension'{extnID = ExtnID} = Ext, ssl) -> - NewExtID = ssl_pkix_oid:id2atom(ExtnID), - ExtAny = setelement(1, Ext, 'Extension-Any'), - {ok, AnyEnc} = 'OTP-PKIX':encode('Extension-Any', ExtAny), - {ok, ExtCd} = 'OTP-PKIX':decode('SSLExtension', list_to_binary(AnyEnc)), - - ExtValue = transform_extension_value(NewExtID, - ExtCd#'SSLExtension'.extnValue, - ssl), - #'Extension'{extnID = NewExtID, - critical = ExtCd#'SSLExtension'.critical, - extnValue = ExtValue}; - -transform(#'Extension'{extnID = ExtnID, extnValue = ExtnValue} = Ext, pkix) -> - NewExtID = ssl_pkix_oid:id2atom(ExtnID), - ExtValue = transform_extension_value(NewExtID, ExtnValue, pkix), - Ext#'Extension'{extnValue = ExtValue}; - -transform(#'AuthorityKeyIdentifier'{authorityCertIssuer = CertIssuer} = Ext, - Type) -> - Ext#'AuthorityKeyIdentifier'{authorityCertIssuer = - transform(CertIssuer, Type)}; - -transform([{directoryName, Value}], Type) -> - [{directoryName, transform(Value, Type)}]; - -transform(X, _) -> - X. - -transform_extension_value('ce-authorityKeyIdentifier', Value, Type) -> - transform(Value, Type); -transform_extension_value(_, Value, _) -> - Value. - -transform_extensions(Exts, Type) when is_list(Exts) -> - [transform(Ext, Type) || Ext <- Exts]; -transform_extensions(Exts, _) -> - Exts. - -get_subj(Cert) -> - (Cert#'Certificate'.tbsCertificate)#'TBSCertificate'.subject. - -signature_digest(BinSignature) -> - case (catch 'OTP-PKIX':decode('DigestInfo', BinSignature)) of - {ok, DigestInfo} -> - list_to_binary(DigestInfo#'DigestInfo'.digest); - _ -> - {error, decode_error} - end. diff --git a/lib/ssl/src/ssl_pkix.hrl b/lib/ssl/src/ssl_pkix.hrl deleted file mode 100644 index a8463369f6..0000000000 --- a/lib/ssl/src/ssl_pkix.hrl +++ /dev/null @@ -1,81 +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% -%% - -%% - --ifndef(ssl_pkix). --define(ssl_pkix, true). - --include("OTP-PKIX.hrl"). - -%% The following commented out records are currently defined in OTP-PKIX.hrl -%% and are considered a public interface through ssl_pkix.hrl. -%% NOTE do not include OTP-PKIX.hrl it is an generated file -%% and may change but the following records will still be -%% availanble from this file. - -% -record('Certificate', { -% tbsCertificate, -% signatureAlgorithm, -% signature}). - -% -record('TBSCertificate', { -% version = asn1_DEFAULT, -% serialNumber, -% signature, -% issuer, -% validity, -% subject, -% subjectPublicKeyInfo, -% issuerUniqueID = asn1_NOVALUE, -% subjectUniqueID = asn1_NOVALUE, -% extensions = asn1_NOVALUE}). - -% -record('AttributeTypeAndValue', { -% type, -% value}). - -% -record('SubjectPublicKeyInfo', { -% algorithm, -% subjectPublicKey}). - --record('SubjectPublicKeyInfo_algorithm', { - algorithm, - parameters = asn1_NOVALUE}). - -% -record('FieldID', { -% fieldType, -% parameters}). - -% -record('Characteristic-two', { -% m, -% basis, -% parameters}). - -% -record('ExtensionAttribute', { -% extensionAttributeType, -% extensionAttributeValue}). - -% -record('Extension', { -% extnID, -% critical = asn1_DEFAULT, -% extnValue}). - --endif. % -ifdef(ssl_pkix). - diff --git a/lib/ssl/src/ssl_record.erl b/lib/ssl/src/ssl_record.erl index da48f049f6..acd0d49c19 100644 --- a/lib/ssl/src/ssl_record.erl +++ b/lib/ssl/src/ssl_record.erl @@ -29,6 +29,7 @@ -include("ssl_internal.hrl"). -include("ssl_alert.hrl"). -include("ssl_handshake.hrl"). +-include("ssl_cipher.hrl"). -include("ssl_debug.hrl"). %% Connection state handling @@ -38,7 +39,10 @@ set_mac_secret/4, set_master_secret/2, activate_pending_connection_state/2, - set_pending_cipher_state/4]). + set_pending_cipher_state/4, + set_renegotiation_flag/2, + set_client_verify_data/3, + set_server_verify_data/3]). %% Handling of incoming data -export([get_tls_records/2]). @@ -62,10 +66,9 @@ %%==================================================================== %% Internal application API %%==================================================================== + %%-------------------------------------------------------------------- -%% Function: init_connection_states(Role) -> #connection_states{} -%% Role = client | server -%% Random = binary() +-spec init_connection_states(client | server) -> #connection_states{}. %% %% Description: Creates a connection_states record with appropriate %% values for the initial SSL connection setup. @@ -81,9 +84,8 @@ init_connection_states(Role) -> }. %%-------------------------------------------------------------------- -%% Function: current_connection_state(States, Type) -> #connection_state{} -%% States = #connection_states{} -%% Type = read | write +-spec current_connection_state(#connection_states{}, read | write) -> + #connection_state{}. %% %% Description: Returns the instance of the connection_state record %% that is currently defined as the current conection state. @@ -96,9 +98,8 @@ current_connection_state(#connection_states{current_write = Current}, Current. %%-------------------------------------------------------------------- -%% Function: pending_connection_state(States, Type) -> #connection_state{} -%% States = #connection_states{} -%% Type = read | write +-spec pending_connection_state(#connection_states{}, read | write) -> + #connection_state{}. %% %% Description: Returns the instance of the connection_state record %% that is currently defined as the pending conection state. @@ -111,14 +112,11 @@ pending_connection_state(#connection_states{pending_write = Pending}, Pending. %%-------------------------------------------------------------------- -%% Function: update_security_params(Params, States) -> -%% #connection_states{} -%% Params = #security_parameters{} -%% States = #connection_states{} +-spec update_security_params(#security_parameters{}, #security_parameters{}, + #connection_states{}) -> #connection_states{}. %% %% Description: Creates a new instance of the connection_states record -%% where the pending states gets its security parameters -%% updated to <Params>. +%% where the pending states gets its security parameters updated. %%-------------------------------------------------------------------- update_security_params(ReadParams, WriteParams, States = #connection_states{pending_read = Read, @@ -131,14 +129,10 @@ update_security_params(ReadParams, WriteParams, States = WriteParams} }. %%-------------------------------------------------------------------- -%% Function: set_mac_secret(ClientWriteMacSecret, -%% ServerWriteMacSecret, Role, States) -> -%% #connection_states{} -%% MacSecret = binary() -%% States = #connection_states{} -%% Role = server | client +-spec set_mac_secret(binary(), binary(), client | server, + #connection_states{}) -> #connection_states{}. %% -%% update the mac_secret field in pending connection states +%% Description: update the mac_secret field in pending connection states %%-------------------------------------------------------------------- set_mac_secret(ClientWriteMacSecret, ServerWriteMacSecret, client, States) -> set_mac_secret(ServerWriteMacSecret, ClientWriteMacSecret, States); @@ -155,12 +149,9 @@ set_mac_secret(ReadMacSecret, WriteMacSecret, %%-------------------------------------------------------------------- -%% Function: set_master_secret(MasterSecret, States) -> -%% #connection_states{} -%% MacSecret = -%% States = #connection_states{} +-spec set_master_secret(binary(), #connection_states{}) -> #connection_states{}. %% -%% Set master_secret in pending connection states +%% Description: Set master_secret in pending connection states %%-------------------------------------------------------------------- set_master_secret(MasterSecret, States = #connection_states{pending_read = Read, @@ -175,12 +166,94 @@ set_master_secret(MasterSecret, master_secret = MasterSecret}}, States#connection_states{pending_read = Read1, pending_write = Write1}. +%%-------------------------------------------------------------------- +-spec set_renegotiation_flag(boolean(), #connection_states{}) -> #connection_states{}. +%% +%% Description: Set secure_renegotiation in pending connection states +%%-------------------------------------------------------------------- +set_renegotiation_flag(Flag, #connection_states{ + current_read = CurrentRead0, + current_write = CurrentWrite0, + pending_read = PendingRead0, + pending_write = PendingWrite0} + = ConnectionStates) -> + CurrentRead = CurrentRead0#connection_state{secure_renegotiation = Flag}, + CurrentWrite = CurrentWrite0#connection_state{secure_renegotiation = Flag}, + PendingRead = PendingRead0#connection_state{secure_renegotiation = Flag}, + PendingWrite = PendingWrite0#connection_state{secure_renegotiation = Flag}, + ConnectionStates#connection_states{current_read = CurrentRead, + current_write = CurrentWrite, + pending_read = PendingRead, + pending_write = PendingWrite}. %%-------------------------------------------------------------------- -%% Function: activate_pending_connection_state(States, Type) -> -%% #connection_states{} -%% States = #connection_states{} -%% Type = read | write +-spec set_client_verify_data(current_read | current_write | current_both, + binary(), #connection_states{})-> + #connection_states{}. +%% +%% Description: Set verify data in connection states. +%%-------------------------------------------------------------------- +set_client_verify_data(current_read, Data, + #connection_states{current_read = CurrentRead0, + pending_write = PendingWrite0} + = ConnectionStates) -> + CurrentRead = CurrentRead0#connection_state{client_verify_data = Data}, + PendingWrite = PendingWrite0#connection_state{client_verify_data = Data}, + ConnectionStates#connection_states{current_read = CurrentRead, + pending_write = PendingWrite}; +set_client_verify_data(current_write, Data, + #connection_states{pending_read = PendingRead0, + current_write = CurrentWrite0} + = ConnectionStates) -> + PendingRead = PendingRead0#connection_state{client_verify_data = Data}, + CurrentWrite = CurrentWrite0#connection_state{client_verify_data = Data}, + ConnectionStates#connection_states{pending_read = PendingRead, + current_write = CurrentWrite}; +set_client_verify_data(current_both, Data, + #connection_states{current_read = CurrentRead0, + current_write = CurrentWrite0} + = ConnectionStates) -> + CurrentRead = CurrentRead0#connection_state{client_verify_data = Data}, + CurrentWrite = CurrentWrite0#connection_state{client_verify_data = Data}, + ConnectionStates#connection_states{current_read = CurrentRead, + current_write = CurrentWrite}. +%%-------------------------------------------------------------------- +-spec set_server_verify_data(current_read | current_write | current_both, + binary(), #connection_states{})-> + #connection_states{}. +%% +%% Description: Set verify data in pending connection states. +%%-------------------------------------------------------------------- +set_server_verify_data(current_write, Data, + #connection_states{pending_read = PendingRead0, + current_write = CurrentWrite0} + = ConnectionStates) -> + PendingRead = PendingRead0#connection_state{server_verify_data = Data}, + CurrentWrite = CurrentWrite0#connection_state{server_verify_data = Data}, + ConnectionStates#connection_states{pending_read = PendingRead, + current_write = CurrentWrite}; + +set_server_verify_data(current_read, Data, + #connection_states{current_read = CurrentRead0, + pending_write = PendingWrite0} + = ConnectionStates) -> + CurrentRead = CurrentRead0#connection_state{server_verify_data = Data}, + PendingWrite = PendingWrite0#connection_state{server_verify_data = Data}, + ConnectionStates#connection_states{current_read = CurrentRead, + pending_write = PendingWrite}; + +set_server_verify_data(current_both, Data, + #connection_states{current_read = CurrentRead0, + current_write = CurrentWrite0} + = ConnectionStates) -> + CurrentRead = CurrentRead0#connection_state{server_verify_data = Data}, + CurrentWrite = CurrentWrite0#connection_state{server_verify_data = Data}, + ConnectionStates#connection_states{current_read = CurrentRead, + current_write = CurrentWrite}. + +%%-------------------------------------------------------------------- +-spec activate_pending_connection_state(#connection_states{}, read | write) -> + #connection_states{}. %% %% Description: Creates a new instance of the connection_states record %% where the pending state of <Type> has been activated. @@ -191,7 +264,9 @@ activate_pending_connection_state(States = NewCurrent = Pending#connection_state{sequence_number = 0}, SecParams = Pending#connection_state.security_parameters, ConnectionEnd = SecParams#security_parameters.connection_end, - NewPending = empty_connection_state(ConnectionEnd), + EmptyPending = empty_connection_state(ConnectionEnd), + SecureRenegotation = NewCurrent#connection_state.secure_renegotiation, + NewPending = EmptyPending#connection_state{secure_renegotiation = SecureRenegotation}, States#connection_states{current_read = NewCurrent, pending_read = NewPending }; @@ -202,17 +277,17 @@ activate_pending_connection_state(States = NewCurrent = Pending#connection_state{sequence_number = 0}, SecParams = Pending#connection_state.security_parameters, ConnectionEnd = SecParams#security_parameters.connection_end, - NewPending = empty_connection_state(ConnectionEnd), + EmptyPending = empty_connection_state(ConnectionEnd), + SecureRenegotation = NewCurrent#connection_state.secure_renegotiation, + NewPending = EmptyPending#connection_state{secure_renegotiation = SecureRenegotation}, States#connection_states{current_write = NewCurrent, pending_write = NewPending }. %%-------------------------------------------------------------------- -%% Function: set_pending_cipher_state(States, ClientState, -%% ServerState, Role) -> -%% #connection_states{} -%% ClientState = ServerState = #cipher_state{} -%% States = #connection_states{} +-spec set_pending_cipher_state(#connection_states{}, #cipher_state{}, + #cipher_state{}, client | server) -> + #connection_states{}. %% %% Description: Set the cipher state in the specified pending connection state. %%-------------------------------------------------------------------- @@ -231,12 +306,10 @@ set_pending_cipher_state(#connection_states{pending_read = Read, pending_write = Write#connection_state{cipher_state = ClientState}}. %%-------------------------------------------------------------------- -%% Function: get_tls_record(Data, Buffer) -> Result -%% Result = {[#tls_compressed{}], NewBuffer} -%% Data = Buffer = NewBuffer = binary() -%% -%% Description: given old buffer and new data from TCP, packs up a records -%% and returns it as a list of #tls_compressed, also returns leftover +-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 %% data %%-------------------------------------------------------------------- get_tls_records(Data, <<>>) -> @@ -299,8 +372,8 @@ get_tls_records_aux(Data, Acc) -> {lists:reverse(Acc), Data}. %%-------------------------------------------------------------------- -%% Function: protocol_version(Version) -> #protocol_version{} -%% Version = atom() +-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. @@ -311,19 +384,16 @@ protocol_version(tlsv1) -> {3, 1}; protocol_version(sslv3) -> {3, 0}; -protocol_version(sslv2) -> +protocol_version(sslv2) -> %% Backwards compatibility {2, 0}; protocol_version({3, 2}) -> 'tlsv1.1'; protocol_version({3, 1}) -> tlsv1; protocol_version({3, 0}) -> - sslv3; -protocol_version({2, 0}) -> - sslv2. + sslv3. %%-------------------------------------------------------------------- -%% Function: protocol_version(Version1, Version2) -> #protocol_version{} -%% Version1 = Version2 = #protocol_version{} +-spec lowest_protocol_version(tls_version(), tls_version()) -> tls_version(). %% %% Description: Lowes protocol version of two given versions %%-------------------------------------------------------------------- @@ -338,8 +408,7 @@ lowest_protocol_version(Version = {M,_}, lowest_protocol_version(_,Version) -> Version. %%-------------------------------------------------------------------- -%% Function: protocol_version(Versions) -> #protocol_version{} -%% Versions = [#protocol_version{}] +-spec highest_protocol_version([tls_version()]) -> tls_version(). %% %% Description: Highest protocol version present in a list %%-------------------------------------------------------------------- @@ -361,14 +430,13 @@ highest_protocol_version(_, [Version | Rest]) -> highest_protocol_version(Version, Rest). %%-------------------------------------------------------------------- -%% Function: supported_protocol_versions() -> Versions -%% Versions = [#protocol_version{}] -%% +-spec supported_protocol_versions() -> [tls_version()]. +%% %% Description: Protocol versions supported %%-------------------------------------------------------------------- supported_protocol_versions() -> Fun = fun(Version) -> - protocol_version(Version) + protocol_version(Version) end, case application:get_env(ssl, protocol_version) of undefined -> @@ -376,14 +444,20 @@ supported_protocol_versions() -> {ok, []} -> lists:map(Fun, ?DEFAULT_SUPPORTED_VERSIONS); {ok, Vsns} when is_list(Vsns) -> - lists:map(Fun, Vsns); + Versions = lists:filter(fun is_acceptable_version/1, lists:map(Fun, Vsns)), + supported_protocol_versions(Versions); {ok, Vsn} -> - [Fun(Vsn)] + Versions = lists:filter(fun is_acceptable_version/1, [Fun(Vsn)]), + supported_protocol_versions(Versions) end. +supported_protocol_versions([]) -> + ?DEFAULT_SUPPORTED_VERSIONS; +supported_protocol_versions([_|_] = Vsns) -> + Vsns. + %%-------------------------------------------------------------------- -%% Function: is_acceptable_version(Version) -> true | false -%% Version = #protocol_version{} +-spec is_acceptable_version(tls_version()) -> boolean(). %% %% Description: ssl version 2 is not acceptable security risks are too big. %%-------------------------------------------------------------------- @@ -394,7 +468,7 @@ is_acceptable_version(_) -> false. %%-------------------------------------------------------------------- -%% Function: compressions() -> binary() +-spec compressions() -> [binary()]. %% %% Description: return a list of compressions supported (currently none) %%-------------------------------------------------------------------- @@ -402,8 +476,8 @@ compressions() -> [?byte(?NULL)]. %%-------------------------------------------------------------------- -%% Function: decode_cipher_text(CipherText, ConnectionStates0) -> -%% {Plain, ConnectionStates} +-spec decode_cipher_text(#ssl_tls{}, #connection_states{}) -> + {#ssl_tls{}, #connection_states{}}| #alert{}. %% %% Description: Decode cipher text %%-------------------------------------------------------------------- @@ -412,13 +486,17 @@ decode_cipher_text(CipherText, ConnnectionStates0) -> #connection_state{compression_state = CompressionS0, security_parameters = SecParams} = ReadState0, CompressAlg = SecParams#security_parameters.compression_algorithm, - {Compressed, ReadState1} = decipher(CipherText, ReadState0), - {Plain, CompressionS1} = uncompress(CompressAlg, - Compressed, CompressionS0), - ConnnectionStates = ConnnectionStates0#connection_states{ - current_read = ReadState1#connection_state{ - compression_state = CompressionS1}}, - {Plain, ConnnectionStates}. + case decipher(CipherText, ReadState0) of + {Compressed, ReadState1} -> + {Plain, CompressionS1} = uncompress(CompressAlg, + Compressed, CompressionS0), + ConnnectionStates = ConnnectionStates0#connection_states{ + current_read = ReadState1#connection_state{ + compression_state = CompressionS1}}, + {Plain, ConnnectionStates}; + #alert{} = Alert -> + Alert + end. %%-------------------------------------------------------------------- %%% Internal functions @@ -433,12 +511,10 @@ initial_connection_state(ConnectionEnd) -> }. initial_security_params(ConnectionEnd) -> - #security_parameters{connection_end = ConnectionEnd, - bulk_cipher_algorithm = ?NULL, - mac_algorithm = ?NULL, - compression_algorithm = ?NULL, - cipher_type = ?NULL - }. + SecParams = #security_parameters{connection_end = ConnectionEnd, + compression_algorithm = ?NULL}, + ssl_cipher:security_parameters(?TLS_NULL_WITH_NULL_NULL, + SecParams). empty_connection_state(ConnectionEnd) -> SecParams = empty_security_params(ConnectionEnd), @@ -544,29 +620,37 @@ encode_tls_cipher_text(Type, {MajVer, MinVer}, Fragment) -> cipher(Type, Version, Fragment, CS0) -> Length = erlang:iolist_size(Fragment), - {Hash, CS1=#connection_state{cipher_state = CipherS0, + {MacHash, CS1=#connection_state{cipher_state = CipherS0, security_parameters= #security_parameters{bulk_cipher_algorithm = BCA} }} = hash_and_bump_seqno(CS0, Type, Version, Length, Fragment), ?DBG_HEX(Fragment), - {Ciphered, CipherS1} = ssl_cipher:cipher(BCA, CipherS0, Hash, Fragment), + {Ciphered, CipherS1} = ssl_cipher:cipher(BCA, CipherS0, MacHash, Fragment), ?DBG_HEX(Ciphered), CS2 = CS1#connection_state{cipher_state=CipherS1}, {Ciphered, CS2}. decipher(TLS=#ssl_tls{type=Type, version=Version, fragment=Fragment}, CS0) -> SP = CS0#connection_state.security_parameters, - BCA = SP#security_parameters.bulk_cipher_algorithm, % eller Cipher? + BCA = SP#security_parameters.bulk_cipher_algorithm, HashSz = SP#security_parameters.hash_size, CipherS0 = CS0#connection_state.cipher_state, - {T, Mac, CipherS1} = ssl_cipher:decipher(BCA, HashSz, CipherS0, Fragment), - CS1 = CS0#connection_state{cipher_state = CipherS1}, - TLength = size(T), - {Hash, CS2} = hash_and_bump_seqno(CS1, Type, Version, TLength, Fragment), - ok = check_hash(Hash, Mac), - {TLS#ssl_tls{fragment = T}, CS2}. + case ssl_cipher:decipher(BCA, HashSz, CipherS0, Fragment, Version) of + {T, Mac, CipherS1} -> + CS1 = CS0#connection_state{cipher_state = CipherS1}, + TLength = size(T), + {MacHash, CS2} = hash_and_bump_seqno(CS1, Type, Version, TLength, T), + case is_correct_mac(Mac, MacHash) of + true -> + {TLS#ssl_tls{fragment = T}, CS2}; + false -> + ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC) + end; + #alert{} = Alert -> + Alert + end. uncompress(?NULL, Data = #ssl_tls{type = _Type, version = _Version, @@ -587,10 +671,12 @@ hash_and_bump_seqno(#connection_state{sequence_number = SeqNo, Length, Fragment), {Hash, CS0#connection_state{sequence_number = SeqNo+1}}. -check_hash(_, _) -> - ok. %% TODO check this +is_correct_mac(Mac, Mac) -> + true; +is_correct_mac(_M,_H) -> + false. -mac_hash(?NULL, {_,_}, _MacSecret, _SeqNo, _Type, +mac_hash({_,_}, ?NULL, _MacSecret, _SeqNo, _Type, _Length, _Fragment) -> <<>>; mac_hash({3, 0}, MacAlg, MacSecret, SeqNo, Type, Length, Fragment) -> diff --git a/lib/ssl/src/ssl_record.hrl b/lib/ssl/src/ssl_record.hrl index 362b7039d4..5fb0070b91 100644 --- a/lib/ssl/src/ssl_record.hrl +++ b/lib/ssl/src/ssl_record.hrl @@ -60,7 +60,11 @@ compression_state, cipher_state, mac_secret, - sequence_number + sequence_number, + %% RFC 5746 + secure_renegotiation, + client_verify_data, + server_verify_data }). -define(MAX_SEQENCE_NUMBER, 18446744073709552000). %% math:pow(2, 64) - 1 = 1.8446744073709552e19 diff --git a/lib/ssl/src/ssl_session.erl b/lib/ssl/src/ssl_session.erl index bcb10daf69..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 @@ -32,11 +32,10 @@ -define(GEN_UNIQUE_ID_MAX_TRIES, 10). +-type seconds() :: integer(). + %%-------------------------------------------------------------------- -%% Function: is_new(ClientSuggestedId, ServerDecidedId) -> true | false -%% -%% ClientSuggestedId = binary() -%% ServerDecidedId = binary() +-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. @@ -45,17 +44,11 @@ is_new(<<>>, _) -> true; is_new(SessionId, SessionId) -> false; -is_new(_, _) -> +is_new(_ClientSuggestion, _ServerDecision) -> true. %%-------------------------------------------------------------------- -%% Function: id(ClientInfo, Cache, CacheCb) -> SessionId -%% -%% ClientInfo = {HostIP, Port, SslOpts} -%% HostIP = ipadress() -%% Port = integer() -%% CacheCb = atom() -%% SessionId = binary() +-spec id({host(), port_num(), #ssl_options{}}, cache_ref(), atom()) -> binary(). %% %% Description: Should be called by the client side to get an id %% for the client hello message. @@ -69,14 +62,8 @@ id(ClientInfo, Cache, CacheCb) -> end. %%-------------------------------------------------------------------- -%% Function: id(Port, SuggestedSessionId, ReuseFun, CacheCb, -%% SecondLifeTime) -> SessionId -%% -%% Port = integer() -%% SuggestedSessionId = SessionId = binary() -%% ReuseFun = fun(SessionId, PeerCert, Compression, CipherSuite) -> -%% true | false -%% CacheCb = atom() +-spec id(port_num(), binary(), #ssl_options{}, cache_ref(), + atom(), seconds()) -> binary(). %% %% Description: Should be called by the server side to get an id %% for the server hello message. @@ -95,10 +82,7 @@ id(Port, SuggestedSessionId, #ssl_options{reuse_sessions = ReuseEnabled, new_id(Port, ?GEN_UNIQUE_ID_MAX_TRIES, Cache, CacheCb) end. %%-------------------------------------------------------------------- -%% Function: valid_session(Session, LifeTime) -> true | false -%% -%% Session = #session{} -%% LifeTime = integer() - seconds +-spec valid_session(#session{}, seconds()) -> boolean(). %% %% Description: Check that the session has not expired %%-------------------------------------------------------------------- @@ -129,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_session_cache.erl b/lib/ssl/src/ssl_session_cache.erl index 4a60892235..823bf7acfa 100644 --- a/lib/ssl/src/ssl_session_cache.erl +++ b/lib/ssl/src/ssl_session_cache.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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,23 +22,24 @@ -behaviour(ssl_session_cache_api). --export([init/0, terminate/1, lookup/2, update/3, delete/2, foldl/3, - select_session/2]). +-include("ssl_handshake.hrl"). +-include("ssl_internal.hrl"). + +-export([init/1, terminate/1, lookup/2, update/3, delete/2, foldl/3, + select_session/2]). + +-type key() :: {{host(), port_num()}, session_id()} | {port_num(), session_id()}. %%-------------------------------------------------------------------- -%% Function: init() -> Cache -%% -%% Cache - Reference to the cash (opaque) +-spec init(list()) -> cache_ref(). %% Returns reference to the cache (opaque) %% %% Description: Return table reference. Called by ssl_manager process. %%-------------------------------------------------------------------- -init() -> +init(_) -> ets:new(cache_name(), [set, protected]). %%-------------------------------------------------------------------- -%% Function: terminate(Cache) -> -%% -%% Cache - as returned by create/0 +-spec terminate(cache_ref()) -> any(). %% %% %% Description: Handles cache table at termination of ssl manager. %%-------------------------------------------------------------------- @@ -46,9 +47,7 @@ terminate(Cache) -> ets:delete(Cache). %%-------------------------------------------------------------------- -%% Function: lookup(Cache, Key) -> Session | undefined -%% Cache - as returned by create/0 -%% Session = #session{} +-spec lookup(cache_ref(), key()) -> #session{} | undefined. %% %% Description: Looks up a cach entry. Should be callable from any %% process. @@ -62,9 +61,7 @@ lookup(Cache, Key) -> end. %%-------------------------------------------------------------------- -%% Function: update(Cache, Key, Session) -> _ -%% Cache - as returned by create/0 -%% Session = #session{} +-spec update(cache_ref(), key(), #session{}) -> any(). %% %% Description: Caches a new session or updates a already cached one. %% Will only be called from the ssl_manager process. @@ -73,11 +70,7 @@ update(Cache, Key, Session) -> ets:insert(Cache, {Key, Session}). %%-------------------------------------------------------------------- -%% Function: delete(Cache, HostIP, Port, Id) -> _ -%% Cache - as returned by create/0 -%% HostIP = Host = string() | ipadress() -%% Port = integer() -%% Id = +-spec delete(cache_ref(), key()) -> any(). %% %% Description: Delets a cache entry. %% Will only be called from the ssl_manager process. @@ -86,28 +79,19 @@ delete(Cache, Key) -> ets:delete(Cache, Key). %%-------------------------------------------------------------------- -%% Function: foldl(Fun, Acc0, Cache) -> Acc -%% -%% Fun - fun() -%% Acc0 - term() -%% Cache - cache_ref() -%% +-spec foldl(fun(), term(), cache_ref()) -> term(). %% %% Description: Calls Fun(Elem, AccIn) on successive elements of the %% cache, starting with AccIn == Acc0. Fun/2 must return a new %% accumulator which is passed to the next call. The function returns -%% the final value of the accumulator. Acc0 is returned if the cache is -%% empty. -%% Should be callable from any process +%% the final value of the accumulator. Acc0 is returned if the cache +%% is empty.Should be callable from any process %%-------------------------------------------------------------------- foldl(Fun, Acc0, Cache) -> ets:foldl(Fun, Acc0, Cache). %%-------------------------------------------------------------------- -%% Function: select_session(Cache, PartialKey) -> [Sessions] -%% -%% Cache - as returned by create/0 -%% PartialKey - opaque Key = {PartialKey, SessionId} +-spec select_session(cache_ref(), {host(), port_num()} | port_num()) -> [#session{}]. %% %% Description: Selects a session that could be reused. Should be callable %% from any process. @@ -119,6 +103,5 @@ select_session(Cache, PartialKey) -> %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- - cache_name() -> ssl_otp_session_cache. diff --git a/lib/ssl/src/ssl_session_cache_api.erl b/lib/ssl/src/ssl_session_cache_api.erl index d2e846e9fd..f8416bf327 100644 --- a/lib/ssl/src/ssl_session_cache_api.erl +++ b/lib/ssl/src/ssl_session_cache_api.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -25,7 +25,7 @@ behaviour_info(callbacks) -> [ - {init, 0}, + {init, 1}, {terminate, 1}, {lookup, 2}, {update, 3}, diff --git a/lib/ssl/src/ssl_ssl3.erl b/lib/ssl/src/ssl_ssl3.erl index df809ce275..1add203fb0 100644 --- a/lib/ssl/src/ssl_ssl3.erl +++ b/lib/ssl/src/ssl_ssl3.erl @@ -30,7 +30,7 @@ -include("ssl_record.hrl"). % MD5 and SHA -export([master_secret/3, finished/3, certificate_verify/3, - mac_hash/6, setup_keys/8, + mac_hash/6, setup_keys/7, suites/0]). -compile(inline). @@ -38,6 +38,8 @@ %% Internal application API %%==================================================================== +-spec master_secret(binary(), binary(), binary()) -> binary(). + master_secret(PremasterSecret, ClientRandom, ServerRandom) -> ?DBG_HEX(PremasterSecret), ?DBG_HEX(ClientRandom), @@ -57,6 +59,8 @@ master_secret(PremasterSecret, ClientRandom, ServerRandom) -> ?DBG_HEX(B), B. +-spec finished(client | server, binary(), {binary(), binary()}) -> binary(). + finished(Role, MasterSecret, {MD5Hash, SHAHash}) -> %% draft-ietf-tls-ssl-version3-00 - 5.6.9 Finished %% struct { @@ -75,8 +79,10 @@ finished(Role, MasterSecret, {MD5Hash, SHAHash}) -> SHA = handshake_hash(?SHA, MasterSecret, Sender, SHAHash), <<MD5/binary, SHA/binary>>. +-spec certificate_verify(key_algo(), binary(), {binary(), binary()}) -> binary(). + certificate_verify(Algorithm, MasterSecret, {MD5Hash, SHAHash}) - when Algorithm == rsa; Algorithm == dh_rsa; Algorithm == dhe_rsa -> + when Algorithm == rsa; Algorithm == dhe_rsa -> %% md5_hash %% MD5(master_secret + pad_2 + %% MD5(handshake_messages + master_secret + pad_1)); @@ -88,13 +94,14 @@ certificate_verify(Algorithm, MasterSecret, {MD5Hash, SHAHash}) SHA = handshake_hash(?SHA, MasterSecret, undefined, SHAHash), <<MD5/binary, SHA/binary>>; -certificate_verify(Algorithm, MasterSecret, {_, SHAHash}) - when Algorithm == dh_dss; Algorithm == dhe_dss -> +certificate_verify(dhe_dss, MasterSecret, {_, SHAHash}) -> %% sha_hash %% SHA(master_secret + pad_2 + %% SHA(handshake_messages + master_secret + pad_1)); handshake_hash(?SHA, MasterSecret, undefined, SHAHash). +-spec mac_hash(integer(), binary(), integer(), integer(), integer(), binary()) -> binary(). + mac_hash(Method, Mac_write_secret, Seq_num, Type, Length, Fragment) -> %% draft-ietf-tls-ssl-version3-00 - 5.2.3.1 %% hash(MAC_write_secret + pad_2 + @@ -114,9 +121,12 @@ mac_hash(Method, Mac_write_secret, Seq_num, Type, Length, Fragment) -> ?DBG_HEX(Mac), Mac. -setup_keys(Exportable, MasterSecret, ServerRandom, ClientRandom, - HS, KML, _EKML, IVS) - when Exportable == no_export; Exportable == ignore -> +-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, 2*(HS+KML+IVS)), %% draft-ietf-tls-ssl-version3-00 - 6.2.2 @@ -137,79 +147,25 @@ setup_keys(Exportable, MasterSecret, ServerRandom, ClientRandom, ?DBG_HEX(ClientIV), ?DBG_HEX(ServerIV), {ClientWriteMacSecret, ServerWriteMacSecret, ClientWriteKey, - ServerWriteKey, ClientIV, ServerIV}; - -setup_keys(export, MasterSecret, ServerRandom, ClientRandom, - HS, KML, EKML, IVS) -> - KeyBlock = generate_keyblock(MasterSecret, ServerRandom, ClientRandom, - 2*(HS+KML)), - %% draft-ietf-tls-ssl-version3-00 - 6.2.2 - %% Exportable encryption algorithms (for which - %% CipherSpec.is_exportable is true) require additional processing as - %% follows to derive their final write keys: + ServerWriteKey, ClientIV, ServerIV}. - %% final_client_write_key = MD5(client_write_key + - %% ClientHello.random + - %% ServerHello.random); - %% final_server_write_key = MD5(server_write_key + - %% ServerHello.random + - %% ClientHello.random); - - %% Exportable encryption algorithms derive their IVs from the random - %% messages: - %% client_write_IV = MD5(ClientHello.random + ServerHello.random); - %% server_write_IV = MD5(ServerHello.random + ClientHello.random); - - <<ClientWriteMacSecret:HS/binary, ServerWriteMacSecret:HS/binary, - ClientWriteKey:KML/binary, ServerWriteKey:KML/binary>> = KeyBlock, - <<ClientIV:IVS/binary, _/binary>> = - hash(?MD5, [ClientRandom, ServerRandom]), - <<ServerIV:IVS/binary, _/binary>> = - hash(?MD5, [ServerRandom, ClientRandom]), - <<FinalClientWriteKey:EKML/binary, _/binary>> = - hash(?MD5, [ClientWriteKey, ClientRandom, ServerRandom]), - <<FinalServerWriteKey:EKML/binary, _/binary>> = - hash(?MD5, [ServerWriteKey, ServerRandom, ClientRandom]), - ?DBG_HEX(ClientWriteMacSecret), - ?DBG_HEX(ServerWriteMacSecret), - ?DBG_HEX(FinalClientWriteKey), - ?DBG_HEX(FinalServerWriteKey), - ?DBG_HEX(ClientIV), - ?DBG_HEX(ServerIV), - {ClientWriteMacSecret, ServerWriteMacSecret, FinalClientWriteKey, - FinalServerWriteKey, ClientIV, ServerIV}. +-spec suites() -> [cipher_suite()]. suites() -> [ - %% TODO: uncomment when supported ?TLS_DHE_RSA_WITH_AES_256_CBC_SHA, - %% ?TLS_DHE_DSS_WITH_AES_256_CBC_SHA, + ?TLS_DHE_DSS_WITH_AES_256_CBC_SHA, ?TLS_RSA_WITH_AES_256_CBC_SHA, ?TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, - %% ?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, + ?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, ?TLS_RSA_WITH_3DES_EDE_CBC_SHA, ?TLS_DHE_RSA_WITH_AES_128_CBC_SHA, - %% ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA, + ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA, ?TLS_RSA_WITH_AES_128_CBC_SHA, - %%?TLS_DHE_DSS_WITH_RC4_128_SHA, TODO: Support this? - %% ?TLS_RSA_WITH_IDEA_CBC_SHA, Not supported: in later openssl version than OTP requires - + %%?TLS_RSA_WITH_IDEA_CBC_SHA, ?TLS_RSA_WITH_RC4_128_SHA, ?TLS_RSA_WITH_RC4_128_MD5, - %%?TLS_RSA_EXPORT1024_WITH_RC4_56_MD5, - %%?TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5, - %%?TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, - %%?TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA, - %%?TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, - %%?TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA, - %%?TLS_DHE_DSS_WITH_RC4_128_SHA, - ?TLS_RSA_WITH_DES_CBC_SHA - %% ?TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, - %% ?TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, - %% ?TLS_RSA_EXPORT_WITH_DES40_CBC_SHA, - %%?TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5, - %%?TLS_RSA_EXPORT_WITH_RC4_40_MD5 ]. %%-------------------------------------------------------------------- @@ -269,8 +225,7 @@ handshake_hash(Method, MasterSecret, Sender, HandshakeHash) -> hash(Method, [MasterSecret, pad_2(Method), InnerHash]). get_sender(client) -> "CLNT"; -get_sender(server) -> "SRVR"; -get_sender(none) -> "". +get_sender(server) -> "SRVR". generate_keyblock(MasterSecret, ServerRandom, ClientRandom, WantedLength) -> gen(MasterSecret, [MasterSecret, ServerRandom, ClientRandom], diff --git a/lib/ssl/src/ssl_sup.erl b/lib/ssl/src/ssl_sup.erl index bd5a02417a..316ed8a4e9 100644 --- a/lib/ssl/src/ssl_sup.erl +++ b/lib/ssl/src/ssl_sup.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1998-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% %% @@ -32,16 +32,18 @@ %%%========================================================================= %%% API %%%========================================================================= + +-spec start_link() -> {ok, pid()} | ignore | {error, term()}. + start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). %%%========================================================================= %%% Supervisor callback %%%========================================================================= -%% init([]) -> {ok, {SupFlags, [ChildSpec]}} -%% -init([]) -> - +-spec init([]) -> {ok, {SupFlags :: tuple(), [ChildSpec :: tuple()]}}. + +init([]) -> %% OLD ssl - moved start to ssl.erl only if old %% ssl is acctualy run! %%Child1 = {ssl_server, {ssl_server, start_link, []}, @@ -67,7 +69,7 @@ init([]) -> session_and_cert_manager_child_spec() -> Opts = manager_opts(), Name = ssl_manager, - StartFunc = {ssl_manager, start_link, Opts}, + StartFunc = {ssl_manager, start_link, [Opts]}, Restart = permanent, Shutdown = 4000, Modules = [ssl_manager], @@ -86,11 +88,12 @@ connection_manager_child_spec() -> manager_opts() -> CbOpts = case application:get_env(ssl, session_cb) of - {ok, Cb} when is_atom(Cb) -> - [{session_cb, Cb}]; - _ -> - [] - end, + {ok, Cb} when is_atom(Cb) -> + InitArgs = session_cb_init_args(), + [{session_cb, Cb}, {session_cb_init_args, InitArgs}]; + _ -> + [] + end, case application:get_env(ssl, session_lifetime) of {ok, Time} when is_integer(Time) -> [{session_lifetime, Time}| CbOpts]; @@ -98,3 +101,10 @@ manager_opts() -> CbOpts end. +session_cb_init_args() -> + case application:get_env(ssl, session_cb_init_args) of + {ok, Args} when is_list(Args) -> + Args; + _ -> + [] + end. diff --git a/lib/ssl/src/ssl_tls1.erl b/lib/ssl/src/ssl_tls1.erl index ce9a135168..d1bc0730ba 100644 --- a/lib/ssl/src/ssl_tls1.erl +++ b/lib/ssl/src/ssl_tls1.erl @@ -30,12 +30,14 @@ -include("ssl_debug.hrl"). -export([master_secret/3, finished/3, certificate_verify/2, mac_hash/7, - setup_keys/5, setup_keys/6, suites/0]). + setup_keys/6, suites/0]). %%==================================================================== %% Internal application API %%==================================================================== +-spec master_secret(binary(), binary(), binary()) -> binary(). + master_secret(PreMasterSecret, ClientRandom, ServerRandom) -> %% RFC 2246 & 4346 - 8.1 %% master_secret = PRF(pre_master_secret, %% "master secret", ClientHello.random + @@ -43,6 +45,8 @@ master_secret(PreMasterSecret, ClientRandom, ServerRandom) -> prf(PreMasterSecret, <<"master secret">>, [ClientRandom, ServerRandom], 48). +-spec finished(client | server, binary(), {binary(), binary()}) -> binary(). + finished(Role, MasterSecret, {MD5Hash, SHAHash}) -> %% RFC 2246 & 4346 - 7.4.9. Finished %% struct { @@ -56,18 +60,21 @@ finished(Role, MasterSecret, {MD5Hash, SHAHash}) -> SHA = hash_final(?SHA, SHAHash), prf(MasterSecret, finished_label(Role), [MD5, SHA], 12). +-spec certificate_verify(key_algo(), {binary(), binary()}) -> binary(). certificate_verify(Algorithm, {MD5Hash, SHAHash}) when Algorithm == rsa; - Algorithm == dh_rsa; Algorithm == dhe_rsa -> MD5 = hash_final(?MD5, MD5Hash), SHA = hash_final(?SHA, SHAHash), <<MD5/binary, SHA/binary>>; -certificate_verify(Algorithm, {_, SHAHash}) when Algorithm == dh_dss; - Algorithm == dhe_dss -> +certificate_verify(dhe_dss, {_, SHAHash}) -> hash_final(?SHA, SHAHash). - + +-spec setup_keys(binary(), binary(), binary(), integer(), + integer(), integer()) -> {binary(), binary(), binary(), + binary(), binary(), binary()}. + setup_keys(MasterSecret, ServerRandom, ClientRandom, HashSize, KeyMatLen, IVSize) -> %% RFC 2246 - 6.3. Key calculation @@ -92,26 +99,30 @@ setup_keys(MasterSecret, ServerRandom, ClientRandom, HashSize, {ClientWriteMacSecret, ServerWriteMacSecret, ClientWriteKey, ServerWriteKey, ClientIV, ServerIV}. -setup_keys(MasterSecret, ServerRandom, ClientRandom, HashSize, KeyMatLen) -> - %% RFC 4346 - 6.3. Key calculation - %% key_block = PRF(SecurityParameters.master_secret, - %% "key expansion", - %% SecurityParameters.server_random + - %% SecurityParameters.client_random); - %% Then the key_block is partitioned as follows: - %% client_write_MAC_secret[SecurityParameters.hash_size] - %% server_write_MAC_secret[SecurityParameters.hash_size] - %% client_write_key[SecurityParameters.key_material_length] - %% server_write_key[SecurityParameters.key_material_length] - WantedLength = 2 * (HashSize + KeyMatLen), - KeyBlock = prf(MasterSecret, "key expansion", - [ServerRandom, ClientRandom], WantedLength), - <<ClientWriteMacSecret:HashSize/binary, - ServerWriteMacSecret:HashSize/binary, - ClientWriteKey:KeyMatLen/binary, ServerWriteKey:KeyMatLen/binary>> - = KeyBlock, - {ClientWriteMacSecret, ServerWriteMacSecret, ClientWriteKey, - ServerWriteKey, undefined, undefined}. +%% TLS v1.1 uncomment when supported. +%% setup_keys(MasterSecret, ServerRandom, ClientRandom, HashSize, KeyMatLen) -> +%% %% RFC 4346 - 6.3. Key calculation +%% %% key_block = PRF(SecurityParameters.master_secret, +%% %% "key expansion", +%% %% SecurityParameters.server_random + +%% %% SecurityParameters.client_random); +%% %% Then the key_block is partitioned as follows: +%% %% client_write_MAC_secret[SecurityParameters.hash_size] +%% %% server_write_MAC_secret[SecurityParameters.hash_size] +%% %% client_write_key[SecurityParameters.key_material_length] +%% %% server_write_key[SecurityParameters.key_material_length] +%% WantedLength = 2 * (HashSize + KeyMatLen), +%% KeyBlock = prf(MasterSecret, "key expansion", +%% [ServerRandom, ClientRandom], WantedLength), +%% <<ClientWriteMacSecret:HashSize/binary, +%% ServerWriteMacSecret:HashSize/binary, +%% ClientWriteKey:KeyMatLen/binary, ServerWriteKey:KeyMatLen/binary>> +%% = KeyBlock, +%% {ClientWriteMacSecret, ServerWriteMacSecret, ClientWriteKey, +%% ServerWriteKey, undefined, undefined}. + +-spec mac_hash(integer(), binary(), integer(), integer(), tls_version(), + integer(), binary()) -> binary(). mac_hash(Method, Mac_write_secret, Seq_num, Type, {Major, Minor}, Length, Fragment) -> @@ -133,37 +144,24 @@ mac_hash(Method, Mac_write_secret, Seq_num, Type, {Major, Minor}, ?DBG_HEX(Mac), Mac. +-spec suites() -> [cipher_suite()]. + suites() -> [ - %% TODO: uncomment when supported ?TLS_DHE_RSA_WITH_AES_256_CBC_SHA, - %%?TLS_DHE_DSS_WITH_AES_256_CBC_SHA, + ?TLS_DHE_DSS_WITH_AES_256_CBC_SHA, ?TLS_RSA_WITH_AES_256_CBC_SHA, ?TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, - %% ?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, + ?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, ?TLS_RSA_WITH_3DES_EDE_CBC_SHA, ?TLS_DHE_RSA_WITH_AES_128_CBC_SHA, - %% ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA, + ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA, ?TLS_RSA_WITH_AES_128_CBC_SHA, - %%?TLS_DHE_DSS_WITH_RC4_128_SHA, TODO: Support this? - %% ?TLS_RSA_WITH_IDEA_CBC_SHA, + %%?TLS_RSA_WITH_IDEA_CBC_SHA, ?TLS_RSA_WITH_RC4_128_SHA, ?TLS_RSA_WITH_RC4_128_MD5, - %%?TLS_RSA_EXPORT1024_WITH_RC4_56_MD5, - %%?TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5, - %%?TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, - %%?TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA, - %%?TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, - %%?TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA, - %%?TLS_DHE_DSS_WITH_RC4_128_SHA, - %%?TLS_DHE_RSA_WITH_DES_CBC_SHA, - %% EDH-DSS-DES-CBC-SHA TODO: ?? + ?TLS_DHE_RSA_WITH_DES_CBC_SHA, ?TLS_RSA_WITH_DES_CBC_SHA - %% ?TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, - %% ?TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, - %%?TLS_RSA_EXPORT_WITH_DES40_CBC_SHA, - %%?TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5, - %%?TLS_RSA_EXPORT_WITH_RC4_40_MD5 ]. %%-------------------------------------------------------------------- @@ -245,7 +243,3 @@ hash_final(?MD5, Conntext) -> crypto:md5_final(Conntext); hash_final(?SHA, Conntext) -> crypto:sha_final(Conntext). - - - - diff --git a/lib/ssl/test/Makefile b/lib/ssl/test/Makefile index bd86120c98..9e4aecac45 100644 --- a/lib/ssl/test/Makefile +++ b/lib/ssl/test/Makefile @@ -1,19 +1,19 @@ # # %CopyrightBegin% -# -# Copyright Ericsson AB 1999-2009. All Rights Reserved. -# +# +# 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% # @@ -50,7 +50,8 @@ MODULES = \ old_ssl_protocol_SUITE \ old_transport_accept_SUITE \ old_ssl_dist_SUITE \ - make_certs + make_certs\ + erl_make_certs ERL_FILES = $(MODULES:%=%.erl) @@ -58,12 +59,10 @@ ERL_FILES = $(MODULES:%=%.erl) HRL_FILES = ssl_test_MACHINE.hrl HRL_FILES_SRC = \ - ssl_pkix.hrl \ ssl_alert.hrl \ ssl_handshake.hrl -HRL_FILES_INC = \ - OTP-PKIX.hrl +HRL_FILES_INC = HRL_FILES_NEEDED_IN_TEST = \ $(HRL_FILES_SRC:%=../src/%) \ diff --git a/lib/ssl/test/erl_make_certs.erl b/lib/ssl/test/erl_make_certs.erl new file mode 100644 index 0000000000..f8aef55754 --- /dev/null +++ b/lib/ssl/test/erl_make_certs.erl @@ -0,0 +1,421 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% +%% + +%% Create test certificates + +-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]). +-compile(export_all). + +%%-------------------------------------------------------------------- +%% @doc Create and return a der encoded certificate +%% Option Default +%% ------------------------------------------------------- +%% digest sha1 +%% validity {date(), date() + week()} +%% version 3 +%% subject [] list of the following content +%% {name, Name} +%% {email, Email} +%% {city, City} +%% {state, State} +%% {org, Org} +%% {org_unit, OrgUnit} +%% {country, Country} +%% {serial, Serial} +%% {title, Title} +%% {dnQualifer, DnQ} +%% issuer = {Issuer, IssuerKey} true (i.e. a ca cert is created) +%% (obs IssuerKey migth be {Key, Password} +%% key = KeyFile|KeyBin|rsa|dsa Subject PublicKey rsa or dsa generates key +%% +%% +%% (OBS: The generated keys are for testing only) +%% @spec ([{::atom(), ::term()}]) -> {Cert::binary(), Key::binary()} +%% @end +%%-------------------------------------------------------------------- + +make_cert(Opts) -> + SubjectPrivateKey = get_key(Opts), + {TBSCert, IssuerKey} = make_tbs(SubjectPrivateKey, Opts), + Cert = public_key:pkix_sign(TBSCert, IssuerKey), + true = verify_signature(Cert, IssuerKey, undef), %% verify that the keys where ok + {Cert, encode_key(SubjectPrivateKey)}. + +%%-------------------------------------------------------------------- +%% @doc Writes pem files in Dir with FileName ++ ".pem" and FileName ++ "_key.pem" +%% @spec (::string(), ::string(), {Cert,Key}) -> ok +%% @end +%%-------------------------------------------------------------------- +write_pem(Dir, FileName, {Cert, Key = {_,_,not_encrypted}}) when is_binary(Cert) -> + 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) +%% the size are in bytes +%% @spec (::integer()) -> {::atom(), ::binary(), ::opaque()} +%% @end +%%-------------------------------------------------------------------- +gen_rsa(Size) when is_integer(Size) -> + Key = gen_rsa2(Size), + {Key, encode_key(Key)}. + +%%-------------------------------------------------------------------- +%% @doc Creates a dsa key (OBS: for testing only) +%% the sizes are in bytes +%% @spec (::integer()) -> {::atom(), ::binary(), ::opaque()} +%% @end +%%-------------------------------------------------------------------- +gen_dsa(LSize,NSize) when is_integer(LSize), is_integer(NSize) -> + Key = gen_dsa2(LSize, NSize), + {Key, encode_key(Key)}. + +%%-------------------------------------------------------------------- +%% @doc Verifies cert signatures +%% @spec (::binary(), ::tuple()) -> ::boolean() +%% @end +%%-------------------------------------------------------------------- +verify_signature(DerEncodedCert, DerKey, _KeyParams) -> + Key = decode_key(DerKey), + case Key of + #'RSAPrivateKey'{modulus=Mod, publicExponent=Exp} -> + public_key:pkix_verify(DerEncodedCert, + #'RSAPublicKey'{modulus=Mod, publicExponent=Exp}); + #'DSAPrivateKey'{p=P, q=Q, g=G, y=Y} -> + public_key:pkix_verify(DerEncodedCert, {Y, #'Dss-Parms'{p=P, q=Q, g=G}}) + end. + +%%%%%%%%%%%%%%%%%%%%%%%%% Implementation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +get_key(Opts) -> + case proplists:get_value(key, Opts) of + undefined -> make_key(rsa, Opts); + rsa -> make_key(rsa, Opts); + dsa -> make_key(dsa, Opts); + Key -> + Password = proplists:get_value(password, Opts, no_passwd), + decode_key(Key, Password) + end. + +decode_key({Key, Pw}) -> + decode_key(Key, Pw); +decode_key(Key) -> + decode_key(Key, no_passwd). + + +decode_key(#'RSAPublicKey'{} = Key,_) -> + Key; +decode_key(#'RSAPrivateKey'{} = Key,_) -> + Key; +decode_key(#'DSAPrivateKey'{} = Key,_) -> + Key; +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), + {'RSAPrivateKey', list_to_binary(Der), not_encrypted}; +encode_key(Key = #'DSAPrivateKey'{}) -> + {ok, Der} = 'OTP-PUB-KEY':encode('DSAPrivateKey', Key), + {'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))), + + 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, + subjectPublicKeyInfo = publickey(SubjectKey), + version = Version, + extensions = extensions(Opts) + }, IssuerKey}. + +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) -> + Decoded = public_key:pkix_decode_cert(Issuer, otp), + #'OTPCertificate'{tbsCertificate=Tbs} = Decoded, + #'OTPTBSCertificate'{subject=Subject} = Tbs, + Subject. + +subject(undefined, IsRootCA) -> + User = if IsRootCA -> "RootCA"; true -> os:getenv("USER") end, + Opts = [{email, User ++ "@erlang.org"}, + {name, User}, + {city, "Stockholm"}, + {country, "SE"}, + {org, "erlang"}, + {org_unit, "testing dep"}], + subject(Opts); +subject(Opts, _) -> + subject(Opts). + +subject(SubjectOpts) when is_list(SubjectOpts) -> + Encode = fun(Opt) -> + {Type,Value} = subject_enc(Opt), + [#'AttributeTypeAndValue'{type=Type, value=Value}] + end, + {rdnSequence, [Encode(Opt) || Opt <- SubjectOpts]}. + +%% Fill in the blanks +subject_enc({name, Name}) -> {?'id-at-commonName', {printableString, Name}}; +subject_enc({email, Email}) -> {?'id-emailAddress', Email}; +subject_enc({city, City}) -> {?'id-at-localityName', {printableString, City}}; +subject_enc({state, State}) -> {?'id-at-stateOrProvinceName', {printableString, State}}; +subject_enc({org, Org}) -> {?'id-at-organizationName', {printableString, Org}}; +subject_enc({org_unit, OrgUnit}) -> {?'id-at-organizationalUnitName', {printableString, OrgUnit}}; +subject_enc({country, Country}) -> {?'id-at-countryName', Country}; +subject_enc({serial, Serial}) -> {?'id-at-serialNumber', Serial}; +subject_enc({title, Title}) -> {?'id-at-title', {printableString, Title}}; +subject_enc({dnQualifer, DnQ}) -> {?'id-at-dnQualifier', DnQ}; +subject_enc(Other) -> Other. + + +extensions(Opts) -> + case proplists:get_value(extensions, Opts, []) of + false -> + asn1_NOVALUE; + Exts -> + lists:flatten([extension(Ext) || Ext <- default_extensions(Exts)]) + end. + +default_extensions(Exts) -> + Def = [{key_usage,undefined}, + {subject_altname, undefined}, + {issuer_altname, undefined}, + {basic_constraints, default}, + {name_constraints, undefined}, + {policy_constraints, undefined}, + {ext_key_usage, undefined}, + {inhibit_any, undefined}, + {auth_key_id, undefined}, + {subject_key_id, undefined}, + {policy_mapping, undefined}], + Filter = fun({Key, _}, D) -> lists:keydelete(Key, 1, D) end, + Exts ++ lists:foldl(Filter, Def, Exts). + +extension({_, undefined}) -> []; +extension({basic_constraints, Data}) -> + case Data of + default -> + #'Extension'{extnID = ?'id-ce-basicConstraints', + extnValue = #'BasicConstraints'{cA=true}, + critical=true}; + false -> + []; + Len when is_integer(Len) -> + #'Extension'{extnID = ?'id-ce-basicConstraints', + extnValue = #'BasicConstraints'{cA=true, pathLenConstraint=Len}, + critical=true}; + _ -> + #'Extension'{extnID = ?'id-ce-basicConstraints', + extnValue = Data} + end; +extension({Id, Data, Critical}) -> + #'Extension'{extnID = Id, extnValue = Data, critical = Critical}. + + +publickey(#'RSAPrivateKey'{modulus=N, publicExponent=E}) -> + Public = #'RSAPublicKey'{modulus=N, publicExponent=E}, + Algo = #'PublicKeyAlgorithm'{algorithm= ?rsaEncryption, parameters='NULL'}, + #'OTPSubjectPublicKeyInfo'{algorithm = Algo, + subjectPublicKey = Public}; +publickey(#'DSAPrivateKey'{p=P, q=Q, g=G, y=Y}) -> + Algo = #'PublicKeyAlgorithm'{algorithm= ?'id-dsa', + parameters=#'Dss-Parms'{p=P, q=Q, g=G}}, + #'OTPSubjectPublicKeyInfo'{algorithm = Algo, subjectPublicKey = Y}. + +validity(Opts) -> + 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, + #'Validity'{notBefore={generalTime, Format(DefFrom)}, + notAfter ={generalTime, Format(DefTo)}}. + +sign_algorithm(#'RSAPrivateKey'{}, Opts) -> + Type = case proplists:get_value(digest, Opts, sha1) of + sha1 -> ?'sha1WithRSAEncryption'; + sha512 -> ?'sha512WithRSAEncryption'; + sha384 -> ?'sha384WithRSAEncryption'; + sha256 -> ?'sha256WithRSAEncryption'; + md5 -> ?'md5WithRSAEncryption'; + md2 -> ?'md2WithRSAEncryption' + end, + {Type, 'NULL'}; +sign_algorithm(#'DSAPrivateKey'{p=P, q=Q, g=G}, _Opts) -> + {?'id-dsa-with-sha1', #'Dss-Parms'{p=P, q=Q, g=G}}. + +make_key(rsa, _Opts) -> + %% (OBS: for testing only) + gen_rsa2(64); +make_key(dsa, _Opts) -> + gen_dsa2(128, 20). %% Bytes i.e. {1024, 160} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% RSA key generation (OBS: for testing only) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +-define(SMALL_PRIMES, [65537,97,89,83,79,73,71,67,61,59,53, + 47,43,41,37,31,29,23,19,17,13,11,7,5,3]). + +gen_rsa2(Size) -> + P = prime(Size), + Q = prime(Size), + N = P*Q, + Tot = (P - 1) * (Q - 1), + [E|_] = lists:dropwhile(fun(Candidate) -> (Tot rem Candidate) == 0 end, ?SMALL_PRIMES), + {D1,D2} = extended_gcd(E, Tot), + D = erlang:max(D1,D2), + case D < E of + true -> + gen_rsa2(Size); + false -> + {Co1,Co2} = extended_gcd(Q, P), + Co = erlang:max(Co1,Co2), + #'RSAPrivateKey'{version = 'two-prime', + modulus = N, + publicExponent = E, + privateExponent = D, + prime1 = P, + prime2 = Q, + exponent1 = D rem (P-1), + exponent2 = D rem (Q-1), + coefficient = Co + } + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% DSA key generation (OBS: for testing only) +%% See http://en.wikipedia.org/wiki/Digital_Signature_Algorithm +%% and the fips_186-3.pdf +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +gen_dsa2(LSize, NSize) -> + Q = prime(NSize), %% Choose N-bit prime Q + X0 = prime(LSize), + P0 = prime((LSize div 2) +1), + + %% Choose L-bit prime modulus P such that p–1 is a multiple of q. + case dsa_search(X0 div (2*Q*P0), P0, Q, 1000) of + error -> + gen_dsa2(LSize, NSize); + P -> + G = crypto:mod_exp(2, (P-1) div Q, P), % Choose G a number whose multiplicative order modulo p is q. + %% such that This may be done by setting g = h^(p–1)/q mod p, commonly h=2 is used. + + X = prime(20), %% Choose x by some random method, where 0 < x < q. + Y = crypto:mod_exp(G, X, P), %% Calculate y = g^x mod p. + + #'DSAPrivateKey'{version=0, p=P, q=Q, g=G, y=Y, x=X} + end. + +%% See fips_186-3.pdf +dsa_search(T, P0, Q, Iter) when Iter > 0 -> + P = 2*T*Q*P0 + 1, + case is_prime(crypto:mpint(P), 50) of + true -> P; + false -> dsa_search(T+1, P0, Q, Iter-1) + end; +dsa_search(_,_,_,_) -> + error. + + +%%%%%%% Crypto Math %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +prime(ByteSize) -> + Rand = odd_rand(ByteSize), + crypto:erlint(prime_odd(Rand, 0)). + +prime_odd(Rand, N) -> + case is_prime(Rand, 50) of + true -> + Rand; + false -> + NotPrime = crypto:erlint(Rand), + prime_odd(crypto:mpint(NotPrime+2), N+1) + end. + +%% see http://en.wikipedia.org/wiki/Fermat_primality_test +is_prime(_, 0) -> true; +is_prime(Candidate, Test) -> + CoPrime = odd_rand(<<0,0,0,4, 10000:32>>, Candidate), + case crypto:mod_exp(CoPrime, Candidate, Candidate) of + CoPrime -> is_prime(Candidate, Test-1); + _ -> false + end. + +odd_rand(Size) -> + Min = 1 bsl (Size*8-1), + Max = (1 bsl (Size*8))-1, + odd_rand(crypto:mpint(Min), crypto:mpint(Max)). + +odd_rand(Min,Max) -> + Rand = <<Sz:32, _/binary>> = crypto:rand_uniform(Min,Max), + BitSkip = (Sz+4)*8-1, + case Rand of + Odd = <<_:BitSkip, 1:1>> -> Odd; + Even = <<_:BitSkip, 0:1>> -> + crypto:mpint(crypto:erlint(Even)+1) + end. + +extended_gcd(A, B) -> + case A rem B of + 0 -> + {0, 1}; + N -> + {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/old_ssl_active_SUITE.erl b/lib/ssl/test/old_ssl_active_SUITE.erl index 010596f351..d1cec26827 100644 --- a/lib/ssl/test/old_ssl_active_SUITE.erl +++ b/lib/ssl/test/old_ssl_active_SUITE.erl @@ -87,6 +87,8 @@ config(Config) -> %% operating system, version of OTP, Erts, kernel and stdlib. %% Check if SSL exists. If this case fails, all other cases are skipped + crypto:start(), + application:start(public_key), case ssl:start() of ok -> ssl:stop(); {error, {already_started, _}} -> ssl:stop(); diff --git a/lib/ssl/test/old_ssl_active_once_SUITE.erl b/lib/ssl/test/old_ssl_active_once_SUITE.erl index 6224b17aa7..63eaa730e9 100644 --- a/lib/ssl/test/old_ssl_active_once_SUITE.erl +++ b/lib/ssl/test/old_ssl_active_once_SUITE.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -79,6 +79,8 @@ config(Config) -> io:format("Config: ~p~n", [Config]), %% Check if SSL exists. If this case fails, all other cases are skipped + crypto:start(), + application:start(public_key), case ssl:start() of ok -> ssl:stop(); {error, {already_started, _}} -> ssl:stop(); diff --git a/lib/ssl/test/old_ssl_dist_SUITE.erl b/lib/ssl/test/old_ssl_dist_SUITE.erl index 56209c3530..97090c1409 100644 --- a/lib/ssl/test/old_ssl_dist_SUITE.erl +++ b/lib/ssl/test/old_ssl_dist_SUITE.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -254,7 +254,8 @@ mk_node_cmdline(ListenPort, Name, Args) -> Prog ++ " " ++ Static ++ " " ++ NameSw ++ " " ++ Name ++ " " - ++ "-pa " ++ Pa ++ " " + ++ "-pa " ++ Pa ++ " " + ++ "-run application start crypto -run application start public_key " ++ "-run " ++ atom_to_list(?MODULE) ++ " cnct2tstsrvr " ++ host_name() ++ " " ++ integer_to_list(ListenPort) ++ " " @@ -524,23 +525,10 @@ add_ssl_opts_config(Config) -> KrnlDir = filename:join([LibDir, "kernel-" ++ KRNL_VSN]), {ok, _} = file:read_file_info(StdlDir), {ok, _} = file:read_file_info(KrnlDir), - SSL_VSN = case lists:keysearch(ssl, 1, Apps) of - {value, {ssl, _, VSN}} -> - VSN; - _ -> - application:start(ssl), - try - {value, - {ssl, - _, - VSN}} = lists:keysearch(ssl, - 1, - application:which_applications()), - VSN - after - application:stop(ssl) - end - end, + SSL_VSN = vsn(ssl), + VSN_CRYPTO = vsn(crypto), + VSN_PKEY = vsn(public_key), + SslDir = filename:join([LibDir, "ssl-" ++ SSL_VSN]), {ok, _} = file:read_file_info(SslDir), %% We are using an installed otp system, create the boot script. @@ -552,6 +540,8 @@ add_ssl_opts_config(Config) -> " {erts, \"~s\"},~n" " [{kernel, \"~s\"},~n" " {stdlib, \"~s\"},~n" + " {crypto, \"~s\"},~n" + " {public_key, \"~s\"},~n" " {ssl, \"~s\"}]}.~n", [case catch erlang:system_info(otp_release) of {'EXIT', _} -> "R11B"; @@ -560,6 +550,8 @@ add_ssl_opts_config(Config) -> erlang:system_info(version), KRNL_VSN, STDL_VSN, + VSN_CRYPTO, + VSN_PKEY, SSL_VSN]), ok = file:close(RelFile), ok = systools:make_script(Script, []), @@ -593,3 +585,17 @@ success(Config) -> {value, {comment, _} = Res} -> Res; _ -> ok end. + +vsn(App) -> + application:start(App), + try + {value, + {ssl, + _, + VSN}} = lists:keysearch(App, + 1, + application:which_applications()), + VSN + after + application:stop(ssl) + end. diff --git a/lib/ssl/test/old_ssl_misc_SUITE.erl b/lib/ssl/test/old_ssl_misc_SUITE.erl index 55d1b71025..2767123a12 100644 --- a/lib/ssl/test/old_ssl_misc_SUITE.erl +++ b/lib/ssl/test/old_ssl_misc_SUITE.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -61,6 +61,8 @@ config(Config) -> io:format("Config: ~p~n", [Config]), %% Check if SSL exists. If this case fails, all other cases are skipped + crypto:start(), + application:start(public_key), case ssl:start() of ok -> ssl:stop(); {error, {already_started, _}} -> ssl:stop(); diff --git a/lib/ssl/test/old_ssl_passive_SUITE.erl b/lib/ssl/test/old_ssl_passive_SUITE.erl index 4cb8c1f0cd..96a7938583 100644 --- a/lib/ssl/test/old_ssl_passive_SUITE.erl +++ b/lib/ssl/test/old_ssl_passive_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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% %% @@ -78,6 +78,8 @@ config(Config) -> io:format("Config: ~p~n", [Config]), %% Check if SSL exists. If this case fails, all other cases are skipped + crypto:start(), + application:start(public_key), case ssl:start() of ok -> ssl:stop(); {error, {already_started, _}} -> ssl:stop(); diff --git a/lib/ssl/test/old_ssl_peer_cert_SUITE.erl b/lib/ssl/test/old_ssl_peer_cert_SUITE.erl index f0b8db2607..e5b3975d41 100644 --- a/lib/ssl/test/old_ssl_peer_cert_SUITE.erl +++ b/lib/ssl/test/old_ssl_peer_cert_SUITE.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -62,6 +62,8 @@ config(Config) -> io:format("Config: ~p~n", [Config]), %% Check if SSL exists. If this case fails, all other cases are skipped + crypto:start(), + application:start(public_key), case ssl:start() of ok -> ssl:stop(); {error, {already_started, _}} -> ssl:stop(); diff --git a/lib/ssl/test/old_ssl_protocol_SUITE.erl b/lib/ssl/test/old_ssl_protocol_SUITE.erl index 7bde5d6749..efdbf45a3d 100644 --- a/lib/ssl/test/old_ssl_protocol_SUITE.erl +++ b/lib/ssl/test/old_ssl_protocol_SUITE.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -55,6 +55,8 @@ config(Config) -> io:format("Config: ~p~n", [Config]), %% Check if SSL exists. If this case fails, all other cases are skipped + crypto:start(), + application:start(public_key), case ssl:start() of ok -> ssl:stop(); {error, {already_started, _}} -> ssl:stop(); diff --git a/lib/ssl/test/old_ssl_verify_SUITE.erl b/lib/ssl/test/old_ssl_verify_SUITE.erl index 5db964526f..7a8cd1578a 100644 --- a/lib/ssl/test/old_ssl_verify_SUITE.erl +++ b/lib/ssl/test/old_ssl_verify_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% 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% %% @@ -60,6 +60,8 @@ config(Config) -> io:format("Config: ~p~n", [Config]), %% Check if SSL exists. If this case fails, all other cases are skipped + crypto:start(), + application:start(public_key), case ssl:start() of ok -> ssl:stop(); {error, {already_started, _}} -> ssl:stop(); diff --git a/lib/ssl/test/old_transport_accept_SUITE.erl b/lib/ssl/test/old_transport_accept_SUITE.erl index 4bb09cee19..71c1d9e181 100644 --- a/lib/ssl/test/old_transport_accept_SUITE.erl +++ b/lib/ssl/test/old_transport_accept_SUITE.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -224,12 +224,9 @@ tolerant_server_loop(Client, LSock, Msg, N) -> tolerant_server_loop(Client, LSock, Msg, N-1). app() -> - case application:get_application(ssl) of - undefined -> - application:start(ssl); - _ -> - ok - end. + crypto:start(), + application:start(public_key), + ssl:start(). start_node(Kind, Params) -> S = atom_to_list(?MODULE)++"_" ++ atom_to_list(Kind), diff --git a/lib/ssl/test/ssl.cover b/lib/ssl/test/ssl.cover index 138bf96b9d..e8daa363c5 100644 --- a/lib/ssl/test/ssl.cover +++ b/lib/ssl/test/ssl.cover @@ -3,5 +3,17 @@ 'PKIX1Explicit88', 'PKIX1Implicit88', 'PKIXAttributeCertificate', - 'SSL-PKIX']}. + 'SSL-PKIX', + ssl_pem, + ssl_pkix, + ssl_base64, + ssl_broker, + ssl_broker_int, + ssl_broker_sup, + ssl_debug, + ssl_server, + ssl_prim, + inet_ssl_dist, + 'OTP-PKIX' + ]}. diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl index 7f33efd7e1..fade67f3ba 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 @@ -27,17 +27,17 @@ -include("test_server.hrl"). -include("test_server_line.hrl"). -include_lib("public_key/include/public_key.hrl"). +-include("ssl_alert.hrl"). -define('24H_in_sec', 86400). -define(TIMEOUT, 60000). -define(EXPIRE, 10). -define(SLEEP, 500). - -behaviour(ssl_session_cache_api). %% For the session cache tests --export([init/0, terminate/1, lookup/2, update/3, +-export([init/1, terminate/1, lookup/2, update/3, delete/2, foldl/3, select_session/2]). %% Test server callback functions @@ -50,14 +50,21 @@ %% Note: This function is free to add any key/value pairs to the Config %% variable, but should NOT alter/remove any existing entries. %%-------------------------------------------------------------------- -init_per_suite(Config) -> +init_per_suite(Config0) -> + Dog = ssl_test_lib:timetrap(?TIMEOUT *2), crypto:start(), + application:start(public_key), ssl:start(), + + %% make rsa certs using oppenssl Result = - (catch make_certs:all(?config(data_dir, Config), - ?config(priv_dir, Config))), + (catch make_certs:all(?config(data_dir, Config0), + ?config(priv_dir, Config0))), test_server:format("Make certs ~p~n", [Result]), - ssl_test_lib:cert_options(Config). + + Config1 = ssl_test_lib:make_dsa_cert(Config0), + Config = ssl_test_lib:cert_options(Config1), + [{watchdog, Dog} | Config]. %%-------------------------------------------------------------------- %% Function: end_per_suite(Config) -> _ @@ -83,11 +90,11 @@ end_per_suite(_Config) -> %% Description: Initialization before each test case %%-------------------------------------------------------------------- init_per_testcase(session_cache_process_list, Config) -> - init_customized_session_cache(Config); + init_customized_session_cache(list, Config); init_per_testcase(session_cache_process_mnesia, Config) -> mnesia:start(), - init_customized_session_cache(Config); + init_customized_session_cache(mnesia, Config); init_per_testcase(reuse_session_expired, Config0) -> Config = lists:keydelete(watchdog, 1, Config0), @@ -98,17 +105,50 @@ init_per_testcase(reuse_session_expired, Config0) -> ssl:start(), [{watchdog, Dog} | Config]; +init_per_testcase(no_authority_key_identifier, Config) -> + %% Clear cach so that root cert will not + %% be found. + ssl:stop(), + ssl:start(), + Config; + +init_per_testcase(TestCase, Config) when TestCase == ciphers_rsa_signed_certs_ssl3; + TestCase == ciphers_rsa_signed_certs_openssl_names_ssl3; + TestCase == ciphers_dsa_signed_certs_ssl3; + TestCase == ciphers_dsa_signed_certs_openssl_names_ssl3 -> + ssl:stop(), + application:load(ssl), + application:set_env(ssl, protocol_version, sslv3), + ssl:start(), + Config; + +init_per_testcase(protocol_versions, Config) -> + ssl:stop(), + application:load(ssl), + %% For backwards compatibility sslv2 should be filtered out. + application:set_env(ssl, protocol_version, [sslv2, sslv3, tlsv1]), + ssl:start(), + Config; + +init_per_testcase(empty_protocol_versions, Config) -> + ssl:stop(), + application:load(ssl), + application:set_env(ssl, protocol_version, []), + ssl:start(), + Config; + init_per_testcase(_TestCase, Config0) -> Config = lists:keydelete(watchdog, 1, Config0), Dog = test_server:timetrap(?TIMEOUT), - [{watchdog, Dog} | Config]. + [{watchdog, Dog} | Config]. -init_customized_session_cache(Config0) -> +init_customized_session_cache(Type, Config0) -> Config = lists:keydelete(watchdog, 1, Config0), Dog = test_server:timetrap(?TIMEOUT), ssl:stop(), application:load(ssl), application:set_env(ssl, session_cb, ?MODULE), + application:set_env(ssl, session_cb_init_args, [Type]), ssl:start(), [{watchdog, Dog} | Config]. @@ -125,11 +165,22 @@ end_per_testcase(session_cache_process_list, Config) -> end_per_testcase(default_action, Config); end_per_testcase(session_cache_process_mnesia, Config) -> application:unset_env(ssl, session_cb), + application:unset_env(ssl, session_cb_init_args), mnesia:stop(), + ssl:stop(), + ssl:start(), end_per_testcase(default_action, Config); end_per_testcase(reuse_session_expired, Config) -> application:unset_env(ssl, session_lifetime), end_per_testcase(default_action, Config); +end_per_testcase(TestCase, Config) when TestCase == ciphers_rsa_signed_certs_ssl3; + TestCase == ciphers_rsa_signed_certs_openssl_names_ssl3; + TestCase == ciphers_dsa_signed_certs_ssl3; + TestCase == ciphers_dsa_signed_certs_openssl_names_ssl3; + TestCase == protocol_versions; + TestCase == empty_protocol_versions-> + application:unset_env(ssl, protocol_version), + end_per_testcase(default_action, Config); end_per_testcase(_TestCase, Config) -> Dog = ?config(watchdog, Config), case Dog of @@ -151,28 +202,41 @@ all(doc) -> ["Test the basic ssl functionality"]; all(suite) -> - [app, connection_info, controlling_process, controller_dies, - peercert, connect_dist, - peername, sockname, socket_options, misc_ssl_options, versions, cipher_suites, - upgrade, upgrade_with_timeout, tcp_connect, - ipv6, ekeyfile, ecertfile, ecacertfile, eoptions, shutdown, - shutdown_write, shutdown_both, shutdown_error, ciphers, - send_close, close_transport_accept, dh_params, - server_verify_peer_passive, + [app, alerts, connection_info, protocol_versions, + empty_protocol_versions, controlling_process, controller_dies, + client_closes_socket, peercert, connect_dist, peername, sockname, + socket_options, misc_ssl_options, versions, cipher_suites, + upgrade, upgrade_with_timeout, tcp_connect, ipv6, ekeyfile, + ecertfile, ecacertfile, eoptions, shutdown, shutdown_write, + shutdown_both, shutdown_error, + ciphers_rsa_signed_certs, ciphers_rsa_signed_certs_ssl3, + ciphers_rsa_signed_certs_openssl_names, + ciphers_rsa_signed_certs_openssl_names_ssl3, + ciphers_dsa_signed_certs, + ciphers_dsa_signed_certs_ssl3, + ciphers_dsa_signed_certs_openssl_names, + ciphers_dsa_signed_certs_openssl_names_ssl3, + send_close, + close_transport_accept, dh_params, server_verify_peer_passive, server_verify_peer_active, server_verify_peer_active_once, - server_verify_none_passive, server_verify_none_active, + server_verify_none_passive, server_verify_none_active, server_verify_none_active_once, server_verify_no_cacerts, server_require_peer_cert_ok, server_require_peer_cert_fail, server_verify_client_once_passive, server_verify_client_once_active, - server_verify_client_once_active_once, - client_verify_none_passive, - client_verify_none_active, client_verify_none_active_once - %%, session_cache_process_list, session_cache_process_mnesia - ,reuse_session, reuse_session_expired, server_does_not_want_to_reuse_session, - client_renegotiate, server_renegotiate, - client_no_wrap_sequence_number, server_no_wrap_sequence_number, - extended_key_usage, validate_extensions_fun + server_verify_client_once_active_once, client_verify_none_passive, + client_verify_none_active, client_verify_none_active_once, + session_cache_process_list, session_cache_process_mnesia, + reuse_session, reuse_session_expired, + server_does_not_want_to_reuse_session, client_renegotiate, + server_renegotiate, client_renegotiate_reused_session, + server_renegotiate_reused_session, client_no_wrap_sequence_number, + server_no_wrap_sequence_number, extended_key_usage, + 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. @@ -183,7 +247,31 @@ app(suite) -> []; app(Config) when is_list(Config) -> ok = test_server:app_test(ssl). - +%%-------------------------------------------------------------------- +alerts(doc) -> + "Test ssl_alert:alert_txt/1"; +alerts(suite) -> + []; +alerts(Config) when is_list(Config) -> + Descriptions = [?CLOSE_NOTIFY, ?UNEXPECTED_MESSAGE, ?BAD_RECORD_MAC, + ?DECRYPTION_FAILED, ?RECORD_OVERFLOW, ?DECOMPRESSION_FAILURE, + ?HANDSHAKE_FAILURE, ?BAD_CERTIFICATE, ?UNSUPPORTED_CERTIFICATE, + ?CERTIFICATE_REVOKED,?CERTIFICATE_EXPIRED, ?CERTIFICATE_UNKNOWN, + ?ILLEGAL_PARAMETER, ?UNKNOWN_CA, ?ACCESS_DENIED, ?DECODE_ERROR, + ?DECRYPT_ERROR, ?EXPORT_RESTRICTION, ?PROTOCOL_VERSION, + ?INSUFFICIENT_SECURITY, ?INTERNAL_ERROR, ?USER_CANCELED, + ?NO_RENEGOTIATION], + Alerts = [?ALERT_REC(?WARNING, ?CLOSE_NOTIFY) | + [?ALERT_REC(?FATAL, Desc) || Desc <- Descriptions]], + lists:foreach(fun(Alert) -> + case ssl_alert:alert_txt(Alert) of + Txt when is_list(Txt) -> + ok; + Other -> + test_server:fail({unexpected, Other}) + end + end, Alerts). +%%-------------------------------------------------------------------- connection_info(doc) -> ["Test the API function ssl:connection_info/1"]; connection_info(suite) -> @@ -212,7 +300,7 @@ connection_info(Config) when is_list(Config) -> Version = ssl_record:protocol_version(ssl_record:highest_protocol_version([])), - ServerMsg = ClientMsg = {ok, {Version, {rsa,rc4_128,sha,no_export}}}, + ServerMsg = ClientMsg = {ok, {Version, {rsa,rc4_128,sha}}}, ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg), @@ -224,6 +312,49 @@ connection_info_result(Socket) -> %%-------------------------------------------------------------------- +protocol_versions(doc) -> + ["Test to set a list of protocol versions in app environment."]; + +protocol_versions(suite) -> + []; + +protocol_versions(Config) when is_list(Config) -> + basic_test(Config). + +empty_protocol_versions(doc) -> + ["Test to set an empty list of protocol versions in app environment."]; + +empty_protocol_versions(suite) -> + []; + +empty_protocol_versions(Config) when is_list(Config) -> + basic_test(Config). + + +basic_test(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, ClientOpts}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). + +%%-------------------------------------------------------------------- + controlling_process(doc) -> ["Test API function controlling_process/2"]; @@ -281,7 +412,7 @@ controlling_process_result(Socket, Pid, Msg) -> ssl:send(Socket, Msg), no_result_msg. - +%%-------------------------------------------------------------------- controller_dies(doc) -> ["Test that the socket is closed after controlling process dies"]; controller_dies(suite) -> []; @@ -322,6 +453,10 @@ controller_dies(Config) when is_list(Config) -> Connect = fun(Pid) -> {ok, Socket} = ssl:connect(Hostname, Port, [{reuseaddr,true},{ssl_imp,new}]), + %% Make sure server finishes and verification + %% and is in coonection state before + %% killing client + test_server:sleep(?SLEEP), Pid ! {self(), connected, Socket}, receive die_nice -> normal end end, @@ -393,6 +528,36 @@ get_close(Pid, Where) -> end. %%-------------------------------------------------------------------- +client_closes_socket(doc) -> + ["Test what happens when client closes socket before handshake is compleated"]; +client_closes_socket(suite) -> []; +client_closes_socket(Config) when is_list(Config) -> + ServerOpts = ?config(server_opts, Config), + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + TcpOpts = [binary, {reuseaddr, true}], + + Server = ssl_test_lib:start_upgrade_server_error([{node, ServerNode}, {port, 0}, + {from, self()}, + {tcp_options, TcpOpts}, + {ssl_options, ServerOpts}]), + Port = ssl_test_lib:inet_port(Server), + + Connect = fun() -> + {ok, _Socket} = rpc:call(ClientNode, gen_tcp, connect, + [Hostname, Port, TcpOpts]), + %% Make sure that ssl_accept is called before + %% client process ends and closes socket. + test_server:sleep(?SLEEP) + end, + + _Client = spawn_link(Connect), + + ssl_test_lib:check_result(Server, {error,closed}), + + ssl_test_lib:close(Server). + +%%-------------------------------------------------------------------- + peercert(doc) -> [""]; @@ -416,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}}, @@ -562,9 +727,12 @@ cipher_suites(suite) -> []; cipher_suites(Config) when is_list(Config) -> - MandatoryCipherSuite = {rsa,'3des_ede_cbc',sha,no_export}, + MandatoryCipherSuite = {rsa,'3des_ede_cbc',sha}, [_|_] = Suites = ssl:cipher_suites(), - true = lists:member(MandatoryCipherSuite, Suites). + true = lists:member(MandatoryCipherSuite, Suites), + Suites = ssl:cipher_suites(erlang), + [_|_] =ssl:cipher_suites(openssl). + %%-------------------------------------------------------------------- socket_options(doc) -> ["Test API function getopts/2 and setopts/2"]; @@ -599,9 +767,16 @@ socket_options(Config) when is_list(Config) -> {options, ClientOpts}]), ssl_test_lib:check_result(Server, ok, Client, ok), - + ssl_test_lib:close(Server), - ssl_test_lib:close(Client). + ssl_test_lib:close(Client), + + {ok, Listen} = ssl:listen(0, ServerOpts), + {ok,[{mode,list}]} = ssl:getopts(Listen, [mode]), + ok = ssl:setopts(Listen, [{mode, binary}]), + {ok,[{mode, binary}]} = ssl:getopts(Listen, [mode]), + {ok,[{recbuf, _}]} = ssl:getopts(Listen, [recbuf]), + ssl:close(Listen). socket_options_result(Socket, Options, DefaultValues, NewOptions, NewValues) -> %% Test get/set emulated opts @@ -610,6 +785,8 @@ socket_options_result(Socket, Options, DefaultValues, NewOptions, NewValues) -> {ok, NewValues} = ssl:getopts(Socket, NewOptions), %% Test get/set inet opts {ok,[{nodelay,false}]} = ssl:getopts(Socket, [nodelay]), + ssl:setopts(Socket, [{nodelay, true}]), + {ok,[{nodelay, true}]} = ssl:getopts(Socket, [nodelay]), ok. %%-------------------------------------------------------------------- @@ -630,7 +807,7 @@ misc_ssl_options(Config) when is_list(Config) -> {password, []}, {reuse_session, fun(_,_,_,_) -> true end}, {debug, []}, - {cb_info, {gen_tcp, tcp, tcp_closed}}], + {cb_info, {gen_tcp, tcp, tcp_closed, tcp_error}}], Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, @@ -796,11 +973,12 @@ upgrade(Config) when is_list(Config) -> TcpOpts = [binary, {reuseaddr, true}], Server = ssl_test_lib:start_upgrade_server([{node, ServerNode}, {port, 0}, - {from, self()}, - {mfa, {?MODULE, - upgrade_result, []}}, - {tcp_options, TcpOpts}, - {ssl_options, ServerOpts}]), + {from, self()}, + {mfa, {?MODULE, + upgrade_result, []}}, + {tcp_options, + [{active, false} | TcpOpts]}, + {ssl_options, ServerOpts}]), Port = ssl_test_lib:inet_port(Server), Client = ssl_test_lib:start_upgrade_client([{node, ClientNode}, {port, Port}, @@ -819,6 +997,7 @@ upgrade(Config) when is_list(Config) -> ssl_test_lib:close(Client). upgrade_result(Socket) -> + ssl:setopts(Socket, [{active, true}]), ok = ssl:send(Socket, "Hello world"), %% Make sure binary is inherited from tcp socket and that we do %% not get the list default! @@ -845,7 +1024,8 @@ upgrade_with_timeout(Config) when is_list(Config) -> {timeout, 5000}, {mfa, {?MODULE, upgrade_result, []}}, - {tcp_options, TcpOpts}, + {tcp_options, + [{active, false} | TcpOpts]}, {ssl_options, ServerOpts}]), Port = ssl_test_lib:inet_port(Server), Client = ssl_test_lib:start_upgrade_client([{node, ClientNode}, @@ -1081,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' }, @@ -1233,20 +1412,130 @@ shutdown_error(Config) when is_list(Config) -> ok = ssl:close(Listen), {error, closed} = ssl:shutdown(Listen, read_write). -%%-------------------------------------------------------------------- -ciphers(doc) -> - [""]; +%%------------------------------------------------------------------- +ciphers_rsa_signed_certs(doc) -> + ["Test all rsa ssl cipher suites in highest support ssl/tls version"]; + +ciphers_rsa_signed_certs(suite) -> + []; + +ciphers_rsa_signed_certs(Config) when is_list(Config) -> + Version = + ssl_record:protocol_version(ssl_record:highest_protocol_version([])), + + Ciphers = ssl_test_lib:rsa_suites(), + test_server:format("tls1 erlang cipher suites ~p~n", [Ciphers]), + run_suites(Ciphers, Version, Config, rsa). + +ciphers_rsa_signed_certs_ssl3(doc) -> + ["Test all rsa ssl cipher suites in ssl3"]; + +ciphers_rsa_signed_certs_ssl3(suite) -> + []; + +ciphers_rsa_signed_certs_ssl3(Config) when is_list(Config) -> + Version = + ssl_record:protocol_version({3,0}), + + Ciphers = ssl_test_lib:rsa_suites(), + test_server:format("ssl3 erlang cipher suites ~p~n", [Ciphers]), + run_suites(Ciphers, Version, Config, rsa). + +ciphers_rsa_signed_certs_openssl_names(doc) -> + ["Test all rsa ssl cipher suites in highest support ssl/tls version"]; -ciphers(suite) -> +ciphers_rsa_signed_certs_openssl_names(suite) -> []; -ciphers(Config) when is_list(Config) -> +ciphers_rsa_signed_certs_openssl_names(Config) when is_list(Config) -> Version = ssl_record:protocol_version(ssl_record:highest_protocol_version([])), + Ciphers = ssl_test_lib:openssl_rsa_suites(), + test_server:format("tls1 openssl cipher suites ~p~n", [Ciphers]), + run_suites(Ciphers, Version, Config, rsa). + + +ciphers_rsa_signed_certs_openssl_names_ssl3(doc) -> + ["Test all dsa ssl cipher suites in ssl3"]; + +ciphers_rsa_signed_certs_openssl_names_ssl3(suite) -> + []; + +ciphers_rsa_signed_certs_openssl_names_ssl3(Config) when is_list(Config) -> + Version = ssl_record:protocol_version({3,0}), + Ciphers = ssl_test_lib:openssl_rsa_suites(), + run_suites(Ciphers, Version, Config, rsa). + + +ciphers_dsa_signed_certs(doc) -> + ["Test all dsa ssl cipher suites in highest support ssl/tls version"]; + +ciphers_dsa_signed_certs(suite) -> + []; + +ciphers_dsa_signed_certs(Config) when is_list(Config) -> + Version = + ssl_record:protocol_version(ssl_record:highest_protocol_version([])), + + Ciphers = ssl_test_lib:dsa_suites(), + test_server:format("tls1 erlang cipher suites ~p~n", [Ciphers]), + run_suites(Ciphers, Version, Config, dsa). + +ciphers_dsa_signed_certs_ssl3(doc) -> + ["Test all dsa ssl cipher suites in ssl3"]; + +ciphers_dsa_signed_certs_ssl3(suite) -> + []; + +ciphers_dsa_signed_certs_ssl3(Config) when is_list(Config) -> + Version = + ssl_record:protocol_version({3,0}), + + Ciphers = ssl_test_lib:dsa_suites(), + test_server:format("ssl3 erlang cipher suites ~p~n", [Ciphers]), + run_suites(Ciphers, Version, Config, dsa). + + +ciphers_dsa_signed_certs_openssl_names(doc) -> + ["Test all dsa ssl cipher suites in highest support ssl/tls version"]; + +ciphers_dsa_signed_certs_openssl_names(suite) -> + []; + +ciphers_dsa_signed_certs_openssl_names(Config) when is_list(Config) -> + Version = + ssl_record:protocol_version(ssl_record:highest_protocol_version([])), + + Ciphers = ssl_test_lib:openssl_dsa_suites(), + test_server:format("tls1 openssl cipher suites ~p~n", [Ciphers]), + run_suites(Ciphers, Version, Config, dsa). + + +ciphers_dsa_signed_certs_openssl_names_ssl3(doc) -> + ["Test all dsa ssl cipher suites in ssl3"]; + +ciphers_dsa_signed_certs_openssl_names_ssl3(suite) -> + []; - Ciphers = ssl:cipher_suites(), +ciphers_dsa_signed_certs_openssl_names_ssl3(Config) when is_list(Config) -> + Version = ssl_record:protocol_version({3,0}), + Ciphers = ssl_test_lib:openssl_dsa_suites(), + run_suites(Ciphers, Version, Config, dsa). + + +run_suites(Ciphers, Version, Config, Type) -> + {ClientOpts, ServerOpts} = + case Type of + rsa -> + {?config(client_opts, Config), + ?config(server_opts, Config)}; + dsa -> + {?config(client_opts, Config), + ?config(server_dsa_opts, Config)} + end, + Result = lists:map(fun(Cipher) -> - cipher(Cipher, Version, Config) end, + cipher(Cipher, Version, Config, ClientOpts, ServerOpts) end, Ciphers), case lists:flatten(Result) of [] -> @@ -1255,30 +1544,36 @@ ciphers(Config) when is_list(Config) -> test_server:format("Cipher suite errors: ~p~n", [Error]), test_server:fail(cipher_suite_failed_see_test_case_log) end. - -cipher(CipherSuite, Version, Config) -> + +erlang_cipher_suite(Suite) when is_list(Suite)-> + ssl_cipher:suite_definition(ssl_cipher:openssl_suite(Suite)); +erlang_cipher_suite(Suite) -> + Suite. + +cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) -> process_flag(trap_exit, true), test_server:format("Testing CipherSuite ~p~n", [CipherSuite]), - ClientOpts = ?config(client_opts, Config), - ServerOpts = ?config(server_opts, Config), {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]}]), - - ServerMsg = ClientMsg = {ok, {Version, CipherSuite}}, - - 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} -> @@ -1294,7 +1589,7 @@ cipher(CipherSuite, Version, Config) -> ok -> []; Error -> - [{CipherSuite, Error}] + [{ErlangCipherSuite, Error}] end. %%-------------------------------------------------------------------- @@ -1884,7 +2179,6 @@ server_require_peer_cert_fail(Config) when is_list(Config) -> Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0}, {from, self()}, - {mfa, {?MODULE, no_result, []}}, {options, [{active, false} | ServerOpts]}]), Port = ssl_test_lib:inet_port(Server), @@ -1892,13 +2186,10 @@ server_require_peer_cert_fail(Config) when is_list(Config) -> Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port}, {host, Hostname}, {from, self()}, - {mfa, {?MODULE, no_result, []}}, {options, [{active, false} | BadClientOpts]}]), ssl_test_lib:check_result(Server, {error, esslaccept}, - Client, {error, esslconnect}), - ssl_test_lib:close(Server), - ssl_test_lib:close(Client). + Client, {error, esslconnect}). %%-------------------------------------------------------------------- @@ -1980,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()}, @@ -1995,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), @@ -2076,6 +2359,76 @@ server_renegotiate(Config) when is_list(Config) -> ok. %%-------------------------------------------------------------------- +client_renegotiate_reused_session(doc) -> + ["Test ssl:renegotiate/1 on client when the ssl session will be reused."]; + +client_renegotiate_reused_session(suite) -> + []; + +client_renegotiate_reused_session(Config) when is_list(Config) -> + process_flag(trap_exit, true), + ServerOpts = ?config(server_opts, Config), + ClientOpts = ?config(client_opts, Config), + + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + + Data = "From erlang to erlang", + + Server = + ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, erlang_ssl_receive, [Data]}}, + {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, + renegotiate_reuse_session, [Data]}}, + {options, [{reuse_sessions, true} | ClientOpts]}]), + + ssl_test_lib:check_result(Client, ok, Server, ok), + + ssl_test_lib:close(Server), + ssl_test_lib:close(Client), + process_flag(trap_exit, false), + ok. +%%-------------------------------------------------------------------- +server_renegotiate_reused_session(doc) -> + ["Test ssl:renegotiate/1 on server when the ssl session will be reused."]; + +server_renegotiate_reused_session(suite) -> + []; + +server_renegotiate_reused_session(Config) when is_list(Config) -> + process_flag(trap_exit, true), + ServerOpts = ?config(server_opts, Config), + ClientOpts = ?config(client_opts, Config), + + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + + Data = "From erlang to erlang", + + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, + renegotiate_reuse_session, [Data]}}, + {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, erlang_ssl_receive, [Data]}}, + {options, [{reuse_sessions, true} | ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + ssl_test_lib:close(Server), + ssl_test_lib:close(Client), + ok. + +%%-------------------------------------------------------------------- client_no_wrap_sequence_number(doc) -> ["Test that erlang client will renegotiate session when", "max sequence number celing is about to be reached. Although" @@ -2162,34 +2515,89 @@ extended_key_usage(suite) -> []; extended_key_usage(Config) when is_list(Config) -> - ClientOpts = ?config(client_opts, Config), - ServerOpts = ?config(server_opts, Config), + ClientOpts = ?config(client_verification_opts, Config), + ServerOpts = ?config(server_verification_opts, Config), PrivDir = ?config(priv_dir, Config), - CertFile = proplists:get_value(certfile, ServerOpts), - KeyFile = proplists:get_value(keyfile, ServerOpts), - NewCertFile = filename:join(PrivDir, "cert.pem"), - - {ok, [{cert, DerCert, _}]} = public_key:pem_to_der(CertFile), + KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"), + [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"), + [{'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: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"), + [{'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: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), - {ok, [KeyInfo]} = public_key:pem_to_der(KeyFile), + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, send_recv_result_active, []}}, + {options, [{verify, verify_peer} | NewServerOpts]}]), + 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_peer} | NewClientOpts]}]), - {ok, Key} = public_key:decode_private_key(KeyInfo), - - {ok, OTPCert} = public_key:pkix_decode_cert(DerCert, otp), + ssl_test_lib:check_result(Server, ok, Client, ok), - ExtKeyUsageExt = {'Extension', ?'id-ce-extKeyUsage', true, [?'id-kp-serverAuth']}, + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). + +%%-------------------------------------------------------------------- +no_authority_key_identifier(doc) -> + ["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_verification_opts, Config), + ServerOpts = ?config(server_opts, Config), + PrivDir = ?config(priv_dir, Config), + + KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"), + [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"), + [{'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, []), + NewOTPTbsCert = OTPTbsCert#'OTPTBSCertificate'{extensions = NewExtensions}, - NewOTPTbsCert = OTPTbsCert#'OTPTBSCertificate'{extensions = [ExtKeyUsageExt |Extensions]}, + 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}]), - + 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), @@ -2203,48 +2611,439 @@ extended_key_usage(Config) when is_list(Config) -> {host, Hostname}, {from, self()}, {mfa, {?MODULE, send_recv_result_active, []}}, - {options, ClientOpts}]), + {options, [{verify, verify_peer} | ClientOpts]}]), ssl_test_lib:check_result(Server, ok, Client, ok), ssl_test_lib:close(Server), ssl_test_lib:close(Client). +delete_authority_key_extension([], Acc) -> + lists:reverse(Acc); +delete_authority_key_extension([#'Extension'{extnID = ?'id-ce-authorityKeyIdentifier'} | Rest], + Acc) -> + delete_authority_key_extension(Rest, Acc); +delete_authority_key_extension([Head | Rest], Acc) -> + delete_authority_key_extension(Rest, [Head | Acc]). + %%-------------------------------------------------------------------- -validate_extensions_fun(doc) -> - ["Test that it is possible to specify a validate_extensions_fun"]; -validate_extensions_fun(suite) -> +invalid_signature_server(doc) -> + ["Test server with invalid signature"]; + +invalid_signature_server(suite) -> []; -validate_extensions_fun(Config) when is_list(Config) -> +invalid_signature_server(Config) when is_list(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"), + [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"), + [{'Certificate', ServerDerCert, _}] = ssl_test_lib:pem_to_der(ServerCertFile), + ServerOTPCert = public_key:pkix_decode_cert(ServerDerCert, otp), + ServerOTPTbsCert = ServerOTPCert#'OTPCertificate'.tbsCertificate, + 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)], - Fun = fun(Extensions, State, _, AccError) -> - {Extensions, State, AccError} - end, + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0}, + {from, self()}, + {options, NewServerOpts}]), + Port = ssl_test_lib:inet_port(Server), + Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {options, [{verify, verify_peer} | ClientOpts]}]), + + ssl_test_lib:check_result(Server, {error, "bad certificate"}, + Client, {error,"bad certificate"}). + +%%-------------------------------------------------------------------- + +invalid_signature_client(doc) -> + ["Test server with invalid signature"]; + +invalid_signature_client(suite) -> + []; + +invalid_signature_client(Config) when is_list(Config) -> + ClientOpts = ?config(client_verification_opts, Config), + ServerOpts = ?config(server_verification_opts, Config), + PrivDir = ?config(priv_dir, Config), + + KeyFile = filename:join(PrivDir, "client/key.pem"), + [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"), + [{'Certificate', ClientDerCert, _}] = ssl_test_lib:pem_to_der(ClientCertFile), + ClientOTPCert = public_key:pkix_decode_cert(ClientDerCert, otp), + ClientOTPTbsCert = ClientOTPCert#'OTPCertificate'.tbsCertificate, + 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), - Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0}, {from, self()}, - {mfa, {?MODULE, send_recv_result_active, []}}, - {options, [{validate_extensions_fun, Fun}, - {verify, verify_peer} | ServerOpts]}]), + {options, [{verify, verify_peer} | ServerOpts]}]), Port = ssl_test_lib:inet_port(Server), + Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {options, NewClientOpts}]), - 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]}]), + tcp_delivery_workaround(Server, {error, "bad certificate"}, + Client, {error,"bad certificate"}). + +tcp_delivery_workaround(Server, ServerMsg, Client, ClientMsg) -> + receive + {Server, ServerMsg} -> + receive + {Client, ClientMsg} -> + ok; + {Client, {error,closed}} -> + test_server:format("client got close"); + Unexpected -> + test_server:fail(Unexpected) + end; + {Client, ClientMsg} -> + receive + {Server, ServerMsg} -> + ok; + Unexpected -> + test_server:fail(Unexpected) + end; + {Client, {error,closed}} -> + receive + {Server, ServerMsg} -> + ok; + Unexpected -> + test_server:fail(Unexpected) + end; + {Server, {error,closed}} -> + receive + {Client, ClientMsg} -> + ok; + {Client, {error,closed}} -> + test_server:format("client got close"), + ok; + Unexpected -> + test_server:fail(Unexpected) + end; + Unexpected -> + test_server:fail(Unexpected) + end. +%%-------------------------------------------------------------------- +cert_expired(doc) -> + ["Test server with invalid signature"]; + +cert_expired(suite) -> + []; + +cert_expired(Config) when is_list(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"), + [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"), + [{'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(), + {Hours, Min, Sec} = time(), + NotBeforeStr = lists:flatten(io_lib:format("~p~s~s~s~s~sZ",[Year-2, + two_digits_str(Month), + two_digits_str(Day), + two_digits_str(Hours), + two_digits_str(Min), + two_digits_str(Sec)])), + NotAfterStr = lists:flatten(io_lib:format("~p~s~s~s~s~sZ",[Year-1, + two_digits_str(Month), + two_digits_str(Day), + two_digits_str(Hours), + two_digits_str(Min), + two_digits_str(Sec)])), + NewValidity = {'Validity', {generalTime, NotBeforeStr}, {generalTime, NotAfterStr}}, + + test_server:format("Validity: ~p ~n NewValidity: ~p ~n", + [OTPTbsCert#'OTPTBSCertificate'.validity, NewValidity]), + + NewOTPTbsCert = OTPTbsCert#'OTPTBSCertificate'{validity = NewValidity}, + 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)], - ssl_test_lib:check_result(Server, ok, Client, ok), + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0}, + {from, self()}, + {options, NewServerOpts}]), + Port = ssl_test_lib:inet_port(Server), + Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {options, [{verify, verify_peer} | ClientOpts]}]), + + ssl_test_lib:check_result(Server, {error, "certificate expired"}, + Client, {error, "certificate expired"}). + +two_digits_str(N) when N < 10 -> + lists:flatten(io_lib:format("0~p", [N])); +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, unknown_ca} = Reason, _) -> + {fail, Reason}; + (_,{extension, _}, UserState) -> + {unknown, UserState}; + (_, valid, UserState) -> + {valid, [test_to_update_user_state | UserState]}; + (_, valid_peer, UserState) -> + {valid, 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}; + (_, valid, UserState) -> + {valid, UserState}; + (_, valid_peer, UserState) -> + {valid, 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) -> + DataDir = ?config(data_dir, Config), + DHParamFile = filename:join(DataDir, "dHParam.pem"), + + SeverVerifyOpts = ?config(server_verification_opts, Config), + {ServerCert, ServerKey, ServerCaCerts, DHParams} = der_input_opts([{dhfile, DHParamFile} | + SeverVerifyOpts]), + ClientVerifyOpts = ?config(client_verification_opts, Config), + {ClientCert, ClientKey, ClientCaCerts, DHParams} = der_input_opts([{dhfile, DHParamFile} | + ClientVerifyOpts]), + ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}, + {dh, DHParams}, + {cert, ServerCert}, {key, ServerKey}, {cacerts, ServerCaCerts}], + ClientOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}, + {dh, DHParams}, + {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), + Dhfile = proplists:get_value(dhfile, Opts), + [{_, Cert, _}] = ssl_test_lib:pem_to_der(Certfile), + [{_, Key, _}] = ssl_test_lib:pem_to_der(Keyfile), + [{_, DHParams, _}] = ssl_test_lib:pem_to_der(Dhfile), + CaCerts = + lists:map(fun(Entry) -> + {_, CaCert, _} = Entry, + CaCert + end, ssl_test_lib:pem_to_der(CaCertsfile)), + {Cert, {rsa, Key}, CaCerts, DHParams}. + %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- @@ -2270,6 +3069,7 @@ send_recv_result_active_once(Socket) -> result_ok(_Socket) -> ok. + renegotiate(Socket, Data) -> test_server:format("Renegotiating ~n", []), Result = ssl:renegotiate(Socket), @@ -2278,14 +3078,14 @@ renegotiate(Socket, Data) -> case Result of ok -> ok; - %% It is not an error in erlang ssl - %% if peer rejects renegotiation. - %% Connection will stay up - {error, renegotiation_rejected} -> - ok; Other -> Other end. + +renegotiate_reuse_session(Socket, Data) -> + %% Make sure session is registerd + test_server:sleep(?SLEEP), + renegotiate(Socket, Data). session_cache_process_list(doc) -> ["Test reuse of sessions (short handshake)"]; @@ -2303,129 +3103,35 @@ session_cache_process_mnesia(suite) -> session_cache_process_mnesia(Config) when is_list(Config) -> session_cache_process(mnesia,Config). -session_cache_process(Type,Config) when is_list(Config) -> - process_flag(trap_exit, true), - setup_session_cb(Type), - - ClientOpts = ?config(client_opts, Config), - ServerOpts = ?config(server_opts, Config), - {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), +session_cache_process(_Type,Config) when is_list(Config) -> + reuse_session(Config). - Server = - ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, - {from, self()}, - {mfa, {?MODULE, session_info_result, []}}, - {options, - [{session_cache_cb, ?MODULE}| - ServerOpts]}]), - Port = ssl_test_lib:inet_port(Server), - Client0 = - ssl_test_lib:start_client([{node, ClientNode}, - {port, Port}, {host, Hostname}, - {mfa, {ssl_test_lib, no_result, []}}, - {from, self()}, {options, ClientOpts}]), - SessionInfo = - receive - {Server, Info} -> - Info - end, - - Server ! listen, - - %% Make sure session is registered - test_server:sleep(?SLEEP), - - Client1 = - ssl_test_lib:start_client([{node, ClientNode}, - {port, Port}, {host, Hostname}, - {mfa, {?MODULE, session_info_result, []}}, - {from, self()}, {options, ClientOpts}]), - receive - {Client1, SessionInfo} -> - ok; - {Client1, Other} -> - test_server:format("Expected: ~p, Unexpected: ~p~n", - [SessionInfo, Other]), - test_server:fail(session_not_reused) - end, - - ssl_test_lib:close(Server), - ssl_test_lib:close(Client0), - ssl_test_lib:close(Client1), - - Server1 = - ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, - {from, self()}, - {mfa, {?MODULE, session_info_result, []}}, - {options, - [{reuse_sessions, false} | ServerOpts]}]), - Port1 = ssl_test_lib:inet_port(Server1), - - Client3 = - ssl_test_lib:start_client([{node, ClientNode}, - {port, Port1}, {host, Hostname}, - {mfa, {?MODULE, session_info_result, []}}, - {from, self()}, {options, ClientOpts}]), - - SessionInfo1 = - receive - {Server1, Info1} -> - Info1 - end, - - Server1 ! listen, - - %% Make sure session is registered - test_server:sleep(?SLEEP), - - Client4 = - ssl_test_lib:start_client([{node, ClientNode}, - {port, Port1}, {host, Hostname}, - {mfa, {?MODULE, session_info_result, []}}, - {from, self()}, {options, ClientOpts}]), - - receive - {Client4, SessionInfo1} -> - test_server:fail( - session_reused_when_session_reuse_disabled_by_server); - {Client4, _Other} -> - ok - end, - - ssl_test_lib:close(Server1), - ssl_test_lib:close(Client3), - ssl_test_lib:close(Client4), - process_flag(trap_exit, false). - -setup_session_cb(Type) -> - ssl_test = ets:new(ssl_test,[named_table, set,public]), - ets:insert(ssl_test, {type,Type}). - -session_cb() -> - [{type,Type}] = ets:lookup(ssl_test, type), - Type. - -init() -> - io:format("~p~n",[?LINE]), - case session_cb() of +init([Type]) -> + ets:new(ssl_test, [named_table, public, set]), + ets:insert(ssl_test, {type, Type}), + case Type of list -> spawn(fun() -> session_loop([]) end); mnesia -> mnesia:start(), - {atomic,ok} = mnesia:create_table(sess_cache, []) + {atomic,ok} = mnesia:create_table(sess_cache, []), + sess_cache end. +session_cb() -> + [{type, Type}] = ets:lookup(ssl_test, type), + Type. + terminate(Cache) -> - io:format("~p~n",[?LINE]), case session_cb() of list -> Cache ! terminate; mnesia -> - {atomic,ok} = mnesia:delete_table(sess_cache, []) + catch {atomic,ok} = + mnesia:delete_table(sess_cache) end. -lookup(Cache, Key) -> - io:format("~p~n",[?LINE]), +lookup(Cache, Key) -> case session_cb() of list -> Cache ! {self(), lookup, Key}, @@ -2435,13 +3141,14 @@ lookup(Cache, Key) -> mnesia:read(sess_cache, Key, read) end) of - {atomic, [Session]} -> Session; - _ -> undefined + {atomic, [{sess_cache, Key, Value}]} -> + Value; + _ -> + undefined end - end. + end. update(Cache, Key, Value) -> - io:format("~p~n",[?LINE]), case session_cb() of list -> Cache ! {update, Key, Value}; @@ -2449,12 +3156,11 @@ update(Cache, Key, Value) -> {atomic, ok} = mnesia:transaction(fun() -> mnesia:write(sess_cache, - Key, Value) + {sess_cache, Key, Value}, write) end) end. delete(Cache, Key) -> - io:format("~p~n",[?LINE]), case session_cb() of list -> Cache ! {delete, Key}; @@ -2466,7 +3172,6 @@ delete(Cache, Key) -> end. foldl(Fun, Acc, Cache) -> - io:format("~p~n",[?LINE]), case session_cb() of list -> Cache ! {self(),foldl,Fun,Acc}, @@ -2480,15 +3185,17 @@ foldl(Fun, Acc, Cache) -> end. select_session(Cache, PartialKey) -> - io:format("~p~n",[?LINE]), case session_cb() of list -> Cache ! {self(),select_session, PartialKey}, - receive {Cache, Res} -> Res end; + receive + {Cache, Res} -> + Res + end; mnesia -> Sel = fun() -> mnesia:select(Cache, - [{{{PartialKey,'$1'}, '$2'}, + [{{sess_cache,{PartialKey,'$1'}, '$2'}, [],['$$']}]) end, {atomic, Res} = mnesia:transaction(Sel), @@ -2508,7 +3215,8 @@ session_loop(Sess) -> end, session_loop(Sess); {update, Key, Value} -> - session_loop([{Key,Value}|Sess]); + NewSess = [{Key,Value}| lists:keydelete(Key,1,Sess)], + session_loop(NewSess); {delete, Key} -> session_loop(lists:keydelete(Key,1,Sess)); {Pid,foldl,Fun,Acc} -> @@ -2516,15 +3224,17 @@ session_loop(Sess) -> Pid ! {self(), Res}, session_loop(Sess); {Pid,select_session,PKey} -> - Sel = fun({{Head, _},Session}, Acc) when Head =:= PKey -> - [Session|Acc]; + Sel = fun({{PKey0, Id},Session}, Acc) when PKey == PKey0 -> + [[Id, Session]|Acc]; (_,Acc) -> Acc - end, - Pid ! {self(), lists:foldl(Sel, [], Sess)}, + end, + Sessions = lists:foldl(Sel, [], Sess), + Pid ! {self(), Sessions}, session_loop(Sess) end. + erlang_ssl_receive(Socket, Data) -> receive {ssl, Socket, Data} -> @@ -2535,4 +3245,3 @@ erlang_ssl_receive(Socket, Data) -> after ?SLEEP * 3 -> test_server:fail({did_not_get, Data}) end. - diff --git a/lib/ssl/test/ssl_packet_SUITE.erl b/lib/ssl/test/ssl_packet_SUITE.erl index 1bcb9a657b..88d2d99ef8 100644 --- a/lib/ssl/test/ssl_packet_SUITE.erl +++ b/lib/ssl/test/ssl_packet_SUITE.erl @@ -42,7 +42,6 @@ -define(MANY, 1000). -define(SOME, 50). - %% Test server callback functions %%-------------------------------------------------------------------- %% Function: init_per_suite(Config) -> Config @@ -55,6 +54,7 @@ %%-------------------------------------------------------------------- init_per_suite(Config) -> crypto:start(), + application:start(public_key), ssl:start(), Result = (catch make_certs:all(?config(data_dir, Config), @@ -144,9 +144,26 @@ all(suite) -> packet_wait_passive, packet_wait_active, packet_baddata_passive, packet_baddata_active, packet_size_passive, packet_size_active, - packet_erl_decode, + packet_cdr_decode, + packet_cdr_decode_list, packet_http_decode, - packet_http_bin_decode_multi + packet_http_decode_list, + packet_http_bin_decode_multi, + packet_http_error_passive, + packet_line_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, + header_decode_two_bytes_two_sent + ]. %% Test cases starts here. @@ -503,7 +520,8 @@ packet_raw_active_once_many_small(Config) when is_list(Config) -> Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port}, {host, Hostname}, {from, self()}, - {mfa, {?MODULE, active_once_raw, [Data, ?MANY]}}, + {mfa, {?MODULE, active_once_raw, + [Data, ?MANY]}}, {options, [{active, once}, {packet, raw} | ClientOpts]}]), @@ -535,7 +553,8 @@ packet_raw_active_once_some_big(Config) when is_list(Config) -> Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port}, {host, Hostname}, {from, self()}, - {mfa, {?MODULE, active_once_raw, [Data, ?SOME]}}, + {mfa, {?MODULE, active_once_raw, + [Data, ?SOME]}}, {options, [{active, once}, {packet, raw} | ClientOpts]}]), @@ -1191,7 +1210,8 @@ packet_send_to_large(Config) when is_list(Config) -> {mfa, {?MODULE, active_packet, [Data, 1]}}, {options, [{active, true} | ClientOpts]}]), - ssl_test_lib:check_result(Server, {error, {badarg, {packet_to_large, 300, 255}}}), + ssl_test_lib:check_result(Server, {error, {badarg, + {packet_to_large, 300, 255}}}), ssl_test_lib:close(Server), ssl_test_lib:close(Client). @@ -1216,7 +1236,8 @@ packet_wait_active(Config) when is_list(Config) -> Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0}, {from, self()}, - {mfa, {?MODULE, send_incomplete ,[Data, ?SOME]}}, + {mfa, {?MODULE, send_incomplete, + [Data, ?SOME]}}, {options, ServerOpts}]), Port = ssl_test_lib:inet_port(Server), Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port}, @@ -1251,7 +1272,8 @@ packet_wait_passive(Config) when is_list(Config) -> Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0}, {from, self()}, - {mfa, {?MODULE, send_incomplete ,[Data, ?SOME]}}, + {mfa, {?MODULE, send_incomplete, + [Data, ?SOME]}}, {options, ServerOpts}]), Port = ssl_test_lib:inet_port(Server), Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port}, @@ -1293,7 +1315,8 @@ packet_baddata_active(Config) when is_list(Config) -> {packet, cdr} | ClientOpts]}]), receive - {Client, {other, {ssl_error, _Socket, {invalid_packet, _}},{error,closed},1}} -> ok; + {Client, {other, {ssl_error, _Socket, + {invalid_packet, _}},{error,closed},1}} -> ok; Unexpected -> test_server:fail({unexpected, Unexpected}) end, @@ -1338,8 +1361,11 @@ packet_baddata_passive(Config) when is_list(Config) -> ssl_test_lib:close(Server), ssl_test_lib:close(Client). %%-------------------------------------------------------------------- + packet_size_active(doc) -> - ["Test that if a packet of size larger than packet_size arrives error msg is sent and socket is closed"]; + ["Test that if a packet of size larger than + packet_size arrives error msg is sent and socket is closed"]; + packet_size_active(suite) -> []; @@ -1363,7 +1389,8 @@ packet_size_active(Config) when is_list(Config) -> {packet, 4}, {packet_size, 10} | ClientOpts]}]), receive - {Client, {other, {ssl_error, _Socket, {invalid_packet, _}},{error,closed},1}} -> ok; + {Client, {other, {ssl_error, _Socket, + {invalid_packet, _}},{error,closed},1}} -> ok; Unexpected -> test_server:fail({unexpected, Unexpected}) end, @@ -1371,10 +1398,11 @@ packet_size_active(Config) when is_list(Config) -> ssl_test_lib:close(Server), ssl_test_lib:close(Client). %%-------------------------------------------------------------------- + packet_size_passive(doc) -> - ["Test that if a packet of size larger than packet_size arrives error msg is sent and socket is closed"]; -packet_size_passive(suite) -> - []; + ["Test that if a packet of size larger + than packet_size arrives error msg is sent and socket is closed"]; +packet_size_passive(suite) -> []; packet_size_passive(Config) when is_list(Config) -> ClientOpts = ?config(client_opts, Config), @@ -1391,7 +1419,8 @@ packet_size_passive(Config) when is_list(Config) -> Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port}, {host, Hostname}, {from, self()}, - {mfa, {?MODULE, passive_recv_packet, [Data, 1]}}, + {mfa, {?MODULE, passive_recv_packet, + [Data, 1]}}, {options, [{active, false}, {packet, 4}, {packet_size, 30} | ClientOpts]}]), @@ -1405,14 +1434,11 @@ packet_size_passive(Config) when is_list(Config) -> ssl_test_lib:close(Client). %%-------------------------------------------------------------------- -packet_erl_decode(doc) -> - ["Test that packets of sent to erlang:decode_packet works, i.e. currently" - "asn1 | cdr | sunrm | fcgi | tpkt | line | http | http_bin" - ]; -packet_erl_decode(suite) -> +packet_cdr_decode(doc) -> + ["Test setting the packet option {packet, cdr}, {mode, binary}"]; +packet_cdr_decode(suite) -> []; - -packet_erl_decode(Config) when is_list(Config) -> +packet_cdr_decode(Config) when is_list(Config) -> ClientOpts = ?config(client_opts, Config), ServerOpts = ?config(server_opts, Config), {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), @@ -1423,54 +1449,64 @@ packet_erl_decode(Config) when is_list(Config) -> Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0}, {from, self()}, - {mfa, {?MODULE, server_packet_decode ,[Data]}}, - {options, [{active, true}, binary, {packet, cdr}|ServerOpts]}]), + {mfa, {?MODULE, server_packet_decode, + [Data]}}, + {options, [{active, true}, binary, + {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}, binary | ClientOpts]}]), + {mfa, {?MODULE, client_packet_decode, + [Data]}}, + {options, [{active, true}, {packet, cdr}, + binary | ClientOpts]}]), ssl_test_lib:check_result(Server, ok, Client, ok), ssl_test_lib:close(Server), 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), -server_packet_decode(Socket, CDR) -> - receive - {ssl, Socket, CDR} -> ok; - Other1 -> exit({?LINE, Other1}) - end, - ok = ssl:send(Socket, CDR), - receive - {ssl, Socket, CDR} -> ok; - Other2 -> exit({?LINE, Other2}) - end, - ok = ssl:send(Socket, CDR), - ok. + %% 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], -client_packet_decode(Socket, CDR) -> - <<P1:10/binary, P2/binary>> = CDR, - ok = ssl:send(Socket, P1), - ok = ssl:send(Socket, P2), - receive - {ssl, Socket, CDR} -> ok; - Other1 -> exit({?LINE, Other1}) - end, - ssl:setopts(Socket, [{packet, cdr}]), - ok = ssl:send(Socket, CDR), - receive - {ssl, Socket, CDR} -> ok; - Other2 -> exit({?LINE, Other2}) - end, - ok. + 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}"]; + ["Test setting the packet option {packet, http} {mode, binary} " + "(Body will be binary http strings are lists)"]; packet_http_decode(suite) -> []; @@ -1489,16 +1525,19 @@ packet_http_decode(Config) when is_list(Config) -> Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0}, {from, self()}, - {mfa, {?MODULE, server_http_decode, [Response]}}, - {options, [{active, true}, binary, {packet, http} | - ServerOpts]}]), + {mfa, {?MODULE, server_http_decode, + [Response]}}, + {options, [{active, true},binary, + {packet, http} | 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_http_decode, [Request]}}, - {options, [{active, true}, binary, {packet, http} | + {mfa, {?MODULE, client_http_decode, + [Request]}}, + {options, [{active, true}, binary, + {packet, http} | ClientOpts]}]), ssl_test_lib:check_result(Server, ok, Client, ok), @@ -1550,6 +1589,66 @@ client_http_decode(Socket, HttpRequest) -> ok. %%-------------------------------------------------------------------- +packet_http_decode_list(doc) -> + ["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) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + + Request = "GET / HTTP/1.1\r\n" + "host: www.example.com\r\n" + "user-agent: HttpTester\r\n" + "\r\n", + Response = "HTTP/1.1 200 OK\r\n" + "\r\n" + "Hello!", + + Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, server_http_decode, + [Response]}}, + {options, [{active, true}, binary, + {packet, http} | + 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_http_decode_list, + [Request]}}, + {options, [{active, true}, list, + {packet, http} | + ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). + + +client_http_decode_list(Socket, HttpRequest) -> + ok = ssl:send(Socket, HttpRequest), + receive + {ssl, Socket, {http_response, {1,1}, 200, "OK"}} -> ok; + Other1 -> exit({?LINE, Other1}) + end, + receive + {ssl, Socket, http_eoh} -> ok; + Other2 -> exit({?LINE, Other2}) + end, + ok = ssl:setopts(Socket, [{packet, 0}]), + receive + {ssl, Socket, "Hello!"} -> ok; + Other3 -> exit({?LINE, Other3}) + end, + ok. + +%%-------------------------------------------------------------------- packet_http_bin_decode_multi(doc) -> ["Test setting the packet option {packet, http_bin} with multiple requests"]; packet_http_bin_decode_multi(suite) -> @@ -1571,16 +1670,20 @@ packet_http_bin_decode_multi(Config) when is_list(Config) -> Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0}, {from, self()}, - {mfa, {?MODULE, server_http_bin_decode, [Response, NumMsgs]}}, - {options, [{active, true}, binary, {packet, http_bin} | + {mfa, {?MODULE, server_http_bin_decode, + [Response, NumMsgs]}}, + {options, [{active, true}, binary, + {packet, http_bin} | 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_http_bin_decode, [Request, NumMsgs]}}, - {options, [{active, true}, binary, {packet, http_bin} | + {mfa, {?MODULE, client_http_bin_decode, + [Request, NumMsgs]}}, + {options, [{active, true}, binary, + {packet, http_bin} | ClientOpts]}]), ssl_test_lib:check_result(Server, ok, Client, ok), @@ -1637,23 +1740,551 @@ client_http_bin_decode(_, _, _) -> ok. %%-------------------------------------------------------------------- +packet_http_error_passive(doc) -> + ["Test setting the packet option {packet, http}, {active, false}" + " with a incorrect http header." ]; +packet_http_error_passive(suite) -> + []; +packet_http_error_passive(Config) when is_list(Config) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + + Request = "GET / HTTP/1.1\r\n" + "host: www.example.com\r\n" + "user-agent HttpTester\r\n" + "\r\n", + Response = "HTTP/1.1 200 OK\r\n" + "\r\n" + "Hello!", + + Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, server_http_decode_error, + [Response]}}, + {options, [{active, false}, binary, + {packet, http} | + 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_http_decode_list, + [Request]}}, + {options, [{active, true}, list, + {packet, http} | + ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). + + +server_http_decode_error(Socket, HttpResponse) -> + assert_packet_opt(Socket, http), + + {ok, {http_request, 'GET', _, {1,1}}} = ssl:recv(Socket, 0), + + assert_packet_opt(Socket, http), + + {ok, {http_header, _, 'Host', _, "www.example.com"}} = ssl:recv(Socket, 0), + assert_packet_opt(Socket, http), + + {ok, {http_error, _}} = ssl:recv(Socket, 0), + + assert_packet_opt(Socket, http), + + {ok, http_eoh} = ssl:recv(Socket, 0), + + assert_packet_opt(Socket, http), + ok = ssl:send(Socket, HttpResponse), + ok. + + +%%-------------------------------------------------------------------- +packet_line_decode(doc) -> + ["Test setting the packet option {packet, line}, {mode, binary}"]; +packet_line_decode(suite) -> + []; +packet_line_decode(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 = list_to_binary(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}, binary, + {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}, + binary | ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). + +%%-------------------------------------------------------------------- + +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). + + +%%-------------------------------------------------------------------- + +packet_asn1_decode(doc) -> + ["Test setting the packet option {packet, asn1}"]; +packet_asn1_decode(suite) -> + []; +packet_asn1_decode(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', Data, _}] = ssl_test_lib:pem_to_der(File), + + Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, server_packet_decode, + [Data]}}, + {options, [{active, true}, binary, + {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}, + binary | ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + + ssl_test_lib:close(Server), + 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) -> + []; +packet_tpkt_decode(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 = 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}, binary, + {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}, + binary | ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + + 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). + +%%-------------------------------------------------------------------- + +%% packet_fcgi_decode(doc) -> +%% ["Test setting the packet option {packet, fcgi}"]; +%% packet_fcgi_decode(suite) -> +%% []; +%% packet_fcgi_decode(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 = ... + +%% Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0}, +%% {from, self()}, +%% {mfa, {?MODULE, server_packet_decode, +%% [Data0, Data1]}}, +%% {options, [{active, true}, binary, +%% {packet, fcgi}|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, +%% [Data0, Data1]}}, +%% {options, [{active, true}, {packet, fcgi}, +%% binary | ClientOpts]}]), + +%% ssl_test_lib:check_result(Server, ok, Client, ok), + +%% ssl_test_lib:close(Server), +%% ssl_test_lib:close(Client). + + +%%-------------------------------------------------------------------- + +packet_sunrm_decode(doc) -> + ["Test setting the packet option {packet, sunrm}"]; +packet_sunrm_decode(suite) -> + []; +packet_sunrm_decode(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 = <<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}, binary, + {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}, + binary | ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + + 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) -> + ["Test setting the packet option {header, 1}"]; +header_decode_one_byte(suite) -> + []; +header_decode_one_byte(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 = <<11:8, "Hello world">>, + + Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, server_header_decode, + [Data, [11 | <<"Hello world">>]]}}, + {options, [{active, true}, binary, + {header,1}|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_header_decode, + [Data, [11 | <<"Hello world">> ]]}}, + {options, [{active, true}, {header, 1}, + binary | ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). + +%%-------------------------------------------------------------------- + +header_decode_two_bytes(doc) -> + ["Test setting the packet option {header, 2}"]; +header_decode_two_bytes(suite) -> + []; +header_decode_two_bytes(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 = <<11:8, "Hello world">>, + + Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, server_header_decode, + [Data, [11, $H | <<"ello world">> ]]}}, + {options, [{active, true}, binary, + {header,2}|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_header_decode, + [Data, [11, $H | <<"ello world">> ]]}}, + {options, [{active, true}, {header, 2}, + binary | ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). + + +%%-------------------------------------------------------------------- + +header_decode_two_bytes_two_sent(doc) -> + ["Test setting the packet option {header, 2} and sending on byte"]; +header_decode_two_bytes_two_sent(suite) -> + []; +header_decode_two_bytes_two_sent(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 = <<"He">>, + + Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, server_header_decode, + [Data, [$H, $e | <<>> ]]}}, + {options, [{active, true}, binary, + {header,2}|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_header_decode, + [Data, [$H, $e | <<>> ]]}}, + {options, [{active, true}, {header, 2}, + binary | ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). + + +%%-------------------------------------------------------------------- + +header_decode_two_bytes_one_sent(doc) -> + ["Test setting the packet option {header, 2} and sending on byte"]; +header_decode_two_bytes_one_sent(suite) -> + []; +header_decode_two_bytes_one_sent(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 = <<"H">>, + + Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, server_header_decode, + [Data, "H"]}}, + {options, [{active, true}, binary, + {header,2}|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_header_decode, + [Data, "H"]}}, + {options, [{active, true}, {header, 2}, + binary | ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). + + +%%-------------------------------------------------------------------- %% 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} -> @@ -1662,7 +2293,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 @@ -1676,6 +2308,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), @@ -1704,8 +2337,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} -> @@ -1717,7 +2355,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 @@ -1732,8 +2370,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} -> @@ -1744,3 +2387,105 @@ active_packet(Socket, Data, N) -> assert_packet_opt(Socket, Type) -> {ok, [{packet, Type}]} = ssl:getopts(Socket, [packet]). + +server_packet_decode(Socket, Packet) -> + receive + {ssl, Socket, Packet} -> ok; + Other1 -> exit({?LINE, Other1}) + end, + ok = ssl:send(Socket, Packet), + receive + {ssl, Socket, Packet} -> ok; + Other2 -> exit({?LINE, Other2}) + end, + ok = ssl:send(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 + {ssl, Socket, Packet} -> ok; + Other1 -> exit({?LINE, Other1}) + end, + ok = ssl:send(Socket, Packet), + receive + {ssl, Socket, Packet} -> ok; + Other2 -> exit({?LINE, Other2}) + end. + +server_header_decode(Socket, Packet, Result) -> + receive + {ssl, Socket, Result} -> ok; + Other1 -> exit({?LINE, Other1}) + end, + ok = ssl:send(Socket, Packet), + receive + {ssl, Socket, Result} -> ok; + Other2 -> exit({?LINE, Other2}) + end, + ok = ssl:send(Socket, Packet). + +client_header_decode(Socket, Packet, Result) -> + ok = ssl:send(Socket, Packet), + receive + {ssl, Socket, Result} -> ok; + Other1 -> exit({?LINE, Other1}) + end, + ok = ssl:send(Socket, Packet), + receive + {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, + [3, 0, ((L) bsr 8) band 16#ff, (L) band 16#ff ,Data]; +add_tpkt_header(IOList) when is_list(IOList) -> + Binary = list_to_binary(IOList), + L = size(Binary) + 4, + [3, 0, ((L) bsr 8) band 16#ff, (L) band 16#ff , Binary]. diff --git a/lib/ssl/test/ssl_payload_SUITE.erl b/lib/ssl/test/ssl_payload_SUITE.erl index a0aa92bdf2..d80df0bfbd 100644 --- a/lib/ssl/test/ssl_payload_SUITE.erl +++ b/lib/ssl/test/ssl_payload_SUITE.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -38,6 +38,7 @@ %%-------------------------------------------------------------------- init_per_suite(Config) -> crypto:start(), + application:start(public_key), ssl:start(), make_certs:all(?config(data_dir, Config), ?config(priv_dir, Config)), ssl_test_lib:cert_options(Config). diff --git a/lib/ssl/test/ssl_test_MACHINE.erl b/lib/ssl/test/ssl_test_MACHINE.erl index e75f7079ed..e0ffa15d80 100644 --- a/lib/ssl/test/ssl_test_MACHINE.erl +++ b/lib/ssl/test/ssl_test_MACHINE.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -60,10 +60,12 @@ many_conns_1() -> %% mk_ssl_cert_opts(_Config) -> Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]), - COpts = [{cacertfile, filename:join([Dir, "client", "cacerts.pem"])}, + COpts = [{ssl_imp, old}, + {cacertfile, filename:join([Dir, "client", "cacerts.pem"])}, {certfile, filename:join([Dir, "client", "cert.pem"])}, {keyfile, filename:join([Dir, "client", "key.pem"])}], - SOpts = [{cacertfile, filename:join([Dir, "server", "cacerts.pem"])}, + SOpts = [{ssl_imp, old}, + {cacertfile, filename:join([Dir, "server", "cacerts.pem"])}, {certfile, filename:join([Dir, "server", "cert.pem"])}, {keyfile, filename:join([Dir, "server", "key.pem"])}], {ok, {COpts, SOpts}}. @@ -225,11 +227,13 @@ start_ssl(Nodes, Config) -> ok. do_start(Env) -> + application:start(crypto), + application:start(public_key), application:load(ssl), lists:foreach( fun({Par, Val}) -> application:set_env(ssl, Par, Val) end, Env), - application:start(ssl), - application:start(crypto). + application:start(ssl). + %% %% start_node(Name) -> {ok, Node} @@ -542,7 +546,7 @@ get_active(St) -> listen(St, LPort) -> case St#st.protomod of ssl -> - ssl:listen(LPort, St#st.sockopts ++ St#st.sslopts); + ssl:listen(LPort, [{ssl_imp, old} | St#st.sockopts ++ St#st.sslopts]); gen_tcp -> gen_tcp:listen(LPort, St#st.sockopts) end. @@ -584,7 +588,8 @@ connect(St, Host, Port) -> case St#st.protomod of ssl -> - case ssl:connect(Host, Port, St#st.sockopts ++ St#st.sslopts, + case ssl:connect(Host, Port, + [{ssl_imp, old} | St#st.sockopts ++ St#st.sslopts], St#st.timeout) of {ok, Sock} -> {ok, LPort} = ssl:sockname(Sock), diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl index 00c5350ad0..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}, @@ -318,6 +324,39 @@ cert_options(Config) -> | Config]. +make_dsa_cert(Config) -> + + {ServerCaCertFile, ServerCertFile, ServerKeyFile} = make_dsa_cert_files("server", Config), + {ClientCaCertFile, ClientCertFile, ClientKeyFile} = make_dsa_cert_files("client", Config), + [{server_dsa_opts, [{ssl_imp, new},{reuseaddr, true}, + {cacertfile, ServerCaCertFile}, + {certfile, ServerCertFile}, {keyfile, ServerKeyFile}]}, + {server_dsa_verify_opts, [{ssl_imp, new},{reuseaddr, true}, + {cacertfile, ClientCaCertFile}, + {certfile, ServerCertFile}, {keyfile, ServerKeyFile}, + {verify, verify_peer}]}, + {client_dsa_opts, [{ssl_imp, new},{reuseaddr, true}, + {cacertfile, ClientCaCertFile}, + {certfile, ClientCertFile}, {keyfile, ClientKeyFile}]} + | Config]. + + + +make_dsa_cert_files(RoleStr, Config) -> + CaInfo = {CaCert, _} = erl_make_certs:make_cert([{key, dsa}]), + {Cert, CertKey} = erl_make_certs:make_cert([{key, dsa}, {issuer, CaInfo}]), + CaCertFile = filename:join([?config(priv_dir, Config), + RoleStr, "dsa_cacerts.pem"]), + CertFile = filename:join([?config(priv_dir, Config), + RoleStr, "dsa_cert.pem"]), + KeyFile = filename:join([?config(priv_dir, Config), + RoleStr, "dsa_key.pem"]), + + 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) -> Result = spawn_link(?MODULE, run_upgrade_server, [Args]), receive @@ -394,6 +433,41 @@ run_upgrade_client(Opts) -> ok = rpc:call(Node, ssl, close, [SslSocket]) end. +start_upgrade_server_error(Args) -> + Result = spawn_link(?MODULE, run_upgrade_server_error, [Args]), + receive + {listen, up} -> + Result + end. + +run_upgrade_server_error(Opts) -> + Node = proplists:get_value(node, Opts), + Port = proplists:get_value(port, Opts), + TimeOut = proplists:get_value(timeout, Opts, infinity), + TcpOptions = proplists:get_value(tcp_options, Opts), + SslOptions = proplists:get_value(ssl_options, Opts), + Pid = proplists:get_value(from, Opts), + + test_server:format("gen_tcp:listen(~p, ~p)~n", [Port, TcpOptions]), + {ok, ListenSocket} = rpc:call(Node, gen_tcp, listen, [Port, TcpOptions]), + Pid ! {listen, up}, + send_selected_port(Pid, Port, ListenSocket), + test_server:format("gen_tcp:accept(~p)~n", [ListenSocket]), + {ok, AcceptSocket} = rpc:call(Node, gen_tcp, accept, [ListenSocket]), + Error = case TimeOut of + infinity -> + test_server:format("ssl:ssl_accept(~p, ~p)~n", + [AcceptSocket, SslOptions]), + rpc:call(Node, ssl, ssl_accept, + [AcceptSocket, SslOptions]); + _ -> + test_server:format("ssl:ssl_accept(~p, ~p, ~p)~n", + [AcceptSocket, SslOptions, TimeOut]), + rpc:call(Node, ssl, ssl_accept, + [AcceptSocket, SslOptions, TimeOut]) + end, + Pid ! {self(), Error}. + start_server_error(Args) -> Result = spawn_link(?MODULE, run_server_error, [Args]), receive @@ -494,3 +568,75 @@ send_selected_port(Pid, 0, Socket) -> Pid ! {self(), {port, NewPort}}; send_selected_port(_,_,_) -> ok. + +rsa_suites() -> + lists:filter(fun({dhe_dss, _, _}) -> + false; + (_) -> + true + 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; + (_) -> + false + end, + ssl:cipher_suites()). + + +openssl_rsa_suites() -> + Ciphers = ssl:cipher_suites(openssl), + lists:filter(fun(Str) -> + case re:run(Str,"DSS",[]) of + nomatch -> + true; + _ -> + false + end + end, Ciphers). + +openssl_dsa_suites() -> + Ciphers = ssl:cipher_suites(openssl), + lists:filter(fun(Str) -> + case re:run(Str,"DSS",[]) of + nomatch -> + false; + _ -> + 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 cbf0447bf0..7f512f2ab9 100644 --- a/lib/ssl/test/ssl_to_openssl_SUITE.erl +++ b/lib/ssl/test/ssl_to_openssl_SUITE.erl @@ -25,14 +25,13 @@ -compile(export_all). -include("test_server.hrl"). --include("test_server_line.hrl"). --include("ssl_pkix.hrl"). -define(TIMEOUT, 120000). -define(SLEEP, 1000). -define(OPENSSL_RENEGOTIATE, "r\n"). -define(OPENSSL_QUIT, "Q\n"). -define(OPENSSL_GARBAGE, "P\n"). +-define(EXPIRE, 10). %% Test server callback functions %%-------------------------------------------------------------------- @@ -44,18 +43,22 @@ %% Note: This function is free to add any key/value pairs to the Config %% variable, but should NOT alter/remove any existing entries. %%-------------------------------------------------------------------- -init_per_suite(Config) -> +init_per_suite(Config0) -> + Dog = ssl_test_lib:timetrap(?TIMEOUT *2), case os:find_executable("openssl") of false -> {skip, "Openssl not found"}; _ -> crypto:start(), + application:start(public_key), ssl:start(), Result = - (catch make_certs:all(?config(data_dir, Config), - ?config(priv_dir, Config))), + (catch make_certs:all(?config(data_dir, Config0), + ?config(priv_dir, Config0))), test_server:format("Make certs ~p~n", [Result]), - ssl_test_lib:cert_options(Config) + Config1 = ssl_test_lib:make_dsa_cert(Config0), + Config = ssl_test_lib:cert_options(Config1), + [{watchdog, Dog} | Config] end. %%-------------------------------------------------------------------- @@ -81,11 +84,29 @@ end_per_suite(_Config) -> %% variable, but should NOT alter/remove any existing entries. %% Description: Initialization before each test case %%-------------------------------------------------------------------- -init_per_testcase(_TestCase, Config0) -> +init_per_testcase(expired_session, Config0) -> + Config = lists:keydelete(watchdog, 1, Config0), + Dog = ssl_test_lib:timetrap(?EXPIRE * 1000 * 5), + ssl:stop(), + application:load(ssl), + application:set_env(ssl, session_lifetime, ?EXPIRE), + ssl:start(), + [{watchdog, Dog} | Config]; + +init_per_testcase(TestCase, Config0) -> Config = lists:keydelete(watchdog, 1, Config0), Dog = ssl_test_lib:timetrap(?TIMEOUT), - [{watchdog, Dog} | Config]. + special_init(TestCase, [{watchdog, Dog} | Config]). + +special_init(TestCase, Config) + when TestCase == erlang_client_openssl_server_renegotiate; + TestCase == erlang_client_openssl_server_no_wrap_sequence_number; + TestCase == erlang_server_openssl_client_no_wrap_sequence_number -> + check_sane_openssl_renegotaite(Config); +special_init(_, Config) -> + Config. + %%-------------------------------------------------------------------- %% Function: end_per_testcase(TestCase, Config) -> _ %% Case - atom() @@ -94,14 +115,20 @@ init_per_testcase(_TestCase, Config0) -> %% A list of key/value pairs, holding the test case configuration. %% Description: Cleanup after each test case %%-------------------------------------------------------------------- -end_per_testcase(_TestCase, Config) -> +end_per_testcase(reuse_session_expired, Config) -> + application:unset_env(ssl, session_lifetime), + end_per_testcase(default_action, Config); + +end_per_testcase(default_action, Config) -> Dog = ?config(watchdog, Config), case Dog of undefined -> ok; _ -> test_server:timetrap_cancel(Dog) - end. + end; +end_per_testcase(_, Config) -> + end_per_testcase(default_action, Config). %%-------------------------------------------------------------------- %% Function: all(Clause) -> TestCases @@ -117,6 +144,10 @@ all(doc) -> all(suite) -> [erlang_client_openssl_server, erlang_server_openssl_client, + tls1_erlang_client_openssl_server_dsa_cert, + tls1_erlang_server_openssl_client_dsa_cert, + ssl3_erlang_client_openssl_server_dsa_cert, + ssl3_erlang_server_openssl_client_dsa_cert, erlang_server_openssl_client_reuse_session, erlang_client_openssl_server_renegotiate, erlang_client_openssl_server_no_wrap_sequence_number, @@ -132,8 +163,11 @@ all(suite) -> tls1_erlang_client_openssl_server_client_cert, tls1_erlang_server_openssl_client_client_cert, tls1_erlang_server_erlang_client_client_cert, - ciphers, - erlang_client_bad_openssl_server + ciphers_rsa_signed_certs, + ciphers_dsa_signed_certs, + erlang_client_bad_openssl_server, + expired_session, + ssl2_erlang_server_openssl_client ]. %% Test cases starts here. @@ -220,6 +254,185 @@ erlang_server_openssl_client(Config) when is_list(Config) -> %%-------------------------------------------------------------------- +tls1_erlang_client_openssl_server_dsa_cert(doc) -> + ["Test erlang server with openssl client"]; +tls1_erlang_client_openssl_server_dsa_cert(suite) -> + []; +tls1_erlang_client_openssl_server_dsa_cert(Config) when is_list(Config) -> + process_flag(trap_exit, true), + ClientOpts = ?config(client_dsa_opts, Config), + ServerOpts = ?config(server_dsa_opts, Config), + + {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config), + + Data = "From openssl to erlang", + + Port = ssl_test_lib:inet_port(node()), + CaCertFile = proplists:get_value(cacertfile, ServerOpts), + CertFile = proplists:get_value(certfile, ServerOpts), + KeyFile = proplists:get_value(keyfile, ServerOpts), + + Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ + " -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile + ++ " -key " ++ KeyFile ++ " -Verify 2 -tls1 -msg", + + test_server:format("openssl cmd: ~p~n", [Cmd]), + + OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + + wait_for_openssl_server(), + + Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, + erlang_ssl_receive, [Data]}}, + {options, ClientOpts}]), + + port_command(OpensslPort, Data), + + ssl_test_lib:check_result(Client, ok), + + %% Clean close down! Server needs to be closed first !! + close_port(OpensslPort), + + ssl_test_lib:close(Client), + process_flag(trap_exit, false), + ok. + +%%-------------------------------------------------------------------- + +tls1_erlang_server_openssl_client_dsa_cert(doc) -> + ["Test erlang server with openssl client"]; +tls1_erlang_server_openssl_client_dsa_cert(suite) -> + []; +tls1_erlang_server_openssl_client_dsa_cert(Config) when is_list(Config) -> + process_flag(trap_exit, true), + ClientOpts = ?config(client_dsa_opts, Config), + ServerOpts = ?config(server_dsa_verify_opts, Config), + + {_, ServerNode, _} = ssl_test_lib:run_where(Config), + + Data = "From openssl to erlang", + CaCertFile = proplists:get_value(cacertfile, ClientOpts), + CertFile = proplists:get_value(certfile, ClientOpts), + KeyFile = proplists:get_value(keyfile, ClientOpts), + + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, erlang_ssl_receive, [Data]}}, + {options, ServerOpts}]), + Port = ssl_test_lib:inet_port(Server), + + Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++ + " -host localhost " ++ " -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile + ++ " -key " ++ KeyFile ++ " -tls1 -msg", + + test_server:format("openssl cmd: ~p~n", [Cmd]), + + OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + port_command(OpenSslPort, Data), + + ssl_test_lib:check_result(Server, ok), + + ssl_test_lib:close(Server), + + close_port(OpenSslPort), + process_flag(trap_exit, false), + ok. + +%%-------------------------------------------------------------------- + +ssl3_erlang_client_openssl_server_dsa_cert(doc) -> + ["Test erlang server with openssl client"]; +ssl3_erlang_client_openssl_server_dsa_cert(suite) -> + []; +ssl3_erlang_client_openssl_server_dsa_cert(Config) when is_list(Config) -> + process_flag(trap_exit, true), + ClientOpts = ?config(client_dsa_opts, Config), + ServerOpts = ?config(server_dsa_opts, Config), + + {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config), + + Data = "From openssl to erlang", + + Port = ssl_test_lib:inet_port(node()), + CaCertFile = proplists:get_value(cacertfile, ServerOpts), + CertFile = proplists:get_value(certfile, ServerOpts), + KeyFile = proplists:get_value(keyfile, ServerOpts), + + Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ + " -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile + ++ " -key " ++ KeyFile ++ " -Verify 2 -ssl3 -msg", + + test_server:format("openssl cmd: ~p~n", [Cmd]), + + OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + + wait_for_openssl_server(), + + Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, + erlang_ssl_receive, [Data]}}, + {options, ClientOpts}]), + + port_command(OpensslPort, Data), + + ssl_test_lib:check_result(Client, ok), + + %% Clean close down! Server needs to be closed first !! + close_port(OpensslPort), + + ssl_test_lib:close(Client), + process_flag(trap_exit, false), + ok. + +%%-------------------------------------------------------------------- + +ssl3_erlang_server_openssl_client_dsa_cert(doc) -> + ["Test erlang server with openssl client"]; +ssl3_erlang_server_openssl_client_dsa_cert(suite) -> + []; +ssl3_erlang_server_openssl_client_dsa_cert(Config) when is_list(Config) -> + process_flag(trap_exit, true), + ClientOpts = ?config(client_dsa_opts, Config), + ServerOpts = ?config(server_dsa_verify_opts, Config), + + {_, ServerNode, _} = ssl_test_lib:run_where(Config), + + Data = "From openssl to erlang", + CaCertFile = proplists:get_value(cacertfile, ClientOpts), + CertFile = proplists:get_value(certfile, ClientOpts), + KeyFile = proplists:get_value(keyfile, ClientOpts), + + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, erlang_ssl_receive, [Data]}}, + {options, ServerOpts}]), + Port = ssl_test_lib:inet_port(Server), + + Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++ + " -host localhost " ++ " -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile + ++ " -key " ++ KeyFile ++ " -ssl3 -msg", + + test_server:format("openssl cmd: ~p~n", [Cmd]), + + OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + port_command(OpenSslPort, Data), + + ssl_test_lib:check_result(Server, ok), + + ssl_test_lib:close(Server), + + close_port(OpenSslPort), + process_flag(trap_exit, false), + ok. + + +%%-------------------------------------------------------------------- + erlang_server_openssl_client_reuse_session(doc) -> ["Test erlang server with openssl client that reconnects with the" "same session id, to test reusing of sessions."]; @@ -297,12 +510,8 @@ erlang_client_openssl_server_renegotiate(Config) when is_list(Config) -> test_server:sleep(?SLEEP), port_command(OpensslPort, OpenSslData), - %%ssl_test_lib:check_result(Client, ok), - %% Currently allow test case to not fail - %% if server requires secure renegotiation from RFC-5746 - %% This should be removed as soon as we have implemented it. - ssl_test_lib:check_result_ignore_renegotiation_reject(Client, ok), - + ssl_test_lib:check_result(Client, ok), + %% Clean close down! Server needs to be closed first !! close_port(OpensslPort), @@ -350,11 +559,7 @@ erlang_client_openssl_server_no_wrap_sequence_number(Config) when is_list(Config {options, [{reuse_sessions, false}, {renegotiate_at, N} | ClientOpts]}]), - %%ssl_test_lib:check_result(Client, ok), - %% Currently allow test case to not fail - %% if server requires secure renegotiation from RFC-5746 - %% This should be removed as soon as we have implemented it. - ssl_test_lib:check_result_ignore_renegotiation_reject(Client, ok), + ssl_test_lib:check_result(Client, ok), %% Clean close down! Server needs to be closed first !! close_port(OpensslPort), @@ -862,19 +1067,46 @@ tls1_erlang_server_erlang_client_client_cert(Config) when is_list(Config) -> ok. %%-------------------------------------------------------------------- -ciphers(doc) -> - [""]; +ciphers_rsa_signed_certs(doc) -> + ["Test cipher suites that uses rsa certs"]; -ciphers(suite) -> +ciphers_rsa_signed_certs(suite) -> []; -ciphers(Config) when is_list(Config) -> +ciphers_rsa_signed_certs(Config) when is_list(Config) -> Version = ssl_record:protocol_version(ssl_record:highest_protocol_version([])), - Ciphers = ssl:cipher_suites(), + Ciphers = ssl_test_lib:rsa_suites(), + run_suites(Ciphers, Version, Config, rsa). + + +ciphers_dsa_signed_certs(doc) -> + ["Test cipher suites that uses dsa certs"]; + +ciphers_dsa_signed_certs(suite) -> + []; + +ciphers_dsa_signed_certs(Config) when is_list(Config) -> + Version = + ssl_record:protocol_version(ssl_record:highest_protocol_version([])), + + Ciphers = ssl_test_lib:dsa_suites(), + run_suites(Ciphers, Version, Config, dsa). + +run_suites(Ciphers, Version, Config, Type) -> + {ClientOpts, ServerOpts} = + case Type of + rsa -> + {?config(client_opts, Config), + ?config(server_opts, Config)}; + dsa -> + {?config(client_opts, Config), + ?config(server_dsa_opts, Config)} + end, + Result = lists:map(fun(Cipher) -> - cipher(Cipher, Version, Config) end, + cipher(Cipher, Version, Config, ClientOpts, ServerOpts) end, Ciphers), case lists:flatten(Result) of [] -> @@ -883,12 +1115,12 @@ ciphers(Config) when is_list(Config) -> test_server:format("Cipher suite errors: ~p~n", [Error]), test_server:fail(cipher_suite_failed_see_test_case_log) end. - -cipher(CipherSuite, Version, Config) -> + + + +cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) -> process_flag(trap_exit, true), test_server:format("Testing CipherSuite ~p~n", [CipherSuite]), - ClientOpts = ?config(client_opts, Config), - ServerOpts = ?config(server_opts, Config), {ClientNode, _ServerNode, Hostname} = ssl_test_lib:run_where(Config), Port = ssl_test_lib:inet_port(node()), @@ -904,17 +1136,31 @@ cipher(CipherSuite, Version, Config) -> 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! @@ -958,7 +1204,7 @@ erlang_client_bad_openssl_server(Config) when is_list(Config) -> wait_for_openssl_server(), - Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + Client0 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, {host, Hostname}, {from, self()}, {mfa, {?MODULE, server_sent_garbage, []}}, @@ -970,15 +1216,120 @@ erlang_client_bad_openssl_server(Config) when is_list(Config) -> test_server:sleep(?SLEEP), - Client ! server_sent_garbage, + Client0 ! server_sent_garbage, + + ssl_test_lib:check_result(Client0, true), + + ssl_test_lib:close(Client0), + + %% Make sure openssl does not hang and leave zombie process + Client1 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {ssl_test_lib, no_result_msg, []}}, + {options, + [{versions, [tlsv1]} | ClientOpts]}]), + + ssl_test_lib:close(Client1), + + %% Clean close down! + close_port(OpensslPort), + process_flag(trap_exit, false), + ok. - ssl_test_lib:check_result(Client, true), +%%-------------------------------------------------------------------- + +expired_session(doc) -> + ["Test our ssl client handling of expired sessions. Will make" + "better code coverage of the ssl_manager module"]; + +expired_session(suite) -> + []; + +expired_session(Config) when is_list(Config) -> + process_flag(trap_exit, true), + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config), + + Port = ssl_test_lib:inet_port(node()), + CertFile = proplists:get_value(certfile, ServerOpts), + KeyFile = proplists:get_value(keyfile, ServerOpts), + + Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ + " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ "", + + test_server:format("openssl cmd: ~p~n", [Cmd]), + + OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + + wait_for_openssl_server(), + + Client0 = + ssl_test_lib:start_client([{node, ClientNode}, + {port, Port}, {host, Hostname}, + {mfa, {ssl_test_lib, no_result, []}}, + {from, self()}, {options, ClientOpts}]), + + ssl_test_lib:close(Client0), + + %% Make sure session is registered + test_server:sleep(?SLEEP), + + Client1 = + ssl_test_lib:start_client([{node, ClientNode}, + {port, Port}, {host, Hostname}, + {mfa, {ssl_test_lib, no_result, []}}, + {from, self()}, {options, ClientOpts}]), + + ssl_test_lib:close(Client1), + %% Make sure session is unregistered due to expiration + test_server:sleep((?EXPIRE+1) * 1000), + + Client2 = + ssl_test_lib:start_client([{node, ClientNode}, + {port, Port}, {host, Hostname}, + {mfa, {ssl_test_lib, no_result, []}}, + {from, self()}, {options, ClientOpts}]), - ssl_test_lib:close(Client), - %% Clean close down! close_port(OpensslPort), + ssl_test_lib:close(Client2), + process_flag(trap_exit, false). + +%%-------------------------------------------------------------------- +ssl2_erlang_server_openssl_client(doc) -> + ["Test that ssl v2 clients are rejected"]; +ssl2_erlang_server_openssl_client(suite) -> + []; +ssl2_erlang_server_openssl_client(Config) when is_list(Config) -> + process_flag(trap_exit, true), + ServerOpts = ?config(server_opts, Config), + + {_, ServerNode, _} = ssl_test_lib:run_where(Config), + + Data = "From openssl to erlang", + + Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0}, + {from, self()}, + {options, ServerOpts}]), + Port = ssl_test_lib:inet_port(Server), + + Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++ + " -host localhost -ssl2 -msg", + + test_server:format("openssl cmd: ~p~n", [Cmd]), + + OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + port_command(OpenSslPort, Data), + + ssl_test_lib:check_result(Server, {error,"protocol version"}), + + ssl_test_lib:close(Server), + + close_port(OpenSslPort), process_flag(trap_exit, false), ok. + %%-------------------------------------------------------------------- erlang_ssl_receive(Socket, Data) -> @@ -1018,8 +1369,7 @@ delayed_send(Socket, [ErlData, OpenSslData]) -> erlang_ssl_receive(Socket, OpenSslData). close_port(Port) -> - port_command(Port, ?OPENSSL_QUIT), - %%catch port_command(Port, "quit\n"), + catch port_command(Port, ?OPENSSL_QUIT), close_loop(Port, 500, false). close_loop(Port, Time, SentClose) -> @@ -1055,6 +1405,7 @@ server_sent_garbage(Socket) -> receive server_sent_garbage -> {error, closed} == ssl:send(Socket, "data") + end. wait_for_openssl_server() -> @@ -1068,3 +1419,12 @@ wait_for_openssl_server() -> test_server:sleep(?SLEEP) end. +check_sane_openssl_renegotaite(Config) -> + case os:cmd("openssl version") of + "OpenSSL 0.9.8" ++ _ -> + {skip, "Known renegotiation bug in OppenSSL"}; + "OpenSSL 0.9.7" ++ _ -> + {skip, "Known renegotiation bug in OppenSSL"}; + _ -> + Config + end. diff --git a/lib/ssl/vsn.mk b/lib/ssl/vsn.mk index a8966d46d7..30a0a3b3f7 100644 --- a/lib/ssl/vsn.mk +++ b/lib/ssl/vsn.mk @@ -1,33 +1,2 @@ -SSL_VSN = 3.11 -TICKETS = 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 +SSL_VSN = 4.1 diff --git a/lib/stdlib/doc/src/Makefile b/lib/stdlib/doc/src/Makefile index 13b9b2ff18..b558697d63 100644 --- a/lib/stdlib/doc/src/Makefile +++ b/lib/stdlib/doc/src/Makefile @@ -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% # include $(ERL_TOP)/make/target.mk @@ -40,6 +40,7 @@ XML_REF3_FILES = \ array.xml \ base64.xml \ beam_lib.xml \ + binary.xml \ c.xml \ calendar.xml \ dets.xml \ diff --git a/lib/stdlib/doc/src/beam_lib.xml b/lib/stdlib/doc/src/beam_lib.xml index b9286f1402..adc411e272 100644 --- a/lib/stdlib/doc/src/beam_lib.xml +++ b/lib/stdlib/doc/src/beam_lib.xml @@ -341,15 +341,17 @@ chunkref() = chunkname() | chunkid()</code> <v>Beam1 = Beam2 = beam()</v> <v>Reason = {modules_different, Module1, Module2}</v> <v> | {chunks_different, ChunkId}</v> + <v> | different_chunks</v> <v> | Reason1 -- see info/1</v> <v> Module1 = Module2 = atom()</v> <v> ChunkId = chunkid()</v> </type> <desc> <p>Compares the contents of two BEAM files. If the module names - are the same, and the chunks with the identifiers - <c>"Code"</c>, <c>"ExpT"</c>, <c>"ImpT"</c>, <c>"StrT"</c>, - and <c>"Atom"</c> have the same contents in both files, + are the same, and all chunks except for the <c>"CInf"</c> chunk + (the chunk containing the compilation information which is + returned by <c>Module:module_info(compile)</c>) + have the same contents in both files, <c>ok</c> is returned. Otherwise an error message is returned.</p> </desc> </func> diff --git a/lib/stdlib/doc/src/binary.xml b/lib/stdlib/doc/src/binary.xml new file mode 100644 index 0000000000..c5eb81a86a --- /dev/null +++ b/lib/stdlib/doc/src/binary.xml @@ -0,0 +1,729 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2009</year> + <year>2010</year> + <holder>Ericsson AB, All Rights Reserved</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved on line 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. + + The Initial Developer of the Original Code is Ericsson AB. + </legalnotice> + + <title>binary</title> + <prepared>Patrik Nyblom</prepared> + <responsible>Kenneth Lundin</responsible> + <docno>1</docno> + <approved></approved> + <checked></checked> + <date>2010-05-05</date> + <rev>A</rev> + <file>binary.xml</file> + </header> + <module>binary</module> + <modulesummary>Library for handling binary data</modulesummary> + <description> + + <p>This module contains functions for manipulating byte-oriented + binaries. Although the majority of functions could be implemented + using bit-syntax, the functions in this library are highly + optimized and are expected to either execute faster or consume + less memory (or both) than a counterpart written in pure Erlang.</p> + + <p>The module is implemented according to the EEP (Erlang Enhancement Proposal) 31.</p> + + <note> + <p> + The library handles byte-oriented data. Bitstrings that are not + binaries (does not contain whole octets of bits) will result in a <c>badarg</c> + exception being thrown from any of the functions in this + module. + </p> + </note> + + + </description> + <section> + <title>DATA TYPES</title> + <code type="none"> + cp() + - Opaque data-type representing a compiled search-pattern. Guaranteed to be a tuple() + to allow programs to distinguish it from non precompiled search patterns. + </code> + <code type="none"> + part() = {Start,Length} + Start = int() + Length = int() + - A representaion of a part (or range) in a binary. Start is a + zero-based offset into a binary() and Length is the length of + that part. As input to functions in this module, a reverse + part specification is allowed, constructed with a negative + Length, so that the part of the binary begins at Start + + Length and is -Length long. This is useful for referencing the + last N bytes of a binary as {size(Binary), -N}. The functions + in this module always return part()'s with positive Length. + </code> + </section> + <funcs> + <func> + <name>at(Subject, Pos) -> int()</name> + <fsummary>Returns the byte at a specific position in a binary</fsummary> + <type> + <v>Subject = binary()</v> + <v>Pos = int() >= 0</v> + </type> + <desc> + + <p>Returns the byte at position <c>Pos</c> (zero-based) in the binary + <c>Subject</c> as an integer. If <c>Pos</c> >= <c>byte_size(Subject)</c>, + a <c>badarg</c> + exception is raised.</p> + + </desc> + </func> + <func> + <name>bin_to_list(Subject) -> list()</name> + <fsummary>Convert a binary to a list of integers</fsummary> + <type> + <v>Subject = binary()</v> + </type> + <desc> + <p>The same as <c>bin_to_list(Subject,{0,byte_size(Subject)})</c>.</p> + </desc> + </func> + <func> + <name>bin_to_list(Subject, PosLen) -> list()</name> + <fsummary>Convert a binary to a list of integers</fsummary> + <type> + <v>Subject = binary()</v> + <v>PosLen = part()</v> + </type> + <desc> + + <p>Converts <c>Subject</c> to a list of <c>int()</c>s, each representing + the value of one byte. The <c>part()</c> denotes which part of the + <c>binary()</c> to convert. Example:</p> + +<code> +1> binary:bin_to_list(<<"erlang">>,{1,3}). +"rla" +%% or [114,108,97] in list notation. +</code> + <p>If <c>PosLen</c> in any way references outside the binary, a <c>badarg</c> exception is raised.</p> + </desc> + </func> + <func> + <name>bin_to_list(Subject, Pos, Len) -> list()</name> + <fsummary>Convert a binary to a list of integers</fsummary> + <type> + <v>Subject = binary()</v> + <v>Pos = int()</v> + <v>Len = int()</v> + </type> + <desc> + <p>The same as<c> bin_to_list(Subject,{Pos,Len})</c>.</p> + </desc> + </func> + <func> + <name>compile_pattern(Pattern) -> cp()</name> + <fsummary>Pre-compiles a binary search pattern</fsummary> + <type> + <v>Pattern = binary() | [ binary() ]</v> + </type> + <desc> + + <p>Builds an internal structure representing a compilation of a + search-pattern, later to be used in the <seealso marker="#match-3">match/3</seealso>, + <seealso marker="#matches-3">matches/3</seealso>, + <seealso marker="#split-3">split/3</seealso> or + <seealso marker="#replace-4">replace/4</seealso> + functions. The <c>cp()</c> returned is guaranteed to be a + <c>tuple()</c> to allow programs to distinguish it from non + pre-compiled search patterns</p> + + <p>When a list of binaries is given, it denotes a set of + alternative binaries to search for. I.e if + <c>[<<"functional">>,<<"programming">>]</c> + is given as <c>Pattern</c>, this + means "either <c><<"functional">></c> or + <c><<"programming">></c>". The pattern is a set of + alternatives; when only a single binary is given, the set has + only one element. The order of alternatives in a pattern is not significant.</p> + + <p>The list of binaries used for search alternatives shall be flat and proper.</p> + + <p>If <c>Pattern</c> is not a binary or a flat proper list of binaries with length > 0, + a <c>badarg</c> exception will be raised.</p> + + </desc> + </func> + <func> + <name>copy(Subject) -> binary()</name> + <fsummary>Creates a duplicate of a binary</fsummary> + <type> + <v>Subject = binary()</v> + </type> + <desc> + <p>The same as <c>copy(Subject, 1)</c>.</p> + </desc> + </func> + <func> + <name>copy(Subject,N) -> binary()</name> + <fsummary>Duplicates a binary N times and creates a new</fsummary> + <type> + <v>Subject = binary()</v> + <v>N = int() >= 0</v> + </type> + <desc> + <p>Creates a binary with the content of <c>Subject</c> duplicated <c>N</c> times.</p> + + <p>This function will always create a new binary, even if <c>N = + 1</c>. By using <c>copy/1</c> on a binary referencing a larger binary, one + might free up the larger binary for garbage collection.</p> + + <note> + <p>By deliberately copying a single binary to avoid referencing + a larger binary, one might, instead of freeing up the larger + binary for later garbage collection, create much more binary + data than needed. Sharing binary data is usually good. Only in + special cases, when small parts reference large binaries and the + large binaries are no longer used in any process, deliberate + copying might be a good idea.</p> </note> + + <p>If <c>N</c> < <c>0</c>, a <c>badarg</c> exception is raised.</p> + </desc> + </func> + <func> + <name>decode_unsigned(Subject) -> Unsigned</name> + <fsummary>Decode a whole binary into an integer of arbitrary size</fsummary> + <type> + <v>Subject = binary()</v> + <v>Unsigned = int() >= 0</v> + </type> + <desc> + <p>The same as <c>decode_unsigned(Subject,big)</c>.</p> + </desc> + </func> + <func> + <name>decode_unsigned(Subject, Endianess) -> Unsigned</name> + <fsummary>Decode a whole binary into an integer of arbitrary size</fsummary> + <type> + <v>Subject = binary()</v> + <v>Endianess = big | little</v> + <v>Unsigned = int() >= 0</v> + </type> + <desc> + + <p>Converts the binary digit representation, in big or little + endian, of a positive integer in <c>Subject</c> to an Erlang <c>int()</c>.</p> + + <p>Example:</p> + + <code> +1> binary:decode_unsigned(<<169,138,199>>,big). +11111111 + </code> + </desc> + </func> + <func> + <name>encode_unsigned(Unsigned) -> binary()</name> + <fsummary>Encodes an unsigned integer into the minimal binary</fsummary> + <type> + <v>Unsigned = int() >= 0</v> + </type> + <desc> + <p>The same as <c>encode_unsigned(Unsigned,big)</c>.</p> + </desc> + </func> + <func> + <name>encode_unsigned(Unsigned,Endianess) -> binary()</name> + <fsummary>Encodes an unsigned integer into the minimal binary</fsummary> + <type> + <v>Unsigned = int() >= 0</v> + <v>Endianess = big | little</v> + </type> + <desc> + + <p>Converts a positive integer to the smallest possible + representation in a binary digit representation, either big + or little endian.</p> + + <p>Example:</p> + + <code> +1> binary:encode_unsigned(11111111,big). +<<169,138,199>> + </code> + </desc> + </func> + <func> + <name>first(Subject) -> int()</name> + <fsummary>Returns the first byte of a binary</fsummary> + <type> + <v>Subject = binary()</v> + </type> + <desc> + + <p>Returns the first byte of the binary <c>Subject</c> as an integer. If the + size of <c>Subject</c> is zero, a <c>badarg</c> exception is raised.</p> + + </desc> + </func> + <func> + <name>last(Subject) -> int()</name> + <fsummary>Returns the last byte of a binary</fsummary> + <type> + <v>Subject = binary()</v> + </type> + <desc> + + <p>Returns the last byte of the binary <c>Subject</c> as an integer. If the + size of <c>Subject</c> is zero, a <c>badarg</c> exception is raised.</p> + + </desc> + </func> + <func> + <name>list_to_bin(ByteList) -> binary()</name> + <fsummary>Convert a list of integers and binaries to a binary</fsummary> + <type> + <v>ByteList = iodata() (see module erlang)</v> + </type> + <desc> + <p>Works exactly as <c>erlang:list_to_binary/1</c>, added for completeness.</p> + </desc> + </func> + <func> + <name>longest_common_prefix(Binaries) -> int()</name> + <fsummary>Returns length of longest common prefix for a set of binaries</fsummary> + <type> + <v>Binaries = [ binary() ]</v> + </type> + <desc> + + <p>Returns the length of the longest common prefix of the + binaries in the list <c>Binaries</c>. Example:</p> + +<code> +1> binary:longest_common_prefix([<<"erlang">>,<<"ergonomy">>]). +2 +2> binary:longest_common_prefix([<<"erlang">>,<<"perl">>]). +0 +</code> + + <p>If <c>Binaries</c> is not a flat list of binaries, a <c>badarg</c> exception is raised.</p> + </desc> + </func> + <func> + <name>longest_common_suffix(Binaries) -> int()</name> + <fsummary>Returns length of longest common suffix for a set of binaries</fsummary> + <type> + <v>Binaries = [ binary() ]</v> + </type> + <desc> + + <p>Returns the length of the longest common suffix of the + binaries in the list <c>Binaries</c>. Example:</p> + +<code> +1> binary:longest_common_suffix([<<"erlang">>,<<"fang">>]). +3 +2> binary:longest_common_suffix([<<"erlang">>,<<"perl">>]). +0 +</code> + + <p>If <c>Binaries</c> is not a flat list of binaries, a <c>badarg</c> exception is raised.</p> + + </desc> + </func> + <func> + <name>match(Subject, Pattern) -> Found | <c>nomatch</c></name> + <fsummary>Searches for the first match of a pattern in a binary</fsummary> + <type> + <v>Subject = binary()</v> + <v>Pattern = binary() | [ binary() ] | cp()</v> + <v>Found = part()</v> + </type> + <desc> + <p>The same as <c>match(Subject, Pattern, [])</c>.</p> + </desc> + </func> + <func> + <name>match(Subject,Pattern,Options) -> Found | <c>nomatch</c></name> + <fsummary>Searches for the first match of a pattern in a binary</fsummary> + <type> + <v>Subject = binary()</v> + <v>Pattern = binary() | [ binary() ] | cp()</v> + <v>Found = part()</v> + <v>Options = [ Option ]</v> + <v>Option = {scope, part()}</v> + </type> + <desc> + + <p>Searches for the first occurrence of <c>Pattern</c> in <c>Subject</c> and + returns the position and length.</p> + + <p>The function will return <c>{Pos,Length}</c> for the binary + in <c>Pattern</c> starting at the lowest position in + <c>Subject</c>, Example:</p> + +<code> +1> binary:match(<<"abcde">>, [<<"bcde">>,<<"cd">>],[]). +{1,4} +</code> + + <p>Even though <c><<"cd">></c> ends before + <c><<"bcde">></c>, <c><<"bcde">></c> + begins first and is therefore the first match. If two + overlapping matches begin at the same position, the longest is + returned.</p> + + <p>Summary of the options:</p> + + <taglist> + <tag>{scope, {Start, Length}}</tag> + <item><p>Only the given part is searched. Return values still have + offsets from the beginning of <c>Subject</c>. A negative <c>Length</c> is + allowed as described in the <c>TYPES</c> section of this manual.</p></item> + </taglist> + + <p>If none of the strings in + <c>Pattern</c> is found, the atom <c>nomatch</c> is returned.</p> + + <p>For a description of <c>Pattern</c>, see + <seealso marker="#compile_pattern-1">compile_pattern/1</seealso>.</p> + + <p>If <c>{scope, {Start,Length}}</c> is given in the options + such that <c>Start</c> is larger than the size of + <c>Subject</c>, <c>Start + Length</c> is less than zero or + <c>Start + Length</c> is larger than the size of + <c>Subject</c>, a <c>badarg</c> exception is raised.</p> + + </desc> + </func> + <func> + <name>matches(Subject, Pattern) -> Found</name> + <fsummary>Searches for all matches of a pattern in a binary</fsummary> + <type> + <v>Subject = binary()</v> + <v>Pattern = binary() | [ binary() ] | cp()</v> + <v>Found = [ part() ] | []</v> + </type> + <desc> + <p>The same as <c>matches(Subject, Pattern, [])</c>.</p> + </desc> + </func> + <func> + <name>matches(Subject,Pattern,Options) -> Found</name> + <fsummary>Searches for all matches of a pattern in a binary</fsummary> + <type> + <v>Subject = binary()</v> + <v>Pattern = binary() | [ binary() ] | cp()</v> + <v>Found = [ part() ] | []</v> + <v>Options = [ Option ]</v> + <v>Option = {scope, part()}</v> + </type> + <desc> + + <p>Works like match, but the <c>Subject</c> is searched until + exhausted and a list of all non-overlapping parts matching + <c>Pattern</c> is returned (in order). </p> + + <p>The first and longest match is preferred to a shorter, + which is illustrated by the following example:</p> + +<code> +1> binary:matches(<<"abcde">>, + [<<"bcde">>,<<"bc">>>,<<"de">>],[]). +[{1,4}] +</code> + + <p>The result shows that <<bcde">> is selected instead of the + shorter match <<"bc">> (which would have given raise to one + more match,<<"de">>). This corresponds to the behavior of posix + regular expressions (and programs like awk), but is not + consistent with alternative matches in re (and Perl), where + instead lexical ordering in the search pattern selects which + string matches.</p> + + <p>If none of the strings in pattern is found, an empty list is returned.</p> + + <p>For a description of <c>Pattern</c>, see <seealso marker="#compile_pattern-1">compile_pattern/1</seealso> and for a + description of available options, see <seealso marker="#match-3">match/3</seealso>.</p> + + <p>If <c>{scope, {Start,Length}}</c> is given in the options such that + <c>Start</c> is larger than the size of <c>Subject</c>, <c>Start + Length</c> is + less than zero or <c>Start + Length</c> is larger than the size of + <c>Subject</c>, a <c>badarg</c> exception is raised.</p> + + </desc> + </func> + <func> + <name>part(Subject, PosLen) -> binary()</name> + <fsummary>Extracts a part of a binary</fsummary> + <type> + <v>Subject = binary()</v> + <v>PosLen = part()</v> + </type> + <desc> + + <p>Extracts the part of the binary <c>Subject</c> described by <c>PosLen</c>.</p> + + <p>Negative length can be used to extract bytes at the end of a binary:</p> + +<code> +1> Bin = <<1,2,3,4,5,6,7,8,9,10>>. +2> binary:part(Bin,{byte_size(Bin), -5)). +<<6,7,8,9,10>> +</code> + + <note> + <p><seealso marker="#part-2">part/2</seealso>and <seealso + marker="#part-3">part/3</seealso> are also available in the + <c>erlang</c> module under the names <c>binary_part/2</c> and + <c>binary_part/3</c>. Those BIFs are allowed in guard tests.</p> + </note> + + <p>If <c>PosLen</c> in any way references outside the binary, a <c>badarg</c> exception + is raised.</p> + + </desc> + </func> + <func> + <name>part(Subject, Pos, Len) -> binary()</name> + <fsummary>Extracts a part of a binary</fsummary> + <type> + <v>Subject = binary()</v> + <v>Pos = int()</v> + <v>Len = int()</v> + </type> + <desc> + <p>The same as <c>part(Subject, {Pos, Len})</c>.</p> + </desc> + </func> + <func> + <name>referenced_byte_size(binary()) -> int()</name> + <fsummary>Determines the size of the actual binary pointed out by a sub-binary</fsummary> + <desc> + + <p>If a binary references a larger binary (often described as + being a sub-binary), it can be useful to get the size of the + actual referenced binary. This function can be used in a program + to trigger the use of <c>copy/1</c>. By copying a binary, one might + dereference the original, possibly large, binary which a smaller + binary is a reference to.</p> + + <p>Example:</p> + + <code> +store(Binary, GBSet) -> + NewBin = + case binary:referenced_byte_size(Binary) of + Large when Large > 2 * byte_size(Binary) -> + binary:copy(Binary); + _ -> + Binary + end, + gb_sets:insert(NewBin,GBSet). + </code> + + <p>In this example, we chose to copy the binary content before + inserting it in the <c>gb_set()</c> if it references a binary more than + twice the size of the data we're going to keep. Of course + different rules for when copying will apply to different + programs.</p> + + <p>Binary sharing will occur whenever binaries are taken apart, + this is the fundamental reason why binaries are fast, + decomposition can always be done with O(1) complexity. In rare + circumstances this data sharing is however undesirable, why this + function together with <c>copy/1</c> might be useful when optimizing + for memory use.</p> + + <p>Example of binary sharing:</p> + + <code> +1> A = binary:copy(<<1>>,100). +<<1,1,1,1,1 ... +2> byte_size(A). +100 +3> binary:referenced_byte_size(A) +100 +4> <<_:10/binary,B:10/binary,_/binary>> = A. +<<1,1,1,1,1 ... +5> byte_size(B). +10 +6> binary:referenced_byte_size(B) +100 + </code> + + <note> + <p>Binary data is shared among processes. If another process + still references the larger binary, copying the part this + process uses only consumes more memory and will not free up the + larger binary for garbage collection. Use this kind of intrusive + functions with extreme care, and only if a real problem is + detected.</p> + </note> + + </desc> + </func> + <func> + <name>replace(Subject,Pattern,Replacement) -> Result</name> + <fsummary>Replaces bytes in a binary according to a pattern</fsummary> + <type> + <v>Subject = binary()</v> + <v>Pattern = binary() | [ binary() ] | cp()</v> + <v>Replacement = binary()</v> + <v>Result = binary()</v> + </type> + <desc> + <p>The same as <c>replace(Subject,Pattern,Replacement,[])</c>.</p> + </desc> + </func> + <func> + <name>replace(Subject,Pattern,Replacement,Options) -> Result</name> + <fsummary>Replaces bytes in a binary according to a pattern</fsummary> + <type> + <v>Subject = binary()</v> + <v>Pattern = binary() | [ binary() ] | cp()</v> + <v>Replacement = binary()</v> + <v>Result = binary()</v> + <v>Options = [ Option ]</v> + <v>Option = global | {scope, part()} | {insert_replaced, InsPos}</v> + <v>InsPos = OnePos | [ OnePos ]</v> + <v>OnePos = int() =< byte_size(Replacement)</v> + </type> + <desc> + + <p>Constructs a new binary by replacing the parts in + <c>Subject</c> matching <c>Pattern</c> with the content of + <c>Replacement</c>.</p> + + <p>If the matching sub-part of <c>Subject</c> giving raise to the + replacement is to be inserted in the result, the option + <c>{insert_replaced, InsPos}</c> will insert the matching part into + <c>Replacement</c> at the given position (or positions) before actually + inserting <c>Replacement</c> into the <c>Subject</c>. Example:</p> + +<code> +1> binary:replace(<<"abcde">>,<<"b">>,<<"[]">>,[{insert_replaced,1}]). +<<"a[b]cde">> +2> binary:replace(<<"abcde">>,[<<"b">>,<<"d">>],<<"[]">>, + [global,{insert_replaced,1}]). +<<"a[b]c[d]e">> +3> binary:replace(<<"abcde">>,[<<"b">>,<<"d">>],<<"[]">>, + [global,{insert_replaced,[1,1]}]). +<<"a[bb]c[dd]e">> +4> binary:replace(<<"abcde">>,[<<"b">>,<<"d">>],<<"[-]">>, + [global,{insert_replaced,[1,2]}]). +<<"a[b-b]c[d-d]e">> +</code> + + <p>If any position given in <c>InsPos</c> is greater than the size of the replacement binary, a <c>badarg</c> exception is raised.</p> + + <p>The options <c>global</c> and <c>{scope, part()}</c> work as for <seealso marker="#split-3">split/3</seealso>. The return type is always a <c>binary()</c>.</p> + + <p>For a description of <c>Pattern</c>, see <seealso marker="#compile_pattern-1">compile_pattern/1</seealso>.</p> + </desc> + </func> + <func> + <name>split(Subject,Pattern) -> Parts</name> + <fsummary>Splits a binary according to a pattern</fsummary> + <type> + <v>Subject = binary()</v> + <v>Pattern = binary() | [ binary() ] | cp()</v> + <v>Parts = [ binary() ]</v> + </type> + <desc> + <p>The same as <c>split(Subject, Pattern, [])</c>.</p> + </desc> + </func> + <func> + <name>split(Subject,Pattern,Options) -> Parts</name> + <fsummary>Splits a binary according to a pattern</fsummary> + <type> + <v>Subject = binary()</v> + <v>Pattern = binary() | [ binary() ] | cp()</v> + <v>Parts = [ binary() ]</v> + <v>Options = [ Option ]</v> + <v>Option = {scope, part()} | trim | global</v> + </type> + <desc> + + <p>Splits Binary into a list of binaries based on Pattern. If + the option global is not given, only the first occurrence of + Pattern in Subject will give rise to a split.</p> + + <p>The parts of Pattern actually found in Subject are not included in the result.</p> + + <p>Example:</p> + +<code> +1> binary:split(<<1,255,4,0,0,0,2,3>>, [<<0,0,0>>,<<2>>],[]). +[<<1,255,4>>, <<2,3>>] +2> binary:split(<<0,1,0,0,4,255,255,9>>, [<<0,0>>, <<255,255>>],[global]). +[<<0,1>>,<<4>>,<<9>>] +</code> + + <p>Summary of options:</p> + <taglist> + + <tag>{scope, part()}</tag> + + <item><p>Works as in <seealso marker="#match-3">match/3</seealso> and + <seealso marker="#matches-3">matches/3</seealso>. Note that + this only defines the scope of the search for matching strings, + it does not cut the binary before splitting. The bytes before + and after the scope will be kept in the result. See example + below.</p></item> + + <tag>trim</tag> + + <item><p>Removes trailing empty parts of the result (as does trim in <c>re:split/3</c>)</p></item> + + <tag>global</tag> + + <item><p>Repeats the split until the <c>Subject</c> is + exhausted. Conceptually the global option makes split work on + the positions returned by <seealso marker="#matches-3">matches/3</seealso>, + while it normally + works on the position returned by + <seealso marker="#match-3">match/3</seealso>.</p></item> + + </taglist> + + <p>Example of the difference between a scope and taking the + binary apart before splitting:</p> + +<code> +1> binary:split(<<"banana">>,[<<"a">>],[{scope,{2,3}}]). +[<<"ban">>,<<"na">>] +2> binary:split(binary:part(<<"banana">>,{2,3}),[<<"a">>],[]). +[<<"n">>,<<"n">>] +</code> + + <p>The return type is always a list of binaries that are all + referencing <c>Subject</c>. This means that the data in <c>Subject</c> is not + actually copied to new binaries and that <c>Subject</c> cannot be + garbage collected until the results of the split are no longer + referenced.</p> + + <p>For a description of <c>Pattern</c>, see <seealso marker="#compile_pattern-1">compile_pattern/1</seealso>.</p> + + </desc> + </func> + </funcs> +</erlref> 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/erl_id_trans.xml b/lib/stdlib/doc/src/erl_id_trans.xml index 7c821d2efc..cfb18ec131 100644 --- a/lib/stdlib/doc/src/erl_id_trans.xml +++ b/lib/stdlib/doc/src/erl_id_trans.xml @@ -5,7 +5,7 @@ <header> <copyright> <year>1996</year> - <year>2007</year> + <year>2010</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> @@ -70,7 +70,8 @@ <section> <title>See Also</title> - <p><seealso marker="erl_parse">erl_parse(3)</seealso>, compile(3).</p> + <p><seealso marker="erl_parse">erl_parse(3)</seealso>, + <seealso marker="compiler:compile">compile(3)</seealso>.</p> </section> </erlref> diff --git a/lib/stdlib/doc/src/erl_lint.xml b/lib/stdlib/doc/src/erl_lint.xml index 6a7d37765c..8639d678fa 100644 --- a/lib/stdlib/doc/src/erl_lint.xml +++ b/lib/stdlib/doc/src/erl_lint.xml @@ -96,8 +96,8 @@ <p>The <c>AbsForms</c> of a module which comes from a file that is read through <c>epp</c>, the Erlang pre-processor, can come from many files. This means that any references to - errors must include the file name (see <seealso marker="epp">epp(3)</seealso>, or parser <seealso marker="erl_parse">erl_parse(3)</seealso> The warnings and - errors returned have the following format: + errors must include the file name (see <seealso marker="epp">epp(3)</seealso>, or parser <seealso marker="erl_parse">erl_parse(3)</seealso>). + The warnings and errors returned have the following format: </p> <code type="none"> [{FileName2,[ErrorInfo]}] </code> diff --git a/lib/stdlib/doc/src/erl_parse.xml b/lib/stdlib/doc/src/erl_parse.xml index ae8a8afd5c..18b592deea 100644 --- a/lib/stdlib/doc/src/erl_parse.xml +++ b/lib/stdlib/doc/src/erl_parse.xml @@ -39,7 +39,7 @@ expressions, or terms. The Abstract Format is described in the ERTS User's Guide. Note that a token list must end with the <em>dot</em> token in order - to be acceptable to the parse functions (see erl_scan).</p> + to be acceptable to the parse functions (see <seealso marker="erl_scan">erl_scan(3)</seealso>).</p> </description> <funcs> <func> diff --git a/lib/stdlib/doc/src/erl_scan.xml b/lib/stdlib/doc/src/erl_scan.xml index 4175146c3c..1199c34f0f 100644 --- a/lib/stdlib/doc/src/erl_scan.xml +++ b/lib/stdlib/doc/src/erl_scan.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2009</year> + <year>1996</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>erl_scan</title> @@ -103,7 +103,7 @@ attributes() = line() | list() | tuple()</code> Info, atom()}</c>, <c>{char, Info, integer()}</c>, <c>{comment, Info, string()}</c>, <c>{float, Info, float()}</c>, <c>{integer, - Info, integer()}</c>, <c>{var, Info, atom()}</c>, + Info, integer()}</c>, <c>{var, Info, atom()}</c>, and <c>{white_space, Info, string()}</c>.</p> <p>The valid options are:</p> <taglist> @@ -149,7 +149,8 @@ attributes() = line() | list() | tuple()</code> <v>StartLocation = EndLocation = location()</v> <v>Options = Option | [Option]</v> <v>Option = {reserved_word_fun,reserved_word_fun()} - | return_comments | return_white_spaces | return</v> + | return_comments | return_white_spaces | return + | text</v> </type> <desc> <p>This is the re-entrant scanner which scans characters until @@ -173,7 +174,7 @@ attributes() = line() | list() | tuple()</code> <tag><c>{error, ErrorInfo, EndLocation}</c></tag> <item> <p>An error occurred. <c>LeftOverChars</c> is the remaining - characters of the input data, + characters of the input data, starting from <c>EndLocation</c>.</p> </item> </taglist> @@ -278,7 +279,7 @@ attributes() = line() | list() | tuple()</code> <item><p>The token's symbol.</p> </item> <tag><c>{text, string()}</c></tag> - <item><p>The token's text..</p> + <item><p>The token's text.</p> </item> </taglist> </desc> @@ -315,7 +316,7 @@ attributes() = line() | list() | tuple()</code> <type> <v>Attributes = attributes()</v> <v>AttributeItemSpec = AttributeItem | [AttributeItem]</v> - <v>AttributesInfo = AttributeInfoTuple | undefined + <v>AttributesInfo = AttributeInfoTuple | undefined | [AttributeInfoTuple]</v> <v>AttributeInfoTuple = {AttributeItem, Info}</v> <v>AttributeItem = atom()</v> @@ -352,7 +353,7 @@ attributes() = line() | list() | tuple()</code> just the line if the column unknown.</p> </item> <tag><c>{text, string()}</c></tag> - <item><p>The token's text..</p> + <item><p>The token's text.</p> </item> </taglist> </desc> diff --git a/lib/stdlib/doc/src/ets.xml b/lib/stdlib/doc/src/ets.xml index 7b9f0e7772..dd4a289c61 100644 --- a/lib/stdlib/doc/src/ets.xml +++ b/lib/stdlib/doc/src/ets.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2009</year> + <year>1996</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>ets</title> @@ -1039,15 +1039,22 @@ ets:select(Table,MatchSpec),</code> the owner terminates.</p> </item> <item> + <marker id="new_2_write_concurrency"></marker> <p><c>{write_concurrency,bool()}</c> - Performance tuning. Default is <c>false</c>, which means that the table - is optimized towards concurrent read access. An operation that + Performance tuning. Default is <c>false</c>. An operation that mutates (writes to) the table will obtain exclusive access, blocking any concurrent access of the same table until finished. If set to <c>true</c>, the table is optimized towards concurrent write access. Different objects of the same table can be mutated (and read) by concurrent processes. This is achieved to some degree at the expense of single access and concurrent reader performance. + The <c>write_concurrency</c> option can be combined with the + <seealso marker="#new_2_read_concurrency">read_concurrency</seealso> + option. You typically want to combine these when large concurrent + read bursts and large concurrent write bursts are common (see the + documentation of the + <seealso marker="#new_2_read_concurrency">read_concurrency</seealso> + option for more information). Note that this option does not change any guarantees about <seealso marker="#concurrency">atomicy and isolation</seealso>. Functions that makes such promises over several objects (like @@ -1055,6 +1062,29 @@ ets:select(Table,MatchSpec),</code> <p>Table type <c>ordered_set</c> is not affected by this option in current implementation.</p> </item> + <item> + <marker id="new_2_read_concurrency"></marker> + <p><c>{read_concurrency,bool()}</c> + Performance tuning. Default is <c>false</c>. When set to + <c>true</c>, the table is optimized for concurrent read + operations. When this option is enabled on a runtime system with + SMP support, read operations become much cheaper; especially on + systems with multiple physical processors. However, switching + between read and write operations becomes more expensive. You + typically want to enable this option when concurrent read + operations are much more frequent than write operations, or when + concurrent reads and writes comes in large read and write + bursts (i.e., lots of reads not interrupted by writes, and lots + of writes not interrupted by reads). You typically do + <em>not</em> want to enable this option when the common access + pattern is a few read operations interleaved with a few write + operations repeatedly. In this case you will get a performance + degradation by enabling this option. The <c>read_concurrency</c> + option can be combined with the + <seealso marker="#new_2_write_concurrency">write_concurrency</seealso> + option. You typically want to combine these when large concurrent + read bursts and large concurrent write bursts are common.</p> + </item> </list> </desc> </func> @@ -1355,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> @@ -1381,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> @@ -1686,7 +1795,7 @@ true</pre> </desc> </func> <func> - <name>to_dets(Tab, DetsTab) -> Tab</name> + <name>to_dets(Tab, DetsTab) -> DetsTab</name> <fsummary>Fill a Dets table with objects from an ETS table.</fsummary> <type> <v>Tab = tid() | atom()</v> diff --git a/lib/stdlib/doc/src/filename.xml b/lib/stdlib/doc/src/filename.xml index 0cf82fa48b..fe6c6f898e 100644 --- a/lib/stdlib/doc/src/filename.xml +++ b/lib/stdlib/doc/src/filename.xml @@ -49,7 +49,7 @@ <title>DATA TYPES</title> <code type="none"> name() = string() | atom() | DeepList - DeepList = [char() | atom() | DeepList]</code> +DeepList = [char() | atom() | DeepList]</code> </section> <funcs> <func> diff --git a/lib/stdlib/doc/src/gen_event.xml b/lib/stdlib/doc/src/gen_event.xml index df09294de6..2234a62ac3 100644 --- a/lib/stdlib/doc/src/gen_event.xml +++ b/lib/stdlib/doc/src/gen_event.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2009</year> + <year>1996</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>gen_event</title> @@ -630,12 +630,66 @@ gen_event:stop -----> Module:terminate/2 <p>The function should return the updated internal state.</p> </desc> </func> + <func> + <name>Module:format_status(Opt, [PDict, State]) -> Status</name> + <fsummary>Optional function for providing a term describing the + current event handler state.</fsummary> + <type> + <v>Opt = normal | terminate</v> + <v>PDict = [{Key, Value}]</v> + <v>State = term()</v> + <v>Status = term()</v> + </type> + <desc> + <note> + <p>This callback is optional, so event handler modules need + not export it. If a handler does not export this function, + the gen_event module uses the handler state directly for + the purposes described below.</p> + </note> + <p>This function is called by a gen_event process when:</p> + <list typed="bulleted"> + <item>One + of <seealso marker="sys#get_status/1">sys:get_status/1,2</seealso> + is invoked to get the gen_event status. <c>Opt</c> is set + to the atom <c>normal</c> for this case.</item> + <item>The event handler terminates abnormally and gen_event + logs an error. <c>Opt</c> is set to the + atom <c>terminate</c> for this case.</item> + </list> + <p>This function is useful for customising the form and + appearance of the event handler state for these cases. An + event handler callback module wishing to customise + the <c>sys:get_status/1,2</c> return value as well as how + its state appears in termination error logs exports an + instance of <c>format_status/2</c> that returns a term + describing the current state of the event handler.</p> + <p><c>PDict</c> is the current value of the gen_event's + process dictionary.</p> + <p><c>State</c> is the internal state of the event + handler.</p> + <p>The function should return <c>Status</c>, a term that + customises the details of the current state of the event + handler. Any term is allowed for <c>Status</c>. The + gen_event module uses <c>Status</c> as follows:</p> + <list typed="bulleted"> + <item>When <c>sys:get_status/1,2</c> is called, gen_event + ensures that its return value contains <c>Status</c> in + place of the event handler's actual state term.</item> + <item>When an event handler terminates abnormally, gen_event + logs <c>Status</c> in place of the event handler's actual + state term.</item> + </list> + <p>One use for this function is to return compact alternative + state representations to avoid having large state terms + printed in logfiles.</p> + </desc> + </func> </funcs> <section> <title>SEE ALSO</title> - <p><seealso marker="supervisor">supervisor(3)</seealso>, + <p><seealso marker="supervisor">supervisor(3)</seealso>, <seealso marker="sys">sys(3)</seealso></p> </section> </erlref> - diff --git a/lib/stdlib/doc/src/gen_fsm.xml b/lib/stdlib/doc/src/gen_fsm.xml index 739cd0bffd..d15383c621 100644 --- a/lib/stdlib/doc/src/gen_fsm.xml +++ b/lib/stdlib/doc/src/gen_fsm.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2009</year> + <year>1996</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>gen_fsm</title> @@ -730,33 +730,58 @@ gen_fsm:sync_send_all_state_event -----> Module:handle_sync_event/4 </desc> </func> <func> - <name>Module:format_status(normal, [PDict, StateData]) -> Status</name> + <name>Module:format_status(Opt, [PDict, StateData]) -> Status</name> <fsummary>Optional function for providing a term describing the current gen_fsm status.</fsummary> <type> + <v>Opt = normal | terminate</v> <v>PDict = [{Key, Value}]</v> <v>StateData = term()</v> - <v>Status = [term()]</v> + <v>Status = term()</v> </type> <desc> - <p><em>This callback is optional, so callback modules need not - export it. The gen_fsm module provides a default - implementation of this function that returns the callback - module state data.</em></p> - <p>This function is called by a gen_fsm process when one - of <seealso marker="sys#get_status/1">sys:get_status/1,2</seealso> - is invoked to get the gen_fsm status. A callback module - wishing to customise the <c>sys:get_status/1,2</c> return - value exports an instance of <c>format_status/2</c> that - returns a term describing the current status of the - gen_fsm.</p> + <note> + <p>This callback is optional, so callback modules need not + export it. The gen_fsm module provides a default + implementation of this function that returns the callback + module state data.</p> + </note> + <p>This function is called by a gen_fsm process when:</p> + <list typed="bulleted"> + <item>One + of <seealso marker="sys#get_status/1">sys:get_status/1,2</seealso> + is invoked to get the gen_fsm status. <c>Opt</c> is set to + the atom <c>normal</c> for this case.</item> + <item>The gen_fsm terminates abnormally and logs an + error. <c>Opt</c> is set to the atom <c>terminate</c> for + this case.</item> + </list> + <p>This function is useful for customising the form and + appearance of the gen_fsm status for these cases. A callback + module wishing to customise the <c>sys:get_status/1,2</c> + return value as well as how its status appears in + termination error logs exports an instance + of <c>format_status/2</c> that returns a term describing the + current status of the gen_fsm.</p> <p><c>PDict</c> is the current value of the gen_fsm's process dictionary.</p> <p><c>StateData</c> is the internal state data of the gen_fsm.</p> - <p>The function should return <c>Status</c>, a list of one or - more terms that customise the details of the current state - and status of the gen_fsm.</p> + <p>The function should return <c>Status</c>, a term that + customises the details of the current state and status of + the gen_fsm. There are no restrictions on the + form <c>Status</c> can take, but for + the <c>sys:get_status/1,2</c> case (when <c>Opt</c> + is <c>normal</c>), the recommended form for + the <c>Status</c> value is <c>[{data, [{"StateData", + Term}]}]</c> where <c>Term</c> provides relevant details of + the gen_fsm state data. Following this recommendation isn't + required, but doing so will make the callback module status + consistent with the rest of the <c>sys:get_status/1,2</c> + return value.</p> + <p>One use for this function is to return compact alternative + state data representations to avoid having large state terms + printed in logfiles.</p> </desc> </func> </funcs> @@ -770,4 +795,3 @@ gen_fsm:sync_send_all_state_event -----> Module:handle_sync_event/4 <seealso marker="sys">sys(3)</seealso></p> </section> </erlref> - diff --git a/lib/stdlib/doc/src/gen_server.xml b/lib/stdlib/doc/src/gen_server.xml index 30c04d1d52..1045766e01 100644 --- a/lib/stdlib/doc/src/gen_server.xml +++ b/lib/stdlib/doc/src/gen_server.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2009</year> + <year>1996</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>gen_server</title> @@ -599,32 +599,57 @@ gen_server:abcast -----> Module:handle_cast/2 </desc> </func> <func> - <name>Module:format_status(normal, [PDict, State]) -> Status</name> + <name>Module:format_status(Opt, [PDict, State]) -> Status</name> <fsummary>Optional function for providing a term describing the current gen_server status.</fsummary> <type> + <v>Opt = normal | terminate</v> <v>PDict = [{Key, Value}]</v> <v>State = term()</v> - <v>Status = [term()]</v> + <v>Status = term()</v> </type> <desc> - <p><em>This callback is optional, so callback modules need not - export it. The gen_server module provides a default - implementation of this function that returns the callback - module state.</em></p> - <p>This function is called by a gen_server process when one + <note> + <p>This callback is optional, so callback modules need not + export it. The gen_server module provides a default + implementation of this function that returns the callback + module state.</p> + </note> + <p>This function is called by a gen_server process when:</p> + <list typed="bulleted"> + <item>One of <seealso marker="sys#get_status/1">sys:get_status/1,2</seealso> - is invoked to get the gen_server status. A callback module - wishing to customise the <c>sys:get_status/1,2</c> return - value exports an instance of <c>format_status/2</c> that - returns a term describing the current status of the - gen_server.</p> + is invoked to get the gen_server status. <c>Opt</c> is set + to the atom <c>normal</c> for this case.</item> + <item>The gen_server terminates abnormally and logs an + error. <c>Opt</c> is set to the atom <c>terminate</c> for this + case.</item> + </list> + <p>This function is useful for customising the form and + appearance of the gen_server status for these cases. A + callback module wishing to customise + the <c>sys:get_status/1,2</c> return value as well as how + its status appears in termination error logs exports an + instance of <c>format_status/2</c> that returns a term + describing the current status of the gen_server.</p> <p><c>PDict</c> is the current value of the gen_server's process dictionary.</p> <p><c>State</c> is the internal state of the gen_server.</p> - <p>The function should return <c>Status</c>, a list of one or - more terms that customise the details of the current state - and status of the gen_server.</p> + <p>The function should return <c>Status</c>, a term that + customises the details of the current state and status of + the gen_server. There are no restrictions on the + form <c>Status</c> can take, but for + the <c>sys:get_status/1,2</c> case (when <c>Opt</c> + is <c>normal</c>), the recommended form for + the <c>Status</c> value is <c>[{data, [{"State", + Term}]}]</c> where <c>Term</c> provides relevant details of + the gen_server state. Following this recommendation isn't + required, but doing so will make the callback module status + consistent with the rest of the <c>sys:get_status/1,2</c> + return value.</p> + <p>One use for this function is to return compact alternative + state representations to avoid having large state terms + printed in logfiles.</p> </desc> </func> </funcs> diff --git a/lib/stdlib/doc/src/io_protocol.xml b/lib/stdlib/doc/src/io_protocol.xml index 201787f7b5..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 @@ -195,7 +195,7 @@ latin1, Module, Function, Args} respectively. </p> below).</p> <p>The function will be called with the data the io_server finds on - it's device, returning {done, Result, RestChars} when enough data is + its device, returning {done, Result, RestChars} when enough data is read (in which case Result is sent to the client and RestChars are kept in the io_server as a buffer for subsequent input) or {more, Continuation}, indicating that more characters are needed to @@ -741,7 +741,7 @@ optimize anything however. It is important though that the returned data is of the right type depending on the options set, so we convert the lists to binaries in the correct encoding <em>if possible</em> before returning. The function supplied in the get_until request may, -as it's final result return anything, so only functions actually +as its final result return anything, so only functions actually returning lists can get them converted to binaries. If the request contained the encoding tag unicode, the lists can contain all unicode codepoints and the binaries should be in UTF-8, if the encoding tag diff --git a/lib/stdlib/doc/src/lists.xml b/lib/stdlib/doc/src/lists.xml index 855a7e0244..92c4eb4f4c 100644 --- a/lib/stdlib/doc/src/lists.xml +++ b/lib/stdlib/doc/src/lists.xml @@ -48,7 +48,7 @@ <item><p>if x <c>F</c> y and y <c>F</c> x then x = y (<c>F</c> is antisymmetric);</p> </item> - <item><p>if x <c>F</c> y and and y <c>F</c> z then x <c>F</c> z + <item><p>if x <c>F</c> y and y <c>F</c> z then x <c>F</c> z (<c>F</c> is transitive);</p> </item> <item><p>x <c>F</c> y or y <c>F</c> x (<c>F</c> is total).</p> @@ -220,7 +220,7 @@ follows:</p> <code type="none"> flatmap(Fun, List1) -> - append(map(Fun, List1))</code> + append(map(Fun, List1)).</code> <p>Example:</p> <pre> > <input>lists:flatmap(fun(X)->[X,X] end, [a,b,c]).</input> @@ -443,7 +443,7 @@ flatmap(Fun, List1) -> <desc> <p>Returns a list containing the sorted elements of the list <c>TupleList1</c>. Sorting is performed on the <c>N</c>th - element of the tuples.</p> + element of the tuples. The sort is stable.</p> </desc> </func> <func> @@ -466,7 +466,7 @@ flatmap(Fun, List1) -> </desc> </func> <func> - <name>keytake(Key, N, TupleList1) -> {value, Tuple, TupleList2} + <name>keytake(Key, N, TupleList1) -> {value, Tuple, TupleList2} | false</name> <fsummary>Extract an element from a list of tuples</fsummary> <type> @@ -523,7 +523,7 @@ flatmap(Fun, List1) -> <v> A = B = term()</v> </type> <desc> - <p><c>mapfold</c> combines the operations of <c>map/2</c> and + <p><c>mapfoldl</c> combines the operations of <c>map/2</c> and <c>foldl/3</c> into one pass. An example, summing the elements in a list and double them at the same time:</p> <pre> @@ -543,7 +543,7 @@ flatmap(Fun, List1) -> <v> A = B = term()</v> </type> <desc> - <p><c>mapfold</c> combines the operations of <c>map/2</c> and + <p><c>mapfoldr</c> combines the operations of <c>map/2</c> and <c>foldr/3</c> into one pass.</p> </desc> </func> @@ -840,7 +840,7 @@ length(lists:seq(From, To, Incr)) == (To-From+Incr) div Incr</code> <c>Pred</c>. <c>splitwith/2</c> behaves as if it is defined as follows:</p> <code type="none"> -splitwith(Pred, List) -> +splitwith(Pred, List) -> {takewhile(Pred, List), dropwhile(Pred, List)}.</code> <p>Examples:</p> <pre> diff --git a/lib/stdlib/doc/src/ms_transform.xml b/lib/stdlib/doc/src/ms_transform.xml index 9f178b426c..ba9f89685b 100644 --- a/lib/stdlib/doc/src/ms_transform.xml +++ b/lib/stdlib/doc/src/ms_transform.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>2002</year><year>2009</year> + <year>2002</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>ms_transform</title> @@ -245,7 +245,7 @@ ets:select(emp_tab, ets:fun2ms( fun(#emp{empno = [$0 | Rest] }) -> {[$0|Rest],[$1|Rest]} end)). </code> - <p>As a matter of fact, this query hit's the feature of partially bound + <p>As a matter of fact, this query hits the feature of partially bound keys in the table type <c>ordered_set</c>, so that not the whole table need be searched, only the part of the table containing keys beginning with <c>0</c> is in fact looked into. </p> diff --git a/lib/stdlib/doc/src/notes.xml b/lib/stdlib/doc/src/notes.xml index c55eafc8b8..6c618bc798 100644 --- a/lib/stdlib/doc/src/notes.xml +++ b/lib/stdlib/doc/src/notes.xml @@ -30,6 +30,419 @@ </header> <p>This document describes the changes made to the STDLIB application.</p> +<section><title>STDLIB 1.17.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>reference() has been substituted for ref() in the + documentation.</p> + <p> + Own Id: OTP-8733</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The ms_transform now warns if the fun head shadows + surrounding variables (just like the warnings you would + get for an ordinary fun in the same context).</p> + <p> + Own Id: OTP-6759</p> + </item> + <item> + <p> + ets:select_reverse/{1,2,3} are now documented.</p> + <p> + Own Id: OTP-7863</p> + </item> + <item> + <p> + Large parts of the <c>ethread</c> library have been + rewritten. The <c>ethread</c> library is an Erlang + runtime system internal, portable thread library used by + the runtime system itself.</p> + <p> + Most notable improvement is a reader optimized rwlock + implementation which dramatically improve the performance + of read-lock/read-unlock operations on multi processor + systems by avoiding ping-ponging of the rwlock cache + lines. The reader optimized rwlock implementation is used + by miscellaneous rwlocks in the runtime system that are + known to be read-locked frequently, and can be enabled on + ETS tables by passing the <seealso + marker="stdlib:ets#new_2_read_concurrency">{read_concurrency, + true}</seealso> option upon table creation. See the + documentation of <seealso + marker="stdlib:ets#new/2">ets:new/2</seealso> for more + information. The reader optimized rwlock implementation + can be fine tuned when starting the runtime system. For + more information, see the documentation of the <seealso + marker="erts:erl#+rg">+rg</seealso> command line argument + of <c>erl</c>.</p> + <p> + There is also a new implementation of rwlocks that is not + optimized for readers. Both implementations interleaves + readers and writers during contention as opposed to, + e.g., the NPTL (Linux) pthread rwlock implementation + which use either a reader or writer preferred strategy. + The reader/writer preferred strategy is problematic since + it starves threads doing the non-preferred operation.</p> + <p> + The new rwlock implementations in general performs better + in ERTS than common pthread implementations. However, in + some extremely heavily contended cases this is not the + case. Such heavy contention can more or less only appear + on ETS tables. This when multiple processes do very large + amounts of write locked operations simultaneously on the + same table. Such use of ETS is bad regardless of rwlock + implementation, will never scale, and is something we + strongly advise against.</p> + <p> + The new rwlock implementations depend on atomic + operations. If no native atomic implementation is found, + a fallback solution will be used. Using the fallback + implies a performance degradation. That is, it is more + important now than before to build OTP with a native + atomic implementation.</p> + <p> + The <c>ethread</c> library contains native atomic + implementations for, x86 (32 and 64 bit), powerpc (32 + bit), sparc V9 (32 and 64 bit), and tilera (32 bit). On + other hardware gcc's builtin support for atomic memory + access will be used if such exists. If no such support is + found, <c>configure</c> will warn about no atomic + implementation available.</p> + <p> + The <c>ethread</c> library can now also use the + <c>libatomic_ops</c> library for atomic memory accesses. + This makes it possible for the Erlang runtime system to + utilize optimized native atomic operations on more + platforms than before. If <c>configure</c> warns about no + atomic implementation available, try using the + <c>libatomic_ops</c> library. Use the <seealso + marker="doc/installation_guide:INSTALL#How-to-Build-and-Install-ErlangOTP_A-Closer-Look-at-the-individual-Steps_Configuring">--with-libatomic_ops=PATH</seealso> + <c>configure</c> command line argument when specifying + where the <c>libatomic_ops</c> installation is located. + The <c>libatomic_ops</c> library can be downloaded from: + <url + href="http://www.hpl.hp.com/research/linux/atomic_ops/">http://www.hpl.hp.com/research/linux/atomic_ops/</url></p> + <p> + The changed API of the <c>ethread</c> library has also + caused modifications in the Erlang runtime system. + Preparations for the to come "delayed deallocation" + feature has also been done since it depends on the + <c>ethread</c> library.</p> + <p> + <em>Note</em>: When building for x86, the <c>ethread</c> + library will now use instructions that first appeared on + the pentium 4 processor. If you want the runtime system + to be compatible with older processors (back to 486) you + need to pass the <seealso + marker="doc/installation_guide:INSTALL#How-to-Build-and-Install-ErlangOTP_A-Closer-Look-at-the-individual-Steps_Configuring">--enable-ethread-pre-pentium4-compatibility</seealso> + <c>configure</c> command line argument when configuring + the system.</p> + <p> + Own Id: OTP-8544</p> + </item> + <item> + <p> + Some Built In Functions (BIFs) from the module erlang was + never made autoimported for backward compatibility + reasons. As local functions now override autoimports, new + autoimports is no longer a problem, why the following + BIFs are finally made autoimported: monitor/2, monitor/3, + demonitor/2, demonitor/3, error/1, error/2, + integer_to_list/2, list_to_integer/2.</p> + <p> + Own Id: OTP-8763</p> + </item> + </list> + </section> + +</section> + +<section><title>STDLIB 1.17</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>The Erlang code preprocessor (<c>epp</c>) sent extra + messages on the form <c>{eof,Location}</c> to the client + when parsing the <c>file</c> attribute. This bug, + introduced in R11B, has been fixed.</p> + <p> + Own Id: OTP-8470</p> + </item> + <item> + <p>The abstract type 'fun' could not be printed by the + Erlang pretty printer (<c>erl_pp</c>). This bug has been + fixed.</p> + <p> + Own Id: OTP-8473</p> + </item> + <item> + <p>The function <c>erl_scan:reserved_word/1</c> no longer + returns <c>true</c> when given the word <c>spec</c>. This + bug was introduced in STDLIB-1.15.3 (R12B-3).</p> + <p> + Own Id: OTP-8567</p> + </item> + <item> + <p>The documentation of <c>lists:keysort/2</c> states + that the sort is stable.</p> + <p> + Own Id: OTP-8628 Aux Id: seq11576 </p> + </item> + <item> + <p> + The shell's line editing has been improved to more + resemble the behaviour of readline and other shells. + (Thanks to Dave Peticolas)</p> + <p> + Own Id: OTP-8635</p> + </item> + <item> + <p>The Erlang code preprocessor (<c>epp</c>) did not + correctly handle premature end-of-input when defining + macros. This bug, introduced in STDLIB 1.16, has been + fixed.</p> + <p> + Own Id: OTP-8665 Aux Id: OTP-7810 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The module binary from EEP31 (and EEP9) is implemented.</p> + <p> + Own Id: OTP-8217</p> + </item> + <item> + <p>The erlang pretty printer (<c>erl_pp</c>) no longer + quotes atoms in types.</p> + <p> + Own Id: OTP-8501</p> + </item> + <item> + <p>The Erlang code preprocessor (<c>epp</c>) now + considers records with no fields as typed.</p> + <p> + Own Id: OTP-8503</p> + </item> + <item> + <p> + Added function <c>zip:foldl/3</c> to iterate over zip + archives.</p> + <p> + Added functions to create and extract escripts. See + <c>escript:create/2</c> and <c>escript:extract/2</c>.</p> + <p> + The undocumented function <c>escript:foldl/3</c> has been + removed. The same functionality can be achieved with the + more flexible functions <c>escript:extract/2</c> and + <c>zip:foldl/3</c>.</p> + <p> + Record fields has been annotated with type info. Source + files as been adapted to fit within 80 chars and trailing + whitespace has been removed.</p> + <p> + Own Id: OTP-8521</p> + </item> + <item> + <p>The Erlang parser no longer duplicates the singleton + type <c>undefined</c> in the type of record fields + without initial value.</p> + <p> + Own Id: OTP-8522</p> + </item> + <item> + <p>A regular expression with many levels of parenthesis + could cause a buffer overflow. That has been corrected. + (Thanks to Michael Santos.)</p> + <p> + Own Id: OTP-8539</p> + </item> + <item> + <p>When defining macros the closing right parenthesis + before the dot is now mandatory.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-8562</p> + </item> + <item> + <p> + Some properties of a compiled re pattern are defined to + allow for guard tests.</p> + <p> + Own Id: OTP-8577</p> + </item> + <item> + <p>Local and imported functions now override the + auto-imported BIFs when the names clash. The pre R14 + behaviour was that auto-imported BIFs would override + local functions. To avoid that old programs change + behaviour, the following will generate an error:</p> + <list><item><p>Doing a call without explicit module name + to a local function having a name clashing with the name + of an auto-imported BIF that was present (and + auto-imported) before OTP R14A</p></item> + <item><p>Explicitly importing a function having a name + clashing with the name of an autoimported BIF that was + present (and autoimported) before OTP R14A</p></item> + <item><p>Using any form of the old compiler directive + <c>nowarn_bif_clash</c></p></item> </list> <p>If the BIF + was added or auto-imported in OTP R14A or later, + overriding it with an import or a local function will + only result in a warning,</p> <p>To resolve clashes, you + can either use the explicit module name <c>erlang</c> to + call the BIF, or you can remove the auto-import of that + specific BIF by using the new compiler directive + <c>-compile({no_auto_import,[F/A]}).</c>, which makes all + calls to the local or imported function without explicit + module name pass without warnings or errors.</p> <p>The + change makes it possible to add auto-imported BIFs + without breaking or silently changing old code in the + future. However some current code ingeniously utilizing + the old behaviour or the <c>nowarn_bif_clash</c> compiler + directive, might need changing to be accepted by the + compiler.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-8579</p> + </item> + <item> + <p>The undocumented, unsupport, and deprecated function + <c>lists:flat_length/1</c> has been removed.</p> + <p> + Own Id: OTP-8584</p> + </item> + <item> + <p> + A bug in re that could cause certain regular expression + matches never to terminate is corrected. (Thanks to + Michael Santos and Gordon Guthrie.)</p> + <p> + Own Id: OTP-8589</p> + </item> + <item> + <p>Nested records can now be accessed without + parenthesis. See the Reference Manual for examples. + (Thanks to YAMASHINA Hio and Tuncer Ayaz.)</p> + <p> + Own Id: OTP-8597</p> + </item> + <item> + <p><c>receive</c> statements that can only read out a + newly created reference are now specially optimized so + that it will execute in constant time regardless of the + number of messages in the receive queue for the process. + That optimization will benefit calls to + <c>gen_server:call()</c>. (See <c>gen:do_call/4</c> for + an example of a receive statement that will be + optimized.)</p> + <p> + Own Id: OTP-8623</p> + </item> + <item> + <p>The beam_lib:cmp/2 function now compares BEAM files in + stricter way. The BEAM files will be considered different + if there are any changes except in the compilation + information ("CInf") chunk. beam_lib:cmp/2 used to ignore + differences in the debug information (significant for + Dialyzer) and other chunks that did not directly change + the run-time behavior.</p> + <p> + Own Id: OTP-8625</p> + </item> + <item> + <p> + When a gen_server, gen_fsm process, or gen_event + terminates abnormally, sometimes the text representation + of the process state can occupy many lines of the error + log, depending on the definition of the state term. A + mechanism to trim out parts of the state from the log has + been added (using a format_status/2 callback). See the + documentation.</p> + <p> + Own Id: OTP-8630</p> + </item> + <item> + <p> + Calling <c>sys:get_status()</c> for processes that have + globally registered names that were not atoms would cause + a crash. Corrected. (Thanks to Steve Vinoski.)</p> + <p> + Own Id: OTP-8656</p> + </item> + <item> + <p>The Erlang scanner has been augmented with two new + tokens: <c>..</c> and <c>...</c>.</p> + <p> + Own Id: OTP-8657</p> + </item> + <item> + <p>Expressions evaluating to integers can now be used in + types and function specifications where hitherto only + integers were allowed ("Erlang_Integer").</p> + <p> + Own Id: OTP-8664</p> + </item> + <item> + <p>The compiler optimizes record operations better.</p> + <p> + Own Id: OTP-8668</p> + </item> + <item> + <p> + The recently added BIFs erlang:min/2, erlang:max/2 and + erlang:port_command/3 are now auto-imported (as they were + originally intended to be). Due to the recent compiler + change (OTP-8579), the only impact on old code defining + it's own min/2, max/2 or port_command/3 functions will be + a warning, the local functions will still be used. The + warning can be removed by using + -compile({no_auto_import,[min/2,max/2,port_command/3]}). + in the source file.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-8669 Aux Id: OTP-8579 </p> + </item> + <item> + <p> + Now, binary_to_term/2 is auto-imported. This will cause a + compile warning if and only if a module has got a local + function with that name.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-8671</p> + </item> + <item> + <p> + The predefined builtin type tid() has been removed. + Instead, ets:tid() should be used.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-8687</p> + </item> + </list> + </section> + +</section> + <section><title>STDLIB 1.16.5</title> <section><title>Fixed Bugs and Malfunctions</title> @@ -50,7 +463,7 @@ <item> <p>A number of bugs concerning re and unicode are corrected:</p> - <p>re:compile no longer looses unicode option, which also + <p>re:compile no longer loses unicode option, which also fixes bug in re:split.</p> <p>re:replace now handles unicode charlist replacement argument</p> diff --git a/lib/stdlib/doc/src/re.xml b/lib/stdlib/doc/src/re.xml index 4d2a0e0995..80adc3e347 100644 --- a/lib/stdlib/doc/src/re.xml +++ b/lib/stdlib/doc/src/re.xml @@ -80,7 +80,11 @@ - a unicode_binary is allowed as the tail of the list</code> <code type="none"> - mp() = Opaque datatype containing a compiled regular expression.</code> + mp() = Opaque datatype containing a compiled regular expression. + - The mp() is guaranteed to be a tuple() having the atom + 're_pattern' as it's first element, to allow for matching in + guards. The arity of the tuple() or the content of the other fields + is however not to be trusted.</code> </section> <funcs> <func> diff --git a/lib/stdlib/doc/src/ref_man.xml b/lib/stdlib/doc/src/ref_man.xml index f6ae368e92..85aae6151d 100644 --- a/lib/stdlib/doc/src/ref_man.xml +++ b/lib/stdlib/doc/src/ref_man.xml @@ -4,7 +4,7 @@ <application xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>1996</year><year>2009</year> + <year>1996</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>STDLIB Reference Manual</title> @@ -37,6 +37,7 @@ <xi:include href="array.xml"/> <xi:include href="base64.xml"/> <xi:include href="beam_lib.xml"/> + <xi:include href="binary.xml"/> <xi:include href="c.xml"/> <xi:include href="calendar.xml"/> <xi:include href="dets.xml"/> diff --git a/lib/stdlib/doc/src/sofs.xml b/lib/stdlib/doc/src/sofs.xml index 8c8ae51262..729df1e678 100644 --- a/lib/stdlib/doc/src/sofs.xml +++ b/lib/stdlib/doc/src/sofs.xml @@ -210,7 +210,7 @@ X[i] to Y[i] and S a subset of X[1] × ... × X[n]. The <marker id="multiple_relative_product"></marker><em>multiple - relative product</em> of TR and and S is defined to be the + relative product</em> of TR and S is defined to be the set {z : z = ((x[1], ..., x[n]), (y[1],...,y[n])) for some (x[1], ..., x[n]) in S and for some (x[i], y[i]) in R[i], diff --git a/lib/stdlib/doc/src/sys.xml b/lib/stdlib/doc/src/sys.xml index 10ead62073..8cbfb9387b 100644 --- a/lib/stdlib/doc/src/sys.xml +++ b/lib/stdlib/doc/src/sys.xml @@ -34,7 +34,7 @@ <module>sys</module> <modulesummary>A Functional Interface to System Messages</modulesummary> <description> - <p>This module contains functions for sending system messages used by programs, and messaged used for debugging purposes. + <p>This module contains functions for sending system messages used by programs, and messages used for debugging purposes. </p> <p>Functions used for implementation of processes should also understand system messages such as debugging diff --git a/lib/stdlib/doc/src/timer.xml b/lib/stdlib/doc/src/timer.xml index 0b6807dd6c..1b34e71490 100644 --- a/lib/stdlib/doc/src/timer.xml +++ b/lib/stdlib/doc/src/timer.xml @@ -202,18 +202,33 @@ </func> <func> <name>tc(Module, Function, Arguments) -> {Time, Value}</name> - <fsummary>Measure the real time it takes to evaluate <c>apply(Module, Function, Arguments)</c></fsummary> + <name>tc(Fun, Arguments) -> {Time, Value}</name> + <fsummary>Measure the real time it takes to evaluate <c>apply(Module, + Function, Arguments)</c> or <c>apply(Fun, Arguments)</c></fsummary> <type> <v>Module = Function = atom()</v> + <v>Fun = fun()</v> <v>Arguments = [term()]</v> <v>Time = integer() in microseconds</v> <v>Value = term()</v> </type> <desc> - <p>Evaluates <c>apply(Module, Function, Arguments)</c> and measures - the elapsed real time. Returns <c>{Time, Value}</c>, where - <c>Time</c> is the elapsed real time in <em>microseconds</em>, - and <c>Value</c> is what is returned from the apply.</p> + <p></p> + <taglist> + <tag><c>tc/3</c></tag> + <item> + <p>Evaluates <c>apply(Module, Function, Arguments)</c> and measures + the elapsed real time as reported by <c>now/0</c>. + Returns <c>{Time, Value}</c>, where + <c>Time</c> is the elapsed real time in <em>microseconds</em>, + and <c>Value</c> is what is returned from the apply.</p> + </item> + <tag><c>tc/2</c></tag> + <item> + <p>Evaluates <c>apply(Fun, Arguments)</c>. Otherwise works + like <c>tc/3</c>.</p> + </item> + </taglist> </desc> </func> <func> diff --git a/lib/stdlib/doc/src/unicode_usage.xml b/lib/stdlib/doc/src/unicode_usage.xml index c5bf10b63d..f1b0659ea2 100644 --- a/lib/stdlib/doc/src/unicode_usage.xml +++ b/lib/stdlib/doc/src/unicode_usage.xml @@ -143,7 +143,7 @@ en_US.UTF-8</pre> <pre> $ echo <input>$LC_CTYPE</input> en_US.UTF-8</pre> -<p>The LANG or LC_CTYPE setting should be consistent with what the terminal is capable of, there is no portable way for Erlang to ask the actual terminal about it's UTF-8 capacity, we have to rely on the language and character type settings.</p> +<p>The LANG or LC_CTYPE setting should be consistent with what the terminal is capable of, there is no portable way for Erlang to ask the actual terminal about its UTF-8 capacity, we have to rely on the language and character type settings.</p> <p>To investigate what Erlang thinks about the terminal, the <c>io:getopts()</c> call can be used when the shell is started:</p> <pre> $ <input>LC_CTYPE=en_US.ISO-8859-1 erl</input> @@ -185,7 +185,7 @@ Eshell V5.7 (abort with ^G) <tag><c>file</c>, <c>group</c> and <c>user</c></tag> <item> <p>I/O-servers throughout the system are able both to handle Unicode data and has options for converting data upon actual output or input to/from the device. As shown earlier, the <seealso marker="stdlib:shell">shell</seealso> has support for Unicode terminals and the <seealso marker="kernel:file">file</seealso> module allows for translation to and from various Unicode formats on disk.</p> -<p>The actual reading and writing of files with Unicode data is however not best done with the <c>file</c> module as it's interface is byte oriented. A file opened with a Unicode encoding (like UTF-8), is then best read or written using the <seealso marker="stdlib:io">io</seealso> module.</p> +<p>The actual reading and writing of files with Unicode data is however not best done with the <c>file</c> module as its interface is byte oriented. A file opened with a Unicode encoding (like UTF-8), is then best read or written using the <seealso marker="stdlib:io">io</seealso> module.</p> </item> <tag><c>re</c></tag> <item> diff --git a/lib/stdlib/doc/src/zip.xml b/lib/stdlib/doc/src/zip.xml index e2ecfec8f0..4d98a20206 100644 --- a/lib/stdlib/doc/src/zip.xml +++ b/lib/stdlib/doc/src/zip.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>2006</year><year>2009</year> + <year>2006</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>zip</title> @@ -42,16 +42,18 @@ <p>By convention, the name of a zip file should end in "<c>.zip</c>". To abide to the convention, you'll need to add "<c>.zip</c>" yourself to the name.</p> - <p>Zip archives are created with the - <seealso marker="#zip_2">zip/2</seealso> or the + <p>Zip archives are created with the + <seealso marker="#zip_2">zip/2</seealso> or the <seealso marker="#zip_2">zip/3</seealso> function. (They are also available as <c>create</c>, to resemble the <c>erl_tar</c> module.)</p> - <p>To extract files from a zip archive, use the - <seealso marker="#unzip_1">unzip/1</seealso> or the + <p>To extract files from a zip archive, use the + <seealso marker="#unzip_1">unzip/1</seealso> or the <seealso marker="#unzip_2">unzip/2</seealso> function. (They are also available as <c>extract</c>.)</p> - <p>To return a list of the files in a zip archive, use the + <p>To fold a function over all files in a zip archive, use the + <seealso marker="#foldl_3">foldl_3</seealso>.</p> + <p>To return a list of the files in a zip archive, use the <seealso marker="#list_dir_1">list_dir/1</seealso> or the <seealso marker="#list_dir_2">list_dir/2</seealso> function. (They are also available as <c>table</c>.)</p> @@ -132,7 +134,7 @@ zip_file() </code> <type> <v>Name = filename()</v> <v>FileList = [FileSpec]</v> - <v>FileSpec = filename() | {filename(), binary()}</v> + <v>FileSpec = filename() | {filename(), binary()} | {filename(), binary(), #file_info{}}</v> <v>Options = [Option]</v> <v>Option = memory | cooked | verbose | {comment, Comment} | {cwd, CWD} | {compress, What} | {uncompress, What}</v> <v>What = all | [Extension] | {add, [Extension]} | {del, [Extension]}</v> @@ -212,16 +214,16 @@ zip_file() </code> <taglist> <tag><c>all</c></tag> <item><p> means that all files will be compressed (as long - as they pass the <c>uncompress</c> condition).</p></item> + as they pass the <c>uncompress</c> condition).</p></item> <tag><c>[Extension]</c></tag> <item><p>means that only files with exactly these extensions - will be compressed.</p></item> + will be compressed.</p></item> <tag><c>{add,[Extension]}</c></tag> <item><p>adds these extensions to the list of compress - extensions.</p></item> + extensions.</p></item> <tag><c>{del,[Extension]}</c></tag> <item><p>deletes these extensions from the list of compress - extensions.</p></item> + extensions.</p></item> </taglist> </item> <tag><c>{uncompress, What}</c></tag> @@ -231,16 +233,16 @@ zip_file() </code> The following values of <c>What</c> are allowed:</p> <taglist> <tag><c>all</c></tag> - <item><p> means that no files will be compressed.</p></item> + <item><p> means that no files will be compressed.</p></item> <tag><c>[Extension]</c></tag> <item><p>means that files with these extensions will be - uncompressed.</p></item> + uncompressed.</p></item> <tag><c>{add,[Extension]}</c></tag> <item><p>adds these extensions to the list of uncompress - extensions.</p></item> + extensions.</p></item> <tag><c>{del,[Extension]}</c></tag> <item><p>deletes these extensions from the list of uncompress - extensions.</p></item> + extensions.</p></item> </taglist> </item> </taglist> @@ -283,7 +285,7 @@ zip_file() </code> the <c>unzip/2</c> function will only extract the files whose names are included in <c>FileList</c>. The full paths, including the names of all sub directories within - the zip archive, must be specified.</p> + the zip archive, must be specified.</p> </item> <tag><c>cooked</c></tag> <item> @@ -327,6 +329,64 @@ zip_file() </code> </desc> </func> <func> + <name>foldl(Fun, Acc0, Archive) -> {ok, Acc1} | {error, Reason}</name> + <fsummary>Fold a function over all files in a zip archive</fsummary> + <type> + <v>Fun = fun(FileInArchive, GetInfo, GetBin, AccIn) -> AccOut</v> + <v>FileInArchive = filename()</v> + <v>GetInfo = fun() -> #file_info{}</v> + <v>GetBin = fun() -> binary()</v> + <v>Acc0 = Acc1 = AccIn = AccOut = term()</v> + <v>Archive = filename() | {filename(), binary()}</v> + </type> + <desc> + <p>The <marker id="foldl_3"></marker> <c>foldl/3</c> function + calls <c>Fun(FileInArchive, GetInfo, GetBin, AccIn)</c> on + successive files in the <c>Archive</c>, starting with <c>AccIn + == Acc0</c>. <c>FileInArchive</c> is the name that the file + has in the archive. <c>GetInfo</c> is a fun that returns info + about the the file. <c>GetBin</c> returns the contents of the + file. Both <c>GetInfo</c> and <c>GetBin</c> must be called + within the <c>Fun</c>. Their behavior is undefined if they are + called outside the context of the <c>Fun</c>. The <c>Fun</c> + must return a new accumulator which is passed to the next + call. <c>foldl/3</c> returns the final value of the + accumulator. <c>Acc0</c> is returned if the archive is + empty. It is not necessary to iterate over all files in the + archive. The iteration may be ended prematurely in a + controlled manner by throwing an exception.</p> + + <p>For example:</p> + <pre> +> <input>Name = "dummy.zip".</input> +"dummy.zip" +> <input>{ok, {Name, Bin}} = zip:create(Name, [{"foo", <<"FOO">>}, {"bar", <<"BAR">>}], [memory]).</input> +{ok,{"dummy.zip", + <<80,75,3,4,20,0,0,0,0,0,74,152,97,60,171,39,212,26,3,0, + 0,0,3,0,0,...>>}} +> <input>{ok, FileSpec} = zip:foldl(fun(N, I, B, Acc) -> [{N, B(), I()} | Acc] end, [], {Name, Bin}).</input> +{ok,[{"bar",<<"BAR">>, + {file_info,3,regular,read_write, + {{2010,3,1},{19,2,10}}, + {{2010,3,1},{19,2,10}}, + {{2010,3,1},{19,2,10}}, + 54,1,0,0,0,0,0}}, + {"foo",<<"FOO">>, + {file_info,3,regular,read_write, + {{2010,3,1},{19,2,10}}, + {{2010,3,1},{19,2,10}}, + {{2010,3,1},{19,2,10}}, + 54,1,0,0,0,0,0}}]} +> <input>{ok, {Name, Bin}} = zip:create(Name, lists:reverse(FileSpec), [memory]).</input> +{ok,{"dummy.zip", + <<80,75,3,4,20,0,0,0,0,0,74,152,97,60,171,39,212,26,3,0, + 0,0,3,0,0,...>>}} +> <input>catch zip:foldl(fun("foo", _, B, _) -> throw(B()); (_, _, _, Acc) -> Acc end, [], {Name, Bin}). </input> +<<"FOO">> +</pre> + </desc> + </func> + <func> <name>list_dir(Archive) -> RetValue</name> <name>list_dir(Archive, Options)</name> <name>table(Archive) -> RetValue</name> diff --git a/lib/stdlib/src/Makefile b/lib/stdlib/src/Makefile index 237818c08b..600303d7e1 100644 --- a/lib/stdlib/src/Makefile +++ b/lib/stdlib/src/Makefile @@ -43,6 +43,7 @@ MODULES= \ array \ base64 \ beam_lib \ + binary \ c \ calendar \ dets \ diff --git a/lib/stdlib/src/beam_lib.erl b/lib/stdlib/src/beam_lib.erl index 820afd3739..74d4ad3da7 100644 --- a/lib/stdlib/src/beam_lib.erl +++ b/lib/stdlib/src/beam_lib.erl @@ -1,24 +1,28 @@ %% %% %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 %% 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(beam_lib). -behaviour(gen_server). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). +%% Avoid warning for local function error/2 clashing with autoimported BIF. +-compile({no_auto_import,[error/2]}). -export([info/1, cmp/2, cmp_dirs/2, @@ -41,12 +45,11 @@ terminate/2,code_change/3]). -export([make_crypto_key/2, get_crypto_key/1]). %Utilities used by compiler +-export_type([attrib_entry/0, compinfo_entry/0, labeled_entry/0]). + -import(lists, [append/1, delete/2, foreach/2, keysort/2, member/2, reverse/1, sort/1, splitwith/2]). --include_lib("kernel/include/file.hrl"). --include("erl_compile.hrl"). - %%------------------------------------------------------------------------- -type beam() :: module() | file:filename() | binary(). @@ -106,6 +109,7 @@ | info_rsn(). -type cmp_rsn() :: {'modules_different', module(), module()} | {'chunks_different', chunkid()} + | 'different_chunks' | info_rsn(). %%------------------------------------------------------------------------- @@ -331,13 +335,11 @@ beam_files(Dir) -> %% -> ok | throw(Error) cmp_files(File1, File2) -> - {ok, {M1, L1}} = read_significant_chunks(File1), - {ok, {M2, L2}} = read_significant_chunks(File2), + {ok, {M1, L1}} = read_all_but_useless_chunks(File1), + {ok, {M2, L2}} = read_all_but_useless_chunks(File2), if M1 =:= M2 -> - List1 = filter_funtab(L1), - List2 = filter_funtab(L2), - cmp_lists(List1, List2); + cmp_lists(L1, L2); true -> error({modules_different, M1, M2}) end. @@ -408,6 +410,20 @@ pad(Size) -> end. %% -> {ok, {Module, Chunks}} | throw(Error) +read_all_but_useless_chunks(File0) when is_atom(File0); + is_list(File0); + is_binary(File0) -> + File = beam_filename(File0), + {ok, Module, ChunkIds0} = scan_beam(File, info), + ChunkIds = [Name || {Name,_,_} <- ChunkIds0, + not is_useless_chunk(Name)], + {ok, Module, Chunks} = scan_beam(File, ChunkIds), + {ok, {Module, lists:reverse(Chunks)}}. + +is_useless_chunk("CInf") -> true; +is_useless_chunk(_) -> false. + +%% -> {ok, {Module, Chunks}} | throw(Error) read_significant_chunks(File) -> case read_chunk_data(File, significant_chunks(), [allow_missing_chunks]) of {ok, {Module, Chunks0}} -> diff --git a/lib/stdlib/src/binary.erl b/lib/stdlib/src/binary.erl new file mode 100644 index 0000000000..f6489788b2 --- /dev/null +++ b/lib/stdlib/src/binary.erl @@ -0,0 +1,177 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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(binary). +%% +%% The following functions implemented as BIF's +%% binary:compile_pattern/1 +%% binary:match/{2,3} +%% binary:matches/{2,3} +%% binary:longest_common_prefix/1 +%% binary:longest_common_suffix/1 +%% binary:first/1 +%% binary:last/1 +%% binary:at/2 +%% binary:part/{2,3} +%% binary:bin_to_list/{1,2,3} +%% binary:list_to_bin/1 +%% binary:copy/{1,2} +%% binary:referenced_byte_size/1 +%% binary:decode_unsigned/{1,2} +%% - Not yet: +%% +%% Implemented in this module: +-export([split/2,split/3,replace/3,replace/4]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% split +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +split(H,N) -> + split(H,N,[]). +split(Haystack,Needles,Options) -> + try + {Part,Global,Trim} = get_opts_split(Options,{no,false,false}), + Moptlist = case Part of + no -> + []; + {A,B} -> + [{scope,{A,B}}] + end, + MList = if + Global -> + binary:matches(Haystack,Needles,Moptlist); + true -> + case binary:match(Haystack,Needles,Moptlist) of + nomatch -> []; + Match -> [Match] + end + end, + do_split(Haystack,MList,0,Trim) + catch + _:_ -> + erlang:error(badarg) + end. + +do_split(H,[],N,true) when N >= byte_size(H) -> + []; +do_split(H,[],N,_) -> + [binary:part(H,{N,byte_size(H)-N})]; +do_split(H,[{A,B}|T],N,Trim) -> + case binary:part(H,{N,A-N}) of + <<>> -> + Rest = do_split(H,T,A+B,Trim), + case {Trim, Rest} of + {true,[]} -> + []; + _ -> + [<<>> | Rest] + end; + Oth -> + [Oth | do_split(H,T,A+B,Trim)] + end. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% replace +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +replace(H,N,R) -> + replace(H,N,R,[]). +replace(Haystack,Needles,Replacement,Options) -> + try + true = is_binary(Replacement), % Make badarg instead of function clause + {Part,Global,Insert} = get_opts_replace(Options,{no,false,[]}), + Moptlist = case Part of + no -> + []; + {A,B} -> + [{scope,{A,B}}] + end, + MList = if + Global -> + binary:matches(Haystack,Needles,Moptlist); + true -> + case binary:match(Haystack,Needles,Moptlist) of + nomatch -> []; + Match -> [Match] + end + end, + ReplList = case Insert of + [] -> + Replacement; + Y when is_integer(Y) -> + splitat(Replacement,0,[Y]); + Li when is_list(Li) -> + splitat(Replacement,0,lists:sort(Li)) + end, + erlang:iolist_to_binary(do_replace(Haystack,MList,ReplList,0)) + catch + _:_ -> + erlang:error(badarg) + end. + + +do_replace(H,[],_,N) -> + [binary:part(H,{N,byte_size(H)-N})]; +do_replace(H,[{A,B}|T],Replacement,N) -> + [binary:part(H,{N,A-N}), + if + is_list(Replacement) -> + do_insert(Replacement, binary:part(H,{A,B})); + true -> + Replacement + end + | do_replace(H,T,Replacement,A+B)]. + +do_insert([X],_) -> + [X]; +do_insert([H|T],R) -> + [H,R|do_insert(T,R)]. + +splitat(H,N,[]) -> + [binary:part(H,{N,byte_size(H)-N})]; +splitat(H,N,[I|T]) -> + [binary:part(H,{N,I-N})|splitat(H,I,T)]. + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Simple helper functions +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +get_opts_split([],{Part,Global,Trim}) -> + {Part,Global,Trim}; +get_opts_split([{scope,{A,B}} | T],{_Part,Global,Trim}) -> + get_opts_split(T,{{A,B},Global,Trim}); +get_opts_split([global | T],{Part,_Global,Trim}) -> + get_opts_split(T,{Part,true,Trim}); +get_opts_split([trim | T],{Part,Global,_Trim}) -> + get_opts_split(T,{Part,Global,true}); +get_opts_split(_,_) -> + throw(badopt). + +get_opts_replace([],{Part,Global,Insert}) -> + {Part,Global,Insert}; +get_opts_replace([{scope,{A,B}} | T],{_Part,Global,Insert}) -> + get_opts_replace(T,{{A,B},Global,Insert}); +get_opts_replace([global | T],{Part,_Global,Insert}) -> + get_opts_replace(T,{Part,true,Insert}); +get_opts_replace([{insert_replaced,N} | T],{Part,Global,_Insert}) -> + get_opts_replace(T,{Part,Global,N}); +get_opts_replace(_,_) -> + throw(badopt). + diff --git a/lib/stdlib/src/c.erl b/lib/stdlib/src/c.erl index 433833e233..6d50a575eb 100644 --- a/lib/stdlib/src/c.erl +++ b/lib/stdlib/src/c.erl @@ -1,25 +1,27 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(c). %% Utilities to use from shell. +%% Avoid warning for local function error/2 clashing with autoimported BIF. +-compile({no_auto_import,[error/2]}). -export([help/0,lc/1,c/1,c/2,nc/1,nc/2, nl/1,l/1,i/0,i/1,ni/0, y/1, y/2, lc_batch/0, lc_batch/1, @@ -31,10 +33,14 @@ -export([display_info/1]). -export([appcall/4]). --import(lists, [reverse/1,flatten/1,sublist/3,sort/1,keysearch/3,keysort/2, +-import(lists, [reverse/1,flatten/1,sublist/3,sort/1,keysort/2, concat/1,max/1,min/1,foreach/2,foldl/3,flatmap/2]). -import(io, [format/1, format/2]). +%%----------------------------------------------------------------------- + +-spec help() -> 'ok'. + help() -> format("bt(Pid) -- stack backtrace for a process\n" "c(File) -- compile and load code in <File>\n" @@ -65,8 +71,12 @@ help() -> %% c(FileName) %% Compile a file/module. +-spec c(file:name()) -> {'ok', module()} | 'error'. + c(File) -> c(File, []). +-spec c(file:name(), [compile:option()]) -> {'ok', module()} | 'error'. + c(File, Opts0) when is_list(Opts0) -> Opts = [report_errors,report_warnings|Opts0], case compile:file(File, Opts) of @@ -82,6 +92,8 @@ c(File, Opt) -> %%% Obtain the 'outdir' option from the argument. Return "." if no %%% such option was given. +-spec outdir([compile:option()]) -> file:filename(). + outdir([]) -> "."; outdir([Opt|Rest]) -> @@ -118,8 +130,8 @@ machine_load(Mod, File, Opts) -> %%% loaded from some other place than current directory. %%% Now, loading from other than current directory is supposed to work. %%% so this function does nothing special. -check_load({error, R}, _) -> {error, R}; -check_load(_, X) -> {ok, X}. +check_load({error, _R} = Error, _) -> Error; +check_load(_, Mod) -> {ok, Mod}. %% Compile a list of modules %% enables the nice unix shell cmd @@ -128,6 +140,8 @@ check_load(_, X) -> {ok, X}. %% with constant c2 defined, c1=v1 (v1 must be a term!), include dir %% IDir, outdir ODir. +-spec lc([erl_compile:cmd_line_arg()]) -> 'ok' | 'error'. + lc(Args) -> case catch split(Args, [], []) of error -> error; @@ -145,7 +159,7 @@ lc_batch() -> io:format("Error: no files to compile~n"), halt(1). --spec lc_batch([_]) -> no_return(). +-spec lc_batch([erl_compile:cmd_line_arg()]) -> no_return(). lc_batch(Args) -> try split(Args, [], []) of @@ -191,8 +205,13 @@ make_term(Str) -> throw(error) end. +-spec nc(file:name()) -> {'ok', module()} | 'error'. + nc(File) -> nc(File, []). +-spec nc(file:name(), [compile:option()] | compile:option()) -> + {'ok', module} | 'error'. + nc(File, Opts0) when is_list(Opts0) -> Opts = Opts0 ++ [report_errors, report_warnings], case compile:file(File, Opts) of @@ -215,26 +234,37 @@ nc(File, Opt) when is_atom(Opt) -> %% l(Mod) %% Reload module Mod from file of same name +-spec l(module()) -> code:load_ret(). l(Mod) -> code:purge(Mod), code:load_file(Mod). %% Network version of l/1 +%%-spec nl(module()) -> nl(Mod) -> case code:get_object_code(Mod) of {_Module, Bin, Fname} -> - rpc:eval_everywhere(code,load_binary,[Mod,Fname,Bin]); + rpc:eval_everywhere(code, load_binary, [Mod, Fname, Bin]); Other -> Other end. +-spec i() -> 'ok'. + i() -> i(processes()). + +-spec ni() -> 'ok'. + ni() -> i(all_procs()). +-spec i([pid()]) -> 'ok'. + i(Ps) -> i(Ps, length(Ps)). +-spec i([pid()], non_neg_integer()) -> 'ok'. + i(Ps, N) when N =< 100 -> iformat("Pid", "Initial Call", "Heap", "Reds", "Msgs"), @@ -275,7 +305,6 @@ paged_i(Ps, Acc, N, Page) -> paged_i([], NewAcc, 0, Page) end. - choice(F) -> case get_line('(c)ontinue (q)uit -->', "c\n") of "c\n" -> @@ -285,7 +314,6 @@ choice(F) -> _ -> choice(F) end. - get_line(P, Default) -> case io:get_line(P) of @@ -305,7 +333,6 @@ mfa_string({M,F,A}) -> mfa_string(X) -> w(X). - display_info(Pid) -> case pinfo(Pid) of undefined -> {0,0,0,0}; @@ -317,7 +344,7 @@ display_info(Pid) -> Other -> Other end, - Reds = fetch(reductions, Info), + Reds = fetch(reductions, Info), LM = length(fetch(messages, Info)), HS = fetch(heap_size, Info), SS = fetch(stack_size, Info), @@ -364,21 +391,30 @@ pinfo(Pid) -> end. fetch(Key, Info) -> - case keysearch(Key, 1, Info) of - {value, {_, Val}} -> Val; + case lists:keyfind(Key, 1, Info) of + {_, Val} -> Val; false -> 0 end. -pid(X,Y,Z) -> +-spec pid(non_neg_integer(), non_neg_integer(), non_neg_integer()) -> pid(). + +pid(X, Y, Z) -> list_to_pid("<" ++ integer_to_list(X) ++ "." ++ integer_to_list(Y) ++ "." ++ integer_to_list(Z) ++ ">"). -i(X,Y,Z) -> pinfo(pid(X,Y,Z)). +-spec i(non_neg_integer(), non_neg_integer(), non_neg_integer()) -> + [{atom(), term()}]. + +i(X, Y, Z) -> pinfo(pid(X, Y, Z)). + +-spec q() -> no_return(). q() -> init:stop(). +-spec bt(pid()) -> 'ok' | 'undefined'. + bt(Pid) -> case catch erlang:process_display(Pid, backtrace) of {'EXIT', _} -> @@ -387,6 +423,8 @@ bt(Pid) -> ok end. +-spec m() -> 'ok'. + m() -> mformat("Module", "File"), foreach(fun ({Mod,File}) -> mformat(Mod, File) end, sort(code:all_loaded())). @@ -414,8 +452,8 @@ error(Fmt, Args) -> f_p_e(P, F) -> case file:path_eval(P, F) of - {error, enoent} -> - {error, enoent}; + {error, enoent} = Enoent -> + Enoent; {error, E={Line, _Mod, _Term}} -> error("file:path_eval(~p,~p): error on line ~p: ~s~n", [P, F, Line, file:format_error(E)]), @@ -438,10 +476,11 @@ bi(I) -> %% %% Short and nice form of module info %% +-spec m(module()) -> 'ok'. m(M) -> L = M:module_info(), - {value,{exports,E}} = keysearch(exports, 1, L), + {exports,E} = lists:keyfind(exports, 1, L), Time = get_compile_time(L), COpts = get_compile_options(L), format("Module ~w compiled: ",[M]), print_time(Time), @@ -470,10 +509,10 @@ get_compile_options(L) -> end. get_compile_info(L, Tag) -> - case keysearch(compile, 1, L) of - {value, {compile, I}} -> - case keysearch(Tag, 1, I) of - {value, {Tag, Val}} -> {ok,Val}; + case lists:keyfind(compile, 1, L) of + {compile, I} -> + case lists:keyfind(Tag, 1, I) of + {Tag, Val} -> {ok,Val}; false -> error end; false -> error @@ -523,6 +562,8 @@ month(11) -> "November"; month(12) -> "December". %% Just because we can't eval receive statements... +-spec flush() -> 'ok'. + flush() -> receive X -> @@ -533,9 +574,13 @@ flush() -> end. %% Print formatted info about all registered names in the system +-spec nregs() -> 'ok'. + nregs() -> foreach(fun (N) -> print_node_regs(N) end, all_regs()). +-spec regs() -> 'ok'. + regs() -> print_node_regs({node(),registered()}). @@ -609,6 +654,8 @@ portformat(Name, Id, Cmd) -> %% cd(Directory) %% These are just wrappers around the file:get/set_cwd functions. +-spec pwd() -> 'ok'. + pwd() -> case file:get_cwd() of {ok, Str} -> @@ -617,6 +664,8 @@ pwd() -> ok = io:format("Cannot determine current directory\n") end. +-spec cd(file:name()) -> 'ok'. + cd(Dir) -> file:set_cwd(Dir), pwd(). @@ -625,9 +674,13 @@ cd(Dir) -> %% ls(Directory) %% The strategy is to print in fixed width files. +-spec ls() -> 'ok'. + ls() -> ls("."). +-spec ls(file:name()) -> 'ok'. + ls(Dir) -> case file:list_dir(Dir) of {ok, Entries} -> @@ -660,24 +713,31 @@ w(X) -> %% memory/[0,1] %% -memory() -> erlang:memory(). +-spec memory() -> [{atom(), non_neg_integer()}]. + +memory() -> erlang:memory(). + +-spec memory(atom()) -> non_neg_integer() + ; ([atom()]) -> [{atom(), non_neg_integer()}]. + memory(TypeSpec) -> erlang:memory(TypeSpec). %% %% Cross Reference Check %% - +%%-spec xm(module() | file:filename()) -> xref:m/1 return xm(M) -> appcall(tools, xref, m, [M]). %% %% Call yecc %% - +%%-spec y(file:name()) -> yecc:file/2 return y(File) -> y(File, []). +%%-spec y(file:name(), [yecc:option()]) -> yecc:file/2 return y(File, Opts) -> - appcall(parsetools, yecc, file, [File,Opts]). + appcall(parsetools, yecc, file, [File, Opts]). %% @@ -699,4 +759,3 @@ appcall(App, M, F, Args) -> erlang:raise(error, undef, Stk) end end. - diff --git a/lib/stdlib/src/dets.erl b/lib/stdlib/src/dets.erl index 7f1c13770b..4584b8184f 100644 --- a/lib/stdlib/src/dets.erl +++ b/lib/stdlib/src/dets.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(dets). @@ -88,6 +88,7 @@ %% Not documented, or not ready for publication. -export([lookup_keys/2]). +-export_type([tab_name/0]). -compile({inline, [{einval,2},{badarg,2},{undefined,1}, {badarg_exit,2},{lookup_reply,2}]}). diff --git a/lib/stdlib/src/dets_sup.erl b/lib/stdlib/src/dets_sup.erl index 5c6caa787d..8ea2ba9b3f 100644 --- a/lib/stdlib/src/dets_sup.erl +++ b/lib/stdlib/src/dets_sup.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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(dets_sup). @@ -22,9 +22,16 @@ -export([start_link/0, init/1]). +-spec start_link() -> {'ok', pid()} | 'ignore' | {'error', term()}. + start_link() -> supervisor:start_link({local, dets_sup}, dets_sup, []). +-spec init([]) -> + {'ok', {{'simple_one_for_one', 4, 3600}, + [{'dets', {'dets', 'istart_link', []}, + 'temporary', 30000, 'worker', ['dets']}]}}. + init([]) -> SupFlags = {simple_one_for_one, 4, 3600}, Child = {dets, {dets, istart_link, []}, temporary, 30000, worker, [dets]}, diff --git a/lib/stdlib/src/digraph.erl b/lib/stdlib/src/digraph.erl index 9bdea671a9..b5f52da921 100644 --- a/lib/stdlib/src/digraph.erl +++ b/lib/stdlib/src/digraph.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(digraph). @@ -36,6 +36,8 @@ -export([get_short_path/3, get_short_cycle/2]). +-export_type([d_type/0, vertex/0]). + -record(digraph, {vtab = notable :: ets:tab(), etab = notable :: ets:tab(), ntab = notable :: ets:tab(), diff --git a/lib/stdlib/src/edlin.erl b/lib/stdlib/src/edlin.erl index 6cb441dbed..026bd9038f 100644 --- a/lib/stdlib/src/edlin.erl +++ b/lib/stdlib/src/edlin.erl @@ -24,6 +24,7 @@ -export([init/0,start/1,edit_line/2,prefix_arg/1]). -export([erase_line/1,erase_inp/1,redraw_line/1]). -export([length_before/1,length_after/1,prompt/1]). +-export([current_line/1]). %%-export([expand/1]). -export([edit_line1/2]). @@ -421,6 +422,7 @@ over_paren_auto([], _, _, _) -> %% length_before(Line) %% length_after(Line) %% prompt(Line) +%% current_line(Line) %% Various functions for accessing bits of a line. erase_line({line,Pbs,{Bef,Aft},_}) -> @@ -447,6 +449,9 @@ length_after({line,_,{_Bef,Aft},_}) -> prompt({line,Pbs,_,_}) -> Pbs. +current_line({line,_,{Bef, Aft},_}) -> + reverse(Bef, Aft ++ "\n"). + %% %% expand(CurrentBefore) -> %% %% {yes,Expansion} | no %% %% Try to expand the word before as either a module name or a function diff --git a/lib/stdlib/src/epp.erl b/lib/stdlib/src/epp.erl index 424aed3d2e..81b2431f40 100644 --- a/lib/stdlib/src/epp.erl +++ b/lib/stdlib/src/epp.erl @@ -109,6 +109,10 @@ format_error(cannot_parse) -> io_lib:format("cannot parse file, giving up", []); format_error({bad,W}) -> io_lib:format("badly formed '~s'", [W]); +format_error(missing_parenthesis) -> + io_lib:format("badly formed define: missing closing right parenthesis",[]); +format_error(premature_end) -> + "premature end"; format_error({call,What}) -> io_lib:format("illegal macro call '~s'",[What]); format_error({undefined,M,none}) -> @@ -161,7 +165,7 @@ parse_file(Epp) -> case normalize_typed_record_fields(Fields) of {typed, NewFields} -> [{attribute, La, record, {Record, NewFields}}, - {attribute, La, type, + {attribute, La, type, {{record, Record}, Fields, []}} |parse_file(Epp)]; not_typed -> @@ -176,6 +180,8 @@ parse_file(Epp) -> [{eof,Location}] end. +normalize_typed_record_fields([]) -> + {typed, []}; normalize_typed_record_fields(Fields) -> normalize_typed_record_fields(Fields, [], false). @@ -184,7 +190,7 @@ normalize_typed_record_fields([], NewFields, Typed) -> true -> {typed, lists:reverse(NewFields)}; false -> not_typed end; -normalize_typed_record_fields([{typed_record_field,Field,_}|Rest], +normalize_typed_record_fields([{typed_record_field,Field,_}|Rest], NewFields, _Typed) -> normalize_typed_record_fields(Rest, [Field|NewFields], true); normalize_typed_record_fields([Field|Rest], NewFields, Typed) -> @@ -320,7 +326,7 @@ wait_req_scan(St) -> wait_req_skip(St, Sis) -> From = wait_request(St), skip_toks(From, St, Sis). - + %% enter_file(Path, FileName, IncludeToken, From, EppState) %% leave_file(From, EppState) %% Handle entering and leaving included files. Notify caller when the @@ -376,16 +382,16 @@ file_name(N) when is_atom(N) -> leave_file(From, St) -> case St#epp.istk of - [I|Cis] -> + [I|Cis] -> epp_reply(From, - {error,{St#epp.location,epp, + {error,{St#epp.location,epp, {illegal,"unterminated",I}}}), leave_file(wait_request(St),St#epp{istk=Cis}); [] -> case St#epp.sstk of [OldSt|Sts] -> close_file(St), - enter_file_reply(From, OldSt#epp.name, + enter_file_reply(From, OldSt#epp.name, OldSt#epp.location, OldSt#epp.location), Ms = dict:store({atom,'FILE'}, {none, @@ -413,7 +419,7 @@ scan_toks(From, St) -> leave_file(From, St#epp{location=Cl}); {error,_E} -> epp_reply(From, {error,{St#epp.location,epp,cannot_parse}}), - leave_file(From, St) %This serious, just exit! + leave_file(wait_request(St), St) %This serious, just exit! end. scan_toks([{'-',_Lh},{atom,_Ld,define}=Define|Toks], From, St) -> @@ -487,28 +493,34 @@ scan_extends(_Ts, _As, Ms) -> Ms. %% scan_define(Tokens, DefineToken, From, EppState) -scan_define([{'(',_Lp},{Type,_Lm,M}=Mac,{',',_Lc}|Toks], _Def, From, St) +scan_define([{'(',_Lp},{Type,_Lm,M}=Mac,{',',Lc}|Toks], _Def, From, St) when Type =:= atom; Type =:= var -> - case dict:find({atom,M}, St#epp.macs) of - {ok, Defs} when is_list(Defs) -> - %% User defined macros: can be overloaded - case proplists:is_defined(none, Defs) of - true -> - epp_reply(From, {error,{loc(Mac),epp,{redefine,M}}}), + case catch macro_expansion(Toks, Lc) of + Expansion when is_list(Expansion) -> + case dict:find({atom,M}, St#epp.macs) of + {ok, Defs} when is_list(Defs) -> + %% User defined macros: can be overloaded + case proplists:is_defined(none, Defs) of + true -> + epp_reply(From, {error,{loc(Mac),epp,{redefine,M}}}), + wait_req_scan(St); + false -> + scan_define_cont(From, St, + {atom, M}, + {none, {none,Expansion}}) + end; + {ok, _PreDef} -> + %% Predefined macros: cannot be overloaded + epp_reply(From, {error,{loc(Mac),epp,{redefine_predef,M}}}), wait_req_scan(St); - false -> + error -> scan_define_cont(From, St, {atom, M}, - {none, {none,macro_expansion(Toks)}}) + {none, {none,Expansion}}) end; - {ok, _PreDef} -> - %% Predefined macros: cannot be overloaded - epp_reply(From, {error,{loc(Mac),epp,{redefine_predef,M}}}), - wait_req_scan(St); - error -> - scan_define_cont(From, St, - {atom, M}, - {none, {none,macro_expansion(Toks)}}) + {error,ErrL,What} -> + epp_reply(From, {error,{ErrL,epp,What}}), + wait_req_scan(St) end; scan_define([{'(',_Lp},{Type,_Lm,M}=Mac,{'(',_Lc}|Toks], Def, From, St) when Type =:= atom; Type =:= var -> @@ -534,6 +546,9 @@ scan_define([{'(',_Lp},{Type,_Lm,M}=Mac,{'(',_Lc}|Toks], Def, From, St) error -> scan_define_cont(From, St, {atom, M}, {Len, {As, Me}}) end; + {error,ErrL,What} -> + epp_reply(From, {error,{ErrL,epp,What}}), + wait_req_scan(St); _ -> epp_reply(From, {error,{loc(Def),epp,{bad,define}}}), wait_req_scan(St) @@ -595,7 +610,7 @@ scan_undef(_Toks, Undef, From, St) -> %% scan_include(Tokens, IncludeToken, From, St) -scan_include([{'(',_Llp},{string,_Lf,NewName0},{')',_Lrp},{dot,_Ld}], Inc, +scan_include([{'(',_Llp},{string,_Lf,NewName0},{')',_Lrp},{dot,_Ld}], Inc, From, St) -> NewName = expand_var(NewName0), enter_file(St#epp.path, NewName, Inc, From, St); @@ -631,7 +646,7 @@ scan_include_lib([{'(',_Llp},{string,_Lf,NewName0},{')',_Lrp},{dot,_Ld}], case file:open(LibName, [read]) of {ok,NewF} -> ExtraPath = [filename:dirname(LibName)], - wait_req_scan(enter_file2(NewF, LibName, From, + wait_req_scan(enter_file2(NewF, LibName, From, St, Loc, ExtraPath)); {error,_E2} -> epp_reply(From, @@ -753,14 +768,14 @@ scan_file([{'(',_Llp},{string,_Ls,Name},{',',_Lc},{integer,_Li,Ln},{')',_Lrp}, Ms = dict:store({atom,'FILE'}, {none,[{string,1,Name}]}, St#epp.macs), Locf = loc(Tf), NewLoc = new_location(Ln, St#epp.location, Locf), - scan_toks(From, St#epp{name=Name,location=NewLoc,macs=Ms}); + wait_req_scan(St#epp{name=Name,location=NewLoc,macs=Ms}); scan_file(_Toks, Tf, From, St) -> epp_reply(From, {error,{loc(Tf),epp,{bad,file}}}), wait_req_scan(St). new_location(Ln, Le, Lf) when is_integer(Lf) -> Ln+(Le-Lf); -new_location(Ln, {Le,_}, {Lf,_}) -> +new_location(Ln, {Le,_}, {Lf,_}) -> {Ln+(Le-Lf),1}. %% skip_toks(From, EppState, SkipIstack) @@ -787,7 +802,7 @@ skip_toks(From, St, [I|Sis]) -> leave_file(From, St#epp{location=Cl,istk=[I|Sis]}); {error,_E} -> epp_reply(From, {error,{St#epp.location,epp,cannot_parse}}), - leave_file(From, St) %This serious, just exit! + leave_file(wait_request(St), St) %This serious, just exit! end; skip_toks(From, St, []) -> scan_toks(From, St). @@ -801,22 +816,23 @@ skip_else(_Else, From, St, Sis) -> skip_toks(From, St, Sis). %% macro_pars(Tokens, ArgStack) -%% macro_expansion(Tokens) +%% macro_expansion(Tokens, Line) %% Extract the macro parameters and the expansion from a macro definition. -macro_pars([{')',_Lp}, {',',_Ld}|Ex], Args) -> - {ok, {lists:reverse(Args), macro_expansion(Ex)}}; -macro_pars([{var,_,Name}, {')',_Lp}, {',',_Ld}|Ex], Args) -> +macro_pars([{')',_Lp}, {',',Ld}|Ex], Args) -> + {ok, {lists:reverse(Args), macro_expansion(Ex, Ld)}}; +macro_pars([{var,_,Name}, {')',_Lp}, {',',Ld}|Ex], Args) -> false = lists:member(Name, Args), %Prolog is nice - {ok, {lists:reverse([Name|Args]), macro_expansion(Ex)}}; + {ok, {lists:reverse([Name|Args]), macro_expansion(Ex, Ld)}}; macro_pars([{var,_L,Name}, {',',_}|Ts], Args) -> - false = lists:member(Name, Args), + false = lists:member(Name, Args), macro_pars(Ts, [Name|Args]). -macro_expansion([{')',_Lp},{dot,_Ld}]) -> []; -macro_expansion([{dot,_Ld}]) -> []; %Be nice, allow no right paren! -macro_expansion([T|Ts]) -> - [T|macro_expansion(Ts)]. +macro_expansion([{')',_Lp},{dot,_Ld}], _L0) -> []; +macro_expansion([{dot,Ld}], _L0) -> throw({error,Ld,missing_parenthesis}); +macro_expansion([T|Ts], _L0) -> + [T|macro_expansion(Ts, element(2, T))]; +macro_expansion([], L0) -> throw({error,L0,premature_end}). %% expand_macros(Tokens, Macros) %% expand_macro(Tokens, MacroToken, RestTokens) @@ -1071,11 +1087,11 @@ epp_reply(From, Rep) -> wait_epp_reply(Epp, Mref) -> receive - {epp_reply,Epp,Rep} -> + {epp_reply,Epp,Rep} -> erlang:demonitor(Mref), receive {'DOWN',Mref,_,_,_} -> ok after 0 -> ok end, Rep; - {'DOWN',Mref,_,_,E} -> + {'DOWN',Mref,_,_,E} -> receive {epp_reply,Epp,Rep} -> Rep after 0 -> exit(E) end @@ -1132,7 +1148,7 @@ get_line({Line,_Column}) -> %% mainly aimed at yecc, the parser generator, which uses the -file %% attribute to get correct lines in messages referring to code %% supplied by the user (actions etc in .yrl files). -%% +%% %% In a perfect world (read: perfectly implemented applications such %% as Xref, Cover, Debugger, etc.) it would not be necessary to %% distinguish -file attributes from epp and the input file. The @@ -1152,7 +1168,7 @@ get_line({Line,_Column}) -> %% have been output by epp (corresponding to -include and %% -include_lib) are kept, but the user's -file attributes are %% removed. This seems sufficient for now. -%% +%% %% It turns out to be difficult to distinguish -file attributes in the %% input file from the ones added by epp unless some action is taken. %% The (less than perfect) solution employed is to let epp assign @@ -1164,7 +1180,7 @@ get_line({Line,_Column}) -> interpret_file_attribute(Forms) -> interpret_file_attr(Forms, 0, []). -interpret_file_attr([{attribute,Loc,file,{File,Line}}=Form | Forms], +interpret_file_attr([{attribute,Loc,file,{File,Line}}=Form | Forms], Delta, Fs) -> {line, L} = erl_scan:attributes_info(Loc, line), if diff --git a/lib/stdlib/src/erl_compile.erl b/lib/stdlib/src/erl_compile.erl index d9d15e05f8..abff37e4bc 100644 --- a/lib/stdlib/src/erl_compile.erl +++ b/lib/stdlib/src/erl_compile.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% %% -module(erl_compile). @@ -23,6 +23,8 @@ -export([compile_cmdline/1]). +-export_type([cmd_line_arg/0]). + %% Mapping from extension to {M,F} to run the correct compiler. compiler(".erl") -> {compile, compile}; diff --git a/lib/stdlib/src/erl_expand_records.erl b/lib/stdlib/src/erl_expand_records.erl index 6fa77f2c3b..61ce41f714 100644 --- a/lib/stdlib/src/erl_expand_records.erl +++ b/lib/stdlib/src/erl_expand_records.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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 : Expand records into tuples. @@ -95,8 +95,9 @@ forms([F | Fs0], St0) -> forms([], St) -> {[],St}. clauses([{clause,Line,H0,G0,B0} | Cs0], St0) -> - {H,St1} = head(H0, St0), - {G,St2} = guard(G0, St1), + {H1,St1} = head(H0, St0), + {G1,St2} = guard(G0, St1), + {H,G} = optimize_is_record(H1, G1, St2), {B,St3} = exprs(B0, St2), {Cs,St4} = clauses(Cs0, St3), {[{clause,Line,H,G,B} | Cs],St4}; @@ -191,7 +192,6 @@ guard_test1(Test, St) -> normalise_test(atom, 1) -> is_atom; normalise_test(binary, 1) -> is_binary; -normalise_test(constant, 1) -> is_constant; normalise_test(float, 1) -> is_float; normalise_test(function, 1) -> is_function; normalise_test(integer, 1) -> is_integer; @@ -346,9 +346,6 @@ expr({'fun',Line,{clauses,Cs0}}, St0) -> {{'fun',Line,{clauses,Cs}},St1}; expr({call,Line,{atom,_,is_record},[A,{atom,_,Name}]}, St) -> record_test(Line, A, Name, St); -expr({'cond',Line,Cs0}, St0) -> - {Cs,St1} = clauses(Cs0, St0), - {{'cond',Line,Cs},St1}; expr({call,Line,{remote,_,{atom,_,erlang},{atom,_,is_record}}, [A,{atom,_,Name}]}, St) -> record_test(Line, A, Name, St); @@ -804,5 +801,137 @@ imported(F, A, St) -> error -> no end. +%%% +%%% Replace is_record/3 in guards with matching if possible. +%%% + +optimize_is_record(H0, G0, #exprec{compile=Opts}) -> + case opt_rec_vars(G0) of + [] -> + {H0,G0}; + Rs0 -> + case lists:member(no_is_record_optimization, Opts) of + true -> + {H0,G0}; + false -> + {H,Rs} = opt_pattern_list(H0, Rs0), + G = opt_remove(G0, Rs), + {H,G} + end + end. + + +%% opt_rec_vars(Guards) -> Vars. +%% Search through the guard expression, looking for +%% variables referenced in those is_record/3 calls that +%% will fail the entire guard if they evaluate to 'false' +%% +%% In the following code +%% +%% f(X, Y, Z) when is_record(X, r1) andalso +%% (is_record(Y, r2) orelse is_record(Z, r3)) +%% +%% the entire guard will be false if the record test for +%% X fails, and the clause can be rewritten to: +%% +%% f({r1,...}=X, Y, Z) when true andalso +%% (is_record(Y, r2) or is_record(Z, r3)) +%% +opt_rec_vars([G|Gs]) -> + Rs = opt_rec_vars_1(G, orddict:new()), + opt_rec_vars(Gs, Rs); +opt_rec_vars([]) -> orddict:new(). + +opt_rec_vars([G|Gs], Rs0) -> + Rs1 = opt_rec_vars_1(G, orddict:new()), + Rs = ordsets:intersection(Rs0, Rs1), + opt_rec_vars(Gs, Rs); +opt_rec_vars([], Rs) -> Rs. + +opt_rec_vars_1([T|Ts], Rs0) -> + Rs = opt_rec_vars_2(T, Rs0), + opt_rec_vars_1(Ts, Rs); +opt_rec_vars_1([], Rs) -> Rs. + +opt_rec_vars_2({op,_,'and',A1,A2}, Rs) -> + opt_rec_vars_1([A1,A2], Rs); +opt_rec_vars_2({op,_,'andalso',A1,A2}, Rs) -> + opt_rec_vars_1([A1,A2], Rs); +opt_rec_vars_2({op,_,'orelse',Arg,{atom,_,fail}}, Rs) -> + %% Since the second argument guarantees failure, + %% it is safe to inspect the first argument. + opt_rec_vars_2(Arg, Rs); +opt_rec_vars_2({call,_,{remote,_,{atom,_,erlang},{atom,_,is_record}}, + [{var,_,V},{atom,_,Tag},{integer,_,Sz}]}, Rs) -> + orddict:store(V, {Tag,Sz}, Rs); +opt_rec_vars_2({call,_,{atom,_,is_record}, + [{var,_,V},{atom,_,Tag},{integer,_,Sz}]}, Rs) -> + orddict:store(V, {Tag,Sz}, Rs); +opt_rec_vars_2(_, Rs) -> Rs. + +opt_pattern_list(Ps, Rs) -> + opt_pattern_list(Ps, Rs, []). + +opt_pattern_list([P0|Ps], Rs0, Acc) -> + {P,Rs} = opt_pattern(P0, Rs0), + opt_pattern_list(Ps, Rs, [P|Acc]); +opt_pattern_list([], Rs, Acc) -> + {reverse(Acc),Rs}. + +opt_pattern({var,_,V}=Var, Rs0) -> + case orddict:find(V, Rs0) of + {ok,{Tag,Sz}} -> + Rs = orddict:store(V, {remove,Tag,Sz}, Rs0), + {opt_var(Var, Tag, Sz),Rs}; + _ -> + {Var,Rs0} + end; +opt_pattern({cons,Line,H0,T0}, Rs0) -> + {H,Rs1} = opt_pattern(H0, Rs0), + {T,Rs} = opt_pattern(T0, Rs1), + {{cons,Line,H,T},Rs}; +opt_pattern({tuple,Line,Es0}, Rs0) -> + {Es,Rs} = opt_pattern_list(Es0, Rs0), + {{tuple,Line,Es},Rs}; +opt_pattern({match,Line,Pa0,Pb0}, Rs0) -> + {Pa,Rs1} = opt_pattern(Pa0, Rs0), + {Pb,Rs} = opt_pattern(Pb0, Rs1), + {{match,Line,Pa,Pb},Rs}; +opt_pattern(P, Rs) -> {P,Rs}. + +opt_var({var,Line,_}=Var, Tag, Sz) -> + Rp = record_pattern(2, -1, ignore, Sz, Line, [{atom,Line,Tag}]), + {match,Line,{tuple,Line,Rp},Var}. + +opt_remove(Gs, Rs) -> + [opt_remove_1(G, Rs) || G <- Gs]. + +opt_remove_1(Ts, Rs) -> + [opt_remove_2(T, Rs) || T <- Ts]. + +opt_remove_2({op,L,'and'=Op,A1,A2}, Rs) -> + {op,L,Op,opt_remove_2(A1, Rs),opt_remove_2(A2, Rs)}; +opt_remove_2({op,L,'andalso'=Op,A1,A2}, Rs) -> + {op,L,Op,opt_remove_2(A1, Rs),opt_remove_2(A2, Rs)}; +opt_remove_2({op,L,'orelse',A1,A2}, Rs) -> + {op,L,'orelse',opt_remove_2(A1, Rs),A2}; +opt_remove_2({call,Line,{remote,_,{atom,_,erlang},{atom,_,is_record}}, + [{var,_,V},{atom,_,Tag},{integer,_,Sz}]}=A, Rs) -> + case orddict:find(V, Rs) of + {ok,{remove,Tag,Sz}} -> + {atom,Line,true}; + _ -> + A + end; +opt_remove_2({call,Line,{atom,_,is_record}, + [{var,_,V},{atom,_,Tag},{integer,_,Sz}]}=A, Rs) -> + case orddict:find(V, Rs) of + {ok,{remove,Tag,Sz}} -> + {atom,Line,true}; + _ -> + A + end; +opt_remove_2(A, _) -> A. + neg_line(L) -> erl_parse:set_line(L, fun(Line) -> -abs(Line) end). diff --git a/lib/stdlib/src/erl_internal.erl b/lib/stdlib/src/erl_internal.erl index 16173d8210..b30b02a96f 100644 --- a/lib/stdlib/src/erl_internal.erl +++ b/lib/stdlib/src/erl_internal.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1998-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(erl_internal). @@ -48,7 +48,7 @@ %% -export([bif/2,bif/3,guard_bif/2, - type_test/2,new_type_test/2,old_type_test/2]). + type_test/2,new_type_test/2,old_type_test/2,old_bif/2]). -export([arith_op/2,bool_op/2,comp_op/2,list_op/2,send_op/2,op_type/2]). %%--------------------------------------------------------------------------- @@ -87,6 +87,8 @@ guard_bif(is_reference, 1) -> true; guard_bif(is_tuple, 1) -> true; guard_bif(is_record, 2) -> true; guard_bif(is_record, 3) -> true; +guard_bif(binary_part, 2) -> true; +guard_bif(binary_part, 3) -> true; guard_bif(Name, A) when is_atom(Name), is_integer(A) -> false. %% Erlang type tests. @@ -229,11 +231,14 @@ bif(apply, 2) -> true; bif(apply, 3) -> true; bif(atom_to_binary, 2) -> true; bif(atom_to_list, 1) -> true; +bif(binary_part, 2) -> true; +bif(binary_part, 3) -> true; bif(binary_to_atom, 2) -> true; bif(binary_to_existing_atom, 2) -> true; bif(binary_to_list, 1) -> true; bif(binary_to_list, 3) -> true; bif(binary_to_term, 1) -> true; +bif(binary_to_term, 2) -> true; bif(bitsize, 1) -> true; bif(bit_size, 1) -> true; bif(bitstring_to_list, 1) -> true; @@ -242,10 +247,14 @@ bif(check_process_code, 2) -> true; bif(concat_binary, 1) -> true; bif(date, 0) -> true; bif(delete_module, 1) -> true; +bif(demonitor, 1) -> true; +bif(demonitor, 2) -> true; bif(disconnect_node, 1) -> true; bif(element, 2) -> true; bif(erase, 0) -> true; bif(erase, 1) -> true; +bif(error, 1) -> true; +bif(error, 2) -> true; bif(exit, 1) -> true; bif(exit, 2) -> true; bif(float, 1) -> true; @@ -261,6 +270,7 @@ bif(halt, 0) -> true; bif(halt, 1) -> true; bif(hd, 1) -> true; bif(integer_to_list, 1) -> true; +bif(integer_to_list, 2) -> true; bif(iolist_size, 1) -> true; bif(iolist_to_binary, 1) -> true; bif(is_alive, 0) -> true; @@ -290,11 +300,16 @@ bif(list_to_bitstring, 1) -> true; bif(list_to_existing_atom, 1) -> true; bif(list_to_float, 1) -> true; bif(list_to_integer, 1) -> true; +bif(list_to_integer, 2) -> true; bif(list_to_pid, 1) -> true; bif(list_to_tuple, 1) -> true; bif(load_module, 2) -> true; bif(make_ref, 0) -> true; +bif(max,2) -> true; +bif(min,2) -> true; bif(module_loaded, 1) -> true; +bif(monitor, 2) -> true; +bif(monitor, 3) -> true; bif(monitor_node, 2) -> true; bif(node, 0) -> true; bif(node, 1) -> true; @@ -305,6 +320,7 @@ bif(open_port, 2) -> true; bif(pid_to_list, 1) -> true; bif(port_close, 1) -> true; bif(port_command, 2) -> true; +bif(port_command, 3) -> true; bif(port_connect, 2) -> true; bif(port_control, 3) -> true; bif(pre_loaded, 0) -> true; @@ -349,3 +365,134 @@ bif(unlink, 1) -> true; bif(unregister, 1) -> true; bif(whereis, 1) -> true; bif(Name, A) when is_atom(Name), is_integer(A) -> false. + +-spec old_bif(Name::atom(), Arity::arity()) -> boolean(). +%% Returns true if erlang:Name/Arity is an old (pre R14) auto-imported BIF, false otherwise. +%% Use erlang:is_bultin(Mod, Name, Arity) to find whether a function is a BIF +%% (meaning implemented in C) or not. + +old_bif(abs, 1) -> true; +old_bif(apply, 2) -> true; +old_bif(apply, 3) -> true; +old_bif(atom_to_binary, 2) -> true; +old_bif(atom_to_list, 1) -> true; +old_bif(binary_to_atom, 2) -> true; +old_bif(binary_to_existing_atom, 2) -> true; +old_bif(binary_to_list, 1) -> true; +old_bif(binary_to_list, 3) -> true; +old_bif(binary_to_term, 1) -> true; +old_bif(bitsize, 1) -> true; +old_bif(bit_size, 1) -> true; +old_bif(bitstring_to_list, 1) -> true; +old_bif(byte_size, 1) -> true; +old_bif(check_process_code, 2) -> true; +old_bif(concat_binary, 1) -> true; +old_bif(date, 0) -> true; +old_bif(delete_module, 1) -> true; +old_bif(disconnect_node, 1) -> true; +old_bif(element, 2) -> true; +old_bif(erase, 0) -> true; +old_bif(erase, 1) -> true; +old_bif(exit, 1) -> true; +old_bif(exit, 2) -> true; +old_bif(float, 1) -> true; +old_bif(float_to_list, 1) -> true; +old_bif(garbage_collect, 0) -> true; +old_bif(garbage_collect, 1) -> true; +old_bif(get, 0) -> true; +old_bif(get, 1) -> true; +old_bif(get_keys, 1) -> true; +old_bif(group_leader, 0) -> true; +old_bif(group_leader, 2) -> true; +old_bif(halt, 0) -> true; +old_bif(halt, 1) -> true; +old_bif(hd, 1) -> true; +old_bif(integer_to_list, 1) -> true; +old_bif(iolist_size, 1) -> true; +old_bif(iolist_to_binary, 1) -> true; +old_bif(is_alive, 0) -> true; +old_bif(is_process_alive, 1) -> true; +old_bif(is_atom, 1) -> true; +old_bif(is_boolean, 1) -> true; +old_bif(is_binary, 1) -> true; +old_bif(is_bitstr, 1) -> true; +old_bif(is_bitstring, 1) -> true; +old_bif(is_float, 1) -> true; +old_bif(is_function, 1) -> true; +old_bif(is_function, 2) -> true; +old_bif(is_integer, 1) -> true; +old_bif(is_list, 1) -> true; +old_bif(is_number, 1) -> true; +old_bif(is_pid, 1) -> true; +old_bif(is_port, 1) -> true; +old_bif(is_reference, 1) -> true; +old_bif(is_tuple, 1) -> true; +old_bif(is_record, 2) -> true; +old_bif(is_record, 3) -> true; +old_bif(length, 1) -> true; +old_bif(link, 1) -> true; +old_bif(list_to_atom, 1) -> true; +old_bif(list_to_binary, 1) -> true; +old_bif(list_to_bitstring, 1) -> true; +old_bif(list_to_existing_atom, 1) -> true; +old_bif(list_to_float, 1) -> true; +old_bif(list_to_integer, 1) -> true; +old_bif(list_to_pid, 1) -> true; +old_bif(list_to_tuple, 1) -> true; +old_bif(load_module, 2) -> true; +old_bif(make_ref, 0) -> true; +old_bif(module_loaded, 1) -> true; +old_bif(monitor_node, 2) -> true; +old_bif(node, 0) -> true; +old_bif(node, 1) -> true; +old_bif(nodes, 0) -> true; +old_bif(nodes, 1) -> true; +old_bif(now, 0) -> true; +old_bif(open_port, 2) -> true; +old_bif(pid_to_list, 1) -> true; +old_bif(port_close, 1) -> true; +old_bif(port_command, 2) -> true; +old_bif(port_connect, 2) -> true; +old_bif(port_control, 3) -> true; +old_bif(pre_loaded, 0) -> true; +old_bif(process_flag, 2) -> true; +old_bif(process_flag, 3) -> true; +old_bif(process_info, 1) -> true; +old_bif(process_info, 2) -> true; +old_bif(processes, 0) -> true; +old_bif(purge_module, 1) -> true; +old_bif(put, 2) -> true; +old_bif(register, 2) -> true; +old_bif(registered, 0) -> true; +old_bif(round, 1) -> true; +old_bif(self, 0) -> true; +old_bif(setelement, 3) -> true; +old_bif(size, 1) -> true; +old_bif(spawn, 1) -> true; +old_bif(spawn, 2) -> true; +old_bif(spawn, 3) -> true; +old_bif(spawn, 4) -> true; +old_bif(spawn_link, 1) -> true; +old_bif(spawn_link, 2) -> true; +old_bif(spawn_link, 3) -> true; +old_bif(spawn_link, 4) -> true; +old_bif(spawn_monitor, 1) -> true; +old_bif(spawn_monitor, 3) -> true; +old_bif(spawn_opt, 2) -> true; +old_bif(spawn_opt, 3) -> true; +old_bif(spawn_opt, 4) -> true; +old_bif(spawn_opt, 5) -> true; +old_bif(split_binary, 2) -> true; +old_bif(statistics, 1) -> true; +old_bif(term_to_binary, 1) -> true; +old_bif(term_to_binary, 2) -> true; +old_bif(throw, 1) -> true; +old_bif(time, 0) -> true; +old_bif(tl, 1) -> true; +old_bif(trunc, 1) -> true; +old_bif(tuple_size, 1) -> true; +old_bif(tuple_to_list, 1) -> true; +old_bif(unlink, 1) -> true; +old_bif(unregister, 1) -> true; +old_bif(whereis, 1) -> true; +old_bif(Name, A) when is_atom(Name), is_integer(A) -> false. diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl index 91f7641af7..077621ac91 100644 --- a/lib/stdlib/src/erl_lint.erl +++ b/lib/stdlib/src/erl_lint.erl @@ -40,7 +40,7 @@ %% Value. %% The option handling functions. --spec bool_option(atom(), atom(), boolean(), [_]) -> boolean(). +-spec bool_option(atom(), atom(), boolean(), [compile:option()]) -> boolean(). bool_option(On, Off, Default, Opts) -> foldl(fun (Opt, _Def) when Opt =:= On -> true; @@ -72,6 +72,10 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) -> %%-define(DEBUGF(X,Y), io:format(X, Y)). -define(DEBUGF(X,Y), void). +-type line() :: erl_scan:line(). % a convenient alias +-type fa() :: {atom(), arity()}. % function+arity +-type ta() :: {atom(), arity()}. % type+arity + %% Usage of records, functions, and imports. The variable table, which %% is passed on as an argument, holds the usage of variables. -record(usage, { @@ -94,9 +98,11 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) -> mod_imports=dict:new() :: dict(), %Module Imports compile=[], %Compile flags records=dict:new() :: dict(), %Record definitions + locals=gb_sets:empty() :: gb_set(), %All defined functions (prescanned) + no_auto=gb_sets:empty() :: gb_set(), %Functions explicitly not autoimported defined=gb_sets:empty() :: gb_set(), %Defined fuctions - on_load=[] :: [{atom(),integer()}], %On-load function - on_load_line=0 :: integer(), %Line for on_load + on_load=[] :: [fa()], %On-load function + on_load_line=0 :: line(), %Line for on_load clashes=[], %Exported functions named as BIFs not_deprecated=[], %Not considered deprecated func=[], %Current function @@ -110,10 +116,11 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) -> %outside any fun or lc xqlc= false :: boolean(), %true if qlc.hrl included new = false :: boolean(), %Has user-defined 'new/N' - called= [], %Called functions + called= [] :: [{fa(),line()}], %Called functions usage = #usage{} :: #usage{}, specs = dict:new() :: dict(), %Type specifications - types = dict:new() :: dict() %Type definitions + types = dict:new() :: dict(), %Type definitions + exp_types=gb_sets:empty():: gb_set() %Exported types }). -type lint_state() :: #lint{}. @@ -161,6 +168,9 @@ format_error({bad_nowarn_unused_function,{F,A}}) -> io_lib:format("function ~w/~w undefined", [F,A]); format_error({bad_nowarn_bif_clash,{F,A}}) -> io_lib:format("function ~w/~w undefined", [F,A]); +format_error(disallowed_nowarn_bif_clash) -> + io_lib:format("compile directive nowarn_bif_clash is no longer allowed,~n" + " - use explicit module names or -compile({no_auto_import, [F/A]})", []); format_error({bad_nowarn_deprecated_function,{M,F,A}}) -> io_lib:format("~w:~w/~w is not a deprecated function", [M,F,A]); format_error({bad_on_load,Term}) -> @@ -186,13 +196,21 @@ format_error({define_import,{F,A}}) -> io_lib:format("defining imported function ~w/~w", [F,A]); format_error({unused_function,{F,A}}) -> io_lib:format("function ~w/~w is unused", [F,A]); -format_error({redefine_bif,{F,A}}) -> - io_lib:format("defining BIF ~w/~w", [F,A]); format_error({call_to_redefined_bif,{F,A}}) -> - io_lib:format("call to ~w/~w will call erlang:~w/~w; " - "not ~w/~w in this module \n" - " (add an explicit module name to the call to avoid this error)", - [F,A,F,A,F,A]); + io_lib:format("ambiguous call of overridden auto-imported BIF ~w/~w~n" + " - use erlang:~w/~w or \"-compile({no_auto_import,[~w/~w]}).\" " + "to resolve name clash", [F,A,F,A,F,A]); +format_error({call_to_redefined_old_bif,{F,A}}) -> + io_lib:format("ambiguous call of overridden pre R14 auto-imported BIF ~w/~w~n" + " - use erlang:~w/~w or \"-compile({no_auto_import,[~w/~w]}).\" " + "to resolve name clash", [F,A,F,A,F,A]); +format_error({redefine_old_bif_import,{F,A}}) -> + io_lib:format("import directive overrides pre R14 auto-imported BIF ~w/~w~n" + " - use \"-compile({no_auto_import,[~w/~w]}).\" " + "to resolve name clash", [F,A,F,A]); +format_error({redefine_bif_import,{F,A}}) -> + io_lib:format("import directive overrides auto-imported BIF ~w/~w~n" + " - use \"-compile({no_auto_import,[~w/~w]}).\" to resolve name clash", [F,A,F,A]); format_error({deprecated, MFA, ReplacementMFA, Rel}) -> io_lib:format("~s is deprecated and will be removed in ~s; use ~s", @@ -213,6 +231,9 @@ format_error(illegal_pattern) -> "illegal pattern"; format_error(illegal_bin_pattern) -> "binary patterns cannot be matched in parallel using '='"; format_error(illegal_expr) -> "illegal expression"; +format_error({illegal_guard_local_call, {F,A}}) -> + io_lib:format("call to local/imported function ~w/~w is illegal in guard", + [F,A]); format_error(illegal_guard_expr) -> "illegal guard expression"; %% --- exports --- format_error({explicit_export,F,A}) -> @@ -242,10 +263,10 @@ format_error({untyped_record,T}) -> format_error({unbound_var,V}) -> io_lib:format("variable ~w is unbound", [V]); format_error({unsafe_var,V,{What,Where}}) -> - io_lib:format("variable ~w unsafe in ~w ~s", + io_lib:format("variable ~w unsafe in ~w ~s", [V,What,format_where(Where)]); format_error({exported_var,V,{What,Where}}) -> - io_lib:format("variable ~w exported from ~w ~s", + io_lib:format("variable ~w exported from ~w ~s", [V,What,format_where(Where)]); format_error({shadowed_var,V,In}) -> io_lib:format("variable ~w shadowed in ~w", [V,In]); @@ -290,22 +311,24 @@ format_error({ill_defined_behaviour_callbacks,Behaviour}) -> %% --- types and specs --- format_error({singleton_typevar, Name}) -> io_lib:format("type variable ~w is only used once (is unbound)", [Name]); +format_error({duplicated_export_type, {T, A}}) -> + io_lib:format("type ~w/~w already exported", [T, A]); format_error({undefined_type, {TypeName, Arity}}) -> io_lib:format("type ~w~s undefined", [TypeName, gen_type_paren(Arity)]); format_error({unused_type, {TypeName, Arity}}) -> io_lib:format("type ~w~s is unused", [TypeName, gen_type_paren(Arity)]); format_error({new_builtin_type, {TypeName, Arity}}) -> io_lib:format("type ~w~s is a new builtin type; " - "its (re)definition is allowed only until the next release", + "its (re)definition is allowed only until the next release", [TypeName, gen_type_paren(Arity)]); format_error({builtin_type, {TypeName, Arity}}) -> - io_lib:format("type ~w~s is a builtin type; it cannot be redefined", + io_lib:format("type ~w~s is a builtin type; it cannot be redefined", [TypeName, gen_type_paren(Arity)]); format_error({renamed_type, OldName, NewName}) -> io_lib:format("type ~w() is now called ~w(); " "please use the new name instead", [OldName, NewName]); format_error({redefine_type, {TypeName, Arity}}) -> - io_lib:format("type ~w~s already defined", + io_lib:format("type ~w~s already defined", [TypeName, gen_type_paren(Arity)]); format_error({type_syntax, Constr}) -> io_lib:format("bad ~w type", [Constr]); @@ -354,7 +377,7 @@ pseudolocals() -> %% %% Used by erl_eval.erl to check commands. -%% +%% exprs(Exprs, BindingsList) -> exprs_opt(Exprs, BindingsList, []). @@ -362,7 +385,7 @@ exprs_opt(Exprs, BindingsList, Opts) -> {St0,Vs} = foldl(fun({{record,_SequenceNumber,_Name},Attr0}, {St1,Vs1}) -> Attr = zip_file_and_line(Attr0, "none"), {attribute_state(Attr, St1),Vs1}; - ({V,_}, {St1,Vs1}) -> + ({V,_}, {St1,Vs1}) -> {St1,[{V,{bound,unused,[]}} | Vs1]} end, {start("nofile",Opts),[]}, BindingsList), Vt = orddict:from_list(Vs), @@ -391,7 +414,7 @@ module(Forms) -> Opts = compiler_options(Forms), St = forms(Forms, start("nofile", Opts)), return_status(St). - + module(Forms, FileName) -> Opts = compiler_options(Forms), St = forms(Forms, start(FileName, Opts)), @@ -506,7 +529,7 @@ pack_errors(Es) -> %% Sort on line number. pack_warnings(Ws) -> - [{File,lists:sort([W || {F,W} <- Ws, F =:= File])} || + [{File,lists:sort([W || {F,W} <- Ws, F =:= File])} || File <- lists:usort([F || {F,_} <- Ws])]. %% add_error(ErrorDescriptor, State) -> State' @@ -516,13 +539,13 @@ pack_warnings(Ws) -> add_error(E, St) -> St#lint{errors=[{St#lint.file,E}|St#lint.errors]}. -add_error(FileLine, E, St) -> +add_error(FileLine, E, St) -> {File,Location} = loc(FileLine), add_error({Location,erl_lint,E}, St#lint{file = File}). add_warning(W, St) -> St#lint{warnings=[{St#lint.file,W}|St#lint.warnings]}. -add_warning(FileLine, W, St) -> +add_warning(FileLine, W, St) -> {File,Location} = loc(FileLine), add_warning({Location,erl_lint,W}, St#lint{file = File}). @@ -538,8 +561,12 @@ loc(L) -> forms(Forms0, St0) -> Forms = eval_file_attribute(Forms0, St0), + Locals = local_functions(Forms), + AutoImportSuppressed = auto_import_suppressed(St0#lint.compile), + StDeprecated = disallowed_compile_flags(Forms,St0), %% Line numbers are from now on pairs {File,Line}. - St1 = includes_qlc_hrl(Forms, St0), + St1 = includes_qlc_hrl(Forms, StDeprecated#lint{locals = Locals, + no_auto = AutoImportSuppressed}), St2 = bif_clashes(Forms, St1), St3 = not_deprecated(Forms, St2), St4 = foldl(fun form/2, pre_scan(Forms, St3), Forms), @@ -561,7 +588,7 @@ pre_scan([_ | Fs], St) -> pre_scan(Fs, St); pre_scan([], St) -> St. - + includes_qlc_hrl(Forms, St) -> %% QLC calls erl_lint several times, sometimes with the compile %% attribute removed. The file attribute, however, is left as is. @@ -667,6 +694,8 @@ attribute_state({attribute,L,extends,_M}, St) -> add_error(L, invalid_extends, St); attribute_state({attribute,L,export,Es}, St) -> export(L, Es, St); +attribute_state({attribute,L,export_type,Es}, St) -> + export_type(L, Es, St); attribute_state({attribute,L,import,Is}, St) -> import(L, Is, St); attribute_state({attribute,L,record,{Name,Fields}}, St) -> @@ -724,27 +753,38 @@ bif_clashes(Forms, St) -> Clashes = ordsets:subtract(ordsets:from_list(Clashes0), Nowarn), St#lint{clashes=Clashes}. --spec is_bif_clash(atom(), byte(), lint_state()) -> boolean(). - -is_bif_clash(_Name, _Arity, #lint{clashes=[]}) -> - false; -is_bif_clash(Name, Arity, #lint{clashes=Clashes}) -> - ordsets:is_element({Name,Arity}, Clashes). - %% not_deprecated(Forms, State0) -> State not_deprecated(Forms, St0) -> %% There are no line numbers in St0#lint.compile. - MFAsL = [{MFA,L} || + MFAsL = [{MFA,L} || {attribute, L, compile, Args} <- Forms, {nowarn_deprecated_function, MFAs0} <- lists:flatten([Args]), MFA <- lists:flatten([MFAs0])], Nowarn = [MFA || {MFA,_L} <- MFAsL], - Bad = [MFAL || {{M,F,A},_L}=MFAL <- MFAsL, + Bad = [MFAL || {{M,F,A},_L}=MFAL <- MFAsL, otp_internal:obsolete(M, F, A) =:= no], St1 = func_line_warning(bad_nowarn_deprecated_function, Bad, St0), St1#lint{not_deprecated = ordsets:from_list(Nowarn)}. +%% The nowarn_bif_clash directive is not only deprecated, it's actually an error from R14A +disallowed_compile_flags(Forms, St0) -> + %% There are (still) no line numbers in St0#lint.compile. + Errors0 = [ {St0#lint.file,{L,erl_lint,disallowed_nowarn_bif_clash}} || + {attribute,[{line,{_,L}}],compile,nowarn_bif_clash} <- Forms ], + Errors1 = [ {St0#lint.file,{L,erl_lint,disallowed_nowarn_bif_clash}} || + {attribute,[{line,{_,L}}],compile,{nowarn_bif_clash, {_,_}}} <- Forms ], + Disabled = (not is_warn_enabled(bif_clash, St0)), + Errors = if + Disabled andalso Errors0 =:= [] -> + [{St0#lint.file,{erl_lint,disallowed_nowarn_bif_clash}} | St0#lint.errors]; + Disabled -> + Errors0 ++ Errors1 ++ St0#lint.errors; + true -> + Errors1 ++ St0#lint.errors + end, + St0#lint{errors=Errors}. + %% post_traversal_check(Forms, State0) -> State. %% Do some further checking after the forms have been traversed and %% data about calls etc. have been collected. @@ -862,7 +902,7 @@ check_deprecated(Forms, St0) -> Bad = [{E,L} || {attribute, L, deprecated, Depr} <- Forms, D <- lists:flatten([Depr]), E <- depr_cat(D, X, Mod)], - foldl(fun ({E,L}, St1) -> + foldl(fun ({E,L}, St1) -> add_error(L, E, St1) end, St0, Bad). @@ -912,7 +952,7 @@ check_imports(Forms, St0) -> true -> Usage = St0#lint.usage, Unused = ordsets:subtract(St0#lint.imports, Usage#usage.imported), - Imports = [{{FA,list_to_atom(package_to_string(Mod))},L} + Imports = [{{FA,list_to_atom(package_to_string(Mod))},L} || {attribute,L,import,{Mod,Fs}} <- Forms, FA <- lists:usort(Fs)], Bad = [{FM,L} || FM <- Unused, {FM2,L} <- Imports, FM =:= FM2], @@ -932,7 +972,7 @@ check_unused_functions(Forms, St0) -> Opts = St1#lint.compile, case member(export_all, Opts) orelse not is_warn_enabled(unused_function, St1) of - true -> + true -> St1; false -> Nowarn = nowarn_function(nowarn_unused_function, Opts), @@ -1003,12 +1043,13 @@ check_option_functions(Forms, Tag0, Type, St0) -> {Tag, FAs0} <- lists:flatten([Args]), Tag0 =:= Tag, FA <- lists:flatten([FAs0])], - DefFunctions = gb_sets:to_list(St0#lint.defined) -- pseudolocals(), + DefFunctions = (gb_sets:to_list(St0#lint.defined) -- pseudolocals()) ++ + [{F,A} || {{F,A},_} <- orddict:to_list(St0#lint.imports)], Bad = [{FA,L} || {FA,L} <- FAsL, not member(FA, DefFunctions)], func_line_error(Type, Bad, St0). nowarn_function(Tag, Opts) -> - ordsets:from_list([FA || {Tag1,FAs} <- Opts, + ordsets:from_list([FA || {Tag1,FAs} <- Opts, Tag1 =:= Tag, FA <- lists:flatten([FAs])]). @@ -1021,11 +1062,8 @@ func_line_error(Type, Fs, St) -> check_untyped_records(Forms, St0) -> case is_warn_enabled(untyped_record, St0) of true -> - %% One possibility is to use the names of all records - %% RecNames = dict:fetch_keys(St0#lint.records), - %% but I think it's better to keep those that are used by the file - Usage = St0#lint.usage, - UsedRecNames = sets:to_list(Usage#usage.used_records), + %% Use the names of all records *defined* in the module (not used) + RecNames = dict:fetch_keys(St0#lint.records), %% these are the records with field(s) containing type info TRecNames = [Name || {attribute,_,type,{{record,Name},Fields,_}} <- Forms, @@ -1038,7 +1076,7 @@ check_untyped_records(Forms, St0) -> [] -> St; % exclude records with no fields [_|_] -> add_warning(L, {untyped_record, N}, St) end - end, St0, UsedRecNames -- TRecNames); + end, St0, RecNames -- TRecNames); false -> St0 end. @@ -1051,10 +1089,10 @@ check_unused_records(Forms, St0) -> %% functions count. Usage = St0#lint.usage, UsedRecords = sets:to_list(Usage#usage.used_records), - URecs = foldl(fun (Used, Recs) -> - dict:erase(Used, Recs) + URecs = foldl(fun (Used, Recs) -> + dict:erase(Used, Recs) end, St0#lint.records, UsedRecords), - Unused = [{Name,FileLine} || + Unused = [{Name,FileLine} || {Name,{FileLine,_Fields}} <- dict:to_list(URecs), element(1, loc(FileLine)) =:= FirstFile], foldl(fun ({N,L}, St) -> @@ -1064,18 +1102,19 @@ check_unused_records(Forms, St0) -> St0 end. -%% For storing the import list we use the orddict module. +%% For storing the import list we use the orddict module. %% We know an empty set is []. -%% export(Line, Exports, State) -> State. +-spec export(line(), [fa()], lint_state()) -> lint_state(). %% Mark functions as exported, also as called from the export line. export(Line, Es, #lint{exports = Es0, called = Called} = St0) -> - {Es1,C1,St1} = + {Es1,C1,St1} = foldl(fun (NA, {E,C,St2}) -> St = case gb_sets:is_element(NA, E) of true -> - add_warning(Line, {duplicated_export, NA}, St2); + Warn = {duplicated_export,NA}, + add_warning(Line, Warn, St2); false -> St2 end, @@ -1084,8 +1123,27 @@ export(Line, Es, #lint{exports = Es0, called = Called} = St0) -> {Es0,Called,St0}, Es), St1#lint{exports = Es1, called = C1}. -%% import(Line, Imports, State) -> State. -%% imported(Name, Arity, State) -> {yes,Module} | no. +-spec export_type(line(), [ta()], lint_state()) -> lint_state(). +%% Mark types as exported; also mark them as used from the export line. + +export_type(Line, ETs, #lint{usage = Usage, exp_types = ETs0} = St0) -> + UTs0 = Usage#usage.used_types, + {ETs1,UTs1,St1} = + foldl(fun (TA, {E,U,St2}) -> + St = case gb_sets:is_element(TA, E) of + true -> + Warn = {duplicated_export_type,TA}, + add_warning(Line, Warn, St2); + false -> + St2 + end, + {gb_sets:add_element(TA, E), dict:store(TA, Line, U), St} + end, + {ETs0,UTs0,St0}, ETs), + St1#lint{usage = Usage#usage{used_types = UTs1}, exp_types = ETs1}. + +-type import() :: {module(), [fa()]} | module(). +-spec import(line(), import(), lint_state()) -> lint_state(). import(Line, {Mod,Fs}, St) -> Mod1 = package_to_string(Mod), @@ -1097,11 +1155,41 @@ import(Line, {Mod,Fs}, St) -> St#lint{imports=add_imports(list_to_atom(Mod1), Mfs, St#lint.imports)}; Efs -> - foldl(fun (Ef, St0) -> - add_error(Line, {redefine_import,Ef}, - St0) + {Err, St1} = + foldl(fun ({bif,{F,A},_}, {Err,St0}) -> + %% BifClash - import directive + Warn = is_warn_enabled(bif_clash, St0) + and (not bif_clash_specifically_disabled(St0,{F,A})), + AutoImpSup = is_autoimport_suppressed(St0#lint.no_auto,{F,A}), + OldBif = erl_internal:old_bif(F,A), + {Err,if + Warn and (not AutoImpSup) and OldBif -> + add_error + (Line, + {redefine_old_bif_import, {F,A}}, + St0); + Warn and (not AutoImpSup) -> + add_warning + (Line, + {redefine_bif_import, {F,A}}, + St0); + true -> + St0 + end}; + (Ef, {_Err,St0}) -> + {true,add_error(Line, + {redefine_import,Ef}, + St0)} end, - St, Efs) + {false,St}, Efs), + if + not Err -> + St1#lint{imports= + add_imports(list_to_atom(Mod1), Mfs, + St#lint.imports)}; + true -> + St1 + end end; false -> add_error(Line, {bad_module_name, Mod1}, St) @@ -1144,13 +1232,15 @@ check_imports(_Line, Fs, Is) -> add_imports(Mod, Fs, Is) -> foldl(fun (F, Is0) -> orddict:store(F, Mod, Is0) end, Is, Fs). +-spec imported(atom(), arity(), lint_state()) -> {'yes',module()} | 'no'. + imported(F, A, St) -> case orddict:find({F,A}, St#lint.imports) of {ok,Mod} -> {yes,Mod}; error -> no end. -%% on_load(Line, Val, State) -> State. +-spec on_load(line(), fa(), lint_state()) -> lint_state(). %% Check an on_load directive and remember it. on_load(Line, {Name,Arity}=Fa, #lint{on_load=OnLoad0}=St0) @@ -1182,7 +1272,7 @@ check_on_load(#lint{defined=Defined,on_load=[{_,0}=Fa], end; check_on_load(St) -> St. -%% call_function(Line, Name, Arity, State) -> State. +-spec call_function(line(), atom(), arity(), lint_state()) -> lint_state(). %% Add to both called and calls. call_function(Line, F, A, #lint{usage=Usage0,called=Cd,func=Func}=St) -> @@ -1194,12 +1284,6 @@ call_function(Line, F, A, #lint{usage=Usage0,called=Cd,func=Func}=St) -> end, St#lint{called=[{NA,Line}|Cd], usage=Usage}. -%% is_function_exported(Name, Arity, State) -> false|true. - -is_function_exported(Name, Arity, #lint{exports=Exports,compile=Compile}) -> - gb_sets:is_element({Name,Arity}, Exports) orelse - member(export_all, Compile). - %% function(Line, Name, Arity, Clauses, State) -> State. function(Line, instance, _Arity, _Cs, St) when St#lint.global_vt =/= [] -> @@ -1208,7 +1292,7 @@ function(Line, Name, Arity, Cs, St0) -> St1 = define_function(Line, Name, Arity, St0#lint{func={Name,Arity}}), clauses(Cs, St1#lint.global_vt, St1). -%% define_function(Line, Name, Arity, State) -> State. +-spec define_function(line(), atom(), arity(), lint_state()) -> lint_state(). define_function(Line, Name, Arity, St0) -> St1 = keyword_warning(Line, Name, St0), @@ -1218,14 +1302,9 @@ define_function(Line, Name, Arity, St0) -> add_error(Line, {redefine_function,NA}, St1); false -> St2 = St1#lint{defined=gb_sets:add_element(NA, St1#lint.defined)}, - St = case erl_internal:bif(Name, Arity) andalso - not is_function_exported(Name, Arity, St2) of - true -> add_warning(Line, {redefine_bif,NA}, St2); - false -> St2 - end, - case imported(Name, Arity, St) of - {yes,_M} -> add_error(Line, {define_import,NA}, St); - no -> St + case imported(Name, Arity, St2) of + {yes,_M} -> add_error(Line, {define_import,NA}, St2); + no -> St2 end end. @@ -1261,7 +1340,7 @@ head([P|Ps], Vt, Old, St0) -> {vtmerge_pat(Pvt, Psvt),vtmerge_pat(Bvt1,Bvt2),St2}; head([], _Vt, _Env, St) -> {[],[],St}. -%% pattern(Pattern, VarTable, Old, BinVarTable, State) -> +%% pattern(Pattern, VarTable, Old, BinVarTable, State) -> %% {UpdVarTable,BinVarTable,State}. %% Check pattern return variables. Old is the set of variables used for %% deciding whether an occurrence is a binding occurrence or a use, and @@ -1279,7 +1358,7 @@ pattern(P, Vt, St) -> pattern({var,_Line,'_'}, _Vt, _Old, _Bvt, St) -> {[],[],St}; %Ignore anonymous variable -pattern({var,Line,V}, _Vt, Old, Bvt, St) -> +pattern({var,Line,V}, _Vt, Old, Bvt, St) -> pat_var(V, Line, Old, Bvt, St); pattern({char,_Line,_C}, _Vt, _Old, _Bvt, St) -> {[],[],St}; pattern({integer,_Line,_I}, _Vt, _Old, _Bvt, St) -> {[],[],St}; @@ -1297,7 +1376,7 @@ pattern({tuple,_Line,Ps}, Vt, Old, Bvt, St) -> %%pattern({struct,_Line,_Tag,Ps}, Vt, Old, Bvt, St) -> %% pattern_list(Ps, Vt, Old, Bvt, St); pattern({record_index,Line,Name,Field}, _Vt, _Old, _Bvt, St) -> - {Vt1,St1} = + {Vt1,St1} = check_record(Line, Name, St, fun (Dfs, St1) -> pattern_field(Field, Name, Dfs, St1) @@ -1312,7 +1391,7 @@ pattern({record_field,Line,_,_}=M, _Vt, _Old, _Bvt, St0) -> end; pattern({record,Line,Name,Pfs}, Vt, Old, Bvt, St) -> case dict:find(Name, St#lint.records) of - {ok,{_Line,Fields}} -> + {ok,{_Line,Fields}} -> St1 = used_record(Name, St), pattern_fields(Pfs, Name, Fields, Vt, Old, Bvt, St1); error -> {[],[],add_error(Line, {undefined_record,Name}, St)} @@ -1372,7 +1451,7 @@ reject_bin_alias({cons,_,H1,T1}, {cons,_,H2,T2}, St0) -> reject_bin_alias(T1, T2, St); reject_bin_alias({tuple,_,Es1}, {tuple,_,Es2}, St) -> reject_bin_alias_list(Es1, Es2, St); -reject_bin_alias({record,_,Name1,Pfs1}, {record,_,Name2,Pfs2}, +reject_bin_alias({record,_,Name1,Pfs1}, {record,_,Name2,Pfs2}, #lint{records=Recs}=St) -> case {dict:find(Name1, Recs),dict:find(Name2, Recs)} of {{ok,{_Line1,Fields1}},{ok,{_Line2,Fields2}}} -> @@ -1454,7 +1533,7 @@ is_pattern_expr_1({op,_Line,Op,A1,A2}) -> erl_internal:arith_op(Op, 2) andalso all(fun is_pattern_expr/1, [A1,A2]); is_pattern_expr_1(_Other) -> false. -%% pattern_bin([Element], VarTable, Old, BinVarTable, State) -> +%% pattern_bin([Element], VarTable, Old, BinVarTable, State) -> %% {UpdVarTable,UpdBinVarTable,State}. %% Check a pattern group. BinVarTable are used binsize variables. @@ -1501,7 +1580,7 @@ good_string_size_type(default, Ts) -> end, Ts); good_string_size_type(_, _) -> false. -%% pat_bit_expr(Pattern, OldVarTable, BinVarTable,State) -> +%% pat_bit_expr(Pattern, OldVarTable, BinVarTable,State) -> %% {UpdVarTable,UpdBinVarTable,State}. %% Check pattern bit expression, only allow really valid patterns! @@ -1516,7 +1595,7 @@ pat_bit_expr(P, _Old, _Bvt, St) -> false -> {[],[],add_error(element(2, P), illegal_pattern, St)} end. -%% pat_bit_size(Size, VarTable, BinVarTable, State) -> +%% pat_bit_size(Size, VarTable, BinVarTable, State) -> %% {Value,UpdVarTable,UpdBinVarTable,State}. %% Check pattern size expression, only allow really valid sizes! @@ -1599,7 +1678,7 @@ bit_size_check(Line, Size, #bittype{type=Type,unit=Unit}, St) -> Sz = Unit * Size, %Total number of bits! St2 = elemtype_check(Line, Type, Sz, St), {Sz,St2}. - + elemtype_check(_Line, float, 32, St) -> St; elemtype_check(_Line, float, 64, St) -> St; elemtype_check(Line, float, _Size, St) -> @@ -1681,8 +1760,6 @@ gexpr({cons,_Line,H,T}, Vt, St) -> gexpr_list([H,T], Vt, St); gexpr({tuple,_Line,Es}, Vt, St) -> gexpr_list(Es, Vt, St); -%%gexpr({struct,_Line,_Tag,Es}, Vt, St) -> -%% gexpr_list(Es, Vt, St); gexpr({record_index,Line,Name,Field}, _Vt, St) -> check_record(Line, Name, St, fun (Dfs, St1) -> record_field(Field, Name, Dfs, St1) end ); @@ -1713,7 +1790,7 @@ gexpr({call,_Line,{atom,_Lr,is_record},[E,{atom,Ln,Name}]}, Vt, St0) -> gexpr({call,Line,{atom,_Lr,is_record},[E,R]}, Vt, St0) -> {Asvt,St1} = gexpr_list([E,R], Vt, St0), {Asvt,add_error(Line, illegal_guard_expr, St1)}; -gexpr({call,Line,{remote,_Lr,{atom,_Lm,erlang},{atom,Lf,is_record}},[E,A]}, +gexpr({call,Line,{remote,_Lr,{atom,_Lm,erlang},{atom,Lf,is_record}},[E,A]}, Vt, St0) -> gexpr({call,Line,{atom,Lf,is_record},[E,A]}, Vt, St0); gexpr({call,_Line,{atom,_Lr,is_record},[E,{atom,_,_Name},{integer,_,_}]}, @@ -1728,14 +1805,22 @@ gexpr({call,Line,{remote,_,{atom,_,erlang},{atom,_,is_record}=Isr},[_,_,_]=Args} gexpr({call,Line,{atom,_La,F},As}, Vt, St0) -> {Asvt,St1} = gexpr_list(As, Vt, St0), A = length(As), - case erl_internal:guard_bif(F, A) of + %% BifClash - Function called in guard + case erl_internal:guard_bif(F, A) andalso no_guard_bif_clash(St1,{F,A}) of true -> %% Also check that it is auto-imported. case erl_internal:bif(F, A) of true -> {Asvt,St1}; false -> {Asvt,add_error(Line, {explicit_export,F,A}, St1)} end; - false -> {Asvt,add_error(Line, illegal_guard_expr, St1)} + false -> + case is_local_function(St1#lint.locals,{F,A}) orelse + is_imported_function(St1#lint.imports,{F,A}) of + true -> + {Asvt,add_error(Line, {illegal_guard_local_call,{F,A}}, St1)}; + _ -> + {Asvt,add_error(Line, illegal_guard_expr, St1)} + end end; gexpr({call,Line,{remote,_Lr,{atom,_Lm,erlang},{atom,_Lf,F}},As}, Vt, St0) -> {Asvt,St1} = gexpr_list(As, Vt, St0), @@ -1780,7 +1865,7 @@ is_guard_test(E) -> %% is_guard_test(Expression, Forms) -> boolean(). is_guard_test(Expression, Forms) -> RecordAttributes = [A || A = {attribute, _, record, _D} <- Forms], - St0 = foldl(fun(Attr0, St1) -> + St0 = foldl(fun(Attr0, St1) -> Attr = zip_file_and_line(Attr0, "none"), attribute_state(Attr, St1) end, start(), RecordAttributes), @@ -1801,7 +1886,7 @@ is_guard_test2(G, RDs) -> %% is_guard_expr(Expression) -> boolean(). %% Test if an expression is a guard expression. -is_guard_expr(E) -> is_gexpr(E, []). +is_guard_expr(E) -> is_gexpr(E, []). is_gexpr({var,_L,_V}, _RDs) -> true; is_gexpr({char,_L,_C}, _RDs) -> true; @@ -1823,7 +1908,7 @@ is_gexpr({record_field,_L,Rec,_Name,Field}, RDs) -> is_gexpr({record,L,Name,Inits}, RDs) -> is_gexpr_fields(Inits, L, Name, RDs); is_gexpr({bin,_L,Fs}, RDs) -> - all(fun ({bin_element,_Line,E,Sz,_Ts}) -> + all(fun ({bin_element,_Line,E,Sz,_Ts}) -> is_gexpr(E, RDs) and (Sz =:= default orelse is_gexpr(Sz, RDs)) end, Fs); is_gexpr({call,_L,{atom,_Lf,F},As}, RDs) -> @@ -1898,15 +1983,13 @@ expr({bc,_Line,E,Qs}, Vt0, St0) -> {vtold(Vt,Vt0),St}; %Don't export local variables expr({tuple,_Line,Es}, Vt, St) -> expr_list(Es, Vt, St); -%%expr({struct,Line,Tag,Es}, Vt, St) -> -%% expr_list(Es, Vt, St); expr({record_index,Line,Name,Field}, _Vt, St) -> check_record(Line, Name, St, fun (Dfs, St1) -> record_field(Field, Name, Dfs, St1) end); expr({record,Line,Name,Inits}, Vt, St) -> check_record(Line, Name, St, - fun (Dfs, St1) -> - init_fields(Inits, Line, Name, Dfs, Vt, St1) + fun (Dfs, St1) -> + init_fields(Inits, Line, Name, Dfs, Vt, St1) end); expr({record_field,Line,_,_}=M, _Vt, St0) -> case expand_package(M, St0) of @@ -1943,8 +2026,6 @@ expr({'case',Line,E,Cs}, Vt, St0) -> {Evt,St1} = expr(E, Vt, St0), {Cvt,St2} = icrt_clauses(Cs, {'case',Line}, vtupdate(Evt, Vt), St1), {vtmerge(Evt, Cvt),St2}; -expr({'cond',Line,Cs}, Vt, St) -> - cond_clauses(Cs,{'cond',Line}, Vt, St); expr({'receive',Line,Cs}, Vt, St) -> icrt_clauses(Cs, {'receive',Line}, Vt, St); expr({'receive',Line,Cs,To,ToEs}, Vt, St0) -> @@ -1963,8 +2044,11 @@ expr({'fun',Line,Body}, Vt, St) -> {Bvt, St1} = fun_clauses(Cs, Vt, St), {vtupdate(Bvt, Vt), St1}; {function,F,A} -> + %% BifClash - Fun expression %% N.B. Only allows BIFs here as well, NO IMPORTS!! - case erl_internal:bif(F, A) of + case ((not is_local_function(St#lint.locals,{F,A})) andalso + (erl_internal:bif(F, A) andalso + (not is_autoimport_suppressed(St#lint.no_auto,{F,A})))) of true -> {[],St}; false -> {[],call_function(Line, F, A, St)} end; @@ -1974,7 +2058,7 @@ expr({'fun',Line,Body}, Vt, St) -> expr({call,_Line,{atom,_Lr,is_record},[E,{atom,Ln,Name}]}, Vt, St0) -> {Rvt,St1} = expr(E, Vt, St0), {Rvt,exist_record(Ln, Name, St1)}; -expr({call,Line,{remote,_Lr,{atom,_Lm,erlang},{atom,Lf,is_record}},[E,A]}, +expr({call,Line,{remote,_Lr,{atom,_Lm,erlang},{atom,Lf,is_record}},[E,A]}, Vt, St0) -> expr({call,Line,{atom,Lf,is_record},[E,A]}, Vt, St0); expr({call,L,{tuple,Lt,[{atom,Lm,erlang},{atom,Lf,is_record}]},As}, Vt, St) -> @@ -1997,29 +2081,54 @@ expr({call,Line,{atom,La,F},As}, Vt, St0) -> St1 = keyword_warning(La, F, St0), {Asvt,St2} = expr_list(As, Vt, St1), A = length(As), - case erl_internal:bif(F, A) of + IsLocal = is_local_function(St2#lint.locals,{F,A}), + IsAutoBif = erl_internal:bif(F, A), + AutoSuppressed = is_autoimport_suppressed(St2#lint.no_auto,{F,A}), + Warn = is_warn_enabled(bif_clash, St2) and (not bif_clash_specifically_disabled(St2,{F,A})), + Imported = imported(F, A, St2), + case ((not IsLocal) andalso (Imported =:= no) andalso + IsAutoBif andalso (not AutoSuppressed)) of true -> St3 = deprecated_function(Line, erlang, F, As, St2), - {Asvt,case is_warn_enabled(bif_clash, St3) andalso - is_bif_clash(F, A, St3) of - false -> - St3; - true -> - add_error(Line, {call_to_redefined_bif,{F,A}}, St3) - end}; + {Asvt,St3}; false -> - {Asvt,case imported(F, A, St2) of + {Asvt,case Imported of {yes,M} -> St3 = check_remote_function(Line, M, F, As, St2), U0 = St3#lint.usage, Imp = ordsets:add_element({{F,A},M},U0#usage.imported), St3#lint{usage=U0#usage{imported = Imp}}; no -> - case {F,A} of - {record_info,2} -> + case {F,A} of + {record_info,2} -> check_record_info_call(Line,La,As,St2); - N when N =:= St2#lint.func -> St2; - _ -> call_function(Line, F, A, St2) + N -> + %% BifClash - function call + %% Issue these warnings/errors even if it's a recursive call + St3 = if + (not AutoSuppressed) andalso IsAutoBif andalso Warn -> + case erl_internal:old_bif(F,A) of + true -> + add_error + (Line, + {call_to_redefined_old_bif, {F,A}}, + St2); + false -> + add_warning + (Line, + {call_to_redefined_bif, {F,A}}, + St2) + end; + true -> + St2 + end, + %% ...but don't lint recursive calls + if + N =:= St3#lint.func -> + St3; + true -> + call_function(Line, F, A, St3) + end end end} end; @@ -2160,7 +2269,7 @@ def_fields(Fs0, Name, St0) -> foldl(fun ({record_field,Lf,{atom,La,F},V}, {Fs,St}) -> case exist_field(F, Fs) of true -> {Fs,add_error(Lf, {redefine_field,Name,F}, St)}; - false -> + false -> St1 = St#lint{recdef_top = true}, {_,St2} = expr(V, [], St1), %% Warnings and errors found are kept, but @@ -2311,7 +2420,7 @@ init_fields(Ifs, Line, Name, Dfs, Vt0, St0) -> Defs = init_fields(Ifs, Line, Dfs), {_,St2} = check_fields(Defs, Name, Dfs, Vt1, St1, fun expr/3), {Vt1,St1#lint{usage = St2#lint.usage}}. - + ginit_fields(Ifs, Line, Name, Dfs, Vt0, St0) -> {Vt1,St1} = check_fields(Ifs, Name, Dfs, Vt0, St0, fun gexpr/3), Defs = init_fields(Ifs, Line, Dfs), @@ -2321,7 +2430,7 @@ ginit_fields(Ifs, Line, Name, Dfs, Vt0, St0) -> IllErrs = [E || {_File,{_Line,erl_lint,illegal_guard_expr}}=E <- Errors], St4 = St1#lint{usage = Usage, errors = IllErrs ++ St1#lint.errors}, {Vt1,St4}. - + %% Default initializations to be carried out init_fields(Ifs, Line, Dfs) -> [ {record_field,Lf,{atom,La,F},copy_expr(Di, Line)} || @@ -2399,7 +2508,7 @@ check_type({ann_type, _L, [_Var, Type]}, SeenVars, St) -> check_type(Type, SeenVars, St); check_type({paren_type, _L, [Type]}, SeenVars, St) -> check_type(Type, SeenVars, St); -check_type({remote_type, L, [{atom, _, Mod}, {atom, _, Name}, Args]}, +check_type({remote_type, L, [{atom, _, Mod}, {atom, _, Name}, Args]}, SeenVars, #lint{module=CurrentMod} = St) -> St1 = case (dict:is_key({Name, length(Args)}, default_types()) @@ -2437,7 +2546,7 @@ check_type({type, L, 'fun', [Dom, Range]}, SeenVars, St) -> check_type({type, -1, product, [Dom, Range]}, SeenVars, St1); check_type({type, L, range, [From, To]}, SeenVars, St) -> St1 = - case {From, To} of + case {erl_eval:partial_eval(From), erl_eval:partial_eval(To)} of {{integer, _, X}, {integer, _, Y}} when X < Y -> St; _ -> add_error(L, {type_syntax, range}, St) end, @@ -2446,8 +2555,8 @@ check_type({type, _L, tuple, any}, SeenVars, St) -> {SeenVars, St}; check_type({type, _L, any}, SeenVars, St) -> {SeenVars, St}; check_type({type, L, binary, [Base, Unit]}, SeenVars, St) -> St1 = - case {Base, Unit} of - {{integer, _, BaseVal}, + case {erl_eval:partial_eval(Base), erl_eval:partial_eval(Unit)} of + {{integer, _, BaseVal}, {integer, _, UnitVal}} when BaseVal >= 0, UnitVal >= 0 -> St; _ -> add_error(L, {type_syntax, binary}, St) end, @@ -2472,7 +2581,13 @@ check_type({type, La, TypeName, Args}, SeenVars, #lint{usage=Usage} = St) -> UsedTypes = dict:store({TypeName, Arity}, La, OldUsed), St#lint{usage=Usage#usage{used_types=UsedTypes}} end, - check_type({type, -1, product, Args}, SeenVars, St1). + check_type({type, -1, product, Args}, SeenVars, St1); +check_type(I, SeenVars, St) -> + case erl_eval:partial_eval(I) of + {integer,_ILn,_Integer} -> {SeenVars, St}; + _Other -> + {SeenVars, add_error(element(2, I), {type_syntax, integer}, St)} + end. check_record_types(Line, Name, Fields, SeenVars, St) -> case dict:find(Name, St#lint.records) of @@ -2480,12 +2595,12 @@ check_record_types(Line, Name, Fields, SeenVars, St) -> case lists:all(fun({type, _, field_type, _}) -> true; (_) -> false end, Fields) of - true -> + true -> check_record_types(Fields, Name, DefFields, SeenVars, St, []); false -> {SeenVars, add_error(Line, {type_syntax, record}, St)} end; - error -> + error -> {SeenVars, add_error(Line, {undefined_record, Name}, St)} end. @@ -2568,7 +2683,6 @@ default_types() -> {set, 0}, {string, 0}, {term, 0}, - {tid, 0}, {timeout, 0}, {var, 1}], dict:from_list([{T, -1} || T <- DefTypes]). @@ -2590,7 +2704,6 @@ is_newly_introduced_builtin_type({gb_tree, 0}) -> true; % opaque is_newly_introduced_builtin_type({iodata, 0}) -> true; is_newly_introduced_builtin_type({queue, 0}) -> true; % opaque is_newly_introduced_builtin_type({set, 0}) -> true; % opaque -is_newly_introduced_builtin_type({tid, 0}) -> true; % opaque %% R13B01 is_newly_introduced_builtin_type({boolean, 0}) -> true; is_newly_introduced_builtin_type({Name, _}) when is_atom(Name) -> false. @@ -2611,7 +2724,7 @@ spec_decl(Line, MFA0, TypeSpecs, St0 = #lint{specs = Specs, module = Mod}) -> check_specs([FunType|Left], Arity, St0) -> {FunType1, CTypes} = case FunType of - {type, _, bounded_fun, [FT = {type, _, 'fun', _}, Cs]} -> + {type, _, bounded_fun, [FT = {type, _, 'fun', _}, Cs]} -> Types0 = [T || {type, _, constraint, [_, T]} <- Cs], {FT, lists:append(Types0)}; {type, _, 'fun', _} = FT -> {FT, []} @@ -2671,10 +2784,12 @@ add_missing_spec_warnings(Forms, St0, Type) -> add_warning(L, {missing_spec,FA}, St) end, St0, Warns). -check_unused_types(Forms, St = #lint{usage=Usage, types=Types}) -> +check_unused_types(Forms, #lint{usage=Usage, types=Ts, exp_types=ExpTs}=St) -> case [File || {attribute,_L,file,{File,_Line}} <- Forms] of [FirstFile|_] -> - UsedTypes = Usage#usage.used_types, + D = Usage#usage.used_types, + L = gb_sets:to_list(ExpTs) ++ dict:fetch_keys(D), + UsedTypes = gb_sets:from_list(L), FoldFun = fun(_Type, -1, AccSt) -> %% Default type @@ -2682,19 +2797,18 @@ check_unused_types(Forms, St = #lint{usage=Usage, types=Types}) -> (Type, FileLine, AccSt) -> case loc(FileLine) of {FirstFile, _} -> - case dict:is_key(Type, UsedTypes) of + case gb_sets:is_member(Type, UsedTypes) of true -> AccSt; - false -> - add_warning(FileLine, - {unused_type, Type}, - AccSt) + false -> + Warn = {unused_type,Type}, + add_warning(FileLine, Warn, AccSt) end; _ -> - %% Don't warn about unused types in include file + %% No warns about unused types in include files AccSt end end, - dict:fold(FoldFun, St, Types); + dict:fold(FoldFun, St, Ts); [] -> St end. @@ -2720,45 +2834,6 @@ icrt_clause({clause,_Line,H,G,B}, Vt0, St0) -> {Bvt,St3} = exprs(B, Vt2, St2), {vtupdate(Bvt, Vt2),St3}. -%% The tests of 'cond' clauses are normal expressions - not guards. -%% Variables bound in a test is visible both in the corresponding body -%% and in the tests and bodies of subsequent clauses: a 'cond' is -%% *equivalent* to nested case-switches on boolean expressions. - -cond_clauses([C], In, Vt, St) -> - last_cond_clause(C, In, Vt, St); -cond_clauses([C | Cs], In, Vt, St) -> - cond_clause(C, Cs, In, Vt, St). - -%% see expr/3 for 'case' -cond_clause({clause,_L,[],[[E]],B}, Cs, In, Vt, St0) -> - {Evt,St1} = expr(E, Vt, St0), - {Cvt, St2} = cond_cases(B, Cs, In, vtupdate(Evt, Vt), St1), - Mvt = vtmerge(Evt, Cvt), - {Mvt,St2}. - -%% see icrt_clauses/4 -cond_cases(B, Cs, In, Vt, St0) -> - %% note that Vt is used for both cases - {Bvt,St1} = exprs(B, Vt, St0), % true case - Vt1 = vtupdate(Bvt, Vt), - {Cvt, St2} = cond_clauses(Cs, In, Vt, St1), % false case - Vt2 = vtupdate(Cvt, Vt), - %% and this also uses Vt - icrt_export([Vt1,Vt2], Vt, In, St2). - -%% last case must call icrt_export/4 with only one vartable -last_cond_clause({clause,_L,[],[[E]],B}, In, Vt, St0) -> - {Evt,St1} = expr(E, Vt, St0), - {Cvt, St2} = last_cond_case(B, In, vtupdate(Evt, Vt), St1), - Mvt = vtmerge(Evt, Cvt), - {Mvt,St2}. - -last_cond_case(B, In, Vt, St0) -> - {Bvt,St1} = exprs(B, Vt, St0), - Vt1 = vtupdate(Bvt, Vt), - icrt_export([Vt1], Vt, In, St1). - icrt_export(Csvt, Vt, In, St) -> Vt1 = vtmerge(Csvt), All = ordsets:subtract(vintersection(Csvt), vtnames(Vt)), @@ -2878,7 +2953,7 @@ fun_clause({clause,_Line,H,G,B}, Vt0, St0) -> %% %% used variable has been used %% unused variable has been bound but not used -%% +%% %% Lines is a list of line numbers where the variable was bound. %% %% Report variable errors/warnings as soon as possible and then change @@ -2908,9 +2983,9 @@ pat_var(V, Line, Vt, Bvt, St) -> case orddict:find(V, Bvt) of {ok, {bound,_Usage,Ls}} -> {[],[{V,{bound,used,Ls}}],St}; - error -> + error -> case orddict:find(V, Vt) of - {ok,{bound,_Usage,Ls}} -> + {ok,{bound,_Usage,Ls}} -> {[{V,{bound,used,Ls}}],[],St}; {ok,{{unsafe,In},_Usage,Ls}} -> {[{V,{bound,used,Ls}}],[], @@ -2963,7 +3038,7 @@ pat_binsize_var(V, Line, Vt, Bvt, St) -> expr_var(V, Line, Vt, St0) -> case orddict:find(V, Vt) of - {ok,{bound,_Usage,Ls}} -> + {ok,{bound,_Usage,Ls}} -> {[{V,{bound,used,Ls}}],St0}; {ok,{{unsafe,In},_Usage,Ls}} -> {[{V,{bound,used,Ls}}], @@ -3001,7 +3076,7 @@ check_old_unused_vars(Vt, Vt0, St0) -> warn_unused_vars(U, Vt, St0). unused_vars(Vt, Vt0, _St0) -> - U0 = orddict:filter(fun (V, {_State,unused,_Ls}) -> + U0 = orddict:filter(fun (V, {_State,unused,_Ls}) -> case atom_to_list(V) of "_"++_ -> false; _ -> true @@ -3017,7 +3092,7 @@ warn_unused_vars(U, Vt, St0) -> false -> St0; true -> foldl(fun ({V,{_,unused,Ls}}, St) -> - foldl(fun (L, St2) -> + foldl(fun (L, St2) -> add_warning(L, {unused_var,V}, St2) end, St, Ls) @@ -3117,7 +3192,7 @@ vt_no_unsafe(Vt) -> [V || {_,{S,_U,_L}}=V <- Vt, -ifdef(NOTUSED). vunion(Vs1, Vs2) -> ordsets:union(vtnames(Vs1), vtnames(Vs2)). -vunion(Vss) -> foldl(fun (Vs, Uvs) -> +vunion(Vss) -> foldl(fun (Vs, Uvs) -> ordsets:union(vtnames(Vs), Uvs) end, [], Vss). @@ -3147,7 +3222,7 @@ modify_line(T, F0) -> %% Forms. modify_line1({function,F,A}, _Mf) -> {function,F,A}; modify_line1({function,M,F,A}, _Mf) -> {function,M,F,A}; -modify_line1({attribute,L,record,{Name,Fields}}, Mf) -> +modify_line1({attribute,L,record,{Name,Fields}}, Mf) -> {attribute,Mf(L),record,{Name,modify_line1(Fields, Mf)}}; modify_line1({attribute,L,spec,{Fun,Types}}, Mf) -> {attribute,Mf(L),spec,{Fun,modify_line1(Types, Mf)}}; @@ -3162,7 +3237,7 @@ modify_line1({warning,W}, _Mf) -> {warning,W}; modify_line1({error,W}, _Mf) -> {error,W}; %% Expressions. modify_line1({clauses,Cs}, Mf) -> {clauses,modify_line1(Cs, Mf)}; -modify_line1({typed_record_field,Field,Type}, Mf) -> +modify_line1({typed_record_field,Field,Type}, Mf) -> {typed_record_field,modify_line1(Field, Mf),modify_line1(Type, Mf)}; modify_line1({Tag,L}, Mf) -> {Tag,Mf(L)}; modify_line1({Tag,L,E1}, Mf) -> @@ -3198,7 +3273,7 @@ check_record_info_call(Line,_La,_As,St) -> has_wildcard_field([{record_field,_Lf,{var,_La,'_'},_Val}|_Fs]) -> true; has_wildcard_field([_|Fs]) -> has_wildcard_field(Fs); has_wildcard_field([]) -> false. - + %% check_remote_function(Line, ModuleName, FuncName, [Arg], State) -> State. %% Perform checks on known remote calls. @@ -3214,7 +3289,7 @@ check_remote_function(Line, M, F, As, St0) -> check_qlc_hrl(Line, M, F, As, St) -> Arity = length(As), case As of - [{lc,_L,_E,_Qs}|_] when M =:= qlc, F =:= q, + [{lc,_L,_E,_Qs}|_] when M =:= qlc, F =:= q, Arity < 3, not St#lint.xqlc -> add_warning(Line, {missing_qlc_hrl, Arity}, St); _ -> @@ -3399,11 +3474,11 @@ extract_sequence(3, [$.,_|Fmt], Need) -> extract_sequence(4, Fmt, Need); extract_sequence(3, Fmt, Need) -> extract_sequence(4, Fmt, Need); -extract_sequence(4, [$t, $c | Fmt], Need) -> - extract_sequence(5, [$c|Fmt], Need); -extract_sequence(4, [$t, $s | Fmt], Need) -> - extract_sequence(5, [$s|Fmt], Need); -extract_sequence(4, [$t, C | _Fmt], _Need) -> +extract_sequence(4, [$t, $c | Fmt], Need) -> + extract_sequence(5, [$c|Fmt], Need); +extract_sequence(4, [$t, $s | Fmt], Need) -> + extract_sequence(5, [$s|Fmt], Need); +extract_sequence(4, [$t, C | _Fmt], _Need) -> {error,"invalid control ~t" ++ [C]}; extract_sequence(4, Fmt, Need) -> extract_sequence(5, Fmt, Need); @@ -3481,3 +3556,56 @@ expand_package(M, St0) -> {error, St1} end end. + + +%% Prebuild set of local functions (to override auto-import) +local_functions(Forms) -> + gb_sets:from_list([ {Func,Arity} || {function,_,Func,Arity,_} <- Forms ]). +%% Predicate to find out if the function is locally defined +is_local_function(LocalSet,{Func,Arity}) -> + gb_sets:is_element({Func,Arity},LocalSet). +%% Predicate to see if a function is explicitly imported +is_imported_function(ImportSet,{Func,Arity}) -> + case orddict:find({Func,Arity}, ImportSet) of + {ok,_Mod} -> true; + error -> false + end. +%% Predicate to see if a function is explicitly imported from the erlang module +is_imported_from_erlang(ImportSet,{Func,Arity}) -> + case orddict:find({Func,Arity}, ImportSet) of + {ok,erlang} -> true; + _ -> false + end. +%% Build set of functions where auto-import is explicitly supressed +auto_import_suppressed(CompileFlags) -> + L0 = [ X || {no_auto_import,X} <- CompileFlags ], + L1 = [ {Y,Z} || {Y,Z} <- lists:flatten(L0), is_atom(Y), is_integer(Z) ], + gb_sets:from_list(L1). +%% Predicate to find out if autoimport is explicitly supressed for a function +is_autoimport_suppressed(NoAutoSet,{Func,Arity}) -> + gb_sets:is_element({Func,Arity},NoAutoSet). +%% Predicate to find out if a function specific bif-clash supression (old deprecated) is present +bif_clash_specifically_disabled(St,{F,A}) -> + Nowarn = nowarn_function(nowarn_bif_clash, St#lint.compile), + lists:member({F,A},Nowarn). + +%% Predicate to find out if an autoimported guard_bif is not overriden in some way +%% Guard Bif without module name is disallowed if +%% * It is overridden by local function +%% * It is overridden by -import and that import is not of itself (i.e. from module erlang) +%% * The autoimport is suppressed or it's not reimported by -import directive +%% Otherwise it's OK (given that it's actually a guard bif and actually is autoimported) +no_guard_bif_clash(St,{F,A}) -> + ( + (not is_local_function(St#lint.locals,{F,A})) + andalso + ( + (not is_imported_function(St#lint.imports,{F,A})) orelse + is_imported_from_erlang(St#lint.imports,{F,A}) + ) + andalso + ( + (not is_autoimport_suppressed(St#lint.no_auto, {F,A})) orelse + is_imported_from_erlang(St#lint.imports,{F,A}) + ) + ). diff --git a/lib/stdlib/src/erl_parse.yrl b/lib/stdlib/src/erl_parse.yrl index fd5d905797..bb4b18cf9b 100644 --- a/lib/stdlib/src/erl_parse.yrl +++ b/lib/stdlib/src/erl_parse.yrl @@ -1,20 +1,20 @@ %% -*- erlang -*- %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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% %% @@ -30,14 +30,12 @@ expr_600 expr_700 expr_800 expr_900 expr_max list tail list_comprehension lc_expr lc_exprs -binary_comprehension +binary_comprehension tuple -atom1 %struct record_expr record_tuple record_field record_fields if_expr if_clause if_clauses case_expr cr_clause cr_clauses receive_expr fun_expr fun_clause fun_clauses -%% cond_expr cond_clause cond_clauses try_expr try_catch try_clause try_clauses query_expr function_call argument_list exprs guard @@ -49,22 +47,22 @@ opt_bit_size_expr bit_size_expr opt_bit_type_list bit_type_list bit_type top_type top_type_100 top_types type typed_expr typed_attr_val type_sig type_sigs type_guard type_guards fun_type fun_type_100 binary_type type_spec spec_fun typed_exprs typed_record_fields field_types field_type -bin_base_type bin_unit_type int_type. +bin_base_type bin_unit_type type_200 type_300 type_400 type_500. Terminals char integer float atom string var '(' ')' ',' '->' ':-' '{' '}' '[' ']' '|' '||' '<-' ';' ':' '#' '.' 'after' 'begin' 'case' 'try' 'catch' 'end' 'fun' 'if' 'of' 'receive' 'when' -'andalso' 'orelse' 'query' 'spec' -%% 'cond' +'andalso' 'orelse' 'query' 'bnot' 'not' '*' '/' 'div' 'rem' 'band' 'and' '+' '-' 'bor' 'bxor' 'bsl' 'bsr' 'or' 'xor' '++' '--' '==' '/=' '=<' '<' '>=' '>' '=:=' '=/=' '<=' '<<' '>>' -'!' '=' '::' +'!' '=' '::' '..' '...' +'spec' % helper dot. Expect 2. @@ -79,19 +77,16 @@ attribute -> '-' atom attr_val : build_attribute('$2', '$3'). attribute -> '-' atom typed_attr_val : build_typed_attribute('$2','$3'). attribute -> '-' atom '(' typed_attr_val ')' : build_typed_attribute('$2','$4'). attribute -> '-' 'spec' type_spec : build_type_spec('$2', '$3'). - -atom1 -> 'spec' : {atom, ?line('$1'), 'spec'}. -atom1 -> atom : '$1'. type_spec -> spec_fun type_sigs : {'$1', '$2'}. type_spec -> '(' spec_fun type_sigs ')' : {'$2', '$3'}. -spec_fun -> atom1 : '$1'. -spec_fun -> atom1 ':' atom1 : {'$1', '$3'}. +spec_fun -> atom : '$1'. +spec_fun -> atom ':' atom : {'$1', '$3'}. %% The following two are retained only for backwards compatibility; %% they are not part of the EEP syntax and should be removed. -spec_fun -> atom1 '/' integer '::' : {'$1', '$3'}. -spec_fun -> atom1 ':' atom1 '/' integer '::' : {'$1', '$3', '$5'}. +spec_fun -> atom '/' integer '::' : {'$1', '$3'}. +spec_fun -> atom ':' atom '/' integer '::' : {'$1', '$3', '$5'}. typed_attr_val -> expr ',' typed_record_fields : {typed_record, '$1', '$3'}. typed_attr_val -> expr '::' top_type : {type_def, '$1', '$3'}. @@ -109,14 +104,15 @@ type_sigs -> type_sig : ['$1']. type_sigs -> type_sig ';' type_sigs : ['$1'|'$3']. type_sig -> fun_type : '$1'. -type_sig -> fun_type 'when' type_guards : {type, ?line('$1'), bounded_fun, +type_sig -> fun_type 'when' type_guards : {type, ?line('$1'), bounded_fun, ['$1','$3']}. type_guards -> type_guard : ['$1']. type_guards -> type_guard ',' type_guards : ['$1'|'$3']. -type_guard -> atom1 '(' top_types ')' : {type, ?line('$1'), constraint, +type_guard -> atom '(' top_types ')' : {type, ?line('$1'), constraint, ['$1', '$3']}. +type_guard -> var '::' top_type : build_def('$1', '$3'). top_types -> top_type : ['$1']. top_types -> top_type ',' top_types : ['$1'|'$3']. @@ -124,58 +120,68 @@ top_types -> top_type ',' top_types : ['$1'|'$3']. top_type -> var '::' top_type_100 : {ann_type, ?line('$1'), ['$1','$3']}. top_type -> top_type_100 : '$1'. -top_type_100 -> type : '$1'. -top_type_100 -> type '|' top_type_100 : lift_unions('$1','$3'). +top_type_100 -> type_200 : '$1'. +top_type_100 -> type_200 '|' top_type_100 : lift_unions('$1','$3'). + +type_200 -> type_300 '..' type_300 : {type, ?line('$1'), range, + [skip_paren('$1'), + skip_paren('$3')]}. +type_200 -> type_300 : '$1'. + +type_300 -> type_300 add_op type_400 : ?mkop2(skip_paren('$1'), + '$2', skip_paren('$3')). +type_300 -> type_400 : '$1'. + +type_400 -> type_400 mult_op type_500 : ?mkop2(skip_paren('$1'), + '$2', skip_paren('$3')). +type_400 -> type_500 : '$1'. + +type_500 -> prefix_op type : ?mkop1('$1', skip_paren('$2')). +type_500 -> type : '$1'. type -> '(' top_type ')' : {paren_type, ?line('$2'), ['$2']}. type -> var : '$1'. -type -> atom1 : '$1'. -type -> atom1 '(' ')' : build_gen_type('$1'). -type -> atom1 '(' top_types ')' : {type, ?line('$1'), +type -> atom : '$1'. +type -> atom '(' ')' : build_gen_type('$1'). +type -> atom '(' top_types ')' : {type, ?line('$1'), normalise('$1'), '$3'}. -type -> atom1 ':' atom1 '(' ')' : {remote_type, ?line('$1'), +type -> atom ':' atom '(' ')' : {remote_type, ?line('$1'), ['$1', '$3', []]}. -type -> atom1 ':' atom1 '(' top_types ')' : {remote_type, ?line('$1'), +type -> atom ':' atom '(' top_types ')' : {remote_type, ?line('$1'), ['$1', '$3', '$5']}. type -> '[' ']' : {type, ?line('$1'), nil, []}. type -> '[' top_type ']' : {type, ?line('$1'), list, ['$2']}. -type -> '[' top_type ',' '.' '.' '.' ']' : {type, ?line('$1'), +type -> '[' top_type ',' '...' ']' : {type, ?line('$1'), nonempty_list, ['$2']}. type -> '{' '}' : {type, ?line('$1'), tuple, []}. type -> '{' top_types '}' : {type, ?line('$1'), tuple, '$2'}. -type -> '#' atom1 '{' '}' : {type, ?line('$1'), record, ['$2']}. -type -> '#' atom1 '{' field_types '}' : {type, ?line('$1'), +type -> '#' atom '{' '}' : {type, ?line('$1'), record, ['$2']}. +type -> '#' atom '{' field_types '}' : {type, ?line('$1'), record, ['$2'|'$4']}. type -> binary_type : '$1'. -type -> int_type : '$1'. -type -> int_type '.' '.' int_type : {type, ?line('$1'), range, - ['$1', '$4']}. +type -> integer : '$1'. type -> 'fun' '(' ')' : {type, ?line('$1'), 'fun', []}. type -> 'fun' '(' fun_type_100 ')' : '$3'. -int_type -> integer : '$1'. -int_type -> '-' integer : abstract(-normalise('$2'), - ?line('$2')). - -fun_type_100 -> '(' '.' '.' '.' ')' '->' top_type +fun_type_100 -> '(' '...' ')' '->' top_type : {type, ?line('$1'), 'fun', - [{type, ?line('$1'), any}, '$7']}. + [{type, ?line('$1'), any}, '$5']}. fun_type_100 -> fun_type : '$1'. fun_type -> '(' ')' '->' top_type : {type, ?line('$1'), 'fun', [{type, ?line('$1'), product, []}, '$4']}. -fun_type -> '(' top_types ')' '->' top_type +fun_type -> '(' top_types ')' '->' top_type : {type, ?line('$1'), 'fun', [{type, ?line('$1'), product, '$2'},'$5']}. field_types -> field_type : ['$1']. field_types -> field_type ',' field_types : ['$1'|'$3']. -field_type -> atom1 '::' top_type : {type, ?line('$1'), field_type, +field_type -> atom '::' top_type : {type, ?line('$1'), field_type, ['$1', '$3']}. -binary_type -> '<<' '>>' : {type, ?line('$1'),binary, - [abstract(0, ?line('$1')), +binary_type -> '<<' '>>' : {type, ?line('$1'),binary, + [abstract(0, ?line('$1')), abstract(0, ?line('$1'))]}. binary_type -> '<<' bin_base_type '>>' : {type, ?line('$1'),binary, ['$2', abstract(0, ?line('$1'))]}. @@ -184,9 +190,9 @@ binary_type -> '<<' bin_unit_type '>>' : {type, ?line('$1'),binary, binary_type -> '<<' bin_base_type ',' bin_unit_type '>>' : {type, ?line('$1'), binary, ['$2', '$4']}. -bin_base_type -> var ':' integer : build_bin_type(['$1'], '$3'). +bin_base_type -> var ':' type : build_bin_type(['$1'], '$3'). -bin_unit_type -> var ':' var '*' integer : build_bin_type(['$1', '$3'], '$5'). +bin_unit_type -> var ':' var '*' type : build_bin_type(['$1', '$3'], '$5'). attr_val -> expr : ['$1']. attr_val -> expr ',' exprs : ['$1' | '$3']. @@ -197,7 +203,7 @@ function -> function_clauses : build_function('$1'). function_clauses -> function_clause : ['$1']. function_clauses -> function_clause ';' function_clauses : ['$1'|'$3']. -function_clause -> atom1 clause_args clause_guard clause_body : +function_clause -> atom clause_args clause_guard clause_body : {clause,?line('$1'),element(3, '$1'),'$2','$3','$4'}. @@ -250,9 +256,9 @@ expr_800 -> expr_900 ':' expr_max : {remote,?line('$2'),'$1','$3'}. expr_800 -> expr_900 : '$1'. -expr_900 -> '.' atom1 : +expr_900 -> '.' atom : {record_field,?line('$1'),{atom,?line('$1'),''},'$2'}. -expr_900 -> expr_900 '.' atom1 : +expr_900 -> expr_900 '.' atom : {record_field,?line('$2'),'$1','$3'}. expr_900 -> expr_max : '$1'. @@ -270,7 +276,6 @@ expr_max -> if_expr : '$1'. expr_max -> case_expr : '$1'. expr_max -> receive_expr : '$1'. expr_max -> fun_expr : '$1'. -%%expr_max -> cond_expr : '$1'. expr_max -> try_expr : '$1'. expr_max -> query_expr : '$1'. @@ -304,8 +309,8 @@ opt_bit_type_list -> '$empty' : default. bit_type_list -> bit_type '-' bit_type_list : ['$1' | '$3']. bit_type_list -> bit_type : ['$1']. -bit_type -> atom1 : element(3,'$1'). -bit_type -> atom1 ':' integer : { element(3,'$1'), element(3,'$3') }. +bit_type -> atom : element(3,'$1'). +bit_type -> atom ':' integer : { element(3,'$1'), element(3,'$3') }. bit_size_expr -> expr_max : '$1'. @@ -325,7 +330,7 @@ tuple -> '{' '}' : {tuple,?line('$1'),[]}. tuple -> '{' exprs '}' : {tuple,?line('$1'),'$2'}. -%%struct -> atom1 tuple : +%%struct -> atom tuple : %% {struct,?line('$1'),element(3, '$1'),element(3, '$2')}. @@ -333,13 +338,17 @@ tuple -> '{' exprs '}' : {tuple,?line('$1'),'$2'}. %% N.B. Field names are returned as the complete object, even if they are %% always atoms for the moment, this might change in the future. -record_expr -> '#' atom1 '.' atom1 : +record_expr -> '#' atom '.' atom : {record_index,?line('$1'),element(3, '$2'),'$4'}. -record_expr -> '#' atom1 record_tuple : +record_expr -> '#' atom record_tuple : {record,?line('$1'),element(3, '$2'),'$3'}. -record_expr -> expr_max '#' atom1 '.' atom1 : +record_expr -> expr_max '#' atom '.' atom : {record_field,?line('$2'),'$1',element(3, '$3'),'$5'}. -record_expr -> expr_max '#' atom1 record_tuple : +record_expr -> expr_max '#' atom record_tuple : + {record,?line('$2'),'$1',element(3, '$3'),'$4'}. +record_expr -> record_expr '#' atom '.' atom : + {record_field,?line('$2'),'$1',element(3, '$3'),'$5'}. +record_expr -> record_expr '#' atom record_tuple : {record,?line('$2'),'$1',element(3, '$3'),'$4'}. record_tuple -> '{' '}' : []. @@ -349,7 +358,7 @@ record_fields -> record_field : ['$1']. record_fields -> record_field ',' record_fields : ['$1' | '$3']. record_field -> var '=' expr : {record_field,?line('$1'),'$1','$3'}. -record_field -> atom1 '=' expr : {record_field,?line('$1'),'$1','$3'}. +record_field -> atom '=' expr : {record_field,?line('$1'),'$1','$3'}. %% N.B. This is called from expr_700. @@ -383,9 +392,9 @@ receive_expr -> 'receive' cr_clauses 'after' expr clause_body 'end' : {'receive',?line('$1'),'$2','$4','$5'}. -fun_expr -> 'fun' atom1 '/' integer : +fun_expr -> 'fun' atom '/' integer : {'fun',?line('$1'),{function,element(3, '$2'),element(3, '$4')}}. -fun_expr -> 'fun' atom1 ':' atom1 '/' integer : +fun_expr -> 'fun' atom ':' atom '/' integer : {'fun',?line('$1'),{function,element(3, '$2'),element(3, '$4'),element(3,'$6')}}. fun_expr -> 'fun' fun_clauses 'end' : build_fun(?line('$1'), '$2'). @@ -415,21 +424,13 @@ try_clauses -> try_clause ';' try_clauses : ['$1' | '$3']. try_clause -> expr clause_guard clause_body : L = ?line('$1'), {clause,L,[{tuple,L,[{atom,L,throw},'$1',{var,L,'_'}]}],'$2','$3'}. -try_clause -> atom1 ':' expr clause_guard clause_body : +try_clause -> atom ':' expr clause_guard clause_body : L = ?line('$1'), {clause,L,[{tuple,L,['$1','$3',{var,L,'_'}]}],'$4','$5'}. try_clause -> var ':' expr clause_guard clause_body : L = ?line('$1'), {clause,L,[{tuple,L,['$1','$3',{var,L,'_'}]}],'$4','$5'}. -%%cond_expr -> 'cond' cond_clauses 'end' : {'cond',?line('$1'),'$2'}. - -%%cond_clauses -> cond_clause : ['$1']. -%%cond_clauses -> cond_clause ';' cond_clauses : ['$1' | '$3']. - -%%cond_clause -> expr clause_body : -%% {clause,?line('$1'),[],[['$1']],'$2'}. - query_expr -> 'query' list_comprehension 'end' : {'query',?line('$1'),'$2'}. @@ -447,7 +448,7 @@ guard -> exprs ';' guard : ['$1'|'$3']. atomic -> char : '$1'. atomic -> integer : '$1'. atomic -> float : '$1'. -atomic -> atom1 : '$1'. +atomic -> atom : '$1'. atomic -> strings : '$1'. strings -> string : '$1'. @@ -492,7 +493,7 @@ rule -> rule_clauses : build_rule('$1'). rule_clauses -> rule_clause : ['$1']. rule_clauses -> rule_clause ';' rule_clauses : ['$1'|'$3']. -rule_clause -> atom1 clause_args clause_guard rule_body : +rule_clause -> atom clause_args clause_guard rule_body : {clause,?line('$1'),element(3, '$1'),'$2','$3','$4'}. rule_body -> ':-' lc_exprs: '$2'. @@ -514,8 +515,8 @@ Erlang code. %% mkop(Op, Arg) -> {op,Line,Op,Arg}. %% mkop(Left, Op, Right) -> {op,Line,Op,Left,Right}. --define(mkop2(L, OpPos, R), - begin +-define(mkop2(L, OpPos, R), + begin {Op,Pos} = OpPos, {op,Pos,Op,L,R} end). @@ -533,6 +534,8 @@ Erlang code. %% These really suck and are only here until Calle gets multiple %% entry points working. +parse_form([{'-',L1},{atom,L2,spec}|Tokens]) -> + parse([{'-',L1},{'spec',L2}|Tokens]); parse_form(Tokens) -> parse(Tokens). @@ -559,7 +562,7 @@ parse_term(Tokens) -> -type attributes() :: 'export' | 'file' | 'import' | 'module' | 'opaque' | 'record' | 'type'. -build_typed_attribute({atom,La,record}, +build_typed_attribute({atom,La,record}, {typed_record, {atom,_Ln,RecordName}, RecTuple}) -> {attribute,La,record,{RecordName,record_tuple(RecTuple)}}; build_typed_attribute({atom,La,Attr}, @@ -582,7 +585,7 @@ build_typed_attribute({atom,La,Attr},_) -> build_type_spec({spec,La}, {SpecFun, TypeSpecs}) -> NewSpecFun = case SpecFun of - {atom, _, Fun} -> + {atom, _, Fun} -> {Fun, find_arity_from_specs(TypeSpecs)}; {{atom,_, Mod}, {atom,_, Fun}} -> {Mod,Fun,find_arity_from_specs(TypeSpecs)}; @@ -605,11 +608,20 @@ find_arity_from_specs([Spec|_]) -> {type, _, 'fun', [{type, _, product, Args},_]} = Fun, length(Args). +build_def(LHS, Types) -> + IsSubType = {atom, ?line(LHS), is_subtype}, + {type, ?line(LHS), constraint, [IsSubType, [LHS, Types]]}. + lift_unions(T1, {type, _La, union, List}) -> {type, ?line(T1), union, [T1|List]}; lift_unions(T1, T2) -> {type, ?line(T1), union, [T1, T2]}. +skip_paren({paren_type,_L,[Type]}) -> + skip_paren(Type); +skip_paren(Type) -> + Type. + build_gen_type({atom, La, tuple}) -> {type, La, tuple, any}; build_gen_type({atom, La, Name}) -> @@ -618,7 +630,7 @@ build_gen_type({atom, La, Name}) -> build_bin_type([{var, _, '_'}|Left], Int) -> build_bin_type(Left, Int); build_bin_type([], Int) -> - Int; + skip_paren(Int); build_bin_type([{var, La, _}|_], _) -> ret_err(La, "Bad binary type"). @@ -716,7 +728,7 @@ attribute_farity(Other) -> Other. attribute_farity_list(Args) -> [attribute_farity(A) || A <- Args]. - + -spec error_bad_decl(integer(), attributes()) -> no_return(). error_bad_decl(L, S) -> @@ -739,17 +751,33 @@ record_fields([{match,_Lm,{atom,La,A},Expr}|Fields]) -> [{record_field,La,{atom,La,A},Expr}|record_fields(Fields)]; record_fields([{typed,Expr,TypeInfo}|Fields]) -> [Field] = record_fields([Expr]), - TypeInfo1 = + TypeInfo1 = case Expr of {match, _, _, _} -> TypeInfo; %% If we have an initializer. - {atom, La, _} -> - lift_unions(abstract(undefined, La), TypeInfo) - end, + {atom, La, _} -> + case has_undefined(TypeInfo) of + false -> + lift_unions(abstract(undefined, La), TypeInfo); + true -> + TypeInfo + end + end, [{typed_record_field,Field,TypeInfo1}|record_fields(Fields)]; record_fields([Other|_Fields]) -> ret_err(?line(Other), "bad record field"); record_fields([]) -> []. +has_undefined({atom,_,undefined}) -> + true; +has_undefined({ann_type,_,[_,T]}) -> + has_undefined(T); +has_undefined({paren_type,_,[T]}) -> + has_undefined(T); +has_undefined({type,_,union,Ts}) -> + lists:any(fun has_undefined/1, Ts); +has_undefined(_) -> + false. + term(Expr) -> try normalise(Expr) catch _:_R -> ret_err(?line(Expr), "bad attribute") @@ -989,7 +1017,7 @@ inop_prec('#') -> {800,700,800}; inop_prec(':') -> {900,800,900}; inop_prec('.') -> {900,900,1000}. --type pre_op() :: 'catch' | '+' | '-' | 'bnot' | '#'. +-type pre_op() :: 'catch' | '+' | '-' | 'bnot' | 'not' | '#'. -spec preop_prec(pre_op()) -> {0 | 600 | 700, 100 | 700 | 800}. diff --git a/lib/stdlib/src/erl_pp.erl b/lib/stdlib/src/erl_pp.erl index b1b5bad294..df4a20b833 100644 --- a/lib/stdlib/src/erl_pp.erl +++ b/lib/stdlib/src/erl_pp.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(erl_pp). @@ -115,7 +115,7 @@ lattribute({attribute,_Line,Name,Arg}, Hook) -> lattribute(module, {M,Vs}, _Hook) -> attr("module",[{var,0,pname(M)}, - foldr(fun(V, C) -> {cons,0,{var,0,V},C} + foldr(fun(V, C) -> {cons,0,{var,0,V},C} end, {nil,0}, Vs)]); lattribute(module, M, _Hook) -> attr("module", [{var,0,pname(M)}]); @@ -140,7 +140,7 @@ typeattr(Tag, {TypeName,Type,Args}, _Hook) -> ltype({ann_type,_Line,[V,T]}) -> typed(lexpr(V, none), T); ltype({paren_type,_Line,[T]}) -> - [$(,ltype(T),$)]; + [$(,ltype(T),$)]; ltype({type,_Line,union,Ts}) -> {seq,[],[],[' |'],ltypes(Ts)}; ltype({type,_Line,list,[T]}) -> @@ -153,7 +153,7 @@ ltype({type,Line,tuple,any}) -> simple_type({atom,Line,tuple}, []); ltype({type,_Line,tuple,Ts}) -> tuple_type(Ts, fun ltype/1); -ltype({type,_Line,record,[N|Fs]}) -> +ltype({type,_Line,record,[{atom,_,N}|Fs]}) -> record_type(N, Fs); ltype({type,_Line,range,[_I1,_I2]=Es}) -> expr_list(Es, '..', fun lexpr/2, none); @@ -161,24 +161,28 @@ ltype({type,_Line,binary,[I1,I2]}) -> binary_type(I1, I2); % except binary() ltype({type,_Line,'fun',[]}) -> leaf("fun()"); -ltype({type,_Line,'fun',_}=FunType) -> +ltype({type,_,'fun',[{type,_,any},_]}=FunType) -> + [fun_type(['fun',$(], FunType),$)]; +ltype({type,_Line,'fun',[{type,_,product,_},_]}=FunType) -> [fun_type(['fun',$(], FunType),$)]; ltype({type,Line,T,Ts}) -> simple_type({atom,Line,T}, Ts); ltype({remote_type,Line,[M,F,Ts]}) -> simple_type({remote,Line,M,F}, Ts); ltype({atom,_,T}) -> - %% Follow the convention to always quote atoms (in types): - leaf([$',atom_to_list(T),$']); + leaf(write(T)); ltype(E) -> lexpr(E, 0, none). -binary_type({integer,_,Int1}=I1, {integer,_,Int2}=I2) -> - E1 = [[leaf("_:"),lexpr(I1, 0, none)] || Int1 =/= 0], - E2 = [[leaf("_:_*"),lexpr(I2, 0, none)] || Int2 =/= 0], +binary_type(I1, I2) -> + B = [[] || {integer,_,0} <- [I1]] =:= [], + U = [[] || {integer,_,0} <- [I2]] =:= [], + P = max_prec(), + E1 = [[leaf("_:"),lexpr(I1, P, none)] || B], + E2 = [[leaf("_:_*"),lexpr(I2, P, none)] || U], {seq,'<<','>>',[$,],E1++E2}. -record_type({atom,_,Name}, Fields) -> +record_type(Name, Fields) -> {first,[record_name(Name)],field_types(Fields)}. field_types(Fs) -> @@ -442,7 +446,7 @@ lexpr({op,_,Op,Arg}, Prec, Hook) -> Ol = leaf(format("~s ", [Op])), El = [Ol,lexpr(Arg, R, Hook)], maybe_paren(P, Prec, El); -lexpr({op,_,Op,Larg,Rarg}, Prec, Hook) when Op =:= 'orelse'; +lexpr({op,_,Op,Larg,Rarg}, Prec, Hook) when Op =:= 'orelse'; Op =:= 'andalso' -> %% Breaks lines since R12B. {L,P,R} = inop_prec(Op), @@ -726,15 +730,15 @@ frmt(Item, I) -> %%% and indentation are inserted between IPs. %%% - {first,I,IP2}: IP2 follows after I, and is output with an indentation %%% updated with the width of I. -%%% - {seq,Before,After,Separator,IPs}: a sequence of Is separated by -%%% Separator. Before is output before IPs, and the indentation of IPs +%%% - {seq,Before,After,Separator,IPs}: a sequence of Is separated by +%%% Separator. Before is output before IPs, and the indentation of IPs %%% is updated with the width of Before. After follows after IPs. %%% - {force_nl,ExtraInfo,I}: fun-info (a comment) forces linebreak before I. %%% - {prefer_nl,Sep,IPs}: forces linebreak between Is unlesss negative %%% indentation. %%% - {string,S}: a string. %%% - {hook,...}, {ehook,...}: hook expressions. -%%% +%%% %%% list, first, seq, force_nl, and prefer_nl all accept IPs, where each %%% element is either an item or a tuple {step|cstep,I1,I2}. step means %%% that I2 is output after linebreak and an incremented indentation. @@ -760,7 +764,7 @@ f({seq,Before,After,Sep,LItems}, I0, ST, WT) -> {CharsL,SizeL} = unz(CharsSizeL), {BCharsL,BSizeL} = unz1([BCharsSize]), Sizes = BSizeL ++ SizeL, - NSepChars = if + NSepChars = if is_list(Sep), Sep =/= [] -> erlang:max(0, length(CharsL)-1); true -> @@ -875,7 +879,7 @@ nl_indent(I, T) when I > 0 -> [$\n|spaces(I, T)]. same_line(I0, SizeL, NSepChars) -> - try + try Size = lists:sum(SizeL) + NSepChars, true = incr(I0, Size) =< ?MAXLINE, {yes,Size} @@ -955,9 +959,9 @@ write_a_string(S, N, Len) -> -define(N_SPACES, 30). spacetab() -> - {[_|L],_} = mapfoldl(fun(_, A) -> {A,[$\s|A]} + {[_|L],_} = mapfoldl(fun(_, A) -> {A,[$\s|A]} end, [], lists:seq(0, ?N_SPACES)), - list_to_tuple(L). + list_to_tuple(L). spaces(N, T) when N =< ?N_SPACES -> element(N, T); @@ -965,7 +969,7 @@ spaces(N, T) -> [element(?N_SPACES, T)|spaces(N-?N_SPACES, T)]. wordtable() -> - L = [begin {leaf,Sz,S} = leaf(W), {S,Sz} end || + L = [begin {leaf,Sz,S} = leaf(W), {S,Sz} end || W <- [" ->"," =","<<",">>","[]","after","begin","case","catch", "end","fun","if","of","receive","try","when"," ::","..", " |"]], diff --git a/lib/stdlib/src/erl_scan.erl b/lib/stdlib/src/erl_scan.erl index 52ec81a78b..18f64c46d0 100644 --- a/lib/stdlib/src/erl_scan.erl +++ b/lib/stdlib/src/erl_scan.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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% %% @@ -48,25 +48,20 @@ -module(erl_scan). -%%% External exports +%%% External exports -export([string/1,string/2,string/3,tokens/3,tokens/4, format_error/1,reserved_word/1, token_info/1,token_info/2, attributes_info/1,attributes_info/2,set_attribute/3]). -%%% Local record. --record(erl_scan, - {resword_fun=fun reserved_word/1, - ws=false, - comment=false, - text=false}). +-export_type([error_info/0, line/0, tokens_result/0]). %%% -%%% Exported functions +%%% Defines and type definitions %%% --define(COLUMN(C), is_integer(C), C >= 1). +-define(COLUMN(C), (is_integer(C) andalso C >= 1)). %% Line numbers less than zero have always been allowed: -define(ALINE(L), is_integer(L)). -define(STRING(S), is_list(S)). @@ -95,44 +90,53 @@ -type error_description() :: term(). -type error_info() :: {location(), module(), error_description()}. +%%% Local record. +-record(erl_scan, + {resword_fun = fun reserved_word/1 :: resword_fun(), + ws = false :: boolean(), + comment = false :: boolean(), + text = false :: boolean()}). + +%%---------------------------------------------------------------------------- + -spec format_error(Error :: term()) -> string(). format_error({string,Quote,Head}) -> lists:flatten(["unterminated " ++ string_thing(Quote) ++ - " starting with " ++ + " starting with " ++ io_lib:write_unicode_string(Head, Quote)]); -format_error({illegal,Type}) -> +format_error({illegal,Type}) -> lists:flatten(io_lib:fwrite("illegal ~w", [Type])); format_error(char) -> "unterminated character"; -format_error({base,Base}) -> +format_error({base,Base}) -> lists:flatten(io_lib:fwrite("illegal base '~w'", [Base])); -format_error(Other) -> +format_error(Other) -> lists:flatten(io_lib:write(Other)). --type string_return() :: {'ok', tokens(), location()} +-type string_return() :: {'ok', tokens(), location()} | {'error', error_info(), location()}. -spec string(String :: string()) -> string_return(). string(String) -> string(String, 1, []). --spec string(String :: string(), StartLocation :: location()) -> +-spec string(String :: string(), StartLocation :: location()) -> string_return(). string(String, StartLocation) -> string(String, StartLocation, []). --spec string(String :: string(), StartLocation :: location(), +-spec string(String :: string(), StartLocation :: location(), Options :: options()) -> string_return(). string(String, Line, Options) when ?STRING(String), ?ALINE(Line) -> string1(String, options(Options), Line, no_col, []); string(String, {Line,Column}, Options) when ?STRING(String), - ?ALINE(Line), + ?ALINE(Line), ?COLUMN(Column) -> string1(String, options(Options), Line, Column, []). -type char_spec() :: string() | 'eof'. -type cont_fun() :: fun((char_spec(), #erl_scan{}, line(), column(), tokens(), any()) -> any()). --opaque return_cont() :: {string(), column(), tokens(), line(), +-opaque return_cont() :: {string(), column(), tokens(), line(), #erl_scan{}, cont_fun(), any()}. -type cont() :: return_cont() | []. -type tokens_result() :: {'ok', tokens(), location()} @@ -141,13 +145,13 @@ string(String, {Line,Column}, Options) when ?STRING(String), -type tokens_return() :: {'done', tokens_result(), char_spec()} | {'more', return_cont()}. --spec tokens(Cont :: cont(), CharSpec :: char_spec(), +-spec tokens(Cont :: cont(), CharSpec :: char_spec(), StartLocation :: location()) -> tokens_return(). tokens(Cont, CharSpec, StartLocation) -> tokens(Cont, CharSpec, StartLocation, []). --spec tokens(Cont :: cont(), CharSpec :: char_spec(), - StartLocation :: location(), Options :: options()) -> +-spec tokens(Cont :: cont(), CharSpec :: char_spec(), + StartLocation :: location(), Options :: options()) -> tokens_return(). tokens([], CharSpec, Line, Options) when ?ALINE(Line) -> tokens1(CharSpec, options(Options), Line, no_col, [], fun scan/6, []); @@ -157,15 +161,15 @@ tokens([], CharSpec, {Line,Column}, Options) when ?ALINE(Line), tokens({Cs,Col,Toks,Line,St,Any,Fun}, CharSpec, _Loc, _Opts) -> tokens1(Cs++CharSpec, St, Line, Col, Toks, Fun, Any). --type attribute_item() :: 'column' | 'length' | 'line' +-type attribute_item() :: 'column' | 'length' | 'line' | 'location' | 'text'. -type info_location() :: location() | term(). --type attribute_info() :: {'column', column()}| {'length', pos_integer()} - | {'line', info_line()} +-type attribute_info() :: {'column', column()}| {'length', pos_integer()} + | {'line', info_line()} | {'location', info_location()} | {'text', string()}. -type token_item() :: 'category' | 'symbol' | attribute_item(). --type token_info() :: {'category', category()} | {'symbol', symbol()} +-type token_info() :: {'category', category()} | {'symbol', symbol()} | attribute_info(). -spec token_info(token()) -> [token_info()]. @@ -214,7 +218,7 @@ attributes_info(Attrs, [A|As]) when is_atom(A) -> AttributeInfo when is_tuple(AttributeInfo) -> [AttributeInfo|attributes_info(Attrs, As)] end; -attributes_info({Line,Column}, column=Item) when ?ALINE(Line), +attributes_info({Line,Column}, column=Item) when ?ALINE(Line), ?COLUMN(Column) -> {Item,Column}; attributes_info(Line, column) when ?ALINE(Line) -> @@ -230,12 +234,12 @@ attributes_info(Attrs, length=Item) -> end; attributes_info(Line, line=Item) when ?ALINE(Line) -> {Item,Line}; -attributes_info({Line,Column}, line=Item) when ?ALINE(Line), +attributes_info({Line,Column}, line=Item) when ?ALINE(Line), ?COLUMN(Column) -> {Item,Line}; attributes_info(Attrs, line=Item) -> attr_info(Attrs, Item); -attributes_info({Line,Column}=Location, location=Item) when ?ALINE(Line), +attributes_info({Line,Column}=Location, location=Item) when ?ALINE(Line), ?COLUMN(Column) -> {Item,Location}; attributes_info(Line, location=Item) when ?ALINE(Line) -> @@ -289,11 +293,11 @@ string_thing(_) -> "string". options(Opts0) when is_list(Opts0) -> Opts = lists:foldr(fun expand_opt/2, [], Opts0), - [RW_fun] = + [RW_fun] = case opts(Opts, [reserved_word_fun], []) of badarg -> erlang:error(badarg, [Opts0]); - R -> + R -> R end, Comment = proplists:get_bool(return_comments, Opts), @@ -307,10 +311,10 @@ options(Opt) -> options([Opt]). opts(Options, [Key|Keys], L) -> - V = case lists:keysearch(Key, 1, Options) of - {value,{reserved_word_fun,F}} when ?RESWORDFUN(F) -> + V = case lists:keyfind(Key, 1, Options) of + {reserved_word_fun,F} when ?RESWORDFUN(F) -> {ok,F}; - {value,{Key,_}} -> + {Key,_} -> badarg; false -> {ok,default_option(Key)} @@ -333,12 +337,13 @@ expand_opt(O, Os) -> [O|Os]. attr_info(Attrs, Item) -> - case catch lists:keysearch(Item, 1, Attrs) of - {value,{Item,Value}} -> - {Item,Value}; - false -> - undefined; - _ -> + try lists:keyfind(Item, 1, Attrs) of + {_Item, _Value} = T -> + T; + false -> + undefined + catch + _:_ -> erlang:error(badarg, [Attrs, Item]) end. @@ -442,6 +447,14 @@ scan1([$\%=C|Cs], St, Line, Col, Toks) -> scan_comment(Cs, St, Line, Col, Toks, [C]); scan1([C|Cs], St, Line, Col, Toks) when ?DIGIT(C) -> scan_number(Cs, St, Line, Col, Toks, [C]); +scan1("..."++Cs, St, Line, Col, Toks) -> + tok2(Cs, St, Line, Col, Toks, "...", '...', 3); +scan1(".."=Cs, _St, Line, Col, Toks) -> + {more,{Cs,Col,Toks,Line,[],fun scan/6}}; +scan1(".."++Cs, St, Line, Col, Toks) -> + tok2(Cs, St, Line, Col, Toks, "..", '..', 2); +scan1("."=Cs, _St, Line, Col, Toks) -> + {more,{Cs,Col,Toks,Line,[],fun scan/6}}; scan1([$.=C|Cs], St, Line, Col, Toks) -> scan_dot(Cs, St, Line, Col, Toks, [C]); scan1([$"|Cs], St, Line, Col, Toks) -> %" Emacs @@ -591,12 +604,12 @@ scan_atom(Cs0, St, Line, Col, Toks, Ncs0) -> case catch list_to_atom(Wcs) of Name when is_atom(Name) -> case (St#erl_scan.resword_fun)(Name) of - true -> + true -> tok2(Cs, St, Line, Col, Toks, Wcs, Name); - false -> + false -> tok3(Cs, St, Line, Col, Toks, atom, Wcs, Name) end; - _Error -> + _Error -> Ncol = incr_column(Col, length(Wcs)), scan_error({illegal,atom}, Line, Col, Line, Ncol, Cs) end @@ -610,7 +623,7 @@ scan_variable(Cs0, St, Line, Col, Toks, Ncs0) -> case catch list_to_atom(Wcs) of Name when is_atom(Name) -> tok3(Cs, St, Line, Col, Toks, var, Wcs, Name); - _Error -> + _Error -> Ncol = incr_column(Col, length(Wcs)), scan_error({illegal,var}, Line, Col, Line, Ncol, Cs) end @@ -644,8 +657,6 @@ scan_dot([$\n=C|Cs], St, Line, Col, Toks, Ncs) -> scan_dot([C|Cs], St, Line, Col, Toks, Ncs) when ?WHITE_SPACE(C) -> Attrs = attributes(Line, Col, St, Ncs++[C]), {ok,[{dot,Attrs}|Toks],Cs,Line,incr_column(Col, 2)}; -scan_dot([]=Cs, _St, Line, Col, Toks, Ncs) -> - {more,{Cs,Col,Toks,Line,Ncs,fun scan_dot/6}}; scan_dot(eof=Cs, St, Line, Col, Toks, Ncs) -> Attrs = attributes(Line, Col, St, Ncs), {ok,[{dot,Attrs}|Toks],Cs,Line,incr_column(Col, 1)}; @@ -690,7 +701,7 @@ scan_nl_spcs([]=Cs, _St, Line, Col, Toks, N) -> {more,{Cs,Col,Toks,Line,N,fun scan_nl_spcs/6}}; scan_nl_spcs(Cs, St, Line, Col, Toks, N) -> newline_end(Cs, St, Line, Col, Toks, N, nl_spcs(N)). - + scan_nl_tabs([$\t|Cs], St, Line, Col, Toks, N) when N < 11 -> scan_nl_tabs(Cs, St, Line, Col, Toks, N+1); scan_nl_tabs([]=Cs, _St, Line, Col, Toks, N) -> @@ -701,7 +712,7 @@ scan_nl_tabs(Cs, St, Line, Col, Toks, N) -> %% Note: returning {more,Cont} is meaningless here; one could just as %% well return several tokens. But since tokens() scans up to a full %% stop anyway, nothing is gained by not collecting all white spaces. -scan_nl_white_space([$\n|Cs], #erl_scan{text = false}=St, Line, no_col=Col, +scan_nl_white_space([$\n|Cs], #erl_scan{text = false}=St, Line, no_col=Col, Toks0, Ncs) -> Toks = [{white_space,Line,lists:reverse(Ncs)}|Toks0], scan_newline(Cs, St, Line+1, Col, Toks); @@ -714,7 +725,7 @@ scan_nl_white_space([C|Cs], St, Line, Col, Toks, Ncs) when ?WHITE_SPACE(C) -> scan_nl_white_space(Cs, St, Line, Col, Toks, [C|Ncs]); scan_nl_white_space([]=Cs, _St, Line, Col, Toks, Ncs) -> {more,{Cs,Col,Toks,Line,Ncs,fun scan_nl_white_space/6}}; -scan_nl_white_space(Cs, #erl_scan{text = false}=St, Line, no_col=Col, +scan_nl_white_space(Cs, #erl_scan{text = false}=St, Line, no_col=Col, Toks, Ncs) -> scan1(Cs, St, Line+1, Col, [{white_space,Line,lists:reverse(Ncs)}|Toks]); scan_nl_white_space(Cs, St, Line, Col, Toks, Ncs0) -> @@ -723,7 +734,7 @@ scan_nl_white_space(Cs, St, Line, Col, Toks, Ncs0) -> Token = {white_space,Attrs,Ncs}, scan1(Cs, St, Line+1, new_column(Col, length(Ncs)), [Token|Toks]). -newline_end(Cs, #erl_scan{text = false}=St, Line, no_col=Col, +newline_end(Cs, #erl_scan{text = false}=St, Line, no_col=Col, Toks, _N, Ncs) -> scan1(Cs, St, Line+1, Col, [{white_space,Line,Ncs}|Toks]); newline_end(Cs, St, Line, Col, Toks, N, Ncs) -> @@ -789,7 +800,7 @@ scan_char([$\\|Cs]=Cs0, St, Line, Col, Toks) -> Ntoks = [{char,Attrs,Val}|Toks], scan1(Ncs, St, Line, Ncol, Ntoks) end; -scan_char([$\n=C|Cs], St, Line, Col, Toks) -> +scan_char([$\n=C|Cs], St, Line, Col, Toks) -> Attrs = attributes(Line, Col, St, [$$,C]), scan1(Cs, St, Line+1, new_column(Col, 1), [{char,Attrs,C}|Toks]); scan_char([C|Cs], St, Line, Col, Toks) when ?CHAR(C) -> @@ -896,7 +907,7 @@ scan_string_no_col([Q|Cs], Line, Col, Q, Wcs, Uni) -> {Cs,Line,Col,_DontCare=[],lists:reverse(Wcs),Uni}; scan_string_no_col([$\n=C|Cs], Line, Col, Q, Wcs, Uni) -> scan_string_no_col(Cs, Line+1, Col, Q, [C|Wcs], Uni); -scan_string_no_col([C|Cs], Line, Col, Q, Wcs, Uni) when C =/= $\\, +scan_string_no_col([C|Cs], Line, Col, Q, Wcs, Uni) when C =/= $\\, ?CHAR(C), ?UNI255(C) -> scan_string_no_col(Cs, Line, Col, Q, [C|Wcs], Uni); scan_string_no_col(Cs, Line, Col, Q, Wcs, Uni) -> @@ -909,7 +920,7 @@ scan_string_col([Q|Cs], Line, Col, Q, Wcs0, Uni) -> {Cs,Line,Col+1,Str,Wcs,Uni}; scan_string_col([$\n=C|Cs], Line, _xCol, Q, Wcs, Uni) -> scan_string_col(Cs, Line+1, 1, Q, [C|Wcs], Uni); -scan_string_col([C|Cs], Line, Col, Q, Wcs, Uni) when C =/= $\\, +scan_string_col([C|Cs], Line, Col, Q, Wcs, Uni) when C =/= $\\, ?CHAR(C), ?UNI255(C) -> scan_string_col(Cs, Line, Col+1, Q, [C|Wcs], Uni); scan_string_col(Cs, Line, Col, Q, Wcs, Uni) -> @@ -970,8 +981,8 @@ scan_string1(eof, Line, Col, _Q, _Str, Wcs, _Uni) -> {error,Line,Col,lists:reverse(Wcs),eof}. -define(OCT(C), C >= $0, C =< $7). --define(HEX(C), C >= $0 andalso C =< $9 orelse - C >= $A andalso C =< $F orelse +-define(HEX(C), C >= $0 andalso C =< $9 orelse + C >= $A andalso C =< $F orelse C >= $a andalso C =< $f). %% \<1-3> octal digits @@ -1086,7 +1097,7 @@ scan_number(Cs, St, Line, Col, Toks, Ncs0) -> Ncol = incr_column(Col, length(Ncs)), scan_error({illegal,integer}, Line, Col, Line, Ncol, Cs) end. - + scan_based_int([C|Cs], St, Line, Col, Toks, {B,Ncs,Bcs}) when ?DIGIT(C), C < $0+B -> scan_based_int(Cs, St, Line, Col, Toks, {B,[C|Ncs],Bcs}); @@ -1262,7 +1273,7 @@ nl_tabs(8) -> "\n\t\t\t\t\t\t\t"; nl_tabs(9) -> "\n\t\t\t\t\t\t\t\t"; nl_tabs(10) -> "\n\t\t\t\t\t\t\t\t\t"; nl_tabs(11) -> "\n\t\t\t\t\t\t\t\t\t\t". - + tabs(1) -> "\t"; tabs(2) -> "\t\t"; tabs(3) -> "\t\t\t"; @@ -1303,5 +1314,4 @@ reserved_word('bsl') -> true; reserved_word('bsr') -> true; reserved_word('or') -> true; reserved_word('xor') -> true; -reserved_word('spec') -> true; reserved_word(_) -> false. diff --git a/lib/stdlib/src/escript.erl b/lib/stdlib/src/escript.erl index 5958a58d7c..99e454f593 100644 --- a/lib/stdlib/src/escript.erl +++ b/lib/stdlib/src/escript.erl @@ -19,102 +19,254 @@ -module(escript). %% Useful functions that can be called from scripts. --export([script_name/0, foldl/3]). +-export([script_name/0, create/2, extract/2]). %% Internal API. -export([start/0, start/1]). --record(state, {file, - module, +%%----------------------------------------------------------------------- + +-define(SHEBANG, "/usr/bin/env escript"). +-define(COMMENT, "This is an -*- erlang -*- file"). + +%%----------------------------------------------------------------------- + +-type mode() :: 'compile' | 'debug' | 'interpret' | 'run'. +-type source() :: 'archive' | 'beam' | 'text'. + +-record(state, {file :: file:filename(), + module :: module(), forms_or_bin, - source, - n_errors, - mode, - exports_main, - has_records}). - + source :: source(), + n_errors :: non_neg_integer(), + mode :: mode(), + exports_main :: boolean(), + has_records :: boolean()}). + +-type shebang() :: string(). +-type comment() :: string(). +-type emu_args() :: string(). + +-record(sections, {type, + shebang :: shebang(), + comment :: comment(), + emu_args :: emu_args(), + body}). + +-record(extract_options, {compile_source}). + +-type zip_file() :: + file:filename() + | {file:filename(), binary()} + | {file:filename(), binary(), file:file_info()}. +-type zip_create_option() :: term(). +-type section() :: + shebang + | {shebang, shebang()} + | comment + | {comment, comment()} + | {emu_args, emu_args()} + | {source, file:filename() | binary()} + | {beam, file:filename() | binary()} + | {archive, file:filename() | binary()} + | {archive, [zip_file()], [zip_create_option()]}. + +%%----------------------------------------------------------------------- + +%% Create a complete escript file with both header and body +-spec create(file:filename() | binary, [section()]) -> + ok | {ok, binary()} | {error, term()}. + +create(File, Options) when is_list(Options) -> + try + S = prepare(Options, #sections{}), + BinList = + [Section || Section <- [S#sections.shebang, + S#sections.comment, + S#sections.emu_args, + S#sections.body], + Section =/= undefined], + case File of + binary -> + {ok, list_to_binary(BinList)}; + _ -> + case file:write_file(File, BinList) of + ok -> + ok; + {error, Reason} -> + {error, {Reason, File}} + end + end + catch + throw:PrepareReason -> + {error, PrepareReason} + end. + +prepare([H | T], S) -> + case H of + {shebang, undefined} -> + prepare(T, S); + shebang -> + prepare(T, S#sections{shebang = "#!" ++ ?SHEBANG ++ "\n"}); + {shebang, default} -> + prepare(T, S#sections{shebang = "#!" ++ ?SHEBANG ++ "\n"}); + {shebang, Shebang} when is_list(Shebang) -> + prepare(T, S#sections{shebang = "#!" ++ Shebang ++ "\n"}); + {comment, undefined} -> + prepare(T, S); + comment -> + prepare(T, S#sections{comment = "%% " ++ ?COMMENT ++ "\n"}); + {comment, default} -> + prepare(T, S#sections{comment = "%% " ++ ?COMMENT ++ "\n"}); + {comment, Comment} when is_list(Comment) -> + prepare(T, S#sections{comment = "%% " ++ Comment ++ "\n"}); + {emu_args, undefined} -> + prepare(T, S); + {emu_args, Args} when is_list(Args) -> + prepare(T, S#sections{emu_args = "%%!" ++ Args ++ "\n"}); + {Type, File} when is_list(File) -> + case file:read_file(File) of + {ok, Bin} -> + prepare(T, S#sections{type = Type, body = Bin}); + {error, Reason} -> + throw({Reason, H}) + end; + {Type, Bin} when is_binary(Bin) -> + prepare(T, S#sections{type = Type, body = Bin}); + {archive = Type, ZipFiles, ZipOptions} + when is_list(ZipFiles), is_list(ZipOptions) -> + File = "dummy.zip", + case zip:create(File, ZipFiles, ZipOptions ++ [memory]) of + {ok, {File, ZipBin}} -> + prepare(T, S#sections{type = Type, body = ZipBin}); + {error, Reason} -> + throw({Reason, H}) + end; + _ -> + throw({badarg, H}) + end; +prepare([], #sections{body = undefined}) -> + throw(missing_body); +prepare([], #sections{type = Type} = S) + when Type =:= source; Type =:= beam; Type =:= archive -> + S; +prepare([], #sections{type = Type}) -> + throw({illegal_type, Type}); +prepare(BadOptions, _) -> + throw({badarg, BadOptions}). + +-type section_name() :: shebang | comment | emu_args | body . +-type extract_option() :: compile_source | {section, [section_name()]}. +-spec extract(file:filename(), [extract_option()]) -> + {ok, [section()]} | {error, term()}. + +extract(File, Options) when is_list(File), is_list(Options) -> + try + EO = parse_extract_options(Options, + #extract_options{compile_source = false}), + {HeaderSz, NextLineNo, Fd, Sections} = + parse_header(File, not EO#extract_options.compile_source), + Type = Sections#sections.type, + case {Type, EO#extract_options.compile_source} of + {source, true} -> + Bin = compile_source(Type, File, Fd, NextLineNo, HeaderSz); + {_, _} -> + ok = file:close(Fd), + case file:read_file(File) of + {ok, <<_Header:HeaderSz/binary, Bin/binary>>} -> + ok; + {error, ReadReason} -> + Bin = get_rid_of_compiler_warning, + throw(ReadReason) + end + end, + return_sections(Sections, Bin) + catch + throw:Reason -> + {error, Reason} + end. + +parse_extract_options([H | T], EO) -> + case H of + compile_source -> + EO2 = EO#extract_options{compile_source = true}, + parse_extract_options(T, EO2); + _ -> + throw({badarg, H}) + end; +parse_extract_options([], EO) -> + EO. + +compile_source(Type, File, Fd, NextLineNo, HeaderSz) -> + {text, _Module, Forms, _HasRecs, _Mode} = + do_parse_file(Type, File, Fd, NextLineNo, HeaderSz, false), + ok = file:close(Fd), + case compile:forms(Forms, [return_errors, debug_info]) of + {ok, _, BeamBin} -> + BeamBin; + {error, Errors, Warnings} -> + throw({compile, [{errors, format_errors(Errors)}, + {warnings, format_errors(Warnings)}]}) + end. + +format_errors(CompileErrors) -> + [lists:flatten([File, ":", integer_to_list(LineNo), ": ", + Mod:format_error(Error)]) || + {File, FileErrors} <- CompileErrors, + {LineNo, Mod, Error} <- FileErrors]. + +return_sections(S, Bin) -> + {ok, [normalize_section(shebang, S#sections.shebang), + normalize_section(comment, S#sections.comment), + normalize_section(emu_args, S#sections.emu_args), + normalize_section(S#sections.type, Bin)]}. + +normalize_section(Name, undefined) -> + {Name, undefined}; +normalize_section(shebang, "#!" ++ Chars) -> + Chopped = string:strip(Chars, right, $\n), + Stripped = string:strip(Chopped, both), + if + Stripped =:= ?SHEBANG -> + {shebang, default}; + true -> + {shebang, Stripped} + end; +normalize_section(comment, Chars) -> + Chopped = string:strip(Chars, right, $\n), + Stripped = string:strip(string:strip(Chopped, left, $%), both), + if + Stripped =:= ?COMMENT -> + {comment, default}; + true -> + {comment, Stripped} + end; +normalize_section(emu_args, "%%!" ++ Chars) -> + Chopped = string:strip(Chars, right, $\n), + Stripped = string:strip(Chopped, both), + {emu_args, Stripped}; +normalize_section(Name, Chars) -> + {Name, Chars}. + +-spec script_name() -> string(). + script_name() -> [ScriptName|_] = init:get_plain_arguments(), ScriptName. -%% Apply Fun(Name, GetInfo, GetBin, Acc) for each file in the escript. -%% -%% Fun/2 must return a new accumulator which is passed to the next call. -%% The function returns the final value of the accumulator. Acc0 is -%% returned if the escript contain an empty archive. -%% -%% GetInfo/0 is a fun that returns a #file_info{} record for the file. -%% GetBin/0 is a fun that returns a the contents of the file as a binary. -%% -%% An escript may contain erlang code, beam code or an archive: -%% -%% archive - the Fun/2 will be applied for each file in the archive -%% beam - the Fun/2 will be applied once and GetInfo/0 returns the file -%% info for the (entire) escript file -%% erl - the Fun/2 will be applied once, GetInfo/0 returns the file -%% info for the (entire) escript file and the GetBin returns -%% the compiled beam code - -%%-spec foldl(fun((string(), -%% fun(() -> #file_info()), -%% fun(() -> binary() -> term()), -%% term()) -> term()), -%% term(), -%% string()). -foldl(Fun, Acc0, File) when is_function(Fun, 4) -> - case parse_file(File, false) of - {text, _, Forms, _HasRecs, _Mode} when is_list(Forms) -> - GetInfo = fun() -> file:read_file_info(File) end, - GetBin = - fun() -> - case compile:forms(Forms, [return_errors, debug_info]) of - {ok, _, BeamBin} -> - BeamBin; - {error, _Errors, _Warnings} -> - fatal("There were compilation errors.") - end - end, - try - {ok, Fun(".", GetInfo, GetBin, Acc0)} - catch - throw:Reason -> - {error, Reason} - end; - {beam, _, BeamBin, _HasRecs, _Mode} when is_binary(BeamBin) -> - GetInfo = fun() -> file:read_file_info(File) end, - GetBin = fun() -> BeamBin end, - try - {ok, Fun(".", GetInfo, GetBin, Acc0)} - catch - throw:Reason -> - {error, Reason} - end; - {archive, _, ArchiveBin, _HasRecs, _Mode} when is_binary(ArchiveBin) -> - ZipFun = - fun({Name, GetInfo, GetBin}, A) -> - A2 = Fun(Name, GetInfo, GetBin, A), - {true, false, A2} - end, - case prim_zip:open(ZipFun, Acc0, {File, ArchiveBin}) of - {ok, PrimZip, Res} -> - ok = prim_zip:close(PrimZip), - {ok, Res}; - {error, bad_eocd} -> - {error, "Not an archive file"}; - {error, Reason} -> - {error, Reason} - end - end. - %% %% Internal API. %% +-spec start() -> no_return(). + start() -> start([]). +-spec start([string()]) -> no_return(). + start(EscriptOptions) -> - try + try %% Commands run using -run or -s are run in a process %% trap_exit set to false. Because this behaviour is %% surprising for users of escript, make sure to reset @@ -143,11 +295,11 @@ parse_and_run(File, Args, Options) -> parse_file(File, CheckOnly), Mode2 = case lists:member("d", Options) of - true -> + true -> debug; false -> case lists:member("c", Options) of - true -> + true -> compile; false -> case lists:member("i", Options) of @@ -177,7 +329,7 @@ parse_and_run(File, Args, Options) -> _Other -> fatal("There were compilation errors.") end - end; + end; is_binary(FormsOrBin) -> case Source of archive -> @@ -190,11 +342,13 @@ parse_and_run(File, Args, Options) -> true -> my_halt(0); false -> - Text = lists:concat(["Function ", Module, ":main/1 is not exported"]), + Text = lists:concat(["Function ", Module, + ":main/1 is not exported"]), fatal(Text) end; _ -> - Text = lists:concat(["Cannot load module ", Module, " from archive"]), + Text = lists:concat(["Cannot load module ", Module, + " from archive"]), fatal(Text) end; ok -> @@ -212,7 +366,7 @@ parse_and_run(File, Args, Options) -> run -> {module, Module} = code:load_binary(Module, File, FormsOrBin), run(Module, Args); - debug -> + debug -> [Base | Rest] = lists:reverse(filename:split(File)), Base2 = filename:basename(Base, code:objfile_extension()), Rest2 = @@ -222,8 +376,8 @@ parse_and_run(File, Args, Options) -> end, SrcFile = filename:join(lists:reverse([Base2 ++ ".erl" | Rest2])), debug(Module, {Module, SrcFile, File, FormsOrBin}, Args) - end - end + end + end end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -231,25 +385,19 @@ parse_and_run(File, Args, Options) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% parse_file(File, CheckOnly) -> - S = #state{file = File, - n_errors = 0, - mode = interpret, - exports_main = false, - has_records = false}, - {ok, Fd} = - case file:open(File, [read]) of - {ok, Fd0} -> - {ok, Fd0}; - {error, R} -> - fatal(lists:concat([file:format_error(R), ": '", File, "'"])) - end, - {HeaderSz, StartLine, ScriptType} = skip_header(Fd, 1), + {HeaderSz, NextLineNo, Fd, Sections} = + parse_header(File, false), + do_parse_file(Sections#sections.type, + File, Fd, NextLineNo, HeaderSz, CheckOnly). + +do_parse_file(Type, File, Fd, NextLineNo, HeaderSz, CheckOnly) -> + S = initial_state(File), #state{mode = Mode, source = Source, module = Module, forms_or_bin = FormsOrBin, has_records = HasRecs} = - case ScriptType of + case Type of archive -> %% Archive file ok = file:close(Fd), @@ -260,63 +408,101 @@ parse_file(File, CheckOnly) -> parse_beam(S, File, HeaderSz, CheckOnly); source -> %% Source code - parse_source(S, File, Fd, StartLine, HeaderSz, CheckOnly) + parse_source(S, File, Fd, NextLineNo, HeaderSz, CheckOnly) end, {Source, Module, FormsOrBin, HasRecs, Mode}. +initial_state(File) -> + #state{file = File, + n_errors = 0, + mode = interpret, + exports_main = false, + has_records = false}. + %% Skip header and make a heuristic guess about the script type -skip_header(P, LineNo) -> +parse_header(File, KeepFirst) -> + LineNo = 1, + {ok, Fd} = + case file:open(File, [read]) of + {ok, Fd0} -> + {ok, Fd0}; + {error, R} -> + fatal(lists:concat([file:format_error(R), ": '", File, "'"])) + end, + %% Skip shebang on first line - {ok, HeaderSz0} = file:position(P, cur), - Line1 = get_line(P), + {ok, HeaderSz0} = file:position(Fd, cur), + Line1 = get_line(Fd), case classify_line(Line1) of shebang -> - find_first_body_line(P, LineNo); + find_first_body_line(Fd, HeaderSz0, LineNo, KeepFirst, + #sections{shebang = Line1}); archive -> - {HeaderSz0, LineNo, archive}; + {HeaderSz0, LineNo, Fd, + #sections{type = archive}}; beam -> - {HeaderSz0, LineNo, beam}; + {HeaderSz0, LineNo, Fd, + #sections{type = beam}}; _ -> - find_first_body_line(P, LineNo) + find_first_body_line(Fd, HeaderSz0, LineNo, KeepFirst, + #sections{}) end. -find_first_body_line(P, LineNo) -> - {ok, HeaderSz1} = file:position(P, cur), +find_first_body_line(Fd, HeaderSz0, LineNo, KeepFirst, Sections) -> + {ok, HeaderSz1} = file:position(Fd, cur), %% Look for special comment on second line - Line2 = get_line(P), - {ok, HeaderSz2} = file:position(P, cur), + Line2 = get_line(Fd), + {ok, HeaderSz2} = file:position(Fd, cur), case classify_line(Line2) of emu_args -> %% Skip special comment on second line - Line3 = get_line(P), - {HeaderSz2, LineNo + 2, guess_type(Line3)}; - _ -> + Line3 = get_line(Fd), + {HeaderSz2, LineNo + 2, Fd, + Sections#sections{type = guess_type(Line3), + comment = undefined, + emu_args = Line2}}; + Line2Type -> %% Look for special comment on third line - Line3 = get_line(P), - {ok, HeaderSz3} = file:position(P, cur), - case classify_line(Line3) of - emu_args -> + Line3 = get_line(Fd), + {ok, HeaderSz3} = file:position(Fd, cur), + Line3Type = classify_line(Line3), + if + Line3Type =:= emu_args -> %% Skip special comment on third line - Line4 = get_line(P), - {HeaderSz3, LineNo + 3, guess_type(Line4)}; - _ -> + Line4 = get_line(Fd), + {HeaderSz3, LineNo + 3, Fd, + Sections#sections{type = guess_type(Line4), + comment = Line2, + emu_args = Line3}}; + Sections#sections.shebang =:= undefined, + KeepFirst =:= true -> + %% No shebang. Use the entire file + {HeaderSz0, LineNo, Fd, + Sections#sections{type = guess_type(Line2)}}; + Sections#sections.shebang =:= undefined -> + %% No shebang. Skip the first line + {HeaderSz1, LineNo, Fd, + Sections#sections{type = guess_type(Line2)}}; + Line2Type =:= comment -> + %% Skip shebang on first line and comment on second + {HeaderSz2, LineNo + 2, Fd, + Sections#sections{type = guess_type(Line3), + comment = Line2}}; + true -> %% Just skip shebang on first line - {HeaderSz1, LineNo + 1, guess_type(Line2)} + {HeaderSz1, LineNo + 1, Fd, + Sections#sections{type = guess_type(Line2)}} end end. - + classify_line(Line) -> case Line of - [$\#, $\! | _] -> - shebang; - [$P, $K | _] -> - archive; - [$F, $O, $R, $1 | _] -> - beam; - [$\%, $\%, $\! | _] -> - emu_args; - _ -> - undefined + "#!" ++ _ -> shebang; + "PK" ++ _ -> archive; + "FOR1" ++ _ -> beam; + "%%!" ++ _ -> emu_args; + "%" ++ _ -> comment; + _ -> undefined end. guess_type(Line) -> @@ -336,8 +522,8 @@ get_line(P) -> parse_archive(S, File, HeaderSz) -> case file:read_file(File) of - {ok, <<_FirstLine:HeaderSz/binary, Bin/binary>>} -> - Mod = + {ok, <<_Header:HeaderSz/binary, Bin/binary>>} -> + Mod = case init:get_argument(escript) of {ok, [["main", M]]} -> %% Use explicit module name @@ -345,14 +531,13 @@ parse_archive(S, File, HeaderSz) -> _ -> %% Use escript name without extension as module name RevBase = lists:reverse(filename:basename(File)), - RevBase2 = + RevBase2 = case lists:dropwhile(fun(X) -> X =/= $. end, RevBase) of [$. | Rest] -> Rest; [] -> RevBase end, list_to_atom(lists:reverse(RevBase2)) end, - S#state{source = archive, mode = run, module = Mod, @@ -365,7 +550,7 @@ parse_archive(S, File, HeaderSz) -> parse_beam(S, File, HeaderSz, CheckOnly) -> - {ok, <<_FirstLine:HeaderSz/binary, Bin/binary>>} = + {ok, <<_Header:HeaderSz/binary, Bin/binary>>} = file:read_file(File), case beam_lib:chunks(Bin, [exports]) of {ok, {Module, [{exports, Exports}]}} -> @@ -399,7 +584,7 @@ parse_source(S, File, Fd, StartLine, HeaderSz, CheckOnly) -> {ok, FileForm} = epp:parse_erl_form(Epp), OptModRes = epp:parse_erl_form(Epp), S2 = S#state{source = text, module = Module}, - S3 = + S3 = case OptModRes of {ok, {attribute,_, module, M} = Form} -> epp_parse_file(Epp, S2#state{module = M}, [Form, FileForm]); @@ -408,8 +593,8 @@ parse_source(S, File, Fd, StartLine, HeaderSz, CheckOnly) -> epp_parse_file2(Epp, S2, [ModForm, FileForm], OptModRes); {error, _} -> epp_parse_file2(Epp, S2, [FileForm], OptModRes); - {eof,LastLine} -> - S#state{forms_or_bin = [FileForm, {eof,LastLine}]} + {eof, _LastLine} = Eof -> + S#state{forms_or_bin = [FileForm, Eof]} end, ok = epp:close(Epp), ok = file:close(Fd), @@ -448,12 +633,12 @@ check_source(S, CheckOnly) -> pre_def_macros(File) -> {MegaSecs, Secs, MicroSecs} = erlang:now(), - Replace = fun(Char) -> + Replace = fun(Char) -> case Char of $\. -> $\_; _ -> Char end - end, + end, CleanBase = lists:map(Replace, filename:basename(File)), ModuleStr = CleanBase ++ "__" ++ @@ -504,8 +689,8 @@ epp_parse_file2(Epp, S, Forms, Parsed) -> io:format("~s:~w: ~s\n", [S#state.file,Ln,Mod:format_error(Args)]), epp_parse_file(Epp, S#state{n_errors = S#state.n_errors + 1}, [Form | Forms]); - {eof,LastLine} -> - S#state{forms_or_bin = lists:reverse([{eof, LastLine} | Forms])} + {eof, _LastLine} = Eof -> + S#state{forms_or_bin = lists:reverse([Eof | Forms])} end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -642,8 +827,8 @@ eval_exprs([E|Es], Bs0, Lf, Ef, RBs) -> eval_exprs(Es, Bs, Lf, Ef, RBs). format_exception(Class, Reason) -> - PF = fun(Term, I) -> - io_lib:format("~." ++ integer_to_list(I) ++ "P", [Term, 50]) + PF = fun(Term, I) -> + io_lib:format("~." ++ integer_to_list(I) ++ "P", [Term, 50]) end, StackTrace = erlang:get_stacktrace(), StackFun = fun(M, _F, _A) -> (M =:= erl_eval) or (M =:= ?MODULE) end, @@ -651,7 +836,7 @@ format_exception(Class, Reason) -> fatal(Str) -> throw(Str). - + my_halt(Reason) -> case process_info(group_leader(), status) of {_,waiting} -> @@ -675,7 +860,7 @@ hidden_apply(App, M, F, Args) -> Arity = length(Args), Text = io_lib:format("Call to ~w:~w/~w in application ~w failed.\n", [M, F, Arity, App]), - fatal(Text); + fatal(Text); Stk -> erlang:raise(error, undef, Stk) end diff --git a/lib/stdlib/src/ets.erl b/lib/stdlib/src/ets.erl index 9f84e3639f..1d033f6f7b 100644 --- a/lib/stdlib/src/ets.erl +++ b/lib/stdlib/src/ets.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(ets). @@ -42,10 +42,15 @@ -export([i/0, i/1, i/2, i/3]). -%%------------------------------------------------------------------------------ +-export_type([tab/0, tid/0]). + +%%----------------------------------------------------------------------------- -type tab() :: atom() | tid(). +%% a similar definition is also in erl_types +-opaque tid() :: integer(). + -type ext_info() :: 'md5sum' | 'object_count'. -type protection() :: 'private' | 'protected' | 'public'. -type type() :: 'bag' | 'duplicate_bag' | 'ordered_set' | 'set'. @@ -63,7 +68,7 @@ -type match_pattern() :: atom() | tuple(). -type match_specs() :: [{match_pattern(), [_], [_]}]. -%%------------------------------------------------------------------------------ +%%----------------------------------------------------------------------------- %% The following functions used to be found in this module, but %% are now BIFs (i.e. implemented in C). @@ -230,7 +235,7 @@ from_dets(EtsTable, DetsTable) -> erlang:error(Unexpected,[EtsTable,DetsTable]) end. --spec to_dets(tab(), dets:tab_name()) -> tab(). +-spec to_dets(tab(), dets:tab_name()) -> dets:tab_name(). to_dets(EtsTable, DetsTable) -> case (catch dets:from_ets(DetsTable, EtsTable)) of @@ -622,14 +627,14 @@ do_read_and_verify(ReadFun,InitState,Tab,FtOptions,HeadCount,Verify) -> end, {ok,Tab}; {ok,{FinalMD5State,FinalCount,['$end_of_table',LastInfo],_}} -> - ECount = case lists:keysearch(count,1,LastInfo) of - {value,{count,N}} -> + ECount = case lists:keyfind(count,1,LastInfo) of + {count,N} -> N; _ -> false end, - EMD5 = case lists:keysearch(md5,1,LastInfo) of - {value,{md5,M}} -> + EMD5 = case lists:keyfind(md5,1,LastInfo) of + {md5,M} -> M; _ -> false @@ -742,22 +747,21 @@ get_header_data(Name,true) -> false -> throw(badfile); true -> - Major = case lists:keysearch(major,1,L) of - {value,{major,Maj}} -> + Major = case lists:keyfind(major,1,L) of + {major,Maj} -> Maj; _ -> 0 end, - Minor = case lists:keysearch(minor,1,L) of - {value,{minor,Min}} -> + Minor = case lists:keyfind(minor,1,L) of + {minor,Min} -> Min; _ -> 0 end, FtOptions = - case lists:keysearch(extended_info,1,L) of - {value,{extended_info,I}} - when is_list(I) -> + case lists:keyfind(extended_info,1,L) of + {extended_info,I} when is_list(I) -> #filetab_options { object_count = @@ -786,29 +790,28 @@ get_header_data(Name,true) -> end; get_header_data(Name, false) -> - case wrap_chunk(Name,start,1,false) of + case wrap_chunk(Name, start, 1, false) of {C,[Tup]} when is_tuple(Tup) -> L = tuple_to_list(Tup), case verify_header_mandatory(L) of false -> throw(badfile); true -> - Major = case lists:keysearch(major_version,1,L) of - {value,{major_version,Maj}} -> + Major = case lists:keyfind(major_version, 1, L) of + {major_version, Maj} -> Maj; _ -> 0 end, - Minor = case lists:keysearch(minor_version,1,L) of - {value,{minor_version,Min}} -> + Minor = case lists:keyfind(minor_version, 1, L) of + {minor_version, Min} -> Min; _ -> 0 end, FtOptions = - case lists:keysearch(extended_info,1,L) of - {value,{extended_info,I}} - when is_list(I) -> + case lists:keyfind(extended_info, 1, L) of + {extended_info, I} when is_list(I) -> #filetab_options { object_count = @@ -825,25 +828,26 @@ get_header_data(Name, false) -> throw(badfile) end. -md5_and_convert([],MD5State,Count) -> +md5_and_convert([], MD5State, Count) -> {[],MD5State,Count,[]}; -md5_and_convert([H|T],MD5State,Count) when is_binary(H) -> +md5_and_convert([H|T], MD5State, Count) when is_binary(H) -> case (catch binary_to_term(H)) of {'EXIT', _} -> md5_and_convert(T,MD5State,Count); - ['$end_of_table',Dat] -> - {[],MD5State,Count,['$end_of_table',Dat]}; + ['$end_of_table',_Dat] = L -> + {[],MD5State,Count,L}; Term -> - X = erlang:md5_update(MD5State,H), - {Rest,NewMD5,NewCount,NewLast} = md5_and_convert(T,X,Count+1), + X = erlang:md5_update(MD5State, H), + {Rest,NewMD5,NewCount,NewLast} = md5_and_convert(T, X, Count+1), {[Term | Rest],NewMD5,NewCount,NewLast} end. -scan_for_endinfo([],Count) -> + +scan_for_endinfo([], Count) -> {[],Count,[]}; -scan_for_endinfo([['$end_of_table',Dat]],Count) -> +scan_for_endinfo([['$end_of_table',Dat]], Count) -> {['$end_of_table',Dat],Count,[]}; -scan_for_endinfo([Term|T],Count) -> - {NewLast,NCount,Rest} = scan_for_endinfo(T,Count+1), +scan_for_endinfo([Term|T], Count) -> + {NewLast,NCount,Rest} = scan_for_endinfo(T, Count+1), {NewLast,NCount,[Term | Rest]}. load_table(ReadFun, State, Tab) -> @@ -852,19 +856,19 @@ load_table(ReadFun, State, Tab) -> [] -> {ok,NewState}; List -> - ets:insert(Tab,List), - load_table(ReadFun,NewState,Tab) + ets:insert(Tab, List), + load_table(ReadFun, NewState, Tab) end. create_tab(I) -> - {value, {name, Name}} = lists:keysearch(name, 1, I), - {value, {type, Type}} = lists:keysearch(type, 1, I), - {value, {protection, P}} = lists:keysearch(protection, 1, I), - {value, {named_table, Val}} = lists:keysearch(named_table, 1, I), - {value, {keypos, Kp}} = lists:keysearch(keypos, 1, I), - {value, {size, Sz}} = lists:keysearch(size, 1, I), + {name, Name} = lists:keyfind(name, 1, I), + {type, Type} = lists:keyfind(type, 1, I), + {protection, P} = lists:keyfind(protection, 1, I), + {named_table, Val} = lists:keyfind(named_table, 1, I), + {keypos, _Kp} = Keypos = lists:keyfind(keypos, 1, I), + {size, Sz} = lists:keyfind(size, 1, I), try - Tab = ets:new(Name, [Type, P, {keypos, Kp} | named_table(Val)]), + Tab = ets:new(Name, [Type, P, Keypos | named_table(Val)]), {ok, Tab, Sz} catch _:_ -> @@ -905,9 +909,9 @@ tabfile_info(File) when is_list(File) ; is_atom(File) -> {value, Val} = lists:keysearch(named_table, 1, FullHeader), {value, Kp} = lists:keysearch(keypos, 1, FullHeader), {value, Sz} = lists:keysearch(size, 1, FullHeader), - Ei = case lists:keysearch(extended_info, 1, FullHeader) of - {value, Ei0} -> Ei0; - _ -> {extended_info, []} + Ei = case lists:keyfind(extended_info, 1, FullHeader) of + false -> {extended_info, []}; + Ei0 -> Ei0 end, {ok, [N,Type,P,Val,Kp,Sz,Ei,{version,{Major,Minor}}]} catch @@ -1021,21 +1025,20 @@ options(Option, Keys) -> options([Option], Keys, []). options(Options, [Key | Keys], L) when is_list(Options) -> - V = case lists:keysearch(Key, 1, Options) of - {value, {n_objects, default}} -> + V = case lists:keyfind(Key, 1, Options) of + {n_objects, default} -> {ok, default_option(Key)}; - {value, {n_objects, NObjs}} when is_integer(NObjs), - NObjs >= 1 -> + {n_objects, NObjs} when is_integer(NObjs), NObjs >= 1 -> {ok, NObjs}; - {value, {traverse, select}} -> + {traverse, select} -> {ok, select}; - {value, {traverse, {select, MS}}} -> - {ok, {select, MS}}; - {value, {traverse, first_next}} -> + {traverse, {select, _MS} = Select} -> + {ok, Select}; + {traverse, first_next} -> {ok, first_next}; - {value, {traverse, last_prev}} -> + {traverse, last_prev} -> {ok, last_prev}; - {value, {Key, _}} -> + {Key, _} -> badarg; false -> Default = default_option(Key), diff --git a/lib/stdlib/src/eval_bits.erl b/lib/stdlib/src/eval_bits.erl index 3671aecdcb..2cbd6cdae7 100644 --- a/lib/stdlib/src/eval_bits.erl +++ b/lib/stdlib/src/eval_bits.erl @@ -2,7 +2,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. +%% 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 @@ -19,6 +19,8 @@ %% -module(eval_bits). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([expr_grp/3,expr_grp/5,match_bits/6, match_bits/7,bin_gen/6]). diff --git a/lib/stdlib/src/file_sorter.erl b/lib/stdlib/src/file_sorter.erl index e21a0c88f3..2a5b08b581 100644 --- a/lib/stdlib/src/file_sorter.erl +++ b/lib/stdlib/src/file_sorter.erl @@ -18,6 +18,8 @@ %% -module(file_sorter). +%% Avoid warning for local function error/2 clashing with autoimported BIF. +-compile({no_auto_import,[error/2]}). -export([sort/1, sort/2, sort/3, keysort/2, keysort/3, keysort/4, merge/2, merge/3, @@ -191,7 +193,7 @@ options([{format, Format} | L], Opts) when Format =:= binary; options([{format, binary_term} | L], Opts) -> options(L, Opts#opts{format = binary_term_fun()}); options([{size, Size} | L], Opts) when is_integer(Size), Size >= 0 -> - options(L, Opts#opts{size = max(Size, 1)}); + options(L, Opts#opts{size = erlang:max(Size, 1)}); options([{no_files, NoFiles} | L], Opts) when is_integer(NoFiles), NoFiles > 1 -> options(L, Opts#opts{no_files = NoFiles}); @@ -997,10 +999,10 @@ close_read_fun(Fd, FileName, fsort) -> file:delete(FileName). read_objs(Fd, FileName, I, L, Bin0, Size0, LSz, W) -> - Max = max(Size0, ?CHUNKSIZE), + Max = erlang:max(Size0, ?CHUNKSIZE), BSz0 = byte_size(Bin0), Min = Size0 - BSz0 + W#w.hdlen, % Min > 0 - NoBytes = max(Min, Max), + NoBytes = erlang:max(Min, Max), case read(Fd, FileName, NoBytes, W) of {ok, Bin} -> BSz = byte_size(Bin), @@ -1180,9 +1182,6 @@ make_key2([Kp], T) -> make_key2([Kp | Kps], T) -> [element(Kp, T) | make_key2(Kps, T)]. -max(A, B) when A < B -> B; -max(A, _) -> A. - infun(W) -> W1 = W#w{in = undefined}, try (W#w.in)(read) of diff --git a/lib/stdlib/src/filelib.erl b/lib/stdlib/src/filelib.erl index 74c5172137..d5ddf9ed7e 100644 --- a/lib/stdlib/src/filelib.erl +++ b/lib/stdlib/src/filelib.erl @@ -20,6 +20,8 @@ %% File utilities. +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([wildcard/1, wildcard/2, is_dir/1, is_file/1, is_regular/1, compile_wildcard/1]). -export([fold_files/5, last_modified/1, file_size/1, ensure_dir/1]). @@ -40,66 +42,66 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec wildcard(name()) -> [file:filename()]. +-spec wildcard(file:name()) -> [file:filename()]. wildcard(Pattern) when is_list(Pattern) -> ?HANDLE_ERROR(do_wildcard(Pattern, file)). --spec wildcard(name(), name() | atom()) -> [file:filename()]. +-spec wildcard(file:name(), file:name() | atom()) -> [file:filename()]. wildcard(Pattern, Cwd) when is_list(Pattern), is_list(Cwd) -> ?HANDLE_ERROR(do_wildcard(Pattern, Cwd, file)); wildcard(Pattern, Mod) when is_list(Pattern), is_atom(Mod) -> ?HANDLE_ERROR(do_wildcard(Pattern, Mod)). --spec wildcard(name(), name(), atom()) -> [file:filename()]. +-spec wildcard(file:name(), file:name(), atom()) -> [file:filename()]. wildcard(Pattern, Cwd, Mod) when is_list(Pattern), is_list(Cwd), is_atom(Mod) -> ?HANDLE_ERROR(do_wildcard(Pattern, Cwd, Mod)). --spec is_dir(name()) -> boolean(). +-spec is_dir(file:name()) -> boolean(). is_dir(Dir) -> do_is_dir(Dir, file). --spec is_dir(name(), atom()) -> boolean(). +-spec is_dir(file:name(), atom()) -> boolean(). is_dir(Dir, Mod) when is_atom(Mod) -> do_is_dir(Dir, Mod). --spec is_file(name()) -> boolean(). +-spec is_file(file:name()) -> boolean(). is_file(File) -> do_is_file(File, file). --spec is_file(name(), atom()) -> boolean(). +-spec is_file(file:name(), atom()) -> boolean(). is_file(File, Mod) when is_atom(Mod) -> do_is_file(File, Mod). --spec is_regular(name()) -> boolean(). +-spec is_regular(file:name()) -> boolean(). is_regular(File) -> do_is_regular(File, file). --spec is_regular(name(), atom()) -> boolean(). +-spec is_regular(file:name(), atom()) -> boolean(). is_regular(File, Mod) when is_atom(Mod) -> do_is_regular(File, Mod). --spec fold_files(name(), string(), boolean(), fun((_,_) -> _), _) -> _. +-spec fold_files(file:name(), string(), boolean(), fun((_,_) -> _), _) -> _. fold_files(Dir, RegExp, Recursive, Fun, Acc) -> do_fold_files(Dir, RegExp, Recursive, Fun, Acc, file). --spec fold_files(name(), string(), boolean(), fun((_,_) -> _), _, atom()) -> _. +-spec fold_files(file:name(), string(), boolean(), fun((_,_) -> _), _, atom()) -> _. fold_files(Dir, RegExp, Recursive, Fun, Acc, Mod) when is_atom(Mod) -> do_fold_files(Dir, RegExp, Recursive, Fun, Acc, Mod). --spec last_modified(name()) -> date_time() | 0. +-spec last_modified(file:name()) -> file:date_time() | 0. last_modified(File) -> do_last_modified(File, file). --spec last_modified(name(), atom()) -> date_time() | 0. +-spec last_modified(file:name(), atom()) -> file:date_time() | 0. last_modified(File, Mod) when is_atom(Mod) -> do_last_modified(File, Mod). --spec file_size(name()) -> non_neg_integer(). +-spec file_size(file:name()) -> non_neg_integer(). file_size(File) -> do_file_size(File, file). --spec file_size(name(), atom()) -> non_neg_integer(). +-spec file_size(file:name(), atom()) -> non_neg_integer(). file_size(File, Mod) when is_atom(Mod) -> do_file_size(File, Mod). @@ -218,7 +220,7 @@ do_file_size(File, Mod) -> %% +type X = filename() | dirname() %% ensures that the directory name required to create D exists --spec ensure_dir(name()) -> 'ok' | {'error', posix()}. +-spec ensure_dir(file:name()) -> 'ok' | {'error', file:posix()}. ensure_dir("/") -> ok; ensure_dir(F) -> diff --git a/lib/stdlib/src/filename.erl b/lib/stdlib/src/filename.erl index cd26b2e219..01c06e4596 100644 --- a/lib/stdlib/src/filename.erl +++ b/lib/stdlib/src/filename.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% %% -module(filename). @@ -57,12 +57,12 @@ %% (for Unix) : absname("/") -> "/" %% (for WIN32): absname("/") -> "D:/" --spec absname(name()) -> string(). +-spec absname(file:name()) -> string(). absname(Name) -> {ok, Cwd} = file:get_cwd(), absname(Name, Cwd). --spec absname(name(), string()) -> string(). +-spec absname(file:name(), string()) -> string(). absname(Name, AbsBase) -> case pathtype(Name) of relative -> @@ -98,7 +98,7 @@ absname_vr([[X, $:]|Name], _, _AbsBase) -> %% For other systems this is just a join/2, but assumes that %% AbsBase must be absolute and Name must be relative. --spec absname_join(string(), name()) -> string(). +-spec absname_join(string(), file:name()) -> string(). absname_join(AbsBase, Name) -> case major_os_type() of vxworks -> @@ -136,7 +136,7 @@ absname_pretty(Abspath, [First|Rest], AbsBase) -> %% basename("/usr/foo/") -> "foo" (trailing slashes ignored) %% basename("/") -> [] --spec basename(name()) -> string(). +-spec basename(file:name()) -> string(). basename(Name0) -> Name = flatten(Name0), {DirSep2, DrvSep} = separators(), @@ -190,7 +190,7 @@ skip_prefix1(Name, _) -> %% rootname(basename("xxx.jam")) -> "xxx" %% rootname(basename("xxx.erl")) -> "xxx" --spec basename(name(), name()) -> string(). +-spec basename(file:name(), file:name()) -> string(). basename(Name0, Ext0) -> Name = flatten(Name0), Ext = flatten(Ext0), @@ -216,7 +216,7 @@ basename([], _Ext, Tail, _DrvSep2) -> %% Example: dirname("/usr/src/kalle.erl") -> "/usr/src", %% dirname("kalle.erl") -> "." --spec dirname(name()) -> string(). +-spec dirname(file:name()) -> string(). dirname(Name0) -> Name = flatten(Name0), case os:type() of @@ -268,7 +268,7 @@ dirname([], Dir, _, _) -> %% %% On Windows: fn:dirname("\\usr\\src/kalle.erl") -> "/usr/src" --spec extension(name()) -> string(). +-spec extension(file:name()) -> string(). extension(Name0) -> Name = flatten(Name0), extension(Name, [], major_os_type()). @@ -357,7 +357,7 @@ maybe_remove_dirsep(Name, _) -> %% a given base directory, which is is assumed to be normalised %% by a previous call to join/{1,2}. --spec append(string(), name()) -> string(). +-spec append(string(), file:name()) -> string(). append(Dir, Name) -> Dir ++ [$/|Name]. @@ -373,7 +373,7 @@ append(Dir, Name) -> %% current working volume. (Windows only) %% Example: a:bar.erl, /temp/foo.erl --spec pathtype(name()) -> 'absolute' | 'relative' | 'volumerelative'. +-spec pathtype(file:name()) -> 'absolute' | 'relative' | 'volumerelative'. pathtype(Atom) when is_atom(Atom) -> pathtype(atom_to_list(Atom)); pathtype(Name) when is_list(Name) -> @@ -422,7 +422,7 @@ win32_pathtype(_) -> relative. %% Examples: rootname("/jam.src/kalle") -> "/jam.src/kalle" %% rootname("/jam.src/foo.erl") -> "/jam.src/foo" --spec rootname(name()) -> string(). +-spec rootname(file:name()) -> string(). rootname(Name0) -> Name = flatten(Name0), rootname(Name, [], [], major_os_type()). @@ -451,7 +451,7 @@ rootname([], Root, _Ext, _OsType) -> %% Examples: rootname("/jam.src/kalle.jam", ".erl") -> "/jam.src/kalle.jam" %% rootname("/jam.src/foo.erl", ".erl") -> "/jam.src/foo" --spec rootname(name(), name()) -> string(). +-spec rootname(file:name(), file:name()) -> string(). rootname(Name0, Ext0) -> Name = flatten(Name0), Ext = flatten(Ext0), @@ -471,7 +471,7 @@ rootname2([Char|Rest], Ext, Result) when is_integer(Char) -> %% split("foo/bar") -> ["foo", "bar"] %% split("a:\\msdev\\include") -> ["a:/", "msdev", "include"] --spec split(name()) -> [string()]. +-spec split(file:name()) -> [string()]. split(Name0) -> Name = flatten(Name0), case os:type() of @@ -771,7 +771,7 @@ vxworks_first2(Devicep, [H|T], FirstComp) -> %% flatten(List) %% Flatten a list, also accepting atoms. --spec flatten(name()) -> string(). +-spec flatten(file:name()) -> string(). flatten(List) -> do_flatten(List, []). diff --git a/lib/stdlib/src/gen.erl b/lib/stdlib/src/gen.erl index 5aab547644..43df6f621d 100644 --- a/lib/stdlib/src/gen.erl +++ b/lib/stdlib/src/gen.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(gen). @@ -212,7 +212,22 @@ do_call(Process, Label, Request, Timeout) -> catch erlang:send(Process, {Label, {self(), Mref}, Request}, [noconnect]), - wait_resp_mon(Node, Mref, Timeout) + receive + {Mref, Reply} -> + erlang:demonitor(Mref, [flush]), + {ok, Reply}; + {'DOWN', Mref, _, _, noconnection} -> + exit({nodedown, Node}); + {'DOWN', Mref, _, _, Reason} -> + exit(Reason) + after Timeout -> + erlang:demonitor(Mref), + receive + {'DOWN', Mref, _, _, _} -> true + after 0 -> true + end, + exit(timeout) + end catch error:_ -> %% Node (C/Java?) is not supporting the monitor. @@ -233,24 +248,6 @@ do_call(Process, Label, Request, Timeout) -> end end. -wait_resp_mon(Node, Mref, Timeout) -> - receive - {Mref, Reply} -> - erlang:demonitor(Mref, [flush]), - {ok, Reply}; - {'DOWN', Mref, _, _, noconnection} -> - exit({nodedown, Node}); - {'DOWN', Mref, _, _, Reason} -> - exit(Reason) - after Timeout -> - erlang:demonitor(Mref), - receive - {'DOWN', Mref, _, _, _} -> true - after 0 -> true - end, - exit(timeout) - end. - wait_resp(Node, Tag, Timeout) -> receive {Tag, Reply} -> diff --git a/lib/stdlib/src/gen_event.erl b/lib/stdlib/src/gen_event.erl index 1b30aaf5eb..b1e9e3a02f 100644 --- a/lib/stdlib/src/gen_event.erl +++ b/lib/stdlib/src/gen_event.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(gen_event). @@ -42,7 +42,6 @@ system_continue/3, system_terminate/4, system_code_change/4, - print_event/3, format_status/2]). -import(error_logger, [error_msg/2]). @@ -239,7 +238,7 @@ fetch_msg(Parent, ServerName, MSL, Debug, Hib) -> Msg when Debug =:= [] -> handle_msg(Msg, Parent, ServerName, MSL, []); Msg -> - Debug1 = sys:handle_debug(Debug, {?MODULE, print_event}, + Debug1 = sys:handle_debug(Debug, fun print_event/3, ServerName, {in, Msg}), handle_msg(Msg, Parent, ServerName, MSL, Debug1) end. @@ -678,12 +677,23 @@ report_error(Handler, Reason, State, LastIn, SName) -> _ -> Reason end, + Mod = Handler#handler.module, + FmtState = case erlang:function_exported(Mod, format_status, 2) of + true -> + Args = [get(), State], + case catch Mod:format_status(terminate, Args) of + {'EXIT', _} -> State; + Else -> Else + end; + _ -> + State + end, error_msg("** gen_event handler ~p crashed.~n" "** Was installed in ~p~n" "** Last event was: ~p~n" "** When handler state == ~p~n" "** Reason == ~p~n", - [handler(Handler),SName,LastIn,State,Reason1]). + [handler(Handler),SName,LastIn,FmtState,Reason1]). handler(Handler) when not Handler#handler.id -> Handler#handler.module; @@ -712,10 +722,20 @@ get_modules(MSL) -> %%----------------------------------------------------------------- %% Status information %%----------------------------------------------------------------- -format_status(_Opt, StatusData) -> - [_PDict, SysState, Parent, _Debug, [ServerName, MSL, _Hib]] = StatusData, +format_status(Opt, StatusData) -> + [PDict, SysState, Parent, _Debug, [ServerName, MSL, _Hib]] = StatusData, Header = lists:concat(["Status for event handler ", ServerName]), + FmtMSL = [case erlang:function_exported(Mod, format_status, 2) of + true -> + Args = [PDict, State], + case catch Mod:format_status(Opt, Args) of + {'EXIT', _} -> MSL; + Else -> MS#handler{state = Else} + end; + _ -> + MS + end || #handler{module = Mod, state = State} = MS <- MSL], [{header, Header}, {data, [{"Status", SysState}, {"Parent", Parent}]}, - {items, {"Installed handlers", MSL}}]. + {items, {"Installed handlers", FmtMSL}}]. diff --git a/lib/stdlib/src/gen_fsm.erl b/lib/stdlib/src/gen_fsm.erl index ba0275ae2b..7d9960b912 100644 --- a/lib/stdlib/src/gen_fsm.erl +++ b/lib/stdlib/src/gen_fsm.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(gen_fsm). @@ -116,7 +116,7 @@ -export([behaviour_info/1]). %% Internal exports --export([init_it/6, print_event/3, +-export([init_it/6, system_continue/3, system_terminate/4, system_code_change/4, @@ -376,7 +376,7 @@ decode_msg(Msg,Parent, Name, StateName, StateData, Mod, Time, Debug, Hib) -> _Msg when Debug =:= [] -> handle_msg(Msg, Parent, Name, StateName, StateData, Mod, Time); _Msg -> - Debug1 = sys:handle_debug(Debug, {?MODULE, print_event}, + Debug1 = sys:handle_debug(Debug, fun print_event/3, {Name, StateName}, {in, Msg}), handle_msg(Msg, Parent, Name, StateName, StateData, Mod, Time, Debug1) @@ -466,11 +466,11 @@ handle_msg(Msg, Parent, Name, StateName, StateData, Mod, _Time, Debug) -> From = from(Msg), case catch dispatch(Msg, Mod, StateName, StateData) of {next_state, NStateName, NStateData} -> - Debug1 = sys:handle_debug(Debug, {?MODULE, print_event}, + Debug1 = sys:handle_debug(Debug, fun print_event/3, {Name, NStateName}, return), loop(Parent, Name, NStateName, NStateData, Mod, infinity, Debug1); {next_state, NStateName, NStateData, Time1} -> - Debug1 = sys:handle_debug(Debug, {?MODULE, print_event}, + Debug1 = sys:handle_debug(Debug, fun print_event/3, {Name, NStateName}, return), loop(Parent, Name, NStateName, NStateData, Mod, Time1, Debug1); {reply, Reply, NStateName, NStateData} when From =/= undefined -> @@ -519,7 +519,7 @@ reply({To, Tag}, Reply) -> reply(Name, {To, Tag}, Reply, Debug, StateName) -> reply({To, Tag}, Reply), - sys:handle_debug(Debug, {?MODULE, print_event}, Name, + sys:handle_debug(Debug, fun print_event/3, Name, {out, Reply, To, StateName}). %%% --------------------------------------------------- @@ -542,7 +542,18 @@ terminate(Reason, Name, Msg, Mod, StateName, StateData, Debug) -> {shutdown,_}=Shutdown -> exit(Shutdown); _ -> - error_info(Reason, Name, Msg, StateName, StateData, Debug), + FmtStateData = + case erlang:function_exported(Mod, format_status, 2) of + true -> + Args = [get(), StateData], + case catch Mod:format_status(terminate, Args) of + {'EXIT', _} -> StateData; + Else -> Else + end; + _ -> + StateData + end, + error_info(Reason,Name,Msg,StateName,FmtStateData,Debug), exit(Reason) end end. @@ -603,22 +614,27 @@ get_msg(Msg) -> Msg. format_status(Opt, StatusData) -> [PDict, SysState, Parent, Debug, [Name, StateName, StateData, Mod, _Time]] = StatusData, - NameTag = if is_pid(Name) -> - pid_to_list(Name); - is_atom(Name) -> - Name - end, - Header = lists:concat(["Status for state machine ", NameTag]), + StatusHdr = "Status for state machine", + Header = if + is_pid(Name) -> + lists:concat([StatusHdr, " ", pid_to_list(Name)]); + is_atom(Name); is_list(Name) -> + lists:concat([StatusHdr, " ", Name]); + true -> + {StatusHdr, Name} + end, Log = sys:get_debug(log, Debug, []), - Specfic = + DefaultStatus = [{data, [{"StateData", StateData}]}], + Specfic = case erlang:function_exported(Mod, format_status, 2) of true -> case catch Mod:format_status(Opt,[PDict,StateData]) of - {'EXIT', _} -> [{data, [{"StateData", StateData}]}]; - Else -> Else + {'EXIT', _} -> DefaultStatus; + StatusList when is_list(StatusList) -> StatusList; + Else -> [Else] end; _ -> - [{data, [{"StateData", StateData}]}] + DefaultStatus end, [{header, Header}, {data, [{"Status", SysState}, diff --git a/lib/stdlib/src/gen_server.erl b/lib/stdlib/src/gen_server.erl index f1a9a31c63..ac81df9cab 100644 --- a/lib/stdlib/src/gen_server.erl +++ b/lib/stdlib/src/gen_server.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(gen_server). @@ -103,7 +103,7 @@ format_status/2]). %% Internal exports --export([init_it/6, print_event/3]). +-export([init_it/6]). -import(error_logger, [format/2]). @@ -353,7 +353,7 @@ decode_msg(Msg, Parent, Name, State, Mod, Time, Debug, Hib) -> _Msg when Debug =:= [] -> handle_msg(Msg, Parent, Name, State, Mod); _Msg -> - Debug1 = sys:handle_debug(Debug, {?MODULE, print_event}, + Debug1 = sys:handle_debug(Debug, fun print_event/3, Name, {in, Msg}), handle_msg(Msg, Parent, Name, State, Mod, Debug1) end. @@ -589,11 +589,11 @@ handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod, Debug) -> Debug1 = reply(Name, From, Reply, NState, Debug), loop(Parent, Name, NState, Mod, Time1, Debug1); {noreply, NState} -> - Debug1 = sys:handle_debug(Debug, {?MODULE, print_event}, Name, + Debug1 = sys:handle_debug(Debug, fun print_event/3, Name, {noreply, NState}), loop(Parent, Name, NState, Mod, infinity, Debug1); {noreply, NState, Time1} -> - Debug1 = sys:handle_debug(Debug, {?MODULE, print_event}, Name, + Debug1 = sys:handle_debug(Debug, fun print_event/3, Name, {noreply, NState}), loop(Parent, Name, NState, Mod, Time1, Debug1); {stop, Reason, Reply, NState} -> @@ -625,11 +625,11 @@ handle_common_reply(Reply, Parent, Name, Msg, Mod, State) -> handle_common_reply(Reply, Parent, Name, Msg, Mod, State, Debug) -> case Reply of {noreply, NState} -> - Debug1 = sys:handle_debug(Debug, {?MODULE, print_event}, Name, + Debug1 = sys:handle_debug(Debug, fun print_event/3, Name, {noreply, NState}), loop(Parent, Name, NState, Mod, infinity, Debug1); {noreply, NState, Time1} -> - Debug1 = sys:handle_debug(Debug, {?MODULE, print_event}, Name, + Debug1 = sys:handle_debug(Debug, fun print_event/3, Name, {noreply, NState}), loop(Parent, Name, NState, Mod, Time1, Debug1); {stop, Reason, NState} -> @@ -642,7 +642,7 @@ handle_common_reply(Reply, Parent, Name, Msg, Mod, State, Debug) -> reply(Name, {To, Tag}, Reply, State, Debug) -> reply({To, Tag}, Reply), - sys:handle_debug(Debug, {?MODULE, print_event}, Name, + sys:handle_debug(Debug, fun print_event/3, Name, {out, Reply, To, State} ). @@ -705,7 +705,18 @@ terminate(Reason, Name, Msg, Mod, State, Debug) -> {shutdown,_}=Shutdown -> exit(Shutdown); _ -> - error_info(Reason, Name, Msg, State, Debug), + FmtState = + case erlang:function_exported(Mod, format_status, 2) of + true -> + Args = [get(), State], + case catch Mod:format_status(terminate, Args) of + {'EXIT', _} -> State; + Else -> Else + end; + _ -> + State + end, + error_info(Reason, Name, Msg, FmtState, Debug), exit(Reason) end end. @@ -829,22 +840,27 @@ name_to_pid(Name) -> %%----------------------------------------------------------------- format_status(Opt, StatusData) -> [PDict, SysState, Parent, Debug, [Name, State, Mod, _Time]] = StatusData, - NameTag = if is_pid(Name) -> - pid_to_list(Name); - is_atom(Name) -> - Name - end, - Header = lists:concat(["Status for generic server ", NameTag]), + StatusHdr = "Status for generic server", + Header = if + is_pid(Name) -> + lists:concat([StatusHdr, " ", pid_to_list(Name)]); + is_atom(Name); is_list(Name) -> + lists:concat([StatusHdr, " ", Name]); + true -> + {StatusHdr, Name} + end, Log = sys:get_debug(log, Debug, []), - Specfic = + DefaultStatus = [{data, [{"State", State}]}], + Specfic = case erlang:function_exported(Mod, format_status, 2) of true -> case catch Mod:format_status(Opt, [PDict, State]) of - {'EXIT', _} -> [{data, [{"State", State}]}]; - Else -> Else + {'EXIT', _} -> DefaultStatus; + StatusList when is_list(StatusList) -> StatusList; + Else -> [Else] end; _ -> - [{data, [{"State", State}]}] + DefaultStatus end, [{header, Header}, {data, [{"Status", SysState}, diff --git a/lib/stdlib/src/io.erl b/lib/stdlib/src/io.erl index 1f8076e864..1d0f9374bc 100644 --- a/lib/stdlib/src/io.erl +++ b/lib/stdlib/src/io.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(io). @@ -32,6 +32,7 @@ parse_erl_form/1,parse_erl_form/2,parse_erl_form/3]). -export([request/1,request/2,requests/1,requests/2]). +-export_type([device/0, format/0]). %%------------------------------------------------------------------------- diff --git a/lib/stdlib/src/io_lib.erl b/lib/stdlib/src/io_lib.erl index 26f6ec8931..4ca9d079b7 100644 --- a/lib/stdlib/src/io_lib.erl +++ b/lib/stdlib/src/io_lib.erl @@ -75,6 +75,8 @@ collect_line/2, collect_line/3, collect_line/4, get_until/3, get_until/4]). +-export_type([chars/0]). + %%---------------------------------------------------------------------- %% XXX: overapproximates a deep list of (unicode) characters diff --git a/lib/stdlib/src/io_lib_fread.erl b/lib/stdlib/src/io_lib_fread.erl index 74316dc730..33553692bc 100644 --- a/lib/stdlib/src/io_lib_fread.erl +++ b/lib/stdlib/src/io_lib_fread.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(io_lib_fread). @@ -22,6 +22,8 @@ -export([fread/2,fread/3]). +-export_type([continuation/0, fread_2_ret/0, fread_3_ret/0]). + -import(lists, [reverse/1,reverse/2]). %%----------------------------------------------------------------------- diff --git a/lib/stdlib/src/lists.erl b/lib/stdlib/src/lists.erl index e1f8d1c200..08ee595f4d 100644 --- a/lib/stdlib/src/lists.erl +++ b/lib/stdlib/src/lists.erl @@ -1,23 +1,26 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(lists). +-compile({no_auto_import,[max/2]}). +-compile({no_auto_import,[min/2]}). + -export([append/2, append/1, subtract/2, reverse/1, nth/2, nthtail/2, prefix/2, suffix/2, last/1, seq/2, seq/3, sum/1, duplicate/2, min/1, max/1, sublist/2, sublist/3, @@ -25,7 +28,7 @@ unzip/1, unzip3/1, zip/2, zip3/3, zipwith/3, zipwith3/4, sort/1, merge/1, merge/2, rmerge/2, merge3/3, rmerge3/3, usort/1, umerge/1, umerge3/3, umerge/2, rumerge3/3, rumerge/2, - concat/1, flatten/1, flatten/2, flat_length/1, flatlength/1, + concat/1, flatten/1, flatten/2, flatlength/1, keydelete/3, keyreplace/4, keytake/3, keystore/4, keysort/2, keymerge/3, rkeymerge/3, rukeymerge/3, ukeysort/2, ukeymerge/3, keymap/3]). @@ -40,8 +43,6 @@ mapfoldl/3,mapfoldr/3,foreach/2,takewhile/2,dropwhile/2,splitwith/2, split/2]). --deprecated([flat_length/1]). - %% member(X, L) -> (true | false) %% test if X is a member of the list L %% Now a BIF! @@ -436,13 +437,6 @@ do_flatten([H|T], Tail) -> do_flatten([], Tail) -> Tail. -%% flat_length(List) (undocumented can be removed later) -%% Calculate the length of a list of lists. - --spec flat_length([_]) -> non_neg_integer(). - -flat_length(List) -> flatlength(List). - %% flatlength(List) %% Calculate the length of a list of lists. 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 7ea7de8d58..5c52dfcbf0 100644 --- a/lib/stdlib/src/otp_internal.erl +++ b/lib/stdlib/src/otp_internal.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% -module(otp_internal). @@ -236,109 +236,137 @@ obsolete_1(erlang, fault, 2) -> obsolete_1(file, rawopen, 2) -> {removed, "deprecated (will be removed in R13B); use file:open/2 with the raw option"}; -obsolete_1(httpd, start, 0) -> {deprecated,{inets,start,[2,3]},"R14B"}; -obsolete_1(httpd, start, 1) -> {deprecated,{inets,start,[2,3]},"R14B"}; -obsolete_1(httpd, start_link, 1) -> {deprecated,{inets,start,[2,3]},"R14B"}; -obsolete_1(httpd, start_child, 0) -> {deprecated,{inets,start,[2,3]},"R14B"}; -obsolete_1(httpd, start_child, 1) -> {deprecated,{inets,start,[2,3]},"R14B"}; -obsolete_1(httpd, stop, 0) -> {deprecated,{inets,stop,2},"R14B"}; -obsolete_1(httpd, stop, 1) -> {deprecated,{inets,stop,2},"R14B"}; -obsolete_1(httpd, stop, 2) -> {deprecated,{inets,stop,2},"R14B"}; -obsolete_1(httpd, stop_child, 0) -> {deprecated,{inets,stop,2},"R14B"}; -obsolete_1(httpd, stop_child, 1) -> {deprecated,{inets,stop,2},"R14B"}; -obsolete_1(httpd, stop_child, 2) -> {deprecated,{inets,stop,2},"R14B"}; -obsolete_1(httpd, restart, 0) -> {deprecated,{httpd,reload_config,2},"R14B"}; -obsolete_1(httpd, restart, 1) -> {deprecated,{httpd,reload_config,2},"R14B"}; -obsolete_1(httpd, restart, 2) -> {deprecated,{httpd,reload_config,2},"R14B"}; -obsolete_1(httpd, block, 0) -> {deprecated,{httpd,reload_config,2},"R14B"}; -obsolete_1(httpd, block, 1) -> {deprecated,{httpd,reload_config,2},"R14B"}; -obsolete_1(httpd, block, 2) -> {deprecated,{httpd,reload_config,2},"R14B"}; -obsolete_1(httpd, block, 3) -> {deprecated,{httpd,reload_config,2},"R14B"}; -obsolete_1(httpd, block, 4) -> {deprecated,{httpd,reload_config,2},"R14B"}; -obsolete_1(httpd, unblock, 0) -> {deprecated,{httpd,reload_config,2},"R14B"}; -obsolete_1(httpd, unblock, 1) -> {deprecated,{httpd,reload_config,2},"R14B"}; -obsolete_1(httpd, unblock, 2) -> {deprecated,{httpd,reload_config,2},"R14B"}; +obsolete_1(http, request, 1) -> {deprecated,{httpc,request,1},"R15B"}; +obsolete_1(http, request, 2) -> {deprecated,{httpc,request,2},"R15B"}; +obsolete_1(http, request, 4) -> {deprecated,{httpc,request,4},"R15B"}; +obsolete_1(http, request, 5) -> {deprecated,{httpc,request,5},"R15B"}; +obsolete_1(http, cancel_request, 1) -> {deprecated,{httpc,cancel_request,1},"R15B"}; +obsolete_1(http, cancel_request, 2) -> {deprecated,{httpc,cancel_request,2},"R15B"}; +obsolete_1(http, set_option, 2) -> {deprecated,{httpc,set_option,2},"R15B"}; +obsolete_1(http, set_option, 3) -> {deprecated,{httpc,set_option,3},"R15B"}; +obsolete_1(http, set_options, 1) -> {deprecated,{httpc,set_options,1},"R15B"}; +obsolete_1(http, set_options, 2) -> {deprecated,{httpc,set_options,2},"R15B"}; +obsolete_1(http, verify_cookies, 2) -> {deprecated,{httpc,verify_cookies,2},"R15B"}; +obsolete_1(http, verify_cookies, 3) -> {deprecated,{httpc,verify_cookies,3},"R15B"}; +obsolete_1(http, cookie_header, 1) -> {deprecated,{httpc,cookie_header,1},"R15B"}; +obsolete_1(http, cookie_header, 2) -> {deprecated,{httpc,cookie_header,2},"R15B"}; +obsolete_1(http, stream_next, 1) -> {deprecated,{httpc,stream_next,1},"R15B"}; +obsolete_1(http, default_profile, 0) -> {deprecated,{httpc,default_profile,0},"R15B"}; + +obsolete_1(httpd, start, 0) -> {removed,{inets,start,[2,3]},"R14B"}; +obsolete_1(httpd, start, 1) -> {removed,{inets,start,[2,3]},"R14B"}; +obsolete_1(httpd, start_link, 0) -> {removed,{inets,start,[2,3]},"R14B"}; +obsolete_1(httpd, start_link, 1) -> {removed,{inets,start,[2,3]},"R14B"}; +obsolete_1(httpd, start_child, 0) -> {removed,{inets,start,[2,3]},"R14B"}; +obsolete_1(httpd, start_child, 1) -> {removed,{inets,start,[2,3]},"R14B"}; +obsolete_1(httpd, stop, 0) -> {removed,{inets,stop,2},"R14B"}; +obsolete_1(httpd, stop, 1) -> {removed,{inets,stop,2},"R14B"}; +obsolete_1(httpd, stop, 2) -> {removed,{inets,stop,2},"R14B"}; +obsolete_1(httpd, stop_child, 0) -> {removed,{inets,stop,2},"R14B"}; +obsolete_1(httpd, stop_child, 1) -> {removed,{inets,stop,2},"R14B"}; +obsolete_1(httpd, stop_child, 2) -> {removed,{inets,stop,2},"R14B"}; +obsolete_1(httpd, restart, 0) -> {removed,{httpd,reload_config,2},"R14B"}; +obsolete_1(httpd, restart, 1) -> {removed,{httpd,reload_config,2},"R14B"}; +obsolete_1(httpd, restart, 2) -> {removed,{httpd,reload_config,2},"R14B"}; +obsolete_1(httpd, block, 0) -> {removed,{httpd,reload_config,2},"R14B"}; +obsolete_1(httpd, block, 1) -> {removed,{httpd,reload_config,2},"R14B"}; +obsolete_1(httpd, block, 2) -> {removed,{httpd,reload_config,2},"R14B"}; +obsolete_1(httpd, block, 3) -> {removed,{httpd,reload_config,2},"R14B"}; +obsolete_1(httpd, block, 4) -> {removed,{httpd,reload_config,2},"R14B"}; +obsolete_1(httpd, unblock, 0) -> {removed,{httpd,reload_config,2},"R14B"}; +obsolete_1(httpd, unblock, 1) -> {removed,{httpd,reload_config,2},"R14B"}; +obsolete_1(httpd, unblock, 2) -> {removed,{httpd,reload_config,2},"R14B"}; obsolete_1(httpd_util, key1search, 2) -> {removed,{proplists,get_value,2},"R13B"}; obsolete_1(httpd_util, key1search, 3) -> {removed,{proplists,get_value,3},"R13B"}; -obsolete_1(ftp, open, 3) -> {deprecated,{inets,start,[2,3]},"R14B"}; -obsolete_1(ftp, force_active, 1) -> {deprecated,{inets,start,[2,3]},"R14B"}; +obsolete_1(ftp, open, 3) -> {removed,{inets,start,[2,3]},"R14B"}; +obsolete_1(ftp, force_active, 1) -> {removed,{inets,start,[2,3]},"R14B"}; %% Added in R12B-4. obsolete_1(ssh_cm, connect, A) when 1 =< A, A =< 3 -> - {deprecated,{ssh,connect,A},"R14B"}; + {removed,{ssh,connect,A},"R14B"}; obsolete_1(ssh_cm, listen, A) when 2 =< A, A =< 4 -> - {deprecated,{ssh,daemon,A},"R14B"}; + {removed,{ssh,daemon,A},"R14B"}; obsolete_1(ssh_cm, stop_listener, 1) -> - {deprecated,{ssh,stop_listener,[1,2]},"R14B"}; + {removed,{ssh,stop_listener,[1,2]},"R14B"}; obsolete_1(ssh_cm, session_open, A) when A =:= 2; A =:= 4 -> - {deprecated,{ssh_connection,session_channel,A},"R14B"}; + {removed,{ssh_connection,session_channel,A},"R14B"}; obsolete_1(ssh_cm, direct_tcpip, A) when A =:= 6; A =:= 8 -> - {deprecated,{ssh_connection,direct_tcpip,A}}; + {removed,{ssh_connection,direct_tcpip,A}}; obsolete_1(ssh_cm, tcpip_forward, 3) -> - {deprecated,{ssh_connection,tcpip_forward,3},"R14B"}; + {removed,{ssh_connection,tcpip_forward,3},"R14B"}; obsolete_1(ssh_cm, cancel_tcpip_forward, 3) -> - {deprecated,{ssh_connection,cancel_tcpip_forward,3},"R14B"}; + {removed,{ssh_connection,cancel_tcpip_forward,3},"R14B"}; obsolete_1(ssh_cm, open_pty, A) when A =:= 3; A =:= 7; A =:= 9 -> - {deprecated,{ssh_connection,open_pty,A},"R14"}; + {removed,{ssh_connection,open_pty,A},"R14"}; obsolete_1(ssh_cm, setenv, 5) -> - {deprecated,{ssh_connection,setenv,5},"R14B"}; + {removed,{ssh_connection,setenv,5},"R14B"}; obsolete_1(ssh_cm, shell, 2) -> - {deprecated,{ssh_connection,shell,2},"R14B"}; + {removed,{ssh_connection,shell,2},"R14B"}; obsolete_1(ssh_cm, exec, 4) -> - {deprecated,{ssh_connection,exec,4},"R14B"}; + {removed,{ssh_connection,exec,4},"R14B"}; obsolete_1(ssh_cm, subsystem, 4) -> - {deprecated,{ssh_connection,subsystem,4},"R14B"}; + {removed,{ssh_connection,subsystem,4},"R14B"}; obsolete_1(ssh_cm, winch, A) when A =:= 4; A =:= 6 -> - {deprecated,{ssh_connection,window_change,A},"R14B"}; + {removed,{ssh_connection,window_change,A},"R14B"}; obsolete_1(ssh_cm, signal, 3) -> - {deprecated,{ssh_connection,signal,3},"R14B"}; + {removed,{ssh_connection,signal,3},"R14B"}; obsolete_1(ssh_cm, attach, A) when A =:= 2; A =:= 3 -> - {deprecated,{ssh,attach,A}}; + {removed,{ssh,attach,A}}; obsolete_1(ssh_cm, detach, 2) -> - {deprecated,"no longer useful; will be removed in R14B"}; + {removed,"no longer useful; will be removed in R14B"}; obsolete_1(ssh_cm, set_user_ack, 4) -> - {deprecated,"no longer useful; will be removed in R14B"}; + {removed,"no longer useful; will be removed in R14B"}; obsolete_1(ssh_cm, adjust_window, 3) -> - {deprecated,{ssh_connection,adjust_window,3},"R14B"}; + {removed,{ssh_connection,adjust_window,3},"R14B"}; obsolete_1(ssh_cm, close, 2) -> - {deprecated,{ssh_connection,close,2},"R14B"}; + {removed,{ssh_connection,close,2},"R14B"}; obsolete_1(ssh_cm, stop, 1) -> - {deprecated,{ssh,close,1},"R14B"}; + {removed,{ssh,close,1},"R14B"}; obsolete_1(ssh_cm, send_eof, 2) -> - {deprecated,{ssh_connection,send_eof,2},"R14B"}; + {removed,{ssh_connection,send_eof,2},"R14B"}; obsolete_1(ssh_cm, send, A) when A =:= 3; A =:= 4 -> - {deprecated,{ssh_connection,send,A},"R14B"}; + {removed,{ssh_connection,send,A},"R14B"}; obsolete_1(ssh_cm, send_ack, A) when 3 =< A, A =< 5 -> - {deprecated,{ssh_connection,send,[3,4]},"R14B"}; + {removed,{ssh_connection,send,[3,4]},"R14B"}; obsolete_1(ssh_ssh, connect, A) when 1 =< A, A =< 3 -> - {deprecated,{ssh,shell,A},"R14B"}; + {removed,{ssh,shell,A},"R14B"}; obsolete_1(ssh_sshd, listen, A) when 0 =< A, A =< 3 -> - {deprecated,{ssh,daemon,[1,2,3]},"R14"}; + {removed,{ssh,daemon,[1,2,3]},"R14"}; obsolete_1(ssh_sshd, stop, 1) -> - {deprecated,{ssh,stop_listener,1}}; + {removed,{ssh,stop_listener,1}}; %% Added in R13A. obsolete_1(regexp, _, _) -> {deprecated, "the regexp module is deprecated (will be removed in R15A); use the re module instead"}; obsolete_1(lists, flat_length, 1) -> - {deprecated,{lists,flatlength,1},"R14"}; + {removed,{lists,flatlength,1},"R14"}; obsolete_1(ssh_sftp, connect, A) when 1 =< A, A =< 3 -> - {deprecated,{ssh_sftp,start_channel,A},"R14B"}; + {removed,{ssh_sftp,start_channel,A},"R14B"}; obsolete_1(ssh_sftp, stop, 1) -> - {deprecated,{ssh_sftp,stop_channel,1},"R14B"}; + {removed,{ssh_sftp,stop_channel,1},"R14B"}; %% Added in R13B01. obsolete_1(ssl_pkix, decode_cert_file, A) when A =:= 1; A =:= 2 -> - {deprecated,"deprecated (will be removed in R14B); use public_key:pem_to_der/1 and public_key:pkix_decode_cert/2 instead"}; + {removed,"removed in R14A; use public_key:pem_to_der/1 and public_key:pkix_decode_cert/2 instead"}; obsolete_1(ssl_pkix, decode_cert, A) when A =:= 1; A =:= 2 -> - {deprecated,{public_key,pkix_decode_cert,2},"R14B"}; + {removed,{public_key,pkix_decode_cert,2},"R14A"}; %% Added in R13B04. obsolete_1(erlang, concat_binary, 1) -> - {deprecated,{erlang,list_to_binary,1},"R14B"}; - + {deprecated,{erlang,list_to_binary,1},"R15B"}; + +%% Added in R14A. +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/src/proc_lib.erl b/lib/stdlib/src/proc_lib.erl index 9aa5e0a71e..4fb64a3353 100644 --- a/lib/stdlib/src/proc_lib.erl +++ b/lib/stdlib/src/proc_lib.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(proc_lib). @@ -34,6 +34,8 @@ %% Internal exports. -export([wake_up/3]). +-export_type([spawn_option/0]). + %%----------------------------------------------------------------------------- -type priority_level() :: 'high' | 'low' | 'max' | 'normal'. diff --git a/lib/stdlib/src/proplists.erl b/lib/stdlib/src/proplists.erl index 35d14891f1..6a45e0f868 100644 --- a/lib/stdlib/src/proplists.erl +++ b/lib/stdlib/src/proplists.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %% ===================================================================== @@ -49,6 +49,8 @@ %% --------------------------------------------------------------------- +-export_type([property/0]). + -type property() :: atom() | tuple(). -type aliases() :: [{any(), any()}]. diff --git a/lib/stdlib/src/qlc.erl b/lib/stdlib/src/qlc.erl index 6e48d95973..bc6944e520 100644 --- a/lib/stdlib/src/qlc.erl +++ b/lib/stdlib/src/qlc.erl @@ -24,6 +24,8 @@ %% External exports +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([parse_transform/2, transform_from_evaluator/2]). -export([q/1, q/2]). diff --git a/lib/stdlib/src/stdlib.app.src b/lib/stdlib/src/stdlib.app.src index 3e52c48e42..9d15f01683 100644 --- a/lib/stdlib/src/stdlib.app.src +++ b/lib/stdlib/src/stdlib.app.src @@ -1,20 +1,20 @@ %% This is an -*- erlang -*- file. %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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, stdlib, @@ -23,6 +23,7 @@ {modules, [array, base64, beam_lib, + binary, c, calendar, dets, diff --git a/lib/stdlib/src/supervisor.erl b/lib/stdlib/src/supervisor.erl index 22269a8d1b..f5d5441184 100644 --- a/lib/stdlib/src/supervisor.erl +++ b/lib/stdlib/src/supervisor.erl @@ -21,7 +21,7 @@ -behaviour(gen_server). %% External exports --export([start_link/2,start_link/3, +-export([start_link/2, start_link/3, start_child/2, restart_child/2, delete_child/2, terminate_child/2, which_children/1, count_children/1, @@ -33,25 +33,47 @@ -export([init/1, handle_call/3, handle_info/2, terminate/2, code_change/3]). -export([handle_cast/2]). +-export_type([child_spec/0, strategy/0]). + +%%-------------------------------------------------------------------------- + +-type child_id() :: pid() | 'undefined'. +-type mfargs() :: {module(), atom(), [term()]}. +-type modules() :: [module()] | 'dynamic'. +-type restart() :: 'permanent' | 'transient' | 'temporary'. +-type shutdown() :: 'brutal_kill' | timeout(). +-type worker() :: 'worker' | 'supervisor'. +-type sup_name() :: {'local', atom()} | {'global', atom()}. +-type sup_ref() :: atom() | {atom(), atom()} | {'global', atom()} | pid(). +-type child_spec() :: {term(),mfargs(),restart(),shutdown(),worker(),modules()}. + +-type strategy() :: 'one_for_all' | 'one_for_one' + | 'rest_for_one' | 'simple_one_for_one'. + +%%-------------------------------------------------------------------------- + +-record(child, {% pid is undefined when child is not running + pid = undefined :: child_id(), + name, + mfargs :: mfargs(), + restart_type :: restart(), + shutdown :: shutdown(), + child_type :: worker(), + modules = [] :: modules()}). +-type child() :: #child{}. + -define(DICT, dict). -record(state, {name, - strategy, - children = [], - dynamics = ?DICT:new(), - intensity, - period, + strategy :: strategy(), + children = [] :: [child()], + dynamics = ?DICT:new() :: ?DICT(), + intensity :: non_neg_integer(), + period :: pos_integer(), restarts = [], module, args}). - --record(child, {pid = undefined, % pid is undefined when child is not running - name, - mfa, - restart_type, - shutdown, - child_type, - modules = []}). +-type state() :: #state{}. -define(is_simple(State), State#state.strategy =:= simple_one_for_one). @@ -65,21 +87,40 @@ behaviour_info(_Other) -> %%% Servers/processes should/could also be built using gen_server.erl. %%% SupName = {local, atom()} | {global, atom()}. %%% --------------------------------------------------- + +-type startlink_err() :: {'already_started', pid()} | 'shutdown' | term(). +-type startlink_ret() :: {'ok', pid()} | 'ignore' | {'error', startlink_err()}. + +-spec start_link(module(), term()) -> startlink_ret(). start_link(Mod, Args) -> gen_server:start_link(supervisor, {self, Mod, Args}, []). +-spec start_link(sup_name(), module(), term()) -> startlink_ret(). start_link(SupName, Mod, Args) -> gen_server:start_link(SupName, supervisor, {SupName, Mod, Args}, []). %%% --------------------------------------------------- %%% Interface functions. %%% --------------------------------------------------- + +-type info() :: term(). +-type startchild_err() :: 'already_present' + | {'already_started', child_id()} | term(). +-type startchild_ret() :: {'ok', child_id()} | {'ok', child_id(), info()} + | {'error', startchild_err()}. + +-spec start_child(sup_ref(), child_spec() | [term()]) -> startchild_ret(). start_child(Supervisor, ChildSpec) -> call(Supervisor, {start_child, ChildSpec}). +-type restart_err() :: 'running' | 'not_found' | 'simple_one_for_one' | term(). +-spec restart_child(sup_ref(), term()) -> + {'ok', child_id()} | {'ok', child_id(), info()} | {'error', restart_err()}. restart_child(Supervisor, Name) -> call(Supervisor, {restart_child, Name}). +-type del_err() :: 'running' | 'not_found' | 'simple_one_for_one'. +-spec delete_child(sup_ref(), term()) -> 'ok' | {'error', del_err()}. delete_child(Supervisor, Name) -> call(Supervisor, {delete_child, Name}). @@ -89,9 +130,13 @@ delete_child(Supervisor, Name) -> %% Note that the child is *always* terminated in some %% way (maybe killed). %%----------------------------------------------------------------- + +-type term_err() :: 'not_found' | 'simple_one_for_one'. +-spec terminate_child(sup_ref(), term()) -> 'ok' | {'error', term_err()}. terminate_child(Supervisor, Name) -> call(Supervisor, {terminate_child, Name}). +-spec which_children(sup_ref()) -> [{term(), child_id(), worker(), modules()}]. which_children(Supervisor) -> call(Supervisor, which_children). @@ -101,6 +146,7 @@ count_children(Supervisor) -> call(Supervisor, Req) -> gen_server:call(Supervisor, Req, infinity). +-spec check_childspecs([child_spec()]) -> 'ok' | {'error', term()}. check_childspecs(ChildSpecs) when is_list(ChildSpecs) -> case check_startspec(ChildSpecs) of {ok, _} -> ok; @@ -113,6 +159,14 @@ check_childspecs(X) -> {error, {badarg, X}}. %%% Initialize the supervisor. %%% %%% --------------------------------------------------- + +-type stop_rsn() :: 'shutdown' | {'bad_return', {module(),'init', term()}} + | {'bad_start_spec', term()} | {'start_spec', term()} + | {'supervisor_data', term()}. + +-spec init({sup_name(), module(), [term()]}) -> + {'ok', state()} | 'ignore' | {'stop', stop_rsn()}. + init({SupName, Mod, Args}) -> process_flag(trap_exit, true), case Mod:init(Args) of @@ -158,12 +212,12 @@ init_dynamic(_State, StartSpec) -> %%----------------------------------------------------------------- %% Func: start_children/2 -%% Args: Children = [#child] in start order -%% SupName = {local, atom()} | {global, atom()} | {pid(),Mod} +%% Args: Children = [child()] in start order +%% SupName = {local, atom()} | {global, atom()} | {pid(), Mod} %% Purpose: Start all children. The new list contains #child's %% with pids. %% Returns: {ok, NChildren} | {error, NChildren} -%% NChildren = [#child] in termination order (reversed +%% NChildren = [child()] in termination order (reversed %% start order) %%----------------------------------------------------------------- start_children(Children, SupName) -> start_children(Children, [], SupName). @@ -182,8 +236,8 @@ start_children([], NChildren, _SupName) -> {ok, NChildren}. do_start_child(SupName, Child) -> - #child{mfa = {M, F, A}} = Child, - case catch apply(M, F, A) of + #child{mfargs = {M, F, Args}} = Child, + case catch apply(M, F, Args) of {ok, Pid} when is_pid(Pid) -> NChild = Child#child{pid = Pid}, report_progress(NChild, SupName), @@ -192,7 +246,7 @@ do_start_child(SupName, Child) -> NChild = Child#child{pid = Pid}, report_progress(NChild, SupName), {ok, Pid, Extra}; - ignore -> + ignore -> {ok, undefined}; {error, What} -> {error, What}; What -> {error, What} @@ -211,15 +265,17 @@ do_start_child_i(M, F, A) -> What -> {error, What} end. - %%% --------------------------------------------------- %%% %%% Callback functions. %%% %%% --------------------------------------------------- +-type call() :: 'which_children' | 'count_children' | {_, _}. % XXX: refine +-spec handle_call(call(), term(), state()) -> {'reply', term(), state()}. + handle_call({start_child, EArgs}, _From, State) when ?is_simple(State) -> - #child{mfa = {M, F, A}} = hd(State#state.children), + #child{mfargs = {M, F, A}} = hd(State#state.children), Args = A ++ EArgs, case do_start_child_i(M, F, Args) of {ok, Pid} -> @@ -235,7 +291,7 @@ handle_call({start_child, EArgs}, _From, State) when ?is_simple(State) -> end; %%% The requests terminate_child, delete_child and restart_child are -%%% invalid for simple_one_for_one supervisors. +%%% invalid for simple_one_for_one supervisors. handle_call({_Req, _Data}, _From, State) when ?is_simple(State) -> {reply, {error, simple_one_for_one}, State}; @@ -297,7 +353,7 @@ handle_call(which_children, _From, State) -> Resp = lists:map(fun(#child{pid = Pid, name = Name, child_type = ChildType, modules = Mods}) -> - {Name, Pid, ChildType, Mods} + {Name, Pid, ChildType, Mods} end, State#state.children), {reply, Resp, State}; @@ -318,7 +374,6 @@ handle_call(count_children, _From, State) when ?is_simple(State) -> {reply, Reply, State}; handle_call(count_children, _From, State) -> - %% Specs and children are together on the children list... {Specs, Active, Supers, Workers} = lists:foldl(fun(Child, Counts) -> @@ -347,15 +402,19 @@ count_child(#child{pid = Pid, child_type = supervisor}, %%% Hopefully cause a function-clause as there is no API function %%% that utilizes cast. +-spec handle_cast('null', state()) -> {'noreply', state()}. + handle_cast(null, State) -> error_logger:error_msg("ERROR: Supervisor received cast-message 'null'~n", []), - {noreply, State}. %% %% Take care of terminated children. %% +-spec handle_info(term(), state()) -> + {'noreply', state()} | {'stop', 'shutdown', state()}. + handle_info({'EXIT', Pid, Reason}, State) -> case restart_child(Pid, Reason, State) of {ok, State1} -> @@ -368,9 +427,12 @@ handle_info(Msg, State) -> error_logger:error_msg("Supervisor received unexpected message: ~p~n", [Msg]), {noreply, State}. + %% %% Terminate this server. %% +-spec terminate(term(), state()) -> 'ok'. + terminate(_Reason, State) -> terminate_children(State#state.children, State#state.name), ok. @@ -384,6 +446,9 @@ terminate(_Reason, State) -> %% NOTE: This requires that the init function of the call-back module %% does not have any side effects. %% +-spec code_change(term(), state(), term()) -> + {'ok', state()} | {'error', term()}. + code_change(_, State, _) -> case (State#state.module):init(State#state.args) of {ok, {SupFlags, StartSpec}} -> @@ -411,7 +476,7 @@ check_flags({Strategy, MaxIntensity, Period}) -> check_flags(What) -> {bad_flags, What}. -update_childspec(State, StartSpec) when ?is_simple(State) -> +update_childspec(State, StartSpec) when ?is_simple(State) -> case check_startspec(StartSpec) of {ok, [Child]} -> {ok, State#state{children = [Child]}}; @@ -437,7 +502,7 @@ update_childspec1([Child|OldC], Children, KeepOld) -> update_childspec1(OldC, Children, [Child|KeepOld]) end; update_childspec1([], Children, KeepOld) -> - % Return them in (keeped) reverse start order. + %% Return them in (kept) reverse start order. lists:reverse(Children ++ KeepOld). update_chsp(OldCh, Children) -> @@ -482,7 +547,7 @@ handle_start_child(Child, State) -> %%% --------------------------------------------------- %%% Restart. A process has terminated. -%%% Returns: {ok, #state} | {shutdown, #state} +%%% Returns: {ok, state()} | {shutdown, state()} %%% --------------------------------------------------- restart_child(Pid, Reason, State) when ?is_simple(State) -> @@ -490,19 +555,19 @@ restart_child(Pid, Reason, State) when ?is_simple(State) -> {ok, Args} -> [Child] = State#state.children, RestartType = Child#child.restart_type, - {M, F, _} = Child#child.mfa, - NChild = Child#child{pid = Pid, mfa = {M, F, Args}}, + {M, F, _} = Child#child.mfargs, + NChild = Child#child{pid = Pid, mfargs = {M, F, Args}}, do_restart(RestartType, Reason, NChild, State); error -> {ok, State} end; restart_child(Pid, Reason, State) -> Children = State#state.children, - case lists:keysearch(Pid, #child.pid, Children) of - {value, Child} -> + case lists:keyfind(Pid, #child.pid, Children) of + #child{} = Child -> RestartType = Child#child.restart_type, do_restart(RestartType, Reason, Child, State); - _ -> + false -> {ok, State} end. @@ -534,7 +599,7 @@ restart(Child, State) -> end. restart(simple_one_for_one, Child, State) -> - #child{mfa = {M, F, A}} = Child, + #child{mfargs = {M, F, A}} = Child, Dynamics = ?DICT:erase(Child#child.pid, State#state.dynamics), case do_start_child_i(M, F, A) of {ok, Pid} -> @@ -580,9 +645,9 @@ restart(one_for_all, Child, State) -> %%----------------------------------------------------------------- %% Func: terminate_children/2 -%% Args: Children = [#child] in termination order +%% Args: Children = [child()] in termination order %% SupName = {local, atom()} | {global, atom()} | {pid(),Mod} -%% Returns: NChildren = [#child] in +%% Returns: NChildren = [child()] in %% startup order (reversed termination order) %%----------------------------------------------------------------- terminate_children(Children, SupName) -> @@ -617,7 +682,6 @@ do_terminate(Child, _SupName) -> %% Returns: ok | {error, OtherReason} (this should be reported) %%----------------------------------------------------------------- shutdown(Pid, brutal_kill) -> - case monitor_child(Pid) of ok -> exit(Pid, kill), @@ -630,9 +694,7 @@ shutdown(Pid, brutal_kill) -> {error, Reason} -> {error, Reason} end; - shutdown(Pid, Time) -> - case monitor_child(Pid) of ok -> exit(Pid, shutdown), %% Try to shutdown gracefully @@ -738,9 +800,9 @@ remove_child(Child, State) -> %% MaxIntensity = integer() %% Period = integer() %% Mod :== atom() -%% Arsg :== term() +%% Args :== term() %% Purpose: Check that Type is of correct type (!) -%% Returns: {ok, #state} | Error +%% Returns: {ok, state()} | Error %%----------------------------------------------------------------- init_state(SupName, Type, Mod, Args) -> case catch init_state1(SupName, Type, Mod, Args) of @@ -755,11 +817,11 @@ init_state1(SupName, {Strategy, MaxIntensity, Period}, Mod, Args) -> validIntensity(MaxIntensity), validPeriod(Period), {ok, #state{name = supname(SupName,Mod), - strategy = Strategy, - intensity = MaxIntensity, - period = Period, - module = Mod, - args = Args}}; + strategy = Strategy, + intensity = MaxIntensity, + period = Period, + module = Mod, + args = Args}}; init_state1(_SupName, Type, _, _) -> {invalid_type, Type}. @@ -771,26 +833,26 @@ validStrategy(What) -> throw({invalid_strategy, What}). validIntensity(Max) when is_integer(Max), Max >= 0 -> true; -validIntensity(What) -> throw({invalid_intensity, What}). +validIntensity(What) -> throw({invalid_intensity, What}). validPeriod(Period) when is_integer(Period), Period > 0 -> true; validPeriod(What) -> throw({invalid_period, What}). -supname(self,Mod) -> {self(),Mod}; -supname(N,_) -> N. +supname(self, Mod) -> {self(), Mod}; +supname(N, _) -> N. %%% ------------------------------------------------------ %%% Check that the children start specification is valid. %%% Shall be a six (6) tuple %%% {Name, Func, RestartType, Shutdown, ChildType, Modules} %%% where Name is an atom -%%% Func is {Mod, Fun, Args} == {atom, atom, list} +%%% Func is {Mod, Fun, Args} == {atom(), atom(), list()} %%% RestartType is permanent | temporary | transient %%% Shutdown = integer() | infinity | brutal_kill %%% ChildType = supervisor | worker %%% Modules = [atom()] | dynamic -%%% Returns: {ok, [#child]} | Error +%%% Returns: {ok, [child()]} | Error %%% ------------------------------------------------------ check_startspec(Children) -> check_startspec(Children, []). @@ -818,14 +880,14 @@ check_childspec(Name, Func, RestartType, Shutdown, ChildType, Mods) -> validChildType(ChildType), validShutdown(Shutdown, ChildType), validMods(Mods), - {ok, #child{name = Name, mfa = Func, restart_type = RestartType, + {ok, #child{name = Name, mfargs = Func, restart_type = RestartType, shutdown = Shutdown, child_type = ChildType, modules = Mods}}. validChildType(supervisor) -> true; validChildType(worker) -> true; validChildType(What) -> throw({invalid_child_type, What}). -validName(_Name) -> true. +validName(_Name) -> true. validFunc({M, F, A}) when is_atom(M), is_atom(F), @@ -923,7 +985,7 @@ report_error(Error, Reason, Child, SupName) -> extract_child(Child) -> [{pid, Child#child.pid}, {name, Child#child.name}, - {mfa, Child#child.mfa}, + {mfargs, Child#child.mfargs}, {restart_type, Child#child.restart_type}, {shutdown, Child#child.shutdown}, {child_type, Child#child.child_type}]. diff --git a/lib/stdlib/src/timer.erl b/lib/stdlib/src/timer.erl index 36fdb48c75..24e14caa69 100644 --- a/lib/stdlib/src/timer.erl +++ b/lib/stdlib/src/timer.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(timer). @@ -22,7 +22,7 @@ send_after/3, send_after/2, exit_after/3, exit_after/2, kill_after/2, kill_after/1, apply_interval/4, send_interval/3, send_interval/2, - cancel/1, sleep/1, tc/3, now_diff/2, + cancel/1, sleep/1, tc/2, tc/3, now_diff/2, seconds/1, minutes/1, hours/1, hms/3]). -export([start_link/0, start/0, @@ -41,54 +41,54 @@ %% %% Time is in milliseconds. %% --opaque tref() :: any(). +-opaque tref() :: {integer(), reference()}. -type time() :: non_neg_integer(). -type timestamp() :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}. %% %% Interface functions %% --spec apply_after(time(), atom(), atom(), [_]) -> {'ok', tref()} | {'error', _}. +-spec apply_after(time(), atom(), atom(), [term()]) -> {'ok', tref()} | {'error', term()}. apply_after(Time, M, F, A) -> req(apply_after, {Time, {M, F, A}}). --spec send_after(time(), pid() | atom(), term()) -> {'ok', tref()} | {'error', _}. +-spec send_after(time(), pid() | atom(), term()) -> {'ok', tref()} | {'error', term()}. send_after(Time, Pid, Message) -> req(apply_after, {Time, {?MODULE, send, [Pid, Message]}}). --spec send_after(time(), _) -> {'ok', tref()} | {'error', _}. +-spec send_after(time(), term()) -> {'ok', tref()} | {'error', term()}. send_after(Time, Message) -> send_after(Time, self(), Message). --spec exit_after(time(), pid() | atom(), _) -> {'ok', tref()} | {'error', _}. +-spec exit_after(time(), pid() | atom(), term()) -> {'ok', tref()} | {'error', term()}. exit_after(Time, Pid, Reason) -> req(apply_after, {Time, {erlang, exit, [Pid, Reason]}}). --spec exit_after(time(), term()) -> {'ok', tref()} | {'error', _}. +-spec exit_after(time(), term()) -> {'ok', tref()} | {'error', term()}. exit_after(Time, Reason) -> exit_after(Time, self(), Reason). --spec kill_after(time(), pid() | atom()) -> {'ok', tref()} | {'error', _}. +-spec kill_after(time(), pid() | atom()) -> {'ok', tref()} | {'error', term()}. kill_after(Time, Pid) -> exit_after(Time, Pid, kill). --spec kill_after(time()) -> {'ok', tref()} | {'error', _}. +-spec kill_after(time()) -> {'ok', tref()} | {'error', term()}. kill_after(Time) -> exit_after(Time, self(), kill). --spec apply_interval(time(), atom(), atom(), [_]) -> {'ok', tref()} | {'error', _}. +-spec apply_interval(time(), atom(), atom(), [term()]) -> {'ok', tref()} | {'error', term()}. apply_interval(Time, M, F, A) -> req(apply_interval, {Time, self(), {M, F, A}}). --spec send_interval(time(), pid() | atom(), term()) -> {'ok', tref()} | {'error', _}. +-spec send_interval(time(), pid() | atom(), term()) -> {'ok', tref()} | {'error', term()}. send_interval(Time, Pid, Message) -> req(apply_interval, {Time, Pid, {?MODULE, send, [Pid, Message]}}). --spec send_interval(time(), term()) -> {'ok', tref()} | {'error', _}. +-spec send_interval(time(), term()) -> {'ok', tref()} | {'error', term()}. send_interval(Time, Message) -> send_interval(Time, self(), Message). --spec cancel(tref()) -> {'ok', 'cancel'} | {'error', _}. +-spec cancel(tref()) -> {'ok', 'cancel'} | {'error', term()}. cancel(BRef) -> req(cancel, BRef). @@ -98,10 +98,21 @@ sleep(T) -> after T -> ok end. + +%% +%% Measure the execution time (in microseconds) for Fun(Args). +%% +-spec tc(function(), [_]) -> {time(), term()}. +tc(F, A) -> + Before = erlang:now(), + Val = (catch apply(F, A)), + After = erlang:now(), + {now_diff(After, Before), Val}. + %% %% Measure the execution time (in microseconds) for an MFA. %% --spec tc(atom(), atom(), [_]) -> {time(), term()}. +-spec tc(atom(), atom(), [term()]) -> {time(), term()}. tc(M, F, A) -> Before = erlang:now(), Val = (catch apply(M, F, A)), @@ -141,7 +152,7 @@ hms(H, M, S) -> start() -> ensure_started(). --spec start_link() -> {'ok', pid()} | {'error', _}. +-spec start_link() -> {'ok', pid()} | {'error', term()}. start_link() -> gen_server:start_link({local, timer_server}, ?MODULE, [], []). @@ -152,6 +163,7 @@ init([]) -> ?INTERVAL_TAB = ets:new(?INTERVAL_TAB, [named_table,protected]), {ok, [], infinity}. +-spec ensure_started() -> 'ok'. ensure_started() -> case whereis(timer_server) of undefined -> @@ -175,6 +187,10 @@ req(Req, Arg) -> %% %% Time and Timeout is in milliseconds. Started is in microseconds. %% +-type timers() :: term(). % XXX: refine? + +-spec handle_call(term(), term(), timers()) -> + {'reply', term(), timers(), timeout()} | {'noreply', timers(), timeout()}. handle_call({apply_after, {Time, Op}, Started}, _From, _Ts) when is_integer(Time), Time >= 0 -> BRef = {Started + 1000*Time, make_ref()}, @@ -194,7 +210,7 @@ handle_call({apply_interval, {Time, To, MFA}, Started}, _From, _Ts) Interval = Time*1000, BRef2 = {Started + Interval, Ref}, Timer = {BRef2, {repeat, Interval, Pid}, MFA}, - ets:insert(?INTERVAL_TAB,{BRef1,BRef2,Pid}), + ets:insert(?INTERVAL_TAB, {BRef1,BRef2,Pid}), ets:insert(?TIMER_TAB, Timer), Timeout = timer_timeout(SysTime), {reply, {ok, BRef1}, [], Timeout}; @@ -202,7 +218,7 @@ handle_call({apply_interval, {Time, To, MFA}, Started}, _From, _Ts) {reply, {error, badarg}, [], next_timeout()} end; handle_call({cancel, BRef = {_Time, Ref}, _}, _From, Ts) - when is_reference(Ref) -> + when is_reference(Ref) -> delete_ref(BRef), {reply, {ok, cancel}, Ts, next_timeout()}; handle_call({cancel, _BRef, _}, _From, Ts) -> @@ -214,6 +230,7 @@ handle_call({apply_interval, _, _}, _From, Ts) -> handle_call(_Else, _From, Ts) -> % Catch anything else {noreply, Ts, next_timeout()}. +-spec handle_info(term(), timers()) -> {'noreply', timers(), timeout()}. handle_info(timeout, Ts) -> % Handle timeouts Timeout = timer_timeout(system_time()), {noreply, Ts, Timeout}; @@ -223,19 +240,21 @@ handle_info({'EXIT', Pid, _Reason}, Ts) -> % Oops, someone died handle_info(_OtherMsg, Ts) -> % Other Msg's {noreply, Ts, next_timeout()}. +-spec handle_cast(term(), timers()) -> {'noreply', timers(), timeout()}. handle_cast(_Req, Ts) -> % Not predicted but handled {noreply, Ts, next_timeout()}. --spec terminate(_, _) -> 'ok'. +-spec terminate(term(), _State) -> 'ok'. terminate(_Reason, _State) -> ok. +-spec code_change(term(), State, term()) -> {'ok', State}. code_change(_OldVsn, State, _Extra) -> %% According to the man for gen server no timer can be set here. {ok, State}. %% -%% timer_timeout(Timers, SysTime) +%% timer_timeout(SysTime) %% %% Apply and remove already timed-out timers. A timer is a tuple %% {Time, BRef, Op, MFA}, where Time is in microseconds. @@ -279,12 +298,13 @@ delete_ref(BRef = {interval, _}) -> ok end; delete_ref(BRef) -> - ets:delete(?TIMER_TAB,BRef). + ets:delete(?TIMER_TAB, BRef). %% %% pid_delete %% +-spec pid_delete(pid()) -> 'ok'. pid_delete(Pid) -> IntervalTimerList = ets:select(?INTERVAL_TAB, @@ -292,13 +312,14 @@ pid_delete(Pid) -> [{'==','$1',Pid}], ['$_']}]), lists:foreach(fun({IntKey, TimerKey, _ }) -> - ets:delete(?INTERVAL_TAB,IntKey), - ets:delete(?TIMER_TAB,TimerKey) + ets:delete(?INTERVAL_TAB, IntKey), + ets:delete(?TIMER_TAB, TimerKey) end, IntervalTimerList). %% Calculate time to the next timeout. Returned timeout must fit in a %% small int. +-spec next_timeout() -> timeout(). next_timeout() -> case ets:first(?TIMER_TAB) of '$end_of_table' -> @@ -358,7 +379,7 @@ get_pid(_) -> get_status() -> Info1 = ets:info(?TIMER_TAB), - {value,{size,TotalNumTimers}} = lists:keysearch(size, 1, Info1), + {size,TotalNumTimers} = lists:keyfind(size, 1, Info1), Info2 = ets:info(?INTERVAL_TAB), - {value,{size,NumIntervalTimers}} = lists:keysearch(size, 1, Info2), + {size,NumIntervalTimers} = lists:keyfind(size, 1, Info2), {{?TIMER_TAB,TotalNumTimers},{?INTERVAL_TAB,NumIntervalTimers}}. diff --git a/lib/stdlib/src/zip.erl b/lib/stdlib/src/zip.erl index f44d97c227..d41aeefa59 100644 --- a/lib/stdlib/src/zip.erl +++ b/lib/stdlib/src/zip.erl @@ -1,26 +1,26 @@ %% %% %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 %% 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(zip). %% Basic api -export([unzip/1, unzip/2, extract/1, extract/2, - zip/2, zip/3, create/2, create/3, + zip/2, zip/3, create/2, create/3, foldl/3, list_dir/1, list_dir/2, table/1, table/2, t/1, tt/1]). @@ -38,7 +38,7 @@ zip_t/1, zip_tt/1, zip_list_dir/1, zip_list_dir/2, zip_close/1]). - + %% just for debugging zip server, not documented, not tested, not to be used -export([zip_get_state/1]). @@ -82,7 +82,7 @@ -record(openzip_opts, { output, % output object (fun) open_opts, % file:open options - cwd % directory to relate paths to + cwd % directory to relate paths to }). % openzip record, state for an open zip-file @@ -93,10 +93,10 @@ input, % archive io object (fun) output, % output io object (fun) zlib, % handle to open zlib - cwd % directory to relate paths to + cwd % directory to relate paths to }). -% Things that I would like to add to the public record #zip_file, +% Things that I would like to add to the public record #zip_file, % but can't as it would make things fail at upgrade. % Instead we use {#zip_file,#zip_file_extra} internally. -record(zip_file_extra, { @@ -278,7 +278,7 @@ file_name_search(Name,Files) -> [ZFile|_] -> ZFile; [] -> false end. - + %% %% add a file to an open archive %% openzip_add(File, OpenZip) -> %% case ?CATCH do_openzip_add(File, OpenZip) of @@ -344,6 +344,25 @@ do_unzip(F, Options) -> Input(close, In1), {ok, Files}. +%% Iterate over all files in a zip archive +foldl(Fun, Acc0, Archive) when is_function(Fun, 4) -> + ZipFun = + fun({Name, GetInfo, GetBin}, A) -> + A2 = Fun(Name, GetInfo, GetBin, A), + {true, false, A2} + end, + case prim_zip:open(ZipFun, Acc0, Archive) of + {ok, PrimZip, Acc1} -> + ok = prim_zip:close(PrimZip), + {ok, Acc1}; + {error, bad_eocd} -> + {error, "Not an archive file"}; + {error, Reason} -> + {error, Reason} + end; +foldl(_,_, _) -> + {error, einval}. + %% Create zip archive name F from Files or binaries %% %% Accepted options: @@ -383,7 +402,7 @@ list_dir(F, Options) -> do_list_dir(F, Options) -> Opts = get_list_dir_options(F, Options), - #list_dir_opts{input = Input, open_opts = OpO, + #list_dir_opts{input = Input, open_opts = OpO, raw_iterator = RawIterator} = Opts, In0 = Input({open, F, OpO}, []), {Info, In1} = get_central_dir(In0, RawIterator, Input), @@ -417,7 +436,7 @@ tt(F) when is_record(F, openzip) -> openzip_tt(F); tt(F) -> t(F, fun raw_long_print_info_etc/5). -%% option utils +%% option utils get_unzip_opt([], Opts) -> Opts; get_unzip_opt([verbose | Rest], Opts) -> @@ -470,7 +489,7 @@ get_zip_opt([{cwd, CWD} | Rest], Opts) -> get_zip_opt([{comment, C} | Rest], Opts) -> get_zip_opt(Rest, Opts#zip_opts{comment = C}); get_zip_opt([{compress, Which} = O| Rest], Opts) -> - Which2 = + Which2 = case Which of all -> all; @@ -485,7 +504,7 @@ get_zip_opt([{compress, Which} = O| Rest], Opts) -> end, get_zip_opt(Rest, Opts#zip_opts{compress = Which2}); get_zip_opt([{uncompress, Which} = O| Rest], Opts) -> - Which2 = + Which2 = case Which of all -> all; @@ -560,16 +579,24 @@ get_openzip_options(Options) -> get_input(F) when is_binary(F) -> fun binary_io/2; get_input(F) when is_list(F) -> - fun file_io/2. + fun file_io/2; +get_input(_) -> + throw(einval). get_zip_input({F, B}) when is_binary(B), is_list(F) -> fun binary_io/2; +get_zip_input({F, B, #file_info{}}) when is_binary(B), is_list(F) -> + fun binary_io/2; +get_zip_input({F, #file_info{}, B}) when is_binary(B), is_list(F) -> + fun binary_io/2; get_zip_input(F) when is_list(F) -> fun file_io/2; get_zip_input({files, []}) -> fun binary_io/2; get_zip_input({files, [File | _]}) -> - get_zip_input(File). + get_zip_input(File); +get_zip_input(_) -> + throw(einval). get_list_dir_options(F, Options) -> Opts = #list_dir_opts{raw_iterator = fun raw_file_info_public/5, @@ -620,6 +647,8 @@ put_eocd(N, Pos, Sz, Comment, Output, Out0) -> get_filename({Name, _}, Type) -> get_filename(Name, Type); +get_filename({Name, _, _}, Type) -> + get_filename(Name, Type); get_filename(Name, regular) -> Name; get_filename(Name, directory) -> @@ -895,7 +924,7 @@ local_file_header_to_bin( CompSize:32/little, UncompSize:32/little, FileNameLength:16/little, - ExtraFieldLength:16/little>>. + ExtraFieldLength:16/little>>. eocd_to_bin(#eocd{disk_num = DiskNum, start_disk_num = StartDiskNum, @@ -912,7 +941,7 @@ eocd_to_bin(#eocd{disk_num = DiskNum, Offset:32/little, ZipCommentLength:16/little>>. -%% put together a local file header +%% put together a local file header local_file_header_from_info_method_name(#file_info{mtime = MTime}, UncompSize, CompMethod, Name) -> @@ -939,7 +968,7 @@ server_loop(OpenZip) -> server_loop(NewOpenZip); Error -> From ! {self(), Error} - end; + end; {From, close} -> From ! {self(), openzip_close(OpenZip)}; {From, get} -> @@ -1024,7 +1053,7 @@ lists_foreach(F, [Hd|Tl]) -> F(Hd), lists_foreach(F, Tl). -%% option utils +%% option utils get_openzip_opt([], Opts) -> Opts; get_openzip_opt([cooked | Rest], #openzip_opts{open_opts = OO} = Opts) -> @@ -1121,7 +1150,7 @@ raw_file_info_public(CD, FileName, FileComment, BExtraField, Acc0) -> Other -> Other end, [H2|T]. - + %% make a file_info from a central directory header cd_file_header_to_file_info(FileName, @@ -1213,8 +1242,8 @@ get_z_file(In0, Z, Input, Output, OpO, FB, CWD, {ZipFile,Extra}) -> {dir, In3}; _ -> %% FileInfo = local_file_header_to_file_info(LH) - %%{Out, In4, CRC, UncompSize} = - {Out, In4, CRC, _UncompSize} = + %%{Out, In4, CRC, UncompSize} = + {Out, In4, CRC, _UncompSize} = get_z_data(CompMethod, In3, FileName1, CompSize, Input, Output, OpO, Z), In5 = skip_z_data_descriptor(GPFlag, Input, In4), @@ -1280,7 +1309,7 @@ get_z_data_loop(CompSize, UncompSize, In0, Out0, Input, Output, Z) -> Out1 = Output({write, Uncompressed}, Out0), get_z_data_loop(CompSize-N, UncompSize + iolist_size(Uncompressed), In1, Out1, Input, Output, Z) - end. + end. %% skip data descriptor if any @@ -1298,7 +1327,7 @@ dos_date_time_to_datetime(DosDate, DosTime) -> <<Hour:5, Min:6, Sec:5>> = <<DosTime:16>>, <<YearFrom1980:7, Month:4, Day:5>> = <<DosDate:16>>, {{YearFrom1980+1980, Month, Day}, - {Hour, Min, Sec}}. + {Hour, Min, Sec}}. dos_date_time_from_datetime({{Year, Month, Day}, {Hour, Min, Sec}}) -> YearFrom1980 = Year-1980, @@ -1319,7 +1348,6 @@ unix_extra_field_and_var_from_bin(<<TSize:16/little, Var}; unix_extra_field_and_var_from_bin(_) -> throw(bad_unix_extra_field). - %% A pwrite-like function for iolists (used by memory-option) @@ -1478,6 +1506,8 @@ local_file_header_from_bin(_) -> %% io functions binary_io({file_info, {_Filename, _B, #file_info{} = FI}}, _A) -> FI; +binary_io({file_info, {_Filename, #file_info{} = FI, _B}}, _A) -> + FI; binary_io({file_info, {_Filename, B}}, A) -> binary_io({file_info, B}, A); binary_io({file_info, B}, _) -> @@ -1493,9 +1523,11 @@ binary_io({file_info, B}, _) -> links = 1, major_device = 0, minor_device = 0, inode = 0, uid = 0, gid = 0}; -binary_io({open, {_Filename, B, _FI}, _Opts}, _) -> +binary_io({open, {_Filename, B, _FI}, _Opts}, _) when is_binary(B) -> + {0, B}; +binary_io({open, {_Filename, _FI, B}, _Opts}, _) when is_binary(B) -> {0, B}; -binary_io({open, {_Filename, B}, _Opts}, _) -> +binary_io({open, {_Filename, B}, _Opts}, _) when is_binary(B) -> {0, B}; binary_io({open, B, _Opts}, _) when is_binary(B) -> {0, B}; diff --git a/lib/stdlib/test/Makefile b/lib/stdlib/test/Makefile index 9beac93eb8..3bbd9ce318 100644 --- a/lib/stdlib/test/Makefile +++ b/lib/stdlib/test/Makefile @@ -9,6 +9,8 @@ MODULES= \ array_SUITE \ base64_SUITE \ beam_lib_SUITE \ + binary_module_SUITE \ + binref \ c_SUITE \ calendar_SUITE \ dets_SUITE \ diff --git a/lib/stdlib/test/binary_module_SUITE.erl b/lib/stdlib/test/binary_module_SUITE.erl new file mode 100644 index 0000000000..16ed9a2c26 --- /dev/null +++ b/lib/stdlib/test/binary_module_SUITE.erl @@ -0,0 +1,1323 @@ +-module(binary_module_SUITE). + +-export([all/1, interesting/1,random_ref_comp/1,random_ref_sr_comp/1, + random_ref_fla_comp/1,parts/1, bin_to_list/1, list_to_bin/1, + copy/1, referenced/1,guard/1,encode_decode/1,badargs/1,longest_common_trap/1]). + +-export([random_number/1, make_unaligned/1]). + + + +%%-define(STANDALONE,1). + +-ifdef(STANDALONE). + +-define(line,erlang:display({?MODULE,?LINE}),). + +-else. + +-include("test_server.hrl"). +-export([init_per_testcase/2, fin_per_testcase/2]). +% Default timetrap timeout (set in init_per_testcase). +% Some of these testcases are really heavy... +-define(default_timeout, ?t:minutes(20)). + +-endif. + + + +-ifdef(STANDALONE). +-export([run/0]). + +run() -> + [ apply(?MODULE,X,[[]]) || X <- all(suite) ]. + +-else. + +init_per_testcase(_Case, Config) -> + ?line Dog = ?t:timetrap(?default_timeout), + [{watchdog, Dog} | Config]. + +fin_per_testcase(_Case, Config) -> + ?line Dog = ?config(watchdog, Config), + ?line test_server:timetrap_cancel(Dog), + ok. +-endif. + +all(suite) -> [interesting,random_ref_fla_comp,random_ref_sr_comp, + random_ref_comp,parts,bin_to_list, list_to_bin, copy, + referenced,guard,encode_decode,badargs,longest_common_trap]. + +-define(MASK_ERROR(EXPR),mask_error((catch (EXPR)))). + + +badargs(doc) -> + ["Tests various badarg exceptions in the module"]; +badargs(Config) when is_list(Config) -> + ?line badarg = ?MASK_ERROR(binary:compile_pattern([<<1,2,3:3>>])), + ?line badarg = ?MASK_ERROR(binary:compile_pattern([<<1,2,3>>|<<1,2>>])), + ?line badarg = ?MASK_ERROR(binary:compile_pattern(<<1,2,3:3>>)), + ?line badarg = ?MASK_ERROR(binary:compile_pattern(<<>>)), + ?line badarg = ?MASK_ERROR(binary:match(<<1,2,3:3>>,<<1>>)), + ?line badarg = ?MASK_ERROR(binary:matches(<<1,2,3:3>>,<<1>>)), + ?line badarg = ?MASK_ERROR(binary:match(<<1,2,3>>,<<1>>, + [{scope,{0,1},1}])), + ?line badarg = ?MASK_ERROR(binary:match(<<1,2,3>>,<<1>>, + [{scape,{0,1}}])), + ?line badarg = ?MASK_ERROR(binary:match(<<1,2,3>>,<<1>>, + [{scope,{0,1,1}}])), + ?line badarg = ?MASK_ERROR(binary:match(<<1,2,3>>,<<1>>,[{scope,0,1}])), + ?line badarg = ?MASK_ERROR(binary:match(<<1,2,3>>,<<1>>,[{scope,[0,1]}])), + ?line badarg = ?MASK_ERROR(binary:match(<<1,2,3>>,<<1>>, + [{scope,{0.1,1}}])), + ?line badarg = ?MASK_ERROR(binary:match(<<1,2,3>>,<<1>>, + [{scope,{1,1.1}}])), + ?line badarg = + ?MASK_ERROR( + binary:match(<<1,2,3>>,<<1>>, + [{scope,{16#FF, + 16#FFFFFFFFFFFFFFFF}}])), + ?line badarg = + ?MASK_ERROR( + binary:match(<<1,2,3>>,<<1>>, + [{scope,{16#FFFFFFFFFFFFFFFF, + -16#7FFFFFFFFFFFFFFF-1}}])), + ?line badarg = + ?MASK_ERROR( + binary:match(<<1,2,3>>,<<1>>, + [{scope,{16#FFFFFFFFFFFFFFFF, + 16#7FFFFFFFFFFFFFFF}}])), + ?line badarg = + ?MASK_ERROR( + binary:part(<<1,2,3>>,{16#FF, + 16#FFFFFFFFFFFFFFFF})), + ?line badarg = + ?MASK_ERROR( + binary:part(<<1,2,3>>,{16#FFFFFFFFFFFFFFFF, + -16#7FFFFFFFFFFFFFFF-1})), + ?line badarg = + ?MASK_ERROR( + binary:part(<<1,2,3>>,{16#FFFFFFFFFFFFFFFF, + 16#7FFFFFFFFFFFFFFF})), + ?line badarg = + ?MASK_ERROR( + binary:part(make_unaligned(<<1,2,3>>),{1,1,1})), + ?line badarg = + ?MASK_ERROR( + binary_part(make_unaligned(<<1,2,3>>),{1,1,1})), + ?line badarg = + ?MASK_ERROR( + binary_part(make_unaligned(<<1,2,3>>),{16#FFFFFFFFFFFFFFFF, + -16#7FFFFFFFFFFFFFFF-1})), + ?line badarg = + ?MASK_ERROR( + binary_part(make_unaligned(<<1,2,3>>),{16#FF, + 16#FFFFFFFFFFFFFFFF})), + ?line badarg = + ?MASK_ERROR( + binary_part(make_unaligned(<<1,2,3>>),{16#FFFFFFFFFFFFFFFF, + 16#7FFFFFFFFFFFFFFF})), + ?line badarg = + ?MASK_ERROR( + binary_part(make_unaligned(<<1,2,3>>),{16#FFFFFFFFFFFFFFFFFF, + -16#7FFF})), + ?line badarg = + ?MASK_ERROR( + binary_part(make_unaligned(<<1,2,3>>),{16#FF, + -16#7FFF})), + ?line badarg = + ?MASK_ERROR( + binary:bin_to_list(<<1,2,3>>,{16#FF, + 16#FFFFFFFFFFFFFFFF})), + ?line badarg = + ?MASK_ERROR( + binary:bin_to_list(<<1,2,3>>,{16#FFFFFFFFFFFFFFFF, + -16#7FFFFFFFFFFFFFFF-1})), + ?line badarg = + ?MASK_ERROR( + binary:bin_to_list(<<1,2,3>>,{16#FFFFFFFFFFFFFFFF, + 16#7FFFFFFFFFFFFFFF})), + ?line [1,2,3] = + ?MASK_ERROR( + binary:bin_to_list(<<1,2,3>>)), + ?line badarg = + ?MASK_ERROR( + binary:bin_to_list(<<1,2,3>>,[])), + ?line badarg = + ?MASK_ERROR( + binary:bin_to_list(<<1,2,3>>,{1,2,3})), + ?line badarg = + ?MASK_ERROR( + binary:bin_to_list(<<1,2,3>>,{1.0,1})), + ?line badarg = + ?MASK_ERROR( + binary:bin_to_list(<<1,2,3>>,{1,1.0})), + ?line badarg = + ?MASK_ERROR( + binary:bin_to_list(<<1,2,3:3>>,{1,1})), + ?line badarg = + ?MASK_ERROR( + binary:bin_to_list(<<1,2,3:3>>)), + ?line badarg = + ?MASK_ERROR( + binary:bin_to_list([1,2,3])), + + ?line nomatch = + ?MASK_ERROR(binary:match(<<1,2,3>>,<<1>>,[{scope,{0,0}}])), + ?line badarg = + ?MASK_ERROR(binary:match(<<1,2,3>>,{bm,<<>>},[{scope,{0,1}}])), + ?line badarg = + ?MASK_ERROR(binary:match(<<1,2,3>>,[],[{scope,{0,1}}])), + ?line badarg = + ?MASK_ERROR(binary:match(<<1,2,3>>,{ac,<<>>},[{scope,{0,1}}])), + ?line {bm,BMMagic} = binary:compile_pattern([<<1,2,3>>]), + ?line {ac,ACMagic} = binary:compile_pattern([<<1,2,3>>,<<4,5>>]), + ?line badarg = + ?MASK_ERROR(binary:match(<<1,2,3>>,{bm,ACMagic},[{scope,{0,1}}])), + ?line badarg = + ?MASK_ERROR(binary:match(<<1,2,3>>,{ac,BMMagic},[{scope,{0,1}}])), + ?line badarg = + ?MASK_ERROR( + binary:match(<<1,2,3>>, + {bm,ets:match_spec_compile([{'_',[],['$_']}])}, + [{scope,{0,1}}])), + ?line badarg = + ?MASK_ERROR( + binary:match(<<1,2,3>>, + {ac,ets:match_spec_compile([{'_',[],['$_']}])}, + [{scope,{0,1}}])), + ?line nomatch = + ?MASK_ERROR(binary:matches(<<1,2,3>>,<<1>>,[{scope,{0,0}}])), + ?line badarg = + ?MASK_ERROR(binary:matches(<<1,2,3>>,{bm,<<>>},[{scope,{0,1}}])), + ?line badarg = + ?MASK_ERROR(binary:matches(<<1,2,3>>,[],[{scope,{0,1}}])), + ?line badarg = + ?MASK_ERROR(binary:matches(<<1,2,3>>,{ac,<<>>},[{scope,{0,1}}])), + ?line badarg = + ?MASK_ERROR(binary:matches(<<1,2,3>>,{bm,ACMagic},[{scope,{0,1}}])), + ?line badarg = + ?MASK_ERROR(binary:matches(<<1,2,3>>,{ac,BMMagic},[{scope,{0,1}}])), + ?line badarg = + ?MASK_ERROR( + binary:matches(<<1,2,3>>, + {bm,ets:match_spec_compile([{'_',[],['$_']}])}, + [{scope,{0,1}}])), + ?line badarg = + ?MASK_ERROR( + binary:matches(<<1,2,3>>, + {ac,ets:match_spec_compile([{'_',[],['$_']}])}, + [{scope,{0,1}}])), + ?line badarg = + ?MASK_ERROR(binary:longest_common_prefix( + [<<0:10000,1,2,4,1:3>>, + <<0:10000,1,2,3>>])), + ?line badarg = + ?MASK_ERROR(binary:longest_common_suffix( + [<<0:10000,1,2,4,1:3>>, + <<0:10000,1,2,3>>])), + ?line badarg = + ?MASK_ERROR(binary:encode_unsigned(-1)), + ?line badarg = + ?MASK_ERROR( + binary:encode_unsigned(-16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), + ?line badarg = + ?MASK_ERROR( + binary:first(<<1,2,4,1:3>>)), + ?line badarg = + ?MASK_ERROR( + binary:first([1,2,4])), + ?line badarg = + ?MASK_ERROR( + binary:last(<<1,2,4,1:3>>)), + ?line badarg = + ?MASK_ERROR( + binary:last([1,2,4])), + ?line badarg = + ?MASK_ERROR( + binary:at(<<1,2,4,1:3>>,2)), + ?line badarg = + ?MASK_ERROR( + binary:at(<<>>,2)), + ?line badarg = + ?MASK_ERROR( + binary:at([1,2,4],2)), + ok. + +longest_common_trap(doc) -> + ["Whitebox test to force special trap conditions in longest_common_{prefix,suffix}"]; +longest_common_trap(Config) when is_list(Config) -> + ?line erts_debug:set_internal_state(available_internal_state,true), + ?line io:format("oldlimit: ~p~n", + [erts_debug:set_internal_state(binary_loop_limit,10)]), + erlang:bump_reductions(10000000), + ?line _ = binary:longest_common_prefix( + [<<0:10000,1,2,4>>, + <<0:10000,1,2,3>>, + <<0:10000,1,3,3>>, + <<0:10000,1,2,4>>, + <<0:10000,1,2,4>>, + <<0:10000,1,2,3>>, + <<0:10000,1,3,3>>, + <<0:10000,1,2,3>>, + <<0:10000,1,3,3>>, + <<0:10000,1,2,4>>, + <<0:10000,1,2,4>>, + <<0:10000,1,2,3>>, + <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0:10000,1,3,3>>, + <<0:10000,1,2,4>>]), + ?line _ = binary:longest_common_prefix( + [<<0:10000,1,2,4>>, + <<0:10000,1,2,3>>, + <<0:10000,1,3,3>>, + <<0:10000,1,2,4>>, + <<0:10000,1,2,4>>, + <<0:10000,1,2,3>>, + <<0:10000,1,3,3>>, + <<0:10000,1,2,3>>, + <<0:10000,1,3,3>>, + <<0:10000,1,2,4>>, + <<0:10000,1,2,4>>, + <<0:10000,1,2,3>>, + <<0,0,0,0,0,0,0,0,0,0,0,0,0,0>>, + <<0:10000,1,2,4>>]), + erlang:bump_reductions(10000000), + ?line _ = binary:longest_common_suffix( + [<<1,2,4,0:10000>>, + <<1,2,4,0:10000>>, + <<1,2,4,0:10000>>, + <<1,2,4,0:10000>>, + <<1,2,4,0:10000>>, + <<1,2,4,0:10000>>, + <<1,2,4,0:10000>>, + <<1,2,4,0:10000>>, + <<1,2,4,0:10000>>, + <<1,2,4,0:10000>>, + <<1,2,4,0:10000>>, + <<1,2,4,0:10000>>, + <<1,3,3,0:10000,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>, + <<1,2,4,0:10000>>]), + ?line _ = binary:longest_common_suffix( + [<<1,2,4,0:10000>>, + <<1,2,4,0:10000>>, + <<1,2,4,0:10000>>, + <<1,2,4,0:10000>>, + <<1,2,4,0:10000>>, + <<1,2,4,0:10000>>, + <<1,2,4,0:10000>>, + <<1,2,4,0:10000>>, + <<1,2,4,0:10000>>, + <<1,2,4,0:10000>>, + <<1,2,4,0:10000>>, + <<1,2,4,0:10000>>, + <<0,0,0,0,0,0,0,0,0,0,0,0,0,0>>, + <<1,2,4,0:10000>>]), + Subj = subj(), + Len = byte_size(Subj), + ?line Len = binary:longest_common_suffix( + [Subj,Subj,Subj]), + ?line io:format("limit was: ~p~n", + [erts_debug:set_internal_state(binary_loop_limit, + default)]), + ?line erts_debug:set_internal_state(available_internal_state,false), + ok. + +subj() -> + Me = self(), + spawn(fun() -> + X0 = iolist_to_binary([ + "1234567890", + %lists:seq(16#21, 16#7e), + lists:duplicate(100, $x) + ]), + Me ! X0, + receive X -> X end + end), + X0 = receive A -> A end, + <<X1:32/binary,_/binary>> = X0, + Subject= <<X1/binary>>, + Subject. + + +interesting(doc) -> + ["Try some interesting patterns"]; +interesting(Config) when is_list(Config) -> + X = do_interesting(binary), + X = do_interesting(binref). + +do_interesting(Module) -> + ?line {0,4} = Module:match(<<"123456">>, + Module:compile_pattern([<<"12">>,<<"1234">>, + <<"23">>,<<"3">>, + <<"34">>,<<"456">>, + <<"45">>,<<"6">>])), + ?line [{0,4},{5,1}] = Module:matches(<<"123456">>, + Module:compile_pattern([<<"12">>,<<"1234">>, + <<"23">>,<<"3">>, + <<"34">>,<<"456">>, + <<"45">>,<<"6">>])), + ?line [{0,4}] = Module:matches(<<"123456">>, + Module:compile_pattern([<<"12">>,<<"1234">>, + <<"23">>,<<"3">>, + <<"34">>,<<"456">>, + <<"45">>])), + ?line [{0,2},{2,2}] = Module:matches(<<"123456">>, + Module:compile_pattern([<<"12">>, + <<"23">>,<<"3">>, + <<"34">>,<<"456">>, + <<"45">>])), + ?line {1,4} = Module:match(<<"123456">>, + Module:compile_pattern([<<"34">>,<<"34">>, + <<"12347">>,<<"2345">>])), + ?line [{1,4}] = Module:matches(<<"123456">>, + Module:compile_pattern([<<"34">>,<<"34">>, + <<"12347">>,<<"2345">>])), + ?line [{2,2}] = Module:matches(<<"123456">>, + Module:compile_pattern([<<"34">>,<<"34">>, + <<"12347">>,<<"2346">>])), + + ?line {0,4} = Module:match(<<"123456">>, + [<<"12">>,<<"1234">>, + <<"23">>,<<"3">>, + <<"34">>,<<"456">>, + <<"45">>,<<"6">>]), + ?line [{0,4},{5,1}] = Module:matches(<<"123456">>, + [<<"12">>,<<"1234">>, + <<"23">>,<<"3">>, + <<"34">>,<<"456">>, + <<"45">>,<<"6">>]), + ?line [{0,4}] = Module:matches(<<"123456">>, + [<<"12">>,<<"1234">>, + <<"23">>,<<"3">>, + <<"34">>,<<"456">>, + <<"45">>]), + ?line [{0,2},{2,2}] = Module:matches(<<"123456">>, + [<<"12">>, + <<"23">>,<<"3">>, + <<"34">>,<<"456">>, + <<"45">>]), + ?line {1,4} = Module:match(<<"123456">>, + [<<"34">>,<<"34">>, + <<"12347">>,<<"2345">>]), + ?line [{1,4}] = Module:matches(<<"123456">>, + [<<"34">>,<<"34">>, + <<"12347">>,<<"2345">>]), + ?line [{2,2}] = Module:matches(<<"123456">>, + [<<"34">>,<<"34">>, + <<"12347">>,<<"2346">>]), + ?line nomatch = Module:match(<<1,2,3,4>>,<<2>>,[{scope,{0,1}}]), + ?line {1,1} = Module:match(<<1,2,3,4>>,<<2>>,[{scope,{0,2}}]), + ?line nomatch = Module:match(<<1,2,3,4>>,<<2,3>>,[{scope,{0,2}}]), + ?line {1,2} = Module:match(<<1,2,3,4>>,<<2,3>>,[{scope,{0,3}}]), + ?line {1,2} = Module:match(<<1,2,3,4>>,<<2,3>>,[{scope,{0,4}}]), + ?line badarg = ?MASK_ERROR(Module:match(<<1,2,3,4>>,<<2,3>>, + [{scope,{0,5}}])), + ?line {1,2} = Module:match(<<1,2,3,4>>,<<2,3>>,[{scope,{4,-4}}]), + ?line {0,3} = Module:match(<<1,2,3,4>>,<<1,2,3>>,[{scope,{4,-4}}]), + ?line {0,4} = Module:match(<<1,2,3,4>>,<<1,2,3,4>>,[{scope,{4,-4}}]), + ?line badarg = ?MASK_ERROR(Module:match(<<1,2,3,4>>,<<1,2,3,4>>, + [{scope,{3,-4}}])), + ?line [] = Module:matches(<<1,2,3,4>>,<<2>>,[{scope,{0,1}}]), + ?line [{1,1}] = Module:matches(<<1,2,3,4>>,[<<2>>,<<3>>],[{scope,{0,2}}]), + ?line [] = Module:matches(<<1,2,3,4>>,<<2,3>>,[{scope,{0,2}}]), + ?line [{1,2}] = Module:matches(<<1,2,3,4>>,<<2,3>>,[{scope,{0,3}}]), + ?line [{1,2}] = Module:matches(<<1,2,3,4>>,<<2,3>>,[{scope,{0,4}}]), + ?line [{1,2}] = Module:matches(<<1,2,3,4>>,[<<2,3>>,<<4>>], + [{scope,{0,3}}]), + ?line [{1,2},{3,1}] = Module:matches(<<1,2,3,4>>,[<<2,3>>,<<4>>], + [{scope,{0,4}}]), + ?line badarg = ?MASK_ERROR(Module:matches(<<1,2,3,4>>,<<2,3>>, + [{scope,{0,5}}])), + ?line [{1,2}] = Module:matches(<<1,2,3,4>>,<<2,3>>,[{scope,{4,-4}}]), + ?line [{1,2},{3,1}] = Module:matches(<<1,2,3,4>>,[<<2,3>>,<<4>>], + [{scope,{4,-4}}]), + ?line [{0,3}] = Module:matches(<<1,2,3,4>>,<<1,2,3>>,[{scope,{4,-4}}]), + ?line [{0,4}] = Module:matches(<<1,2,3,4>>,<<1,2,3,4>>,[{scope,{4,-4}}]), + ?line badarg = ?MASK_ERROR(Module:matches(<<1,2,3,4>>,<<1,2,3,4>>, + [{scope,{3,-4}}])), + ?line badarg = ?MASK_ERROR(Module:matches(<<1,2,3,4>>,[<<1,2,3,4>>], + [{scope,{3,-4}}])), + ?line [<<1,2,3>>,<<6,7,8>>] = Module:split(<<1,2,3,4,5,6,7,8>>,<<4,5>>), + ?line [<<1,2,3>>,<<6,7,8>>] = Module:split(<<1,2,3,4,5,6,7,8>>, + [<<4,5>>,<<7>>]), + ?line [<<1,2,3>>,<<6>>,<<8>>] = Module:split(<<1,2,3,4,5,6,7,8>>, + [<<4,5>>,<<7>>],[global]), + ?line [<<1,2,3>>,<<6>>,<<>>,<<>>] = Module:split(<<1,2,3,4,5,6,7,8>>, + [<<4,5>>,<<7>>,<<8>>], + [global]), + ?line [<<1,2,3>>,<<6>>] = Module:split(<<1,2,3,4,5,6,7,8>>, + [<<4,5>>,<<7>>,<<8>>], + [global,trim]), + ?line [<<1,2,3,4,5,6,7,8>>] = Module:split(<<1,2,3,4,5,6,7,8>>, + [<<4,5>>,<<7>>,<<8>>], + [global,trim,{scope,{0,4}}]), + ?line [<<1,2,3>>,<<6,7,8>>] = Module:split(<<1,2,3,4,5,6,7,8>>, + [<<4,5>>,<<7>>,<<8>>], + [global,trim,{scope,{0,5}}]), + ?line badarg = ?MASK_ERROR( + Module:replace(<<1,2,3,4,5,6,7,8>>, + [<<4,5>>,<<7>>,<<8>>],<<99>>, + [global,trim,{scope,{0,5}}])), + ?line <<1,2,3,99,6,7,8>> = Module:replace(<<1,2,3,4,5,6,7,8>>, + [<<4,5>>,<<7>>,<<8>>],<<99>>,[]), + ?line <<1,2,3,99,6,99,99>> = Module:replace(<<1,2,3,4,5,6,7,8>>, + [<<4,5>>,<<7>>,<<8>>],<<99>>, + [global]), + ?line <<1,2,3,99,6,7,8>> = Module:replace(<<1,2,3,4,5,6,7,8>>, + [<<4,5>>,<<7>>,<<8>>],<<99>>, + [global,{scope,{0,5}}]), + ?line <<1,2,3,99,6,7,8>> = Module:replace(<<1,2,3,4,5,6,7,8>>, + [<<4,5>>,<<7>>,<<8>>],<<99>>, + [global,{scope,{0,5}}]), + ?line <<1,2,3,99,6,7,8>> = Module:replace(<<1,2,3,4,5,6,7,8>>, + [<<4,5>>,<<7>>,<<8>>],<<99>>, + [global,{scope,{0,5}}]), + ?line badarg = ?MASK_ERROR(Module:replace(<<1,2,3,4,5,6,7,8>>, + [<<4,5>>,<<7>>,<<8>>],<<99>>, + [global,{scope,{0,5}}, + {insert,1}])), + ?line <<1,2,3,99,4,5,6,7,8>> = Module:replace(<<1,2,3,4,5,6,7,8>>, + [<<4,5>>,<<7>>,<<8>>],<<99>>, + [global,{scope,{0,5}}, + {insert_replaced,1}]), + ?line <<1,2,3,9,4,5,9,6,7,8>> = Module:replace(<<1,2,3,4,5,6,7,8>>, + [<<4,5>>,<<7>>,<<8>>], + <<9,9>>, + [global,{scope,{0,5}}, + {insert_replaced,1}]), + ?line badarg = ?MASK_ERROR(Module:replace(<<1,2,3,4,5,6,7,8>>, + [<<4,5>>,<<7>>,<<8>>],<<>>, + [global,{scope,{0,5}}, + {insert_replaced,1}])), + ?line 2 = Module:longest_common_prefix([<<1,2,4>>,<<1,2,3>>]), + ?line 2 = Module:longest_common_prefix([<<1,2,4>>,<<1,2>>]), + ?line 1 = Module:longest_common_prefix([<<1,2,4>>,<<1>>]), + ?line 0 = Module:longest_common_prefix([<<1,2,4>>,<<>>]), + ?line 1 = Module:longest_common_prefix([<<1,2,4>>,<<1,2,3>>,<<1,3,3>>]), + ?line 1 = Module:longest_common_prefix([<<1,2,4>>,<<1,2,3>>,<<1,3,3>>,<<1,2,4>>]), + ?line 1251 = Module:longest_common_prefix([<<0:10000,1,2,4>>, + <<0:10000,1,2,3>>, + <<0:10000,1,3,3>>, + <<0:10000,1,2,4>>]), + ?line 12501 = Module:longest_common_prefix([<<0:100000,1,2,4>>, + <<0:100000,1,2,3>>, + <<0:100000,1,3,3>>, + <<0:100000,1,2,4>>]), + ?line 1251 = Module:longest_common_prefix( + [make_unaligned(<<0:10000,1,2,4>>), + <<0:10000,1,2,3>>, + make_unaligned(<<0:10000,1,3,3>>), + <<0:10000,1,2,4>>]), + ?line 12501 = Module:longest_common_prefix( + [<<0:100000,1,2,4>>, + make_unaligned(<<0:100000,1,2,3>>), + <<0:100000,1,3,3>>, + make_unaligned(<<0:100000,1,2,4>>)]), + ?line 1250001 = Module:longest_common_prefix([<<0:10000000,1,2,4>>, + <<0:10000000,1,2,3>>, + <<0:10000000,1,3,3>>, + <<0:10000000,1,2,4>>]), + if % Too cruel for the reference implementation + Module =:= binary -> + ?line erts_debug:set_internal_state(available_internal_state,true), + ?line io:format("oldlimit: ~p~n", + [erts_debug:set_internal_state( + binary_loop_limit,100)]), + ?line 1250001 = Module:longest_common_prefix( + [<<0:10000000,1,2,4>>, + <<0:10000000,1,2,3>>, + <<0:10000000,1,3,3>>, + <<0:10000000,1,2,4>>]), + ?line io:format("limit was: ~p~n", + [erts_debug:set_internal_state(binary_loop_limit, + default)]), + ?line erts_debug:set_internal_state(available_internal_state, + false); + true -> + ok + end, + ?line 1 = Module:longest_common_suffix([<<0:100000000,1,2,4,5>>, + <<0:100000000,1,2,3,5>>, + <<0:100000000,1,3,3,5>>, + <<0:100000000,1,2,4,5>>]), + ?line 1 = Module:longest_common_suffix([<<1,2,4,5>>, + <<0:100000000,1,2,3,5>>, + <<0:100000000,1,3,3,5>>, + <<0:100000000,1,2,4,5>>]), + ?line 1 = Module:longest_common_suffix([<<1,2,4,5,5>>,<<5,5>>, + <<0:100000000,1,3,3,5,5>>, + <<0:100000000,1,2,4,5>>]), + ?line 0 = Module:longest_common_suffix([<<1,2,4,5,5>>,<<5,5>>, + <<0:100000000,1,3,3,5,5>>, + <<0:100000000,1,2,4>>]), + ?line 2 = Module:longest_common_suffix([<<1,2,4,5,5>>,<<5,5>>, + <<0:100000000,1,3,3,5,5>>, + <<0:100000000,1,2,4,5,5>>]), + ?line 1 = Module:longest_common_suffix([<<1,2,4,5,5>>,<<5>>, + <<0:100000000,1,3,3,5,5>>, + <<0:100000000,1,2,4,5,5>>]), + ?line 0 = Module:longest_common_suffix([<<1,2,4,5,5>>,<<>>, + <<0:100000000,1,3,3,5,5>>, + <<0:100000000,1,2,4,5,5>>]), + ?line 0 = Module:longest_common_suffix([<<>>,<<0:100000000,1,3,3,5,5>>, + <<0:100000000,1,2,4,5,5>>]), + ?line 0 = Module:longest_common_suffix([<<>>,<<0:100000000,1,3,3,5,5>>, + <<0:100000000,1,2,4,5,5>>]), + ?line 2 = Module:longest_common_suffix([<<5,5>>,<<0:100000000,1,3,3,5,5>>, + <<0:100000000,1,2,4,5,5>>]), + ?line 2 = Module:longest_common_suffix([<<5,5>>,<<5,5>>,<<4,5,5>>]), + ?line 2 = Module:longest_common_suffix([<<5,5>>,<<5,5>>,<<5,5>>]), + ?line 3 = Module:longest_common_suffix([<<4,5,5>>,<<4,5,5>>,<<4,5,5>>]), + ?line 0 = Module:longest_common_suffix([<<>>]), + ?line badarg = ?MASK_ERROR(Module:longest_common_suffix([])), + ?line badarg = ?MASK_ERROR(Module:longest_common_suffix([apa])), + ?line badarg = ?MASK_ERROR(Module:longest_common_suffix([[<<>>]])), + ?line badarg = ?MASK_ERROR(Module:longest_common_suffix([[<<0>>, + <<1:9>>]])), + ?line 0 = Module:longest_common_prefix([<<>>]), + ?line badarg = ?MASK_ERROR(Module:longest_common_prefix([])), + ?line badarg = ?MASK_ERROR(Module:longest_common_prefix([apa])), + ?line badarg = ?MASK_ERROR(Module:longest_common_prefix([[<<>>]])), + ?line badarg = ?MASK_ERROR(Module:longest_common_prefix([[<<0>>, + <<1:9>>]])), + + ?line <<1:6,Bin:3/binary,_:2>> = <<1:6,1,2,3,1:2>>, + ?line <<1,2,3>> = Bin, + ?line 1 = Module:first(Bin), + ?line 1 = Module:first(<<1>>), + ?line 1 = Module:first(<<1,2,3>>), + ?line badarg = ?MASK_ERROR(Module:first(<<>>)), + ?line badarg = ?MASK_ERROR(Module:first(apa)), + ?line 3 = Module:last(Bin), + ?line 1 = Module:last(<<1>>), + ?line 3 = Module:last(<<1,2,3>>), + ?line badarg = ?MASK_ERROR(Module:last(<<>>)), + ?line badarg = ?MASK_ERROR(Module:last(apa)), + ?line 1 = Module:at(Bin,0), + ?line 1 = Module:at(<<1>>,0), + ?line 1 = Module:at(<<1,2,3>>,0), + ?line 2 = Module:at(<<1,2,3>>,1), + ?line 3 = Module:at(<<1,2,3>>,2), + ?line badarg = ?MASK_ERROR(Module:at(<<1,2,3>>,3)), + ?line badarg = ?MASK_ERROR(Module:at(<<1,2,3>>,-1)), + ?line badarg = ?MASK_ERROR(Module:at(<<1,2,3>>,apa)), + ?line "hejsan" = [ Module:at(<<"hejsan">>,I) || I <- lists:seq(0,5) ], + + ?line badarg = ?MASK_ERROR(Module:bin_to_list(<<1,2,3>>,3,-4)), + ?line [1,2,3] = ?MASK_ERROR(Module:bin_to_list(<<1,2,3>>,3,-3)), + + ?line badarg = ?MASK_ERROR(Module:decode_unsigned(<<1,2,1:2>>,big)), + ?line badarg = ?MASK_ERROR(Module:decode_unsigned(<<1,2,1:2>>,little)), + ?line badarg = ?MASK_ERROR(Module:decode_unsigned(apa)), + ?line badarg = ?MASK_ERROR(Module:decode_unsigned(125,little)), + ?line 0 = ?MASK_ERROR(Module:decode_unsigned(<<>>,little)), + ?line 0 = ?MASK_ERROR(Module:decode_unsigned(<<>>,big)), + ?line 0 = ?MASK_ERROR(Module:decode_unsigned(<<0>>,little)), + ?line 0 = ?MASK_ERROR(Module:decode_unsigned(<<0>>,big)), + ?line 0 = ?MASK_ERROR(Module:decode_unsigned(make_unaligned(<<0>>), + little)), + ?line 0 = ?MASK_ERROR(Module:decode_unsigned(make_unaligned(<<0>>),big)), + ?line badarg = ?MASK_ERROR(Module:encode_unsigned(apa)), + ?line badarg = ?MASK_ERROR(Module:encode_unsigned(125.3,little)), + ?line badarg = ?MASK_ERROR(Module:encode_unsigned({1},little)), + ?line badarg = ?MASK_ERROR(Module:encode_unsigned([1],little)), + ?line <<0>> = ?MASK_ERROR(Module:encode_unsigned(0,little)), + ?line <<0>> = ?MASK_ERROR(Module:encode_unsigned(0,big)), + ok. + +encode_decode(doc) -> + ["test binary:encode_unsigned/1,2 and binary:decode_unsigned/1,2"]; +encode_decode(Config) when is_list(Config) -> + ?line random:seed({1271,769940,559934}), + ?line ok = encode_decode_loop({1,200},1000), % Need to be long enough + % to create offheap binaries + ok. + +encode_decode_loop(_Range,0) -> + ok; +encode_decode_loop(Range, X) -> + ?line N = random_number(Range), + ?line A = binary:encode_unsigned(N), + ?line B = binary:encode_unsigned(N,big), + ?line C = binref:encode_unsigned(N), + ?line D = binref:encode_unsigned(N,big), + ?line E = binary:encode_unsigned(N,little), + ?line F = binref:encode_unsigned(N,little), + ?line G = binary:decode_unsigned(A), + ?line H = binary:decode_unsigned(A,big), + ?line I = binref:decode_unsigned(A), + ?line J = binary:decode_unsigned(E,little), + ?line K = binref:decode_unsigned(E,little), + ?line L = binary:decode_unsigned(make_unaligned(A)), + ?line M = binary:decode_unsigned(make_unaligned(E),little), + ?line PaddedBig = <<0:48,A/binary>>, + ?line PaddedLittle = <<E/binary,0:48>>, + ?line O = binary:decode_unsigned(PaddedBig), + ?line P = binary:decode_unsigned(make_unaligned(PaddedBig)), + ?line Q = binary:decode_unsigned(PaddedLittle,little), + ?line R = binary:decode_unsigned(make_unaligned(PaddedLittle),little), + ?line S = binref:decode_unsigned(PaddedLittle,little), + ?line T = binref:decode_unsigned(PaddedBig), + case (((A =:= B) and (B =:= C) and (C =:= D)) and + ((E =:= F)) and + ((N =:= G) and (G =:= H) and (H =:= I) and + (I =:= J) and (J =:= K) and (K =:= L) and (L =:= M)) and + ((M =:= O) and (O =:= P) and (P =:= Q) and (Q =:= R) and + (R =:= S) and (S =:= T)))of + true -> + encode_decode_loop(Range,X-1); + _ -> + io:format("Failed to encode/decode ~w~n(Results ~p)~n", + [N,[A,B,C,D,E,F,G,H,I,J,K,L,M,x,O,P,Q,R,S,T]]), + exit(mismatch) + end. + +guard(doc) -> + ["Smoke test of the guard BIFs binary_part/2,3"]; +guard(Config) when is_list(Config) -> + {comment, "Guard tests are run in emulator test suite"}. + +referenced(doc) -> + ["Test refernced_byte_size/1 bif."]; +referenced(Config) when is_list(Config) -> + ?line badarg = ?MASK_ERROR(binary:referenced_byte_size([])), + ?line badarg = ?MASK_ERROR(binary:referenced_byte_size(apa)), + ?line badarg = ?MASK_ERROR(binary:referenced_byte_size({})), + ?line badarg = ?MASK_ERROR(binary:referenced_byte_size(1)), + ?line A = <<1,2,3>>, + ?line B = binary:copy(A,1000), + ?line 3 = binary:referenced_byte_size(A), + ?line 3000 = binary:referenced_byte_size(B), + ?line <<_:8,C:2/binary>> = A, + ?line 3 = binary:referenced_byte_size(C), + ?line 2 = binary:referenced_byte_size(binary:copy(C)), + ?line <<_:7,D:2/binary,_:1>> = A, + ?line 2 = binary:referenced_byte_size(binary:copy(D)), + ?line 3 = binary:referenced_byte_size(D), + ?line <<_:8,E:2/binary,_/binary>> = B, + ?line 3000 = binary:referenced_byte_size(E), + ?line 2 = binary:referenced_byte_size(binary:copy(E)), + ?line <<_:7,F:2/binary,_:1,_/binary>> = B, + ?line 2 = binary:referenced_byte_size(binary:copy(F)), + ?line 3000 = binary:referenced_byte_size(F), + ok. + + + +list_to_bin(doc) -> + ["Test list_to_bin/1 bif"]; +list_to_bin(Config) when is_list(Config) -> + %% Just some smoke_tests first, then go nuts with random cases + ?line badarg = ?MASK_ERROR(binary:list_to_bin({})), + ?line badarg = ?MASK_ERROR(binary:list_to_bin(apa)), + ?line badarg = ?MASK_ERROR(binary:list_to_bin(<<"apa">>)), + F1 = fun(L) -> + ?MASK_ERROR(binref:list_to_bin(L)) + end, + F2 = fun(L) -> + ?MASK_ERROR(binary:list_to_bin(L)) + end, + ?line random_iolist:run(1000,F1,F2), + ok. + +copy(doc) -> + ["Test copy/1,2 bif's"]; +copy(Config) when is_list(Config) -> + ?line <<1,2,3>> = binary:copy(<<1,2,3>>), + ?line RS = random_string({1,10000}), + ?line RS = RS2 = binary:copy(RS), + ?line false = erts_debug:same(RS,RS2), + ?line <<>> = ?MASK_ERROR(binary:copy(<<1,2,3>>,0)), + ?line badarg = ?MASK_ERROR(binary:copy(<<1,2,3:3>>,2)), + ?line badarg = ?MASK_ERROR(binary:copy([],0)), + ?line <<>> = ?MASK_ERROR(binary:copy(<<>>,0)), + ?line badarg = ?MASK_ERROR(binary:copy(<<1,2,3>>,1.0)), + ?line badarg = ?MASK_ERROR(binary:copy(<<1,2,3>>, + 16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), + ?line <<>> = binary:copy(<<>>,10000), + ?line random:seed({1271,769940,559934}), + ?line ok = random_copy(3000), + ?line erts_debug:set_internal_state(available_internal_state,true), + ?line io:format("oldlimit: ~p~n", + [erts_debug:set_internal_state(binary_loop_limit,10)]), + ?line Subj = subj(), + ?line XX = binary:copy(Subj,1000), + ?line XX = binref:copy(Subj,1000), + ?line ok = random_copy(1000), + ?line kill_copy_loop(1000), + ?line io:format("limit was: ~p~n", + [erts_debug:set_internal_state(binary_loop_limit, + default)]), + ?line erts_debug:set_internal_state(available_internal_state,false), + ok. + +kill_copy_loop(0) -> + ok; +kill_copy_loop(N) -> + {Pid,Ref} = spawn_monitor(fun() -> + ok = random_copy(1000) + end), + receive + after 10 -> + ok + end, + exit(Pid,kill), + receive + {'DOWN',Ref,process,Pid,_} -> + kill_copy_loop(N-1) + after 1000 -> + exit(did_not_die) + end. + +random_copy(0) -> + ok; +random_copy(N) -> + Str = random_string({0,N}), + Num = random:uniform(N div 10+1), + A = ?MASK_ERROR(binary:copy(Str,Num)), + B = ?MASK_ERROR(binref:copy(Str,Num)), + C = ?MASK_ERROR(binary:copy(make_unaligned(Str),Num)), + case {(A =:= B), (B =:= C)} of + {true,true} -> + random_copy(N-1); + _ -> + io:format("Failed to pick copy ~s ~p times~n", + [Str,Num]), + io:format("A:~p,~nB:~p,~n,C:~p.~n", + [A,B,C]), + exit(mismatch) + end. + +bin_to_list(doc) -> + ["Test bin_to_list/1,2,3 bif's"]; +bin_to_list(Config) when is_list(Config) -> + %% Just some smoke_tests first, then go nuts with random cases + ?line X = <<1,2,3,4,0:1000000,5>>, + ?line Y = make_unaligned(X), + ?line LX = binary:bin_to_list(X), + ?line LX = binary:bin_to_list(X,0,byte_size(X)), + ?line LX = binary:bin_to_list(X,byte_size(X),-byte_size(X)), + ?line LX = binary:bin_to_list(X,{0,byte_size(X)}), + ?line LX = binary:bin_to_list(X,{byte_size(X),-byte_size(X)}), + ?line LY = binary:bin_to_list(Y), + ?line LY = binary:bin_to_list(Y,0,byte_size(Y)), + ?line LY = binary:bin_to_list(Y,byte_size(Y),-byte_size(Y)), + ?line LY = binary:bin_to_list(Y,{0,byte_size(Y)}), + ?line LY = binary:bin_to_list(Y,{byte_size(Y),-byte_size(Y)}), + ?line 1 = hd(LX), + ?line 5 = lists:last(LX), + ?line 1 = hd(LY), + ?line 5 = lists:last(LY), + ?line X = list_to_binary(LY), + ?line Y = list_to_binary(LY), + ?line X = list_to_binary(LY), + ?line [5] = lists:nthtail(byte_size(X)-1,LX), + ?line [0,5] = lists:nthtail(byte_size(X)-2,LX), + ?line [0,5] = lists:nthtail(byte_size(Y)-2,LY), + ?line random:seed({1271,769940,559934}), + ?line ok = random_bin_to_list(5000), + ok. + +random_bin_to_list(0) -> + ok; +random_bin_to_list(N) -> + Str = random_string({1,N}), + Parts0 = random_parts(10,N), + Parts1 = Parts0 ++ [ {X+Y,-Y} || {X,Y} <- Parts0 ], + [ begin + try + true = ?MASK_ERROR(binary:bin_to_list(Str,Z)) =:= + ?MASK_ERROR(binref:bin_to_list(Str,Z)), + true = ?MASK_ERROR(binary:bin_to_list(Str,Z)) =:= + ?MASK_ERROR(binary:bin_to_list(make_unaligned(Str),Z)) + catch + _:_ -> + io:format("Error, Str = <<\"~s\">>.~nZ = ~p.~n", + [Str,Z]), + exit(badresult) + end + end || Z <- Parts1 ], + [ begin + try + true = ?MASK_ERROR(binary:bin_to_list(Str,A,B)) =:= + ?MASK_ERROR(binref:bin_to_list(Str,A,B)), + true = ?MASK_ERROR(binary:bin_to_list(Str,A,B)) =:= + ?MASK_ERROR(binary:bin_to_list(make_unaligned(Str),A,B)) + catch + _:_ -> + io:format("Error, Str = <<\"~s\">>.~nA = ~p.~nB = ~p.~n", + [Str,A,B]), + exit(badresult) + end + end || {A,B} <- Parts1 ], + random_bin_to_list(N-1). + +parts(doc) -> + ["Test the part/2,3 bif's"]; +parts(Config) when is_list(Config) -> + %% Some simple smoke tests to begin with + ?line Simple = <<1,2,3,4,5,6,7,8>>, + ?line <<1,2>> = binary:part(Simple,0,2), + ?line <<1,2>> = binary:part(Simple,{0,2}), + ?line Simple = binary:part(Simple,0,8), + ?line Simple = binary:part(Simple,{0,8}), + ?line badarg = ?MASK_ERROR(binary:part(Simple,0,9)), + ?line badarg = ?MASK_ERROR(binary:part(Simple,{0,9})), + ?line badarg = ?MASK_ERROR(binary:part(Simple,1,8)), + ?line badarg = ?MASK_ERROR(binary:part(Simple,{1,8})), + ?line badarg = ?MASK_ERROR(binary:part(Simple,{3,-4})), + ?line badarg = ?MASK_ERROR(binary:part(Simple,{3.0,1})), + ?line badarg = ?MASK_ERROR( + binary:part(Simple,{16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ,1})), + ?line <<2,3,4,5,6,7,8>> = binary:part(Simple,{1,7}), + ?line <<2,3,4,5,6,7,8>> = binary:part(Simple,{8,-7}), + ?line Simple = binary:part(Simple,{8,-8}), + ?line badarg = ?MASK_ERROR(binary:part(Simple,{1,-8})), + ?line badarg = ?MASK_ERROR(binary:part(Simple,{8,-9})), + ?line badarg = ?MASK_ERROR(binary:part(Simple,{0,-1})), + ?line <<>> = binary:part(Simple,{8,0}), + ?line badarg = ?MASK_ERROR(binary:part(Simple,{9,0})), + ?line badarg = ?MASK_ERROR(binary:part(Simple,{-1,0})), + ?line badarg = ?MASK_ERROR(binary:part(Simple,{7,2})), + ?line <<8>> = binary:part(Simple,{7,1}), + ?line random:seed({1271,769940,559934}), + ?line random_parts(5000), + ok. + + +random_parts(0) -> + ok; +random_parts(N) -> + Str = random_string({1,N}), + Parts0 = random_parts(10,N), + Parts1 = Parts0 ++ [ {X+Y,-Y} || {X,Y} <- Parts0 ], + [ begin + true = ?MASK_ERROR(binary:part(Str,Z)) =:= + ?MASK_ERROR(binref:part(Str,Z)), + true = ?MASK_ERROR(binary:part(Str,Z)) =:= + ?MASK_ERROR(erlang:binary_part(Str,Z)), + true = ?MASK_ERROR(binary:part(Str,Z)) =:= + ?MASK_ERROR(binary:part(make_unaligned(Str),Z)) + end || Z <- Parts1 ], + random_parts(N-1). + +random_parts(0,_) -> + []; +random_parts(X,N) -> + Pos = random:uniform(N), + Len = random:uniform((Pos * 12) div 10), + [{Pos,Len} | random_parts(X-1,N)]. + +random_ref_comp(doc) -> + ["Test pseudorandomly generated cases against reference imlementation"]; +random_ref_comp(Config) when is_list(Config) -> + ?line put(success_counter,0), + ?line random:seed({1271,769940,559934}), + ?line do_random_match_comp(5000,{1,40},{30,1000}), + io:format("Number of successes: ~p~n",[get(success_counter)]), + ?line do_random_match_comp2(5000,{1,40},{30,1000}), + io:format("Number of successes: ~p~n",[get(success_counter)]), + ?line do_random_match_comp3(5000,{1,40},{30,1000}), + io:format("Number of successes: ~p~n",[get(success_counter)]), + ?line do_random_match_comp4(5000,{1,40},{30,1000}), + io:format("Number of successes: ~p~n",[get(success_counter)]), + ?line do_random_matches_comp(5000,{1,40},{30,1000}), + io:format("Number of successes: ~p~n",[get(success_counter)]), + ?line do_random_matches_comp2(5000,{1,40},{30,1000}), + io:format("Number of successes: ~p~n",[get(success_counter)]), + ?line do_random_matches_comp3(5,{1,40},{30,1000}), + ?line erts_debug:set_internal_state(available_internal_state,true), + ?line io:format("oldlimit: ~p~n",[ erts_debug:set_internal_state(binary_loop_limit,100)]), + ?line do_random_match_comp(5000,{1,40},{30,1000}), + ?line do_random_matches_comp3(5,{1,40},{30,1000}), + ?line io:format("limit was: ~p~n",[ erts_debug:set_internal_state(binary_loop_limit,default)]), + ?line erts_debug:set_internal_state(available_internal_state,false), + ok. + +random_ref_sr_comp(doc) -> + ["Test pseudorandomly generated cases against reference imlementation of split and replace"]; +random_ref_sr_comp(Config) when is_list(Config) -> + ?line put(success_counter,0), + ?line random:seed({1271,769940,559934}), + ?line do_random_split_comp(5000,{1,40},{30,1000}), + io:format("Number of successes: ~p~n",[get(success_counter)]), + ?line do_random_replace_comp(5000,{1,40},{30,1000}), + io:format("Number of successes: ~p~n",[get(success_counter)]), + ?line do_random_split_comp2(5000,{1,40},{30,1000}), + io:format("Number of successes: ~p~n",[get(success_counter)]), + ?line do_random_replace_comp2(5000,{1,40},{30,1000}), + io:format("Number of successes: ~p~n",[get(success_counter)]), + ok. +random_ref_fla_comp(doc) -> + ["Test pseudorandomly generated cases against reference imlementation of split and replace"]; +random_ref_fla_comp(Config) when is_list(Config) -> + ?line put(success_counter,0), + ?line random:seed({1271,769940,559934}), + ?line do_random_first_comp(5000,{1,1000}), + ?line do_random_last_comp(5000,{1,1000}), + ?line do_random_at_comp(5000,{1,1000}), + io:format("Number of successes: ~p~n",[get(success_counter)]), + ok. + +do_random_first_comp(0,_) -> + ok; +do_random_first_comp(N,Range) -> + S = random_string(Range), + A = ?MASK_ERROR(binref:first(S)), + B = ?MASK_ERROR(binary:first(S)), + C = ?MASK_ERROR(binary:first(make_unaligned(S))), + case {(A =:= B), (B =:= C)} of + {true,true} -> + do_random_first_comp(N-1,Range); + _ -> + io:format("Failed to pick first of ~s~n", + [S]), + io:format("A:~p,~nB:~p,~n,C:~p.~n", + [A,B,C]), + exit(mismatch) + end. + +do_random_last_comp(0,_) -> + ok; +do_random_last_comp(N,Range) -> + S = random_string(Range), + A = ?MASK_ERROR(binref:last(S)), + B = ?MASK_ERROR(binary:last(S)), + C = ?MASK_ERROR(binary:last(make_unaligned(S))), + case {(A =:= B), (B =:= C)} of + {true,true} -> + do_random_last_comp(N-1,Range); + _ -> + io:format("Failed to pick last of ~s~n", + [S]), + io:format("A:~p,~nB:~p,~n,C:~p.~n", + [A,B,C]), + exit(mismatch) + end. +do_random_at_comp(0,_) -> + ok; +do_random_at_comp(N,{Min,Max}=Range) -> + S = random_string(Range), + XMax = Min + ((Max - Min) * 3) div 4, + Pos = random_length({Min,XMax}), %% some out of range + A = ?MASK_ERROR(binref:at(S,Pos)), + B = ?MASK_ERROR(binary:at(S,Pos)), + C = ?MASK_ERROR(binary:at(make_unaligned(S),Pos)), + if + A =/= badarg -> + put(success_counter,get(success_counter)+1); + true -> + ok + end, + case {(A =:= B), (B =:= C)} of + {true,true} -> + do_random_at_comp(N-1,Range); + _ -> + io:format("Failed to pick last of ~s~n", + [S]), + io:format("A:~p,~nB:~p,~n,C:~p.~n", + [A,B,C]), + exit(mismatch) + end. + +do_random_matches_comp(0,_,_) -> + ok; +do_random_matches_comp(N,NeedleRange,HaystackRange) -> + NumNeedles = element(2,HaystackRange) div element(2,NeedleRange), + Needles = [random_string(NeedleRange) || + _ <- lists:duplicate(NumNeedles,a)], + Haystack = random_string(HaystackRange), + true = do_matches_comp(Needles,Haystack), + do_random_matches_comp(N-1,NeedleRange,HaystackRange). + +do_random_matches_comp2(0,_,_) -> + ok; +do_random_matches_comp2(N,NeedleRange,HaystackRange) -> + NumNeedles = element(2,HaystackRange) div element(2,NeedleRange), + Haystack = random_string(HaystackRange), + Needles = [random_substring(NeedleRange,Haystack) || + _ <- lists:duplicate(NumNeedles,a)], + true = do_matches_comp(Needles,Haystack), + do_random_matches_comp2(N-1,NeedleRange,HaystackRange). + +do_random_matches_comp3(0,_,_) -> + ok; +do_random_matches_comp3(N,NeedleRange,HaystackRange) -> + NumNeedles = element(2,HaystackRange) div element(2,NeedleRange), + Haystack = random_string(HaystackRange), + Needles = [random_substring(NeedleRange,Haystack) || + _ <- lists:duplicate(NumNeedles,a)], + RefRes = binref:matches(Haystack,Needles), + true = do_matches_comp_loop(10000,Needles,Haystack, RefRes), + do_random_matches_comp3(N-1,NeedleRange,HaystackRange). + +do_matches_comp_loop(0,_,_,_) -> + true; +do_matches_comp_loop(N, Needles, Haystack0,RR) -> + DummySize=N*8, + Haystack1 = <<0:DummySize,Haystack0/binary>>, + RR1=[{X+N,Y} || {X,Y} <- RR], + true = do_matches_comp2(Needles,Haystack1,RR1), + Haystack2 = <<Haystack0/binary,Haystack1/binary>>, + RR2 = RR ++ [{X2+N+byte_size(Haystack0),Y2} || {X2,Y2} <- RR], + true = do_matches_comp2(Needles,Haystack2,RR2), + do_matches_comp_loop(N-1, Needles, Haystack0,RR). + + +do_matches_comp2(N,H,A) -> + C = ?MASK_ERROR(binary:matches(H,N)), + case (A =:= C) of + true -> + true; + _ -> + io:format("Failed to match ~p (needle) against ~s (haystack)~n", + [N,H]), + io:format("A:~p,~n,C:~p.~n", + [A,C]), + exit(mismatch) + end. +do_matches_comp(N,H) -> + A = ?MASK_ERROR(binref:matches(H,N)), + B = ?MASK_ERROR(binref:matches(H,binref:compile_pattern(N))), + C = ?MASK_ERROR(binary:matches(H,N)), + D = ?MASK_ERROR(binary:matches(make_unaligned(H), + binary:compile_pattern([make_unaligned2(X) || X <- N]))), + if + A =/= nomatch -> + put(success_counter,get(success_counter)+1); + true -> + ok + end, + case {(A =:= B), (B =:= C),(C =:= D)} of + {true,true,true} -> + true; + _ -> + io:format("Failed to match ~p (needle) against ~s (haystack)~n", + [N,H]), + io:format("A:~p,~nB:~p,~n,C:~p,~n,D:~p.~n", + [A,B,C,D]), + exit(mismatch) + end. + +do_random_match_comp(0,_,_) -> + ok; +do_random_match_comp(N,NeedleRange,HaystackRange) -> + Needle = random_string(NeedleRange), + Haystack = random_string(HaystackRange), + true = do_match_comp(Needle,Haystack), + do_random_match_comp(N-1,NeedleRange,HaystackRange). + +do_random_match_comp2(0,_,_) -> + ok; +do_random_match_comp2(N,NeedleRange,HaystackRange) -> + Haystack = random_string(HaystackRange), + Needle = random_substring(NeedleRange,Haystack), + true = do_match_comp(Needle,Haystack), + do_random_match_comp2(N-1,NeedleRange,HaystackRange). + +do_random_match_comp3(0,_,_) -> + ok; +do_random_match_comp3(N,NeedleRange,HaystackRange) -> + NumNeedles = element(2,HaystackRange) div element(2,NeedleRange), + Haystack = random_string(HaystackRange), + Needles = [random_substring(NeedleRange,Haystack) || + _ <- lists:duplicate(NumNeedles,a)], + true = do_match_comp3(Needles,Haystack), + do_random_match_comp3(N-1,NeedleRange,HaystackRange). + +do_random_match_comp4(0,_,_) -> + ok; +do_random_match_comp4(N,NeedleRange,HaystackRange) -> + NumNeedles = element(2,HaystackRange) div element(2,NeedleRange), + Haystack = random_string(HaystackRange), + Needles = [random_string(NeedleRange) || + _ <- lists:duplicate(NumNeedles,a)], + true = do_match_comp3(Needles,Haystack), + do_random_match_comp4(N-1,NeedleRange,HaystackRange). + +do_match_comp(N,H) -> + A = ?MASK_ERROR(binref:match(H,N)), + B = ?MASK_ERROR(binref:match(H,binref:compile_pattern([N]))), + C = ?MASK_ERROR(binary:match(make_unaligned(H),N)), + D = ?MASK_ERROR(binary:match(H,binary:compile_pattern([N]))), + E = ?MASK_ERROR(binary:match(H,binary:compile_pattern(make_unaligned(N)))), + if + A =/= nomatch -> + put(success_counter,get(success_counter)+1); + true -> + ok + end, + case {(A =:= B), (B =:= C),(C =:= D),(D =:= E)} of + {true,true,true,true} -> + true; + _ -> + io:format("Failed to match ~s (needle) against ~s (haystack)~n", + [N,H]), + io:format("A:~p,~nB:~p,~n,C:~p,~n,D:~p,E:~p.~n", + [A,B,C,D,E]), + exit(mismatch) + end. + +do_match_comp3(N,H) -> + A = ?MASK_ERROR(binref:match(H,N)), + B = ?MASK_ERROR(binref:match(H,binref:compile_pattern(N))), + C = ?MASK_ERROR(binary:match(H,N)), + D = ?MASK_ERROR(binary:match(H,binary:compile_pattern(N))), + if + A =/= nomatch -> + put(success_counter,get(success_counter)+1); + true -> + ok + end, + case {(A =:= B), (B =:= C),(C =:= D)} of + {true,true,true} -> + true; + _ -> + io:format("Failed to match ~s (needle) against ~s (haystack)~n", + [N,H]), + io:format("A:~p,~nB:~p,~n,C:~p,~n,D:~p.~n", + [A,B,C,D]), + exit(mismatch) + end. + +do_random_split_comp(0,_,_) -> + ok; +do_random_split_comp(N,NeedleRange,HaystackRange) -> + Haystack = random_string(HaystackRange), + Needle = random_substring(NeedleRange,Haystack), + true = do_split_comp(Needle,Haystack,[]), + true = do_split_comp(Needle,Haystack,[global]), + true = do_split_comp(Needle,Haystack,[global,trim]), + do_random_split_comp(N-1,NeedleRange,HaystackRange). +do_random_split_comp2(0,_,_) -> + ok; +do_random_split_comp2(N,NeedleRange,HaystackRange) -> + NumNeedles = element(2,HaystackRange) div element(2,NeedleRange), + Haystack = random_string(HaystackRange), + Needles = [random_substring(NeedleRange,Haystack) || + _ <- lists:duplicate(NumNeedles,a)], + true = do_split_comp(Needles,Haystack,[]), + true = do_split_comp(Needles,Haystack,[global]), + do_random_split_comp2(N-1,NeedleRange,HaystackRange). + +do_split_comp(N,H,Opts) -> + A = ?MASK_ERROR(binref:split(H,N,Opts)), + D = ?MASK_ERROR(binary:split(H,binary:compile_pattern(N),Opts)), + if + (A =/= [N]) and is_list(A) -> + put(success_counter,get(success_counter)+1); + true -> + ok + end, + case (A =:= D) of + true -> + true; + _ -> + io:format("Failed to split ~n~p ~n(haystack) with ~n~p ~n(needle) " + "~nand options ~p~n", + [H,N,Opts]), + io:format("A:~p,D:~p.~n", + [A,D]), + exit(mismatch) + end. + +do_random_replace_comp(0,_,_) -> + ok; +do_random_replace_comp(N,NeedleRange,HaystackRange) -> + Haystack = random_string(HaystackRange), + Needle = random_substring(NeedleRange,Haystack), + Repl = random_string(NeedleRange), + Insertat = random_length(NeedleRange), %Sometimes larger than Repl + true = do_replace_comp(Needle,Haystack,Repl,[]), + true = do_replace_comp(Needle,Haystack,Repl,[global]), + true = do_replace_comp(Needle,Haystack,Repl, + [global,{insert_replaced,Insertat}]), + do_random_replace_comp(N-1,NeedleRange,HaystackRange). +do_random_replace_comp2(0,_,_) -> + ok; +do_random_replace_comp2(N,NeedleRange,HaystackRange) -> + NumNeedles = element(2,HaystackRange) div element(2,NeedleRange), + Haystack = random_string(HaystackRange), + Needles = [random_substring(NeedleRange,Haystack) || + _ <- lists:duplicate(NumNeedles,a)], + Repl = random_string(NeedleRange), + Insertat = random_length(NeedleRange), %Sometimes larger than Repl + true = do_replace_comp(Needles,Haystack,Repl,[]), + true = do_replace_comp(Needles,Haystack,Repl,[global]), + true = do_replace_comp(Needles,Haystack,Repl, + [global,{insert_replaced,Insertat}]), + do_random_replace_comp2(N-1,NeedleRange,HaystackRange). + +do_replace_comp(N,H,R,Opts) -> + A = ?MASK_ERROR(binref:replace(H,N,R,Opts)), + D = ?MASK_ERROR(binary:replace(H,binary:compile_pattern(N),R,Opts)), + if + (A =/= N) and is_binary(A) -> + put(success_counter,get(success_counter)+1); + true -> + ok + end, + case (A =:= D) of + true -> + true; + _ -> + io:format("Failed to replace ~s (haystack) by ~s (needle) " + "inserting ~s (replacement) and options ~p~n", + [H,N,R,Opts]), + io:format("A:~p,D:~p.~n", + [A,D]), + exit(mismatch) + end. + +one_random_number(N) -> + M = ((N - 1) rem 10) + 1, + element(M,{$0,$1,$2,$3,$4,$5,$6,$7,$8,$9}). + +one_random(N) -> + M = ((N - 1) rem 68) + 1, + element(M,{$a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t, + $u,$v,$w,$x,$y,$z,$�,$�,$�,$A,$B,$C,$D,$E,$F,$G,$H, + $I,$J,$K,$L,$M,$N,$O,$P,$Q,$R,$S,$T,$U,$V,$W,$X,$Y,$Z,$�, + $�,$�,$0,$1,$2,$3,$4,$5,$6,$7,$8,$9}). + +random_number({Min,Max}) -> % Min and Max are *length* of number in + % decimal positions + X = random:uniform(Max - Min + 1) + Min - 1, + list_to_integer([one_random_number(random:uniform(10)) || _ <- lists:seq(1,X)]). + + +random_length({Min,Max}) -> + random:uniform(Max - Min + 1) + Min - 1. +random_string({Min,Max}) -> + X = random:uniform(Max - Min + 1) + Min - 1, + list_to_binary([one_random(random:uniform(68)) || _ <- lists:seq(1,X)]). +random_substring({Min,Max},Hay) -> + X = random:uniform(Max - Min + 1) + Min - 1, + Y = byte_size(Hay), + Z = if + X > Y -> Y; + true -> X + end, + PMax = Y - Z, + Pos = random:uniform(PMax + 1) - 1, + <<_:Pos/binary,Res:Z/binary,_/binary>> = Hay, + Res. + +mask_error({'EXIT',{Err,_}}) -> + Err; +mask_error(Else) -> + Else. + +make_unaligned(Bin0) when is_binary(Bin0) -> + Bin1 = <<0:3,Bin0/binary,31:5>>, + Sz = byte_size(Bin0), + <<0:3,Bin:Sz/binary,31:5>> = id(Bin1), + Bin. +make_unaligned2(Bin0) when is_binary(Bin0) -> + Bin1 = <<31:5,Bin0/binary,0:3>>, + Sz = byte_size(Bin0), + <<31:5,Bin:Sz/binary,0:3>> = id(Bin1), + Bin. + +id(I) -> I. diff --git a/lib/stdlib/test/binref.erl b/lib/stdlib/test/binref.erl new file mode 100644 index 0000000000..6d96736ef3 --- /dev/null +++ b/lib/stdlib/test/binref.erl @@ -0,0 +1,588 @@ +-module(binref). + +-export([compile_pattern/1,match/2,match/3,matches/2,matches/3, + split/2,split/3,replace/3,replace/4,first/1,last/1,at/2, + part/2,part/3,copy/1,copy/2,encode_unsigned/1,encode_unsigned/2, + decode_unsigned/1,decode_unsigned/2,referenced_byte_size/1, + longest_common_prefix/1,longest_common_suffix/1,bin_to_list/1, + bin_to_list/2,bin_to_list/3,list_to_bin/1]). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% compile_pattern, a dummy +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +compile_pattern(Pattern) when is_binary(Pattern) -> + {[Pattern]}; +compile_pattern(Pattern) -> + try + [ true = is_binary(P) || P <- Pattern ], + {Pattern} + catch + _:_ -> + erlang:error(badarg) + end. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% match and matches +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +match(H,N) -> + match(H,N,[]). +match(Haystack,Needle,Options) when is_binary(Needle) -> + match(Haystack,[Needle],Options); +match(Haystack,{Needles},Options) -> + match(Haystack,Needles,Options); +match(Haystack,Needles,Options) -> + try + true = is_binary(Haystack) and is_list(Needles), % badarg, not function_clause + case get_opts_match(Options,nomatch) of + nomatch -> + mloop(Haystack,Needles); + {A,B} when B > 0 -> + <<_:A/binary,SubStack:B/binary,_/binary>> = Haystack, + mloop(SubStack,Needles,A,B+A); + {A,B} when B < 0 -> + Start = A + B, + Len = -B, + <<_:Start/binary,SubStack:Len/binary,_/binary>> = Haystack, + mloop(SubStack,Needles,Start,Len+Start); + _ -> + nomatch + end + catch + _:_ -> + erlang:error(badarg) + end. +matches(H,N) -> + matches(H,N,[]). +matches(Haystack,Needle,Options) when is_binary(Needle) -> + matches(Haystack,[Needle],Options); +matches(Haystack,{Needles},Options) -> + matches(Haystack,Needles,Options); +matches(Haystack,Needles,Options) -> + try + true = is_binary(Haystack) and is_list(Needles), % badarg, not function_clause + case get_opts_match(Options,nomatch) of + nomatch -> + msloop(Haystack,Needles); + {A,B} when B > 0 -> + <<_:A/binary,SubStack:B/binary,_/binary>> = Haystack, + msloop(SubStack,Needles,A,B+A); + {A,B} when B < 0 -> + Start = A + B, + Len = -B, + <<_:Start/binary,SubStack:Len/binary,_/binary>> = Haystack, + msloop(SubStack,Needles,Start,Len+Start); + _ -> + [] + end + catch + _:_ -> + erlang:error(badarg) + end. + +mloop(Haystack,Needles) -> + mloop(Haystack,Needles,0,byte_size(Haystack)). + +mloop(_Haystack,_Needles,N,M) when N >= M -> + nomatch; +mloop(Haystack,Needles,N,M) -> + case mloop2(Haystack,Needles,N,nomatch) of + nomatch -> + % Not found + <<_:8,NewStack/binary>> = Haystack, + mloop(NewStack,Needles,N+1,M); + {N,Len} -> + {N,Len} + end. + +msloop(Haystack,Needles) -> + msloop(Haystack,Needles,0,byte_size(Haystack)). + +msloop(_Haystack,_Needles,N,M) when N >= M -> + []; +msloop(Haystack,Needles,N,M) -> + case mloop2(Haystack,Needles,N,nomatch) of + nomatch -> + % Not found + <<_:8,NewStack/binary>> = Haystack, + msloop(NewStack,Needles,N+1,M); + {N,Len} -> + NewN = N+Len, + if + NewN >= M -> + [{N,Len}]; + true -> + <<_:Len/binary,NewStack/binary>> = Haystack, + [{N,Len} | msloop(NewStack,Needles,NewN,M)] + end + end. + +mloop2(_Haystack,[],_N,Res) -> + Res; +mloop2(Haystack,[Needle|Tail],N,Candidate) -> + NS = byte_size(Needle), + case Haystack of + <<Needle:NS/binary,_/binary>> -> + NewCandidate = case Candidate of + nomatch -> + {N,NS}; + {N,ONS} when ONS < NS -> + {N,NS}; + Better -> + Better + end, + mloop2(Haystack,Tail,N,NewCandidate); + _ -> + mloop2(Haystack,Tail,N,Candidate) + end. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% split +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +split(H,N) -> + split(H,N,[]). +split(Haystack,{Needles},Options) -> + split(Haystack, Needles, Options); +split(Haystack,Needles0,Options) -> + try + Needles = if + is_list(Needles0) -> + Needles0; + is_binary(Needles0) -> + [Needles0]; + true -> + exit(badtype) + end, + {Part,Global,Trim} = get_opts_split(Options,{nomatch,false,false}), + {Start,End,NewStack} = + case Part of + nomatch -> + {0,byte_size(Haystack),Haystack}; + {A,B} when B >= 0 -> + <<_:A/binary,SubStack:B/binary,_/binary>> = Haystack, + {A,A+B,SubStack}; + {A,B} when B < 0 -> + S = A + B, + L = -B, + <<_:S/binary,SubStack:L/binary,_/binary>> = Haystack, + {S,S+L,SubStack} + end, + MList = if + Global -> + msloop(NewStack,Needles,Start,End); + true -> + case mloop(NewStack,Needles,Start,End) of + nomatch -> + []; + X -> + [X] + end + end, + do_split(Haystack,MList,0,Trim) + catch + _:_ -> + erlang:error(badarg) + end. + +do_split(H,[],N,true) when N >= byte_size(H) -> + []; +do_split(H,[],N,_) -> + [part(H,{N,byte_size(H)-N})]; +do_split(H,[{A,B}|T],N,Trim) -> + case part(H,{N,A-N}) of + <<>> -> + Rest = do_split(H,T,A+B,Trim), + case {Trim, Rest} of + {true,[]} -> + []; + _ -> + [<<>> | Rest] + end; + Oth -> + [Oth | do_split(H,T,A+B,Trim)] + end. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% replace +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +replace(H,N,R) -> + replace(H,N,R,[]). +replace(Haystack,{Needles},Replacement,Options) -> + replace(Haystack,Needles,Replacement,Options); + +replace(Haystack,Needles0,Replacement,Options) -> + try + Needles = if + is_list(Needles0) -> + Needles0; + is_binary(Needles0) -> + [Needles0]; + true -> + exit(badtype) + end, + true = is_binary(Replacement), % Make badarg instead of function clause + {Part,Global,Insert} = get_opts_replace(Options,{nomatch,false,[]}), + {Start,End,NewStack} = + case Part of + nomatch -> + {0,byte_size(Haystack),Haystack}; + {A,B} when B >= 0 -> + <<_:A/binary,SubStack:B/binary,_/binary>> = Haystack, + {A,A+B,SubStack}; + {A,B} when B < 0 -> + S = A + B, + L = -B, + <<_:S/binary,SubStack:L/binary,_/binary>> = Haystack, + {S,S+L,SubStack} + end, + MList = if + Global -> + msloop(NewStack,Needles,Start,End); + true -> + case mloop(NewStack,Needles,Start,End) of + nomatch -> + []; + X -> + [X] + end + end, + ReplList = case Insert of + [] -> + Replacement; + Y when is_integer(Y) -> + splitat(Replacement,0,[Y]); + Li when is_list(Li) -> + splitat(Replacement,0,lists:sort(Li)) + end, + erlang:iolist_to_binary(do_replace(Haystack,MList,ReplList,0)) + catch + _:_ -> + erlang:error(badarg) + end. + + +do_replace(H,[],_,N) -> + [part(H,{N,byte_size(H)-N})]; +do_replace(H,[{A,B}|T],Replacement,N) -> + [part(H,{N,A-N}), + if + is_list(Replacement) -> + do_insert(Replacement, part(H,{A,B})); + true -> + Replacement + end + | do_replace(H,T,Replacement,A+B)]. + +do_insert([X],_) -> + [X]; +do_insert([H|T],R) -> + [H,R|do_insert(T,R)]. + +splitat(H,N,[]) -> + [part(H,{N,byte_size(H)-N})]; +splitat(H,N,[I|T]) -> + [part(H,{N,I-N})|splitat(H,I,T)]. + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% first, last and at +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +first(Subject) -> + try + <<A:8,_/binary>> = Subject, + A + catch + _:_ -> + erlang:error(badarg) + end. + +last(Subject) -> + try + N = byte_size(Subject) - 1, + <<_:N/binary,A:8>> = Subject, + A + catch + _:_ -> + erlang:error(badarg) + end. + +at(Subject,X) -> + try + <<_:X/binary,A:8,_/binary>> = Subject, + A + catch + _:_ -> + erlang:error(badarg) + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% bin_to_list +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +bin_to_list(Subject) -> + try + binary_to_list(Subject) + catch + _:_ -> + erlang:error(badarg) + end. + +bin_to_list(Subject,T) -> + try + {A0,B0} = T, + {A,B} = if + B0 < 0 -> + {A0+B0,-B0}; + true -> + {A0,B0} + end, + binary_to_list(Subject,A+1,A+B) + catch + _:_ -> + erlang:error(badarg) + end. + +bin_to_list(Subject,A,B) -> + try + bin_to_list(Subject,{A,B}) + catch + _:_ -> + erlang:error(badarg) + end. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% list_to_bin +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +list_to_bin(List) -> + try + erlang:list_to_binary(List) + catch + _:_ -> + erlang:error(badarg) + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% longest_common_prefix +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +longest_common_prefix(LB) -> + try + true = is_list(LB) and (length(LB) > 0), % Make badarg instead of function clause + do_longest_common_prefix(LB,0) + catch + _:_ -> + erlang:error(badarg) + end. + +do_longest_common_prefix(LB,X) -> + case do_lcp(LB,X,no) of + true -> + do_longest_common_prefix(LB,X+1); + false -> + X + end. +do_lcp([],_,_) -> + true; +do_lcp([Bin|_],X,_) when byte_size(Bin) =< X -> + false; +do_lcp([Bin|T],X,no) -> + Ch = at(Bin,X), + do_lcp(T,X,Ch); +do_lcp([Bin|T],X,Ch) -> + Ch2 = at(Bin,X), + if + Ch =:= Ch2 -> + do_lcp(T,X,Ch); + true -> + false + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% longest_common_suffix +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +longest_common_suffix(LB) -> + try + true = is_list(LB) and (length(LB) > 0), % Make badarg instead of function clause + do_longest_common_suffix(LB,0) + catch + _:_ -> + erlang:error(badarg) + end. + +do_longest_common_suffix(LB,X) -> + case do_lcs(LB,X,no) of + true -> + do_longest_common_suffix(LB,X+1); + false -> + X + end. +do_lcs([],_,_) -> + true; +do_lcs([Bin|_],X,_) when byte_size(Bin) =< X -> + false; +do_lcs([Bin|T],X,no) -> + Ch = at(Bin,byte_size(Bin) - 1 - X), + do_lcs(T,X,Ch); +do_lcs([Bin|T],X,Ch) -> + Ch2 = at(Bin,byte_size(Bin) - 1 - X), + if + Ch =:= Ch2 -> + do_lcs(T,X,Ch); + true -> + false + end. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% part +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +part(Subject,Part) -> + try + do_part(Subject,Part) + catch + _:_ -> + erlang:error(badarg) + end. + +part(Subject,Pos,Len) -> + part(Subject,{Pos,Len}). + +do_part(Bin,{A,B}) when B >= 0 -> + <<_:A/binary,Sub:B/binary,_/binary>> = Bin, + Sub; +do_part(Bin,{A,B}) when B < 0 -> + S = A + B, + L = -B, + <<_:S/binary,Sub:L/binary,_/binary>> = Bin, + Sub. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% copy +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +copy(Subject) -> + copy(Subject,1). +copy(Subject,N) -> + try + true = is_integer(N) and (N >= 0) and is_binary(Subject), % Badarg, not function clause + erlang:list_to_binary(lists:duplicate(N,Subject)) + catch + _:_ -> + erlang:error(badarg) + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% encode_unsigned +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +encode_unsigned(Unsigned) -> + encode_unsigned(Unsigned,big). +encode_unsigned(Unsigned,Endian) -> + try + true = is_integer(Unsigned) and (Unsigned >= 0), + if + Unsigned =:= 0 -> + <<0>>; + true -> + case Endian of + big -> + list_to_binary(do_encode(Unsigned,[])); + little -> + list_to_binary(do_encode_r(Unsigned)) + end + end + catch + _:_ -> + erlang:error(badarg) + end. + +do_encode(0,L) -> + L; +do_encode(N,L) -> + Byte = N band 255, + NewN = N bsr 8, + do_encode(NewN,[Byte|L]). + +do_encode_r(0) -> + []; +do_encode_r(N) -> + Byte = N band 255, + NewN = N bsr 8, + [Byte|do_encode_r(NewN)]. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% decode_unsigned +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +decode_unsigned(Subject) -> + decode_unsigned(Subject,big). + +decode_unsigned(Subject,Endian) -> + try + true = is_binary(Subject), + case Endian of + big -> + do_decode(Subject,0); + little -> + do_decode_r(Subject,0) + end + catch + _:_ -> + erlang:error(badarg) + end. + +do_decode(<<>>,N) -> + N; +do_decode(<<X:8,Bin/binary>>,N) -> + do_decode(Bin,(N bsl 8) bor X). + +do_decode_r(<<>>,N) -> + N; +do_decode_r(Bin,N) -> + Sz = byte_size(Bin) - 1, + <<NewBin:Sz/binary,X>> = Bin, + do_decode_r(NewBin, (N bsl 8) bor X). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% referenced_byte_size cannot +%% be implemented in pure +%% erlang +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +referenced_byte_size(Bin) when is_binary(Bin) -> + erlang:error(not_implemented); +referenced_byte_size(_) -> + erlang:error(badarg). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Simple helper functions +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Option "parsing" +get_opts_match([],Part) -> + Part; +get_opts_match([{scope,{A,B}} | T],_Part) -> + get_opts_match(T,{A,B}); +get_opts_match(_,_) -> + throw(badopt). + +get_opts_split([],{Part,Global,Trim}) -> + {Part,Global,Trim}; +get_opts_split([{scope,{A,B}} | T],{_Part,Global,Trim}) -> + get_opts_split(T,{{A,B},Global,Trim}); +get_opts_split([global | T],{Part,_Global,Trim}) -> + get_opts_split(T,{Part,true,Trim}); +get_opts_split([trim | T],{Part,Global,_Trim}) -> + get_opts_split(T,{Part,Global,true}); +get_opts_split(_,_) -> + throw(badopt). + +get_opts_replace([],{Part,Global,Insert}) -> + {Part,Global,Insert}; +get_opts_replace([{scope,{A,B}} | T],{_Part,Global,Insert}) -> + get_opts_replace(T,{{A,B},Global,Insert}); +get_opts_replace([global | T],{Part,_Global,Insert}) -> + get_opts_replace(T,{Part,true,Insert}); +get_opts_replace([{insert_replaced,N} | T],{Part,Global,_Insert}) -> + get_opts_replace(T,{Part,Global,N}); +get_opts_replace(_,_) -> + throw(badopt). diff --git a/lib/stdlib/test/dummy1_h.erl b/lib/stdlib/test/dummy1_h.erl index 4377d774a3..5b503d5984 100644 --- a/lib/stdlib/test/dummy1_h.erl +++ b/lib/stdlib/test/dummy1_h.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(dummy1_h). @@ -21,7 +21,7 @@ %% Test event handler for gen_event_SUITE.erl -export([init/1, handle_event/2, handle_call/2, handle_info/2, - terminate/2]). + terminate/2, format_status/2]). init(make_error) -> {error, my_error}; @@ -67,4 +67,5 @@ terminate(remove_handler, Parent) -> terminate(_Reason, _State) -> ok. - +format_status(_Opt, [_PDict, _State]) -> + "dummy1_h handler state". diff --git a/lib/stdlib/test/epp_SUITE.erl b/lib/stdlib/test/epp_SUITE.erl index 9a3ae0baf5..e31dfdd764 100644 --- a/lib/stdlib/test/epp_SUITE.erl +++ b/lib/stdlib/test/epp_SUITE.erl @@ -19,11 +19,12 @@ -module(epp_SUITE). -export([all/1]). --export([rec_1/1, predef_mac/1, +-export([rec_1/1, predef_mac/1, upcase_mac/1, upcase_mac_1/1, upcase_mac_2/1, variable/1, variable_1/1, otp_4870/1, otp_4871/1, otp_5362/1, pmod/1, not_circular/1, skip_header/1, otp_6277/1, otp_7702/1, - otp_8130/1, overload_mac/1, otp_8388/1]). + otp_8130/1, overload_mac/1, otp_8388/1, otp_8470/1, otp_8503/1, + otp_8562/1, otp_8665/1]). -export([epp_parse_erl_form/2]). @@ -38,7 +39,7 @@ -define(config(A,B),config(A,B)). %% -define(t, test_server). -define(t, io). -config(priv_dir, _) -> +config(priv_dir, _) -> filename:absname("./epp_SUITE_priv"); config(data_dir, _) -> filename:absname("./epp_SUITE_data"). @@ -63,7 +64,7 @@ all(doc) -> all(suite) -> [rec_1, upcase_mac, predef_mac, variable, otp_4870, otp_4871, otp_5362, pmod, not_circular, skip_header, otp_6277, otp_7702, otp_8130, - overload_mac, otp_8388]. + overload_mac, otp_8388, otp_8470, otp_8503, otp_8562, otp_8665]. rec_1(doc) -> ["Recursive macros hang or crash epp (OTP-1398)."]; @@ -191,7 +192,7 @@ variable_1(Config) when is_list(Config) -> %% variable_1.erl includes variable_1_include.hrl and %% variable_1_include_dir.hrl. ?line {ok, List} = epp:parse_file(File, [], []), - ?line {value, {attribute,_,a,{value1,value2}}} = + ?line {value, {attribute,_,a,{value1,value2}}} = lists:keysearch(a,3,List), ok. @@ -218,13 +219,13 @@ otp_4871(Config) when is_list(Config) -> %% Testing crash in erl_scan. Unfortunately there currently is %% no known way to crash erl_scan so it is emulated by killing the %% file io server. This assumes lots of things about how - %% the processes are started and how monitors are set up, + %% the processes are started and how monitors are set up, %% so there are some sanity checks before killing. ?line {ok,Epp} = epp:open(File, []), timer:sleep(1), ?line {current_function,{epp,_,_}} = process_info(Epp, current_function), ?line {monitored_by,[Io]} = process_info(Epp, monitored_by), - ?line {current_function,{file_io_server,_,_}} = + ?line {current_function,{file_io_server,_,_}} = process_info(Io, current_function), ?line exit(Io, emulate_crash), timer:sleep(1), @@ -301,7 +302,7 @@ otp_5362(Config) when is_list(Config) -> Back_hrl = [<<" -file(\"">>,File_Back,<<"\", 2). ">>], - + ?line ok = file:write_file(File_Back, Back), ?line ok = file:write_file(File_Back_hrl, list_to_binary(Back_hrl)), @@ -332,7 +333,7 @@ otp_5362(Config) when is_list(Config) -> ?line ok = file:write_file(File_Change, list_to_binary(Change)), - ?line {ok, change_5362, ChangeWarnings} = + ?line {ok, change_5362, ChangeWarnings} = compile:file(File_Change, Copts), ?line true = message_compare( [{File_Change,[{{1002,21},erl_lint,{unused_var,'B'}}]}, @@ -440,9 +441,9 @@ skip_header(Config) when is_list(Config) -> that should be skipped -module(epp_test_skip_header). -export([main/1]). - + main(_) -> ?MODULE. - + ">>), ?line {ok, Fd} = file:open(File, [read]), ?line io:get_line(Fd, ''), @@ -493,9 +494,9 @@ otp_7702(Config) when is_list(Config) -> t() -> ?RECEIVE(foo, bar).">>, ?line ok = file:write_file(File, Contents), - ?line {ok, file_7702, []} = + ?line {ok, file_7702, []} = compile:file(File, [debug_info,return,{outdir,Dir}]), - + BeamFile = filename:join(Dir, "file_7702.beam"), {ok, AC} = beam_lib:chunks(BeamFile, [abstract_code]), @@ -505,7 +506,7 @@ otp_7702(Config) when is_list(Config) -> L end, Forms2 = [erl_lint:modify_line(Form, Fun) || Form <- Forms], - ?line + ?line [{attribute,1,file,_}, _, _, @@ -616,9 +617,9 @@ otp_8130(Config) when is_list(Config) -> "t() -> 14 = (#file_info{size = 14})#file_info.size, ok.\n">>, ok}, - {otp_8130_7, + {otp_8130_7_new, <<"-record(b, {b}).\n" - "-define(A, {{a,#b.b.\n" + "-define(A, {{a,#b.b).\n" "t() -> {{a,2}} = ?A}}, ok.">>, ok}, @@ -636,7 +637,7 @@ otp_8130(Config) when is_list(Config) -> ], ?line [] = run(Config, Ts), - + Cs = [{otp_8130_c1, <<"-define(M1(A), if\n" "A =:= 1 -> B;\n" @@ -680,7 +681,7 @@ otp_8130(Config) when is_list(Config) -> <<"\n-include_lib(\"$apa/foo.hrl\").\n">>, {errors,[{{2,2},epp,{include,lib,"$apa/foo.hrl"}}],[]}}, - + {otp_8130_c9, <<"-define(S, ?S).\n" "t() -> ?S.\n">>, @@ -750,7 +751,14 @@ otp_8130(Config) when is_list(Config) -> {otp_8130_c24, <<"\n-include(\"no such file.erl\").\n">>, - {errors,[{{2,2},epp,{include,file,"no such file.erl"}}],[]}} + {errors,[{{2,2},epp,{include,file,"no such file.erl"}}],[]}}, + + {otp_8130_7, + <<"-record(b, {b}).\n" + "-define(A, {{a,#b.b.\n" + "t() -> {{a,2}} = ?A}}, ok.">>, + {errors,[{{2,20},epp,missing_parenthesis}, + {{3,19},epp,{undefined,'A',none}}],[]}} ], ?line [] = compile(Config, Cs), @@ -767,7 +775,7 @@ otp_8130(Config) when is_list(Config) -> ?line Dir = ?config(priv_dir, Config), ?line File = filename:join(Dir, "otp_8130.erl"), - ?line ok = file:write_file(File, + ?line ok = file:write_file(File, "-module(otp_8130).\n" "-define(a, 3.14).\n" "t() -> ?a.\n"), @@ -780,7 +788,7 @@ otp_8130(Config) when is_list(Config) -> ?line {eof,_} = epp:scan_erl_form(Epp), ?line ['BASE_MODULE','BASE_MODULE_STRING','BEAM','FILE','LINE', 'MACHINE','MODULE','MODULE_STRING',a] = macs(Epp), - ?line epp:close(Epp), + ?line epp:close(Epp), %% escript ModuleStr = "any_name", @@ -807,7 +815,7 @@ otp_8130(Config) when is_list(Config) -> PreDefMacros = [{a,1},a], ?line {error,{redefine,a}} = epp:open(File, [], PreDefMacros) end(), - + ?line {error,enoent} = epp:open("no such file", []), ?line {error,enoent} = epp:parse_file("no such file", [], []), @@ -933,7 +941,7 @@ ifdef(Config) -> <<"\n-if.\n" "-endif.\n">>, {errors,[{{2,2},epp,{'NYI','if'}}],[]}}, - + {define_c7, <<"-ifndef(a).\n" "-elif.\n" @@ -1047,13 +1055,13 @@ overload_mac(Config) when is_list(Config) -> "-undef(A).\n" "t1() -> ?A.\n", "t2() -> ?A(1).">>, - {errors,[{{4,9},epp,{undefined,'A', none}}, - {{5,9},epp,{undefined,'A', 1}}],[]}}, + {errors,[{{4,10},epp,{undefined,'A', none}}, + {{5,10},epp,{undefined,'A', 1}}],[]}}, %% cannot overload predefined macros {overload_mac_c2, <<"-define(MODULE(X), X).">>, - {errors,[{{1,9},epp,{redefine_predef,'MODULE'}}],[]}}, + {errors,[{{1,50},epp,{redefine_predef,'MODULE'}}],[]}}, %% cannot overload macros with same arity {overload_mac_c3, @@ -1120,25 +1128,87 @@ otp_8388(Config) when is_list(Config) -> {macro_1, <<"-define(m(A), A).\n" "t() -> ?m(,).\n">>, - {errors,[{{2,11},epp,{arg_error,m}}],[]}}, + {errors,[{{2,9},epp,{arg_error,m}}],[]}}, {macro_2, <<"-define(m(A), A).\n" "t() -> ?m(a,).\n">>, - {errors,[{{2,12},epp,{arg_error,m}}],[]}}, + {errors,[{{2,9},epp,{arg_error,m}}],[]}}, {macro_3, <<"-define(LINE, a).\n">>, - {errors,[{{1,9},epp,{redefine_predef,'LINE'}}],[]}}, + {errors,[{{1,50},epp,{redefine_predef,'LINE'}}],[]}}, {macro_4, <<"-define(A(B, C, D), {B,C,D}).\n" "t() -> ?A(a,,3).\n">>, - {errors,[{{2,8},epp,{mismatch,'A'}}],[]}}, + {errors,[{{2,9},epp,{mismatch,'A'}}],[]}}, {macro_5, <<"-define(Q, {?F0(), ?F1(,,4)}).\n">>, - {errors,[{{1,24},epp,{arg_error,'F1'}}],[]}} + {errors,[{{1,62},epp,{arg_error,'F1'}}],[]}}, + {macro_6, + <<"-define(FOO(X), ?BAR(X)).\n" + "-define(BAR(X), ?FOO(X)).\n" + "-undef(FOO).\n" + "test() -> ?BAR(1).\n">>, + {errors,[{{4,12},epp,{undefined,'FOO',1}}],[]}} ], ?line [] = compile(Config, Ts), ok. +otp_8470(doc) -> + ["OTP-8470. Bugfix (one request - two replies)."]; +otp_8470(suite) -> + []; +otp_8470(Config) when is_list(Config) -> + Dir = ?config(priv_dir, Config), + C = <<"-file(\"erl_parse.yrl\", 486).\n" + "-file(\"erl_parse.yrl\", 488).\n">>, + ?line File = filename:join(Dir, "otp_8470.erl"), + ?line ok = file:write_file(File, C), + ?line {ok, _List} = epp:parse_file(File, [], []), + file:delete(File), + ?line receive _ -> fail() after 0 -> ok end, + ok. + +otp_8503(doc) -> + ["OTP-8503. Record with no fields is considered typed."]; +otp_8503(suite) -> + []; +otp_8503(Config) when is_list(Config) -> + Dir = ?config(priv_dir, Config), + C = <<"-record(r, {}).">>, + ?line File = filename:join(Dir, "otp_8503.erl"), + ?line ok = file:write_file(File, C), + ?line {ok, List} = epp:parse_file(File, [], []), + ?line [_] = [F || {attribute,_,type,{{record,r},[],[]}}=F <- List], + file:delete(File), + ?line receive _ -> fail() after 0 -> ok end, + ok. + +otp_8562(doc) -> + ["OTP-8503. Record with no fields is considered typed."]; +otp_8562(suite) -> + []; +otp_8562(Config) when is_list(Config) -> + Cs = [{otp_8562, + <<"-define(P(), {a,b}.\n" + "-define(P3, .\n">>, + {errors,[{{1,60},epp,missing_parenthesis}, + {{2,13},epp,missing_parenthesis}], []}} + ], + ?line [] = compile(Config, Cs), + ok. + +otp_8665(doc) -> + ["OTP-8665. Bugfix premature end."]; +otp_8665(suite) -> + []; +otp_8665(Config) when is_list(Config) -> + Cs = [{otp_8562, + <<"-define(A, a)\n">>, + {errors,[{{1,54},epp,premature_end}],[]}} + ], + ?line [] = compile(Config, Cs), + ok. + check(Config, Tests) -> eval_tests(Config, fun check_test/2, Tests). @@ -1155,7 +1225,7 @@ eval_tests(Config, Fun, Tests) -> case message_compare(E, Return) of true -> BadL; - false -> + false -> ?t:format("~nTest ~p failed. Expected~n ~p~n" "but got~n ~p~n", [N, E, Return]), fail() @@ -1170,9 +1240,9 @@ check_test(Config, Test) -> ?line File = filename:join(PrivDir, Filename), ?line ok = file:write_file(File, Test), ?line case epp:parse_file(File, [PrivDir], []) of - {ok,Forms} -> + {ok,Forms} -> [E || E={error,_} <- Forms]; - {error,Error} -> + {error,Error} -> Error end. @@ -1187,7 +1257,7 @@ compile_test(Config, Test0) -> {ok, Ws} -> warnings(File, Ws); Else -> Else end. - + warnings(File, Ws) -> case lists:append([W || {F, W} <- Ws, F =:= File]) of [] -> []; @@ -1231,7 +1301,7 @@ message_compare(T, T) -> message_compare(T1, T2) -> ln(T1) =:= T2. -%% Replaces locations like {Line,Column} with Line. +%% Replaces locations like {Line,Column} with Line. ln({warnings,L}) -> {warnings,ln0(L)}; ln({errors,EL,WL}) -> diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl index 8581b496aa..d0c0d68b4a 100644 --- a/lib/stdlib/test/erl_lint_SUITE.erl +++ b/lib/stdlib/test/erl_lint_SUITE.erl @@ -1784,6 +1784,9 @@ otp_5362(Config) when is_list(Config) -> {15,erl_lint,{undefined_field,ok,nix}}, {16,erl_lint,{field_name_is_variable,ok,'Var'}}]}}, + %% Nowarn_bif_clash has changed behaviour as local functions + %% nowdays supersede auto-imported BIFs, why nowarn_bif_clash in itself generates an error + %% (OTP-8579) /PaN {otp_5362_4, <<"-compile(nowarn_deprecated_function). -compile(nowarn_bif_clash). @@ -1795,9 +1798,8 @@ otp_5362(Config) when is_list(Config) -> warn_deprecated_function, warn_bif_clash]}, {error, - [{5,erl_lint,{call_to_redefined_bif,{spawn,1}}}], - [{3,erl_lint,{redefine_bif,{spawn,1}}}, - {4,erl_lint,{deprecated,{erlang,hash,2},{erlang,phash2,2}, + [{5,erl_lint,{call_to_redefined_old_bif,{spawn,1}}}], + [{4,erl_lint,{deprecated,{erlang,hash,2},{erlang,phash2,2}, "in a future release"}}]}}, {otp_5362_5, @@ -1808,8 +1810,8 @@ otp_5362(Config) when is_list(Config) -> spawn(A). ">>, {[nowarn_unused_function]}, - {warnings, - [{3,erl_lint,{redefine_bif,{spawn,1}}}]}}, + {errors, + [{2,erl_lint,disallowed_nowarn_bif_clash}],[]}}, %% The special nowarn_X are not affected by general warn_X. {otp_5362_6, @@ -1822,8 +1824,8 @@ otp_5362(Config) when is_list(Config) -> {[nowarn_unused_function, warn_deprecated_function, warn_bif_clash]}, - {warnings, - [{3,erl_lint,{redefine_bif,{spawn,1}}}]}}, + {errors, + [{2,erl_lint,disallowed_nowarn_bif_clash}],[]}}, {otp_5362_7, <<"-export([spawn/1]). @@ -1838,7 +1840,9 @@ otp_5362(Config) when is_list(Config) -> spawn(A). ">>, {[nowarn_unused_function]}, - {error,[{4,erl_lint,{bad_nowarn_bif_clash,{spawn,2}}}], + {error,[{3,erl_lint,disallowed_nowarn_bif_clash}, + {4,erl_lint,disallowed_nowarn_bif_clash}, + {4,erl_lint,{bad_nowarn_bif_clash,{spawn,2}}}], [{5,erl_lint,{bad_nowarn_deprecated_function,{3,hash,-1}}}, {5,erl_lint,{bad_nowarn_deprecated_function,{erlang,hash,-1}}}, {5,erl_lint,{bad_nowarn_deprecated_function,{{a,b,c},hash,-1}}}]} @@ -1865,7 +1869,21 @@ otp_5362(Config) when is_list(Config) -> t() -> #a{}. ">>, {[]}, - []} + []}, + + {otp_5362_10, + <<"-compile({nowarn_deprecated_function,{erlang,hash,2}}). + -compile({nowarn_bif_clash,{spawn,1}}). + -import(x,[spawn/1]). + spin(A) -> + erlang:hash(A, 3000), + spawn(A). + ">>, + {[nowarn_unused_function, + warn_deprecated_function, + warn_bif_clash]}, + {errors, + [{2,erl_lint,disallowed_nowarn_bif_clash}],[]}} ], @@ -2234,7 +2252,7 @@ otp_5878(Config) when is_list(Config) -> {15,erl_lint,{undefined_field,r3,q}}, {17,erl_lint,{undefined_field,r,q}}, {21,erl_lint,illegal_guard_expr}, - {23,erl_lint,illegal_guard_expr}], + {23,erl_lint,{illegal_guard_local_call,{l,0}}}], []} = run_test2(Config, Ill1, [warn_unused_record]), @@ -2389,9 +2407,9 @@ bif_clash(Config) when is_list(Config) -> N. ">>, [], - {errors,[{2,erl_lint,{call_to_redefined_bif,{size,1}}}],[]}}, + {errors,[{2,erl_lint,{call_to_redefined_old_bif,{size,1}}}],[]}}, - %% Verify that (some) warnings can be turned off. + %% Verify that warnings can not be turned off in the old way. {clash2, <<"-export([t/1,size/1]). t(X) -> @@ -2400,17 +2418,198 @@ bif_clash(Config) when is_list(Config) -> size({N,_}) -> N. - %% My own abs/1 function works on lists too. - %% Unfortunately, it is not exported, so there will - %% be a warning that can't be turned off. + %% My own abs/1 function works on lists too. From R14 this really works. abs([H|T]) when $a =< H, H =< $z -> [H-($a-$A)|abs(T)]; abs([H|T]) -> [H|abs(T)]; abs([]) -> []; abs(X) -> erlang:abs(X). ">>, - {[nowarn_bif_clash]}, - {warnings,[{11,erl_lint,{redefine_bif,{abs,1}}}, - {11,erl_lint,{unused_function,{abs,1}}}]}}], + {[nowarn_unused_function,nowarn_bif_clash]}, + {errors,[{erl_lint,disallowed_nowarn_bif_clash}],[]}}, + %% As long as noone calls an overridden BIF, it's totally OK + {clash3, + <<"-export([size/1]). + size({N,_}) -> + N; + size(X) -> + erlang:size(X). + ">>, + [], + []}, + %% But this is totally wrong - meaning of the program changed in R14, so this is an error + {clash4, + <<"-export([size/1]). + size({N,_}) -> + N; + size(X) -> + size(X). + ">>, + [], + {errors,[{5,erl_lint,{call_to_redefined_old_bif,{size,1}}}],[]}}, + %% For a post R14 bif, its only a warning + {clash5, + <<"-export([binary_part/2]). + binary_part({B,_},{X,Y}) -> + binary_part(B,{X,Y}); + binary_part(B,{X,Y}) -> + binary:part(B,X,Y). + ">>, + [], + {warnings,[{3,erl_lint,{call_to_redefined_bif,{binary_part,2}}}]}}, + %% If you really mean to call yourself here, you can "unimport" size/1 + {clash6, + <<"-export([size/1]). + -compile({no_auto_import,[size/1]}). + size([]) -> + 0; + size({N,_}) -> + N; + size([_|T]) -> + 1+size(T). + ">>, + [], + []}, + %% Same for the post R14 autoimport warning + {clash7, + <<"-export([binary_part/2]). + -compile({no_auto_import,[binary_part/2]}). + binary_part({B,_},{X,Y}) -> + binary_part(B,{X,Y}); + binary_part(B,{X,Y}) -> + binary:part(B,X,Y). + ">>, + [], + []}, + %% but this doesn't mean the local function is allowed in a guard... + {clash8, + <<"-export([x/1]). + -compile({no_auto_import,[binary_part/2]}). + x(X) when binary_part(X,{1,2}) =:= <<1,2>> -> + hej. + binary_part({B,_},{X,Y}) -> + binary_part(B,{X,Y}); + binary_part(B,{X,Y}) -> + binary:part(B,X,Y). + ">>, + [], + {errors,[{3,erl_lint,{illegal_guard_local_call,{binary_part,2}}}],[]}}, + %% no_auto_import is not like nowarn_bif_clash, it actually removes the autoimport + {clash9, + <<"-export([x/1]). + -compile({no_auto_import,[binary_part/2]}). + x(X) -> + binary_part(X,{1,2}) =:= <<1,2>>. + ">>, + [], + {errors,[{4,erl_lint,{undefined_function,{binary_part,2}}}],[]}}, + %% but we could import it again... + {clash10, + <<"-export([x/1]). + -compile({no_auto_import,[binary_part/2]}). + -import(erlang,[binary_part/2]). + x(X) -> + binary_part(X,{1,2}) =:= <<1,2>>. + ">>, + [], + []}, + %% and actually use it in a guard... + {clash11, + <<"-export([x/1]). + -compile({no_auto_import,[binary_part/2]}). + -import(erlang,[binary_part/2]). + x(X) when binary_part(X,{0,1}) =:= <<0>> -> + binary_part(X,{1,2}) =:= <<1,2>>. + ">>, + [], + []}, + %% but for non-obvious historical reasons, imported functions cannot be used in + %% fun construction without the module name... + {clash12, + <<"-export([x/1]). + -compile({no_auto_import,[binary_part/2]}). + -import(erlang,[binary_part/2]). + x(X) when binary_part(X,{0,1}) =:= <<0>> -> + binary_part(X,{1,2}) =:= fun binary_part/2. + ">>, + [], + {errors,[{5,erl_lint,{undefined_function,{binary_part,2}}}],[]}}, + %% Not from erlang and not from anywhere else + {clash13, + <<"-export([x/1]). + -compile({no_auto_import,[binary_part/2]}). + -import(x,[binary_part/2]). + x(X) -> + binary_part(X,{1,2}) =:= fun binary_part/2. + ">>, + [], + {errors,[{5,erl_lint,{undefined_function,{binary_part,2}}}],[]}}, + %% ...while real auto-import is OK. + {clash14, + <<"-export([x/1]). + x(X) when binary_part(X,{0,1}) =:= <<0>> -> + binary_part(X,{1,2}) =:= fun binary_part/2. + ">>, + [], + []}, + %% Import directive clashing with old bif is an error, regardless of if it's called or not + {clash15, + <<"-export([x/1]). + -import(x,[abs/1]). + x(X) -> + binary_part(X,{1,2}). + ">>, + [], + {errors,[{2,erl_lint,{redefine_old_bif_import,{abs,1}}}],[]}}, + %% For a new BIF, it's only a warning + {clash16, + <<"-export([x/1]). + -import(x,[binary_part/3]). + x(X) -> + abs(X). + ">>, + [], + {warnings,[{2,erl_lint,{redefine_bif_import,{binary_part,3}}}]}}, + %% And, you cannot redefine already imported things that aren't auto-imported + {clash17, + <<"-export([x/1]). + -import(x,[binary_port/3]). + -import(y,[binary_port/3]). + x(X) -> + abs(X). + ">>, + [], + {errors,[{3,erl_lint,{redefine_import,{{binary_port,3},x}}}],[]}}, + %% Not with local functions either + {clash18, + <<"-export([x/1]). + -import(x,[binary_port/3]). + binary_port(A,B,C) -> + binary_part(A,B,C). + x(X) -> + abs(X). + ">>, + [], + {errors,[{3,erl_lint,{define_import,{binary_port,3}}}],[]}}, + %% Like clash8: Dont accept a guard if it's explicitly module-name called either + {clash19, + <<"-export([binary_port/3]). + -compile({no_auto_import,[binary_part/3]}). + -import(x,[binary_part/3]). + binary_port(A,B,C) when x:binary_part(A,B,C) -> + binary_part(A,B,C+1). + ">>, + [], + {errors,[{4,erl_lint,illegal_guard_expr}],[]}}, + %% Not with local functions either + {clash20, + <<"-export([binary_port/3]). + -import(x,[binary_part/3]). + binary_port(A,B,C) -> + binary_part(A,B,C). + ">>, + [warn_unused_import], + {warnings,[{2,erl_lint,{redefine_bif_import,{binary_part,3}}}]}} + ], ?line [] = run(Config, Ts), ok. diff --git a/lib/stdlib/test/erl_pp_SUITE.erl b/lib/stdlib/test/erl_pp_SUITE.erl index 0a119d1e38..c57541fba9 100644 --- a/lib/stdlib/test/erl_pp_SUITE.erl +++ b/lib/stdlib/test/erl_pp_SUITE.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %%%---------------------------------------------------------------- @@ -45,7 +45,8 @@ hook/1, neg_indent/1, tickets/1, - otp_6321/1, otp_6911/1, otp_6914/1, otp_8150/1, otp_8238/1]). + otp_6321/1, otp_6911/1, otp_6914/1, otp_8150/1, otp_8238/1, + otp_8473/1, otp_8522/1, otp_8567/1, otp_8664/1]). %% Internal export. -export([ehook/6]). @@ -149,15 +150,15 @@ recs(Config) when is_list(Config) -> (A#r1.a)#r.a > 3 -> 3 end(#r1{a = #r{a = 4}}), 7 = fun(A) when record(A#r3.a, r1) -> 7 end(#r3{}), - [#r1{a = 2,b = 1}] = + [#r1{a = 2,b = 1}] = fun() -> - [A || A <- [#r1{a = 1, b = 3}, - #r2{a = 2,b = 1}, + [A || A <- [#r1{a = 1, b = 3}, + #r2{a = 2,b = 1}, #r1{a = 2, b = 1}], - A#r1.a > + A#r1.a > A#r1.b] end(), - {[_],b} = + {[_],b} = fun(L) -> %% A is checked only once: R1 = [{A,B} || A <- L, A#r1.a, B <- L, A#r1.b], @@ -176,7 +177,7 @@ recs(Config) when is_list(Config) -> end(#r1{a = 2}), %% The test done twice (an effect of doing the test as soon as possible). - 3 = fun(A) when A#r1.a > 3, + 3 = fun(A) when A#r1.a > 3, record(A, r1) -> 3 end(#r1{a = 5}), @@ -250,18 +251,18 @@ recs(Config) when is_list(Config) -> ok end(), - both = fun(A) when A#r.a, A#r.b -> both + both = fun(A) when A#r.a, A#r.b -> both end(#r{a = true, b = true}), ok = fun() -> - F = fun(A, B) when ((A#r1.a) orelse (B#r2.a)) + F = fun(A, B) when ((A#r1.a) orelse (B#r2.a)) or (B#r2.b) or (A#r1.b) -> true; (_, _) -> false end, - true = F(#r1{a = false, b = false}, + true = F(#r1{a = false, b = false}, #r2{a = false, b = true}), - false = F(#r1{a = true, b = true}, + false = F(#r1{a = true, b = true}, #r1{a = false, b = true}), ok end(), @@ -272,7 +273,7 @@ recs(Config) when is_list(Config) -> <<"-record(r1, {a, b = foo:bar(kljlfjsdlf, kjlksdjf)}). -record(r2, {c = #r1{}, d = #r1{a = bar:foo(kljklsjdf)}}). - t() -> + t() -> R = #r2{}, R#r2{c = R, d = #r1{}}.">>} ], @@ -303,10 +304,10 @@ try_catch(Config) when is_list(Config) -> {try_6, <<"t() -> try 1=2 catch throw:{badmatch,2} -> 3 end.">>}, {try_7, - <<"t() -> try 1=2 of 3 -> 4 + <<"t() -> try 1=2 of 3 -> 4 catch error:{badmatch,2} -> 5 end.">>}, {try_8, - <<"t() -> try 1=2 + <<"t() -> try 1=2 catch error:{badmatch,2} -> 3 after put(try_catch, 4) end.">>}, {try_9, @@ -370,7 +371,7 @@ receive_after(Config) when is_list(Config) -> {X,Y}; Z -> Z - after + after foo:bar() -> {3,4} end.">>} @@ -428,7 +429,7 @@ head_tail(Config) when is_list(Config) -> {list_4, <<"t() -> [a].">>}, {list_5, - <<"t() -> + <<"t() -> [foo:bar(lkjljlskdfj, klsdajflds, sdafkljsdlfkjdas, kjlsdadjl), bar:foo(kljlkjsdf, lkjsdlfj, [kljsfj, sdfdsfsad])].">>} ], @@ -461,7 +462,7 @@ cond1(Config) when is_list(Config) -> " true ->\n" " {x,y}\n" "end" = CChars, -% ?line ok = pp_expr(<<"cond +% ?line ok = pp_expr(<<"cond % {foo,bar} -> % [a,b]; % true -> @@ -543,7 +544,7 @@ old_mnemosyne_syntax(Config) when is_list(Config) -> " X <- table(tab),\n" " X.foo = bar\n" " ]\n" - "end" = + "end" = lists:flatten(erl_pp:expr(Q)), R = {rule,12,sales,2, @@ -558,7 +559,7 @@ old_mnemosyne_syntax(Config) when is_list(Config) -> {atom,14,sales}}]}]}, ?line "sales(E, employee) :-\n" " E <- table(employee),\n" - " E.salary = sales.\n" = + " E.salary = sales.\n" = lists:flatten(erl_pp:form(R)), ok. @@ -659,7 +660,7 @@ hook(Config) when is_list(Config) -> ?line "INVALID-FORM:{foo,bar}:" = lists:flatten(erl_pp:expr({foo,bar})), - %% A list (as before R6), not a list of lists. + %% A list (as before R6), not a list of lists. G = [{op,1,'>',{atom,1,a},{foo,{atom,1,b}}}], % not a proper guard GChars = lists:flatten(erl_pp:guard(G, H)), G2 = [{op,1,'>',{atom,1,a}, @@ -676,23 +677,23 @@ hook(Config) when is_list(Config) -> %% Note: no leading spaces before "begin". Block = {block,0,[{match,0,{var,0,'A'},{integer,0,3}}, {atom,0,true}]}, - ?line "begin\n A =" ++ _ = + ?line "begin\n A =" ++ _ = lists:flatten(erl_pp:expr(Block, 17, none)), %% Special... - ?line true = + ?line true = "{some,value}" =:= lists:flatten(erl_pp:expr({value,0,{some,value}})), %% Silly... ?line true = - "if true -> 0 end" =:= + "if true -> 0 end" =:= flat_expr({'if',0,[{clause,0,[],[],[{atom,0,0}]}]}), %% More compatibility: before R6 OldIf = {'if',0,[{clause,0,[],[{atom,0,true}],[{atom,0,b}]}]}, NewIf = {'if',0,[{clause,0,[],[[{atom,0,true}]],[{atom,0,b}]}]}, OldIfChars = lists:flatten(erl_pp:expr(OldIf)), - NewIfChars = lists:flatten(erl_pp:expr(NewIf)), + NewIfChars = lists:flatten(erl_pp:expr(NewIf)), ?line true = OldIfChars =:= NewIfChars, ok. @@ -705,7 +706,7 @@ remove_indentation(S) -> ehook(HE, I, P, H, foo, bar) -> hook(HE, I, P, H). -hook({foo,E}, I, P, H) -> +hook({foo,E}, I, P, H) -> erl_pp:expr({call,0,{atom,0,foo},[E]}, I, P, H). neg_indent(suite) -> @@ -721,14 +722,14 @@ neg_indent(Config) when is_list(Config) -> end">>), ?line ok = pp_expr( <<"fun() -> - F = fun(A, B) when ((A#r1.a) orelse (B#r2.a)) + F = fun(A, B) when ((A#r1.a) orelse (B#r2.a)) or (B#r2.b) or (A#r1.b) -> true; (_, _) -> false end, - true = F(#r1{a = false, b = false}, + true = F(#r1{a = false, b = false}, #r2{a = false, b = true}), - false = F(#r1{a = true, b = true}, + false = F(#r1{a = true, b = true}, #r1{a = false, b = true}), ok end()">>), @@ -763,7 +764,8 @@ neg_indent(Config) when is_list(Config) -> ok. tickets(suite) -> - [otp_6321, otp_6911, otp_6914, otp_8150, otp_8238]. + [otp_6321, otp_6911, otp_6914, otp_8150, otp_8238, otp_8473, otp_8522, + otp_8567, otp_8664]. otp_6321(doc) -> "OTP_6321. Bug fix of exprs()."; @@ -812,7 +814,7 @@ otp_8150(doc) -> "OTP_8150. Types."; otp_8150(suite) -> []; otp_8150(Config) when is_list(Config) -> - ?line _ = [{N,ok} = {N,pp_forms(B)} || + ?line _ = [{N,ok} = {N,pp_forms(B)} || {N,B} <- type_examples() ], ok. @@ -846,7 +848,7 @@ type_examples() -> {ex4,<<"-type t1() :: atom(). ">>}, {ex5,<<"-type t2() :: [t1()]. ">>}, {ex6,<<"-type t3(Atom) :: integer(Atom). ">>}, - {ex7,<<"-type t4() :: t3(foobar). ">>}, + {ex7,<<"-type '\\'t::4'() :: t3('\\'foobar'). ">>}, {ex8,<<"-type t5() :: {t1(), t3(foo)}. ">>}, {ex9,<<"-type t6() :: 1 | 2 | 3 | 'foo' | 'bar'. ">>}, {ex10,<<"-type t7() :: []. ">>}, @@ -882,16 +884,16 @@ type_examples() -> "1|2|3|4|a|b|c|d| " "nonempty_maybe_improper_list(integer, any())]}. ">>}, {ex30,<<"-type t99() ::" - "{t2(),t4(),t5(),t6(),t7(),t8(),t10(),t14()," + "{t2(),'\\'t::4'(),t5(),t6(),t7(),t8(),t10(),t14()," "t15(),t20(),t21(), t22(),t25()}. ">>}, {ex31,<<"-spec t1(FooBar :: t99()) -> t99();" "(t2()) -> t2();" - "(t4()) -> t4() when is_subtype(t4(), t24);" + "('\\'t::4'()) -> '\\'t::4'() when is_subtype('\\'t::4'(), t24);" "(t23()) -> t23() when is_subtype(t23(), atom())," " is_subtype(t23(), t14());" "(t24()) -> t24() when is_subtype(t24(), atom())," " is_subtype(t24(), t14())," - " is_subtype(t24(), t4()).">>}, + " is_subtype(t24(), '\\'t::4'()).">>}, {ex32,<<"-spec mod:t2() -> any(). ">>}, {ex33,<<"-opaque attributes_data() :: " "[{'column', column()} | {'line', info_line()} |" @@ -911,12 +913,126 @@ type_examples() -> "f19 = 3 :: integer()|undefined," "f5 = 3 :: undefined|integer()}). ">>}]. +otp_8473(doc) -> + "OTP_8473. Bugfix abstract type 'fun'."; +otp_8473(suite) -> []; +otp_8473(Config) when is_list(Config) -> + Ex = [{ex1,<<"-type 'fun'(A) :: A.\n" + "-type funkar() :: 'fun'(fun((integer()) -> atom())).\n">>}], + ?line _ = [{N,ok} = {N,pp_forms(B)} || + {N,B} <- Ex], + ok. + +otp_8522(doc) -> + "OTP_8522. Avoid duplicated 'undefined' in record field types."; +otp_8522(suite) -> []; +otp_8522(Config) when is_list(Config) -> + FileName = filename('otp_8522.erl', Config), + C = <<"-module(otp_8522).\n" + "-record(r, {f1 :: undefined,\n" + " f2 :: A :: undefined,\n" + " f3 :: (undefined),\n" + " f4 :: x | y | undefined | z,\n" + " f5 :: a}).\n">>, + ?line ok = file:write_file(FileName, C), + ?line {ok, _} = compile:file(FileName, [{outdir,?privdir},debug_info]), + BF = filename("otp_8522", Config), + ?line {ok, A} = beam_lib:chunks(BF, [abstract_code]), + ?line 5 = count_atom(A, undefined), + ok. + +count_atom(A, A) -> + 1; +count_atom(T, A) when is_tuple(T) -> + count_atom(tuple_to_list(T), A); +count_atom(L, A) when is_list(L) -> + lists:sum([count_atom(T, A) || T <- L]); +count_atom(_, _) -> + 0. + +otp_8567(doc) -> + "OTP_8567. Avoid duplicated 'undefined' in record field types."; +otp_8567(suite) -> []; +otp_8567(Config) when is_list(Config) -> + FileName = filename('otp_8567.erl', Config), + C = <<"-module otp_8567.\n" + "-compile export_all.\n" + "-spec(a).\n" + "-record r, {a}.\n" + "-record s, {a :: integer()}.\n" + "-type t() :: {#r{},#s{}}.\n">>, + ?line ok = file:write_file(FileName, C), + ?line {error,[{_,[{3,erl_parse,["syntax error before: ","')'"]}]}],_} = + compile:file(FileName, [return]), + + F = <<"-module(otp_8567).\n" + "-compile(export_all).\n" + "-record(t, {a}).\n" + "-record(u, {a :: integer()}).\n" + "-opaque ot() :: {#t{}, #u{}}.\n" + "-opaque(ot1() :: atom()).\n" + "-type a() :: integer().\n" + "-spec t() -> a().\n" + "t() ->\n" + " 3.\n" + "\n" + "-spec(t1/1 :: (ot()) -> ot1()).\n" + "t1(A) ->\n" + " A.\n" + "\n" + "-spec(t2 (ot()) -> ot1()).\n" + "t2(A) ->\n" + " A.\n" + "\n" + "-spec(otp_8567:t3/1 :: (ot()) -> ot1()).\n" + "t3(A) ->\n" + " A.\n" + "\n" + "-spec(otp_8567:t4 (ot()) -> ot1()).\n" + "t4(A) ->\n" + " A.\n">>, + ?line ok = pp_forms(F), + + ok. + +otp_8664(doc) -> + "OTP_8664. Types with integer expressions."; +otp_8664(suite) -> []; +otp_8664(Config) when is_list(Config) -> + FileName = filename('otp_8664.erl', Config), + C1 = <<"-module(otp_8664).\n" + "-export([t/0]).\n" + "-define(A, -3).\n" + "-define(B, (?A*(-1 band (((2)))))).\n" + "-type t1() :: ?B | ?A.\n" + "-type t2() :: ?B-1 .. -?B.\n" + "-type t3() :: 9 band (8 - 3) | 1+2 | 5 band 3.\n" + "-type b1() :: <<_:_*(3-(-1))>>\n" + " | <<_:(-(?B))>>\n" + " | <<_:4>>.\n" + "-type u() :: 1 .. 2 | 3.. 4 | (8-3) ..6 | 5+0..6.\n" + "-type t() :: t1() | t2() | t3() | b1() | u().\n" + "-spec t() -> t().\n" + "t() -> 3.\n">>, + ?line ok = file:write_file(FileName, C1), + ?line {ok, _, []} = compile:file(FileName, [return]), + + C2 = <<"-module(otp_8664).\n" + "-export([t/0]).\n" + "-spec t() -> 9 and 4.\n" + "t() -> 0.\n">>, + ?line ok = file:write_file(FileName, C2), + ?line {error,[{_,[{3,erl_lint,{type_syntax,integer}}]}],_} = + compile:file(FileName, [return]), + + ok. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% compile(Config, Tests) -> F = fun({N,P}, BadL) -> case catch compile_file(Config, P) of - ok -> + ok -> case pp_forms(P) of ok -> BadL; @@ -924,8 +1040,8 @@ compile(Config, Tests) -> ?t:format("~nTest ~p failed.~n", [N]), fail() end; - Bad -> - ?t:format("~nTest ~p failed. got~n ~p~n", + Bad -> + ?t:format("~nTest ~p failed. got~n ~p~n", [N, Bad]), fail() end @@ -955,7 +1071,7 @@ compile_file(Config, Test0) -> Error -> Error end. - + compile_file(Config, Test0, Opts0) -> FileName = filename('erl_pp_test.erl', Config), Test = list_to_binary(["-module(erl_pp_test). " @@ -964,7 +1080,7 @@ compile_file(Config, Test0, Opts0) -> Opts = [export_all,return,nowarn_unused_record,{outdir,?privdir} | Opts0], ok = file:write_file(FileName, Test), case compile:file(FileName, Opts) of - {ok, _M, _Ws} -> + {ok, _M, _Ws} -> {ok, filename:rootname(FileName)}; Error -> Error end. @@ -991,7 +1107,7 @@ pp_forms(Bin, Hook) -> end. parse_and_pp_forms(String, Hook) -> - lists:append(lists:map(fun(AF) -> erl_pp:form(AF, Hook) + lists:append(lists:map(fun(AF) -> erl_pp:form(AF, Hook) end, parse_forms(String))). parse_forms(Chars) -> @@ -999,13 +1115,13 @@ parse_forms(Chars) -> parse_forms2(String, [], 1, []). parse_forms2([], _Cont, _Line, Forms) -> - lists:reverse(Forms); + lists:reverse(Forms); parse_forms2(String, Cont0, Line, Forms) -> case erl_scan:tokens(Cont0, String, Line) of {done, {ok, Tokens, EndLine}, Chars} -> {ok, Form} = erl_parse:parse_form(Tokens), parse_forms2(Chars, [], EndLine, [Form | Forms]); - {more, Cont} when element(3, Cont) =:= [] -> + {more, Cont} when element(3, Cont) =:= [] -> %% extra spaces after forms... parse_forms2([], Cont, Line, Forms); {more, Cont} -> @@ -1023,10 +1139,10 @@ pp_expr(Bin, Hook) -> PP2 = (catch parse_and_pp_expr(PPneg, 0, Hook)), if PP1 =:= PP2 -> % same line numbers - case + case (test_max_line(PP1) =:= ok) and (test_new_line(PPneg) =:= ok) of - true -> + true -> ok; false -> not_ok @@ -1059,7 +1175,7 @@ test_max_line(String) -> end. max_line(String) -> - lists:max([0 | [length(Sub) || + lists:max([0 | [length(Sub) || Sub <- string:tokens(String, "\n"), string:substr(Sub, 1, 5) =/= "-file"]]). diff --git a/lib/stdlib/test/erl_scan_SUITE.erl b/lib/stdlib/test/erl_scan_SUITE.erl index 32a06d15c7..32eb97bc92 100644 --- a/lib/stdlib/test/erl_scan_SUITE.erl +++ b/lib/stdlib/test/erl_scan_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1998-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(erl_scan_SUITE). @@ -34,7 +34,7 @@ -define(line, put(line, ?LINE), ). -define(config(A,B),config(A,B)). -define(t, test_server). -%% config(priv_dir, _) -> +%% config(priv_dir, _) -> %% "."; %% config(data_dir, _) -> %% ".". @@ -45,7 +45,7 @@ init_per_testcase(_Case, Config) when is_list(Config) -> ?line Dog=test_server:timetrap(test_server:seconds(1200)), [{watchdog, Dog}|Config]. - + fin_per_testcase(_Case, Config) -> Dog=?config(watchdog, Config), test_server:timetrap_cancel(Dog), @@ -97,7 +97,7 @@ assert_type(N, integer) when is_integer(N) -> ok; assert_type(N, atom) when is_atom(N) -> ok. - + check(String) -> Error = erl_scan:string(String), check_error(Error, erl_scan). @@ -146,7 +146,7 @@ iso88591(Config) when is_list(Config) -> ok -> ok %Aok end. -otp_7810(doc) -> +otp_7810(doc) -> ["OTP-7810. White spaces, comments, and more.."]; otp_7810(suite) -> []; @@ -185,7 +185,7 @@ reserved_words() -> 'andalso', 'orelse', 'end', 'fun', 'if', 'let', 'of', 'query', 'receive', 'when', 'bnot', 'not', 'div', 'rem', 'band', 'and', 'bor', 'bxor', 'bsl', 'bsr', - 'or', 'xor', 'spec'] , % 'spec' shouldn't be there... + 'or', 'xor'], [begin ?line {RW, true} = {RW, erl_scan:reserved_word(RW)}, S = atom_to_list(RW), @@ -203,7 +203,7 @@ atoms() -> ?line test_string("a@2", [{atom,1,a@2}]), ?line test_string([39,65,200,39], [{atom,1,'A�'}]), ?line test_string("�rlig �sten", [{atom,1,�rlig},{atom,1,�sten}]), - ?line {ok,[{atom,_,'$a'}],{1,6}} = + ?line {ok,[{atom,_,'$a'}],{1,6}} = erl_scan:string("'$\\a'", {1,1}), ?line test("'$\\a'"), ok. @@ -221,8 +221,8 @@ punctuations() -> Three = ["/=:=", "<=:=", "==:=", ">=:="], % three tokens... No = Three ++ L, SL0 = [{S1++S2,{-length(S1),S1,S2}} || - S1 <- L, - S2 <- L, + S1 <- L, + S2 <- L, not lists:member(S1++S2, No)], SL = family_list(SL0), %% Two tokens. When there are several answers, the one with @@ -244,21 +244,24 @@ punctuations() -> {'\\',1},{'^',1},{'`',1},{'~',1}], ?line test_string("#&*+/:<>?@\\^`~", PTs2), + ?line test_string(".. ", [{'..',1}]), + ?line test("1 .. 2"), + ?line test_string("...", [{'...',1}]), ok. comments() -> ?line test("a %%\n b"), ?line {ok,[],1} = erl_scan:string("%"), ?line test("a %%\n b"), - ?line {ok,[{atom,_,a},{atom,_,b}],{2,3}} = + ?line {ok,[{atom,_,a},{atom,_,b}],{2,3}} = erl_scan:string("a %%\n b",{1,1}), - ?line {ok,[{atom,_,a},{comment,_,"%%"},{atom,_,b}],{2,3}} = + ?line {ok,[{atom,_,a},{comment,_,"%%"},{atom,_,b}],{2,3}} = erl_scan:string("a %%\n b",{1,1}, [return_comments]), ?line {ok,[{atom,_,a}, {white_space,_," "}, {white_space,_,"\n "}, {atom,_,b}], - {2,3}} = + {2,3}} = erl_scan:string("a %%\n b",{1,1},[return_white_spaces]), ?line {ok,[{atom,_,a}, {white_space,_," "}, @@ -275,14 +278,14 @@ errors() -> ?line {error,{1,erl_scan,char},1} = erl_scan:string("$"), ?line test_string([34,65,200,34], [{string,1,"A�"}]), ?line test_string("\\", [{'\\',1}]), - ?line {'EXIT',_} = + ?line {'EXIT',_} = (catch {foo, erl_scan:string('$\\a', {1,1})}), % type error - ?line {'EXIT',_} = + ?line {'EXIT',_} = (catch {foo, erl_scan:tokens([], '$\\a', {1,1})}), % type error ?line "{a,tuple}" = erl_scan:format_error({a,tuple}), ok. - + integers() -> [begin I = list_to_integer(S), @@ -299,14 +302,14 @@ base_integers() -> ?line test_string(BS++"#"++S, Ts) end || {BS,S} <- [{"2","11"}, {"5","23234"}, {"12","05a"}, {"16","abcdef"}, {"16","ABCDEF"}] ], - + ?line {error,{1,erl_scan,{base,1}},1} = erl_scan:string("1#000"), - + ?line test_string("12#bc", [{integer,1,11},{atom,1,c}]), - + [begin Str = BS ++ "#" ++ S, - ?line {error,{1,erl_scan,{illegal,integer}},1} = + ?line {error,{1,erl_scan,{illegal,integer}},1} = erl_scan:string(Str) end || {BS,S} <- [{"3","3"},{"15","f"}, {"12","c"}] ], @@ -323,8 +326,8 @@ floats() -> end || FS <- ["1.0","001.17","3.31200","1.0e0","1.0E17", "34.21E-18", "17.0E+14"]], ?line test_string("1.e2", [{integer,1,1},{'.',1},{atom,1,e2}]), - - ?line {error,{1,erl_scan,{illegal,float}},1} = + + ?line {error,{1,erl_scan,{illegal,float}},1} = erl_scan:string("1.0e400"), [begin ?line {error,{1,erl_scan,{illegal,float}},1} = erl_scan:string(S) @@ -345,16 +348,16 @@ dots() -> {".a", {ok,[{'.',1},{atom,1,a}],1}} ], ?line [R = erl_scan:string(S) || {S, R} <- Dot], - + ?line {ok,[{dot,_}=T1],{1,2}} = erl_scan:string(".", {1,1}, text), - ?line [{column,1},{length,1},{line,1},{text,"."}] = + ?line [{column,1},{length,1},{line,1},{text,"."}] = erl_scan:token_info(T1, [column, length, line, text]), ?line {ok,[{dot,_}=T2],{1,3}} = erl_scan:string(".%", {1,1}, text), - ?line [{column,1},{length,1},{line,1},{text,"."}] = + ?line [{column,1},{length,1},{line,1},{text,"."}] = erl_scan:token_info(T2, [column, length, line, text]), ?line {ok,[{dot,_}=T3],{1,6}} = erl_scan:string(".% �h", {1,1}, text), - ?line [{column,1},{length,1},{line,1},{text,"."}] = + ?line [{column,1},{length,1},{line,1},{text,"."}] = erl_scan:token_info(T3, [column, length, line, text]), ?line {error,{{1,2},erl_scan,char},{1,3}} = erl_scan:string(".$", {1,1}), @@ -376,10 +379,10 @@ dots() -> ?line {done,{ok,[{comment,_,"%. "}, {white_space,_,"\n"}, {dot,_}], - {2,3}}, ""} = + {2,3}}, ""} = erl_scan:tokens(C, "\n. ", {1,1}, return), % any loc, any options - ?line [test_string(S, R) || + ?line [test_string(S, R) || {S, R} <- [{".$\n", [{'.',1},{char,1,$\n}]}, {"$\\\n", [{char,1,$\n}]}, {"'\\\n'", [{atom,1,'\n'}]}, @@ -392,7 +395,7 @@ chars() -> Ts = [{char,1,C}], ?line test_string(L, Ts) end || C <- lists:seq(0, 255)], - + %% Leading zeroes... [begin L = lists:flatten(io_lib:format("$\\~3.8.0b", [C])), @@ -406,13 +409,13 @@ chars() -> Ts = [{char,1,C band 2#11111}], ?line test_string(L, Ts) end || C <- lists:seq(0, 255)], - + [begin L = "$\\" ++ [C], Ts = [{char,1,V}], ?line test_string(L, Ts) - end || {C,V} <- [{$n,$\n}, {$r,$\r}, {$t,$\t}, {$v,$\v}, - {$b,$\b}, {$f,$\f}, {$e,$\e}, {$s,$\s}, + end || {C,V} <- [{$n,$\n}, {$r,$\r}, {$t,$\t}, {$v,$\v}, + {$b,$\b}, {$f,$\f}, {$e,$\e}, {$s,$\s}, {$d,$\d}]], EC = [$\n,$\r,$\t,$\v,$\b,$\f,$\e,$\s,$\d], @@ -445,7 +448,7 @@ chars() -> end || C <- lists:seq(0, 255) -- (No ++ [$\\])], ?line test_string("$\n", [{char,1,$\n}]), - ?line {error,{{1,1},erl_scan,char},{1,4}} = + ?line {error,{{1,1},erl_scan,char},{1,4}} = erl_scan:string("$\\^",{1,1}), ?line test_string("$\\\n", [{char,1,$\n}]), %% Robert's scanner returns line 1: @@ -453,7 +456,7 @@ chars() -> ?line test_string("$\n\n", [{char,1,$\n}]), ?line test("$\n\n"), ok. - + variables() -> ?line test_string(" \237_Aou�eiy��", [{var,1,'_Aou�eiy��'}]), @@ -469,8 +472,8 @@ eof() -> ?line {done,{eof,2},eof} = erl_scan:tokens(C1, eof, 1), {more, C2} = erl_scan:tokens([], "abra", 1), %% An error before R13A. - %% ?line {done,Err={error,{1,erl_scan,scan},1},eof} = - ?line {done,{ok,[{atom,1,abra}],1},eof} = + %% ?line {done,Err={error,{1,erl_scan,scan},1},eof} = + ?line {done,{ok,[{atom,1,abra}],1},eof} = erl_scan:tokens(C2, eof, 1), %% With column. @@ -478,7 +481,7 @@ eof() -> ?line {done,{eof,{2,1}},eof} = erl_scan:tokens(C3, eof, 1), {more, C4} = erl_scan:tokens([], "abra", {1,1}), %% An error before R13A. - %% ?line {done,{error,{{1,1},erl_scan,scan},{1,5}},eof} = + %% ?line {done,{error,{{1,1},erl_scan,scan},{1,5}},eof} = ?line {done,{ok,[{atom,_,abra}],{1,5}},eof} = erl_scan:tokens(C4, eof, 1), @@ -486,7 +489,7 @@ eof() -> %% the R12B scanner returns eof as LeftoverChars: (eof is correct) ?line {more, C5} = erl_scan:tokens([], "a", 1), %% An error before R13A. - %% ?line {done,{error,{1,erl_scan,scan},1},eof} = + %% ?line {done,{error,{1,erl_scan,scan},1},eof} = ?line {done,{ok,[{atom,1,a}],1},eof} = erl_scan:tokens(C5,eof,1), @@ -528,7 +531,7 @@ illegal() -> erl_scan:tokens([], "foo "++Atom++". ", {1,1}), ?line {error,{{1,1},erl_scan,{illegal,atom}},{1,1003}} = erl_scan:string(QAtom, {1,1}), - ?line {done,{error,{{1,5},erl_scan,{illegal,atom}},{1,1007}},". "} = + ?line {done,{error,{{1,5},erl_scan,{illegal,atom}},{1,1007}},". "} = erl_scan:tokens([], "foo "++QAtom++". ", {1,1}), ?line {error,{{1,1},erl_scan,{illegal,var}},{1,1001}} = erl_scan:string(Var, {1,1}), @@ -553,7 +556,7 @@ crashes() -> ?line {'EXIT',_} = (catch {foo, erl_scan:string("\"\\v"++[-1,$"])}), %$" ?line {'EXIT',_} = (catch {foo, erl_scan:string([$",-1,$"])}), ?line {'EXIT',_} = (catch {foo, erl_scan:string("% foo"++[-1])}), - ?line {'EXIT',_} = + ?line {'EXIT',_} = (catch {foo, erl_scan:string("% foo"++[-1],{1,1})}), ?line {'EXIT',_} = (catch {foo, erl_scan:string([a])}), % type error @@ -564,7 +567,7 @@ crashes() -> ?line {'EXIT',_} = (catch {foo, erl_scan:string("\"\\v"++[a,$"])}), %$" ?line {'EXIT',_} = (catch {foo, erl_scan:string([$",a,$"])}), ?line {'EXIT',_} = (catch {foo, erl_scan:string("% foo"++[a])}), - ?line {'EXIT',_} = + ?line {'EXIT',_} = (catch {foo, erl_scan:string("% foo"++[a],{1,1})}), ?line {'EXIT',_} = (catch {foo, erl_scan:string([3.0])}), % type error @@ -573,26 +576,26 @@ crashes() -> options() -> %% line and column are not options, but tested here - ?line {ok,[{atom,1,foo},{white_space,1," "},{comment,1,"% bar"}], 1} = + ?line {ok,[{atom,1,foo},{white_space,1," "},{comment,1,"% bar"}], 1} = erl_scan:string("foo % bar", 1, return), - ?line {ok,[{atom,1,foo},{white_space,1," "}],1} = + ?line {ok,[{atom,1,foo},{white_space,1," "}],1} = erl_scan:string("foo % bar", 1, return_white_spaces), - ?line {ok,[{atom,1,foo},{comment,1,"% bar"}],1} = + ?line {ok,[{atom,1,foo},{comment,1,"% bar"}],1} = erl_scan:string("foo % bar", 1, return_comments), - ?line {ok,[{atom,17,foo}],17} = + ?line {ok,[{atom,17,foo}],17} = erl_scan:string("foo % bar", 17), - ?line {'EXIT',{function_clause,_}} = - (catch {foo, + ?line {'EXIT',{function_clause,_}} = + (catch {foo, erl_scan:string("foo % bar", {a,1}, [])}), % type error - ?line {ok,[{atom,_,foo}],{17,18}} = + ?line {ok,[{atom,_,foo}],{17,18}} = erl_scan:string("foo % bar", {17,9}, []), - ?line {'EXIT',{function_clause,_}} = + ?line {'EXIT',{function_clause,_}} = (catch {foo, erl_scan:string("foo % bar", {1,0}, [])}), % type error - ?line {ok,[{foo,1}],1} = + ?line {ok,[{foo,1}],1} = erl_scan:string("foo % bar",1, [{reserved_word_fun, fun(W) -> W =:= foo end}]), - ?line {'EXIT',{badarg,_}} = + ?line {'EXIT',{badarg,_}} = (catch {foo, erl_scan:string("foo % bar",1, % type error [{reserved_word_fun, @@ -618,14 +621,14 @@ more_options() -> token_info() -> ?line {ok,[T1],_} = erl_scan:string("foo", {1,18}, [text]), - {'EXIT',{badarg,_}} = + {'EXIT',{badarg,_}} = (catch {foo, erl_scan:token_info(T1, foo)}), % type error ?line {line,1} = erl_scan:token_info(T1, line), ?line {column,18} = erl_scan:token_info(T1, column), ?line {length,3} = erl_scan:token_info(T1, length), ?line {text,"foo"} = erl_scan:token_info(T1, text), ?line [{category,atom},{column,18},{length,3},{line,1}, - {symbol,foo},{text,"foo"}] = + {symbol,foo},{text,"foo"}] = erl_scan:token_info(T1), ?line [{length,3},{column,18}] = erl_scan:token_info(T1, [length, column]), @@ -648,9 +651,9 @@ token_info() -> ?line {category,'='} = erl_scan:token_info(T3, category), ?line [{symbol,'='}] = erl_scan:token_info(T3, [symbol]), ok. - + attributes_info() -> - ?line {'EXIT',_} = + ?line {'EXIT',_} = (catch {foo,erl_scan:attributes_info(foo)}), % type error ?line [{line,18}] = erl_scan:attributes_info(18), ?line {location,19} = erl_scan:attributes_info(19, location), @@ -717,9 +720,9 @@ set_attribute() -> ?line [{line,{17,11}},{text,"foo"}] = erl_scan:attributes_info(A7, [line,column,text]), - ?line {'EXIT',_} = + ?line {'EXIT',_} = (catch {foo, erl_scan:set_attribute(line, [], F2)}), % type error - ?line {'EXIT',{badarg,_}} = + ?line {'EXIT',{badarg,_}} = (catch {foo, erl_scan:set_attribute(column, [], F2)}), % type error ok. @@ -790,14 +793,14 @@ unicode() -> ?line {ok,[{char,1,83},{integer,1,45}],1} = erl_scan:string("$\\12345"), % not unicode - ?line {error,{1,erl_scan,{illegal,character}},1} = + ?line {error,{1,erl_scan,{illegal,character}},1} = erl_scan:string([1089]), - ?line {error,{{1,1},erl_scan,{illegal,character}},{1,2}} = + ?line {error,{{1,1},erl_scan,{illegal,character}},{1,2}} = erl_scan:string([1089], {1,1}), ?line {error,{1,erl_scan,{illegal,character}},1} = - %% ?line {error,{1,erl_scan,{illegal,atom}},1} = + %% ?line {error,{1,erl_scan,{illegal,atom}},1} = erl_scan:string("'a"++[1089]++"b'"), - ?line {error,{{1,3},erl_scan,{illegal,character}},{1,4}} = + ?line {error,{{1,3},erl_scan,{illegal,character}},{1,4}} = erl_scan:string("'a"++[1089]++"b'", {1,1}), ?line test("\"a"++[1089]++"b\""), ?line {ok,[{char,1,1}],1} = erl_scan:string([$$,$\\,$^,1089]), @@ -822,7 +825,7 @@ unicode() -> ?line {ok,[{integer,1,16#aaa}],1} = erl_scan:string(Qs), ?line {ok,[Q2],{1,9}} = erl_scan:string("$\\x{aaa}", {1,1}, text), ?line [{category,integer},{column,1},{length,8}, - {line,1},{symbol,16#aaa},{text,Qs}] = + {line,1},{symbol,16#aaa},{text,Qs}] = erl_scan:token_info(Q2), U1 = "\"\\x{aaa}\"", @@ -830,11 +833,11 @@ unicode() -> ?line [{category,'['},{column,1},{length,1},{line,1}, {symbol,'['},{text,"\""}] = erl_scan:token_info(T1, Tags), ?line [{category,integer},{column,2},{length,7}, - {line,1},{symbol,16#aaa},{text,"\\x{aaa}"}] = + {line,1},{symbol,16#aaa},{text,"\\x{aaa}"}] = erl_scan:token_info(T2, Tags), ?line [{category,']'},{column,9},{length,1},{line,1}, {symbol,']'},{text,"\""}] = erl_scan:token_info(T3, Tags), - ?line {ok,[{'[',1},{integer,1,16#aaa},{']',1}],1} = + ?line {ok,[{'[',1},{integer,1,16#aaa},{']',1}],1} = erl_scan:string(U1, 1), U2 = "\"\\x41\\x{fff}\\x42\"", @@ -844,7 +847,7 @@ unicode() -> U3 = "\"a\n\\x{fff}\n\"", ?line {ok,[{'[',1},{char,1,$a},{',',1},{char,1,$\n}, {',',2},{integer,2,16#fff},{',',2},{char,2,$\n}, - {']',3}],3} = + {']',3}],3} = erl_scan:string(U3, 1), U4 = "\"\\^\n\\x{aaa}\\^\n\"", @@ -867,10 +870,10 @@ unicode() -> {char,_,$d},{']',_}],{1,8}} = erl_scan:string(Str1, {1,1}), ?line test(Str1), Comment = "%% "++[1089], - ?line {ok,[{comment,1,[$%,$%,$\s,1089]}],1} = + ?line {ok,[{comment,1,[$%,$%,$\s,1089]}],1} = erl_scan:string(Comment, 1, return), - ?line {ok,[{comment,_,[$%,$%,$\s,1089]}],{1,5}} = - erl_scan:string(Comment, {1,1}, return), + ?line {ok,[{comment,_,[$%,$%,$\s,1089]}],{1,5}} = + erl_scan:string(Comment, {1,1}, return), ok. more_chars() -> @@ -885,7 +888,7 @@ more_chars() -> erl_scan:tokens(C1, eof, 1), ?line {ok,[{char,1,123},{atom,1,a},{'}',1}],1} = erl_scan:string("$\\{a}"), - + ?line {error,{{1,1},erl_scan,char},{1,4}} = erl_scan:string("$\\x", {1,1}), ?line {error,{{1,1},erl_scan,char},{1,5}} = @@ -893,12 +896,12 @@ more_chars() -> ?line {more, C3} = erl_scan:tokens([], "$\\x", {1,1}), ?line {done,{error,{{1,1},erl_scan,char},{1,4}},eof} = erl_scan:tokens(C3, eof, 1), - ?line {error,{{1,1},erl_scan,char},{1,5}} = + ?line {error,{{1,1},erl_scan,char},{1,5}} = erl_scan:string("$\\x{",{1,1}), ?line {more, C2} = erl_scan:tokens([], "$\\x{", {1,1}), - ?line {done,{error,{{1,1},erl_scan,char},{1,5}},eof} = + ?line {done,{error,{{1,1},erl_scan,char},{1,5}},eof} = erl_scan:tokens(C2, eof, 1), - ?line {error,{1,erl_scan,{illegal,character}},1} = + ?line {error,{1,erl_scan,{illegal,character}},1} = erl_scan:string("$\\x{g}"), ?line {error,{{1,1},erl_scan,{illegal,character}},{1,5}} = erl_scan:string("$\\x{g}", {1,1}), @@ -924,12 +927,12 @@ more_chars() -> ?line test("$\\x{10FFFF}"), ?line test("$\\x{10ffff}"), ?line test("\"$\n \\{1}\""), - ?line {error,{1,erl_scan,{illegal,character}},1} = + ?line {error,{1,erl_scan,{illegal,character}},1} = erl_scan:string("$\\x{110000}"), - ?line {error,{{1,1},erl_scan,{illegal,character}},{1,12}} = + ?line {error,{{1,1},erl_scan,{illegal,character}},{1,12}} = erl_scan:string("$\\x{110000}", {1,1}), - ?line {error,{{1,1},erl_scan,{illegal,character}},{1,4}} = + ?line {error,{{1,1},erl_scan,{illegal,character}},{1,4}} = erl_scan:string("$\\xfg", {1,1}), ?line test("$\\xffg"), @@ -953,11 +956,11 @@ test(String) -> {Wtokens, Wend}, {Ctokens, Cend}, {CWtokens, CWend}, - {CWtokens2, _}] = + {CWtokens2, _}] = [scan_string_with_column(String, X) || - X <- [[], - [return_white_spaces], - [return_comments], + X <- [[], + [return_white_spaces], + [return_comments], [return], [return]]], % for white space compaction test @@ -969,7 +972,7 @@ test(String) -> {none,Tokens} = {none, filter_tokens(CWtokens, [white_space,comment])}, {comments,Ctokens} = {comments,filter_tokens(CWtokens, [white_space])}, - {white_spaces,Wtokens} = + {white_spaces,Wtokens} = {white_spaces,filter_tokens(CWtokens, [comment])}, %% Use token attributes to extract parts from the original string, @@ -991,9 +994,9 @@ test(String) -> %% Line attribute only: [Simple,Wsimple,Csimple,WCsimple] = Simples = [element(2, erl_scan:string(String, 1, Opts)) || - Opts <- [[], - [return_white_spaces], - [return_comments], + Opts <- [[], + [return_white_spaces], + [return_comments], [return]]], {consistent,true} = {consistent,consistent_attributes(Simples)}, {simple_wc,WCsimple} = {simple_wc,simplify(CWtokens)}, @@ -1004,19 +1007,19 @@ test(String) -> %% Line attribute only, with text: [SimpleTxt,WsimpleTxt,CsimpleTxt,WCsimpleTxt] = SimplesTxt = [element(2, erl_scan:string(String, 1, [text|Opts])) || - Opts <- [[], - [return_white_spaces], - [return_comments], + Opts <- [[], + [return_white_spaces], + [return_comments], [return]]], TextTxt = get_text(WCsimpleTxt), {text_txt,TextTxt,String} = {text_txt,String,TextTxt}, - {consistent_txt,true} = + {consistent_txt,true} = {consistent_txt,consistent_attributes(SimplesTxt)}, - {simple_txt,SimpleTxt} = + {simple_txt,SimpleTxt} = {simple_txt,filter_tokens(WCsimpleTxt, [white_space,comment])}, - {simple_c_txt,CsimpleTxt} = + {simple_c_txt,CsimpleTxt} = {simple_c_txt,filter_tokens(WCsimpleTxt, [white_space])}, - {simple_w_txt,WsimpleTxt} = + {simple_w_txt,WsimpleTxt} = {simple_w_txt,filter_tokens(WCsimpleTxt, [comment])}, ok. @@ -1024,18 +1027,18 @@ test(String) -> test_white_space_compaction(Tokens, Tokens2) when Tokens =:= Tokens2 -> [WS, WS2] = [select_tokens(Ts, [white_space]) || Ts <- [Tokens, Tokens2]], test_wsc(WS, WS2). - + test_wsc([], []) -> ok; test_wsc([Token|Tokens], [Token2|Tokens2]) -> - [Text, Text2] = [Text || - {text, Text} <- + [Text, Text2] = [Text || + {text, Text} <- [erl_scan:token_info(T, text) || T <- [Token, Token2]]], Sz = erts_debug:size(Text), Sz2 = erts_debug:size({Text, Text2}), IsCompacted = Sz2 < 2*Sz+erts_debug:size({a,a}), - ToBeCompacted = is_compacted(Text), + ToBeCompacted = is_compacted(Text), if IsCompacted =:= ToBeCompacted -> test_wsc(Tokens, Tokens2); @@ -1050,14 +1053,14 @@ is_compacted("\n\r") -> is_compacted("\n\f") -> true; is_compacted([$\n|String]) -> - all_spaces(String) + all_spaces(String) orelse all_tabs(String); is_compacted(String) -> all_spaces(String) orelse all_tabs(String). - + all_spaces(L) -> all_same(L, $\s). @@ -1078,7 +1081,7 @@ newlines_first([Token|Tokens]) -> _ -> Nnls =:= 0 end, - if + if OK -> newlines_first(Tokens); true -> OK end. @@ -1097,7 +1100,7 @@ simplify([]) -> get_text(Tokens) -> lists:flatten( - [T || + [T || Token <- Tokens, ({text,T} = erl_scan:token_info(Token, text)) =/= []]). @@ -1108,7 +1111,7 @@ test_decorated_tokens(String, Tokens) -> token_attrs(Tokens) -> [{L,C,Len,T} || Token <- Tokens, - ([{line,L},{column,C},{length,Len},{text,T}] = + ([{line,L},{column,C},{length,Len},{text,T}] = erl_scan:token_info(Token, [line,column,length,text])) =/= []]. test_strings([], _S, Line, Column) -> @@ -1150,7 +1153,7 @@ scan_string_with_column(String, Options0) -> {ok, Ts1, End1} = erl_scan:string(String, StartLoc, Options), TString = String ++ ". ", {ok,Ts2,End2} = scan_tokens(TString, Options, [], StartLoc), - {ok, Ts3, End3} = + {ok, Ts3, End3} = scan_tokens_1({more, []}, TString, Options, [], StartLoc), {end_2,End2,End3} = {end_2,End3,End2}, {EndLine1,EndColumn1} = End1, @@ -1190,8 +1193,8 @@ consistent_attributes([Ts | TsL]) -> L = [T || T <- Ts, is_integer(element(2, T))], case L of [] -> - TagsL = [[Tag || {Tag,_} <- - erl_scan:attributes_info(element(2, T))] || + TagsL = [[Tag || {Tag,_} <- + erl_scan:attributes_info(element(2, T))] || T <- Ts], case lists:usort(TagsL) of [_] -> diff --git a/lib/stdlib/test/escript_SUITE.erl b/lib/stdlib/test/escript_SUITE.erl index 70aae54d62..77fd190e45 100644 --- a/lib/stdlib/test/escript_SUITE.erl +++ b/lib/stdlib/test/escript_SUITE.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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(escript_SUITE). @@ -22,16 +22,20 @@ init_per_testcase/2, fin_per_testcase/2, basic/1, - errors/1, + errors/1, strange_name/1, emulator_flags/1, module_script/1, beam_script/1, archive_script/1, - epp/1 + epp/1, + create_and_extract/1, + foldl/1, + verify_sections/3 ]). -include("test_server.hrl"). +-include_lib("kernel/include/file.hrl"). all(suite) -> [ @@ -42,7 +46,9 @@ all(suite) -> module_script, beam_script, archive_script, - epp + epp, + create_and_extract, + foldl ]. init_per_testcase(_Case, Config) -> @@ -68,11 +74,11 @@ basic(Config) when is_list(Config) -> ?line run(Dir, "factorial_warning 20", [data_dir,<<"factorial_warning:12: Warning: function bar/0 is unused\n" "factorial 20 = 2432902008176640000\nExitCode:0">>]), - ?line run(Dir, "-s", "factorial_warning", + ?line run_with_opts(Dir, "-s", "factorial_warning", [data_dir,<<"factorial_warning:12: Warning: function bar/0 is unused\nExitCode:0">>]), - ?line run(Dir, "-s -i", "factorial_warning", + ?line run_with_opts(Dir, "-s -i", "factorial_warning", [data_dir,<<"factorial_warning:12: Warning: function bar/0 is unused\nExitCode:0">>]), - ?line run(Dir, "-c -s", "factorial_warning", + ?line run_with_opts(Dir, "-c -s", "factorial_warning", [data_dir,<<"factorial_warning:12: Warning: function bar/0 is unused\nExitCode:0">>]), ?line run(Dir, "filesize "++filename:join(?config(data_dir, Config),"filesize"), [data_dir,<<"filesize:11: Warning: function id/1 is unused\n324\nExitCode:0">>]), @@ -100,7 +106,7 @@ errors(Config) when is_list(Config) -> [data_dir,<<"lint_error:6: function main/1 already defined\n">>, data_dir,"lint_error:8: variable 'ExitCode' is unbound\n", <<"escript: There were compilation errors.\nExitCode:127">>]), - ?line run(Dir, "-s", "lint_error", + ?line run_with_opts(Dir, "-s", "lint_error", [data_dir,<<"lint_error:6: function main/1 already defined\n">>, data_dir,"lint_error:8: variable 'ExitCode' is unbound\n", <<"escript: There were compilation errors.\nExitCode:127">>]), @@ -140,31 +146,31 @@ module_script(Config) when is_list(Config) -> OrigFile = filename:join([Data,"emulator_flags"]), {ok, OrigBin} = file:read_file(OrigFile), ?line [Shebang, Mode, Flags | Source] = string:tokens(binary_to_list(OrigBin), "\n"), - ?line {ok, OrigFI} = file:read_file_info(OrigFile), + ?line {ok, OrigFI} = file:read_file_info(OrigFile), %% Write source file Priv = ?config(priv_dir, Config), Dir = filename:absname(Priv), % Get rid of trailing slash. Base = "module_script", ErlFile = filename:join([Priv, Base ++ ".erl"]), - ErlCode = ["-module(", Base, ").\n", + ErlCode = ["\n-module(", Base, ").\n", "-export([main/1]).\n\n", string:join(Source, "\n"), "\n"], ?line ok = file:write_file(ErlFile, ErlCode), - + %%%%%%% %% Create and run scripts without emulator flags %% With shebang NoArgsBase = Base ++ "_no_args_with_shebang", NoArgsFile = filename:join([Priv, NoArgsBase]), - ?line ok = file:write_file(NoArgsFile, + ?line ok = file:write_file(NoArgsFile, [Shebang, "\n", ErlCode]), ?line ok = file:write_file_info(NoArgsFile, OrigFI), - - ?line run(Dir, NoArgsBase ++ " -arg1 arg2 arg3", + + ?line run(Dir, NoArgsBase ++ " -arg1 arg2 arg3", [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n" "nostick:[]\n" "mnesia:[]\n" @@ -172,7 +178,7 @@ module_script(Config) when is_list(Config) -> "unknown:[]\n" "ExitCode:0">>]), - ?line run(Dir, "", NoArgsBase ++ " -arg1 arg2 arg3", + ?line run_with_opts(Dir, "", NoArgsBase ++ " -arg1 arg2 arg3", [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n" "nostick:[]\n" "mnesia:[]\n" @@ -183,33 +189,33 @@ module_script(Config) when is_list(Config) -> %% Without shebang NoArgsBase2 = Base ++ "_no_args_without_shebang", NoArgsFile2 = filename:join([Priv, NoArgsBase2]), - ?line ok = file:write_file(NoArgsFile2, + ?line ok = file:write_file(NoArgsFile2, ["Something else than shebang!!!", "\n", ErlCode]), ?line ok = file:write_file_info(NoArgsFile2, OrigFI), - - ?line run(Dir, "", NoArgsBase2 ++ " -arg1 arg2 arg3", + + ?line run_with_opts(Dir, "", NoArgsBase2 ++ " -arg1 arg2 arg3", [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n" "nostick:[]\n" "mnesia:[]\n" "ERL_FLAGS=false\n" "unknown:[]\n" "ExitCode:0">>]), - + %% Plain module without header NoArgsBase3 = Base ++ "_no_args_without_header", NoArgsFile3 = filename:join([Priv, NoArgsBase3]), ?line ok = file:write_file(NoArgsFile3, [ErlCode]), ?line ok = file:write_file_info(NoArgsFile3, OrigFI), - - ?line run(Dir, "", NoArgsBase3 ++ " -arg1 arg2 arg3", + + ?line run_with_opts(Dir, "", NoArgsBase3 ++ " -arg1 arg2 arg3", [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n" "nostick:[]\n" "mnesia:[]\n" "ERL_FLAGS=false\n" "unknown:[]\n" "ExitCode:0">>]), - + %%%%%%% %% Create and run scripts with emulator flags @@ -217,12 +223,12 @@ module_script(Config) when is_list(Config) -> ArgsBase = Base ++ "_args_with_shebang", ArgsFile = filename:join([Priv, ArgsBase]), ?line ok = file:write_file(ArgsFile, - [Shebang, "\n", + [Shebang, "\n", Mode, "\n", Flags, "\n", ErlCode]), - ?line ok = file:write_file_info(ArgsFile, OrigFI), - + ?line ok = file:write_file_info(ArgsFile, OrigFI), + ?line run(Dir, ArgsBase ++ " -arg1 arg2 arg3", [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n" "nostick:[{nostick,[]}]\n" @@ -242,32 +248,32 @@ beam_script(Config) when is_list(Config) -> OrigFile = filename:join([Data,"emulator_flags"]), {ok, OrigBin} = file:read_file(OrigFile), ?line [Shebang, Mode, Flags | Source] = string:tokens(binary_to_list(OrigBin), "\n"), - ?line {ok, OrigFI} = file:read_file_info(OrigFile), + ?line {ok, OrigFI} = file:read_file_info(OrigFile), %% Write source file Priv = ?config(priv_dir, Config), Dir = filename:absname(Priv), % Get rid of trailing slash. Base = "beam_script", ErlFile = filename:join([Priv, Base ++ ".erl"]), - ?line ok = file:write_file(ErlFile, - ["-module(", Base, ").\n", + ?line ok = file:write_file(ErlFile, + ["\n-module(", Base, ").\n", "-export([main/1]).\n\n", string:join(Source, "\n"), "\n"]), %% Compile the code ?line {ok, _Mod, BeamCode} = compile:file(ErlFile, [binary]), - + %%%%%%% %% Create and run scripts without emulator flags %% With shebang NoArgsBase = Base ++ "_no_args_with_shebang", NoArgsFile = filename:join([Priv, NoArgsBase]), - ?line ok = file:write_file(NoArgsFile, + ?line ok = file:write_file(NoArgsFile, [Shebang, "\n", BeamCode]), - ?line ok = file:write_file_info(NoArgsFile, OrigFI), + ?line ok = file:write_file_info(NoArgsFile, OrigFI), ?line run(Dir, NoArgsBase ++ " -arg1 arg2 arg3", [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n" @@ -277,7 +283,7 @@ beam_script(Config) when is_list(Config) -> "unknown:[]\n" "ExitCode:0">>]), - ?line run(Dir, "", NoArgsBase ++ " -arg1 arg2 arg3", + ?line run_with_opts(Dir, "", NoArgsBase ++ " -arg1 arg2 arg3", [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n" "nostick:[]\n" "mnesia:[]\n" @@ -288,12 +294,12 @@ beam_script(Config) when is_list(Config) -> %% Without shebang NoArgsBase2 = Base ++ "_no_args_without_shebang", NoArgsFile2 = filename:join([Priv, NoArgsBase2]), - ?line ok = file:write_file(NoArgsFile2, + ?line ok = file:write_file(NoArgsFile2, ["Something else than shebang!!!", "\n", BeamCode]), - ?line ok = file:write_file_info(NoArgsFile2, OrigFI), + ?line ok = file:write_file_info(NoArgsFile2, OrigFI), - ?line run(Dir, "", NoArgsBase2 ++ " -arg1 arg2 arg3", + ?line run_with_opts(Dir, "", NoArgsBase2 ++ " -arg1 arg2 arg3", [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n" "nostick:[]\n" "mnesia:[]\n" @@ -305,9 +311,9 @@ beam_script(Config) when is_list(Config) -> NoArgsBase3 = Base ++ "_no_args_without_header", NoArgsFile3 = filename:join([Priv, NoArgsBase3]), ?line ok = file:write_file(NoArgsFile3, [BeamCode]), - ?line ok = file:write_file_info(NoArgsFile3, OrigFI), + ?line ok = file:write_file_info(NoArgsFile3, OrigFI), - ?line run(Dir, "", NoArgsBase3 ++ " -arg1 arg2 arg3", + ?line run_with_opts(Dir, "", NoArgsBase3 ++ " -arg1 arg2 arg3", [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n" "nostick:[]\n" "mnesia:[]\n" @@ -322,12 +328,12 @@ beam_script(Config) when is_list(Config) -> ArgsBase = Base ++ "_args", ArgsFile = filename:join([Priv, ArgsBase]), ?line ok = file:write_file(ArgsFile, - [Shebang, "\n", + [Shebang, "\n", Mode, "\n", Flags, "\n", BeamCode]), - ?line ok = file:write_file_info(ArgsFile, OrigFI), - + ?line ok = file:write_file_info(ArgsFile, OrigFI), + ?line run(Dir, ArgsBase ++ " -arg1 arg2 arg3", [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n" "nostick:[{nostick,[]}]\n" @@ -356,13 +362,13 @@ archive_script(Config) when is_list(Config) -> ?line ok = compile_app(TopDir, "archive_script_dict"), ?line ok = compile_app(TopDir, "archive_script_dummy"), ?line {ok, MainFiles} = file:list_dir(TopDir), - ?line ok = compile_files(MainFiles, TopDir, TopDir), - + ?line ok = compile_files(MainFiles, TopDir, TopDir), + %% Create the archive {ok, TopFiles} = file:list_dir(TopDir), ?line {ok, {_, ArchiveBin}} = zip:create(Archive, TopFiles, [memory, {compress, []}, {cwd, TopDir}]), - + %% Read the source script OrigFile = filename:join([DataDir, "emulator_flags"]), {ok, OrigBin} = file:read_file(OrigFile), @@ -371,73 +377,73 @@ archive_script(Config) when is_list(Config) -> Flags = "%%! -archive_script_dict foo bar" " -archive_script_dict foo" " -archive_script_dummy bar", - ?line {ok, OrigFI} = file:read_file_info(OrigFile), - + ?line {ok, OrigFI} = file:read_file_info(OrigFile), + %%%%%%% %% Create and run scripts without emulator flags - MainBase = "archive_script_main", - MainScript = filename:join([PrivDir, MainBase]), + MainBase = "archive_script_main", + MainScript = filename:join([PrivDir, MainBase]), %% With shebang - ?line ok = file:write_file(MainScript, + ?line ok = file:write_file(MainScript, [Shebang, "\n", Flags, "\n", ArchiveBin]), - ?line ok = file:write_file_info(MainScript, OrigFI), - + ?line ok = file:write_file_info(MainScript, OrigFI), + ?line run(PrivDir, MainBase ++ " -arg1 arg2 arg3", - [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n" + [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n" "dict:[{archive_script_dict,[\"foo\",\"bar\"]},{archive_script_dict,[\"foo\"]}]\n" "dummy:[{archive_script_dummy,[\"bar\"]}]\n" "priv:{ok,<<\"Some private data...\\n\">>}\n" "ExitCode:0">>]), - ?line run(PrivDir, "", MainBase ++ " -arg1 arg2 arg3", - [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n" + ?line run_with_opts(PrivDir, "", MainBase ++ " -arg1 arg2 arg3", + [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n" "dict:[{archive_script_dict,[\"foo\",\"bar\"]},{archive_script_dict,[\"foo\"]}]\n" "dummy:[{archive_script_dummy,[\"bar\"]}]\n" "priv:{ok,<<\"Some private data...\\n\">>}\n" "ExitCode:0">>]), - + ?line ok = file:rename(MainScript, MainScript ++ "_with_shebang"), %% Without shebang (no flags) - ?line ok = file:write_file(MainScript, + ?line ok = file:write_file(MainScript, ["Something else than shebang!!!", "\n", ArchiveBin]), - ?line ok = file:write_file_info(MainScript, OrigFI), - - ?line run(PrivDir, "", MainBase ++ " -arg1 arg2 arg3", - [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n" + ?line ok = file:write_file_info(MainScript, OrigFI), + + ?line run_with_opts(PrivDir, "", MainBase ++ " -arg1 arg2 arg3", + [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n" "dict:[]\n" "dummy:[]\n" "priv:{ok,<<\"Some private data...\\n\">>}\n" "ExitCode:0">>]), ?line ok = file:rename(MainScript, MainScript ++ "_without_shebang"), - + %% Plain archive without header (no flags) - + ?line ok = file:write_file(MainScript, [ArchiveBin]), - ?line ok = file:write_file_info(MainScript, OrigFI), - - ?line run(PrivDir, "", MainBase ++ " -arg1 arg2 arg3", - [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n" + ?line ok = file:write_file_info(MainScript, OrigFI), + + ?line run_with_opts(PrivDir, "", MainBase ++ " -arg1 arg2 arg3", + [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n" "dict:[]\n" "dummy:[]\n" "priv:{ok,<<\"Some private data...\\n\">>}\n" "ExitCode:0">>]), ?line ok = file:rename(MainScript, MainScript ++ "_without_header"), - + %%%%%%% %% Create and run scripts with emulator flags AltBase = "archive_script_alternate_main", AltScript = filename:join([PrivDir, AltBase]), - ?line ok = file:write_file(AltScript, + ?line ok = file:write_file(AltScript, [Shebang, "\n", Mode, "\n", Flags, " -escript main archive_script_main2\n", ArchiveBin]), - ?line ok = file:write_file_info(AltScript, OrigFI), + ?line ok = file:write_file_info(AltScript, OrigFI), ?line run(PrivDir, AltBase ++ " -arg1 arg2 arg3", [<<"main2:[\"-arg1\",\"arg2\",\"arg3\"]\n" @@ -445,7 +451,7 @@ archive_script(Config) when is_list(Config) -> "dummy:[{archive_script_dummy,[\"bar\"]}]\n" "priv:{ok,<<\"Some private data...\\n\">>}\n" "ExitCode:0">>]), - + ok. compile_app(TopDir, AppName) -> @@ -482,6 +488,254 @@ epp(Config) when is_list(Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +create_and_extract(Config) when is_list(Config) -> + {NewFile, FileInfo, + EmuArg, Source, + _ErlBase, ErlCode, + _BeamBase, BeamCode, + ArchiveBin} = + prepare_creation("create_and_extract", Config), + + Bodies = + [[{source, ErlCode}], + [{beam, BeamCode}], + [{archive, ArchiveBin}]], + + %% Verify all combinations of scripts with shebangs + [verify_sections(NewFile, FileInfo, S ++ C ++ E ++ B) || + S <- [[{shebang, default}], + [{shebang, "/usr/bin/env escript"}]], + C <- [[], + [{comment, undefined}], + [{comment, default}], + [{comment, "This is a nonsense comment"}]], + E <- [[], + [{emu_args, undefined}], + [{emu_args, EmuArg}]], + B <- [[{source, Source}] | Bodies]], + + %% Verify all combinations of scripts without shebangs + [verify_sections(NewFile, FileInfo, S ++ C ++ E ++ B) || + S <- [[], [{shebang, undefined}]], + C <- [[], [{comment, undefined}]], + E <- [[], [{emu_args, undefined}]], + B <- Bodies], + + %% Verify the compile_source option + file:delete(NewFile), + ?line ok = escript:create(NewFile, [{source, Source}]), + ?line {ok, [_, _, _, {source, Source}]} = escript:extract(NewFile, []), + ?line {ok, [_, _, _, {source, BeamCode2}]} = + escript:extract(NewFile, [compile_source]), + verify_sections(NewFile, FileInfo, + [{shebang, default}, + {comment, default}, + {beam, BeamCode2}]), + + file:delete(NewFile), + ok. + +prepare_creation(Base, Config) -> + %% Read the source + PrivDir = ?config(priv_dir, Config), + DataDir = ?config(data_dir, Config), + OrigFile = filename:join([DataDir,"emulator_flags"]), + ?line {ok, FileInfo} = file:read_file_info(OrigFile), + NewFile = filename:join([PrivDir, Base]), + ?line {ok, [{shebang, default}, + {comment, _}, + {emu_args, EmuArg}, + {source, Source}]} = + escript:extract(OrigFile, []), + + %% Compile the code + ErlFile = NewFile ++ ".erl", + ErlCode = list_to_binary(["\n-module(", Base, ").\n", + "-export([main/1]).\n\n", + Source, "\n\n"]), + ?line ok = file:write_file(ErlFile, ErlCode), + + %% Compile the code + ?line {ok, _Mod, BeamCode} = + compile:file(ErlFile, [binary, debug_info]), + + %% Create an archive + ?line {ok, {_, ArchiveBin}} = + zip:create("dummy_archive_name", + [{Base ++ ".erl", ErlCode}, + {Base ++ ".beam", BeamCode}], + [{compress, []}, memory]), + {NewFile, FileInfo, + EmuArg, Source, + Base ++ ".erl", ErlCode, + Base ++ ".beam", BeamCode, + ArchiveBin}. + +verify_sections(File, FileInfo, Sections) -> + io:format("~p:verify_sections(\n\t~p,\n\t~p,\n\t~p).\n", + [?MODULE, File, FileInfo, Sections]), + + %% Create + file:delete(File), + ?line ok = escript:create(File, Sections), + ?line ok = file:write_file_info(File, FileInfo), + + %% Run + Dir = filename:absname(filename:dirname(File)), + Base = filename:basename(File), + + HasArg = fun(Tag) -> + case lists:keysearch(Tag, 1, Sections) of + false -> false; + {value, {_, undefined}} -> false; + {value, _} -> true + end + end, + ExpectedMain = <<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n">>, + ExpectedOutput = + case HasArg(emu_args) of + true -> + <<"nostick:[{nostick,[]}]\n" + "mnesia:[{mnesia,[\"dir\",\"a/directory\"]},{mnesia,[\"debug\",\"verbose\"]}]\n" + "ERL_FLAGS=false\n" + "unknown:[]\n" + "ExitCode:0">>; + false -> + <<"nostick:[]\nmnesia:[]\nERL_FLAGS=false\nunknown:[]\nExitCode:0">> + end, + + InputArgs = Base ++ " -arg1 arg2 arg3", + Expected = <<ExpectedMain/binary, ExpectedOutput/binary>>, + case HasArg(shebang) of + true -> + ?line run(Dir, InputArgs, [Expected]); + false -> + ?line run_with_opts(Dir, [], InputArgs, [Expected]) + end, + + %% Verify + ?line {ok, Bin} = escript:create(binary, Sections), + ?line {ok, Read} = file:read_file(File), + ?line Bin = Read, % Assert + + Normalized = normalize_sections(Sections), + ?line {ok, Extracted} = escript:extract(File, []), + io:format("Normalized; ~p\n", [Normalized]), + io:format("Extracted ; ~p\n", [Extracted]), + ?line Normalized = Extracted, % Assert + ok. + +normalize_sections(Sections) -> + AtomToTuple = + fun(Val) -> + if + is_atom(Val) -> {Val, default}; + true -> Val + end + end, + case lists:map(AtomToTuple, [{K, V} || {K, V} <- Sections, V =/= undefined]) of + [{shebang, Shebang} | Rest] -> + [{shebang, Shebang} | + case Rest of + [{comment, Comment} | Rest2] -> + [{comment, Comment} | + case Rest2 of + [{emu_args, EmuArgs}, Body] -> + [{emu_args, EmuArgs}, Body]; + [Body] -> + [{emu_args, undefined}, Body] + end + ]; + [{emu_args, EmuArgs}, Body] -> + [{comment, undefined}, {emu_args, EmuArgs}, Body]; + [Body] -> + [{comment, undefined}, {emu_args, undefined}, Body] + end + ]; + [Body] -> + [{shebang, undefined}, {comment, undefined}, {emu_args, undefined}, Body] + end. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +foldl(Config) when is_list(Config) -> + {NewFile, _FileInfo, + _EmuArg, _Source, + ErlBase, ErlCode, + BeamBase, _BeamCode, + ArchiveBin} = + prepare_creation("foldl", Config), + + Collect = fun(Name, GetInfo, GetBin, Acc) -> + [{Name, GetInfo(), GetBin()} | Acc] + end, + + %% Get line numbers and the file attribute right + SourceFile = NewFile ++ ".erl", + <<_:1/binary, ErlCode2/binary>> = ErlCode, + ?line ok = file:write_file(SourceFile, ErlCode2), + ?line {ok, _Mod, BeamCode} = + compile:file(SourceFile, [binary, debug_info]), + + %% Verify source script + ?line ok = escript:create(SourceFile, [{source, ErlCode}]), + ?line {ok, [{".", _, BeamCode2}]} + = escript_foldl(Collect, [], SourceFile), + + ?line {ok, Abstr} = beam_lib:chunks(BeamCode, [abstract_code]), + ?line {ok, Abstr2} = beam_lib:chunks(BeamCode2, [abstract_code]), + %% io:format("abstr1=~p\n", [Abstr]), + %% io:format("abstr2=~p\n", [Abstr2]), + ?line Abstr = Abstr2, % Assert + + %% Verify beam script + ?line ok = escript:create(NewFile, [{beam, BeamCode}]), + ?line {ok, [{".", _, BeamCode}]} + = escript_foldl(Collect, [], NewFile), + + %% Verify archive scripts + ?line ok = escript:create(NewFile, [{archive, ArchiveBin}]), + ?line {ok, [{BeamBase, #file_info{}, _}, + {ErlBase, #file_info{}, _}]} + = escript_foldl(Collect, [], NewFile), + + ArchiveFiles = [{ErlBase, ErlCode}, {BeamBase, BeamCode}], + ?line ok = escript:create(NewFile, [{archive, ArchiveFiles, []}]), + ?line {ok, [{BeamBase, _, _}, + {ErlBase, _, _}]} + = escript_foldl(Collect, [], NewFile), + + ok. + +escript_foldl(Fun, Acc, File) -> + code:ensure_loaded(zip), + case erlang:function_exported(zip, foldl, 3) of + true -> + emulate_escript_foldl(Fun, Acc, File); + false -> + escript:foldl(Fun, Acc, File) + end. + +emulate_escript_foldl(Fun, Acc, File) -> + case escript:extract(File, [compile_source]) of + {ok, [_Shebang, _Comment, _EmuArgs, Body]} -> + case Body of + {source, BeamCode} -> + GetInfo = fun() -> file:read_file_info(File) end, + GetBin = fun() -> BeamCode end, + {ok, Fun(".", GetInfo, GetBin, Acc)}; + {beam, BeamCode} -> + GetInfo = fun() -> file:read_file_info(File) end, + GetBin = fun() -> BeamCode end, + {ok, Fun(".", GetInfo, GetBin, Acc)}; + {archive, ArchiveBin} -> + zip:foldl(Fun, Acc, {File, ArchiveBin}) + end; + {error, Reason} -> + {error, Reason} + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + run(Dir, Cmd0, Expected0) -> Expected = iolist_to_binary(expected_output(Expected0, Dir)), Cmd = case os:type() of @@ -490,7 +744,7 @@ run(Dir, Cmd0, Expected0) -> end, do_run(Dir, Cmd, Expected). -run(Dir, Opts, Cmd0, Expected) -> +run_with_opts(Dir, Opts, Cmd0, Expected) -> Cmd = case os:type() of {win32,_} -> "escript " ++ Opts ++ " " ++ filename:nativename(Dir) ++ "\\" ++ Cmd0; _ -> "escript " ++ Opts ++ " " ++ Dir ++ "/" ++ Cmd0 @@ -533,8 +787,8 @@ expected_output([data_dir|T], Data) -> [filename:nativename(Data)++Slash|expected_output(T, Data)]; expected_output([H|T], Data) -> [H|expected_output(T, Data)]; -expected_output([], _) -> +expected_output([], _) -> []; -expected_output(Bin, _) when is_binary(Bin) -> +expected_output(Bin, _) when is_binary(Bin) -> Bin. diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl index 13c87ca005..7f39dbe21f 100644 --- a/lib/stdlib/test/ets_SUITE.erl +++ b/lib/stdlib/test/ets_SUITE.erl @@ -33,7 +33,7 @@ -export([misc/1, dups/1, misc1/1, safe_fixtable/1, info/1, tab2list/1]). -export([files/1, tab2file/1, tab2file2/1, tab2file3/1, tabfile_ext1/1, tabfile_ext2/1, tabfile_ext3/1, tabfile_ext4/1]). --export([heavy/1, heavy_lookup/1, heavy_lookup_element/1]). +-export([heavy/1, heavy_lookup/1, heavy_lookup_element/1, heavy_concurrent/1]). -export([lookup_element/1, lookup_element_mult/1]). -export([fold/1]). -export([foldl_ordered/1, foldr_ordered/1, foldl/1, foldr/1, fold_empty/1]). @@ -63,7 +63,8 @@ meta_lookup_unnamed_read/1, meta_lookup_unnamed_write/1, meta_lookup_named_read/1, meta_lookup_named_write/1, meta_newdel_unnamed/1, meta_newdel_named/1]). --export([smp_insert/1, smp_fixed_delete/1, smp_unfix_fix/1, smp_select_delete/1, otp_8166/1]). +-export([smp_insert/1, smp_fixed_delete/1, smp_unfix_fix/1, smp_select_delete/1, + otp_8166/1, otp_8732/1]). -export([exit_large_table_owner/1, exit_many_large_table_owner/1, exit_many_tables_owner/1, @@ -89,9 +90,12 @@ match_delete_do/1, match_delete3_do/1, firstnext_do/1, slot_do/1, match1_do/1, match2_do/1, match_object_do/1, match_object2_do/1, misc1_do/1, safe_fixtable_do/1, info_do/1, dups_do/1, heavy_lookup_do/1, - heavy_lookup_element_do/1, member_do/1, otp_5340_do/1, otp_7665_do/1, meta_wb_do/1 + heavy_lookup_element_do/1, member_do/1, otp_5340_do/1, otp_7665_do/1, meta_wb_do/1, + do_heavy_concurrent/1 ]). +-export([t_select_reverse/1]). + -include("test_server.hrl"). init_per_testcase(Case, Config) -> @@ -126,10 +130,10 @@ 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_6842_select_1000, otp_7665, otp_8732, meta_wb, grow_shrink, grow_pseudo_deleted, shrink_pseudo_deleted, meta_smp, @@ -391,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, {16862,16072,16072,16078}), + ?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), @@ -402,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, {16849,16060,16048,16054}), + ?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), @@ -413,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, {16836,16048,16024,16030}), + ?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) @@ -786,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) -> @@ -3877,7 +3942,7 @@ make_sub_binary(List, Num) when is_list(List) -> {_,B} = split_binary(Bin, N+1), B. -heavy(suite) -> [heavy_lookup, heavy_lookup_element]. +heavy(suite) -> [heavy_lookup, heavy_lookup_element, heavy_concurrent]. %% Lookup stuff like crazy... heavy_lookup(doc) -> ["Performs multiple lookups for every key ", @@ -3940,6 +4005,44 @@ do_lookup_element(Tab, N, M) -> end. +heavy_concurrent(_Config) -> + repeat_for_opts(do_heavy_concurrent). + +do_heavy_concurrent(Opts) -> + ?line Size = 20000, + ?line EtsMem = etsmem(), + ?line Tab = ets:new(blupp, [set, public, {keypos, 2} | Opts]), + ?line ok = fill_tab2(Tab, 0, Size), + ?line Procs = lists:map( + fun (N) -> + spawn_link( + fun () -> + do_heavy_concurrent_proc(Tab, Size, N) + end) + end, + lists:seq(1, 500)), + ?line lists:foreach(fun (P) -> + M = erlang:monitor(process, P), + receive + {'DOWN', M, process, P, _} -> + ok + end + end, + Procs), + ?line true = ets:delete(Tab), + ?line verify_etsmem(EtsMem). + +do_heavy_concurrent_proc(_Tab, 0, _Offs) -> + done; +do_heavy_concurrent_proc(Tab, N, Offs) when (N+Offs) rem 100 == 0 -> + Data = {"here", are, "S O M E ", data, "toooooooooooooooooo", insert, + make_ref(), make_ref(), make_ref()}, + true=ets:insert(Tab, {{self(),Data}, N}), + do_heavy_concurrent_proc(Tab, N-1, Offs); +do_heavy_concurrent_proc(Tab, N, Offs) -> + _ = ets:lookup(Tab, N), + do_heavy_concurrent_proc(Tab, N-1, Offs). + fold(suite) -> [foldl_ordered, foldr_ordered, foldl, foldr, fold_empty]. @@ -5010,8 +5113,14 @@ verify_table_load(T) -> end. - - +otp_8732(doc) -> ["ets:select on a tree with NIL key object"]; +otp_8732(Config) when is_list(Config) -> + Tab = ets:new(noname,[ordered_set]), + filltabstr(Tab,999), + ets:insert(Tab,{[],"nasty NIL object"}), + ?line [] = ets:match(Tab,{'_',nomatch}), %% Will hang if bug not fixed + ok. + smp_select_delete(suite) -> []; smp_select_delete(doc) -> @@ -5336,7 +5445,7 @@ only_if_smp(Schedulers, Func) -> %% Repeat test function with different combination of table options %% repeat_for_opts(F) -> - repeat_for_opts(F, [write_concurrency]). + repeat_for_opts(F, [write_concurrency, read_concurrency]). repeat_for_opts(F, OptGenList) when is_atom(F) -> repeat_for_opts(fun(Opts) -> ?MODULE:F(Opts) end, OptGenList); @@ -5356,6 +5465,7 @@ repeat_for_opts(F, [Atom | Tail], AccList) when is_atom(Atom) -> repeat_for_opts(F, [repeat_for_opts_atom2list(Atom) | Tail ], AccList). repeat_for_opts_atom2list(all_types) -> [set,ordered_set,bag,duplicate_bag]; -repeat_for_opts_atom2list(write_concurrency) -> [{write_concurrency,false},{write_concurrency,true}]. +repeat_for_opts_atom2list(write_concurrency) -> [{write_concurrency,false},{write_concurrency,true}]; +repeat_for_opts_atom2list(read_concurrency) -> [{read_concurrency,false},{read_concurrency,true}]. diff --git a/lib/stdlib/test/gen_event_SUITE.erl b/lib/stdlib/test/gen_event_SUITE.erl index 8cbffaca56..4f7de451e3 100644 --- a/lib/stdlib/test/gen_event_SUITE.erl +++ b/lib/stdlib/test/gen_event_SUITE.erl @@ -23,9 +23,11 @@ -export([all/1]). -export([start/1, test_all/1, add_handler/1, add_sup_handler/1, delete_handler/1, swap_handler/1, swap_sup_handler/1, - notify/1, sync_notify/1, call/1, info/1, hibernate/1]). + notify/1, sync_notify/1, call/1, info/1, hibernate/1, + call_format_status/1, error_format_status/1]). -all(suite) -> {req, [stdlib], [start, test_all, hibernate]}. +all(suite) -> {req, [stdlib], [start, test_all, hibernate, + call_format_status, error_format_status]}. %% -------------------------------------- %% Start an event manager. @@ -844,3 +846,56 @@ info(Config) when is_list(Config) -> ?line ok = gen_event:stop(my_dummy_handler), ok. + +call_format_status(suite) -> + []; +call_format_status(doc) -> + ["Test that sys:get_status/1,2 calls format_status/2"]; +call_format_status(Config) when is_list(Config) -> + ?line {ok, Pid} = gen_event:start({local, my_dummy_handler}), + %% State here intentionally differs from what we expect from format_status + State = self(), + FmtState = "dummy1_h handler state", + ?line ok = gen_event:add_handler(my_dummy_handler, dummy1_h, [State]), + ?line Status1 = sys:get_status(Pid), + ?line Status2 = sys:get_status(Pid, 5000), + ?line ok = gen_event:stop(Pid), + ?line {status, Pid, _, [_, _, Pid, [], Data1]} = Status1, + ?line HandlerInfo1 = proplists:get_value(items, Data1), + ?line {"Installed handlers", [{_,dummy1_h,_,FmtState,_}]} = HandlerInfo1, + ?line {status, Pid, _, [_, _, Pid, [], Data2]} = Status2, + ?line HandlerInfo2 = proplists:get_value(items, Data2), + ?line {"Installed handlers", [{_,dummy1_h,_,FmtState,_}]} = HandlerInfo2, + ok. + +error_format_status(suite) -> + []; +error_format_status(doc) -> + ["Test that a handler error calls format_status/2"]; +error_format_status(Config) when is_list(Config) -> + ?line error_logger_forwarder:register(), + OldFl = process_flag(trap_exit, true), + State = self(), + ?line {ok, Pid} = gen_event:start({local, my_dummy_handler}), + ?line ok = gen_event:add_sup_handler(my_dummy_handler, dummy1_h, [State]), + ?line ok = gen_event:notify(my_dummy_handler, do_crash), + ?line receive + {gen_event_EXIT,dummy1_h,{'EXIT',_}} -> ok + after 5000 -> + ?t:fail(exit_gen_event) + end, + FmtState = "dummy1_h handler state", + receive + {error,_GroupLeader, {Pid, + "** gen_event handler"++_, + [dummy1_h,my_dummy_handler,do_crash, + FmtState, _]}} -> + ok; + Other -> + ?line io:format("Unexpected: ~p", [Other]), + ?line ?t:fail() + end, + ?t:messages_get(), + ?line ok = gen_event:stop(Pid), + process_flag(trap_exit, OldFl), + ok. diff --git a/lib/stdlib/test/gen_fsm_SUITE.erl b/lib/stdlib/test/gen_fsm_SUITE.erl index 23c1d9a193..dd120f8c05 100644 --- a/lib/stdlib/test/gen_fsm_SUITE.erl +++ b/lib/stdlib/test/gen_fsm_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(gen_fsm_SUITE). @@ -30,7 +30,7 @@ -export([shutdown/1]). --export([sys/1, sys1/1, call_format_status/1]). +-export([sys/1, sys1/1, call_format_status/1, error_format_status/1]). -export([hibernate/1,hiber_idle/3,hiber_wakeup/3,hiber_idle/2,hiber_wakeup/2]). @@ -305,7 +305,7 @@ shutdown(Config) when is_list(Config) -> ok. -sys(suite) -> [sys1, call_format_status]. +sys(suite) -> [sys1, call_format_status, error_format_status]. sys1(Config) when is_list(Config) -> ?line {ok, Pid} = @@ -320,10 +320,53 @@ sys1(Config) when is_list(Config) -> call_format_status(Config) when is_list(Config) -> ?line {ok, Pid} = gen_fsm:start(gen_fsm_SUITE, [], []), ?line Status = sys:get_status(Pid), - ?line {status, Pid, _Mod, [_PDict, running, _Parent, _, Data]} = Status, + ?line {status, Pid, _Mod, [_PDict, running, _, _, Data]} = Status, ?line [format_status_called | _] = lists:reverse(Data), - ?line stop_it(Pid). + ?line stop_it(Pid), + + %% check that format_status can handle a name being an atom (pid is + %% already checked by the previous test) + ?line {ok, Pid2} = gen_fsm:start({local, gfsm}, gen_fsm_SUITE, [], []), + ?line Status2 = sys:get_status(gfsm), + ?line {status, Pid2, _Mod, [_PDict2, running, _, _, Data2]} = Status2, + ?line [format_status_called | _] = lists:reverse(Data2), + ?line stop_it(Pid2), + %% check that format_status can handle a name being a term other than a + %% pid or atom + GlobalName1 = {global, "CallFormatStatus"}, + ?line {ok, Pid3} = gen_fsm:start(GlobalName1, gen_fsm_SUITE, [], []), + ?line Status3 = sys:get_status(GlobalName1), + ?line {status, Pid3, _Mod, [_PDict3, running, _, _, Data3]} = Status3, + ?line [format_status_called | _] = lists:reverse(Data3), + ?line stop_it(Pid3), + GlobalName2 = {global, {name, "term"}}, + ?line {ok, Pid4} = gen_fsm:start(GlobalName2, gen_fsm_SUITE, [], []), + ?line Status4 = sys:get_status(GlobalName2), + ?line {status, Pid4, _Mod, [_PDict4, running, _, _, Data4]} = Status4, + ?line [format_status_called | _] = lists:reverse(Data4), + ?line stop_it(Pid4). + +error_format_status(Config) when is_list(Config) -> + ?line error_logger_forwarder:register(), + OldFl = process_flag(trap_exit, true), + StateData = "called format_status", + ?line {ok, Pid} = gen_fsm:start(gen_fsm_SUITE, {state_data, StateData}, []), + %% bad return value in the gen_fsm loop + ?line {'EXIT',{{bad_return_value, badreturn},_}} = + (catch gen_fsm:sync_send_event(Pid, badreturn)), + receive + {error,_GroupLeader,{Pid, + "** State machine"++_, + [Pid,{_,_,badreturn},idle,StateData,_]}} -> + ok; + Other -> + ?line io:format("Unexpected: ~p", [Other]), + ?line ?t:fail() + end, + ?t:messages_get(), + process_flag(trap_exit, OldFl), + ok. %% Hibernation hibernate(suite) -> []; @@ -704,6 +747,8 @@ init(hiber) -> {ok, hiber_idle, []}; init(hiber_now) -> {ok, hiber_idle, [], hibernate}; +init({state_data, StateData}) -> + {ok, idle, StateData}; init(_) -> {ok, idle, state_data}. @@ -844,5 +889,7 @@ handle_sync_event(stop_shutdown_reason, _From, _State, Data) -> handle_sync_event({get, _Pid}, _From, State, Data) -> {reply, {state, State, Data}, State, Data}. -format_status(_Opt, [_Pdict, _StateData]) -> +format_status(terminate, [_Pdict, StateData]) -> + StateData; +format_status(normal, [_Pdict, _StateData]) -> [format_status_called]. diff --git a/lib/stdlib/test/gen_server_SUITE.erl b/lib/stdlib/test/gen_server_SUITE.erl index 6efdce78a1..99388ba2e3 100644 --- a/lib/stdlib/test/gen_server_SUITE.erl +++ b/lib/stdlib/test/gen_server_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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(gen_server_SUITE). @@ -30,7 +30,8 @@ call_remote_n1/1, call_remote_n2/1, call_remote_n3/1, spec_init/1, spec_init_local_registered_parent/1, spec_init_global_registered_parent/1, - otp_5854/1, hibernate/1, otp_7669/1, call_format_status/1 + otp_5854/1, hibernate/1, otp_7669/1, call_format_status/1, + error_format_status/1, call_with_huge_message_queue/1 ]). % spawn export @@ -51,7 +52,9 @@ all(suite) -> call_remote_n2, call_remote_n3, spec_init, spec_init_local_registered_parent, spec_init_global_registered_parent, - otp_5854, hibernate, otp_7669, call_format_status]. + otp_5854, hibernate, otp_7669, + call_format_status, error_format_status, + call_with_huge_message_queue]. -define(default_timeout, ?t:minutes(1)). @@ -895,15 +898,105 @@ call_format_status(doc) -> ["Test that sys:get_status/1,2 calls format_status/2"]; call_format_status(Config) when is_list(Config) -> ?line {ok, Pid} = gen_server:start_link({local, call_format_status}, - gen_server_SUITE, [], []), + ?MODULE, [], []), ?line Status1 = sys:get_status(call_format_status), ?line {status, Pid, _Mod, [_PDict, running, _Parent, _, Data1]} = Status1, ?line [format_status_called | _] = lists:reverse(Data1), ?line Status2 = sys:get_status(call_format_status, 5000), ?line {status, Pid, _Mod, [_PDict, running, _Parent, _, Data2]} = Status2, ?line [format_status_called | _] = lists:reverse(Data2), + + %% check that format_status can handle a name being a pid (atom is + %% already checked by the previous test) + ?line {ok, Pid3} = gen_server:start_link(gen_server_SUITE, [], []), + ?line Status3 = sys:get_status(Pid3), + ?line {status, Pid3, _Mod, [_PDict3, running, _Parent, _, Data3]} = Status3, + ?line [format_status_called | _] = lists:reverse(Data3), + + %% check that format_status can handle a name being a term other than a + %% pid or atom + GlobalName1 = {global, "CallFormatStatus"}, + ?line {ok, Pid4} = gen_server:start_link(GlobalName1, + gen_server_SUITE, [], []), + ?line Status4 = sys:get_status(Pid4), + ?line {status, Pid4, _Mod, [_PDict4, running, _Parent, _, Data4]} = Status4, + ?line [format_status_called | _] = lists:reverse(Data4), + GlobalName2 = {global, {name, "term"}}, + ?line {ok, Pid5} = gen_server:start_link(GlobalName2, + gen_server_SUITE, [], []), + ?line Status5 = sys:get_status(GlobalName2), + ?line {status, Pid5, _Mod, [_PDict5, running, _Parent, _, Data5]} = Status5, + ?line [format_status_called | _] = lists:reverse(Data5), + ok. + +%% Verify that error termination correctly calls our format_status/2 fun +%% +error_format_status(suite) -> + []; +error_format_status(doc) -> + ["Test that an error termination calls format_status/2"]; +error_format_status(Config) when is_list(Config) -> + ?line error_logger_forwarder:register(), + OldFl = process_flag(trap_exit, true), + State = "called format_status", + ?line {ok, Pid} = gen_server:start_link(?MODULE, {state, State}, []), + ?line {'EXIT',{crashed,_}} = (catch gen_server:call(Pid, crash)), + receive + {'EXIT', Pid, crashed} -> + ok + end, + receive + {error,_GroupLeader,{Pid, + "** Generic server"++_, + [Pid,crash,State,crashed]}} -> + ok; + Other -> + ?line io:format("Unexpected: ~p", [Other]), + ?line ?t:fail() + end, + ?t:messages_get(), + process_flag(trap_exit, OldFl), + ok. + +%% Test that the time for a huge message queue is not +%% significantly slower than with an empty message queue. +call_with_huge_message_queue(Config) when is_list(Config) -> + ?line Pid = spawn_link(fun echo_loop/0), + + ?line {Time,ok} = tc(fun() -> calls(10, Pid) end), + + ?line [self() ! {msg,N} || N <- lists:seq(1, 500000)], + erlang:garbage_collect(), + ?line {NewTime,ok} = tc(fun() -> calls(10, Pid) end), + io:format("Time for empty message queue: ~p", [Time]), + io:format("Time for huge message queue: ~p", [NewTime]), + + case (NewTime+1) / (Time+1) of + Q when Q < 10 -> + ok; + Q -> + io:format("Q = ~p", [Q]), + ?line ?t:fail() + end, ok. +calls(0, _) -> ok; +calls(N, Pid) -> + {ultimate_answer,42} = call(Pid, {ultimate_answer,42}), + calls(N-1, Pid). + +call(Pid, Msg) -> + gen_server:call(Pid, Msg, infinity). + +tc(Fun) -> + timer:tc(erlang, apply, [Fun,[]]). + +echo_loop() -> + receive + {'$gen_call',{Pid,Ref},Msg} -> + Pid ! {Ref,Msg}, + echo_loop() + end. %%-------------------------------------------------------------- %% Help functions to spec_init_* @@ -1064,5 +1157,7 @@ terminate({From, stopped_info}, _State) -> terminate(_Reason, _State) -> ok. -format_status(_Opt, [_PDict, _State]) -> - [format_status_called]. +format_status(terminate, [_PDict, State]) -> + State; +format_status(normal, [_PDict, _State]) -> + format_status_called. diff --git a/lib/stdlib/test/io_proto_SUITE.erl b/lib/stdlib/test/io_proto_SUITE.erl index 93159fbd5b..d9672a8c7b 100644 --- a/lib/stdlib/test/io_proto_SUITE.erl +++ b/lib/stdlib/test/io_proto_SUITE.erl @@ -17,6 +17,7 @@ %% %CopyrightEnd% %% -module(io_proto_SUITE). +-compile(r12). -export([all/1]). 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/test/qlc_SUITE.erl b/lib/stdlib/test/qlc_SUITE.erl index ff11ebc6bf..e21de8770a 100644 --- a/lib/stdlib/test/qlc_SUITE.erl +++ b/lib/stdlib/test/qlc_SUITE.erl @@ -1,25 +1,26 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% 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% %% %%%---------------------------------------------------------------- %%% Purpose:Test Suite for the 'qlc' module. %%%----------------------------------------------------------------- -module(qlc_SUITE). +-compile(r12). -define(QLC, qlc). -define(QLCs, "qlc"). @@ -3183,7 +3184,9 @@ lookup2(Config) when is_list(Config) -> [] = qlc:e(Q), false = lookup_keys(Q) end, [{1,b},{2,3}])">>, - {warnings,[{{3,48},qlc,nomatch_filter}]}}, + {warnings,[{2,sys_core_fold,nomatch_guard}, + {3,qlc,nomatch_filter}, + {3,sys_core_fold,{eval_failure,badarg}}]}}, <<"etsc(fun(E) -> Q = qlc:q([X || {X} <- ets:table(E), element(1,{X}) =:= 1]), diff --git a/lib/stdlib/test/re_SUITE.erl b/lib/stdlib/test/re_SUITE.erl index 02683f9f1a..46a84d4e24 100644 --- a/lib/stdlib/test/re_SUITE.erl +++ b/lib/stdlib/test/re_SUITE.erl @@ -18,12 +18,12 @@ %% -module(re_SUITE). --export([all/1, pcre/1,compile_options/1,run_options/1,combined_options/1,replace_autogen/1,global_capture/1,replace_input_types/1,replace_return/1,split_autogen/1,split_options/1,split_specials/1,error_handling/1,pcre_cve_2008_2371/1]). +-export([all/1, pcre/1,compile_options/1,run_options/1,combined_options/1,replace_autogen/1,global_capture/1,replace_input_types/1,replace_return/1,split_autogen/1,split_options/1,split_specials/1,error_handling/1,pcre_cve_2008_2371/1,pcre_compile_workspace_overflow/1,re_infinite_loop/1]). -include("test_server.hrl"). -include_lib("kernel/include/file.hrl"). -all(suite) -> [pcre,compile_options,run_options,combined_options,replace_autogen,global_capture,replace_input_types,replace_return,split_autogen,split_options,split_specials,error_handling,pcre_cve_2008_2371]. +all(suite) -> [pcre,compile_options,run_options,combined_options,replace_autogen,global_capture,replace_input_types,replace_return,split_autogen,split_options,split_specials,error_handling,pcre_cve_2008_2371,pcre_compile_workspace_overflow,re_infinite_loop]. pcre(doc) -> ["Run all applicable tests from the PCRE testsuites."]; @@ -544,3 +544,25 @@ pcre_cve_2008_2371(Config) when is_list(Config) -> %% Make sure it doesn't crash the emulator. re:compile(<<"(?i)[\xc3\xa9\xc3\xbd]|[\xc3\xa9\xc3\xbdA]">>, [unicode]), ok. + +pcre_compile_workspace_overflow(doc) -> + "Patch from http://vcs.pcre.org/viewvc/code/trunk/pcre_compile.c?r1=504&r2=505&view=patch"; +pcre_compile_workspace_overflow(Config) when is_list(Config) -> + N = 819, + ?line {error,{"internal error: overran compiling workspace",799}} = + re:compile([lists:duplicate(N, $(), lists:duplicate(N, $))]), + ok. +re_infinite_loop(doc) -> + "Make sure matches that really loop infinitely actually fail"; +re_infinite_loop(Config) when is_list(Config) -> + Dog = ?t:timetrap(?t:minutes(1)), + ?line Str = + "http:/www.flickr.com/slideShow/index.gne?group_id=&user_id=69845378@N0", + ?line EMail_regex = "[a-z0-9!#$%&'*+/=?^_`{|}~-]+" + ++ "(\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*" + ++ "@.*([a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+" + ++ "([a-zA-Z]{2}|com|org|net|gov|mil" + ++ "|biz|info|mobi|name|aero|jobs|museum)", + ?line nomatch = re:run(Str, EMail_regex), + ?t:timetrap_cancel(Dog), + ok. diff --git a/lib/stdlib/test/timer_simple_SUITE.erl b/lib/stdlib/test/timer_simple_SUITE.erl index 021a22c61b..6aa2b7b945 100644 --- a/lib/stdlib/test/timer_simple_SUITE.erl +++ b/lib/stdlib/test/timer_simple_SUITE.erl @@ -224,11 +224,19 @@ cancel2(Config) when is_list(Config) -> tc(doc) -> "Test sleep/1 and tc/3."; tc(suite) -> []; tc(Config) when is_list(Config) -> - % This should both sleep and tc - ?line {Res, ok} = timer:tc(timer, sleep, [500]), - ?line ok = if - Res < 500*1000 -> {too_early, Res}; % Too early - Res > 800*1000 -> {too_late, Res}; % Too much time + % This should both sleep and tc/3 + ?line {Res1, ok} = timer:tc(timer, sleep, [500]), + ?line ok = if + Res1 < 500*1000 -> {too_early, Res1}; % Too early + Res1 > 800*1000 -> {too_late, Res1}; % Too much time + true -> ok + end, + + % This should both sleep and tc/2 + ?line {Res2, ok} = timer:tc(fun(T) -> timer:sleep(T) end, [500]), + ?line ok = if + Res2 < 500*1000 -> {too_early, Res2}; % Too early + Res2 > 800*1000 -> {too_late, Res2}; % Too much time true -> ok end, diff --git a/lib/stdlib/test/zip_SUITE.erl b/lib/stdlib/test/zip_SUITE.erl index 12ca655000..48b14396c1 100644 --- a/lib/stdlib/test/zip_SUITE.erl +++ b/lib/stdlib/test/zip_SUITE.erl @@ -18,12 +18,13 @@ %% -module(zip_SUITE). --export([all/1, borderline/1, atomic/1, +-export([all/1, borderline/1, atomic/1, bad_zip/1, unzip_from_binary/1, unzip_to_binary/1, zip_to_binary/1, unzip_options/1, zip_options/1, list_dir_options/1, aliases/1, openzip_api/1, zip_api/1, unzip_jar/1, - compress_control/1]). + compress_control/1, + foldl/1]). -include("test_server.hrl"). -include("test_server_line.hrl"). @@ -35,7 +36,8 @@ all(suite) -> [borderline, atomic, bad_zip, zip_to_binary, unzip_options, zip_options, list_dir_options, aliases, openzip_api, zip_api, unzip_jar, - compress_control]. + compress_control, + foldl]. borderline(doc) -> ["Test creating, listing and extracting one file from an archive " @@ -110,17 +112,17 @@ get_data(Port, Expect) -> {Port, {data, Bytes}} -> get_data(Port, match_output(Bytes, Expect, Port)); {Port, eof} -> - Port ! {self(), close}, + Port ! {self(), close}, receive {Port, closed} -> true - end, + end, receive - {'EXIT', Port, _} -> + {'EXIT', Port, _} -> ok after 1 -> % force context switch ok - end, + end, match_output(eof, Expect, Port) end. @@ -290,7 +292,7 @@ unzip_options(Config) when is_list(Config) -> DataDir = ?config(data_dir, Config), PrivDir = ?config(priv_dir, Config), Long = filename:join(DataDir, "abc.zip"), - + %% create a temp directory Subdir = filename:join(PrivDir, "t"), ok = file:make_dir(Subdir), @@ -303,7 +305,7 @@ unzip_options(Config) when is_list(Config) -> %% Verify. ?line true = (length(FList) =:= length(RetList)), - ?line lists:foreach(fun(F)-> {ok,B} = file:read_file(filename:join(DataDir, F)), + ?line lists:foreach(fun(F)-> {ok,B} = file:read_file(filename:join(DataDir, F)), {ok,B} = file:read_file(filename:join(Subdir, F)) end, FList), ?line lists:foreach(fun(F)-> ok = file:delete(F) end, @@ -321,7 +323,7 @@ unzip_jar(Config) when is_list(Config) -> DataDir = ?config(data_dir, Config), PrivDir = ?config(priv_dir, Config), JarFile = filename:join(DataDir, "test.jar"), - + %% create a temp directory Subdir = filename:join(PrivDir, "jartest"), ok = file:make_dir(Subdir), @@ -479,7 +481,7 @@ unzip_to_binary(Config) when is_list(Config) -> DataDir = ?config(data_dir, Config), PrivDir = ?config(priv_dir, Config), - delete_all_in(PrivDir), + delete_all_in(PrivDir), file:set_cwd(PrivDir), Long = filename:join(DataDir, "abc.zip"), @@ -595,17 +597,17 @@ do_delete_files([],Cnt) -> Cnt; do_delete_files([Item|Rest], Cnt) -> case file:delete(Item) of - ok -> + ok -> DelCnt = 1; {error,eperm} -> file:change_mode(Item, 8#777), DelCnt = delete_files(filelib:wildcard(filename:join(Item, "*"))), - file:del_dir(Item); + file:del_dir(Item); {error,eacces} -> %% We'll see about that! file:change_mode(Item, 8#777), case file:delete(Item) of - ok -> + ok -> DelCnt = 1; {error,_} -> erlang:yield(), @@ -643,22 +645,22 @@ compress_control(Config) when is_list(Config) -> ], test_compress_control(Dir, - Files, + Files, [{compress, []}], []), test_compress_control(Dir, - Files, + Files, [{uncompress, all}], []), test_compress_control(Dir, - Files, + Files, [{uncompress, []}], [".txt", ".exe", ".zip", ".lzh", ".arj"]), test_compress_control(Dir, - Files, + Files, [], [".txt", ".exe"]), @@ -686,7 +688,7 @@ test_compress_control(Dir, Files, ZipOptions, Expected) -> create_files(Files), {ok, Zip} = zip:create(Zip, [Dir], ZipOptions), - + {ok, OpenZip} = zip:openzip_open(Zip, [memory]), {ok,[#zip_comment{comment = ""} | ZipList]} = zip:openzip_list_dir(OpenZip), io:format("compress_control: -> ~p -> ~p\n -> ~pn", [Expected, ZipOptions, ZipList]), @@ -698,19 +700,19 @@ test_compress_control(Dir, Files, ZipOptions, Expected) -> delete_files(lists:reverse(Names)), % Remove plain files before directories ok. - + verify_compression([{Name, Kind, _Filler} | Files], ZipList, OpenZip, ZipOptions, Expected) -> {Name2, BinSz} = case Kind of - dir -> + dir -> {Name ++ "/", 0}; - _ -> + _ -> {ok, {Name, Bin}} = zip:openzip_get(Name, OpenZip), {Name, size(Bin)} end, {Name2, {value, ZipFile}} = {Name2, lists:keysearch(Name2, #zip_file.name, ZipList)}, #zip_file{info = #file_info{size = InfoSz, type = InfoType}, comp_size = InfoCompSz} = ZipFile, - + Ext = filename:extension(Name), IsComp = is_compressed(Ext, Kind, ZipOptions), ExpComp = lists:member(Ext, Expected), @@ -757,3 +759,33 @@ extensions([H | T], Old) -> extensions([], Old) -> Old. +foldl(Config) -> + PrivDir = ?config(priv_dir, Config), + File = filename:join([PrivDir, "foldl.zip"]), + + FooBin = <<"FOO">>, + BarBin = <<"BAR">>, + Files = [{"foo", FooBin}, {"bar", BarBin}], + ?line {ok, {File, Bin}} = zip:create(File, Files, [memory]), + ZipFun = fun(N, I, B, Acc) -> [{N, B(), I()} | Acc] end, + ?line {ok, FileSpec} = zip:foldl(ZipFun, [], {File, Bin}), + ?line [{"bar", BarBin, #file_info{}}, {"foo", FooBin, #file_info{}}] = FileSpec, + ?line {ok, {File, Bin}} = zip:create(File, lists:reverse(FileSpec), [memory]), + ?line {foo_bin, FooBin} = + try + zip:foldl(fun("foo", _, B, _) -> throw(B()); (_, _, _, Acc) -> Acc end, [], {File, Bin}) + catch + throw:FooBin -> + {foo_bin, FooBin} + end, + ?line ok = file:write_file(File, Bin), + ?line {ok, FileSpec} = zip:foldl(ZipFun, [], File), + + ?line {error, einval} = zip:foldl(fun() -> ok end, [], File), + ?line {error, einval} = zip:foldl(ZipFun, [], 42), + ?line {error, einval} = zip:foldl(ZipFun, [], {File, 42}), + + ?line ok = file:delete(File), + ?line {error, enoent} = zip:foldl(ZipFun, [], File), + + ok. diff --git a/lib/stdlib/vsn.mk b/lib/stdlib/vsn.mk index 75dc7dc62f..1757d35160 100644 --- a/lib/stdlib/vsn.mk +++ b/lib/stdlib/vsn.mk @@ -1,2 +1 @@ -STDLIB_VSN = 1.16.5 - +STDLIB_VSN = 1.17.1 diff --git a/lib/syntax_tools/doc/src/notes.xml b/lib/syntax_tools/doc/src/notes.xml index a3b842b50b..fca93a27d9 100644 --- a/lib/syntax_tools/doc/src/notes.xml +++ b/lib/syntax_tools/doc/src/notes.xml @@ -31,6 +31,21 @@ <p>This document describes the changes made to the Syntax_Tools application.</p> +<section><title>Syntax_Tools 1.6.6</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Minor changes and clean-ups.</p> + <p> + Own Id: OTP-8709</p> + </item> + </list> + </section> + +</section> + <section><title>Syntax_Tools 1.6.5</title> <section><title>Improvements and New Features</title> diff --git a/lib/syntax_tools/src/erl_comment_scan.erl b/lib/syntax_tools/src/erl_comment_scan.erl index 09ce21a428..108ab3bffd 100644 --- a/lib/syntax_tools/src/erl_comment_scan.erl +++ b/lib/syntax_tools/src/erl_comment_scan.erl @@ -26,6 +26,7 @@ -export([file/1, join_lines/1, scan_lines/1, string/1]). +-export_type([comment/0]). %% ===================================================================== @@ -273,12 +274,8 @@ join_lines([], Txt, L, Col, Ind) -> filename([C|T]) when is_integer(C), C > 0, C =< 255 -> [C | filename(T)]; -filename([H|T]) -> - filename(H) ++ filename(T); filename([]) -> []; -filename(N) when is_atom(N) -> - atom_to_list(N); filename(N) -> report_error("bad filename: `~P'.", [N, 25]), exit(error). diff --git a/lib/syntax_tools/src/erl_prettypr.erl b/lib/syntax_tools/src/erl_prettypr.erl index 606441bcf1..c2c72d1ed2 100644 --- a/lib/syntax_tools/src/erl_prettypr.erl +++ b/lib/syntax_tools/src/erl_prettypr.erl @@ -384,7 +384,7 @@ lay_postcomments(Cs, D) -> beside(D, floating(break(stack_comments(Cs, true)), 1, 0)). %% Format (including padding, if `Pad' is `true', otherwise not) -%% and stack the listed comments above each other, +%% and stack the listed comments above each other. stack_comments([C | Cs], Pad) -> D = stack_comment_lines(erl_syntax:comment_text(C)), @@ -405,9 +405,7 @@ stack_comments([C | Cs], Pad) -> D1; % done _ -> above(D1, stack_comments(Cs, Pad)) - end; -stack_comments([], _) -> - empty(). + end. %% Stack lines of text above each other and prefix each string in %% the list with a single `%' character. diff --git a/lib/syntax_tools/src/erl_recomment.erl b/lib/syntax_tools/src/erl_recomment.erl index 145bbc6f37..94e760dad7 100644 --- a/lib/syntax_tools/src/erl_recomment.erl +++ b/lib/syntax_tools/src/erl_recomment.erl @@ -486,7 +486,7 @@ build_tree(Node) -> %% Include L, while preserving Min =< Max. tree_node(minpos(L, Min), - max(L, Max), + erlang:max(L, Max), erl_syntax:type(Node), erl_syntax:get_attrs(Node), Subtrees) @@ -507,7 +507,7 @@ build_list(Ts) -> build_list([T | Ts], Min, Max, Ack) -> Node = build_tree(T), Min1 = minpos(node_min(Node), Min), - Max1 = max(node_max(Node), Max), + Max1 = erlang:max(node_max(Node), Max), build_list(Ts, Min1, Max1, [Node | Ack]); build_list([], Min, Max, Ack) -> list_node(Min, Max, lists:reverse(Ack)). @@ -518,7 +518,7 @@ build_list_list(Ls) -> build_list_list([L | Ls], Min, Max, Ack) -> Node = build_list(L), Min1 = minpos(node_min(Node), Min), - Max1 = max(node_max(Node), Max), + Max1 = erlang:max(node_max(Node), Max), build_list_list(Ls, Min1, Max1, [Node | Ack]); build_list_list([], Min, Max, Ack) -> {lists:reverse(Ack), Min, Max}. @@ -723,9 +723,6 @@ tree_node_attrs(#tree{attrs = Attrs}) -> %% Just the generic "maximum" function -max(X, Y) when X > Y -> X; -max(_, Y) -> Y. - %% Return the least positive integer of X and Y, or zero if none of them %% are positive. (This is necessary for computing minimum source line %% numbers, since zero (or negative) numbers may occur, but they diff --git a/lib/syntax_tools/src/erl_syntax.erl b/lib/syntax_tools/src/erl_syntax.erl index 9a2967d550..a40bf83c5a 100644 --- a/lib/syntax_tools/src/erl_syntax.erl +++ b/lib/syntax_tools/src/erl_syntax.erl @@ -309,6 +309,7 @@ data/1, is_tree/1]). +-export_type([forms/0, syntaxTree/0, syntaxTreeAttributes/0]). %% ===================================================================== %% IMPLEMENTATION NOTES: diff --git a/lib/syntax_tools/src/erl_syntax_lib.erl b/lib/syntax_tools/src/erl_syntax_lib.erl index 5c4e074488..4808971a59 100644 --- a/lib/syntax_tools/src/erl_syntax_lib.erl +++ b/lib/syntax_tools/src/erl_syntax_lib.erl @@ -46,6 +46,8 @@ new_variable_names/2, new_variable_names/3, strip_comments/1, to_comment/1, to_comment/2, to_comment/3, variables/1]). +-export_type([info_pair/0]). + %% ===================================================================== -type ordset(X) :: [X]. % XXX: TAKE ME OUT @@ -400,10 +402,7 @@ new_variable_name(N, R, _T, F, S) -> %% implementation of `sets'. start_range(S) -> - max(sets:size(S) * ?START_RANGE_FACTOR, ?MINIMUM_RANGE). - -max(X, Y) when X > Y -> X; -max(_, Y) -> Y. + erlang:max(sets:size(S) * ?START_RANGE_FACTOR, ?MINIMUM_RANGE). %% The previous number might or might not be used to compute the %% next number to be tried. It is currently not used. diff --git a/lib/syntax_tools/src/igor.erl b/lib/syntax_tools/src/igor.erl index e92e9593b6..702b399615 100644 --- a/lib/syntax_tools/src/igor.erl +++ b/lib/syntax_tools/src/igor.erl @@ -699,7 +699,7 @@ merge_files(Name, Trees, Files, Opts) -> options :: [option()] }). --spec merge_sources(atom(), erl_syntax:forms(), [option()]) -> +-spec merge_sources(atom(), [erl_syntax:forms()], [option()]) -> {erl_syntax:syntaxTree(), [stubDescriptor()]}. merge_sources(Name, Sources, Opts) -> @@ -782,12 +782,12 @@ merge_sources_1(Name, Modules, Trees, Opts) -> %% however not "safe" by default. If no modules are explicitly %% specified as static, it is assumed that *all* are static. Static0 = ordsets:from_list(proplists:append_values(static, Opts)), - case proplists:is_defined(static, Opts) of - false -> - Static = All; - true -> - Static = ordsets:add_element(Name, Static0) - end, + Static = case proplists:is_defined(static, Opts) of + false -> + All; + true -> + ordsets:add_element(Name, Static0) + end, check_module_names(Static, All, "declared 'static'"), verbose("static modules: ~p.", [Static], Opts), @@ -806,8 +806,8 @@ merge_sources_1(Name, Modules, Trees, Opts) -> verbose("safe modules: ~p.", [Safe], Opts), Preserved = (ordsets:is_element(Name, Sources) - and ordsets:is_element(Name, Export)) - or proplists:get_bool(no_banner, Opts), + andalso ordsets:is_element(Name, Export)) + orelse proplists:get_bool(no_banner, Opts), NoHeaders = proplists:get_bool(no_headers, Opts), Notes = proplists:get_value(notes, Opts, always), Rs = proplists:append_values(redirect, Opts), @@ -2924,9 +2924,7 @@ make_attribute({Name, Term}) -> [erl_syntax:abstract(Term)]). is_auto_import({F, A}) -> - erl_internal:bif(F, A); -is_auto_import(_) -> - false. + erl_internal:bif(F, A). timestamp() -> {{Yr, Mth, Dy}, {Hr, Mt, Sc}} = erlang:localtime(), diff --git a/lib/syntax_tools/src/prettypr.erl b/lib/syntax_tools/src/prettypr.erl index 1868f63e54..c13fa30998 100644 --- a/lib/syntax_tools/src/prettypr.erl +++ b/lib/syntax_tools/src/prettypr.erl @@ -48,6 +48,8 @@ nest/2, par/1, par/2, sep/1, text/1, null_text/1, text_par/1, text_par/2]). +-export_type([document/0]). + %% --------------------------------------------------------------------- -type deep_string() :: [char() | deep_string()]. diff --git a/lib/syntax_tools/vsn.mk b/lib/syntax_tools/vsn.mk index 2ba5eac582..6051fb8e39 100644 --- a/lib/syntax_tools/vsn.mk +++ b/lib/syntax_tools/vsn.mk @@ -1 +1 @@ -SYNTAX_TOOLS_VSN = 1.6.5 +SYNTAX_TOOLS_VSN = 1.6.6 diff --git a/lib/test_server/doc/src/notes.xml b/lib/test_server/doc/src/notes.xml index b6e0a6cefa..e0c4c28e44 100644 --- a/lib/test_server/doc/src/notes.xml +++ b/lib/test_server/doc/src/notes.xml @@ -32,6 +32,112 @@ <file>notes.xml</file> </header> +<section><title>Test_Server 3.4.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Returning {return_group_result,failed} from end_per_group + in a group that is part of a sequence, did not cause the + proceeding cases (or groups) to get skipped. This has + been fixed.</p> + <p> + Own Id: OTP-8753 Aux Id: seq11644 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Common Test has been updated to handle start options and + test specification terms for test case groups (and test + cases in groups). Also, an option named 'label', has been + added that associates the test run with a name that + Common Test prints in the overview HTML logs.</p> + <p> + Own Id: OTP-8725 Aux Id: OTP-8727 </p> + </item> + <item> + <p> + It is now possible to skip all tests in a suite, or a + group, by returning {fail,Reason} from the end_tc/5 + framework function for init_per_suite, or init_per_group.</p> + <p> + Own Id: OTP-8805 Aux Id: seq11664 </p> + </item> + </list> + </section> + +</section> + +<section><title>Test_Server 3.4</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Returning {fail,Reason} from the framework end_tc + function was not handled properly by Test Server for all + test suite functions.</p> + <p> + Own Id: OTP-8492 Aux Id: seq11502 </p> + </item> + <item> + <p> + If the framework end_tc function would hang and get + aborted by Test Server, there was no indication of + failure in the logs. This has been fixed.</p> + <p> + Own Id: OTP-8682 Aux Id: seq11504 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + It is now possible for the Test Server framework end_tc + function to change the status of the test case from ok or + auto-skipped to failed by returning {fail,Reason}.</p> + <p> + Own Id: OTP-8495 Aux Id: seq11502 </p> + </item> + <item> + <p> + Test Server will now call the end_per_testcase/2 function + even if the test case has been terminated explicitly + (with abort_current_testcase/1), or after a timetrap + timeout. Under these circumstances the return value of + end_per_testcase is completely ignored. Therefore the + function will not be able to change the reason for test + case termination by returning {fail,Reason}, nor will it + be able to save data with {save_config,Data}.</p> + <p> + Own Id: OTP-8500 Aux Id: seq11521 </p> + </item> + <item> + <p> + Previously, a repeat property of a test case group + specified the number of times the group should be + repeated after the main test run. I.e. {repeat,N} would + case the group to execute 1+N times. To be consistent + with the behaviour of the run_test repeat option, this + has been changed. N now specifies the absolute number of + executions instead.</p> + <p> + Own Id: OTP-8689 Aux Id: seq11502 </p> + </item> + </list> + </section> + +</section> + <section><title>Test_Server 3.3.6</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/test_server/doc/src/test_server.xml b/lib/test_server/doc/src/test_server.xml index 6e75425862..0cae75d692 100644 --- a/lib/test_server/doc/src/test_server.xml +++ b/lib/test_server/doc/src/test_server.xml @@ -167,6 +167,22 @@ </desc> </func> <func> + <name>adjusted_sleep(MSecs) -> ok</name> + <fsummary>Suspens the calling task for a specified time.</fsummary> + <type> + <v>MSecs = integer() | float() | infinity</v> + <d>The default number of milliseconds to sleep</d> + </type> + <desc> + <p>This function suspends the calling process for at least the + supplied number of milliseconds. The function behaves the same + way as <c>test_server:sleep/1</c>, only <c>MSecs</c> + will be multiplied by the 'multiply_timetraps' value, if set, + and also automatically scaled up if 'scale_timetraps' is set + to true (which it is by default).</p> + </desc> + </func> + <func> <name>hours(N) -> MSecs</name> <name>minutes(N) -> MSecs</name> <name>seconds(N) -> MSecs</name> diff --git a/lib/test_server/doc/src/test_server_ctrl.xml b/lib/test_server/doc/src/test_server_ctrl.xml index 0ed5f88544..2368c4bacc 100644 --- a/lib/test_server/doc/src/test_server_ctrl.xml +++ b/lib/test_server/doc/src/test_server_ctrl.xml @@ -376,6 +376,31 @@ Optional, if not given the test server controller node </desc> </func> <func> + <name>scale_timetraps(Bool) -> ok</name> + <fsummary>.</fsummary> + <type> + <v>Bool = true | false</v> + </type> + <desc> + <p>This function should be called before a test is started. + The parameter specifies if test_server should attempt + to automatically scale the timetrap value in order to compensate + for delays caused by e.g. the cover tool.</p> + </desc> + </func> + <func> + <name>get_timetrap_parameters() -> {N,Bool} </name> + <fsummary>Read the parameter values that affect timetraps.</fsummary> + <type> + <v>N = integer() | infinity</v> + <v>Bool = true | false</v> + </type> + <desc> + <p>This function may be called to read the values set by + <c>multiply_timetraps/1</c> and <c>scale_timetraps/1</c>.</p> + </desc> + </func> + <func> <name>cover(Application,Analyse) -> ok</name> <name>cover(CoverFile,Analyse) -> ok</name> <name>cover(App,CoverFile,Analyse) -> ok</name> @@ -538,9 +563,6 @@ Optional, if not given the test server controller node test server controller node. The log must be formatted using <c>ttb:format/1/2</c>. </p> - <p>This is valid for all targets except the OSE/Delta target - for which all nodes will be logged and automatically formatted - in one single text file called <c>allnodes-test_server</c>.</p> </desc> </func> <func> @@ -610,7 +632,7 @@ Optional, if not given the test server controller node <tag><c>NAME name</c></tag> <item>Names the test suite to something else than the default name. This does not apply to <c>SPEC</c> which keeps - it's names. + its names. </item> <tag><c>PARAMETERS parameterfile</c></tag> <item>Specifies the parameter file to use when starting diff --git a/lib/test_server/doc/src/ts.xml b/lib/test_server/doc/src/ts.xml index 0f91d3eea2..f60c79aadd 100644 --- a/lib/test_server/doc/src/ts.xml +++ b/lib/test_server/doc/src/ts.xml @@ -250,7 +250,7 @@ running test suites. If a remote host is to be used, the <c>TargetSystem</c> argument must be given so that "cross installation" can be done. This should be used for testing on - VxWorks or OSE/Delta. Installation is required for any of the + VxWorks. Installation is required for any of the functions in <c>ts</c> to work. </p> <p>Opts may be one or more of @@ -275,7 +275,7 @@ strings. </item> <item><c>{slavetargets, SlaveTarges}</c><br></br> - For VxWorks and OSE/Delta only. This is a list of + For VxWorks only. This is a list of available hosts where slave nodes can be started. This is necessary because only one node can run per host in the VxWorks environment. This is not the same as diff --git a/lib/test_server/src/Makefile b/lib/test_server/src/Makefile index d55a3a597d..3dca55178d 100644 --- a/lib/test_server/src/Makefile +++ b/lib/test_server/src/Makefile @@ -139,7 +139,7 @@ release_tests_spec: opt $(TARGET_FILES) $(TS_TARGET_FILES) \ $(AUTOCONF_FILES) $(C_FILES) $(COVER_FILES) $(CONFIG) \ $(RELEASE_PATH)/test_server - $(INSTALL_PROGRAM) $(PROGRAMS) $(RELEASE_PATH)/test_server + $(INSTALL_SCRIPT) $(PROGRAMS) $(RELEASE_PATH)/test_server release_docs_spec: diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl index f918f47415..ee121e5bb6 100644 --- a/lib/test_server/src/test_server.erl +++ b/lib/test_server/src/test_server.erl @@ -35,7 +35,7 @@ -export([fail/0,fail/1,format/1,format/2,format/3]). -export([capture_start/0,capture_stop/0,capture_get/0]). -export([messages_get/0]). --export([hours/1,minutes/1,seconds/1,sleep/1,timecall/3]). +-export([hours/1,minutes/1,seconds/1,sleep/1,adjusted_sleep/1,timecall/3]). -export([timetrap_scale_factor/0,timetrap/1,timetrap_cancel/1]). -export([m_out_of_n/3,do_times/4,do_times/2]). -export([call_crash/3,call_crash/4,call_crash/5]). @@ -89,14 +89,14 @@ init(Host,Port,Starter) -> global:register_name(?MODULE,self()), process_flag(trap_exit,true), test_server_sup:cleanup_crash_dumps(), - case gen_tcp:connect(Host,Port, [binary, - {reuseaddr,true}, + case gen_tcp:connect(Host,Port, [binary, + {reuseaddr,true}, {packet,2}]) of - {ok,MainSock} -> + {ok,MainSock} -> Starter ! {self(),started}, request(MainSock,{target_info,init_target_info()}), loop(#state{controller={Host,MainSock}}); - Error -> + Error -> Starter ! {self(),{error, {could_not_contact_controller,Error}}} end. @@ -127,7 +127,7 @@ loop(#state{controller={_,MainSock}} = State) -> halt(); {'EXIT',Pid,Reason} -> case lists:keysearch(Pid,1,State#state.jobs) of - {value,{Pid,Name}} -> + {value,{Pid,Name}} -> case Reason of normal -> ignore; _other -> request(MainSock,{job_proc_killed,Name,Reason}) @@ -157,14 +157,14 @@ init_purify() -> job(Host,Port,Starter) -> process_flag(trap_exit,true), init_purify(), - case gen_tcp:connect(Host,Port, [binary, - {reuseaddr,true}, + case gen_tcp:connect(Host,Port, [binary, + {reuseaddr,true}, {packet,4}, {active,false}]) of {ok,JobSock} -> Starter ! {self(),started}, job(JobSock); - Error -> + Error -> Starter ! {self(),{error, {could_not_contact_controller,Error}}} end. @@ -192,7 +192,7 @@ get_jobdir() -> true -> {ok,Cwd} = file:get_cwd(), Cwd ++ "/" ++ Basename; - false -> + false -> filename:absname(Basename) end. @@ -216,7 +216,7 @@ send_privdir(JobDir,JobSock) -> del_dir(Dir) -> case file:read_file_info(Dir) of - {ok,#file_info{type=directory}} -> + {ok,#file_info{type=directory}} -> {ok,Cont} = file:list_dir(Dir), lists:foreach(fun(F) -> del_dir(filename:join(Dir,F)) end, Cont), ok = file:del_dir(Dir); @@ -227,7 +227,7 @@ del_dir(Dir) -> catch file:delete(Dir), ok end. - + %% %% Receive and decode request on job socket %% @@ -237,7 +237,7 @@ job_loop(JobSock) -> ok -> job_loop(JobSock); {stop,R} -> R end. - + decode_job({{beam,Mod,Which},Beam}) -> % FIXME, shared directory structure on host and target required, % "Library beams" are not loaded from HOST... /Patrik @@ -254,7 +254,7 @@ decode_job({{datadir,Tarfile0},Archive}) -> ok = erl_tar:extract(Tarfile,[compressed,{cwd,JobDir}]), ok = file:delete(Tarfile), ok; -decode_job({test_case,Case}) -> +decode_job({test_case,Case}) -> Result = run_test_case_apply(Case), JobSock = get(test_server_job_sock), request(JobSock,{test_case_result,Result}), @@ -266,11 +266,11 @@ decode_job({test_case,Case}) -> request(JobSock,{{crash_dumps,filename:basename(TarFile)},TarBin}) end, ok; -decode_job({sync_apply,{M,F,A}}) -> +decode_job({sync_apply,{M,F,A}}) -> R = apply(M,F,A), request(get(test_server_job_sock),{sync_result,R}), ok; -decode_job(job_done) -> +decode_job(job_done) -> {stop,stopped}. %% @@ -282,9 +282,9 @@ decode_job(job_done) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% cover_compile({App,Include,Exclude,Cross}) -> +%% cover_compile({App,Include,Exclude,Cross}) -> %% {ok,AnalyseModules} | {error,Reason} -%% +%% %% App = atom() , name of application to be compiled %% Exclude = [atom()], list of modules to exclude %% Include = [atom()], list of modules outside of App that should be included @@ -293,7 +293,7 @@ decode_job(job_done) -> %% in the cover compilation, but that shall not be part of %% the cover analysis for this application. %% -%% Cover compile the given application. Return {ok,AnalyseMods} if application +%% Cover compile the given application. Return {ok,AnalyseMods} if application %% is found, else {error,application_not_found}. cover_compile({none,_Exclude,Include,Cross}) -> @@ -330,7 +330,7 @@ cover_compile({App,all,Include,Cross}) -> end; cover_compile({App,Exclude,Include,Cross}) -> case code:lib_dir(App) of - {error,bad_name} -> + {error,bad_name} -> case Include++Cross of [] -> io:format("\nWARNING: Can't find lib_dir for \'~w\'\n" @@ -366,7 +366,7 @@ cover_compile({App,Exclude,Include,Cross}) -> {ok,AnalyseMods} end end. - + module_names(Beams) -> [list_to_atom(filename:basename(filename:rootname(Beam))) || Beam <- Beams]. @@ -380,11 +380,11 @@ do_cover_compile1([Dont|Rest]) when Dont=:=cover; Dont=:=test_server_ctrl -> do_cover_compile1(Rest); do_cover_compile1([M|Rest]) -> - case {code:is_sticky(M),code:is_loaded(M)} of + case {code:is_sticky(M),code:is_loaded(M)} of {true,_} -> code:unstick_mod(M), case cover:compile_beam(M) of - {ok,_} -> + {ok,_} -> ok; Error -> io:fwrite("\nWARNING: Could not cover compile ~w: ~p\n", @@ -402,7 +402,7 @@ do_cover_compile1([M|Rest]) -> end; {false,_} -> case cover:compile_beam(M) of - {ok,_} -> + {ok,_} -> ok; Error -> io:fwrite("\nWARNING: Could not cover compile ~w: ~p\n", @@ -415,14 +415,14 @@ do_cover_compile1([]) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% cover_analyse(Analyse,Modules) -> [{M,{Cov,NotCov,Details}}] -%% +%% %% Analyse = {details,Dir} | details | {overview,void()} | overview %% Modules = [atom()], the modules to analyse %% %% Cover analysis. If this is a remote target, analyse_to_file can not be used. %% In that case the analyse level 'line' is used instead if Analyse==details. %% -%% If this is a local target, the test directory is given +%% If this is a local target, the test directory is given %% (Analyse=={details,Dir}) and analyse_to_file can be used directly. %% %% If Analyse==overview | {overview,Dir} analyse_to_file is not used, only @@ -432,12 +432,12 @@ do_cover_compile1([]) -> %% all.coverdata in that directory. cover_analyse(Analyse,Modules) -> io:fwrite("Cover analysing...\n",[]), - DetailsFun = + DetailsFun = case Analyse of {details,Dir} -> case cover:export(filename:join(Dir,"all.coverdata")) of ok -> - fun(M) -> + fun(M) -> OutFile = filename:join(Dir, atom_to_list(M) ++ ".COVER.html"), @@ -451,7 +451,7 @@ cover_analyse(Analyse,Modules) -> Error -> fun(_) -> Error end end; - details -> + details -> fun(M) -> case cover:analyse(M,line) of {ok,Lines} -> @@ -489,7 +489,7 @@ cover_analyse(Analyse,Modules) -> unstick_all_sticky(Node) -> lists:filter( - fun(M) -> + fun(M) -> case code:is_sticky(M) of true -> rpc:call(Node,code,unstick_mod,[M]), @@ -502,24 +502,24 @@ unstick_all_sticky(Node) -> stick_all_sticky(Node,Sticky) -> lists:foreach( - fun(M) -> + fun(M) -> rpc:call(Node,code,stick_mod,[M]) end, Sticky). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% run_test_case_apply(Mod,Func,Args,Name,RunInit,MultiplyTimetrap) -> +%% run_test_case_apply(Mod,Func,Args,Name,RunInit,TimetrapData) -> %% {Time,Value,Loc,Opts,Comment} | {died,Reason,unknown,Comment} -%% +%% %% Time = float() (seconds) %% Value = term() %% Loc = term() %% Comment = string() %% Reason = term() %% -%% Spawns off a process (case process) that actually runs the test suite. -%% The case process will have the job process as group leader, which makes +%% Spawns off a process (case process) that actually runs the test suite. +%% The case process will have the job process as group leader, which makes %% it possible to capture all it's output from io:format/2, etc. %% %% The job process then sits down and waits for news from the case process. @@ -535,40 +535,43 @@ stick_all_sticky(Node,Sticky) -> %% called or the comment given by the return value {comment,Comment} from %% a test case. %% -%% {died,Reason,unknown,Comment} is returned if the test case was killed +%% {died,Reason,unknown,Comment} is returned if the test case was killed %% by some other process. Reason is the kill reason provided. %% -%% MultiplyTimetrap indicates a possible extension of all timetraps -%% Timetraps will be multiplied by this integer. If it is infinity, no -%% timetraps will be started at all. +%% TimetrapData = {MultiplyTimetrap,ScaleTimetrap}, which indicates a +%% possible extension of all timetraps. Timetraps will be multiplied by +%% MultiplyTimetrap. If it is infinity, no timetraps will be started at all. +%% ScaleTimetrap indicates if test_server should attemp to automatically +%% compensate timetraps for runtime delays introduced by e.g. tools like +%% cover. -run_test_case_apply({CaseNum,Mod,Func,Args,Name,RunInit,MultiplyTimetrap}) -> +run_test_case_apply({CaseNum,Mod,Func,Args,Name,RunInit,TimetrapData}) -> purify_format("Test case #~w ~w:~w/1", [CaseNum, Mod, Func]), case os:getenv("TS_RUN_VALGRIND") of - false -> + false -> ok; _ -> os:putenv("VALGRIND_LOGFILE_INFIX",atom_to_list(Mod)++"."++ atom_to_list(Func)++"-") end, test_server_h:testcase({Mod,Func,1}), - ProcBef = erlang:system_info(process_count), - Result = run_test_case_apply(Mod, Func, Args, Name, RunInit, MultiplyTimetrap), + ProcBef = erlang:system_info(process_count), + Result = run_test_case_apply(Mod, Func, Args, Name, RunInit, TimetrapData), ProcAft = erlang:system_info(process_count), purify_new_leaks(), DetFail = get(test_server_detected_fail), {Result,DetFail,ProcBef,ProcAft}. - -run_test_case_apply(Mod, Func, Args, Name, RunInit, MultiplyTimetrap) -> + +run_test_case_apply(Mod, Func, Args, Name, RunInit, TimetrapData) -> case get(test_server_job_dir) of undefined -> %% i'm a local target - do_run_test_case_apply(Mod, Func, Args, Name, RunInit, MultiplyTimetrap); + do_run_test_case_apply(Mod, Func, Args, Name, RunInit, TimetrapData); JobDir -> %% i'm a remote target case Args of [Config] when is_list(Config) -> - {value,{data_dir,HostDataDir}} = + {value,{data_dir,HostDataDir}} = lists:keysearch(data_dir, 1, Config), DataBase = filename:basename(HostDataDir), TargetDataDir = filename:join(JobDir, DataBase), @@ -578,18 +581,18 @@ run_test_case_apply(Mod, Func, Args, Name, RunInit, MultiplyTimetrap) -> Config2 = lists:keyreplace(priv_dir, 1, Config1, {priv_dir,TargetPrivDir}), do_run_test_case_apply(Mod, Func, [Config2], Name, RunInit, - MultiplyTimetrap); + TimetrapData); _other -> do_run_test_case_apply(Mod, Func, Args, Name, RunInit, - MultiplyTimetrap) + TimetrapData) end end. -do_run_test_case_apply(Mod, Func, Args, Name, RunInit, MultiplyTimetrap) -> +do_run_test_case_apply(Mod, Func, Args, Name, RunInit, TimetrapData) -> {ok,Cwd} = file:get_cwd(), Args2Print = case Args of - [Args1] when is_list(Args1) -> + [Args1] when is_list(Args1) -> lists:keydelete(tc_group_result, 1, Args1); - _ -> + _ -> Args end, print(minor, "Test case started with:\n~s:~s(~p)\n", [Mod,Func,Args2Print]), @@ -600,16 +603,16 @@ do_run_test_case_apply(Mod, Func, Args, Name, RunInit, MultiplyTimetrap) -> OldGLeader = group_leader(), %% Set ourself to group leader for the spawned process group_leader(self(),self()), - Pid = + Pid = spawn_link( - fun() -> - run_test_case_eval(Mod, Func, Args, Name, Ref, - RunInit, MultiplyTimetrap, + fun() -> + run_test_case_eval(Mod, Func, Args, Name, Ref, + RunInit, TimetrapData, TCCallback) end), group_leader(OldGLeader, self()), put(test_server_detected_fail, []), - run_test_case_msgloop(Ref, Pid, false, false, ""). + run_test_case_msgloop(Ref, Pid, false, false, "", undefined). %% Ugly bug (pre R5A): %% If this process (group leader of the test case) terminates before @@ -620,7 +623,7 @@ do_run_test_case_apply(Mod, Func, Args, Name, RunInit, MultiplyTimetrap) -> %% A test case is known to have failed if it returns {'EXIT', _} tuple, %% or sends a message {failed, File, Line} to it's group_leader %% -run_test_case_msgloop(Ref, Pid, CaptureStdout, Terminate, Comment) -> +run_test_case_msgloop(Ref, Pid, CaptureStdout, Terminate, Comment, CurrConf) -> %% NOTE: Keep job_proxy_msgloop/0 up to date when changes %% are made in this function! {Timeout,ReturnValue} = @@ -641,13 +644,13 @@ run_test_case_msgloop(Ref, Pid, CaptureStdout, Terminate, Comment) -> receive {'DOWN', Mon, process, Pid, _} -> Comment - after 10000 -> + after 10000 -> %% Pid is probably trapping exits, hit it harder... exit(Pid, kill), %% here's the only place we know Reason, so we save %% it as a comment, potentially replacing user data Error = lists:flatten(io_lib:format("Aborted: ~p",[Reason])), - Error1 = lists:flatten([string:strip(S,left) || + Error1 = lists:flatten([string:strip(S,left) || S <- string:tokens(Error,[$\n])]), if length(Error1) > 63 -> string:substr(Error1,1,60) ++ "..."; @@ -655,149 +658,224 @@ run_test_case_msgloop(Ref, Pid, CaptureStdout, Terminate, Comment) -> Error1 end end, - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,NewComment); + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,NewComment,CurrConf); {io_request,From,ReplyAs,{put_chars,io_lib,Func,[Format,Args]}} when is_list(Format) -> Msg = (catch io_lib:Func(Format,Args)), run_test_case_msgloop_io(ReplyAs,CaptureStdout,Msg,From,Func), - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment); + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf); {io_request,From,ReplyAs,{put_chars,io_lib,Func,[Format,Args]}} when is_atom(Format) -> Msg = (catch io_lib:Func(Format,Args)), run_test_case_msgloop_io(ReplyAs,CaptureStdout,Msg,From,Func), - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment); + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf); {io_request,From,ReplyAs,{put_chars,Bytes}} -> run_test_case_msgloop_io( ReplyAs,CaptureStdout,Bytes,From,put_chars), - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment); + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf); {io_request,From,ReplyAs,{put_chars,unicode,io_lib,Func,[Format,Args]}} when is_list(Format) -> Msg = unicode_to_latin1(catch io_lib:Func(Format,Args)), run_test_case_msgloop_io(ReplyAs,CaptureStdout,Msg,From,Func), - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment); + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf); {io_request,From,ReplyAs,{put_chars,latin1,io_lib,Func,[Format,Args]}} when is_list(Format) -> Msg = (catch io_lib:Func(Format,Args)), run_test_case_msgloop_io(ReplyAs,CaptureStdout,Msg,From,Func), - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment); + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf); {io_request,From,ReplyAs,{put_chars,unicode,io_lib,Func,[Format,Args]}} when is_atom(Format) -> Msg = unicode_to_latin1(catch io_lib:Func(Format,Args)), run_test_case_msgloop_io(ReplyAs,CaptureStdout,Msg,From,Func), - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment); + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf); {io_request,From,ReplyAs,{put_chars,latin1,io_lib,Func,[Format,Args]}} when is_atom(Format) -> Msg = (catch io_lib:Func(Format,Args)), run_test_case_msgloop_io(ReplyAs,CaptureStdout,Msg,From,Func), - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment); + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf); {io_request,From,ReplyAs,{put_chars,unicode,Bytes}} -> run_test_case_msgloop_io( ReplyAs,CaptureStdout,unicode_to_latin1(Bytes),From,put_chars), - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment); + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf); {io_request,From,ReplyAs,{put_chars,latin1,Bytes}} -> run_test_case_msgloop_io( ReplyAs,CaptureStdout,Bytes,From,put_chars), - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment); + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf); IoReq when element(1, IoReq) == io_request -> %% something else, just pass it on group_leader() ! IoReq, - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment); + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf); {structured_io,ClientPid,Msg} -> output(Msg, ClientPid), - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment); + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf); {capture,NewCapture} -> - run_test_case_msgloop(Ref,Pid,NewCapture,Terminate,Comment); + run_test_case_msgloop(Ref,Pid,NewCapture,Terminate,Comment,CurrConf); {sync_apply,From,MFA} -> sync_local_or_remote_apply(false,From,MFA), - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment); + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf); {sync_apply_proxy,Proxy,From,MFA} -> sync_local_or_remote_apply(Proxy,From,MFA), - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment); + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf); {printout,Detail,Format,Args} -> print(Detail,Format,Args), - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment); + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf); {comment,NewComment} -> Terminate1 = case Terminate of - {true,{Time,Value,Loc,Opts,_OldComment}} -> + {true,{Time,Value,Loc,Opts,_OldComment}} -> {true,{Time,Value,mod_loc(Loc),Opts,NewComment}}; Other -> Other end, - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate1,NewComment); + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate1,NewComment,CurrConf); + {set_curr_conf,NewCurrConf} -> + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,NewCurrConf); {'EXIT',Pid,{Ref,Time,Value,Loc,Opts}} -> RetVal = {Time/1000000,Value,mod_loc(Loc),Opts,Comment}, - run_test_case_msgloop(Ref,Pid,CaptureStdout,{true,RetVal},Comment); + run_test_case_msgloop(Ref,Pid,CaptureStdout,{true,RetVal},Comment,undefined); {'EXIT',Pid,Reason} -> case Reason of {timetrap_timeout,TVal,Loc} -> %% convert Loc to form that can be formatted - Loc1 = mod_loc(Loc), - {Mod,Func} = get_mf(Loc1), - %% The framework functions mustn't execute on this - %% group leader process or io will cause deadlock, - %% so we spawn a dedicated process for the operation - %% and let the group leader go back to handle io. - spawn_fw_call(Mod,Func,Pid,{timetrap_timeout,TVal}, - Loc1,self(),Comment), - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment); + case mod_loc(Loc) of + {FwMod,FwFunc,framework} -> + %% timout during framework call + spawn_fw_call(FwMod,FwFunc,Pid, + {framework_error,{timetrap,TVal}}, + unknown,self(),Comment), + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate, + Comment,undefined); + Loc1 -> + {Mod,Func} = get_mf(Loc1), + %% call end_per_testcase on a separate process, + %% only so that the user has a chance to clean up + %% after init_per_testcase, even after a timetrap timeout + NewCurrConf = + case CurrConf of + {{Mod,Func},Conf} -> + EndConfPid = + call_end_conf(Mod,Func,Pid, + {timetrap_timeout,TVal}, + Loc1,[{tc_status, + {failed, + timetrap_timeout}}|Conf], + TVal), + {EndConfPid,{Mod,Func},Conf}; + _ -> + %% The framework functions mustn't execute on this + %% group leader process or io will cause deadlock, + %% so we spawn a dedicated process for the operation + %% and let the group leader go back to handle io. + spawn_fw_call(Mod,Func,Pid,{timetrap_timeout,TVal}, + Loc1,self(),Comment), + undefined + end, + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate, + Comment,NewCurrConf) + end; {timetrap_timeout,TVal,Loc,InitOrEnd} -> - Loc1 = mod_loc(Loc), - {Mod,_Func} = get_mf(Loc1), - spawn_fw_call(Mod,InitOrEnd,Pid,{timetrap_timeout,TVal}, - Loc1,self(),Comment), - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment); - {testcase_aborted,Reason,Loc} -> - Loc1 = mod_loc(Loc), - {Mod,Func} = get_mf(Loc1), - spawn_fw_call(Mod,Func,Pid,{testcase_aborted,Reason}, - Loc1,self(),Comment), - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment); - killed -> + case mod_loc(Loc) of + {FwMod,FwFunc,framework} -> + %% timout during framework call + spawn_fw_call(FwMod,FwFunc,Pid, + {framework_error,{timetrap,TVal}}, + unknown,self(),Comment); + Loc1 -> + {Mod,_Func} = get_mf(Loc1), + spawn_fw_call(Mod,InitOrEnd,Pid,{timetrap_timeout,TVal}, + Loc1,self(),Comment) + end, + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf); + {testcase_aborted,AbortReason,AbortLoc} -> + ErrorMsg = {testcase_aborted,AbortReason}, + case mod_loc(AbortLoc) of + {FwMod,FwFunc,framework} -> + %% abort during framework call + spawn_fw_call(FwMod,FwFunc,Pid, + {framework_error,ErrorMsg}, + unknown,self(),Comment), + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate, + Comment,undefined); + Loc1 -> + {Mod,Func} = get_mf(Loc1), + %% call end_per_testcase on a separate process, only so + %% that the user has a chance to clean up after init_per_testcase, + %% even after abortion + NewCurrConf = + case CurrConf of + {{Mod,Func},Conf} -> + TVal = case lists:keysearch(default_timeout,1,Conf) of + {value,{default_timeout,Tmo}} -> Tmo; + _ -> ?DEFAULT_TIMETRAP_SECS*1000 + end, + EndConfPid = + call_end_conf(Mod,Func,Pid,ErrorMsg, + Loc1, + [{tc_status,{failed,ErrorMsg}}|Conf], + TVal), + {EndConfPid,{Mod,Func},Conf}; + _ -> + spawn_fw_call(Mod,Func,Pid,ErrorMsg, + Loc1,self(),Comment), + undefined + end, + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate, + Comment,NewCurrConf) + end; + killed -> %% result of an exit(TestCase,kill) call, which is the - %% only way to abort a testcase process that traps exits + %% only way to abort a testcase process that traps exits %% (see abort_current_testcase) spawn_fw_call(undefined,undefined,Pid,testcase_aborted_or_killed, unknown,self(),Comment), - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment); + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf); {fw_error,{FwMod,FwFunc,FwError}} -> spawn_fw_call(FwMod,FwFunc,Pid,{framework_error,FwError}, unknown,self(),Comment), - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment); - _ -> + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf); + _Other -> %% the testcase has terminated because of Reason (e.g. an exit %% because a linked process failed) spawn_fw_call(undefined,undefined,Pid,Reason, unknown,self(),Comment), - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment) + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf) + end; + {EndConfPid,{call_end_conf,Data,_Result}} -> + case CurrConf of + {EndConfPid,{Mod,Func},_Conf} -> + {_Mod,_Func,TCPid,TCExitReason,Loc} = Data, + spawn_fw_call(Mod,Func,TCPid,TCExitReason,Loc,self(),Comment), + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,undefined); + _ -> + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf) end; {_FwCallPid,fw_notify_done,RetVal} -> %% the framework has been notified, we're finished - run_test_case_msgloop(Ref,Pid,CaptureStdout,{true,RetVal},Comment); + run_test_case_msgloop(Ref,Pid,CaptureStdout,{true,RetVal},Comment,undefined); {'EXIT',_FwCallPid,{fw_notify_done,Func,Error}} -> %% a framework function failed CB = os:getenv("TEST_SERVER_FRAMEWORK"), Loc = case CB of - false -> + false -> {test_server,Func}; - _ -> + _ -> {list_to_atom(CB),Func} end, RetVal = {died,{framework_error,Loc,Error},Loc,"Framework error"}, - run_test_case_msgloop(Ref,Pid,CaptureStdout,{true,RetVal},Comment); + run_test_case_msgloop(Ref,Pid,CaptureStdout,{true,RetVal},Comment,undefined); {failed,File,Line} -> - put(test_server_detected_fail, + put(test_server_detected_fail, [{File, Line}| get(test_server_detected_fail)]), - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment); + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf); _Other when not is_tuple(_Other) -> %% ignore anything not generated by test server - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment); + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf); _Other when element(1, _Other) /= 'EXIT', element(1, _Other) /= started, element(1, _Other) /= finished, element(1, _Other) /= print -> %% ignore anything not generated by test server - run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment) + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf) after Timeout -> ReturnValue end. @@ -819,12 +897,43 @@ run_test_case_msgloop_io(ReplyAs,CaptureStdout,Msg,From,Func) -> output(Msg,Sender) -> local_or_remote_apply({test_server_ctrl,output,[Msg,Sender]}). +call_end_conf(Mod,Func,TCPid,TCExitReason,Loc,Conf,TVal) -> + Starter = self(), + Data = {Mod,Func,TCPid,TCExitReason,Loc}, + EndConfProc = + fun() -> + Supervisor = self(), + EndConfApply = + fun() -> + case catch apply(Mod,end_per_testcase,[Func,Conf]) of + {'EXIT',Why} -> + group_leader() ! {printout,12, + "ERROR! ~p:end_per_testcase(~p, ~p)" + " crashed!\n\tReason: ~p\n", + [Mod,Func,Conf,Why]}; + _ -> + ok + end, + Supervisor ! {self(),end_conf} + end, + Pid = spawn_link(EndConfApply), + receive + {Pid,end_conf} -> + Starter ! {self(),{call_end_conf,Data,ok}}; + {'EXIT',Pid,Reason} -> + Starter ! {self(),{call_end_conf,Data,{error,Reason}}} + after TVal -> + Starter ! {self(),{call_end_conf,Data,{error,timeout}}} + end + end, + spawn_link(EndConfProc). + spawn_fw_call(Mod,{init_per_testcase,Func},Pid,{timetrap_timeout,TVal}=Why, Loc,SendTo,Comment) -> FwCall = fun() -> Skip = {skip,{failed,{Mod,init_per_testcase,Why}}}, - %% if init_per_testcase fails, the test case + %% if init_per_testcase fails, the test case %% should be skipped case catch test_server_sup:framework_call( end_tc,[?pl2a(Mod),Func,{Pid,Skip,[[]]}]) of @@ -838,6 +947,7 @@ spawn_fw_call(Mod,{init_per_testcase,Func},Pid,{timetrap_timeout,TVal}=Why, {TVal/1000,Skip,Loc,[],Comment}} end, spawn_link(FwCall); + spawn_fw_call(Mod,{end_per_testcase,Func},Pid,{timetrap_timeout,TVal}=Why, Loc,SendTo,_Comment) -> FwCall = @@ -869,7 +979,7 @@ spawn_fw_call(FwMod,FwFunc,_Pid,{framework_error,FwError},_,SendTo,_Comment) -> fun() -> test_server_sup:framework_call(report, [framework_error, {{FwMod,FwFunc},FwError}]), - Comment = + Comment = lists:flatten( io_lib:format("<font color=\"red\">" "WARNING! ~w:~w failed!</font>", [FwMod,FwFunc])), @@ -953,9 +1063,10 @@ job_proxy_msgloop() -> %% A test case is known to have failed if it returns {'EXIT', _} tuple, %% or sends a message {failed, File, Line} to it's group_leader -run_test_case_eval(Mod, Func, Args0, Name, Ref, RunInit, - MultiplyTimetrap, TCCallback) -> - put(test_server_multiply_timetraps,MultiplyTimetrap), +run_test_case_eval(Mod, Func, Args0, Name, Ref, RunInit, + TimetrapData, TCCallback) -> + put(test_server_multiply_timetraps,TimetrapData), + {{Time,Value},Loc,Opts} = case test_server_sup:framework_call(init_tc,[?pl2a(Mod),Func,Args0], {ok,Args0}) of @@ -1004,6 +1115,8 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) -> put(test_server_init_or_end_conf,undefined), %% call user callback function if defined NewConf1 = user_callback(TCCallback, Mod, Func, init, NewConf), + %% save current state in controller loop + group_leader() ! {set_curr_conf,{{Mod,Func},NewConf1}}, put(test_server_loc, {Mod,Func}), %% execute the test case {{T,Return},Loc} = {ts_tc(Mod, Func, [NewConf1]),get_loc()}, @@ -1025,6 +1138,8 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) -> _ -> {[{tc_status,ok}|NewConf1],Return,ok} end, + %% clear current state in controller loop + group_leader() ! {set_curr_conf,undefined}, %% call user callback function if defined EndConf1 = user_callback(TCCallback, Mod, Func, 'end', EndConf), {FWReturn1,TSReturn1,EndConf2} = @@ -1036,9 +1151,10 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) -> {{error,ReasonToFail},{failed,ReasonToFail},EndConf1}; {failed,{_,end_per_testcase,_}} = Failure -> % unexpected termination {Failure,TSReturn,EndConf1}; - _ -> + _ -> {FWReturn,TSReturn,EndConf1} end, + put(test_server_init_or_end_conf,undefined), case test_server_sup:framework_call(end_tc, [?pl2a(Mod), Func, {FWReturn1,[EndConf2]}]) of {fail,Reason} -> @@ -1067,7 +1183,7 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) -> {{T,Return2},Loc,Opts} end. -%% the return value is a list and we have to check if it contains +%% the return value is a list and we have to check if it contains %% the result of an end conf case or if it's a Config list process_return_val([Return], M,F,A, Loc, Final) when is_list(Return) -> ReturnTags = [skip,skip_and_save,save_config,comment,return_group_result], @@ -1082,24 +1198,33 @@ process_return_val([Return], M,F,A, Loc, Final) when is_list(Return) -> true -> % must be return value from end conf case process_return_val1(Return, M,F,A, Loc, Final, []); false -> % must be Config value from init conf case - test_server_sup:framework_call(end_tc, [?pl2a(M),F,{ok,A}]), - {Return,[]} + case test_server_sup:framework_call(end_tc, [?pl2a(M),F,{ok,A}]) of + {fail,FWReason} -> + fw_error_notify(M,F,A, FWReason), + {{failed,FWReason},[]}; + _ -> + {Return,[]} + end end; %% the return value is not a list, so it's the return value from an %% end conf case or it's a dummy value that can be ignored process_return_val(Return, M,F,A, Loc, Final) -> process_return_val1(Return, M,F,A, Loc, Final, []). -process_return_val1([Failed={E,TCError}|_], M,F,A=[Args], Loc, _, SaveOpts) when E=='EXIT'; +process_return_val1([Failed={E,TCError}|_], M,F,A=[Args], Loc, _, SaveOpts) when E=='EXIT'; E==failed -> fw_error_notify(M,F,A, TCError, mod_loc(Loc)), - test_server_sup:framework_call(end_tc, - [?pl2a(M),F,{{error,TCError}, - [[{tc_status,{failed,TCError}}|Args]]}]), - {Failed,SaveOpts}; -process_return_val1([SaveCfg={save_config,_}|Opts], M,F,[Args], Loc, Final, SaveOpts) -> + case test_server_sup:framework_call(end_tc, + [?pl2a(M),F,{{error,TCError}, + [[{tc_status,{failed,TCError}}|Args]]}]) of + {fail,FWReason} -> + {{failed,FWReason},SaveOpts}; + _ -> + {Failed,SaveOpts} + end; +process_return_val1([SaveCfg={save_config,_}|Opts], M,F,[Args], Loc, Final, SaveOpts) -> process_return_val1(Opts, M,F,[[SaveCfg|Args]], Loc, Final, SaveOpts); -process_return_val1([{skip_and_save,Why,SaveCfg}|Opts], M,F,[Args], Loc, _, SaveOpts) -> +process_return_val1([{skip_and_save,Why,SaveCfg}|Opts], M,F,[Args], Loc, _, SaveOpts) -> process_return_val1(Opts, M,F,[[{save_config,SaveCfg}|Args]], Loc, {skip,Why}, SaveOpts); process_return_val1([GR={return_group_result,_}|Opts], M,F,A, Loc, Final, SaveOpts) -> process_return_val1(Opts, M,F,A, Loc, Final, [GR|SaveOpts]); @@ -1109,8 +1234,12 @@ process_return_val1([RetVal={Tag,_}|Opts], M,F,A, Loc, _, SaveOpts) when Tag==sk process_return_val1([_|Opts], M,F,A, Loc, Final, SaveOpts) -> process_return_val1(Opts, M,F,A, Loc, Final, SaveOpts); process_return_val1([], M,F,A, _Loc, Final, SaveOpts) -> - test_server_sup:framework_call(end_tc, [?pl2a(M),F,{Final,A}]), - {Final,lists:reverse(SaveOpts)}. + case test_server_sup:framework_call(end_tc, [?pl2a(M),F,{Final,A}]) of + {fail,FWReason} -> + {{failed,FWReason},SaveOpts}; + _ -> + {Final,lists:reverse(SaveOpts)} + end. user_callback(undefined, _, _, _, Args) -> Args; @@ -1138,7 +1267,7 @@ init_per_testcase(Mod, Func, Args) -> case erlang:function_exported(Mod,init_per_testcase,2) of true -> case catch my_apply(Mod, init_per_testcase, [Func|Args]) of - {'$test_server_ok',{Skip,Reason}} when Skip==skip; + {'$test_server_ok',{Skip,Reason}} when Skip==skip; Skip==skipped -> {skip,Reason}; {'$test_server_ok',Res={skip_and_save,_,_}} -> @@ -1149,31 +1278,31 @@ init_per_testcase(Mod, Func, Args) -> [] -> {ok,NewConf}; Bad -> - group_leader() ! {printout,12, + group_leader() ! {printout,12, "ERROR! init_per_testcase has returned " - "bad elements in Config: ~p\n",[Bad]}, + "bad elements in Config: ~p\n",[Bad]}, {skip,{failed,{Mod,init_per_testcase,bad_return}}} end; {'$test_server_ok',_Other} -> - group_leader() ! {printout,12, + group_leader() ! {printout,12, "ERROR! init_per_testcase did not return " - "a Config list.\n",[]}, + "a Config list.\n",[]}, {skip,{failed,{Mod,init_per_testcase,bad_return}}}; {'EXIT',Reason} -> Line = get_loc(), FormattedLoc = test_server_sup:format_loc(mod_loc(Line)), - group_leader() ! {printout,12, + group_leader() ! {printout,12, "ERROR! init_per_testcase crashed!\n" "\tLocation: ~s\n\tReason: ~p\n", - [FormattedLoc,Reason]}, + [FormattedLoc,Reason]}, {skip,{failed,{Mod,init_per_testcase,Reason}}}; Other -> Line = get_loc(), FormattedLoc = test_server_sup:format_loc(mod_loc(Line)), - group_leader() ! {printout,12, + group_leader() ! {printout,12, "ERROR! init_per_testcase thrown!\n" "\tLocation: ~s\n\tReason: ~p\n", - [FormattedLoc, Other]}, + [FormattedLoc, Other]}, {skip,{failed,{Mod,init_per_testcase,Other}}} end; false -> @@ -1182,7 +1311,7 @@ init_per_testcase(Mod, Func, Args) -> [Config] = Args, {ok, Config} end. - + end_per_testcase(Mod, Func, Conf) -> case erlang:function_exported(Mod,end_per_testcase,2) of true -> @@ -1211,11 +1340,11 @@ do_end_per_testcase(Mod,EndFunc,Func,Conf) -> comment(io_lib:format("<font color=\"red\">" "WARNING: ~w crashed!" "</font>\n",[EndFunc])), - group_leader() ! {printout,12, + group_leader() ! {printout,12, "WARNING: ~w crashed!\n" "Reason: ~p\n" "Line: ~s\n", - [EndFunc, Reason, + [EndFunc, Reason, test_server_sup:format_loc( mod_loc(get_loc()))]}, {failed,{Mod,end_per_testcase,Why}}; @@ -1223,13 +1352,13 @@ do_end_per_testcase(Mod,EndFunc,Func,Conf) -> comment(io_lib:format("<font color=\"red\">" "WARNING: ~w thrown!" "</font>\n",[EndFunc])), - group_leader() ! {printout,12, + group_leader() ! {printout,12, "WARNING: ~w thrown!\n" "Reason: ~p\n" "Line: ~s\n", - [EndFunc, Other, + [EndFunc, Other, test_server_sup:format_loc( - mod_loc(get_loc()))]}, + mod_loc(get_loc()))]}, {failed,{Mod,end_per_testcase,Other}} end. @@ -1254,7 +1383,7 @@ get_mf(_) -> {undefined,undefined}. mod_loc(Loc) -> %% handle diff line num versions - case Loc of + case Loc of [{{_M,_F},_L}|_] -> [{?pl2a(M),F,L} || {{M,F},L} <- Loc]; [{_M,_F}|_] -> @@ -1286,7 +1415,7 @@ fw_error_notify(Mod, Func, Args, Error, Loc) -> %% Args = [term()] %% %% Just like io:format, except that depending on the Detail value, the output -%% is directed to console, major and/or minor log files. +%% is directed to console, major and/or minor log files. print(Detail,Format,Args) -> local_or_remote_apply({test_server_ctrl,print,[Detail,Format,Args]}). @@ -1296,11 +1425,11 @@ print(Detail,Format,Args) -> %% %% Prints Leader followed by a time stamp (date and time). Depending on %% the Detail value, the output is directed to console, major and/or minor -%% log files. +%% log files. print_timestamp(Detail,Leader) -> local_or_remote_apply({test_server_ctrl,print_timestamp,[Detail,Leader]}). - + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% lookup_config(Key,Config) -> {value,{Key,Value}} | undefined @@ -1326,11 +1455,11 @@ ts_tc(M, F, A) -> Val = (catch my_apply(M, F, A)), After = erlang:now(), Result = case Val of - {'$test_server_ok', R} -> + {'$test_server_ok', R} -> R; % test case ok - {'EXIT',_Reason} = R -> + {'EXIT',_Reason} = R -> R; % test case crashed - Other -> + Other -> {failed, {thrown,Other}} % test case was thrown end, Elapsed = @@ -1352,7 +1481,7 @@ my_apply(M, F, A) -> %% in an attempt to keep this modules small (yeah, right!) %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% unicode_to_latin1(Chars) when is_list(Chars); is_binary(Chars) -> - lists:flatten( + lists:flatten( [ case X of High when High > 255 -> io_lib:format("\\{~.8B}",[X]); @@ -1460,6 +1589,44 @@ sleep(MSecs) -> ok. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% adjusted_sleep(Time) -> ok +%% Time = integer() | float() | infinity +%% +%% Sleeps the specified number of milliseconds, multiplied by the +%% 'multiply_timetraps' value (if set) and possibly also automatically scaled +%% up if 'scale_timetraps' is set to true (which is default). +%% This function also accepts floating point numbers (which are truncated) and +%% the atom 'infinity'. +adjusted_sleep(infinity) -> + receive + after infinity -> + ok + end; +adjusted_sleep(MSecs) -> + {Multiplier,ScaleFactor} = + case test_server_ctrl:get_timetrap_parameters() of + {undefined,undefined} -> + {1,1}; + {undefined,false} -> + {1,1}; + {undefined,true} -> + {1,timetrap_scale_factor()}; + {infinity,_} -> + {infinity,1}; + {Mult,undefined} -> + {Mult,1}; + {Mult,false} -> + {Mult,1}; + {Mult,true} -> + {Mult,timetrap_scale_factor()} + end, + receive + after trunc(MSecs*Multiplier*ScaleFactor) -> + ok + end, + ok. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% fail(Reason) -> exit({suite_failed,Reason}) %% %% Immediately calls exit. Included because test suites are easier @@ -1509,9 +1676,9 @@ break(Comment) -> receive continue -> ok end. spawn_break_process(Pid) -> - spawn(fun() -> + spawn(fun() -> register(test_server_break_process,self()), - receive + receive continue -> continue(Pid); cancel -> ok end @@ -1561,20 +1728,21 @@ timetrap_scale_factor() -> %% timetrap(Timeout) -> Handle %% Handle = term() %% -%% Creates a time trap, that will kill the calling process if the +%% Creates a time trap, that will kill the calling process if the %% trap is not cancelled with timetrap_cancel/1, within Timeout milliseconds. - timetrap(Timeout0) -> Timeout = time_ms(Timeout0), cancel_default_timetrap(), case get(test_server_multiply_timetraps) of - undefined -> timetrap1(Timeout); - infinity -> infinity; - Int -> timetrap1(Timeout*Int) + undefined -> timetrap1(Timeout, true); + {undefined,false} -> timetrap1(Timeout, false); + {undefined,_} -> timetrap1(Timeout, true); + {infinity,_} -> infinity; + {Int,Scale} -> timetrap1(Timeout*Int, Scale) end. -timetrap1(Timeout) -> - Ref = spawn_link(test_server_sup,timetrap,[Timeout,self()]), +timetrap1(Timeout, Scale) -> + Ref = spawn_link(test_server_sup,timetrap,[Timeout,Scale,self()]), case get(test_server_timetraps) of undefined -> put(test_server_timetraps,[Ref]); List -> put(test_server_timetraps,[Ref|List]) @@ -1582,7 +1750,6 @@ timetrap1(Timeout) -> Ref. ensure_timetrap(Config) -> - %format("ensure_timetrap:~p~n",[Config]), case get(test_server_timetraps) of [_|_] -> ok; @@ -1623,7 +1790,7 @@ cancel_default_timetrap() -> time_ms({hours,N}) -> hours(N); time_ms({minutes,N}) -> minutes(N); time_ms({seconds,N}) -> seconds(N); -time_ms({Other,_N}) -> +time_ms({Other,_N}) -> format("=== ERROR: Invalid time specification: ~p. " "Should be seconds, minutes, or hours.~n", [Other]), exit({invalid_time_spec,Other}); @@ -1763,21 +1930,21 @@ call_crash(Time,Crash,M,F,A) -> %% Slave and Peer: %% {remote, true} - Start the node on a remote host. If not specified, %% the node will be started on the local host (with -%% some exceptions, as for the case of VxWorks and OSE, +%% some exceptions, for instance VxWorks, %% where all nodes are started on a remote host). %% {args, Arguments} - Arguments passed directly to the node. %% {cleanup, false} - Nodes started with this option will not be killed %% by the test server after completion of the test case %% Therefore it is IMPORTANT that the USER terminates %% the node!! -%% {erl, ReleaseList} - Use an Erlang emulator determined by ReleaseList -%% when starting nodes, instead of the same emulator +%% {erl, ReleaseList} - Use an Erlang emulator determined by ReleaseList +%% when starting nodes, instead of the same emulator %% as the test server is running. ReleaseList is a list -%% of specifiers, where a specifier is either -%% {release, Rel}, {prog, Prog}, or 'this'. Rel is -%% either the name of a release, e.g., "r7a" or -%% 'latest'. 'this' means using the same emulator as -%% the test server. Prog is the name of an emulator +%% of specifiers, where a specifier is either +%% {release, Rel}, {prog, Prog}, or 'this'. Rel is +%% either the name of a release, e.g., "r7a" or +%% 'latest'. 'this' means using the same emulator as +%% the test server. Prog is the name of an emulator %% executable. If the list has more than one element, %% one of them is picked randomly. (Only %% works on Solaris and Linux, and the test @@ -1792,13 +1959,13 @@ call_crash(Time,Crash,M,F,A) -> %% peer nodes. %% Note that slave nodes always act as if they had %% fail_on_error==false. -%% +%% start_node(Name, Type, Options) -> lists:foreach( - fun(N) -> + fun(N) -> case firstname(N) of - Name -> + Name -> format("=== WARNING: Trying to start node \'~w\' when node" " with same first name exists: ~w", [Name, N]); _other -> ok @@ -1817,19 +1984,19 @@ start_node(Name, Type, Options) -> %% Cannot run cover on shielded node or on a node started %% by a shielded node. Cover = case is_cover() of - true -> + true -> not is_shielded(Name) andalso same_version(Node); - false -> + false -> false end, net_adm:ping(Node), case Cover of - true -> + true -> Sticky = unstick_all_sticky(Node), cover:start(Node), stick_all_sticky(Node,Sticky); - _ -> + _ -> ok end, {ok,Node}; @@ -1857,7 +2024,7 @@ wait_for_node(Slave) -> self(), {test_server_ctrl,wait_for_node,[Slave]}}, receive {sync_result,R} -> R end. - + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% stop_node(Name) -> true|false @@ -1867,7 +2034,7 @@ wait_for_node(Slave) -> stop_node(Slave) -> Nocover = is_shielded(Slave) orelse not same_version(Slave), case is_cover() of - true when not Nocover -> + true when not Nocover -> Sticky = unstick_all_sticky(Slave), cover:stop(Slave), stick_all_sticky(Slave,Sticky); @@ -1895,10 +2062,10 @@ stop_node(Slave) -> %% with the {cleanup,false} option, or it was started %% in some other way than test_server:start_node/3 format("=== WARNING: Attempt to stop a nonexisting slavenode (~p)~n" - "=== Trying to kill it anyway!!!", + "=== Trying to kill it anyway!!!", [Slave]), case net_adm:ping(Slave)of - pong -> + pong -> slave:stop(Slave), true; pang -> @@ -1918,7 +2085,7 @@ is_release_available(Release) -> self(), {test_server_ctrl,is_release_available,[Release]}}, receive {sync_result,R} -> R end. - + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% run_on_shielded_node(Fun, CArgs) -> term() @@ -1937,7 +2104,7 @@ is_release_available(Release) -> %% %% Fun - Function to execute %% CArg - Extra command line arguments to use when starting -%% the shielded node. +%% the shielded node. %% %% If Fun is successfully executed, the result is returned. %% @@ -2014,14 +2181,8 @@ temp_name(Stem) -> app_test(App) -> app_test(App, pedantic). app_test(App, Mode) -> - case os:type() of - {ose,_} -> - Comment = "Skipping app_test on OSE", - comment(Comment), % in case user ignores the return value - {skip,Comment}; - _other -> - test_server_sup:app_test(App, Mode) - end. + test_server_sup:app_test(App, Mode). + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -2043,8 +2204,8 @@ is_native(Mod) -> %% The given String will occur in the comment field %% of the table on the test suite result page. If %% called several times, only the last comment is -%% printed. -%% comment/1 is also overwritten by the return value +%% printed. +%% comment/1 is also overwritten by the return value %% {comment,Comment} or fail/1 (which prints Reason %% as a comment). comment(String) -> @@ -2160,7 +2321,7 @@ purify_new_fds_inuse() -> {'EXIT', _} -> false; Inuse when is_integer(Inuse) -> Inuse end. - + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% purify_format(Format, Args) -> ok %% Format = string() @@ -2208,9 +2369,9 @@ local_or_remote_apply({M,F,A} = MFA) -> request(Sock,Request) -> gen_tcp:send(Sock,<<1,(term_to_binary(Request))/binary>>). -%% +%% %% Generic receive function for communication with host -%% +%% recv(Sock) -> case gen_tcp:recv(Sock,0) of {error,closed} -> diff --git a/lib/test_server/src/test_server_ctrl.erl b/lib/test_server/src/test_server_ctrl.erl index 4cb5863955..1dc5646184 100644 --- a/lib/test_server/src/test_server_ctrl.erl +++ b/lib/test_server/src/test_server_ctrl.erl @@ -27,7 +27,7 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% MODULE DEPENDENCIES: -%% HARD TO REMOVE: erlang, lists, io_lib, gen_server, file, io, string, +%% HARD TO REMOVE: erlang, lists, io_lib, gen_server, file, io, string, %% code, ets, rpc, gen_tcp, inet, erl_tar, sets, %% test_server, test_server_sup, test_server_node %% EASIER TO REMOVE: filename, filelib, lib, re @@ -36,7 +36,7 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% ARCHITECTURE -%% +%% %% The Erlang Test Server can be run on the target machine (local target) %% or towards a remote target. The execution flow is mainly the same in %% both cases, but with a remote target the test cases are (obviously) @@ -44,11 +44,11 @@ %% socket connections because the host should not be introduced as an %% additional node in the distributed erlang system in which the test %% cases are run. -%% -%% +%% +%% %% Local Target: %% ============= -%% +%% %% ----- %% | | test_server_ctrl ({global,test_server}) %% ----- (test_server_ctrl.erl) @@ -62,33 +62,33 @@ %% ----- %% | | CaseProc %% ----- (test_server.erl) -%% -%% -%% +%% +%% +%% %% test_server_ctrl is the main process in the system. It is a registered %% process, and it will always be alive when testing is ongoing. %% test_server_ctrl initiates testing and monitors JobProc(s). -%% -%% When target is local, and Test Server is *not* being used by a framework -%% application (where it might cause duplicate name problems in a distributed -%% test environment), the process is globally registered as 'test_server' +%% +%% When target is local, and Test Server is *not* being used by a framework +%% application (where it might cause duplicate name problems in a distributed +%% test environment), the process is globally registered as 'test_server' %% to be able to simulate the {global,test_server} process on a remote target. -%% -%% JobProc is spawned for each 'job' added to the test_server_ctrl. +%% +%% JobProc is spawned for each 'job' added to the test_server_ctrl. %% A job can mean one test case, one test suite or one spec. %% JobProc creates and writes logs and presents results from testing. %% JobProc is the group leader for CaseProc. -%% +%% %% CaseProc is spawned for each test case. It runs the test case and %% sends results and any other information to its group leader - JobProc. -%% -%% -%% +%% +%% +%% %% Remote Target: %% ============== -%% +%% %% HOST TARGET -%% +%% %% ----- MainSock ----- %% test_server_ctrl | |- - - - - - -| | {global,test_server} %% (test_server_ctrl.erl) ----- ----- (test_server.erl) @@ -102,36 +102,36 @@ %% ----- %% | | CaseProc %% ----- (test_server.erl) -%% -%% -%% -%% +%% +%% +%% +%% %% A separate test_server process only exists when target is remote. It %% is then the main process on target. It is started when test_server_ctrl %% is started, and a socket connection is established between %% test_server_ctrl and test_server. The following information can be sent %% over MainSock: -%% +%% %% HOST TARGET %% -> {target_info, TargetInfo} (during initiation) %% <- {job_proc_killed,Name,Reason} (if a JobProcT dies unexpectedly) %% -> {job,Port,Name} (to start a new JobProcT) -%% -%% +%% +%% %% When target is remote, JobProc is split into to processes: JobProcH %% executing on Host and JobProcT executing on Target. (The two processes %% execute the same code as JobProc does when target is local.) JobProcH %% and JobProcT communicates over a socket connection. The following %% information can be sent over JobSock: -%% +%% %% HOST TARGET %% -> {test_case, Case} To start a new test case %% -> {beam,Mod} .beam file as binary to be loaded %% on target, e.g. a test suite %% -> {datadir,Tarfile} Content of the datadir for a test suite %% <- {apply,MFA} MFA to be applied on host, ignore return; -%% (apply is used for printing information in -%% log or console) +%% (apply is used for printing information in +%% log or console) %% <- {sync_apply,MFA} MFA to be applied on host, wait for return %% (used for starting and stopping slave nodes) %% -> {sync_apply,MFA} MFA to be applied on target, wait for return @@ -141,7 +141,7 @@ %% <- {crash_dumps,Tarfile} When a test case is finished %% -> job_done When a job is finished %% <- {privdir,Privdir} When a job is finished -%% +%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -151,17 +151,19 @@ %%% OPERATOR INTERFACE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -export([add_spec/1, add_dir/2, add_dir/3]). --export([add_module/1, add_module/2, add_case/2, add_case/3, add_cases/2, - add_cases/3]). +-export([add_module/1, add_module/2, + add_conf/3, + add_case/2, add_case/3, add_cases/2, add_cases/3]). -export([add_dir_with_skip/3, add_dir_with_skip/4, add_tests_with_skip/3]). -export([add_module_with_skip/2, add_module_with_skip/3, + add_conf_with_skip/4, add_case_with_skip/3, add_case_with_skip/4, add_cases_with_skip/3, add_cases_with_skip/4]). -export([jobs/0, run_test/1, wait_finish/0, idle_notify/1, abort_current_testcase/1, abort/0]). -export([start_get_totals/1, stop_get_totals/0]). -export([get_levels/0, set_levels/3]). --export([multiply_timetraps/1]). +-export([multiply_timetraps/1, scale_timetraps/1, get_timetrap_parameters/0]). -export([cover/2, cover/3, cover/7, cross_cover_analyse/1, cross_cover_analyse/2, trc/1, stop_trace/0]). -export([testcase_callback/1]). @@ -207,13 +209,15 @@ -define(pl2a(M), test_server_sup:package_atom(M)). -define(void_fun, fun() -> ok end). --define(mod_result(X), if X == skip -> skipped; - X == auto_skip -> skipped; +-define(mod_result(X), if X == skip -> skipped; + X == auto_skip -> skipped; true -> X end). --record(state,{jobs=[],levels={1,19,10},multiply_timetraps=1,finish=false, +-record(state,{jobs=[],levels={1,19,10}, + multiply_timetraps=1,scale_timetraps=true, + finish=false, target_info, trc=false, cover=false, wait_for_node=[], - testcase_callback=undefined, idle_notify=[], + testcase_callback=undefined, idle_notify=[], get_totals=false, random_seed=undefined}). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -222,21 +226,28 @@ add_dir(Name, Job=[Dir|_Dirs]) when is_list(Dir) -> add_job(cast_to_list(Name), lists:map(fun(D)-> {dir,cast_to_list(D)} end, Job)); -add_dir(Name, Dir) -> +add_dir(Name, Dir) -> add_job(cast_to_list(Name), {dir,cast_to_list(Dir)}). add_dir(Name, Job=[Dir|_Dirs], Pattern) when is_list(Dir) -> add_job(cast_to_list(Name), lists:map(fun(D)-> {dir,cast_to_list(D), cast_to_list(Pattern)} end, Job)); -add_dir(Name, Dir, Pattern) -> +add_dir(Name, Dir, Pattern) -> add_job(cast_to_list(Name), {dir,cast_to_list(Dir),cast_to_list(Pattern)}). add_module(Mod) when is_atom(Mod) -> add_job(atom_to_list(Mod), {Mod,all}). + add_module(Name, Mods) when is_list(Mods) -> add_job(cast_to_list(Name), lists:map(fun(Mod) -> {Mod,all} end, Mods)). +add_conf(Name, Mod, Conf) when is_tuple(Conf) -> + add_job(cast_to_list(Name), {Mod,[Conf]}); + +add_conf(Name, Mod, Confs) when is_list(Confs) -> + add_job(cast_to_list(Name), {Mod,Confs}). + add_case(Mod, Case) when is_atom(Mod), is_atom(Case) -> add_job(atom_to_list(Mod), {Mod,Case}). @@ -256,14 +267,14 @@ add_spec(Spec) -> false -> {error,nofile} end. -%% This version of the interface is to be used if there are +%% This version of the interface is to be used if there are %% suites or cases that should be skipped. add_dir_with_skip(Name, Job=[Dir|_Dirs], Skip) when is_list(Dir) -> add_job(cast_to_list(Name), lists:map(fun(D)-> {dir,cast_to_list(D)} end, Job), Skip); -add_dir_with_skip(Name, Dir, Skip) -> +add_dir_with_skip(Name, Dir, Skip) -> add_job(cast_to_list(Name), {dir,cast_to_list(Dir)}, Skip). add_dir_with_skip(Name, Job=[Dir|_Dirs], Pattern, Skip) when is_list(Dir) -> @@ -271,7 +282,7 @@ add_dir_with_skip(Name, Job=[Dir|_Dirs], Pattern, Skip) when is_list(Dir) -> lists:map(fun(D)-> {dir,cast_to_list(D), cast_to_list(Pattern)} end, Job), Skip); -add_dir_with_skip(Name, Dir, Pattern, Skip) -> +add_dir_with_skip(Name, Dir, Pattern, Skip) -> add_job(cast_to_list(Name), {dir,cast_to_list(Dir),cast_to_list(Pattern)}, Skip). @@ -281,6 +292,12 @@ add_module_with_skip(Mod, Skip) when is_atom(Mod) -> add_module_with_skip(Name, Mods, Skip) when is_list(Mods) -> add_job(cast_to_list(Name), lists:map(fun(Mod) -> {Mod,all} end, Mods), Skip). +add_conf_with_skip(Name, Mod, Conf, Skip) when is_tuple(Conf) -> + add_job(cast_to_list(Name), {Mod,[Conf]}, Skip); + +add_conf_with_skip(Name, Mod, Confs, Skip) when is_list(Confs) -> + add_job(cast_to_list(Name), {Mod,Confs}, Skip). + add_case_with_skip(Mod, Case, Skip) when is_atom(Mod), is_atom(Case) -> add_job(atom_to_list(Mod), {Mod,Case}, Skip). @@ -295,15 +312,14 @@ add_cases_with_skip(Name, Mod, Cases, Skip) when is_atom(Mod), is_list(Cases) -> add_tests_with_skip(LogDir, Tests, Skip) -> add_job(LogDir, - lists:map(fun({Dir,all,all}) -> + lists:map(fun({Dir,all,all}) -> {Dir,{dir,Dir}}; - ({Dir,Mods,all}) -> + ({Dir,Mods,all}) -> {Dir,lists:map(fun(M) -> {M,all} end, Mods)}; ({Dir,Mod,Cases}) -> {Dir,{Mod,Cases}} end, Tests), Skip). - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% COMMAND LINE INTERFACE @@ -315,7 +331,7 @@ parse_cmd_line(['SPEC',Spec|Cmds], SpecList, Names, Param, Trc, Cov, TCCB) -> case file:consult(Spec) of {ok, TermList} -> Name = filename:rootname(Spec), - parse_cmd_line(Cmds, TermList++SpecList, [Name|Names], Param, + parse_cmd_line(Cmds, TermList++SpecList, [Name|Names], Param, Trc, Cov, TCCB); {error,Reason} -> io:format("Can't open ~s: ~p\n", @@ -406,7 +422,7 @@ run_test(CommandLine) -> end, testcase_callback(TCCB), add_job(Name, {command_line,SpecList}), - + %% adding of jobs involves file i/o which may take long time %% when running a nfs mounted file system (VxWorks). case controller_call(get_target_info) of @@ -479,6 +495,12 @@ set_levels(Show, Major, Minor) -> multiply_timetraps(N) -> controller_call({multiply_timetraps,N}). +scale_timetraps(Bool) -> + controller_call({scale_timetraps,Bool}). + +get_timetrap_parameters() -> + controller_call(get_timetrap_parameters). + trc(TraceFile) -> controller_call({trace,TraceFile}, 2*?ACCEPT_TIMEOUT). @@ -551,7 +573,7 @@ controller_call(Arg, Timeout) -> Other -> Other end. - + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -617,7 +639,7 @@ contact_main_target(local) -> case os:getenv("TEST_SERVER_FRAMEWORK") of false -> %% Local target! The global test_server process implemented by - %% test_server.erl will not be started, so we simulate it by + %% test_server.erl will not be started, so we simulate it by %% globally registering this process instead. global:sync(), case global:whereis_name(test_server) of @@ -681,9 +703,9 @@ read_parameters([], Par) when Par#par.type==undefined -> read_parameters([], Par) when Par#par.target==undefined -> {error, {missing_mandatory_parameter,target}}; read_parameters([], Par0) -> - Par = + Par = case {Par0#par.type, Par0#par.master} of - {ose, undefined} -> + {ose, undefined} -> %% Use this node as master and bootserver for target %% and slave nodes Par0#par{master = atom_to_list(node()), @@ -691,10 +713,10 @@ read_parameters([], Par0) -> {ose, _Master} -> %% Master for target and slave nodes was defined in parameterfile Par0; - _ -> + _ -> %% Use target as master for slave nodes, %% (No master is used for target) - Par0#par{master="test_server@" ++ Par0#par.target} + Par0#par{master="test_server@" ++ Par0#par.target} end, {ok,Par}. @@ -708,7 +730,7 @@ naming() -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% handle_call(kill_slavenodes, From, State) -> ok %% -%% Kill all slave nodes that remain after a test case +%% Kill all slave nodes that remain after a test case %% is completed. %% handle_call(kill_slavenodes, _From, State) -> @@ -736,7 +758,7 @@ handle_call(get_hosts, _From, State) -> {reply, Hosts, State}; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% handle_call({add_job,Dir,Name,TopCase,Skip}, _, State) -> +%% handle_call({add_job,Dir,Name,TopCase,Skip}, _, State) -> %% ok | {error,Reason} %% %% Dir = string() @@ -760,7 +782,7 @@ handle_call(get_hosts, _From, State) -> handle_call({add_job,Dir,Name,TopCase,Skip}, _From, State) -> LogDir = Dir ++ ?logdir_ext, - ExtraTools = + ExtraTools = case State#state.cover of false -> []; {App,Analyse} -> [{cover,App,Analyse}] @@ -776,19 +798,21 @@ handle_call({add_job,Dir,Name,TopCase,Skip}, _From, State) -> {spec,SpecName} -> Pid = spawn_tester( ?MODULE, do_spec, - [SpecName,State#state.multiply_timetraps], - LogDir, Name, State#state.levels, + [SpecName,{State#state.multiply_timetraps, + State#state.scale_timetraps}], + LogDir, Name, State#state.levels, State#state.testcase_callback, ExtraTools1), NewJobs = [{Name,Pid}|State#state.jobs], - {reply, ok, State#state{jobs=NewJobs}}; + {reply, ok, State#state{jobs=NewJobs}}; {command_line,SpecList} -> Pid = spawn_tester( ?MODULE, do_spec_list, - [SpecList,State#state.multiply_timetraps], - LogDir, Name, State#state.levels, + [SpecList,{State#state.multiply_timetraps, + State#state.scale_timetraps}], + LogDir, Name, State#state.levels, State#state.testcase_callback, ExtraTools1), NewJobs = [{Name,Pid}|State#state.jobs], - {reply, ok, State#state{jobs=NewJobs}}; + {reply, ok, State#state{jobs=NewJobs}}; TopCase -> case State#state.get_totals of {CliPid,Fun} -> @@ -798,10 +822,11 @@ handle_call({add_job,Dir,Name,TopCase,Skip}, _From, State) -> _ -> Cfg = make_config([]), Pid = spawn_tester( - ?MODULE, do_test_cases, + ?MODULE, do_test_cases, [TopCase,Skip,Cfg, - State#state.multiply_timetraps], - LogDir, Name, State#state.levels, + {State#state.multiply_timetraps, + State#state.scale_timetraps}], + LogDir, Name, State#state.levels, State#state.testcase_callback, ExtraTools1), NewJobs = [{Name,Pid}|State#state.jobs], {reply, ok, State#state{jobs=NewJobs}} @@ -827,7 +852,7 @@ handle_call(jobs, _From, State) -> %% handle_call({abort_current_testcase,Reason}, _, State) -> Result %% Reason = term() %% Result = ok | {error,no_testcase_running} -%% +%% %% Attempts to abort the test case that's currently running. handle_call({abort_current_testcase,Reason}, _From, State) -> @@ -855,7 +880,7 @@ handle_call({abort_current_testcase,Reason}, _From, State) -> handle_call({finish,Fini}, _From, State) -> case State#state.jobs of [] -> - lists:foreach(fun({Cli,Fun}) -> Fun(Cli) end, + lists:foreach(fun({Cli,Fun}) -> Fun(Cli) end, State#state.idle_notify), State2 = State#state{finish=false}, {stop,shutdown,{ok,self()}, State2}; @@ -878,7 +903,7 @@ handle_call({idle_notify,Fun}, {Cli,_Ref}, State) -> {reply, {ok,self()}, State}; _ -> Subscribed = State#state.idle_notify, - {reply, {ok,self()}, + {reply, {ok,self()}, State#state{idle_notify=[{Cli,Fun}|Subscribed]}} end; @@ -891,7 +916,7 @@ handle_call({idle_notify,Fun}, {Cli,_Ref}, State) -> handle_call({start_get_totals,Fun}, {Cli,_Ref}, State) -> {reply, {ok,self()}, State#state{get_totals={Cli,Fun}}}; - + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% handle_call(stop_get_totals, From, State) -> ok %% @@ -942,11 +967,31 @@ handle_call({multiply_timetraps,N}, _From, State) -> {reply,ok,State#state{multiply_timetraps=N}}; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% handle_call({scale_timetraps,Bool}, _, State) -> ok +%% Bool = true | false +%% +%% Specifies if test_server should scale the timetrap value +%% automatically if e.g. cover is running. + +handle_call({scale_timetraps,Bool}, _From, State) -> + {reply,ok,State#state{scale_timetraps=Bool}}; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% handle_call(get_timetrap_parameters, _, State) -> {Multiplier,Scale} +%% Multiplier = integer() | infinity +%% Scale = true | false +%% +%% Returns the parameter values that affect timetraps. + +handle_call(get_timetrap_parameters, _From, State) -> + {reply,{State#state.multiply_timetraps,State#state.scale_timetraps},State}; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% handle_call({trace,TraceFile}, _, State) -> ok | {error,Reason} %% -%% Starts a separate node (trace control node) which +%% Starts a separate node (trace control node) which %% starts tracing on target and all slave nodes -%% +%% %% TraceFile is a text file with elements of type %% {Trace,Mod,TracePattern}. %% {Trace,Mod,Func,TracePattern}. @@ -955,10 +1000,10 @@ handle_call({multiply_timetraps,N}, _From, State) -> %% Trace = tp | tpl; local or global call trace %% Mod,Func = atom(), Arity=integer(); defines what to trace %% TracePattern = [] | match_spec() -%% +%% %% The 'call' trace flag is set on all processes, and then %% the given trace patterns are set. - + handle_call({trace,TraceFile}, _From, State=#state{trc=false}) -> TI = State#state.target_info, case test_server_node:start_tracer_node(TraceFile, TI) of @@ -993,7 +1038,7 @@ handle_call({cover,App,Analyse}, _From, State) -> %% handle_call({testcase_callback,{Mod,Func}}, _, State) -> ok | {error,Reason} %% %% Add a callback function that will be called before and after every -%% test case (on the test case process): +%% test case (on the test case process): %% %% Mod:Func(Suite,TestCase,InitOrEnd,Config) %% @@ -1001,9 +1046,9 @@ handle_call({cover,App,Analyse}, _From, State) -> handle_call({testcase_callback,ModFunc}, _From, State) -> case ModFunc of - {Mod,Func} -> + {Mod,Func} -> case code:is_loaded(Mod) of - {file,_} -> + {file,_} -> ok; false -> code:load_file(Mod) @@ -1065,15 +1110,15 @@ handle_call({start_node, Name, Type, Options}, From, State) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% handle_call({wait_for_node,Node}, _, State) -> ok %% -%% Waits for a new node to take contact. Used if +%% Waits for a new node to take contact. Used if %% node is started with option {wait,false} handle_call({wait_for_node, Node}, From, State) -> - NewWaitList = + NewWaitList = case ets:lookup(slave_tab,Node) of - [] -> + [] -> [{Node,From}|State#state.wait_for_node]; - _ -> + _ -> gen_server:reply(From,ok), State#state.wait_for_node end, @@ -1086,7 +1131,7 @@ handle_call({wait_for_node, Node}, From, State) -> %% - the node is really stopped by test_server when this returns. handle_call({stop_node, Name}, _From, State) -> - R = test_server_node:stop_node(Name, State#state.target_info), + R = test_server_node:stop_node(Name, State#state.target_info), {reply, R, State}; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1112,7 +1157,7 @@ handle_cast({node_started,Node}, State) -> false -> ok; Trc -> test_server_node:trace_nodes(Trc, [Node]) end, - NewWaitList = + NewWaitList = case lists:keysearch(Node,1,State#state.wait_for_node) of {value,{Node,From}} -> gen_server:reply(From, ok), @@ -1128,10 +1173,10 @@ handle_cast({node_started,Node}, State) -> %% Reason = term() %% %% Handles exit messages from linked processes. Only test suites and -%% possibly a target client are expected to be linked. +%% possibly a target client are expected to be linked. %% When a test suite terminates, it is removed from the job queue. %% If a target client terminates it means that we lost contact with -%% target. The test_server_ctrl process is terminated, and teminate/2 +%% target. The test_server_ctrl process is terminated, and teminate/2 %% will do the cleanup handle_info({'EXIT',Pid,Reason}, State) -> @@ -1139,7 +1184,7 @@ handle_info({'EXIT',Pid,Reason}, State) -> false -> TI = State#state.target_info, case TI#target_info.target_client of - Pid -> + Pid -> %% The target client died - lost contact with target {stop,{lost_contact_with_target,Reason},State}; _other -> @@ -1160,13 +1205,13 @@ handle_info({'EXIT',Pid,Reason}, State) -> State2 = State#state{jobs=NewJobs}, case NewJobs of [] -> - lists:foreach(fun({Cli,Fun}) -> Fun(Cli) end, + lists:foreach(fun({Cli,Fun}) -> Fun(Cli) end, State2#state.idle_notify), case State2#state.finish of false -> {noreply,State2#state{idle_notify=[]}}; _ -> % true | abort - %% test_server:finish() has been called and + %% test_server:finish() has been called and %% there are no jobs in the job queue => %% stop the test_server_ctrl {stop,shutdown,State2#state{finish=false}} @@ -1174,7 +1219,7 @@ handle_info({'EXIT',Pid,Reason}, State) -> _ -> % pending jobs case State2#state.finish of abort -> % abort test now! - lists:foreach(fun({Cli,Fun}) -> Fun(Cli) end, + lists:foreach(fun({Cli,Fun}) -> Fun(Cli) end, State2#state.idle_notify), {stop,shutdown,State2#state{finish=false}}; _ -> % true | false @@ -1194,9 +1239,9 @@ handle_info({tcp,_MainSock,<<1,Request/binary>>}, State) -> case binary_to_term(Request) of {job_proc_killed,Name,Reason} -> %% The only purpose of this is to inform the user about what - %% happened on target. + %% happened on target. %% The local job proc will soon be killed by the closed socket or - %% because the job is finished. Then the above clause ('EXIT') will + %% because the job is finished. Then the above clause ('EXIT') will %% handle the problem. io:format("Suite ~s was killed on remote target with reason" " ~p\n", [Name,Reason]); @@ -1204,13 +1249,13 @@ handle_info({tcp,_MainSock,<<1,Request/binary>>}, State) -> ignore end, {noreply,State}; - + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% handle_info({tcp_closed,Sock}, State) %% %% A Socket was closed. This indicates that a node died. -%% This can be +%% This can be %% *Target node (if remote) %% *Slave or peer node started by a test suite %% *Trace controll node @@ -1221,10 +1266,10 @@ handle_info({tcp_closed,Sock}, State=#state{trc=Sock}) -> {noreply,State#state{trc=false}}; handle_info({tcp_closed,Sock}, State) -> case test_server_node:nodedown(Sock,State#state.target_info) of - target_died -> + target_died -> %% terminate/2 will do the cleanup {stop,target_died,State}; - _ -> + _ -> {noreply,State} end; @@ -1260,7 +1305,7 @@ kill_all_jobs([]) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% spawn_tester(Mod, Func, Args, Dir, Name, Levels, +%% spawn_tester(Mod, Func, Args, Dir, Name, Levels, %% TestCaseCallback, ExtraTools) -> Pid %% Mod = atom() %% Func = atom() @@ -1268,23 +1313,23 @@ kill_all_jobs([]) -> %% Dir = string() %% Name = string() %% Levels = {integer(),integer(),integer()} -%% TestCaseCallback = {CBMod,CBFunc} | undefined +%% TestCaseCallback = {CBMod,CBFunc} | undefined %% ExtraTools = [ExtraTool,...] %% ExtraTool = CoverInfo | TraceInfo | RandomSeed %% %% Spawns a test suite execute-process, just an ordinary spawn, except %% that it will set a lot of dictionary information before starting the %% named function. Also, the execution is timed and protected by a catch. -%% When the named function is done executing, a summary of the results +%% When the named function is done executing, a summary of the results %% is printed to the log files. spawn_tester(Mod, Func, Args, Dir, Name, Levels, TCCallback, ExtraTools) -> spawn_link( - fun() -> init_tester(Mod, Func, Args, Dir, Name, Levels, - TCCallback, ExtraTools) + fun() -> init_tester(Mod, Func, Args, Dir, Name, Levels, + TCCallback, ExtraTools) end). -init_tester(Mod, Func, Args, Dir, Name, {SumLev,MajLev,MinLev}, +init_tester(Mod, Func, Args, Dir, Name, {SumLev,MajLev,MinLev}, TCCallback, ExtraTools) -> process_flag(trap_exit, true), put(test_server_name, Name), @@ -1324,7 +1369,7 @@ init_tester(Mod, Func, Args, Dir, Name, {SumLev,MajLev,MinLev}, {Skipped,_} -> {Skipped,io_lib:format(", ~p Skipped", [Skipped])} end, OkN = get(test_server_ok), - FailedN = get(test_server_failed), + FailedN = get(test_server_failed), print(html,"<tr><td></td><td><b>TOTAL</b></td><td></td><td></td>" "<td>~.3fs</td><td><b>~s</b></td><td>~p Ok, ~p Failed~s of ~p</td></tr>\n", [Time,SuccessStr,OkN,FailedN,SkipStr,OkN+FailedN+SkippedN]). @@ -1338,9 +1383,9 @@ ts_tc(M, F, A) -> {Elapsed,Val}. elapsed_time(Before, After) -> - (element(1,After)*1000000000000 + + (element(1,After)*1000000000000 + element(2,After)*1000000 + element(3,After)) - - (element(1,Before)*1000000000000 + + (element(1,Before)*1000000000000 + element(2,Before)*1000000 + element(3,Before)). start_extra_tools(ExtraTools) -> @@ -1378,28 +1423,32 @@ stop_extra_tools([], _) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% do_spec(SpecName, MultiplyTimetrap) -> {error,Reason} | exit(Result) +%% do_spec(SpecName, TimetrapSpec) -> {error,Reason} | exit(Result) %% SpecName = string() +%% TimetrapSpec = MultiplyTimetrap | {MultiplyTimetrap,ScaleTimetrap} %% MultiplyTimetrap = integer() | infinity +%% ScaleTimetrap = bool() %% %% Reads the named test suite specification file, and executes it. %% -%% This function is meant to be called by a process created by +%% This function is meant to be called by a process created by %% spawn_tester/7, which sets up some necessary dictionary values. -do_spec(SpecName, MultiplyTimetrap) when is_list(SpecName) -> +do_spec(SpecName, TimetrapSpec) when is_list(SpecName) -> case file:consult(SpecName) of {ok,TermList} -> - do_spec_list(TermList,MultiplyTimetrap); + do_spec_list(TermList,TimetrapSpec); {error,Reason} -> io:format("Can't open ~s: ~p\n", [SpecName,Reason]), {error,{cant_open_spec,Reason}} end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% do_spec_list(TermList) -> exit(Result) +%% do_spec_list(TermList, TimetrapSpec) -> exit(Result) %% TermList = [term()|...] +%% TimetrapSpec = MultiplyTimetrap | {MultiplyTimetrap,ScaleTimetrap} %% MultiplyTimetrap = integer() | infinity +%% ScaleTimetrap = bool() %% %% Executes a list of test suite specification commands. The following %% commands are available, and may occur zero or more times (if several, @@ -1422,21 +1471,21 @@ do_spec(SpecName, MultiplyTimetrap) when is_list(SpecName) -> %% nodenames will be generated from the local host. %% %% {hosts, Hosts} Specifies a list of available hosts on which to start -%% slave nodes. It is used when the {remote, true} option is given to the +%% slave nodes. It is used when the {remote, true} option is given to the %% test_server:start_node/3 function. Also, if {require_nodenames, Num} is -%% contained in the TermList, the generated nodenames will be spread over +%% contained in the TermList, the generated nodenames will be spread over %% all hosts given in this Hosts list. The hostnames are given as atoms or %% strings. -%% +%% %% {diskless, true}</c></tag> is kept for backwards compatiblilty and %% should not be used. Use a configuration test case instead. -%% -%% This function is meant to be called by a process created by +%% +%% This function is meant to be called by a process created by %% spawn_tester/7, which sets up some necessary dictionary values. -do_spec_list(TermList0, MultiplyTimetrap) -> +do_spec_list(TermList0, TimetrapSpec) -> Nodes = [], - TermList = + TermList = case lists:keysearch(hosts, 1, TermList0) of {value, {hosts, Hosts0}} -> Hosts = lists:map(fun(H) -> cast_to_list(H) end, Hosts0), @@ -1447,7 +1496,7 @@ do_spec_list(TermList0, MultiplyTimetrap) -> end, DefaultConfig = make_config([{nodes,Nodes}]), {TopCases,SkipList,Config} = do_spec_terms(TermList, [], [], DefaultConfig), - do_test_cases(TopCases, SkipList, Config, MultiplyTimetrap). + do_test_cases(TopCases, SkipList, Config, TimetrapSpec). do_spec_terms([], TopCases, SkipList, Config) -> {TopCases,SkipList,Config}; @@ -1470,21 +1519,21 @@ do_spec_terms([{default_timeout,Tmo}|Terms], TopCases, SkipList, Config) -> do_spec_terms([{require_nodenames,NumNames}|Terms], TopCases, SkipList, Config) -> NodeNames0=generate_nodenames(NumNames), NodeNames=lists:delete([], NodeNames0), - do_spec_terms(Terms, TopCases, SkipList, + do_spec_terms(Terms, TopCases, SkipList, update_config(Config, {nodenames,NodeNames})); do_spec_terms([Other|Terms], TopCases, SkipList, Config) -> io:format("** WARNING: Spec file contains unknown directive ~p\n", [Other]), do_spec_terms(Terms, TopCases, SkipList, Config). - + generate_nodenames(Num) -> Hosts = case controller_call(get_hosts) of - [] -> + [] -> TI = controller_call(get_target_info), [TI#target_info.host]; - List -> + List -> List end, generate_nodenames2(Num, Hosts, []). @@ -1511,25 +1560,25 @@ temp_nodename([Chr|Base], Acc) -> %% NoOfCases = integer() | unknown %% %% Counts the test cases that are about to run and returns that number. -%% If there's a conf group in TestSpec with a repeat property, the total number +%% If there's a conf group in TestSpec with a repeat property, the total number %% of cases can not be calculated and NoOfCases = unknown. count_test_cases(TopCases, SkipCases) when is_list(TopCases) -> case collect_all_cases(TopCases, SkipCases) of - {error,_} -> - error; + {error,_Why} = Error -> + Error; TestSpec -> {get_suites(TestSpec, []), case remove_conf(TestSpec) of {repeats,_} -> unknown; - TestSpec1 -> + TestSpec1 -> length(TestSpec1) end} end; count_test_cases(TopCase, SkipCases) -> count_test_cases([TopCase], SkipCases). - + remove_conf(Cases) -> remove_conf(Cases, [], false). @@ -1538,13 +1587,15 @@ remove_conf([{conf, _Ref, Props, _MF}|Cases], NoConf, Repeats) -> case get_repeat(Props) of undefined -> remove_conf(Cases, NoConf, Repeats); + {_RepType,1} -> + remove_conf(Cases, NoConf, Repeats); _ -> remove_conf(Cases, NoConf, true) end; remove_conf([{make,_Ref,_MF}|Cases], NoConf, Repeats) -> remove_conf(Cases, NoConf, Repeats); -remove_conf([{skip_case,{Type,_Ref,_MF,_Cmt}}|Cases], - NoConf, Repeats) when Type==conf; +remove_conf([{skip_case,{Type,_Ref,_MF,_Cmt}}|Cases], + NoConf, Repeats) when Type==conf; Type==make -> remove_conf(Cases, NoConf, Repeats); remove_conf([C|Cases], NoConf, Repeats) -> @@ -1582,22 +1633,30 @@ add_mod(Mod, Mods) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% do_test_cases(TopCases, SkipCases, Config, MultiplyTimetrap) -> +%% do_test_cases(TopCases, SkipCases, Config, TimetrapSpec) -> %% exit(Result) %% %% TopCases = term() (See collect_cases/3) %% SkipCases = term() (See collect_cases/3) %% Config = term() (See collect_cases/3) +%% TimetrapSpec = MultiplyTimetrap | {MultiplyTimetrap,ScaleTimetrap} %% MultiplyTimetrap = integer() | infinity +%% ScaleTimetrap = bool() %% %% Initializes and starts the test run, for "ordinary" test suites. %% Creates log directories and log files, inserts initial timestamps and %% configuration information into the log files. %% -%% This function is meant to be called by a process created by +%% This function is meant to be called by a process created by %% spawn_tester/7, which sets up some necessary dictionary values. - -do_test_cases(TopCases, SkipCases, Config, MultiplyTimetrap) when is_list(TopCases) -> +do_test_cases(TopCases, SkipCases, + Config, MultiplyTimetrap) when is_integer(MultiplyTimetrap); + MultiplyTimetrap == infinity -> + do_test_cases(TopCases, SkipCases, Config, {MultiplyTimetrap,true}); + +do_test_cases(TopCases, SkipCases, + Config, TimetrapData) when is_list(TopCases), + is_tuple(TimetrapData) -> start_log_file(), case collect_all_cases(TopCases, SkipCases) of {error,Why} -> @@ -1607,27 +1666,36 @@ do_test_cases(TopCases, SkipCases, Config, MultiplyTimetrap) when is_list(TopCas N = case remove_conf(TestSpec0) of {repeats,_} -> unknown; TS -> length(TS) - end, + end, put(test_server_cases, N), put(test_server_case_num, 0), - TestSpec = + TestSpec = add_init_and_end_per_suite(TestSpec0, undefined, undefined), + TI = get_target_info(), print(1, "Starting test~s", [print_if_known(N, {", ~w test cases",[N]}, {" (with repeated test cases)",[]})]), - test_server_sup:framework_call(report, [tests_start, - {get(test_server_name),N}]), - print(html, - "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n" - "<!-- autogenerated by '"++atom_to_list(?MODULE)++"'. -->\n" - "<html>\n" - "<head><title>Test ~p results</title>\n" - "<meta http-equiv=\"cache-control\" content=\"no-cache\">\n" - "</head>\n" - "<body bgcolor=\"white\" text=\"black\" " - "link=\"blue\" vlink=\"purple\" alink=\"red\">" - "<h2>Results from test ~p</h2>\n", - [get(test_server_name),get(test_server_name)]), + Test = get(test_server_name), + test_server_sup:framework_call(report, [tests_start,{Test,N}]), + + Header = + case test_server_sup:framework_call(overview_html_header, [Test], "") of + "" -> + TestName = lists:flatten(io_lib:format("~p", [Test])), + ["<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n", + "<!-- autogenerated by '", atom_to_list(?MODULE), "'. -->\n", + "<html>\n", + "<head><title>Test ", TestName, " results</title>\n", + "<meta http-equiv=\"cache-control\" content=\"no-cache\">\n", + "</head>\n", + "<body bgcolor=\"white\" text=\"black\" ", + "link=\"blue\" vlink=\"purple\" alink=\"red\">", + "<h2>Results from test ", TestName, "</h2>\n"]; + Html -> + ["<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n", + "<!-- autogenerated by '", atom_to_list(?MODULE), "'. -->\n" | Html] + end, + print(html, Header, []), print_timestamp(html, "Test started at "), print(html, "<p>Host:<br>\n"), @@ -1643,7 +1711,7 @@ do_test_cases(TopCases, SkipCases, Config, MultiplyTimetrap) when is_list(TopCas [TI#target_info.version, TI#target_info.root_dir]); _ -> case test_server_sup:framework_call(target_info, []) of - TargetInfo when is_list(TargetInfo), + TargetInfo when is_list(TargetInfo), length(TargetInfo) > 0 -> print(html, "<p>Target:<br>\n"), print(html, "~s\n", [TargetInfo]); @@ -1658,7 +1726,7 @@ do_test_cases(TopCases, SkipCases, Config, MultiplyTimetrap) when is_list(TopCas [?suitelog_name,?coverlog_name]), print(html,"<p>~s" "<p>\n" - "<table border=3 cellpadding=5>" + "<table bgcolor=\"white\" border=\"3\" cellpadding=\"5\">" "<tr><th>Num</th><th>Module</th><th>Case</th><th>Log</th>" "<th>Time</th><th>Result</th><th>Comment</th></tr>\n", [print_if_known(N, {"Suite contains ~p test cases.\n",[N]}, @@ -1681,12 +1749,12 @@ do_test_cases(TopCases, SkipCases, Config, MultiplyTimetrap) when is_list(TopCas print(major, "=otp_release ~s", [TI#target_info.otp_release]), print(major, "=started ~s", [lists:flatten(timestamp_get(""))]), - run_test_cases(TestSpec, Config, MultiplyTimetrap) + run_test_cases(TestSpec, Config, TimetrapData) end; -do_test_cases(TopCase, SkipCases, Config, MultiplyTimetrap) -> +do_test_cases(TopCase, SkipCases, Config, TimetrapSpec) -> %% when not list(TopCase) - do_test_cases([TopCase], SkipCases, Config, MultiplyTimetrap). + do_test_cases([TopCase], SkipCases, Config, TimetrapSpec). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1741,8 +1809,8 @@ start_log_file() -> ok. make_html_link(LinkName, Target, Explanation) -> - %% if possible use a relative reference�to�Target. - TargetL = filename:split(Target), + %% if possible use a relative reference to Target. + TargetL = filename:split(Target), PwdL = filename:split(filename:dirname(LinkName)), Href = case lists:prefix(PwdL, TargetL) of true -> @@ -1782,7 +1850,7 @@ start_minor_log_file(Mod, Func) -> start_minor_log_file1(Mod, Func, LogDir, AbsName); {ok,_} -> %% special case, duplicate names {_,S,Us} = now(), - Name1_0 = + Name1_0 = lists:flatten(io_lib:format("~s.~s.~w.~w~s", [Mod,Func,S, trunc(Us/1000), ?html_ext])), @@ -1853,7 +1921,7 @@ html_convert_modules(TestSpec, _Config) -> %% Retrieve a list of modules out of the test spec. html_isolate_modules(List) -> html_isolate_modules(List, sets:new()). - + html_isolate_modules([], Set) -> sets:to_list(Set); html_isolate_modules([{skip_case,_}|Cases], Set) -> html_isolate_modules(Cases, Set); @@ -1919,36 +1987,36 @@ add_init_and_end_per_suite([{make,_,_}=Case|Cases], LastMod, LastRef) -> [Case|add_init_and_end_per_suite(Cases, LastMod, LastRef)]; add_init_and_end_per_suite([{skip_case,{{Mod,all},_}}=Case|Cases], LastMod, LastRef) when Mod =/= LastMod -> - {PreCases, NextMod, NextRef} = + {PreCases, NextMod, NextRef} = do_add_end_per_suite_and_skip(LastMod, LastRef, Mod), PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef)]; add_init_and_end_per_suite([{skip_case,{{Mod,_},_}}=Case|Cases], LastMod, LastRef) when Mod =/= LastMod -> - {PreCases, NextMod, NextRef} = + {PreCases, NextMod, NextRef} = do_add_init_and_end_per_suite(LastMod, LastRef, Mod), PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef)]; add_init_and_end_per_suite([{skip_case,{conf,_,{Mod,_},_}}=Case|Cases], LastMod, LastRef) when Mod =/= LastMod -> - {PreCases, NextMod, NextRef} = + {PreCases, NextMod, NextRef} = do_add_init_and_end_per_suite(LastMod, LastRef, Mod), PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef)]; add_init_and_end_per_suite([{skip_case,_}=Case|Cases], LastMod, LastRef) -> [Case|add_init_and_end_per_suite(Cases, LastMod, LastRef)]; -add_init_and_end_per_suite([{conf,_,_,{Mod,_}}=Case|Cases], LastMod, LastRef) +add_init_and_end_per_suite([{conf,_,_,{Mod,_}}=Case|Cases], LastMod, LastRef) when Mod =/= LastMod -> - {PreCases, NextMod, NextRef} = + {PreCases, NextMod, NextRef} = do_add_init_and_end_per_suite(LastMod, LastRef, Mod), PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef)]; add_init_and_end_per_suite([{conf,_,_,_}=Case|Cases], LastMod, LastRef) -> [Case|add_init_and_end_per_suite(Cases, LastMod, LastRef)]; -add_init_and_end_per_suite([{Mod,_}=Case|Cases], LastMod, LastRef) +add_init_and_end_per_suite([{Mod,_}=Case|Cases], LastMod, LastRef) when Mod =/= LastMod -> - {PreCases, NextMod, NextRef} = + {PreCases, NextMod, NextRef} = do_add_init_and_end_per_suite(LastMod, LastRef, Mod), PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef)]; add_init_and_end_per_suite([{Mod,_,_}=Case|Cases], LastMod, LastRef) when Mod =/= LastMod -> - {PreCases, NextMod, NextRef} = + {PreCases, NextMod, NextRef} = do_add_init_and_end_per_suite(LastMod, LastRef, Mod), PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef)]; add_init_and_end_per_suite([Case|Cases], LastMod, LastRef)-> @@ -1965,7 +2033,7 @@ do_add_init_and_end_per_suite(LastMod, LastRef, Mod) -> false -> code:load_file(Mod); _ -> ok end, - {Init,NextMod,NextRef} = + {Init,NextMod,NextRef} = case erlang:function_exported(Mod, init_per_suite, 1) of true -> Ref = make_ref(), @@ -1973,15 +2041,15 @@ do_add_init_and_end_per_suite(LastMod, LastRef, Mod) -> false -> {[],Mod,undefined} end, - Cases = + Cases = if LastRef==undefined -> Init; LastRef==skipped_suite -> Init; true -> - %% Adding end_per_suite here without checking if the + %% Adding end_per_suite here without checking if the %% function is actually exported. This is because a - %% conf case must have an end case - so if it doesn't + %% conf case must have an end case - so if it doesn't %% exist, it will only fail... [{conf,LastRef,[],{LastMod,end_per_suite}}|Init] end, @@ -1997,23 +2065,19 @@ do_add_end_per_suite_and_skip(LastMod, LastRef, Mod) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% run_test_cases(TestSpec, Config, MultiplyTimetrap) -> exit(Result) +%% run_test_cases(TestSpec, Config, TimetrapData) -> exit(Result) %% %% If remote target, a socket connection is established. %% Runs the specified tests, then displays/logs the summary. -run_test_cases(TestSpec, Config, MultiplyTimetrap) -> +run_test_cases(TestSpec, Config, TimetrapData) -> maybe_open_job_sock(), html_convert_modules(TestSpec, Config), - %%! For readable tracing... - %%! Config1 = [{data_dir,""},{priv_dir,""},{nodes,[]}], - %%! run_test_cases_loop(TestSpec, [[]], MultiplyTimetrap, [], []), + run_test_cases_loop(TestSpec, [Config], TimetrapData, [], []), - run_test_cases_loop(TestSpec, [Config], MultiplyTimetrap, [], []), - maybe_get_privdir(), {AllSkippedN,UserSkipN,AutoSkipN,SkipStr} = @@ -2060,10 +2124,10 @@ maybe_open_job_sock() -> %% tar packet containing the privdir created by the test case. maybe_get_privdir() -> case get(test_server_ctrl_job_sock) of - undefined -> + undefined -> %% local target ok; - Sock -> + Sock -> %% remote target request(Sock, job_done), gen_tcp:close(Sock) @@ -2071,37 +2135,39 @@ maybe_get_privdir() -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% run_test_cases_loop(TestCases, Config, MultiplyTimetrap, Mode, Status) -> ok +%% run_test_cases_loop(TestCases, Config, TimetrapData, Mode, Status) -> ok %% TestCases = [Test,...] %% Config = [[{Key,Val},...],...] +%% TimetrapData = {MultiplyTimetrap,ScaleTimetrap} %% MultiplyTimetrap = integer() | infinity +%% ScaleTimetrap = bool() %% Mode = [{Ref,[Prop,..],StartTime}] %% Ref = reference() -%% Prop = {name,Name} | sequence | parallel | +%% Prop = {name,Name} | sequence | parallel | %% shuffle | {shuffle,Seed} | -%% repeat | {repeat,N} | +%% repeat | {repeat,N} | %% repeat_until_all_ok | {repeat_until_all_ok,N} | -%% repeat_until_any_ok | {repeat_until_any_ok,N} | -%% repeat_until_any_fail | {repeat_until_any_fail,N} | -%% repeat_until_all_fail | {repeat_until_all_fail,N} +%% repeat_until_any_ok | {repeat_until_any_ok,N} | +%% repeat_until_any_fail | {repeat_until_any_fail,N} | +%% repeat_until_all_fail | {repeat_until_all_fail,N} %% Status = [{Ref,{{Ok,Skipped,Failed},CopiedCases}}] %% Ok = Skipped = Failed = [Case,...] %% %% Execute the TestCases under configuration Config. Config is a list %% of lists, where hd(Config) holds the config tuples for the current -%% conf case and tl(Config) is the data for the higher level conf cases. -%% Config data is "inherited" from top to nested conf cases, but +%% conf case and tl(Config) is the data for the higher level conf cases. +%% Config data is "inherited" from top to nested conf cases, but %% never the other way around. if length(Config) == 1, Config contains %% only the initial config data for the suite. %% %% Test may be one of the following: %% -%% {conf,Ref,Props,{Mod,Func}} Mod:Func is a configuration modification +%% {conf,Ref,Props,{Mod,Func}} Mod:Func is a configuration modification %% function, call it with the current configuration as argument. It will %% return a new configuration. %% -%% {make,Ref,{Mod,Func,Args}} Mod:Func is a make function, and it is called -%% with the given arguments. This function will *always* be called on the host +%% {make,Ref,{Mod,Func,Args}} Mod:Func is a make function, and it is called +%% with the given arguments. This function will *always* be called on the host %% - not on target. %% %% {Mod,Case} This is a normal test case. Determine the correct @@ -2114,16 +2180,16 @@ maybe_get_privdir() -> %% {skip_case,{conf,Ref,Case,Comment}} An init conf case gets skipped %% by the user. This will also cause the end conf case to be skipped. %% Note that it is not possible to skip an end conf case directly (it -%% can only be skipped indirectly by a skipped init conf case). The -%% comment (which gets printed in the log files) describes why the case +%% can only be skipped indirectly by a skipped init conf case). The +%% comment (which gets printed in the log files) describes why the case %% was skipped. %% -%% {skip_case,{Case,Comment}} A normal test case skipped by the user. -%% The comment (which gets printed in the log files) describes why the +%% {skip_case,{Case,Comment}} A normal test case skipped by the user. +%% The comment (which gets printed in the log files) describes why the %% case was skipped. %% %% {auto_skip_case,{conf,Ref,Case,Comment},Mode} This is the result of -%% an end conf case being automatically skipped due to a failing init +%% an end conf case being automatically skipped due to a failing init %% conf case. It could also be a nested conf case that gets skipped %% because of a failed or skipped top level conf. %% @@ -2151,25 +2217,25 @@ maybe_get_privdir() -> %% messages to the main process instead of writing the data to file %% (only true for printouts to common log files). %% -%% If a conf group nested under a parallel group in the test +%% If a conf group nested under a parallel group in the test %% specification should be started, the 'test_server_common_io_handler' %% value gets set also on the main process. This causes all printouts -%% to common files - both from parallel test cases and from cases +%% to common files - both from parallel test cases and from cases %% executed by the main process - to all end up as messages in the -%% inbox of the main process. +%% inbox of the main process. %% %% During execution of a parallel group (or of a group nested under a -%% parallel group), *any* new test case being started gets registered +%% parallel group), *any* new test case being started gets registered %% in a list saved in the dictionary with 'test_server_queued_io' as key. %% When the top level parallel group is finished (only then can we be %% sure all parallel test cases have finished and "reported in"), the -%% list of test cases is traversed in order and printout messages from -%% each process - including the main process - are handled in turn. See +%% list of test cases is traversed in order and printout messages from +%% each process - including the main process - are handled in turn. See %% handle_test_case_io_and_status/0 for details. %% %% To be able to handle nested conf groups with different properties, %% the Mode argument specifies a list of {Ref,Properties} tuples. -%% The head of the Mode list at any given time identifies the group +%% The head of the Mode list at any given time identifies the group %% currently being processed. The tail of the list identifies groups %% on higher level. %% @@ -2179,13 +2245,13 @@ maybe_get_privdir() -> %% %% A group nested under a parallel group will start executing in %% parallel with previous (parallel) test cases (no matter what -%% properties the nested group has). Test cases are however never +%% properties the nested group has). Test cases are however never %% executed in parallel with the start or end conf case of the same %% group! Because of this, the test_server_ctrl loop waits at %% the end conf of a group for all parallel cases to finish %% before the end conf case actually executes. This has the effect %% that it's only after a nested group has finished that any -%% remaining parallel cases in the previous group get spawned (*). +%% remaining parallel cases in the previous group get spawned (*). %% Example (all parallel cases): %% %% group1_init |----> @@ -2201,15 +2267,16 @@ maybe_get_privdir() -> %% run_test_cases_loop([{auto_skip_case,{Type,Ref,Case,Comment},SkipMode}|Cases], - Config, MultiplyTimetrap, Mode, Status) when Type==conf; - Type==make -> - + Config, TimetrapData, Mode, Status) when Type==conf; + Type==make -> file:set_cwd(filename:dirname(get(test_server_dir))), CurrIOHandler = get(test_server_common_io_handler), + ParentMode = tl(Mode), + %% check and update the mode for test case execution and io msg handling case {curr_ref(Mode),check_props(parallel, Mode)} of {Ref,Ref} -> - case check_props(parallel, tl(Mode)) of + case check_props(parallel, ParentMode) of false -> %% this is a skipped end conf for a top level parallel group, %% buffered io can be flushed @@ -2217,24 +2284,24 @@ run_test_cases_loop([{auto_skip_case,{Type,Ref,Case,Comment},SkipMode}|Cases], set_io_buffering(undefined), {Mod,Func} = skip_case(auto, Ref, 0, Case, Comment, false, SkipMode), test_server_sup:framework_call(report, [tc_auto_skip,{?pl2a(Mod),Func,Comment}]), - run_test_cases_loop(Cases, Config, MultiplyTimetrap, tl(Mode), + run_test_cases_loop(Cases, Config, TimetrapData, ParentMode, delete_status(Ref, Status)); _ -> - %% this is a skipped end conf for a parallel group nested under a + %% this is a skipped end conf for a parallel group nested under a %% parallel group (io buffering is active) wait_for_cases(Ref), {Mod,Func} = skip_case(auto, Ref, 0, Case, Comment, true, SkipMode), test_server_sup:framework_call(report, [tc_auto_skip,{?pl2a(Mod),Func,Comment}]), case CurrIOHandler of - {Ref,_} -> + {Ref,_} -> %% current_io_handler was set by start conf of this - %% group, so we can unset it now (no more io from main + %% group, so we can unset it now (no more io from main %% process needs to be buffered) set_io_buffering(undefined); - _ -> + _ -> ok end, - run_test_cases_loop(Cases, Config, MultiplyTimetrap, tl(Mode), + run_test_cases_loop(Cases, Config, TimetrapData, ParentMode, delete_status(Ref, Status)) end; {Ref,false} -> @@ -2242,7 +2309,31 @@ run_test_cases_loop([{auto_skip_case,{Type,Ref,Case,Comment},SkipMode}|Cases], %% nested under a parallel group {Mod,Func} = skip_case(auto, Ref, 0, Case, Comment, false, SkipMode), test_server_sup:framework_call(report, [tc_auto_skip,{?pl2a(Mod),Func,Comment}]), - run_test_cases_loop(Cases, Config, MultiplyTimetrap, tl(Mode), + + %% Check if this group is auto skipped because of error in the init conf. + %% If so, check if the parent group is a sequence, and if it is, skip + %% all proceeding tests in that group. + GrName = get_name(Mode), + Cases1 = + case get_tc_results(Status) of + {_,_,Fails} when length(Fails) > 0 -> + case lists:member({group_result,GrName}, Fails) of + true -> + case check_prop(sequence, ParentMode) of + false -> + Cases; + ParentRef -> + Reason = {group_result,GrName,failed}, + skip_cases_upto(ParentRef, Cases, + Reason, tc, Mode) + end; + false -> + Cases + end; + _ -> + Cases + end, + run_test_cases_loop(Cases1, Config, TimetrapData, ParentMode, delete_status(Ref, Status)); {Ref,_} -> %% this is a skipped end conf for a non-parallel group nested under @@ -2250,22 +2341,22 @@ run_test_cases_loop([{auto_skip_case,{Type,Ref,Case,Comment},SkipMode}|Cases], {Mod,Func} = skip_case(auto, Ref, 0, Case, Comment, true, SkipMode), test_server_sup:framework_call(report, [tc_auto_skip,{?pl2a(Mod),Func,Comment}]), case CurrIOHandler of - {Ref,_} -> + {Ref,_} -> %% current_io_handler was set by start conf of this - %% group, so we can unset it now (no more io from main + %% group, so we can unset it now (no more io from main %% process needs to be buffered) set_io_buffering(undefined); - _ -> + _ -> ok end, - run_test_cases_loop(Cases, Config, MultiplyTimetrap, tl(Mode), + run_test_cases_loop(Cases, Config, TimetrapData, tl(Mode), delete_status(Ref, Status)); {_,false} -> %% this is a skipped start conf for a group which is not nested %% under a parallel group {Mod,Func} = skip_case(auto, Ref, 0, Case, Comment, false, SkipMode), test_server_sup:framework_call(report, [tc_auto_skip,{?pl2a(Mod),Func,Comment}]), - run_test_cases_loop(Cases, Config, MultiplyTimetrap, [conf(Ref,[])|Mode], Status); + run_test_cases_loop(Cases, Config, TimetrapData, [conf(Ref,[])|Mode], Status); {_,Ref0} when is_reference(Ref0) -> %% this is a skipped start conf for a group nested under a parallel group %% and if this is the first nested group, io buffering must be activated @@ -2276,19 +2367,19 @@ run_test_cases_loop([{auto_skip_case,{Type,Ref,Case,Comment},SkipMode}|Cases], end, {Mod,Func} = skip_case(auto, Ref, 0, Case, Comment, true, SkipMode), test_server_sup:framework_call(report, [tc_auto_skip,{?pl2a(Mod),Func,Comment}]), - run_test_cases_loop(Cases, Config, MultiplyTimetrap, [conf(Ref,[])|Mode], Status) - end; + run_test_cases_loop(Cases, Config, TimetrapData, [conf(Ref,[])|Mode], Status) + end; run_test_cases_loop([{auto_skip_case,{Case,Comment},SkipMode}|Cases], - Config, MultiplyTimetrap, Mode, Status) -> + Config, TimetrapData, Mode, Status) -> {Mod,Func} = skip_case(auto, undefined, get(test_server_case_num)+1, Case, Comment, (undefined /= get(test_server_common_io_handler)), SkipMode), test_server_sup:framework_call(report, [tc_auto_skip,{?pl2a(Mod),Func,Comment}]), - run_test_cases_loop(Cases, Config, MultiplyTimetrap, Mode, + run_test_cases_loop(Cases, Config, TimetrapData, Mode, update_status(skipped, Mod, Func, Status)); run_test_cases_loop([{skip_case,{conf,Ref,Case,Comment}}|Cases0], - Config, MultiplyTimetrap, Mode, Status) -> + Config, TimetrapData, Mode, Status) -> {Mod,Func} = skip_case(user, Ref, 0, Case, Comment, (undefined /= get(test_server_common_io_handler))), {Cases,Config1} = @@ -2301,24 +2392,23 @@ run_test_cases_loop([{skip_case,{conf,Ref,Case,Comment}}|Cases0], {skip_cases_upto(Ref, Cases0, Comment, conf, Mode),Config} end, test_server_sup:framework_call(report, [tc_user_skip,{?pl2a(Mod),Func,Comment}]), - run_test_cases_loop(Cases, Config1, MultiplyTimetrap, Mode, + run_test_cases_loop(Cases, Config1, TimetrapData, Mode, update_status(skipped, Mod, Func, Status)); run_test_cases_loop([{skip_case,{Case,Comment}}|Cases], - Config, MultiplyTimetrap, Mode, Status) -> + Config, TimetrapData, Mode, Status) -> {Mod,Func} = skip_case(user, undefined, get(test_server_case_num)+1, Case, Comment, (undefined /= get(test_server_common_io_handler))), test_server_sup:framework_call(report, [tc_user_skip,{?pl2a(Mod),Func,Comment}]), - run_test_cases_loop(Cases, Config, MultiplyTimetrap, Mode, + run_test_cases_loop(Cases, Config, TimetrapData, Mode, update_status(skipped, Mod, Func, Status)); %% a start *or* end conf case, wrapping test cases or other conf cases -run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0, - Config, MultiplyTimetrap, Mode0, Status) -> - +run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0, + Config, TimetrapData, Mode0, Status) -> CurrIOHandler = get(test_server_common_io_handler), %% check and update the mode for test case execution and io msg handling - {StartConf,Mode,IOHandler,ConfTime,Status1} = + {StartConf,Mode,IOHandler,ConfTime,Status1} = case {curr_ref(Mode0),check_props(parallel, Mode0)} of {Ref,Ref} -> case check_props(parallel, tl(Mode0)) of @@ -2334,19 +2424,19 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0, {false,tl(Mode0),undefined,Elapsed, update_status(Ref, OkSkipFail, Status)}; _ -> - %% this is an end conf for a parallel group nested under a + %% this is an end conf for a parallel group nested under a %% parallel group (io buffering is active) OkSkipFail = wait_for_cases(Ref), queue_test_case_io(Ref, self(), 0, Mod, Func), Elapsed = elapsed_time(conf_start(Ref, Mode0),?now)/1000000, case CurrIOHandler of - {Ref,_} -> + {Ref,_} -> %% current_io_handler was set by start conf of this %% group, so we can unset it after this case (no %% more io from main process needs to be buffered) {false,tl(Mode0),undefined,Elapsed, update_status(Ref, OkSkipFail, Status)}; - _ -> + _ -> {false,tl(Mode0),CurrIOHandler,Elapsed, update_status(Ref, OkSkipFail, Status)} end @@ -2362,16 +2452,16 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0, queue_test_case_io(Ref, self(), 0, Mod, Func), Elapsed = elapsed_time(conf_start(Ref, Mode0),?now)/1000000, case CurrIOHandler of - {Ref,_} -> + {Ref,_} -> %% current_io_handler was set by start conf of this %% group, so we can unset it after this case (no %% more io from main process needs to be buffered) {false,tl(Mode0),undefined,Elapsed,Status}; - _ -> + _ -> {false,tl(Mode0),CurrIOHandler,Elapsed,Status} end; {_,false} -> - %% this is a start conf for a group which is not nested under a + %% this is a start conf for a group which is not nested under a %% parallel group, check if this case starts a new parallel group case lists:member(parallel, Props) of true -> @@ -2424,9 +2514,9 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0, end; NumStr -> %% Ex: "123 456 789" or "123,456,789" -> {123,456,789} - list_to_tuple([list_to_integer(NS) || + list_to_tuple([list_to_integer(NS) || NS <- string:tokens(NumStr, [$ ,$:,$,])]) - end, + end, {shuffle_cases(Ref, Cs0, UseSeed),{shuffle,UseSeed}} end; not StartConf -> @@ -2440,17 +2530,19 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0, if StartConf -> case get_repeat(Props) of undefined -> - %% we *must* have a status entry for every conf since we + %% we *must* have a status entry for every conf since we %% will continously update status with test case results %% without knowing the Ref (but update hd(Status)) {false,new_status(Ref, Status1),Cases1,?void_fun}; - _ -> + {_RepType,N} when N =< 1 -> + {false,new_status(Ref, Status1),Cases1,?void_fun}; + _ -> {Copied,_} = copy_cases(Ref, make_ref(), Cs1), {true,new_status(Ref, Copied, Status1),Cases1,?void_fun} end; not StartConf -> RepVal = get_repeat(get_props(Mode0)), - ReportStop = + ReportStop = fun() -> print(minor, "~n*** Stopping repeat operation ~w", [RepVal]), print(1, "Stopping repeat operation ~w", [RepVal]) @@ -2461,21 +2553,23 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0, case RepVal of undefined -> {false,EndStatus,Cases1,?void_fun}; + {_RepType,N} when N =< 1 -> + {false,EndStatus,Cases1,?void_fun}; {repeat,_} -> {true,EndStatus,CopiedCases++Cases1,?void_fun}; {repeat_until_all_ok,_} -> {RestCs,Fun} = case get_tc_results(Status1) of - {_,_,[]} -> + {_,_,[]} -> {Cases1,ReportStop}; - _ -> + _ -> {CopiedCases++Cases1,?void_fun} end, {true,EndStatus,RestCs,Fun}; {repeat_until_any_ok,_} -> {RestCs,Fun} = case get_tc_results(Status1) of - {Ok,_,_} when length(Ok) > 0 -> + {Ok,_,_Fails} when length(Ok) > 0 -> {Cases1,ReportStop}; - _ -> + _ -> {CopiedCases++Cases1,?void_fun} end, {true,EndStatus,RestCs,Fun}; @@ -2483,15 +2577,15 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0, {RestCs,Fun} = case get_tc_results(Status1) of {_,_,Fails} when length(Fails) > 0 -> {Cases1,ReportStop}; - _ -> + _ -> {CopiedCases++Cases1,?void_fun} end, {true,EndStatus,RestCs,Fun}; {repeat_until_all_fail,_} -> {RestCs,Fun} = case get_tc_results(Status1) of - {[],_,_} -> + {[],_,_} -> {Cases1,ReportStop}; - _ -> + _ -> {CopiedCases++Cases1,?void_fun} end, {true,EndStatus,RestCs,Fun} @@ -2517,13 +2611,13 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0, [{tc_group_properties,get_props(Mode0)}, {tc_group_result,[{ok,TcOk},{skipped,TcSkip},{failed,TcFail}]}] end, - ActualCfg = + ActualCfg = update_config(hd(Config), [{priv_dir,get(test_server_priv_dir)}, {data_dir,get_data_dir(Mod)}] ++ CfgProps), CurrMode = curr_mode(Ref, Mode0, Mode), - ConfCaseResult = run_test_case(Ref, 0, Mod, Func, [ActualCfg], skip_init, target, - MultiplyTimetrap, CurrMode), + ConfCaseResult = run_test_case(Ref, 0, Mod, Func, [ActualCfg], skip_init, target, + TimetrapData, CurrMode), case ConfCaseResult of {_,NewCfg,_} when Func == init_per_suite, is_list(NewCfg) -> @@ -2533,8 +2627,8 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0, [] -> set_io_buffering(IOHandler), stop_minor_log_file(), - run_test_cases_loop(Cases, [NewCfg|Config], - MultiplyTimetrap, Mode, Status2); + run_test_cases_loop(Cases, [NewCfg|Config], + TimetrapData, Mode, Status2); Bad -> print(minor, "~n*** ~p returned bad elements in Config: ~p.~n", [Func,Bad]), @@ -2542,53 +2636,55 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0, Cases2 = skip_cases_upto(Ref, Cases, Reason, conf, CurrMode), set_io_buffering(IOHandler), stop_minor_log_file(), - run_test_cases_loop(Cases2, Config, MultiplyTimetrap, Mode, + run_test_cases_loop(Cases2, Config, TimetrapData, Mode, delete_status(Ref, Status2)) - end; + end; {_,NewCfg,_} when StartConf, is_list(NewCfg) -> print_conf_time(ConfTime), set_io_buffering(IOHandler), stop_minor_log_file(), - run_test_cases_loop(Cases, [NewCfg|Config], MultiplyTimetrap, Mode, Status2); + run_test_cases_loop(Cases, [NewCfg|Config], TimetrapData, Mode, Status2); {_,{framework_error,{FwMod,FwFunc},Reason},_} -> print(minor, "~n*** ~p failed in ~p. Reason: ~p~n", [FwMod,FwFunc,Reason]), print(1, "~p failed in ~p. Reason: ~p~n", [FwMod,FwFunc,Reason]), exit(framework_error); - {_,Fail,_} when element(1,Fail) == 'EXIT'; + {_,Fail,_} when element(1,Fail) == 'EXIT'; element(1,Fail) == timetrap_timeout; element(1,Fail) == failed -> - {Cases2,Config1} = + {Cases2,Config1,Status3} = if StartConf -> ReportAbortRepeat(failed), print(minor, "~n*** ~p failed.~n" " Skipping all cases.", [Func]), Reason = {failed,{Mod,Func,Fail}}, - {skip_cases_upto(Ref, Cases, Reason, conf, CurrMode),Config}; + {skip_cases_upto(Ref, Cases, Reason, conf, CurrMode), + Config, + update_status(failed, group_result, get_name(Mode), + delete_status(Ref, Status2))}; not StartConf -> ReportRepeatStop(), print_conf_time(ConfTime), - {Cases,tl(Config)} + {Cases,tl(Config),delete_status(Ref, Status2)} end, set_io_buffering(IOHandler), stop_minor_log_file(), - run_test_cases_loop(Cases2, Config1, MultiplyTimetrap, Mode, - delete_status(Ref, Status2)); + run_test_cases_loop(Cases2, Config1, TimetrapData, Mode, Status3); {died,Why,_} when Func == init_per_suite -> print(minor, "~n*** Unexpected exit during init_per_suite.~n", []), Reason = {failed,{Mod,init_per_suite,Why}}, Cases2 = skip_cases_upto(Ref, Cases, Reason, conf, CurrMode), set_io_buffering(IOHandler), stop_minor_log_file(), - run_test_cases_loop(Cases2, Config, MultiplyTimetrap, Mode, - delete_status(Ref, Status2)); + run_test_cases_loop(Cases2, Config, TimetrapData, Mode, + delete_status(Ref, Status2)); {_,{Skip,Reason},_} when StartConf and ((Skip==skip) or (Skip==skipped)) -> ReportAbortRepeat(skipped), print(minor, "~n*** ~p skipped.~n" " Skipping all cases.", [Func]), set_io_buffering(IOHandler), stop_minor_log_file(), - run_test_cases_loop(skip_cases_upto(Ref, Cases, Reason, conf, CurrMode), - Config, MultiplyTimetrap, Mode, + run_test_cases_loop(skip_cases_upto(Ref, Cases, Reason, conf, CurrMode), + Config, TimetrapData, Mode, delete_status(Ref, Status2)); {_,{skip_and_save,Reason,_SavedConfig},_} when StartConf -> ReportAbortRepeat(skipped), @@ -2596,8 +2692,8 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0, " Skipping all cases.", [Func]), set_io_buffering(IOHandler), stop_minor_log_file(), - run_test_cases_loop(skip_cases_upto(Ref, Cases, Reason, conf, CurrMode), - Config, MultiplyTimetrap, Mode, + run_test_cases_loop(skip_cases_upto(Ref, Cases, Reason, conf, CurrMode), + Config, TimetrapData, Mode, delete_status(Ref, Status2)); {_,_Other,_} when Func == init_per_suite -> print(minor, "~n*** init_per_suite failed to return a Config list.~n", []), @@ -2605,61 +2701,77 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0, Cases2 = skip_cases_upto(Ref, Cases, Reason, conf, CurrMode), set_io_buffering(IOHandler), stop_minor_log_file(), - run_test_cases_loop(Cases2, Config, MultiplyTimetrap, Mode, + run_test_cases_loop(Cases2, Config, TimetrapData, Mode, delete_status(Ref, Status2)); {_,_Other,_} when StartConf -> print_conf_time(ConfTime), set_io_buffering(IOHandler), ReportRepeatStop(), stop_minor_log_file(), - run_test_cases_loop(Cases, [hd(Config)|Config], MultiplyTimetrap, + run_test_cases_loop(Cases, [hd(Config)|Config], TimetrapData, Mode, Status2); - + {_,_EndConfRetVal,Opts} -> - %% check if return_group_result is set (ok, skipped or failed) and - %% if so return the value to the group "above" so that result may be - %% used for evaluating repeat_until_* - Status3 = + %% Check if return_group_result is set (ok, skipped or failed) and + %% if so: + %% 1) *If* the parent group is a sequence, skip all proceeding tests + %% in that group. + %% 2) Return the value to the group "above" so that result may be + %% used for evaluating a 'repeat_until_*' property. + GrName = get_name(Mode0, Func), + {Cases2,Status3} = case lists:keysearch(return_group_result, 1, Opts) of + {value,{_,failed}} -> + case {curr_ref(Mode),check_prop(sequence, Mode)} of + {ParentRef,ParentRef} -> + Reason = {group_result,GrName,failed}, + {skip_cases_upto(ParentRef, Cases, Reason, tc, Mode), + update_status(failed, group_result, GrName, + delete_status(Ref, Status2))}; + _ -> + {Cases,update_status(failed, group_result, GrName, + delete_status(Ref, Status2))} + end; {value,{_,GroupResult}} -> - update_status(GroupResult, group_result, Func, - delete_status(Ref, Status2)); + {Cases,update_status(GroupResult, group_result, GrName, + delete_status(Ref, Status2))}; false -> - delete_status(Ref, Status2) + {Cases,update_status(ok, group_result, GrName, + delete_status(Ref, Status2))} end, print_conf_time(ConfTime), ReportRepeatStop(), set_io_buffering(IOHandler), stop_minor_log_file(), - run_test_cases_loop(Cases, tl(Config), MultiplyTimetrap, Mode, Status3) + run_test_cases_loop(Cases2, tl(Config), TimetrapData, Mode, Status3) end; -run_test_cases_loop([{make,Ref,{Mod,Func,Args}}|Cases0], Config, MultiplyTimetrap, Mode, Status) -> - case run_test_case(Ref, 0, Mod, Func, Args, skip_init, host, MultiplyTimetrap) of +run_test_cases_loop([{make,Ref,{Mod,Func,Args}}|Cases0], Config, TimetrapData, Mode, Status) -> + case run_test_case(Ref, 0, Mod, Func, Args, skip_init, host, TimetrapData) of {_,Why={'EXIT',_},_} -> print(minor, "~n*** ~p failed.~n" " Skipping all cases.", [Func]), Reason = {failed,{Mod,Func,Why}}, Cases = skip_cases_upto(Ref, Cases0, Reason, conf, Mode), stop_minor_log_file(), - run_test_cases_loop(Cases, Config, MultiplyTimetrap, Mode, Status); + run_test_cases_loop(Cases, Config, TimetrapData, Mode, Status); {_,_Whatever,_} -> stop_minor_log_file(), - run_test_cases_loop(Cases0, Config, MultiplyTimetrap, Mode, Status) + run_test_cases_loop(Cases0, Config, TimetrapData, Mode, Status) end; -run_test_cases_loop([{conf,_Ref,_Props,_X}=Conf|_Cases0], - Config, _MultiplyTimetrap, _Mode, _Status) -> +run_test_cases_loop([{conf,_Ref,_Props,_X}=Conf|_Cases0], + Config, _TimetrapData, _Mode, _Status) -> erlang:error(badarg, [Conf,Config]); -run_test_cases_loop([{Mod,Case}|Cases], Config, MultiplyTimetrap, Mode, Status) -> - ActualCfg = +run_test_cases_loop([{Mod,Case}|Cases], Config, TimetrapData, Mode, Status) -> + ActualCfg = update_config(hd(Config), [{priv_dir,get(test_server_priv_dir)}, {data_dir,get_data_dir(Mod)}]), run_test_cases_loop([{Mod,Case,[ActualCfg]}|Cases], Config, - MultiplyTimetrap, Mode, Status); + TimetrapData, Mode, Status); -run_test_cases_loop([{Mod,Func,Args}|Cases], Config, MultiplyTimetrap, Mode, Status) -> +run_test_cases_loop([{Mod,Func,Args}|Cases], Config, TimetrapData, Mode, Status) -> Num = put(test_server_case_num, get(test_server_case_num)+1), %% check the current execution mode and save info about the case if %% detected that printouts to common log files is handled later @@ -2669,15 +2781,15 @@ run_test_cases_loop([{Mod,Func,Args}|Cases], Config, MultiplyTimetrap, Mode, Sta undefined -> %% io printouts are written to straight to file ok; - _ -> + _ -> %% io messages are buffered, put test case in queue queue_test_case_io(undefined, self(), Num+1, Mod, Func) end; _ -> ok end, - case run_test_case(undefined, Num+1, Mod, Func, Args, - run_init, target, MultiplyTimetrap, Mode) of + case run_test_case(undefined, Num+1, Mod, Func, Args, + run_init, target, TimetrapData, Mode) of %% callback to framework module failed, exit immediately {_,{framework_error,{FwMod,FwFunc},Reason},_} -> print(minor, "~n*** ~p failed in ~p. Reason: ~p~n", [FwMod,FwFunc,Reason]), @@ -2688,50 +2800,50 @@ run_test_cases_loop([{Mod,Func,Args}|Cases], Config, MultiplyTimetrap, Mode, Sta {Time,RetVal,_} -> {Failed,Status1} = case Time of - died -> + died -> {true,update_status(failed, Mod, Func, Status)}; _ when is_tuple(RetVal) -> case element(1, RetVal) of - R when R=='EXIT'; R==failed -> + R when R=='EXIT'; R==failed -> {true,update_status(failed, Mod, Func, Status)}; - R when R==skip; R==skipped -> + R when R==skip; R==skipped -> {false,update_status(skipped, Mod, Func, Status)}; - _ -> + _ -> {false,update_status(ok, Mod, Func, Status)} end; - _ -> + _ -> {false,update_status(ok, Mod, Func, Status)} - end, + end, case check_prop(sequence, Mode) of false -> stop_minor_log_file(), - run_test_cases_loop(Cases, Config, MultiplyTimetrap, Mode, Status1); - Ref -> - %% the case is in a sequence; we must check the result and + run_test_cases_loop(Cases, Config, TimetrapData, Mode, Status1); + Ref -> + %% the case is in a sequence; we must check the result and %% determine if the following cases should run or be skipped if not Failed -> % proceed with next case stop_minor_log_file(), - run_test_cases_loop(Cases, Config, MultiplyTimetrap, Mode, Status1); + run_test_cases_loop(Cases, Config, TimetrapData, Mode, Status1); true -> % skip rest of cases in sequence print(minor, "~n*** ~p failed.~n" " Skipping all other cases in sequence.", [Func]), Reason = {failed,{Mod,Func}}, Cases2 = skip_cases_upto(Ref, Cases, Reason, tc, Mode), stop_minor_log_file(), - run_test_cases_loop(Cases2, Config, MultiplyTimetrap, Mode, Status1) + run_test_cases_loop(Cases2, Config, TimetrapData, Mode, Status1) end end; %% the test case is being executed in parallel with the main process (and %% other test cases) and Pid is the dedicated process executing the case Pid -> - %% io from Pid will be buffered in the main process inbox and handled + %% io from Pid will be buffered in the main process inbox and handled %% later, so we have to save info about the case queue_test_case_io(undefined, Pid, Num+1, Mod, Func), - run_test_cases_loop(Cases, Config, MultiplyTimetrap, Mode, Status) + run_test_cases_loop(Cases, Config, TimetrapData, Mode, Status) end; %% TestSpec processing finished -run_test_cases_loop([], _Config, _MultiplyTimetrap, _, _) -> +run_test_cases_loop([], _Config, _TimetrapData, _, _) -> ok. %%-------------------------------------------------------------------- @@ -2765,7 +2877,10 @@ get_copied_cases([{_,{_,Cases}} | _Status]) -> Cases. get_tc_results([{_,{OkSkipFail,_}} | _Status]) -> - OkSkipFail. + OkSkipFail; +get_tc_results([]) -> % in case init_per_suite crashed + {[],[],[]}. + conf(Ref, Props) -> {Ref,Props,?now}. @@ -2798,12 +2913,18 @@ check_props(Attrib, Mode) -> case [R || {R,Ps,_} <- Mode, lists:member(Attrib, Ps)] of [] -> false; [Ref|_] -> Ref - end. + end. + +get_name(Mode, Def) -> + case get_name(Mode) of + undefined -> Def; + Name -> Name + end. get_name([{_Ref,Props,_}|_]) -> proplists:get_value(name, Props); get_name([]) -> - undefined. + undefined. conf_start(Ref, Mode) -> case lists:keysearch(Ref, 1, Mode) of @@ -2826,10 +2947,10 @@ print_conf_time(0) -> print_conf_time(ConfTime) -> print(major, "=group_time ~.3fs", [ConfTime]), print(minor, "~n=== Total execution time of group: ~.3fs~n", [ConfTime]). - -print_props(_, []) -> + +print_props(_, []) -> ok; -print_props(true, Props) -> +print_props(true, Props) -> print(major, "=group_props ~p", [Props]), print(minor, "Group properties: ~p~n", [Props]); print_props(_, _) -> @@ -2853,12 +2974,12 @@ update_repeat(Props) -> Props1 = if N == forever -> [{RepType,N}|lists:keydelete(RepType, 1, Props)]; - N < 2 -> + N < 3 -> lists:keydelete(RepType, 1, Props); - N >= 2 -> + N >= 3 -> [{RepType,N-1}|lists:keydelete(RepType, 1, Props)] end, - %% if shuffle is used in combination with repeat, a new + %% if shuffle is used in combination with repeat, a new %% seed shouldn't be set every new turn case get_shuffle(Props1) of undefined -> @@ -2874,13 +2995,13 @@ get_shuffle(Props) -> delete_shuffle(Props) -> delete_prop([shuffle], Props). -%% Return {Item,Value} if found, else if Item alone +%% Return {Item,Value} if found, else if Item alone %% is found, return {Item,Default} get_prop([Item|Items], Default, Props) -> case lists:keysearch(Item, 1, Props) of - {value,R} -> + {value,R} -> R; - false -> + false -> case lists:member(Item, Props) of true -> {Item,Default}; @@ -2940,8 +3061,8 @@ random_order(1, {_Pos,Seed}, [{_Ix,CaseOrGroup}], Shuffled) -> put(test_server_curr_random_seed, Seed), Shuffled++CaseOrGroup; random_order(N, {Pos,NewSeed}, IxCases, Shuffled) -> - {First,[{_Ix,CaseOrGroup}|Rest]} = lists:split(Pos-1, IxCases), - random_order(N-1, random:uniform_s(N-1, NewSeed), + {First,[{_Ix,CaseOrGroup}|Rest]} = lists:split(Pos-1, IxCases), + random_order(N-1, random:uniform_s(N-1, NewSeed), First++Rest, Shuffled++CaseOrGroup). @@ -2949,7 +3070,7 @@ random_order(N, {Pos,NewSeed}, IxCases, Shuffled) -> %% skip_case(Type, Ref, CaseNum, Case, Comment, SendSync) -> {Mod,Func} %% %% Prints info about a skipped case in the major and html log files. -%% SendSync determines if start and finished messages must be sent so +%% SendSync determines if start and finished messages must be sent so %% that the printouts can be buffered and handled in order with io from %% parallel processes. @@ -2969,13 +3090,13 @@ skip_case(Type, Ref, CaseNum, Case, Comment, SendSync, Mode) -> not SendSync -> skip_case1(Type, CaseNum, Mod, Func, Comment, Mode) end, - MF. + MF. skip_case1(Type, CaseNum, Mod, Func, Comment, Mode) -> {{Col0,Col1},_} = get_font_style((CaseNum > 0), Mode), ResultCol = if Type == auto -> "#ffcc99"; Type == user -> "#ff9933" - end, + end, Comment1 = reason_to_string(Comment), @@ -3084,7 +3205,7 @@ modify_cases_upto1(Ref, ModOp, [{skip_case,{_F,_Cmt}}=MF|T], Orig, Alt) -> %% next is a normal case (possibly in a sequence), mark as skipped, or copy, and proceed modify_cases_upto1(Ref, {skip,Reason,_,Mode}=Op, [{_M,_F}=MF|T], Orig, Alt) -> - modify_cases_upto1(Ref, Op, T, Orig, [{auto_skip_case,{MF,Reason},Mode}|Alt]); + modify_cases_upto1(Ref, Op, T, Orig, [{auto_skip_case,{MF,Reason},Mode}|Alt]); modify_cases_upto1(Ref, CopyOp, [{_M,_F}=MF|T], Orig, Alt) -> modify_cases_upto1(Ref, CopyOp, T, [MF|Orig], [MF|Alt]); @@ -3110,7 +3231,7 @@ set_io_buffering(IOHandler) -> %% queue_test_case_io(Pid, Num, Mod, Func) -> ok %% %% Save info about test case that gets its io buffered. This can -%% be a parallel test case or it can be a test case (conf or normal) +%% be a parallel test case or it can be a test case (conf or normal) %% that belongs to a group nested under a parallel group. The queue %% is processed after io buffering is disabled. See run_test_cases_loop/4 %% and handle_test_case_io_and_status/0 for more info. @@ -3124,10 +3245,10 @@ queue_test_case_io(Ref, Pid, Num, Mod, Func) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% wait_for_cases(Ref) -> {Ok,Skipped,Failed} %% -%% At the end of a nested parallel group, we have to wait for the test +%% At the end of a nested parallel group, we have to wait for the test %% cases to terminate before we can go on (since test cases never execute -%% in parallel with the end conf case of the group). When a top level -%% parallel group is finished, buffered io messages must be handled and +%% in parallel with the end conf case of the group). When a top level +%% parallel group is finished, buffered io messages must be handled and %% this is taken care of by handle_test_case_io_and_status/0. wait_for_cases(Ref) -> @@ -3135,15 +3256,15 @@ wait_for_cases(Ref) -> [] -> {[],[],[]}; Cases -> - [_Start|TCs] = + [_Start|TCs] = lists:dropwhile(fun({R,_,_,_,_}) when R == Ref -> false; (_) -> true end, Cases), wait_and_resend(Ref, TCs, [],[],[]) end. -wait_and_resend(Ref, [{OtherRef,_,0,_,_}|Ps], - Ok,Skip,Fail) when is_reference(OtherRef), +wait_and_resend(Ref, [{OtherRef,_,0,_,_}|Ps], + Ok,Skip,Fail) when is_reference(OtherRef), OtherRef /= Ref -> %% ignore cases that belong to nested group Ps1 = rm_cases_upto(OtherRef, Ps), @@ -3152,7 +3273,7 @@ wait_and_resend(Ref, [{OtherRef,_,0,_,_}|Ps], wait_and_resend(Ref, [{_,CurrPid,CaseNum,Mod,Func}|Ps] = Cases, Ok,Skip,Fail) -> receive {finished,_Ref,CurrPid,CaseNum,Mod,Func,Result,_RetVal} = Msg -> - %% resend message to main process so that it can be used + %% resend message to main process so that it can be used %% to handle buffered io messages later self() ! Msg, MF = {Mod,Func}, @@ -3163,7 +3284,7 @@ wait_and_resend(Ref, [{_,CurrPid,CaseNum,Mod,Func}|Ps] = Cases, Ok,Skip,Fail) -> failed -> {Ok,Skip,[MF|Fail]} end, wait_and_resend(Ref, Ps, Ok1,Skip1,Fail1); - {'EXIT',CurrPid,Reason} when Reason /= normal -> + {'EXIT',CurrPid,Reason} when Reason /= normal -> %% unexpected termination of test case process {value,{_,_,CaseNum,Mod,Func}} = lists:keysearch(CurrPid, 2, Cases), print(1, "Error! Process for test case #~p (~p:~p) died! Reason: ~p", @@ -3186,17 +3307,17 @@ rm_cases_upto(Ref, [_|Ps]) -> %% execution. The common log files (major, html etc) must however be %% written to sequentially. The test case processes send print requests %% to the main (starting) process (the same process executing -%% run_test_cases_loop/4), which handles these requests in the same +%% run_test_cases_loop/4), which handles these requests in the same %% order that the test case processes were started. %% %% An io session is always started with a {started,Ref,Pid,Num,Mod,Func} %% message and terminated with {finished,Ref,Pid,Num,Mod,Func,Result,RetVal}. %% The result shipped with the finished message from a parallel process -%% is used to update status data of the current test run. An 'EXIT' -%% message from each parallel test case process (after finishing and +%% is used to update status data of the current test run. An 'EXIT' +%% message from each parallel test case process (after finishing and %% terminating) is also received and handled here. %% -%% During execution of a parallel group, any cases (conf or normal) +%% During execution of a parallel group, any cases (conf or normal) %% belonging to a nested group will also get its io printouts buffered. %% This is necessary to get the major and html log files written in %% correct sequence. This function handles also the print messages @@ -3207,7 +3328,7 @@ rm_cases_upto(Ref, [_|Ps]) -> %% See the header comment for run_test_cases_loop/4 for more %% info about IO handling. %% -%% Note: It is important that the type of messages handled here +%% Note: It is important that the type of messages handled here %% do not get consumated by test_server:run_test_case_msgloop/5 %% during the test case execution (e.g. in the catch clause of %% the receive)! @@ -3231,7 +3352,7 @@ handle_test_case_io_and_status() -> ok end, Cases), Result - end. + end. %% Handle cases (without Ref) that belong to the top parallel group (i.e. when Refs = []) handle_io_and_exit_loop([], [{undefined,CurrPid,CaseNum,Mod,Func}|Ps] = Cases, Ok,Skip,Fail) -> @@ -3249,7 +3370,7 @@ handle_io_and_exit_loop([], [{undefined,CurrPid,CaseNum,Mod,Func}|Ps] = Cases, O 1000 -> exit({testcase_failed_to_start,Mod,Func}) end; - + %% Handle cases that belong to groups nested under top parallel group handle_io_and_exit_loop(Refs, [{Ref,CurrPid,CaseNum,Mod,Func}|Ps] = Cases, Ok,Skip,Fail) -> receive @@ -3269,7 +3390,7 @@ handle_io_and_exit_loop(Refs, [{Ref,CurrPid,CaseNum,Mod,Func}|Ps] = Cases, Ok,Sk 1000 -> exit({testcase_failed_to_start,Mod,Func}) end; - + handle_io_and_exit_loop(_, [], Ok,Skip,Fail) -> {lists:reverse(Ok),lists:reverse(Skip),lists:reverse(Fail)}. @@ -3286,7 +3407,7 @@ handle_io_and_exits(Main, CurrPid, CaseNum, Mod, Func, Cases) -> failed -> put(test_server_failed, get(test_server_failed)+1); skipped -> - SkipCounters = + SkipCounters = update_skip_counters(RetVal, get(test_server_skipped)), put(test_server_skipped, SkipCounters) end, @@ -3298,7 +3419,7 @@ handle_io_and_exits(Main, CurrPid, CaseNum, Mod, Func, Cases) -> handle_io_and_exits(Main, CurrPid, CaseNum, Mod, Func, Cases); %% unexpected termination of test case process - {'EXIT',TCPid,Reason} when Reason /= normal -> + {'EXIT',TCPid,Reason} when Reason /= normal -> {value,{_,_,Num,M,F}} = lists:keysearch(TCPid, 2, Cases), print(1, "Error! Process for test case #~p (~p:~p) died! Reason: ~p", [Num, M, F, Reason]), @@ -3307,65 +3428,65 @@ handle_io_and_exits(Main, CurrPid, CaseNum, Mod, Func, Cases) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% run_test_case(Ref, Num, Mod, Func, Args, RunInit, -%% Where, MultiplyTimetrap, Mode) -> RetVal +%% run_test_case(Ref, Num, Mod, Func, Args, RunInit, +%% Where, TimetrapData, Mode) -> RetVal %% %% Creates the minor log file and inserts some test case specific headers -%% and footers into the log files. If a remote target is used, the test +%% and footers into the log files. If a remote target is used, the test %% suite (binary) and the content of data_dir is sent. Then the test case -%% is executed and the result is printed to the log files (also info +%% is executed and the result is printed to the log files (also info %% about lingering processes & slave nodes in the system is presented). -%% +%% %% RunInit decides if the per test case init is to be run (true for all %% but conf cases). %% -%% Where specifies if the test case should run on target or on the host. +%% Where specifies if the test case should run on target or on the host. %% (Note that 'make' test cases always run on host). -%% +%% %% Mode specifies if the test case should be executed by a dedicated, %% parallel, process rather than sequentially by the main process. If %% the former, the new process is spawned and the dictionary of the main %% process is copied to the test case process. -%% -%% RetVal is the result of executing the test case. It contains info +%% +%% RetVal is the result of executing the test case. It contains info %% about the execution time and the return value of the test case function. -run_test_case(Ref, Num, Mod, Func, Args, RunInit, Where, MultiplyTimetrap) -> +run_test_case(Ref, Num, Mod, Func, Args, RunInit, Where, TimetrapData) -> file:set_cwd(filename:dirname(get(test_server_dir))), - run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where, - MultiplyTimetrap, [], [], self()). + run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where, + TimetrapData, [], [], self()). -run_test_case(Ref, Num, Mod, Func, Args, skip_init, Where, MultiplyTimetrap, Mode) -> +run_test_case(Ref, Num, Mod, Func, Args, skip_init, Where, TimetrapData, Mode) -> %% a conf case is always executed by the main process - run_test_case1(Ref, Num, Mod, Func, Args, skip_init, Where, - MultiplyTimetrap, [], Mode, self()); + run_test_case1(Ref, Num, Mod, Func, Args, skip_init, Where, + TimetrapData, [], Mode, self()); -run_test_case(Ref, Num, Mod, Func, Args, RunInit, Where, MultiplyTimetrap, Mode) -> +run_test_case(Ref, Num, Mod, Func, Args, RunInit, Where, TimetrapData, Mode) -> file:set_cwd(filename:dirname(get(test_server_dir))), case check_prop(parallel, Mode) of false -> %% this is a sequential test case - run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where, - MultiplyTimetrap, [], Mode, self()); + run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where, + TimetrapData, [], Mode, self()); _Ref -> %% this a parallel test case, spawn the new process Main = self(), - {dictionary,State} = process_info(self(), dictionary), + {dictionary,State} = process_info(self(), dictionary), spawn_link(fun() -> - run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where, - MultiplyTimetrap, State, Mode, Main) - end) + run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where, + TimetrapData, State, Mode, Main) + end) end. -run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where, - MultiplyTimetrap, State, Mode, Main) -> - %% if this runs on a parallel test case process, +run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where, + TimetrapData, State, Mode, Main) -> + %% if this runs on a parallel test case process, %% copy the dictionary from the main process do_if_parallel(Main, fun() -> process_flag(trap_exit, true) end, ok), CopyDict = fun() -> lists:foreach(fun({Key,Val}) -> put(Key, Val) end, State) end, do_if_parallel(Main, CopyDict, ok), do_if_parallel(Main, fun() -> put(test_server_common_io_handler, {tc,Main}) end, ok), - %% if io is being buffered, send start io session message + %% if io is being buffered, send start io session message %% (no matter if case runs on parallel or main process) case get(test_server_common_io_handler) of undefined -> ok; @@ -3373,7 +3494,7 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where, end, TSDir = get(test_server_dir), case Where of - target -> + target -> maybe_send_beam_and_datadir(Mod); host -> ok @@ -3396,8 +3517,8 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where, do_if_parallel(Main, ok, fun erlang:yield/0), %% run the test case {Result,DetectedFail,ProcsBefore,ProcsAfter} = - run_test_case_apply(Num, Mod, Func, Args, get_name(Mode), - RunInit, Where, MultiplyTimetrap), + run_test_case_apply(Num, Mod, Func, Args, get_name(Mode), + RunInit, Where, TimetrapData), {Time,RetVal,Loc,Opts,Comment} = case Result of Normal={_Time,_RetVal,_Loc,_Opts,_Comment} -> Normal; @@ -3409,7 +3530,7 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where, print(major, "=ended ~s", [lists:flatten(timestamp_get(""))]), do_if_parallel(Main, ok, fun() -> file:set_cwd(filename:dirname(TSDir)) end), - + %% call the appropriate progress function clause to print the results to log Status = case {Time,RetVal} of @@ -3423,16 +3544,16 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where, progress(skip, Num, Mod, Func, Loc, Reason, Time, Comment, Style); {_,{'EXIT',_Pid,{Skip,Reason}}} when Skip==skip; Skip==skipped -> - progress(skip, Num, Mod, Func, Loc, Reason, + progress(skip, Num, Mod, Func, Loc, Reason, Time, Comment, Style); {_,{'EXIT',_Pid,Reason}} -> - progress(failed, Num, Mod, Func, Loc, Reason, + progress(failed, Num, Mod, Func, Loc, Reason, Time, Comment, Style); {_,{'EXIT',Reason}} -> - progress(failed, Num, Mod, Func, Loc, Reason, + progress(failed, Num, Mod, Func, Loc, Reason, Time, Comment, Style); {_, {failed, Reason}} -> - progress(failed, Num, Mod, Func, Loc, Reason, + progress(failed, Num, Mod, Func, Loc, Reason, Time, Comment, Style); {_, {Skip, Reason}} when Skip==skip; Skip==skipped -> progress(skip, Num, Mod, Func, Loc, Reason, @@ -3442,7 +3563,7 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where, [] -> progress(ok, Num, Mod, Func, Loc, RetVal, Time, Comment, Style); - + Reason -> progress(failed, Num, Mod, Func, Loc, Reason, Time, Comment, Style) @@ -3465,18 +3586,18 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where, {US,AS} = get(test_server_skipped), put(test_server_skipped, {US,AS+1}) end, - %% only if test case execution is sequential do we care about the + %% only if test case execution is sequential do we care about the %% remaining processes and slave nodes count case self() of Main -> case test_server_sup:framework_call(warn, [processes], true) of true -> if ProcsBefore < ProcsAfter -> - print(minor, + print(minor, "WARNING: ~w more processes in system after test case", [ProcsAfter-ProcsBefore]); ProcsBefore > ProcsAfter -> - print(minor, + print(minor, "WARNING: ~w less processes in system after test case", [ProcsBefore-ProcsAfter]); true -> ok @@ -3487,13 +3608,13 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where, case test_server_sup:framework_call(warn, [nodes], true) of true -> case catch controller_call(kill_slavenodes) of - {'EXIT',_}=Exit -> + {'EXIT',_} = Exit -> print(minor, "WARNING: There might be slavenodes left in the" " system. I tried to kill them, but I failed: ~p\n", [Exit]); [] -> ok; - List -> + List -> print(minor, "WARNING: ~w slave nodes in system after test"++ "case. Tried to killed them.~n"++ " Names:~p", @@ -3505,8 +3626,8 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where, _ -> ok end, - %% if the test case was executed sequentially, this updates the execution - %% time count on the main process (adding execution time of parallel test + %% if the test case was executed sequentially, this updates the execution + %% time count on the main process (adding execution time of parallel test %% case groups is done in run_test_cases_loop/4) if is_number(Time) -> put(test_server_total_time, get(test_server_total_time)+Time); @@ -3515,7 +3636,7 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where, end, check_new_crash_dumps(Where), - %% if io is being buffered, send finished message + %% if io is being buffered, send finished message %% (no matter if case runs on parallel or main process) case get(test_server_common_io_handler) of undefined -> ok; @@ -3528,7 +3649,7 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where, %%-------------------------------------------------------------------- %% various help functions -%% Call If() if we're on parallel process, or +%% Call If() if we're on parallel process, or %% call Else() if we're on main process do_if_parallel(Pid, If, Else) -> case self() of @@ -3536,7 +3657,7 @@ do_if_parallel(Pid, If, Else) -> if is_function(Else) -> Else(); true -> Else end; - _ -> + _ -> if is_function(If) -> If(); true -> If end @@ -3549,13 +3670,13 @@ num2str(N) -> integer_to_list(N). %% and the content of datadir til target. maybe_send_beam_and_datadir(Mod) -> case get(test_server_ctrl_job_sock) of - undefined -> + undefined -> %% local target ok; JobSock -> %% remote target case get(test_server_downloaded_suites) of - undefined -> + undefined -> send_beam_and_datadir(Mod, JobSock), put(test_server_downloaded_suites, [Mod]); Suites -> @@ -3571,10 +3692,10 @@ maybe_send_beam_and_datadir(Mod) -> send_beam_and_datadir(Mod, JobSock) -> case code:which(Mod) of - non_existing -> + non_existing -> io:format("** WARNING: Suite ~w could not be found on host\n", [Mod]); - BeamFile -> + BeamFile -> send_beam(JobSock, Mod, BeamFile) end, DataDir = get_data_dir(Mod), @@ -3589,7 +3710,7 @@ send_beam_and_datadir(Mod, JobSock) -> ModsInDatadir = filelib:wildcard(Wc), SendBeamFun = fun(X) -> send_beam(JobSock, X) end, lists:foreach(SendBeamFun, ModsInDatadir), - %% No need to send C code or makefiles since + %% No need to send C code or makefiles since %% no compilation can be done on target anyway. %% Compiled C code must exist on target. %% Beam files are already sent as binaries. @@ -3597,7 +3718,7 @@ send_beam_and_datadir(Mod, JobSock) -> %% is to compile it. Filter = fun("Makefile") -> false; ("Makefile.src") -> false; - (Y) -> + (Y) -> case filename:extension(Y) of ".c" -> false; ObjExt -> false; @@ -3611,7 +3732,7 @@ send_beam_and_datadir(Mod, JobSock) -> Tarfile = "data_dir.tar.gz", {ok,Tar} = erl_tar:open(Tarfile, [write,compressed]), ShortDataDir = filename:basename(DataDir), - AddTarFun = + AddTarFun = fun(File) -> Long = filename:join(DataDir, File), Short = filename:join(ShortDataDir, File), @@ -3628,11 +3749,11 @@ send_beam_and_datadir(Mod, JobSock) -> send_beam(JobSock, BeamFile) -> Mod=filename:rootname(filename:basename(BeamFile), code:objfile_extension()), - send_beam(JobSock, list_to_atom(Mod), BeamFile). + send_beam(JobSock, list_to_atom(Mod), BeamFile). send_beam(JobSock, Mod, BeamFile) -> {ok,BeamBin} = file:read_file(BeamFile), request(JobSock, {{beam,Mod,BeamFile}, BeamBin}). - + check_new_crash_dumps(Where) -> case Where of target -> @@ -3649,25 +3770,25 @@ check_new_crash_dumps(Where) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% progress(Result, CaseNum, Mod, Func, Location, Reason, Time, +%% progress(Result, CaseNum, Mod, Func, Location, Reason, Time, %% Comment, TimeFormat) -> Result %% %% Prints the result of the test case to log file. %% Note: Strings that are to be written to the minor log must %% be prefixed with "=== " here, or the indentation will be wrong. -progress(skip, CaseNum, Mod, Func, Loc, Reason, Time, +progress(skip, CaseNum, Mod, Func, Loc, Reason, Time, Comment, {St0,St1}) -> - {Reason1,{Color,Ret}} = if_auto_skip(Reason, + {Reason1,{Color,Ret}} = if_auto_skip(Reason, fun() -> {"#ffcc99",auto_skip} end, fun() -> {"#ff9933",skip} end), print(major, "=result skipped", []), - print(1, "*** SKIPPED *** ~s", + print(1, "*** SKIPPED *** ~s", [get_info_str(Func, CaseNum, get(test_server_cases))]), test_server_sup:framework_call(report, [tc_done,{?pl2a(Mod),Func, {skipped,Reason1}}]), ReasonStr = reason_to_string(Reason1), - ReasonStr1 = lists:flatten([string:strip(S,left) || + ReasonStr1 = lists:flatten([string:strip(S,left) || S <- string:tokens(ReasonStr,[$\n])]), ReasonStr2 = if length(ReasonStr1) > 80 -> @@ -3686,10 +3807,10 @@ progress(skip, CaseNum, Mod, Func, Loc, Reason, Time, [Time,Color,ReasonStr2,Comment1]), FormatLoc = test_server_sup:format_loc(Loc), print(minor, "=== location ~s", [FormatLoc]), - print(minor, "=== reason = ~s", [ReasonStr1]), + print(minor, "=== reason = ~s", [ReasonStr1]), Ret; - -progress(failed, CaseNum, Mod, Func, Loc, timetrap_timeout, T, + +progress(failed, CaseNum, Mod, Func, Loc, timetrap_timeout, T, Comment0, {St0,St1}) -> print(major, "=result failed: timeout, ~p", [Loc]), print(1, "*** FAILED *** ~s", @@ -3699,23 +3820,23 @@ progress(failed, CaseNum, Mod, Func, Loc, timetrap_timeout, T, {failed,timetrap_timeout}}]), FormatLastLoc = test_server_sup:format_loc(get_last_loc(Loc)), ErrorReason = io_lib:format("{timetrap_timeout,~s}", [FormatLastLoc]), - Comment = + Comment = case Comment0 of "" -> "<font color=\"red\">" ++ ErrorReason ++ "</font>"; - _ -> "<font color=\"red\">" ++ ErrorReason ++ "</font><br>" ++ + _ -> "<font color=\"red\">" ++ ErrorReason ++ "</font><br>" ++ to_string(Comment0) end, - print(html, + print(html, "<td>" ++ St0 ++ "~.3fs" ++ St1 ++ "</td>" "<td><font color=\"red\">FAILED</font></td>" - "<td>~s</td></tr>\n", + "<td>~s</td></tr>\n", [T/1000,Comment]), FormatLoc = test_server_sup:format_loc(Loc), print(minor, "=== location ~s", [FormatLoc]), print(minor, "=== reason = timetrap timeout", []), failed; -progress(failed, CaseNum, Mod, Func, Loc, {testcase_aborted,Reason}, _T, +progress(failed, CaseNum, Mod, Func, Loc, {testcase_aborted,Reason}, _T, Comment0, {St0,St1}) -> print(major, "=result failed: testcase_aborted, ~p", [Loc]), print(1, "*** FAILED *** ~s", @@ -3725,23 +3846,23 @@ progress(failed, CaseNum, Mod, Func, Loc, {testcase_aborted,Reason}, _T, {failed,testcase_aborted}}]), FormatLastLoc = test_server_sup:format_loc(get_last_loc(Loc)), ErrorReason = io_lib:format("{testcase_aborted,~s}", [FormatLastLoc]), - Comment = + Comment = case Comment0 of "" -> "<font color=\"red\">" ++ ErrorReason ++ "</font>"; - _ -> "<font color=\"red\">" ++ ErrorReason ++ "</font><br>" ++ + _ -> "<font color=\"red\">" ++ ErrorReason ++ "</font><br>" ++ to_string(Comment0) end, - print(html, + print(html, "<td>" ++ St0 ++ "died" ++ St1 ++ "</td>" "<td><font color=\"red\">FAILED</font></td>" - "<td>~s</td></tr>\n", + "<td>~s</td></tr>\n", [Comment]), FormatLoc = test_server_sup:format_loc(Loc), print(minor, "=== location ~s", [FormatLoc]), print(minor, "=== reason = {testcase_aborted,~p}", [Reason]), failed; -progress(failed, CaseNum, Mod, Func, unknown, Reason, Time, +progress(failed, CaseNum, Mod, Func, unknown, Reason, Time, Comment0, {St0,St1}) -> print(major, "=result failed: ~p, ~p", [Reason,unknown]), print(1, "*** FAILED *** ~s", @@ -3749,10 +3870,10 @@ progress(failed, CaseNum, Mod, Func, unknown, Reason, Time, test_server_sup:framework_call(report, [tc_done,{?pl2a(Mod),Func, {failed,Reason}}]), TimeStr = io_lib:format(if is_float(Time) -> "~.3fs"; - true -> "~w" + true -> "~w" end, [Time]), ErrorReason = lists:flatten(io_lib:format("~p", [Reason])), - ErrorReason1 = lists:flatten([string:strip(S,left) || + ErrorReason1 = lists:flatten([string:strip(S,left) || S <- string:tokens(ErrorReason,[$\n])]), ErrorReason2 = if length(ErrorReason1) > 63 -> @@ -3760,13 +3881,13 @@ progress(failed, CaseNum, Mod, Func, unknown, Reason, Time, true -> ErrorReason1 end, - Comment = + Comment = case Comment0 of "" -> "<font color=\"red\">" ++ ErrorReason2 ++ "</font>"; - _ -> "<font color=\"red\">" ++ ErrorReason2 ++ "</font><br>" ++ + _ -> "<font color=\"red\">" ++ ErrorReason2 ++ "</font><br>" ++ to_string(Comment0) end, - print(html, + print(html, "<td>" ++ St0 ++ "~s" ++ St1 ++ "</td>" "<td><font color=\"red\">FAILED</font></td>" "<td>~s</td></tr>\n", @@ -3776,7 +3897,7 @@ progress(failed, CaseNum, Mod, Func, unknown, Reason, Time, print(minor, "=== reason = "++FStr, [FormattedReason]), failed; -progress(failed, CaseNum, Mod, Func, Loc, Reason, Time, +progress(failed, CaseNum, Mod, Func, Loc, Reason, Time, Comment0, {St0,St1}) -> print(major, "=result failed: ~p, ~p", [Reason,Loc]), print(1, "*** FAILED *** ~s", @@ -3784,18 +3905,18 @@ progress(failed, CaseNum, Mod, Func, Loc, Reason, Time, test_server_sup:framework_call(report, [tc_done,{?pl2a(Mod),Func, {failed,Reason}}]), TimeStr = io_lib:format(if is_float(Time) -> "~.3fs"; - true -> "~w" + true -> "~w" end, [Time]), - Comment = + Comment = case Comment0 of "" -> ""; _ -> "<br>" ++ to_string(Comment0) end, FormatLastLoc = test_server_sup:format_loc(get_last_loc(Loc)), - print(html, + print(html, "<td>" ++ St0 ++ "~s" ++ St1 ++ "</td>" "<td><font color=\"red\">FAILED</font></td>" - "<td><font color=\"red\">~s</font>~s</td></tr>\n", + "<td><font color=\"red\">~s</font>~s</td></tr>\n", [TimeStr,FormatLastLoc,Comment]), FormatLoc = test_server_sup:format_loc(Loc), print(minor, "=== location ~s", [FormatLoc]), @@ -3803,7 +3924,7 @@ progress(failed, CaseNum, Mod, Func, Loc, Reason, Time, print(minor, "=== reason = "++FStr, [FormattedReason]), failed; -progress(ok, _CaseNum, Mod, Func, _Loc, RetVal, Time, +progress(ok, _CaseNum, Mod, Func, _Loc, RetVal, Time, Comment0, {St0,St1}) -> print(minor, "successfully completed test case", []), test_server_sup:framework_call(report, [tc_done,{?pl2a(Mod),Func,ok}]), @@ -3852,9 +3973,9 @@ get_info_str(Func, 0, _Cases) -> get_info_str(_Func, CaseNum, unknown) -> "test case " ++ integer_to_list(CaseNum); get_info_str(_Func, CaseNum, Cases) -> - "test case " ++ integer_to_list(CaseNum) ++ + "test case " ++ integer_to_list(CaseNum) ++ " of " ++ integer_to_list(Cases). - + print_if_known(Known, {SK,AK}, {SU,AU}) -> {S,A} = if Known == unknown -> {SU,AU}; true -> {SK,AK} @@ -3880,7 +4001,7 @@ reason_to_string({failed,{_,FailFunc,bad_return}}) -> atom_to_list(FailFunc) ++ " bad return value"; reason_to_string({failed,{_,FailFunc,{timetrap_timeout,_}}}) -> atom_to_list(FailFunc) ++ " timed out"; -reason_to_string(FWInitFail = {failed,{_CB,init_tc,_Reason}}) -> +reason_to_string(FWInitFail = {failed,{_CB,init_tc,_Reason}}) -> to_string(FWInitFail); reason_to_string({failed,{_,FailFunc,_}}) -> atom_to_list(FailFunc) ++ " failed"; @@ -3889,29 +4010,29 @@ reason_to_string(Other) -> %get_font_style(Prop) -> % {Col,St0,St1} = get_font_style1(Prop), -% {{"<font color="++Col++">","</font>"}, +% {{"<font color="++Col++">","</font>"}, % {"<font color="++Col++">"++St0,St1++"</font>"}}. - + get_font_style(NormalCase, Mode) -> - Prop = if not NormalCase -> + Prop = if not NormalCase -> default; true -> case check_prop(parallel, Mode) of - false -> + false -> case check_prop(sequence, Mode) of - false -> + false -> default; - _ -> + _ -> sequence end; - _ -> + _ -> parallel end end, {Col,St0,St1} = get_font_style1(Prop), - {{"<font color="++Col++">","</font>"}, + {{"<font color="++Col++">","</font>"}, {"<font color="++Col++">"++St0,St1++"</font>"}}. - + get_font_style1(parallel) -> {"\"darkslategray\"","<i>","</i>"}; get_font_style1(sequence) -> @@ -3931,7 +4052,7 @@ get_font_style1(default) -> %% The framework application can switch this feature off by setting %% *its* application environment variable 'format_exception' to false. %% It is also possible to switch formatting off by starting the -%% test_server node with init argument 'test_server_format_exception' +%% test_server node with init argument 'test_server_format_exception' %% set to false. format_exception(Reason={_Error,Stack}) when is_list(Stack) -> @@ -3950,17 +4071,17 @@ format_exception(Reason={_Error,Stack}) when is_list(Stack) -> _ -> do_format_exception(Reason) end - end; + end; format_exception(Error) -> format_exception({Error,[]}). do_format_exception(Reason={Error,Stack}) -> StackFun = fun(_, _, _) -> false end, - PF = fun(Term, I) -> - io_lib:format("~." ++ integer_to_list(I) ++ "p", [Term]) + PF = fun(Term, I) -> + io_lib:format("~." ++ integer_to_list(I) ++ "p", [Term]) end, case catch lib:format_exception(1, error, Error, Stack, StackFun, PF) of - {'EXIT',_} -> + {'EXIT',_} -> {"~p",Reason}; Formatted -> Formatted1 = re:replace(Formatted, "exception error: ", "", [{return,list}]), @@ -3969,8 +4090,8 @@ do_format_exception(Reason={Error,Stack}) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% run_test_case_apply(CaseNum, Mod, Func, Args, Name, RunInit, -%% Where, MultiplyTimetrap) -> +%% run_test_case_apply(CaseNum, Mod, Func, Args, Name, RunInit, +%% Where, TimetrapData) -> %% {{Time,RetVal,Loc,Opts,Comment},DetectedFail,ProcessesBefore,ProcessesAfter} | %% {{died,Reason,unknown,Comment},DetectedFail,ProcessesBefore,ProcessesAfter} %% Name = atom() @@ -3984,24 +4105,24 @@ do_format_exception(Reason={Error,Stack}) -> %% ProcessesBefore = ProcessesAfter = integer() %% %% Where indicates if the test should run on target or always on the host. -%% -%% If test is to be run on target, and target is remote the request is +%% +%% If test is to be run on target, and target is remote the request is %% sent over socket to target, and test_server runs the case and sends the %% result back over the socket. Else test_server runs the case directly on host. -run_test_case_apply(CaseNum, Mod, Func, Args, Name, RunInit, host, MultiplyTimetrap) -> +run_test_case_apply(CaseNum, Mod, Func, Args, Name, RunInit, host, TimetrapData) -> test_server:run_test_case_apply({CaseNum,Mod,Func,Args,Name,RunInit, - MultiplyTimetrap}); -run_test_case_apply(CaseNum, Mod, Func, Args, Name, RunInit, target, MultiplyTimetrap) -> + TimetrapData}); +run_test_case_apply(CaseNum, Mod, Func, Args, Name, RunInit, target, TimetrapData) -> case get(test_server_ctrl_job_sock) of undefined -> %% local target test_server:run_test_case_apply({CaseNum,Mod,Func,Args,Name,RunInit, - MultiplyTimetrap}); + TimetrapData}); JobSock -> %% remote target request(JobSock, {test_case,{CaseNum,Mod,Func,Args,Name,RunInit, - MultiplyTimetrap}}), + TimetrapData}}), read_job_sock_loop(JobSock) end. @@ -4012,15 +4133,15 @@ run_test_case_apply(CaseNum, Mod, Func, Args, Name, RunInit, target, MultiplyTim %% Args = [term()] %% %% Just like io:format, except that depending on the Detail value, the output -%% is directed to console, major and/or minor log files. +%% is directed to console, major and/or minor log files. %% %% To handle printouts to common (not minor) log files from parallel test %% case processes, the test_server_common_io_handler value is checked. If %% set, the data is sent to the main controlling process. Note that test %% cases that belong to a conf group nested under a parallel group will also %% get its io data sent to main rather than immediately printed out, even -%% if the test cases are executed by the same, main, process (ie the main -%% process sends messages to itself then). +%% if the test cases are executed by the same, main, process (ie the main +%% process sends messages to itself then). %% %% Buffered io is handled by the handle_test_case_io_and_status/0 function. @@ -4040,21 +4161,21 @@ print_or_buffer(Detail, Msg, Printer) -> output({Detail,Msg}, Printer); MinLevel when is_number(Detail), Detail >= MinLevel -> output({Detail,Msg}, Printer); - _ -> % Detail < Minor | major | html + _ -> % Detail < Minor | major | html case get(test_server_common_io_handler) of - undefined -> + undefined -> output({Detail,Msg}, Printer); {_,MainPid} -> MainPid ! {print,self(),Detail,Msg} end - end. + end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% print_timestamp(Detail, Leader) -> ok %% %% Prints Leader followed by a time stamp (date and time). Depending on %% the Detail value, the output is directed to console, major and/or minor -%% log files. +%% log files. print_timestamp(Detail, Leader) -> print(Detail, timestamp_get(Leader), []). @@ -4288,7 +4409,7 @@ update_config(Config, []) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% collect_cases(CurMod, TopCase, SkipList) -> +%% collect_cases(CurMod, TopCase, SkipList) -> %% BasicCaseList | {error,Reason} %% %% CurMod = atom() @@ -4319,18 +4440,18 @@ update_config(Config, []) -> %% are listed, and each Module:all(suite) is called %% {dir,Dir,Pattern} All modules <Pattern>_SUITE in the named dir %% are listed, and each Module:all(suite) is called -%% {conf,InitMF,Cases,FinMF} -%% {conf,Props,InitMF,Cases,FinMF} +%% {conf,InitMF,Cases,FinMF} +%% {conf,Props,InitMF,Cases,FinMF} %% InitMF is placed in the BasicCaseList, then %% Cases is treated according to this table, then %% FinMF is placed in the BasicCaseList. InitMF %% and FinMF are configuration manipulation %% functions. See below. -%% {make,InitMFA,Cases,FinMFA} +%% {make,InitMFA,Cases,FinMFA} %% InitMFA is placed in the BasicCaseList, then %% Cases is treated according to this table, then %% FinMFA is placed in the BasicCaseList. InitMFA -%% and FinMFA are make/unmake functions. If InitMFA +%% and FinMFA are make/unmake functions. If InitMFA %% fails, Cases are not run. InitMFA and FinMFA are %% always run on the host - not on target. %% @@ -4339,7 +4460,7 @@ update_config(Config, []) -> %% %% [] Leaf case %% {req,ReqList} Kept for backwards compatibility - same as [] -%% {req,ReqList,Cases} Kept for backwards compatibility - +%% {req,ReqList,Cases} Kept for backwards compatibility - %% Cases parsed recursively with collect_cases/3 %% Cases (list) Recursively parsed with collect_cases/3 %% @@ -4351,7 +4472,7 @@ update_config(Config, []) -> %% Configuration manipulation functions are called with the current %% configuration list as only argument, and are expected to return a new %% configuration list. Such a pair of function may, for example, start a -%% server and stop it after a serie of test cases. +%% server and stop it after a serie of test cases. %% %% SkipCases is expected to be in the format: %% @@ -4364,10 +4485,10 @@ update_config(Config, []) -> skip}). % skip list collect_all_cases(Top, Skip) when is_list(Skip) -> - Result = + Result = case collect_cases(Top, #cc{mod=[],skip=Skip}) of {ok,Cases,_St} -> Cases; - Other -> Other + Other -> Other end, Result. @@ -4379,12 +4500,12 @@ collect_cases([Case|Cs0], St0) -> case collect_cases(Cs0, St1) of {ok,FlatCases2,St} -> {ok,FlatCases1 ++ FlatCases2,St}; - {error,_Reason}=Error -> Error + {error,_Reason} = Error -> Error end; - {error,_Reason}=Error -> Error + {error,_Reason} = Error -> Error end; - + collect_cases({module,Case}, St) when is_atom(Case), is_atom(St#cc.mod) -> collect_case({St#cc.mod,Case}, St); collect_cases({module,Mod,Case}, St) -> @@ -4404,38 +4525,71 @@ collect_cases({conf,InitMF,CaseList,FinF}, St) when is_atom(FinF) -> collect_cases({conf,InitMF,CaseList,FinMF}, St0) -> collect_cases({conf,[],InitMF,CaseList,FinMF}, St0); collect_cases({conf,Props,InitF,CaseList,FinMF}, St) when is_atom(InitF) -> - collect_cases({conf,Props,{St#cc.mod,InitF},CaseList,FinMF}, St); + case init_props(Props) of + {error,_} -> + {ok,[],St}; + Props1 -> + collect_cases({conf,Props1,{St#cc.mod,InitF},CaseList,FinMF}, St) + end; collect_cases({conf,Props,InitMF,CaseList,FinF}, St) when is_atom(FinF) -> - collect_cases({conf,Props,InitMF,CaseList,{St#cc.mod,FinF}}, St); -collect_cases({conf,Props,InitMF,CaseList,FinMF}, St0) -> - case collect_cases(CaseList, St0) of - {ok,[],_St}=Empty -> - Empty; - {ok,FlatCases,St} -> + case init_props(Props) of + {error,_} -> + {ok,[],St}; + Props1 -> + collect_cases({conf,Props1,InitMF,CaseList,{St#cc.mod,FinF}}, St) + end; +collect_cases({conf,Props,InitMF,CaseList,FinMF} = Conf, St) -> + case init_props(Props) of + {error,_} -> + {ok,[],St}; + Props1 -> Ref = make_ref(), - case in_skip_list(InitMF, St#cc.skip) of - {true,Comment} -> - {ok,[{skip_case,{conf,Ref,InitMF,Comment}} | - FlatCases ++ [{conf,Ref,[],FinMF}]],St}; + Skips = St#cc.skip, + case in_skip_list({St#cc.mod,Conf}, Skips) of + {true,Comment} -> % conf init skipped + {ok,[{skip_case,{conf,Ref,InitMF,Comment}} | + [] ++ [{conf,Ref,[],FinMF}]],St}; + {true,Name,Comment} when is_atom(Name) -> % all cases skipped + {ok,[{skip_case,{{St#cc.mod,{group,Name}},Comment}}],St}; + {true,ToSkip,_} when is_list(ToSkip) -> % some cases skipped + case collect_cases(CaseList, + St#cc{skip=ToSkip++Skips}) of + {ok,[],_St} = Empty -> + Empty; + {ok,FlatCases,St1} -> + {ok,[{conf,Ref,Props1,InitMF} | + FlatCases ++ [{conf,Ref, + keep_name(Props1), + FinMF}]],St1#cc{skip=Skips}}; + {error,_Reason} = Error -> + Error + end; false -> - {ok,[{conf,Ref,Props,InitMF} | - FlatCases ++ [{conf,Ref,keep_name(Props),FinMF}]],St} - end; - {error,_Reason}=Error -> - Error + case collect_cases(CaseList, St) of + {ok,[],_St} = Empty -> + Empty; + {ok,FlatCases,St1} -> + {ok,[{conf,Ref,Props1,InitMF} | + FlatCases ++ [{conf,Ref, + keep_name(Props1), + FinMF}]],St1}; + {error,_Reason} = Error -> + Error + end + end end; collect_cases({make,InitMFA,CaseList,FinMFA}, St0) -> case collect_cases(CaseList, St0) of - {ok,[],_St}=Empty -> Empty; + {ok,[],_St} = Empty -> Empty; {ok,FlatCases,St} -> Ref = make_ref(), - {ok,[{make,Ref,InitMFA}|FlatCases ++ + {ok,[{make,Ref,InitMFA}|FlatCases ++ [{make,Ref,FinMFA}]],St}; - {error,_Reason}=Error -> Error + {error,_Reason} = Error -> Error end; -collect_cases({Module, Cases}, St) when is_list(Cases) -> +collect_cases({Module, Cases}, St) when is_list(Cases) -> case (catch collect_case(Cases, St#cc{mod=Module}, [])) of {ok, NewCases, NewSt} -> {ok, NewCases, NewSt}; @@ -4450,8 +4604,11 @@ collect_cases({_Mod,_Case,_Args}=Spec, St) -> collect_case(Spec, St); collect_cases(Case, St) when is_atom(Case), is_atom(St#cc.mod) -> collect_case({St#cc.mod,Case}, St); -collect_cases(Other, _St) -> - {error,{bad_subtest_spec,Other}}. +collect_cases(Other, St) -> + {error,{bad_subtest_spec,St#cc.mod,Other}}. + +collect_case({Mod,{conf,_,_,_,_}=Conf}, St) -> + collect_case_invoke(Mod, Conf, [], St); collect_case(MFA, St) -> case in_skip_list(MFA, St#cc.skip) of @@ -4475,9 +4632,9 @@ collect_case_invoke(Mod, Case, MFA, St) -> case os:getenv("TEST_SERVER_FRAMEWORK") of false -> case catch apply(Mod, Case, [suite]) of - {'EXIT',_} -> + {'EXIT',_} -> {ok,[MFA],St}; - Suite -> + Suite -> collect_subcases(Mod, Case, MFA, St, Suite) end; _ -> @@ -4485,9 +4642,10 @@ collect_case_invoke(Mod, Case, MFA, St) -> collect_subcases(Mod, Case, MFA, St, Suite) end. -collect_subcases(Mod, Case, MFA, St, Suite) -> +collect_subcases(Mod, Case, MFA, St, Suite) -> case Suite of [] when Case == all -> {ok,[],St}; + [] when element(1, Case) == conf -> {ok,[],St}; [] -> {ok,[MFA],St}; %%%! --- START Kept for backwards compatibilty --- %%%! Requirements are not used @@ -4498,6 +4656,8 @@ collect_subcases(Mod, Case, MFA, St, Suite) -> %%%! --- END Kept for backwards compatibilty --- {Skip,Reason} when Skip==skip; Skip==skipped -> {ok,[{skip_case,{MFA,Reason}}],St}; + {error,Reason} -> + throw(Reason); SubCases -> collect_case_subcases(Mod, Case, SubCases, St) end. @@ -4536,7 +4696,7 @@ collect_case_deny(Mod, Case, MFA, ReqList, SubCases, St) -> {granted,SubCases} -> collect_case_subcases(Mod, Case, SubCases, St) end. - + check_deny([Req|Reqs], DenyList) -> case check_deny_req(Req, DenyList) of {denied,_Comment}=Denied -> Denied; @@ -4559,8 +4719,49 @@ check_deny_req(Req, DenyList) -> false -> granted end. +in_skip_list({Mod,{conf,Props,InitMF,_CaseList,_FinMF}}, SkipList) -> + case in_skip_list(InitMF, SkipList) of + {true,_} = Yes -> + Yes; + _ -> + case proplists:get_value(name, Props) of + undefined -> + false; + Name -> + ToSkip = + lists:flatmap( + fun({M,{conf,SProps,_,SCaseList,_},Cmt}) when + M == Mod -> + case proplists:get_value(name, SProps) of + all -> + [{M,all,Cmt}]; + Name -> + case SCaseList of + all -> + [{M,all,Cmt}]; + _ -> + [{M,F,Cmt} || F <- SCaseList] + end; + _ -> + [] + end; + (_) -> + [] + end, SkipList), + case ToSkip of + [] -> + false; + _ -> + case lists:keysearch(all, 2, ToSkip) of + {value,{_,_,Cmt}} -> {true,Name,Cmt}; + _ -> {true,ToSkip,""} + end + end + end + end; + in_skip_list({Mod,Func,_Args}, SkipList) -> - in_skip_list({Mod,Func}, SkipList); + in_skip_list({Mod,Func}, SkipList); in_skip_list({Mod,Func}, [{Mod,Funcs,Comment}|SkipList]) when is_list(Funcs) -> case lists:member(Func, Funcs) of true -> @@ -4577,9 +4778,21 @@ in_skip_list({Mod,Func}, [_|SkipList]) -> in_skip_list(_, []) -> false. +%% remove unnecessary properties +init_props(Props) -> + case get_repeat(Props) of + Repeat = {_RepType,N} when N < 2 -> + if N == 0 -> + {error,{invalid_property,Repeat}}; + true -> + lists:delete(Repeat, Props) + end; + _ -> + Props + end. + keep_name(Props) -> lists:filter(fun({name,_}) -> true; (_) -> false end, Props). - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Target node handling functions %% @@ -4615,13 +4828,13 @@ start_node(Name, Type, Options) -> end, case Warning of [] -> ok; - _ -> + _ -> format(1, Warning), format(minor, Warning) end, {ok, Nodename}; {fail,{Ret, Host, Cmd}} -> - format(minor, + format(minor, "Failed to start node ~p on ~p with command: ~p~n" "Reason: ~p", [Name, Host, Cmd, Ret]), @@ -4630,7 +4843,7 @@ start_node(Name, Type, Options) -> format(minor, "Failed to start node ~p: ~p", [Name,Ret]), Ret; {Ret, Host, Cmd} -> - format(minor, + format(minor, "Failed to start node ~p on ~p with command: ~p~n" "Reason: ~p", [Name, Host, Cmd, Ret]), @@ -4685,7 +4898,7 @@ read_job_sock_loop(Sock) -> exit({controller,connection_lost,Reason}); {ok,<<1,Request/binary>>} -> case decode(binary_to_term(Request)) of - ok -> + ok -> read_job_sock_loop(Sock); {stop,Result} -> Result @@ -4695,14 +4908,14 @@ read_job_sock_loop(Sock) -> decode({apply,{M,F,A}}) -> apply(M,F,A), ok; -decode({sync_apply,{M,F,A}}) -> +decode({sync_apply,{M,F,A}}) -> R = apply(M,F,A), request(get(test_server_ctrl_job_sock),{sync_result,R}), ok; decode({sync_result,Result}) -> {stop,Result}; decode({test_case_result,Result}) -> - {stop,Result}; + {stop,Result}; decode({privdir,empty_priv_dir}) -> {stop,ok}; decode({{privdir,PrivDirTar},TarBin}) -> @@ -4742,7 +4955,7 @@ p({A,B,C}) -> p(X) -> pinfo(X). -t() -> +t() -> t(wall_clock). t(X) -> element(1, statistics(X)). @@ -4781,7 +4994,7 @@ display_info([Pid|T], R, M) -> Other -> Other end, - Reds = fetch(reductions, Info), + Reds = fetch(reductions, Info), LM = length(fetch(messages, Info)), pformat(io_lib:format("~w", [Pid]), io_lib:format("~w", [Call]), @@ -4822,12 +5035,12 @@ pinfo(P) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% A module is included in the cover analysis if -%% - it belongs to the tested application and is not listed in the +%% - it belongs to the tested application and is not listed in the %% {exclude,List} part of the App.cover file %% - it does not belong to the application, but is listed in the %% {include,List} part of the App.cover file -%% - it does not belong to the application, but is listed in the -%% cross.cover file (in the test_server application) under 'all' +%% - it does not belong to the application, but is listed in the +%% cross.cover file (in the test_server application) under 'all' %% or under the tested application. %% %% The modules listed in the cross.cover file are modules that are @@ -4893,7 +5106,7 @@ read_cover_file(CoverFile) -> io:fwrite("Faulty format of CoverFile ~p\n", [CoverFile]), {[],[]} end; - {error,Reason} -> + {error,Reason} -> io:fwrite("Can't read CoverFile ~p\nReason: ~p\n", [CoverFile,Reason]), {[],[]} @@ -4958,7 +5171,7 @@ cover_analyse({App,CoverInfo}, Analyse, AnalyseMods, TestDir) -> end, io:fwrite(CoverLog, "<p>Excluded module(s): <code>~p</code>\n", [Excluded]), - + Coverage = cover_analyse(Analyse, AnalyseMods), case lists:filter(fun({_M,{_,_,_}}) -> false; @@ -4968,7 +5181,7 @@ cover_analyse({App,CoverInfo}, Analyse, AnalyseMods, TestDir) -> ok; Bad -> io:fwrite(CoverLog, "<p>Analysis failed for ~w module(s): " - "<code>~w</code>\n", + "<code>~w</code>\n", [length(Bad),[BadM || {BadM,{_,_Why}} <- Bad]]) end, @@ -5002,10 +5215,10 @@ cross_cover_analyse(Analyse, CrossModules) -> CoverdataFiles = get_coverdata_files(), lists:foreach(fun(CDF) -> cover:import(CDF) end, CoverdataFiles), io:fwrite("Cover analysing... ", []), - DetailsFun = + DetailsFun = case Analyse of details -> - fun(Dir,M) -> + fun(Dir,M) -> OutFile = filename:join(Dir, atom_to_list(M) ++ ".CROSS_COVER.html"), @@ -5018,7 +5231,7 @@ cross_cover_analyse(Analyse, CrossModules) -> SortedModules = case CrossModules of undefined -> - sort_modules([Mod || Mod <- get_all_cross_modules(), + sort_modules([Mod || Mod <- get_all_cross_modules(), lists:member(Mod, cover:imported_modules())], []); _ -> sort_modules(CrossModules, []) @@ -5031,7 +5244,7 @@ cross_cover_analyse(Analyse, CrossModules) -> %% cross.cover, write a cross cover log (cross_cover.html). write_cross_cover_logs([{App,Coverage}|T]) -> case last_test_for_app(App) of - false -> + false -> ok; Dir -> CoverLogName = filename:join(Dir,?cross_coverlog_name), @@ -5045,13 +5258,13 @@ write_cross_cover_logs([{App,Coverage}|T]) -> end, write_cross_cover_logs(T); write_cross_cover_logs([]) -> - io:fwrite("done\n", []). + io:fwrite("done\n", []). %% Find all exported coverdata files. First find all the latest %% run.<timestamp> directories, and the check if there is a file named %% all.coverdata. get_coverdata_files() -> - PossibleFiles = [last_coverdata_file(Dir) || + PossibleFiles = [last_coverdata_file(Dir) || Dir <- filelib:wildcard([$*|?logdir_ext]), filelib:is_dir(Dir)], [File || File <- PossibleFiles, filelib:is_file(File)]. @@ -5074,12 +5287,12 @@ last_test([_|Rest], Latest) -> last_test(Rest, Latest); last_test([], Latest) -> Latest. - + %% Sort modules according to the application they belong to. %% Return [{App,LastTestDir,ModuleList}] sort_modules([M|Modules], Acc) -> App = get_app(M), - Acc1 = + Acc1 = case lists:keysearch(App, 1, Acc) of {value,{App,LastTest,List}} -> lists:keyreplace(App, 1, Acc, {App,LastTest,[M|List]}); @@ -5120,9 +5333,9 @@ get_all_cross_modules() -> get_cross_modules(all). get_cross_modules(App) -> case file:consult(?cross_cover_file) of - {ok,List} -> + {ok,List} -> get_cross_modules(App, List, []); - _X -> + _X -> [] end. @@ -5134,11 +5347,11 @@ get_cross_modules(App, [_H|T], Acc) -> get_cross_modules(App, T, Acc); get_cross_modules(_App, [], Acc) -> Acc. - + %% Support functions for writing the cover logs (both cross and normal) write_coverlog_header(CoverLog) -> - case catch + case catch io:fwrite(CoverLog, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n" "<!-- autogenerated by '~w'. -->\n" @@ -5162,13 +5375,13 @@ format_analyse(M,Cov,NotCov,undefined) -> io_lib:fwrite("<tr><td>~w</td>" "<td align=right>~w %</td>" "<td align=right>~w</td>" - "<td align=right>~w</td></tr>\n", + "<td align=right>~w</td></tr>\n", [M,pc(Cov,NotCov),Cov,NotCov]); format_analyse(M,Cov,NotCov,{file,File}) -> io_lib:fwrite("<tr><td><a href=\"~s\">~w</a></td>" "<td align=right>~w %</td>" "<td align=right>~w</td>" - "<td align=right>~w</td></tr>\n", + "<td align=right>~w</td></tr>\n", [filename:basename(File),M,pc(Cov,NotCov),Cov,NotCov]); format_analyse(M,Cov,NotCov,{lines,Lines}) -> CoverOutName = atom_to_list(M)++".COVER.html", @@ -5177,15 +5390,15 @@ format_analyse(M,Cov,NotCov,{lines,Lines}) -> io_lib:fwrite("<tr><td><a href=\"~s\">~w</a></td>" "<td align=right>~w %</td>" "<td align=right>~w</td>" - "<td align=right>~w</td></tr>\n", + "<td align=right>~w</td></tr>\n", [CoverOutName,M,pc(Cov,NotCov),Cov,NotCov]); format_analyse(M,Cov,NotCov,{error,_}) -> io_lib:fwrite("<tr><td>~w</td>" "<td align=right>~w %</td>" "<td align=right>~w</td>" - "<td align=right>~w</td></tr>\n", + "<td align=right>~w</td></tr>\n", [M,pc(Cov,NotCov),Cov,NotCov]). - + pc(0,0) -> 0; @@ -5200,9 +5413,9 @@ write_not_covered(CoverOut,M,Lines) -> "<table border=3 cellpadding=5>\n" "<th>Line Number</th>\n", [M]), - lists:foreach(fun({{_M,Line},{0,1}}) -> + lists:foreach(fun({{_M,Line},{0,1}}) -> io:fwrite(CoverOut,"<tr><td>~w</td></tr>\n", [Line]); - (_) -> + (_) -> ok end, Lines), @@ -5216,7 +5429,7 @@ write_default_coverlog(TestDir) -> file:close(CoverLog). write_default_cross_coverlog(TestDir) -> - {ok,CrossCoverLog} = + {ok,CrossCoverLog} = file:open(filename:join(TestDir,?cross_coverlog_name), [write]), write_coverlog_header(CrossCoverLog), io:fwrite(CrossCoverLog, @@ -5232,7 +5445,7 @@ write_cover_result_table(CoverLog,Coverage) -> "<th>Not covered (Lines)</th>\n", []), {TotCov,TotNotCov} = - lists:foldl(fun({M,{Cov,NotCov,Details}},{AccCov,AccNotCov}) -> + lists:foldl(fun({M,{Cov,NotCov,Details}},{AccCov,AccNotCov}) -> Str = format_analyse(M,Cov,NotCov,Details), io:fwrite(CoverLog,"~s", [Str]), {AccCov+Cov,AccNotCov+NotCov}; diff --git a/lib/test_server/src/test_server_internal.hrl b/lib/test_server/src/test_server_internal.hrl index 6fa5ef75b1..c9c52854e3 100644 --- a/lib/test_server/src/test_server_internal.hrl +++ b/lib/test_server/src/test_server_internal.hrl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -37,7 +37,7 @@ username, % string() cookie, % string(); Cookie for target node naming, % string(); "-name" | "-sname" - master, % string(); For OSE this is the master + master, % string(); Was used for OSE's master % node for main target and slave nodes. % For other platforms the target node % itself is master for slave nodes diff --git a/lib/test_server/src/test_server_node.erl b/lib/test_server/src/test_server_node.erl index ddc89d50d4..49025b1a3d 100644 --- a/lib/test_server/src/test_server_node.erl +++ b/lib/test_server/src/test_server_node.erl @@ -1,31 +1,29 @@ %% %% %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 %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% -module(test_server_node). --compile(r11). +-compile(r12). %%% %%% The same compiled code for this module must be possible to load -%%% in R11B, R12B and later. To make that possible no bit syntax -%%% must be used. +%%% in R12B and later. %%% - %% Test Controller interface -export([is_release_available/1]). -export([start_remote_main_target/1,stop/1]). diff --git a/lib/test_server/src/test_server_sup.erl b/lib/test_server/src/test_server_sup.erl index 89edb0f881..625724fbb5 100644 --- a/lib/test_server/src/test_server_sup.erl +++ b/lib/test_server/src/test_server_sup.erl @@ -21,7 +21,7 @@ %%% Purpose: Test server support functions. %%%------------------------------------------------------------------- -module(test_server_sup). --export([timetrap/2, timetrap_cancel/1, capture_get/1, messages_get/1, +-export([timetrap/2, timetrap/3, timetrap_cancel/1, capture_get/1, messages_get/1, timecall/3, call_crash/5, app_test/2, check_new_crash_dumps/0, cleanup_crash_dumps/0, crash_dump_dir/0, tar_crash_dumps/0, get_username/0, get_os_family/0, @@ -34,16 +34,23 @@ -define(src_listing_ext, ".src.html"). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% timetrap(Timeout,Pid) -> Handle +%% timetrap(Timeout,Scale,Pid) -> Handle %% Handle = term() %% %% Creates a time trap, that will kill the given process if the %% trap is not cancelled with timetrap_cancel/1, within Timeout %% milliseconds. +%% Scale says if the time should be scaled up to compensate for +%% delays during the test (e.g. if cover is running). timetrap(Timeout0, Pid) -> + timetrap(Timeout0, true, Pid). + +timetrap(Timeout0, Scale, Pid) -> process_flag(priority, max), - Timeout = test_server:timetrap_scale_factor() * Timeout0, + Timeout = if not Scale -> Timeout0; + true -> test_server:timetrap_scale_factor() * Timeout0 + end, receive after trunc(Timeout) -> Line = test_server:get_loc(Pid), @@ -497,6 +504,7 @@ framework_call(Callback,Func,Args,DefaultReturn) -> end, case erlang:function_exported(Mod,Func,length(Args)) of true -> + put(test_server_loc, {Mod,Func,framework}), EH = fun(Reason) -> exit({fw_error,{Mod,Func,Reason}}) end, try apply(Mod,Func,Args) of Result -> diff --git a/lib/test_server/src/ts.erl b/lib/test_server/src/ts.erl index 1b750c3858..fcd955345f 100644 --- a/lib/test_server/src/ts.erl +++ b/lib/test_server/src/ts.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,7 +71,7 @@ %%% ts_erl_config Finds out information about the Erlang system, %%% for instance the location of erl_interface. %%% This works for either an installed OTP or an Erlang -%%% system running from Clearcase. +%%% system running in a git repository/source tree. %%% ts_make Interface to run the `make' program on Unix %%% and other platforms. %%% ts_make_erl A corrected version of the standar Erlang module @@ -112,7 +112,7 @@ " Mandatory for remote targets\n" " {master, {MasterHost, MasterCookie}}\n" " - Master host and cookie for targets which are\n" - " started as slave nodes (i.e. OSE/Delta targets\n" + " started as slave nodes.\n" " erl_boot_server must be started on master before\n" " test is run.\n" " Optional, default is controller host and then\n" diff --git a/lib/test_server/src/ts_erl_config.erl b/lib/test_server/src/ts_erl_config.erl index 4fc46fc5d6..640c8ddc9f 100644 --- a/lib/test_server/src/ts_erl_config.erl +++ b/lib/test_server/src/ts_erl_config.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% %% @@ -70,18 +70,18 @@ dl_vars(Vars, _) -> ShlibRules = ts_lib:subst(ShlibRules0, Vars), [{'SHLIB_RULES', ShlibRules}|Vars]. -erts_lib_name(multi_threaded, win32) -> +erts_lib_name(multi_threaded, {win32, V}) -> link_library("erts_MD" ++ case is_debug_build() of true -> "d"; false -> "" end, - win32); -erts_lib_name(single_threaded, win32) -> + {win32, V}); +erts_lib_name(single_threaded, {win32, V}) -> link_library("erts_ML" ++ case is_debug_build() of true -> "d"; false -> "" end, - win32); + {win32, V}); erts_lib_name(multi_threaded, OsType) -> link_library("erts_r", OsType); erts_lib_name(single_threaded, OsType) -> @@ -107,7 +107,7 @@ erts_lib(Vars,OsType) -> ErtsIncludeInternal, ErtsLib, ErtsLibInternal}; - {Type, Root, Target} when Type == clearcase; Type == srctree -> + {srctree, Root, Target} -> Erts = filename:join([Root, "erts"]), ErtsInclude = filename:join([Erts, "include"]), ErtsIncludeTarget = filename:join([ErtsInclude, Target]), @@ -146,7 +146,7 @@ erl_include(Vars) -> case erl_root(Vars) of {installed, Root} -> filename:join([Root, "usr", "include"]); - {Type, Root, Target} when Type == clearcase; Type == srctree -> + {srctree, Root, Target} -> filename:join([Root, "erts", "emulator", "beam"]) ++ " -I" ++ filename:join([Root, "erts", "emulator"]) ++ system_include(Root, Vars) @@ -161,7 +161,6 @@ system_include(Root, Vars) -> case ts_lib:var(os, Vars) of "Windows" ++ _T -> "sys/win32"; "VxWorks" -> "sys.vxworks"; - "OSE" -> "sys/ose"; _ -> "sys/unix" end, " -I" ++ filename:nativename(filename:join([Root, "erts", "emulator", SysDir])). @@ -180,7 +179,7 @@ erl_interface(Vars,OsType) -> {srctree, _Root, _Target} when OsType =:= vxworks -> {filename:join(Dir, "lib"), filename:join([Dir, "src"])}; - {Type, _Root, Target} when Type == clearcase; Type == srctree -> + {srctree, _Root, Target} -> {filename:join([Dir, "obj", Target]), filename:join([Dir, "src", Target])} end} @@ -219,7 +218,7 @@ erl_interface(Vars,OsType) -> {unix,_} -> "-lpthread"; _ -> - "" % VxWorks or OSE + "" % VxWorks end, CrossCompile = case OsType of vxworks -> "true"; @@ -247,7 +246,7 @@ ic(Vars, OsType) -> case erl_root(Vars) of {installed, _Root} -> filename:join([Dir, "priv", "lib"]); - {Type, _Root, Target} when Type == clearcase; Type == srctree -> + {srctree, _Root, Target} -> filename:join([Dir, "priv", "lib", Target]) end, filename:join(Dir, "include")} @@ -267,21 +266,6 @@ jinterface(Vars, _OsType) -> end, [{jinterface_classpath, filename:nativename(ClassPath)}|Vars]. -%% Unused! -% ig_vars(Vars) -> -% {Lib0, Incl} = -% case erl_root(Vars) of -% {installed, Root} -> -% Base = filename:join([Root, "usr"]), -% {filename:join([Base, "lib"]), -% filename:join([Base, "include"])}; -% {Type, Root, Target} when Type == clearcase; Type == srctree -> -% {filename:join([Root, "lib", "ig", "obj", Target]), -% filename:join([Root, "lib", "ig", "include"])} -% end, -% [{ig_libdir, filename:nativename(Lib0)}, -% {ig_include, filename:nativename(Incl)}|Vars]. - lib_dir(Vars, Lib) -> LibLibDir = case Lib of erts -> @@ -318,9 +302,6 @@ lib_dir(Vars, Lib) -> erl_root(Vars) -> Root = code:root_dir(), case ts_lib:erlang_type() of - {clearcase, _Version} -> - Target = get_var(target, Vars), - {clearcase, Root, Target}; {srctree, _Version} -> Target = get_var(target, Vars), {srctree, Root, Target}; @@ -350,10 +331,7 @@ sock_libraries({unix, _}) -> sock_libraries(vxworks) -> ""; sock_libraries(ose) -> - ""; -sock_libraries(_Other) -> - exit({sock_libraries, not_supported}). - + "". link_library(LibName,{win32, _}) -> LibName ++ ".lib"; diff --git a/lib/test_server/src/ts_install.erl b/lib/test_server/src/ts_install.erl index 94926eba80..bbbb7883db 100644 --- a/lib/test_server/src/ts_install.erl +++ b/lib/test_server/src/ts_install.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% %% -module(ts_install). @@ -175,15 +175,8 @@ get_testcase_callback() -> get_rsh_name() -> case os:getenv("ERL_RSH") of - false -> - case ts_lib:erlang_type() of - {clearcase, _} -> - "ctrsh"; - {_, _} -> - "rsh" - end; - Str -> - Str + false -> "rsh"; + Str -> Str end. platform_id(Vars) -> diff --git a/lib/test_server/src/ts_lib.erl b/lib/test_server/src/ts_lib.erl index 082c9e0519..2f0a4ea8c0 100644 --- a/lib/test_server/src/ts_lib.erl +++ b/lib/test_server/src/ts_lib.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% %% -module(ts_lib). @@ -21,6 +21,8 @@ -include_lib("kernel/include/file.hrl"). -include("ts.hrl"). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([error/1, var/2, erlang_type/0, initial_capital/1, interesting_logs/1, specs/1, suites/2, last_test/1, @@ -72,12 +74,10 @@ progress(Vars, Level, Format, Args) -> erlang_type() -> {_, Version} = init:script_id(), - RelDir = filename:join([code:root_dir(), "releases"]), % Only in installed - SysDir = filename:join([code:root_dir(), "system"]), % Nonexisting link/dir outside ClearCase - case {filelib:is_file(RelDir),filelib:is_file(SysDir)} of - {true,_} -> {otp, Version}; % installed OTP - {_,true} -> {clearcase, Version}; - _ -> {srctree, Version} + RelDir = filename:join(code:root_dir(), "releases"), % Only in installed + case filelib:is_file(RelDir) of + true -> {otp,Version}; % installed OTP + false -> {srctree,Version} % source code tree end. %% Upcases the first letter in a string. diff --git a/lib/test_server/src/ts_reports.erl b/lib/test_server/src/ts_reports.erl index b41291d342..f981a77ae4 100644 --- a/lib/test_server/src/ts_reports.erl +++ b/lib/test_server/src/ts_reports.erl @@ -1,7 +1,7 @@ %% %% %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 @@ -27,6 +27,8 @@ -include_lib("kernel/include/file.hrl"). -include("ts.hrl"). +-compile({no_auto_import,[error/1]}). + -import(filename, [basename/1, rootname/1]). -import(ts_lib, [error/1]). diff --git a/lib/test_server/src/ts_run.erl b/lib/test_server/src/ts_run.erl index 3461e1383c..888ac98973 100644 --- a/lib/test_server/src/ts_run.erl +++ b/lib/test_server/src/ts_run.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% %% @@ -198,8 +198,6 @@ get_spec_filename_1(Vars, TestDir, File) -> case ts_lib:var(os, Vars) of "VxWorks" -> check_spec_filename(TestDir, File, ".spec.vxworks"); - "OSE" -> - check_spec_filename(TestDir, File, ".spec.ose"); "Windows"++_ -> check_spec_filename(TestDir, File, ".spec.win"); _Other -> @@ -306,53 +304,36 @@ make_make(Vars, Spec, State) -> add_make_testcase(Vars, Spec, St) -> Makefile = St#state.makefile, Dir = filename:dirname(Makefile), - case ts_lib:var(os, Vars) of - "OSE" -> - %% For OSE, C code in datadir must be linked in the image file, - %% and erlang code is sent as binaries from test_server_ctrl - %% Making erlang code here because the Makefile.src probably won't - %% work. - Erl_flags=[{i, "../../test_server"}|ts_lib:var(erl_flags,Vars)], - {ok, Cwd} = file:get_cwd(), - ok = file:set_cwd(Dir), - Result = (catch make:all(Erl_flags)), - ok = file:set_cwd(Cwd), - case Result of - up_to_date -> {ok, Vars, Spec, St}; - _error -> {error, {erlang_make_failed,Dir}} - end; + Shortname = filename:basename(Makefile), + Suite = filename:basename(Dir, "_data"), + Config = [{data_dir,Dir},{makefile,Shortname}], + MakeModule = Suite ++ "_make", + MakeModuleSrc = filename:join(filename:dirname(Dir), + MakeModule ++ ".erl"), + MakeMod = list_to_atom(MakeModule), + case filelib:is_file(MakeModuleSrc) of + true -> ok; + false -> generate_make_module(ts_lib:var(make_command, Vars), + MakeModuleSrc, + MakeModule) + end, + case Suite of + "all_SUITE" -> + {ok,Vars,Spec,St#state{all={MakeMod,Config}}}; _ -> - Shortname = filename:basename(Makefile), - Suite = filename:basename(Dir, "_data"), - Config = [{data_dir,Dir},{makefile,Shortname}], - MakeModule = Suite ++ "_make", - MakeModuleSrc = filename:join(filename:dirname(Dir), - MakeModule ++ ".erl"), - MakeMod = list_to_atom(MakeModule), - case filelib:is_file(MakeModuleSrc) of - true -> ok; - false -> generate_make_module(ts_lib:var(make_command, Vars), - MakeModuleSrc, - MakeModule) - end, - case Suite of - "all_SUITE" -> - {ok,Vars,Spec,St#state{all={MakeMod,Config}}}; - _ -> - %% Avoid duplicates of testcases. There is no longer - %% a check for this in test_server_ctrl. - TestCase = {list_to_atom(Suite),all}, - TopCase0 = case St#state.topcase of - List when is_list(List) -> - List -- [TestCase]; - Top -> - [Top] -- [TestCase] - end, - TopCase = [{make,{MakeMod,make,[Config]}, - TestCase, - {MakeMod,unmake,[Config]}}|TopCase0], - {ok,Vars,Spec,St#state{topcase=TopCase}} - end + %% Avoid duplicates of testcases. There is no longer + %% a check for this in test_server_ctrl. + TestCase = {list_to_atom(Suite),all}, + TopCase0 = case St#state.topcase of + List when is_list(List) -> + List -- [TestCase]; + Top -> + [Top] -- [TestCase] + end, + TopCase = [{make,{MakeMod,make,[Config]}, + TestCase, + {MakeMod,unmake,[Config]}}|TopCase0], + {ok,Vars,Spec,St#state{topcase=TopCase}} end. generate_make_module(MakeCmd, Name, ModuleString) -> @@ -392,7 +373,7 @@ make_test_suite(Vars, _Spec, State) -> {ok, Cwd} = file:get_cwd(), ok = file:set_cwd(TestDir), - Result = (catch make:all(Erl_flags)), + Result = (catch make_all(Erl_flags)), ok = file:set_cwd(Cwd), case Result of up_to_date -> @@ -629,9 +610,6 @@ make_test_server_args(Args0,Options,Vars) -> "VxWorks" -> F = write_parameterfile(vxworks,Vars), " PARAMETERS " ++ F; - "OSE" -> - F = write_parameterfile(ose,Vars), - " PARAMETERS " ++ F; _ -> "" end, @@ -743,4 +721,52 @@ split_one(Path) -> split_path(Path) -> string:tokens(Path,";"). +%% +%% Run make:all/1 if the test suite seems to be designed +%% to be built/re-built by ts. +%% +make_all(Flags) -> + case filelib:is_regular("Emakefile") of + false -> + make_all_no_emakefile(Flags); + true -> + make:all(Flags) + end. +make_all_no_emakefile(Flags) -> + case filelib:wildcard("*.beam") of + [] -> + %% Since there are no *.beam files, we will assume + %% that this test suite was designed to be built and + %% re-built by ts. Create an Emakefile so that + %% make:all/1 will be run the next time too + %% (in case a test suite is being interactively + %% developed). + create_emakefile(Flags, "*.erl"); + [_|_] -> + %% There is no Emakefile and there already are + %% some *.beam files here. Assume that this test + %% suite was not designed to be re-built by ts. + %% Only create a Emakefile that will compile + %% generated *_SUITE_make files (if any). + create_emakefile(Flags, "*_SUITE_make.erl") + end. + +create_emakefile(Flags, Wc) -> + case filelib:wildcard(Wc) of + [] -> + %% There are no files to be built (i.e. not even any + %% generated *_SUITE_make.erl files). We must handle + %% this case specially, because make:all/1 will crash + %% on Emakefile with an empty list of modules. + io:put_chars("No Emakefile found - not running make:all/1\n"), + up_to_date; + [_|_]=Ms0 -> + io:format("Creating an Emakefile for compiling files matching ~s\n", + [Wc]), + Ms = [list_to_atom(filename:rootname(M, ".erl")) || M <- Ms0], + Make0 = {Ms,Flags}, + Make = io_lib:format("~p. \n", [Make0]), + ok = file:write_file("Emakefile", Make), + make:all(Flags) + end. diff --git a/lib/test_server/test/Makefile b/lib/test_server/test/Makefile index 702d73f5af..fcb1282d16 100644 --- a/lib/test_server/test/Makefile +++ b/lib/test_server/test/Makefile @@ -88,7 +88,7 @@ release_spec: opt release_tests_spec: make_emakefile $(INSTALL_DIR) $(RELSYSDIR) $(INSTALL_DATA) $(EMAKEFILE) $(ERL_FILES) $(COVERFILE) $(RELSYSDIR) - $(INSTALL_PROGRAM) test_server.spec $(RELSYSDIR) + $(INSTALL_DATA) test_server.spec $(RELSYSDIR) chmod -f -R u+w $(RELSYSDIR) @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) diff --git a/lib/test_server/test/test_server_SUITE.erl b/lib/test_server/test/test_server_SUITE.erl index dfe1028d3a..0563e1104f 100644 --- a/lib/test_server/test/test_server_SUITE.erl +++ b/lib/test_server/test/test_server_SUITE.erl @@ -183,7 +183,7 @@ multiply_timetrap(suite) -> []; multiply_timetrap(doc) -> ["Test multiply timetrap"]; multiply_timetrap(Config) when is_list(Config) -> %% This simulates the call to test_server_ctrl:multiply_timetraps/1: - put(test_server_multiply_timetraps,2), + put(test_server_multiply_timetraps,{2,true}), Dog = ?t:timetrap(500), timer:sleep(800), diff --git a/lib/test_server/vsn.mk b/lib/test_server/vsn.mk index e3aac682ec..4c3df28814 100644 --- a/lib/test_server/vsn.mk +++ b/lib/test_server/vsn.mk @@ -1,2 +1,2 @@ -TEST_SERVER_VSN = 3.3.6 +TEST_SERVER_VSN = 3.4.1 diff --git a/lib/tools/c_src/Makefile.in b/lib/tools/c_src/Makefile.in index e6b76e2238..65a7f5f424 100644 --- a/lib/tools/c_src/Makefile.in +++ b/lib/tools/c_src/Makefile.in @@ -128,12 +128,13 @@ EMEM_ERTS_LIB=erts_r$(TYPEMARKER) endif +EMEM_ETHR_LIBS=$(subst -l$(ETHR_LIB_NAME),-l$(ETHR_LIB_NAME)$(TYPEMARKER),$(subst -lerts_internal_r,-lerts_internal_r$(TYPEMARKER),$(ETHR_LIBS))) + EMEM_LIBS = $(LIBS) \ -L$(ERL_TOP)/erts/lib/$(TARGET) \ -L$(ERL_TOP)/erts/lib/internal/$(TARGET) \ -l$(EMEM_ERTS_LIB) \ - -l$(ETHR_LIB_NAME)$(TYPEMARKER) \ - $(ETHR_X_LIBS) + $(EMEM_ETHR_LIBS) EMEM_OBJS = $(addprefix $(EMEM_OBJ_DIR)/,$(notdir $(EMEM_SRCS:.c=.o))) diff --git a/lib/tools/c_src/erl_memory.c b/lib/tools/c_src/erl_memory.c index a0e139f059..872d55e789 100644 --- a/lib/tools/c_src/erl_memory.c +++ b/lib/tools/c_src/erl_memory.c @@ -1,22 +1,22 @@ -/* ``The contents of this file are subject to the Erlang Public License, +/* + * %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 via the world wide web at http://www.erlang.org/. - * + * 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. - * - * The Initial Developer of the Original Code is Ericsson Utvecklings AB. - * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings - * AB. All Rights Reserved.'' - * - * $Id$ + * + * %CopyrightEnd% */ - /* * Description: * @@ -281,17 +281,13 @@ mutex_destroy(ethr_mutex *mtx) static INLINE void mutex_lock(ethr_mutex *mtx) { - int res = ethr_mutex_lock(mtx); - if (res) - error_msg(res, "Mutex lock"); + ethr_mutex_lock(mtx); } static INLINE void mutex_unlock(ethr_mutex *mtx) { - int res = ethr_mutex_unlock(mtx); - if (res) - error_msg(res, "Mutex unlock"); + ethr_mutex_unlock(mtx); } static INLINE void @@ -314,16 +310,14 @@ static INLINE void cond_wait(ethr_cond *cnd, ethr_mutex *mtx) { int res = ethr_cond_wait(cnd, mtx); - if (res) + if (res != 0 && res != EINTR) error_msg(res, "Cond wait"); } static INLINE void cond_signal(ethr_cond *cnd) { - int res = ethr_cond_signal(cnd); - if (res) - error_msg(res, "Cond signal"); + ethr_cond_signal(cnd); } @@ -2774,7 +2768,7 @@ main(int argc, char *argv[]) exit(1); } - if (ethr_init(NULL) != 0) { + if (ethr_init(NULL) != 0 || ethr_late_init(NULL) != 0) { fprintf(stderr, "emem: failed to initialize thread package\n"); exit(1); } diff --git a/lib/tools/doc/src/eprof.xml b/lib/tools/doc/src/eprof.xml index ae1033f2d0..6d68c90768 100644 --- a/lib/tools/doc/src/eprof.xml +++ b/lib/tools/doc/src/eprof.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2009</year> + <year>1996</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>eprof</title> @@ -35,8 +35,7 @@ used. The profiling is done using the Erlang trace BIFs. Tracing of local function calls for a specified set of processes is enabled when profiling is begun, and disabled when profiling is stopped.</p> - <p>When using Eprof, expect a significant slowdown in program execution, - in most cases at least 100 percent.</p> + <p>When using Eprof expect a slowdown in program execution.</p> </description> <funcs> <func> @@ -47,15 +46,19 @@ <v>Reason = {already_started,Pid}</v> </type> <desc> - <p>Starts the Eprof server which owns the Eprof internal database.</p> + <p>Starts the Eprof server which holds the internal state of the collected data.</p> </desc> </func> <func> - <name>start_profiling(Rootset) -> profiling | error</name> - <name>profile(Rootset) -> profiling | error</name> + <name>start_profiling(Rootset) -> profiling | {error, Reason}</name> + <name>start_profiling(Rootset,Pattern) -> profiling | {error, Reason}</name> <fsummary>Start profiling.</fsummary> <type> <v>Rootset = [atom() | pid()]</v> + <v>Pattern = {Module, Function, Arity}</v> + <v>Module = Function = atom()</v> + <v>Arity = integer()</v> + <v>Reason = term()</v> </type> <desc> <p>Starts profiling for the processes in <c>Rootset</c> (and any new @@ -64,6 +67,9 @@ <p><c>Rootset</c> is a list of pids and registered names.</p> <p>The function returns <c>profiling</c> if tracing could be enabled for all processes in <c>Rootset</c>, or <c>error</c> otherwise.</p> + <p>A pattern can be selected to narrow the profiling. For instance ca a specific + module be selected and only the code processes executes in that module will be + profiled.</p> </desc> </func> <func> @@ -75,14 +81,20 @@ </desc> </func> <func> - <name>profile(Rootset,Fun) -> {ok,Value} | {error,Reason} | error</name> - <name>profile(Rootset,Module,Function,Args) -> {ok,Value} | {error,Reason} | error</name> + <name>profile(Fun) -> profiling | {error, Reason}</name> + <name>profile(Rootset) -> profiling | {error, Reason}</name> + <name>profile(Rootset,Fun) -> {ok, Value} | {error,Reason}</name> + <name>profile(Rootset,Fun,Pattern) -> {ok, Value} | {error, Reason}</name> + <name>profile(Rootset,Module,Function,Args) -> {ok, Value} | {error, Reason}</name> + <name>profile(Rootset,Module,Function,Args,Pattern) -> {ok, Value} | {error, Reason}</name> <fsummary>Start profiling.</fsummary> <type> <v>Rootset = [atom() | pid()]</v> <v>Fun = fun() -> term()</v> + <v>Pattern = {Module, Function, Arity}</v> <v>Module = Function = atom()</v> <v>Args = [term()]</v> + <v>Arity = integer()</v> <v>Value = Reason = term()</v> </type> <desc> @@ -96,7 +108,7 @@ <c>Rootset</c>, the function returns <c>{ok,Value}</c> when <c>Fun()</c>/<c>apply</c> returns with the value <c>Value</c>, or <c>{error,Reason}</c> if <c>Fun()</c>/<c>apply</c> fails with - exit reason <c>Reason</c>. Otherwise it returns <c>error</c> + exit reason <c>Reason</c>. Otherwise it returns <c>{error, Reason}</c> immediately.</p> <p>The programmer must ensure that the function given as argument is truly synchronous and that no work continues after @@ -104,7 +116,15 @@ </desc> </func> <func> - <name>analyse()</name> + <name>analyze() -> ok</name> + <name>analyze(Type) -> ok</name> + <name>analyze(Type,Options) -> ok</name> + <type> + <v>Type = procs | total</v> + <v>Options = [{filter, Filter} | {sort, Sort}</v> + <v>Filter = [{calls, integer()} | {time, float()}]</v> + <v>Sort = time | calls | mfa</v> + </type> <fsummary>Display profiling results per process.</fsummary> <desc> <p>Call this function when profiling has been stopped to display @@ -113,17 +133,10 @@ <item>how much time has been used by each process, and</item> <item>in which function calls this time has been spent.</item> </list> - <p>Time is shown as percentage of total time, not as absolute time.</p> - </desc> - </func> - <func> - <name>total_analyse()</name> - <fsummary>Display profiling results per function call.</fsummary> - <desc> - <p>Call this function when profiling has been stopped to display + <p>Call <c>analyze</c> with <c>total</c> option when profiling has been stopped to display the results per function call, that is in which function calls the time has been spent.</p> - <p>Time is shown as percentage of total time, not as absolute time.</p> + <p>Time is shown as percentage of total time and as absolute time.</p> </desc> </func> <func> diff --git a/lib/tools/doc/src/erlang_mode.xml b/lib/tools/doc/src/erlang_mode.xml index 912c442153..c21afc1f9b 100644 --- a/lib/tools/doc/src/erlang_mode.xml +++ b/lib/tools/doc/src/erlang_mode.xml @@ -173,7 +173,7 @@ sum(L) -> sum(L, 0). sum([H|T], Sum) -> sum(T, Sum + H); - sum([], Sum) -> Sum."</code> + sum([], Sum) -> Sum.</code> </item> </list> </section> diff --git a/lib/tools/doc/src/erlang_mode_chapter.xml b/lib/tools/doc/src/erlang_mode_chapter.xml index b22c6b1809..8aabd6ae74 100644 --- a/lib/tools/doc/src/erlang_mode_chapter.xml +++ b/lib/tools/doc/src/erlang_mode_chapter.xml @@ -45,7 +45,7 @@ <section> <title>Elisp</title> - <p>There are two Elsip modules include in this tool package + <p>There are two Elisp modules included in this tool package for Emacs. There is erlang.el that defines the actual erlang mode and there is erlang-start.el that makes some nice initializations.</p> </section> diff --git a/lib/tools/doc/src/notes.xml b/lib/tools/doc/src/notes.xml index e7d1ae150c..4a71993da9 100644 --- a/lib/tools/doc/src/notes.xml +++ b/lib/tools/doc/src/notes.xml @@ -30,6 +30,92 @@ </header> <p>This document describes the changes made to the Tools application.</p> +<section><title>Tools 2.6.6.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + <c>cover</c> will now show ampersand characters in the + source code correctly. (Thanks to Tom Moertel.)</p> + <p> + Own Id: OTP-8776</p> + </item> + </list> + </section> + +</section> + +<section><title>Tools 2.6.6</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>A race condition affecting Cover has been removed.</p> + <p> + Own Id: OTP-8469</p> + </item> + <item> + <p> + Emacs improvements:</p> + <p> + Fixed emacs-mode installation problems.</p> + <p> + Fixed a couple of -spec and -type indentation and + font-lock problems.</p> + <p> + Fixed error messages on emacs-21.</p> + <p> + Magnus Henoch fixed several issues.</p> + <p> + Ralf Doering, Klas Johansson and Chris Bernard + contributed various emacs-eunit improvements.</p> + <p> + Klas Johansson and Dave Peticolas added emacs-flymake + support.</p> + <p> + Own Id: OTP-8530</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>Xref has been updated to use the <c>re</c> module + instead of the deprecated <c>regexp</c> module.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-8472</p> + </item> + <item> + <p>When given the option <c>{builtins,true}</c> Xref now + adds calls to operators.</p> + <p> + Own Id: OTP-8647</p> + </item> + <item> + <p><c>eprof</c> has been reimplemented with support in + the Erlang virtual machine and is now both faster (i.e. + slows down the code being measured less) and scales much + better. In measurements we saw speed-ups compared to the + old eprof ranging from 6 times (for sequential code that + only uses one scheduler/core) up to 84 times (for + parallel code that uses 8 cores).</p> + <p>Note: The API for the <c>eprof</c> has been cleaned up + and extended. See the documentation.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-8706</p> + </item> + </list> + </section> + +</section> + <section><title>Tools 2.6.5.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/tools/doc/src/xref.xml b/lib/tools/doc/src/xref.xml index 407a7392ad..75ffa25311 100644 --- a/lib/tools/doc/src/xref.xml +++ b/lib/tools/doc/src/xref.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>2000</year><year>2009</year> + <year>2000</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>xref</title> @@ -239,7 +239,7 @@ represented by <item>RegArity ::= RegString | Number | <c>_</c> | <c>-1</c></item> <item>RegAtom ::= RegString | Atom | <c>_</c></item> <item>RegString ::= - a regular expression, as described in the - <c>regexp</c> module, enclosed in double quotes -</item> + <c>re</c> module, enclosed in double quotes -</item> <item>Type ::= <c>Fun</c> | <c>Mod</c> | <c>App</c> | <c>Rel</c></item> <item>Function ::= Atom</item> <item>Application ::= Atom</item> @@ -264,8 +264,7 @@ represented by Assigning a type to a list or tuple of <c>Constant</c> is equivalent to assigning the type to each <c>Constant</c>. </p> - <p> <marker id="regexp"></marker> -<em>Regular expressions</em> are used as a + <p><marker id="regexp"></marker><em>Regular expressions</em> are used as a means to select some of the vertices of a graph. A <c>RegExpr</c> consisting of a <c>RegString</c> and a type - an example is <c>"xref_.*" : Mod</c> - is interpreted as those @@ -1546,8 +1545,11 @@ Evaluates a predefined analysis. </funcs> <section> - <title>See Also</title> - <p>beam_lib(3), digraph(3), digraph_utils(3), regexp(3), + <title>See Also</title><p> + <seealso marker="stdlib:beam_lib">beam_lib(3)</seealso>, + <seealso marker="stdlib:digraph">digraph(3)</seealso>, + <seealso marker="stdlib:digraph_utils">digraph_utils(3)</seealso>, + <seealso marker="stdlib:re">re(3)</seealso>, <seealso marker="xref_chapter">TOOLS User's Guide</seealso></p> </section> </erlref> diff --git a/lib/tools/emacs/Makefile b/lib/tools/emacs/Makefile index 7249263992..8533488463 100644 --- a/lib/tools/emacs/Makefile +++ b/lib/tools/emacs/Makefile @@ -37,8 +37,12 @@ MAN_FILES= \ tags.3 EMACS_FILES= \ + erlang-skels \ + erlang-skels-old \ + erlang_appwiz \ erlang-start \ erlang-eunit \ + erlang-flymake \ erlang README_FILES= README diff --git a/lib/tools/emacs/README b/lib/tools/emacs/README index ca068d04c4..cc107dcd41 100644 --- a/lib/tools/emacs/README +++ b/lib/tools/emacs/README @@ -42,7 +42,14 @@ Files\erl-<Ver>: (setq erlang-root-dir "C:/Program Files/erl<Ver>") (setq exec-path (cons "C:/Program Files/erl<Ver>/bin" exec-path)) (require 'erlang-start) - +Miscellaneous addons +-------------------- + +In order to check erlang source code on the fly, add the following +line to your .emacs file (after erlang-start, see above). See +erlang-flymake.el for more information on how to customize the syntax +check. + (require 'erlang-flymake) diff --git a/lib/tools/emacs/erlang-eunit.el b/lib/tools/emacs/erlang-eunit.el index 05528aee6d..f2c0db67dd 100644 --- a/lib/tools/emacs/erlang-eunit.el +++ b/lib/tools/emacs/erlang-eunit.el @@ -1,27 +1,44 @@ ;; ;; %CopyrightBegin% -;; -;; Copyright Ericsson AB 2009. All Rights Reserved. -;; +;; +;; 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% ;;; ;;; Purpose: Provide EUnit utilities. ;;; ;;; Author: Klas Johansson -(defvar erlang-eunit-separate-src-and-test-directories t - "*Whether or not to keep source and EUnit test files in separate directories") +(eval-when-compile + (require 'cl)) + +(defvar erlang-eunit-src-candidate-dirs '("../src" ".") + "*Name of directories which to search for source files matching +an EUnit test file. The first directory in the list will be used, +if there is no match.") + +(defvar erlang-eunit-test-candidate-dirs '("../test" ".") + "*Name of directories which to search for EUnit test files matching +a source file. The first directory in the list will be used, +if there is no match.") + +(defvar erlang-eunit-autosave nil + "*Set to non-nil to automtically save unsaved buffers before running tests. +This is useful, reducing the save-compile-load-test cycle to one keychord.") + +(defvar erlang-eunit-recent-info '((mode . nil) (module . nil) (test . nil) (cover . nil)) + "Info about the most recent running of an EUnit test representation.") ;;; ;;; Switch between src/EUnit test buffers @@ -41,7 +58,6 @@ buffer and vice versa" "Open the EUnit test file which corresponds to a src file" (find-file-other-window (erlang-eunit-test-filename src-file-path))) - ;;; ;;; Open the src file which corresponds to the an EUnit test file ;;; @@ -52,37 +68,55 @@ buffer and vice versa" ;;; Return the name and path of the EUnit test file ;;, (input may be either the source filename itself or the EUnit test filename) (defun erlang-eunit-test-filename (file-path) - (erlang-eunit-rewrite-filename file-path "test" "_tests")) + (if (erlang-eunit-test-file-p file-path) + file-path + (erlang-eunit-rewrite-filename file-path erlang-eunit-test-candidate-dirs))) ;;; Return the name and path of the source file ;;, (input may be either the source filename itself or the EUnit test filename) (defun erlang-eunit-src-filename (file-path) - (erlang-eunit-rewrite-filename file-path "src" "")) + (if (erlang-eunit-src-file-p file-path) + file-path + (erlang-eunit-rewrite-filename file-path erlang-eunit-src-candidate-dirs))) ;;; Rewrite a filename from the src or test filename to the other -(defun erlang-eunit-rewrite-filename (orig-file-path dest-dirname dest-suffix) - (let* ((root-dir-name (erlang-eunit-file-root-dir-name orig-file-path)) - (src-module-name (erlang-eunit-source-module-name orig-file-path)) - (dest-base-name (concat src-module-name dest-suffix ".erl")) - (dest-dir-name-1 (file-name-directory orig-file-path)) - (dest-dir-name-2 (filename-join root-dir-name dest-dirname)) - (dest-file-name-1 (filename-join dest-dir-name-1 dest-base-name)) - (dest-file-name-2 (filename-join dest-dir-name-2 dest-base-name))) - ;; This function tries to be a bit intelligent: - ;; * if there already is a test (or source) file in the same - ;; directory as a source (or test) file, it'll be picked - ;; * if there already is a test (or source) file in a separate - ;; test (or src) directory, it'll be picked - ;; * otherwise it'll resort to whatever alternative (same or - ;; separate directories) that the user has chosen - (cond ((file-readable-p dest-file-name-1) - dest-file-name-1) - ((file-readable-p dest-file-name-2) - dest-file-name-2) - (erlang-eunit-separate-src-and-test-directories - dest-file-name-2) - (t - dest-file-name-1)))) +(defun erlang-eunit-rewrite-filename (orig-file-path candidate-dirs) + (or (erlang-eunit-locate-buddy orig-file-path candidate-dirs) + (erlang-eunit-buddy-file-path orig-file-path (car candidate-dirs)))) + +;;; Search for a file's buddy file (a source file's EUnit test file, +;;; or an EUnit test file's source file) in a list of candidate +;;; directories. +(defun erlang-eunit-locate-buddy (orig-file-path candidate-dirs) + (when candidate-dirs + (let ((buddy-file-path (erlang-eunit-buddy-file-path + orig-file-path + (car candidate-dirs)))) + (if (file-readable-p buddy-file-path) + buddy-file-path + (erlang-eunit-locate-buddy orig-file-path (cdr candidate-dirs)))))) + +(defun erlang-eunit-buddy-file-path (orig-file-path buddy-dir-name) + (let* ((orig-dir-name (file-name-directory orig-file-path)) + (buddy-dir-name (file-truename + (filename-join orig-dir-name buddy-dir-name))) + (buddy-base-name (erlang-eunit-buddy-basename orig-file-path))) + (filename-join buddy-dir-name buddy-base-name))) + +;;; Return the basename of the buddy file: +;;; /tmp/foo/src/x.erl --> x_tests.erl +;;; /tmp/foo/test/x_tests.erl --> x.erl +(defun erlang-eunit-buddy-basename (file-path) + (let ((src-module-name (erlang-eunit-source-module-name file-path))) + (cond + ((erlang-eunit-src-file-p file-path) + (concat src-module-name "_tests.erl")) + ((erlang-eunit-test-file-p file-path) + (concat src-module-name ".erl"))))) + +;;; Checks whether a file is a source file or not +(defun erlang-eunit-src-file-p (file-path) + (not (erlang-eunit-test-file-p file-path))) ;;; Checks whether a file is a EUnit test file or not (defun erlang-eunit-test-file-p (file-path) @@ -93,23 +127,17 @@ buffer and vice versa" ;;; /tmp/foo/test/x_tests.erl --> x (defun erlang-eunit-source-module-name (file-path) (interactive) - (let* ((file-name (file-name-nondirectory file-path)) - (base-name (file-name-sans-extension file-name))) - (if (string-match "^\\(.+\\)_tests$" base-name) - (substring base-name (match-beginning 1) (match-end 1)) - base-name))) - -;;; Return the directory name which is common to both src and test -;;; /tmp/foo/src/x.erl --> /tmp/foo -;;; /tmp/foo/test/x_tests.erl --> /tmp/foo -(defun erlang-eunit-file-root-dir-name (file-path) - (erlang-eunit-dir-parent-dirname (file-name-directory file-path))) - -;;; Return the parent directory name of a directory -;;; /tmp/foo/ --> /tmp -;;; /tmp/foo --> /tmp -(defun erlang-eunit-dir-parent-dirname (dir-name) - (file-name-directory (directory-file-name dir-name))) + (let ((module-name (erlang-eunit-module-name file-path))) + (if (string-match "^\\(.+\\)_tests$" module-name) + (substring module-name (match-beginning 1) (match-end 1)) + module-name))) + +;;; Return the module name of the file +;;; /tmp/foo/src/x.erl --> x +;;; /tmp/foo/test/x_tests.erl --> x_tests +(defun erlang-eunit-module-name (file-path) + (interactive) + (file-name-sans-extension (file-name-nondirectory file-path))) ;;; Older emacsen don't have string-match-p. (defun erlang-eunit-string-match-p (regexp string &optional start) @@ -125,25 +153,158 @@ buffer and vice versa" (concat dir file) (concat dir "/" file))) +;;; Get info about the most recent running of EUnit +(defun erlang-eunit-recent (key) + (cdr (assq key erlang-eunit-recent-info))) + +;;; Record info about the most recent running of EUnit +;;; Known modes are 'module-mode and 'test-mode +(defun erlang-eunit-record-recent (mode module test) + (setcdr (assq 'mode erlang-eunit-recent-info) mode) + (setcdr (assq 'module erlang-eunit-recent-info) module) + (setcdr (assq 'test erlang-eunit-recent-info) test)) + +;;; Record whether the most recent running of EUnit included cover +;;; compilation +(defun erlang-eunit-record-recent-compile (under-cover) + (setcdr (assq 'cover erlang-eunit-recent-info) under-cover)) + +;;; Determine options for EUnit. +(defun erlang-eunit-opts () + (if current-prefix-arg ", [verbose]" "")) + +;;; Determine current test function +(defun erlang-eunit-current-test () + (save-excursion + (erlang-end-of-function 1) + (erlang-beginning-of-function 1) + (erlang-name-of-function))) + +(defun erlang-eunit-simple-test-p (test-name) + (if (erlang-eunit-string-match-p "^\\(.+\\)_test$" test-name) t nil)) + +(defun erlang-eunit-test-generator-p (test-name) + (if (erlang-eunit-string-match-p "^\\(.+\\)_test_$" test-name) t nil)) + +;;; Run one EUnit test +(defun erlang-eunit-run-test (module-name test-name) + (let ((command + (cond ((erlang-eunit-simple-test-p test-name) + (format "eunit:test({%s, %s}%s)." + module-name test-name (erlang-eunit-opts))) + ((erlang-eunit-test-generator-p test-name) + (format "eunit:test({generator, %s, %s}%s)." + module-name test-name (erlang-eunit-opts))) + (t (format "%% WARNING: '%s' is not a test function" test-name))))) + (erlang-eunit-record-recent 'test-mode module-name test-name) + (erlang-eunit-inferior-erlang-send-command command))) + ;;; Run EUnit tests for the current module -(defun erlang-eunit-run-tests () - "Run the EUnit test suite for the current module. +(defun erlang-eunit-run-module-tests (module-name) + (let ((command (format "eunit:test(%s%s)." module-name (erlang-eunit-opts)))) + (erlang-eunit-record-recent 'module-mode module-name nil) + (erlang-eunit-inferior-erlang-send-command command))) -With prefix arg, runs tests with the verbose flag set." +(defun erlang-eunit-compile-and-run-recent () + "Compile the source and test files and repeat the most recent EUnit test run. + +With prefix arg, compiles for debug and runs tests with the verbose flag set." (interactive) - (let* ((module-name (erlang-add-quotes-if-needed - (erlang-eunit-source-module-name buffer-file-name))) - (opts (if current-prefix-arg ", [verbose]" "")) - (command (format "eunit:test(%s%s)." module-name opts))) - (erlang-eunit-inferior-erlang-send-command command))) + (case (erlang-eunit-recent 'mode) + ('test-mode + (erlang-eunit-compile-and-test + 'erlang-eunit-run-test (list (erlang-eunit-recent 'module) + (erlang-eunit-recent 'test)))) + ('module-mode + (erlang-eunit-compile-and-test + 'erlang-eunit-run-module-tests (list (erlang-eunit-recent 'module)) + (erlang-eunit-recent 'cover))) + (t (error "EUnit has not yet been run. Please run a test first.")))) + +(defun erlang-eunit-cover-compile () + "Cover compile current module." + (interactive) + (let* ((erlang-compile-extra-opts + (append (list 'debug_info) erlang-compile-extra-opts)) + (module-name + (erlang-add-quotes-if-needed + (erlang-eunit-module-name buffer-file-name))) + (compile-command + (format "cover:compile_beam(%s)." module-name))) + (erlang-compile) + (if (erlang-eunit-last-compilation-successful-p) + (erlang-eunit-inferior-erlang-send-command compile-command)))) + +(defun erlang-eunit-analyze-coverage () + "Analyze the data collected by cover tool for the module in the +current buffer. + +Assumes that the module has been cover compiled prior to this +call. This function will do two things: print the number of +covered and uncovered functions in the erlang shell and display a +new buffer called *<module name> coverage* which shows the source +code along with the coverage analysis results." + (interactive) + (let* ((module-name (erlang-add-quotes-if-needed + (erlang-eunit-module-name buffer-file-name))) + (tmp-filename (make-temp-file "cover")) + (analyze-command (format "cover:analyze_to_file(%s, \"%s\"). " + module-name tmp-filename)) + (buf-name (format "*%s coverage*" module-name))) + (erlang-eunit-inferior-erlang-send-command analyze-command) + ;; The purpose of the following snippet is to get the result of the + ;; analysis from a file into a new buffer (or an old, if one with + ;; the specified name already exists). Also we want the erlang-mode + ;; *and* view-mode to be enabled. + (save-excursion + (let ((buf (get-buffer-create (format "*%s coverage*" module-name)))) + (set-buffer buf) + (setq buffer-read-only nil) + (insert-file-contents tmp-filename nil nil nil t) + (if (= (buffer-size) 0) + (kill-buffer buf) + ;; FIXME: this would be a good place to enable (emacs-mode) + ;; to get some nice syntax highlighting in the + ;; coverage report, but it doesn't play well with + ;; flymake. Leave it off for now. + (view-buffer buf)))) + (delete-file tmp-filename))) + +(defun erlang-eunit-compile-and-run-current-test () + "Compile the source and test files and run the current EUnit test. -;;; Compile source and EUnit test file and finally run EUnit tests for -;;; the current module -(defun erlang-eunit-compile-and-run-tests () - "Compile the source and test files and run the EUnit test suite. +With prefix arg, compiles for debug and runs tests with the verbose flag set." + (interactive) + (let ((module-name (erlang-add-quotes-if-needed + (erlang-eunit-module-name buffer-file-name))) + (test-name (erlang-eunit-current-test))) + (erlang-eunit-compile-and-test + 'erlang-eunit-run-test (list module-name test-name)))) + +(defun erlang-eunit-compile-and-run-module-tests () + "Compile the source and test files and run all EUnit tests in the module. With prefix arg, compiles for debug and runs tests with the verbose flag set." (interactive) + (let ((module-name (erlang-add-quotes-if-needed + (erlang-eunit-source-module-name buffer-file-name)))) + (erlang-eunit-compile-and-test + 'erlang-eunit-run-module-tests (list module-name)))) + +;;; Compile source and EUnit test file and finally run EUnit tests for +;;; the current module +(defun erlang-eunit-compile-and-test (test-fun test-args &optional under-cover) + "Compile the source and test files and run the EUnit test suite. + +If under-cover is set to t, the module under test is compile for +code coverage analysis. If under-cover is left out or not set, +coverage analysis is disabled. The result of the code coverage +is both printed to the erlang shell (the number of covered vs +uncovered functions in a module) and written to a buffer called +*<module> coverage* (which shows the source code for the module +and the number of times each line is covered). +With prefix arg, compiles for debug and runs tests with the verbose flag set." + (erlang-eunit-record-recent-compile under-cover) (let ((src-filename (erlang-eunit-src-filename buffer-file-name)) (test-filename (erlang-eunit-test-filename buffer-file-name))) @@ -151,7 +312,7 @@ With prefix arg, compiles for debug and runs tests with the verbose flag set." ;; below, is to ask the question about saving buffers only once, ;; instead of possibly several: one for each file to compile, ;; for instance for both x.erl and x_tests.erl. - (save-some-buffers) + (save-some-buffers erlang-eunit-autosave) (flet ((save-some-buffers (&optional any) nil)) ;; Compilation of the source file is mandatory (the file must @@ -159,23 +320,56 @@ With prefix arg, compiles for debug and runs tests with the verbose flag set." ;; test file on the other hand, is optional, since eunit tests may ;; be placed in the source file instead. Any compilation error ;; will prevent the subsequent steps to be run (hence the `and') - (and (erlang-eunit-compile-file src-filename) + (and (erlang-eunit-compile-file src-filename under-cover) (if (file-readable-p test-filename) (erlang-eunit-compile-file test-filename) t) - (erlang-eunit-run-tests))))) + (apply test-fun test-args) + (if under-cover + (save-excursion + (set-buffer (find-file-noselect src-filename)) + (erlang-eunit-analyze-coverage))))))) + +(defun erlang-eunit-compile-and-run-module-tests-under-cover () + "Compile the source and test files and run the EUnit test suite and measure +code coverage. -(defun erlang-eunit-compile-file (file-path) +With prefix arg, compiles for debug and runs tests with the verbose flag set." + (interactive) + (let ((module-name (erlang-add-quotes-if-needed + (erlang-eunit-source-module-name buffer-file-name)))) + (erlang-eunit-compile-and-test + 'erlang-eunit-run-module-tests (list module-name) t))) + +(defun erlang-eunit-compile-file (file-path &optional under-cover) (if (file-readable-p file-path) (save-excursion - (set-buffer (find-file-noselect file-path)) - (erlang-compile) - (erlang-eunit-last-compilation-successful-p)) + (set-buffer (find-file-noselect file-path)) + ;; In order to run a code coverage analysis on a + ;; module, we have two options: + ;; + ;; * either compile the module with cover:compile instead of the + ;; regular compiler + ;; + ;; * or first compile the module with the regular compiler (but + ;; *with* debug_info) and then compile it for coverage + ;; analysis using cover:compile_beam. + ;; + ;; We could accomplish the first by changing the + ;; erlang-compile-erlang-function to cover:compile, but there's + ;; a risk that that's used for other purposes. Therefore, a + ;; safer alternative (although with more steps) is to add + ;; debug_info to the list of compiler options and go for the + ;; second alternative. + (if under-cover + (erlang-eunit-cover-compile) + (erlang-compile)) + (erlang-eunit-last-compilation-successful-p)) (let ((msg (format "Could not read %s" file-path))) - (erlang-eunit-inferior-erlang-send-command + (erlang-eunit-inferior-erlang-send-command (format "%% WARNING: %s" msg)) (error msg)))) - + (defun erlang-eunit-last-compilation-successful-p () (save-excursion (set-buffer inferior-erlang-buffer) @@ -184,7 +378,7 @@ With prefix arg, compiles for debug and runs tests with the verbose flag set." (lambda (re) (let ((continue t) (result t)) (while continue ; ignore warnings, stop at errors - (if (re-search-forward re (point-max) t) + (if (re-search-forward re (point-max) t) (if (erlang-eunit-is-compilation-warning) t (setq result nil) @@ -195,7 +389,7 @@ With prefix arg, compiles for debug and runs tests with the verbose flag set." (mapcar (lambda (e) (car e)) erlang-error-regexp-alist)))) (defun erlang-eunit-is-compilation-warning () - (erlang-eunit-string-match-p + (erlang-eunit-string-match-p "[0-9]+: Warning:" (buffer-substring (line-beginning-position) (line-end-position)))) @@ -221,22 +415,22 @@ With prefix arg, compiles for debug and runs tests with the verbose flag set." ;;; Key bindings ;;;==================================================================== -(defvar erlang-eunit-toggle-src-and-test-file-other-window-key "\C-c\C-et" - "*Key to which the `erlang-eunit-toggle-src-and-test-file-other-window' -function will be bound.") -(defvar erlang-eunit-compile-and-run-tests-key "\C-c\C-ek" - "*Key to which the `erlang-eunit-compile-and-run-tests' -function will be bound.") +(defconst erlang-eunit-key-bindings + '(("\C-c\C-et" erlang-eunit-toggle-src-and-test-file-other-window) + ("\C-c\C-ek" erlang-eunit-compile-and-run-module-tests) + ("\C-c\C-ej" erlang-eunit-compile-and-run-current-test) + ("\C-c\C-el" erlang-eunit-compile-and-run-recent) + ("\C-c\C-ec" erlang-eunit-compile-and-run-module-tests-under-cover) + ("\C-c\C-ev" erlang-eunit-cover-compile) + ("\C-c\C-ea" erlang-eunit-analyze-coverage))) (defun erlang-eunit-add-key-bindings () - (erlang-eunit-ensure-keymap-for-key - erlang-eunit-toggle-src-and-test-file-other-window-key) - (local-set-key erlang-eunit-toggle-src-and-test-file-other-window-key - 'erlang-eunit-toggle-src-and-test-file-other-window) - (erlang-eunit-ensure-keymap-for-key - erlang-eunit-compile-and-run-tests-key) - (local-set-key erlang-eunit-compile-and-run-tests-key - 'erlang-eunit-compile-and-run-tests)) + (dolist (binding erlang-eunit-key-bindings) + (erlang-eunit-bind-key (car binding) (cadr binding)))) + +(defun erlang-eunit-bind-key (key function) + (erlang-eunit-ensure-keymap-for-key key) + (local-set-key key function)) (defun erlang-eunit-ensure-keymap-for-key (key-seq) (let ((prefix-keys (butlast (append key-seq nil))) diff --git a/lib/tools/emacs/erlang-flymake.el b/lib/tools/emacs/erlang-flymake.el new file mode 100644 index 0000000000..bc368e9454 --- /dev/null +++ b/lib/tools/emacs/erlang-flymake.el @@ -0,0 +1,102 @@ +;; erlang-flymake.el +;; +;; Syntax check erlang source code on the fly (integrates with flymake). +;; +;; Start using flymake with erlang by putting the following somewhere +;; in your .emacs file: +;; +;; (require 'erlang-flymake) +;; +;; Flymake is rather eager and does its syntax checks frequently by +;; default and if you are bothered by this, you might want to put the +;; following in your .emacs as well: +;; +;; (erlang-flymake-only-on-save) +;; +;; There are a couple of variables which control the compilation options: +;; * erlang-flymake-get-code-path-dirs-function +;; * erlang-flymake-get-include-dirs-function +;; * erlang-flymake-extra-opts +;; +;; This code is inspired by http://www.emacswiki.org/emacs/FlymakeErlang. + +(require 'flymake) +(eval-when-compile + (require 'cl)) + +(defvar erlang-flymake-command + "erlc" + "The command that will be used to perform the syntax check") + +(defvar erlang-flymake-get-code-path-dirs-function + 'erlang-flymake-get-code-path-dirs + "Return a list of ebin directories to add to the code path.") + +(defvar erlang-flymake-get-include-dirs-function + 'erlang-flymake-get-include-dirs + "Return a list of include directories to add to the compiler options.") + +(defvar erlang-flymake-extra-opts + (list "+warn_obsolete_guard" + "+warn_unused_import" + "+warn_shadow_vars" + "+warn_export_vars" + "+strong_validation" + "+report") + "A list of options that will be passed to the compiler") + +(defun erlang-flymake-only-on-save () + "Trigger flymake only when the buffer is saved (disables syntax +check on newline and when there are no changes)." + (interactive) + ;; There doesn't seem to be a way of disabling this; set to the + ;; largest int available as a workaround (most-positive-fixnum + ;; equates to 8.5 years on my machine, so it ought to be enough ;-) ) + (setq flymake-no-changes-timeout most-positive-fixnum) + (setq flymake-start-syntax-check-on-newline nil)) + + +(defun erlang-flymake-get-code-path-dirs () + (list (concat (erlang-flymake-get-app-dir) "ebin"))) + +(defun erlang-flymake-get-include-dirs () + (list (concat (erlang-flymake-get-app-dir) "include"))) + +(defun erlang-flymake-get-app-dir () + (let ((src-path (file-name-directory (buffer-file-name)))) + (file-name-directory (directory-file-name src-path)))) + +(defun erlang-flymake-init () + (let* ((temp-file + (flet ((flymake-get-temp-dir () (erlang-flymake-temp-dir))) + (flymake-init-create-temp-buffer-copy + 'flymake-create-temp-with-folder-structure))) + (code-dir-opts + (erlang-flymake-flatten + (mapcar (lambda (dir) (list "-pa" dir)) + (funcall erlang-flymake-get-code-path-dirs-function)))) + (inc-dir-opts + (erlang-flymake-flatten + (mapcar (lambda (dir) (list "-I" dir)) + (funcall erlang-flymake-get-include-dirs-function)))) + (compile-opts + (append inc-dir-opts + code-dir-opts + erlang-flymake-extra-opts))) + (list erlang-flymake-command (append compile-opts (list temp-file))))) + +(defun erlang-flymake-temp-dir () + ;; Squeeze the user's name in there in order to make sure that files + ;; for two users who are working on the same computer (like a linux + ;; box) don't collide + (format "%s/flymake-%s" temporary-file-directory user-login-name)) + +(defun erlang-flymake-flatten (list) + (apply #'append list)) + +(add-to-list 'flymake-allowed-file-name-masks + '("\\.erl\\'" erlang-flymake-init)) +(add-hook 'erlang-mode-hook 'flymake-mode) + +(provide 'erlang-flymake) +;; erlang-flymake ends here diff --git a/lib/tools/emacs/erlang-start.el b/lib/tools/emacs/erlang-start.el index 542e81f24c..bbcea3e46a 100644 --- a/lib/tools/emacs/erlang-start.el +++ b/lib/tools/emacs/erlang-start.el @@ -90,6 +90,11 @@ (or (assoc (car b) auto-mode-alist) (setq auto-mode-alist (cons b auto-mode-alist)))) +;; +;; Associate files using interpreter "escript" with Erlang mode. +;; + +(add-to-list 'interpreter-mode-alist (cons "escript" 'erlang-mode)) ;; ;; Ignore files ending in ".jam", ".vee", and ".beam" when performing diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el index da586ee09a..91acfdf2b6 100644 --- a/lib/tools/emacs/erlang.el +++ b/lib/tools/emacs/erlang.el @@ -659,24 +659,30 @@ resulting regexp is surrounded by \\_< and \\_>." (eval-and-compile (defconst erlang-guards-regexp (erlang-regexp-opt erlang-guards 'symbols))) - (eval-and-compile (defvar erlang-predefined-types '("any" "arity" + "boolean" "byte" "char" "cons" "deep_string" + "iolist" "maybe_improper_list" + "module" "mfa" "nil" + "neg_integer" "none" "non_neg_integer" "nonempty_list" "nonempty_improper_list" "nonempty_maybe_improper_list" + "no_return" + "pos_integer" "string" + "term" "timeout") "Erlang type specs types")) @@ -885,15 +891,54 @@ files written in other languages than Erlang.") If nil, the inferior shell replaces the window. This is the traditional behaviour.") -(defvar erlang-mode-map nil +(defconst inferior-erlang-use-cmm (boundp 'minor-mode-overriding-map-alist) + "Non-nil means use `compilation-minor-mode' in Erlang shell.") + +(defvar erlang-mode-map + (let ((map (make-sparse-keymap))) + (unless (boundp 'indent-line-function) + (define-key map "\t" 'erlang-indent-command)) + (define-key map ";" 'erlang-electric-semicolon) + (define-key map "," 'erlang-electric-comma) + (define-key map "<" 'erlang-electric-lt) + (define-key map ">" 'erlang-electric-gt) + (define-key map "\C-m" 'erlang-electric-newline) + (if (not (boundp 'delete-key-deletes-forward)) + (define-key map "\177" 'backward-delete-char-untabify) + (define-key map [(backspace)] 'backward-delete-char-untabify)) + ;;(unless (boundp 'fill-paragraph-function) + (define-key map "\M-q" 'erlang-fill-paragraph) + (unless (boundp 'beginning-of-defun-function) + (define-key map "\M-\C-a" 'erlang-beginning-of-function) + (define-key map "\M-\C-e" 'erlang-end-of-function) + (define-key map '(meta control h) 'erlang-mark-function)) ; Xemacs + (define-key map "\M-\t" 'erlang-complete-tag) + (define-key map "\C-c\M-\t" 'tempo-complete-tag) + (define-key map "\M-+" 'erlang-find-next-tag) + (define-key map "\C-c\M-a" 'erlang-beginning-of-clause) + (define-key map "\C-c\M-b" 'tempo-backward-mark) + (define-key map "\C-c\M-e" 'erlang-end-of-clause) + (define-key map "\C-c\M-f" 'tempo-forward-mark) + (define-key map "\C-c\M-h" 'erlang-mark-clause) + (define-key map "\C-c\C-c" 'comment-region) + (define-key map "\C-c\C-j" 'erlang-generate-new-clause) + (define-key map "\C-c\C-k" 'erlang-compile) + (define-key map "\C-c\C-l" 'erlang-compile-display) + (define-key map "\C-c\C-s" 'erlang-show-syntactic-information) + (define-key map "\C-c\C-q" 'erlang-indent-function) + (define-key map "\C-c\C-u" 'erlang-uncomment-region) + (define-key map "\C-c\C-y" 'erlang-clone-arguments) + (define-key map "\C-c\C-a" 'erlang-align-arrows) + (define-key map "\C-c\C-z" 'erlang-shell-display) + (unless inferior-erlang-use-cmm + (define-key map "\C-x`" 'erlang-next-error)) + map) "*Keymap used in Erlang mode.") (defvar erlang-mode-abbrev-table nil "Abbrev table in use in Erlang-mode buffers.") (defvar erlang-mode-syntax-table nil "Syntax table in use in Erlang-mode buffers.") -(defconst inferior-erlang-use-cmm (boundp 'minor-mode-overriding-map-alist) - "Non-nil means use `compilation-minor-mode' in Erlang shell.") (defvar erlang-skel-file "erlang-skels" @@ -988,7 +1033,7 @@ behaviour.") (list (concat "^\\(-" erlang-atom-regexp "\\)\\(\\s-\\|\\.\\|(\\)") 1 (if (boundp 'font-lock-preprocessor-face) 'font-lock-preprocessor-face - 'font-lock-function-name-face))) + 'font-lock-constant-face))) "Font lock keyword highlighting attributes.") (defvar erlang-font-lock-keywords-quotes @@ -1019,10 +1064,12 @@ are highlighted by syntactic analysis.") (list (list (concat "?\\s-*\\(" erlang-atom-regexp "\\|" erlang-variable-regexp "\\)") - 1 'font-lock-type-face) + 1 'font-lock-constant-face) (list (concat "^\\(-\\(?:define\\|ifn?def\\)\\)\\s-*(\\s-*\\(" erlang-atom-regexp "\\|" erlang-variable-regexp "\\)") - (list 1 'font-lock-preprocessor-face t) + (if (boundp 'font-lock-preprocessor-face) + (list 1 'font-lock-preprocessor-face t) + (list 1 'font-lock-constant-face t)) (list 3 'font-lock-type-face t t)) (list "^-e\\(lse\\|ndif\\)\\>" 0 'font-lock-preprocessor-face t)) "Font lock keyword highlighting macros. @@ -1245,7 +1292,7 @@ Other commands: (setq major-mode 'erlang-mode) (setq mode-name "Erlang") (erlang-syntax-table-init) - (erlang-keymap-init) + (use-local-map erlang-mode-map) (erlang-electric-init) (erlang-menu-init) (erlang-mode-variables) @@ -1300,53 +1347,6 @@ Other commands: (set-syntax-table erlang-mode-syntax-table)) -(defun erlang-keymap-init () - (if erlang-mode-map - nil - (setq erlang-mode-map (make-sparse-keymap)) - (erlang-mode-commands erlang-mode-map)) - (use-local-map erlang-mode-map)) - - -(defun erlang-mode-commands (map) - (unless (boundp 'indent-line-function) - (define-key map "\t" 'erlang-indent-command)) - (define-key map ";" 'erlang-electric-semicolon) - (define-key map "," 'erlang-electric-comma) - (define-key map "<" 'erlang-electric-lt) - (define-key map ">" 'erlang-electric-gt) - (define-key map "\C-m" 'erlang-electric-newline) - (if (not (boundp 'delete-key-deletes-forward)) - (define-key map "\177" 'backward-delete-char-untabify) - (define-key map [(backspace)] 'backward-delete-char-untabify)) - ;;(unless (boundp 'fill-paragraph-function) - (define-key map "\M-q" 'erlang-fill-paragraph) - (unless (boundp 'beginning-of-defun-function) - (define-key map "\M-\C-a" 'erlang-beginning-of-function) - (define-key map "\M-\C-e" 'erlang-end-of-function) - (define-key map '(meta control h) 'erlang-mark-function)) ; Xemacs - (define-key map "\M-\t" 'erlang-complete-tag) - (define-key map "\C-c\M-\t" 'tempo-complete-tag) - (define-key map "\M-+" 'erlang-find-next-tag) - (define-key map "\C-c\M-a" 'erlang-beginning-of-clause) - (define-key map "\C-c\M-b" 'tempo-backward-mark) - (define-key map "\C-c\M-e" 'erlang-end-of-clause) - (define-key map "\C-c\M-f" 'tempo-forward-mark) - (define-key map "\C-c\M-h" 'erlang-mark-clause) - (define-key map "\C-c\C-c" 'comment-region) - (define-key map "\C-c\C-j" 'erlang-generate-new-clause) - (define-key map "\C-c\C-k" 'erlang-compile) - (define-key map "\C-c\C-l" 'erlang-compile-display) - (define-key map "\C-c\C-s" 'erlang-show-syntactic-information) - (define-key map "\C-c\C-q" 'erlang-indent-function) - (define-key map "\C-c\C-u" 'erlang-uncomment-region) - (define-key map "\C-c\C-y" 'erlang-clone-arguments) - (define-key map "\C-c\C-a" 'erlang-align-arrows) - (define-key map "\C-c\C-z" 'erlang-shell-display) - (unless inferior-erlang-use-cmm - (define-key map "\C-x`" 'erlang-next-error))) - - (defun erlang-electric-init () ;; Set up electric character functions to work with ;; delsel/pending-del mode. Also, set up text properties for bit @@ -1400,7 +1400,7 @@ Other commands: (set (make-local-variable 'imenu-prev-index-position-function) 'erlang-beginning-of-function) (set (make-local-variable 'imenu-extract-index-name-function) - 'erlang-get-function-name) + 'erlang-get-function-name-and-arity) (set (make-local-variable 'tempo-match-finder) "[^-a-zA-Z0-9_]\\([-a-zA-Z0-9_]*\\)\\=") (set (make-local-variable 'beginning-of-defun-function) @@ -2490,9 +2490,10 @@ Value is list (stack token-start token-type in-what)." ((looking-at "\\(of\\)[^_a-zA-Z0-9]") ;; Must handle separately, try X of -> catch (if (and stack (eq (car (car stack)) 'try)) - (let ((try-column (nth 2 (car stack)))) + (let ((try-column (nth 2 (car stack))) + (try-pos (nth 1 (car stack)))) (erlang-pop stack) - (erlang-push (list 'icr token try-column) stack)))) + (erlang-push (list 'icr try-pos try-column) stack)))) ((looking-at "\\(fun\\)[^_a-zA-Z0-9]") ;; Push a new layer if we are defining a `fun' @@ -2653,7 +2654,8 @@ Value is list (stack token-start token-type in-what)." (cond ((eq (car (car stack)) '\() (erlang-pop stack) (if (and (eq (car (car stack)) 'fun) - (eq (car (car (cdr stack))) '::)) + (or (eq (car (car (last stack))) 'spec) + (eq (car (car (cdr stack))) '::))) ;; -type() ;; Inside fun type def ') closes fun definition (erlang-pop stack))) ((eq (car (car stack)) 'icr) @@ -2752,7 +2754,7 @@ Return nil if inside string, t if in a comment." ;; ;; `after' should be indented to the same level as the ;; corresponding receive. - (cond ((looking-at "\\(after\\|catch\\|of\\)\\($\\|[^_a-zA-Z0-9]\\)") + (cond ((looking-at "\\(after\\|of\\)\\($\\|[^_a-zA-Z0-9]\\)") (nth 2 stack-top)) ((looking-at "when[^_a-zA-Z0-9]") ;; Handling one when part @@ -2771,7 +2773,7 @@ Return nil if inside string, t if in a comment." ((and (eq (car stack-top) '||) (looking-at "\\(]\\|>>\\)[^_a-zA-Z0-9]")) (nth 2 (car (cdr stack)))) ;; Real indentation, where operators create extra indentation etc. - ((memq (car stack-top) '(-> || begin try)) + ((memq (car stack-top) '(-> || try begin)) (if (looking-at "\\(of\\)[^_a-zA-Z0-9]") (nth 2 stack-top) (goto-char (nth 1 stack-top)) @@ -2800,19 +2802,24 @@ Return nil if inside string, t if in a comment." (erlang-caddr (car stack)) 0)) ((looking-at "catch\\($\\|[^_a-zA-Z0-9]\\)") - (if (or (eq (car stack-top) 'try) - (eq (car (car (cdr stack))) 'icr)) - (progn - (if (eq (car stack-top) '->) - (erlang-pop stack)) - (if stack - (erlang-caddr (car stack)) - 0)) - base)) ;; old catch + ;; Are we in a try + (let ((start (if (eq (car stack-top) '->) + (car (cdr stack)) + stack-top))) + (if (null start) nil + (goto-char (nth 1 start))) + (cond ((looking-at "try\\($\\|[^_a-zA-Z0-9]\\)") + (progn + (if (eq (car stack-top) '->) + (erlang-pop stack)) + (if stack + (erlang-caddr (car stack)) + 0))) + (t (erlang-indent-standard indent-point token base 'nil))))) ;; old catch (t (erlang-indent-standard indent-point token base 'nil) )))) - )) + )) ((eq (car stack-top) 'when) (goto-char (nth 1 stack-top)) (if (looking-at "when\\s *\\($\\|%\\)") @@ -2838,27 +2845,32 @@ Return nil if inside string, t if in a comment." (current-column))) ;; Type and Spec indentation ((eq (car stack-top) '::) - (cond ((null erlang-argument-indent) - ;; indent to next column. - (+ 2 (nth 2 stack-top))) - ((looking-at "::[^_a-zA-Z0-9]") - (nth 2 stack-top)) - (t - (let ((start-alternativ (if (looking-at "|") 2 0))) - (goto-char (nth 1 stack-top)) - (- (cond ((looking-at "::\\s *\\($\\|%\\)") - ;; Line ends with :: - (if (eq (car (car (last stack))) 'spec) + (if (looking-at "}") + ;; Closing record definition with types + ;; pop stack and recurse + (erlang-calculate-stack-indent indent-point + (cons (erlang-pop stack) (cdr state))) + (cond ((null erlang-argument-indent) + ;; indent to next column. + (+ 2 (nth 2 stack-top))) + ((looking-at "::[^_a-zA-Z0-9]") + (nth 2 stack-top)) + (t + (let ((start-alternativ (if (looking-at "|") 2 0))) + (goto-char (nth 1 stack-top)) + (- (cond ((looking-at "::\\s *\\($\\|%\\)") + ;; Line ends with :: + (if (eq (car (car (last stack))) 'spec) (+ (erlang-indent-find-preceding-expr 1) erlang-argument-indent) - (+ (erlang-indent-find-preceding-expr 2) - erlang-argument-indent))) - (t - ;; Indent to the same column as the first - ;; argument. - (goto-char (+ 2 (nth 1 stack-top))) - (skip-chars-forward " \t") - (current-column))) start-alternativ))))) + (+ (erlang-indent-find-preceding-expr 2) + erlang-argument-indent))) + (t + ;; Indent to the same column as the first + ;; argument. + (goto-char (+ 2 (nth 1 stack-top))) + (skip-chars-forward " \t") + (current-column))) start-alternativ)))))) ))) (defun erlang-indent-standard (indent-point token base inside-parenthesis) @@ -2874,8 +2886,8 @@ Return nil if inside string, t if in a comment." (+ base erlang-indent-level)) (t (goto-char indent-point) - (cond ((memq (following-char) '(?\( ?{)) - ;; Function application or record. + (cond ((memq (following-char) '(?\( )) + ;; Function application. (+ (erlang-indent-find-preceding-expr) erlang-argument-indent)) ;; Empty line, or end; treat it as the end of @@ -2930,10 +2942,16 @@ This assumes that the preceding expression is either simple (skip-chars-backward " \t") ;; Needed to match the colon in "'foo':'bar'". (if (not (memq (preceding-char) '(?# ?:))) - col - (backward-char 1) - (forward-sexp -1) - (current-column))))) + col + ;; Special hack to handle: (note line break) + ;; [#myrecord{ + ;; foo = foo}] + (or + (ignore-errors + (backward-char 1) + (forward-sexp -1) + (current-column)) + col))))) (defun erlang-indent-parenthesis (stack-position) (let ((previous (erlang-indent-find-preceding-expr))) @@ -3472,8 +3490,8 @@ Normally used in conjunction with `erlang-beginning-of-clause', e.g.: (erlang-get-function-arrow)))" (and (save-excursion - (re-search-forward "[^-:]*-\\|:" (point-max) t) - (erlang-buffer-substring (- (point) 1) (+ (point) 1))))) + (re-search-forward "->" (point-max) t) + (erlang-buffer-substring (- (point) 2) (+ (point) 1))))) (defun erlang-get-function-arity () "Return the number of arguments of function at point, or nil." @@ -3502,6 +3520,13 @@ Normally used in conjunction with `erlang-beginning-of-clause', e.g.: res) (error nil))))) +(defun erlang-get-function-name-and-arity () + "Return the name and arity of the function at point, or nil. +The return value is a string of the form \"foo/1\"." + (let ((name (erlang-get-function-name)) + (arity (erlang-get-function-arity))) + (and name arity (format "%s/%d" name arity)))) + (defun erlang-get-function-arguments () "Return arguments of current function, or nil." (if (not (looking-at (eval-when-compile @@ -3677,6 +3702,7 @@ non-whitespace characters following the point on the current line." (setq erlang-electric-newline-inhibit nil) (setq erlang-electric-newline-inhibit t) (undo-boundary) + (erlang-indent-line) (end-of-line) (newline) (if (condition-case nil @@ -4897,9 +4923,14 @@ a prompt. When nil, we will wait forever, or until \\[keyboard-quit].") (defvar inferior-erlang-buffer nil "Buffer of last invoked inferior Erlang, or nil.") +;; Enable uniquifying Erlang shell buffers based on directory name. +(eval-after-load "uniquify" + '(add-to-list 'uniquify-list-buffers-directory-modes 'erlang-shell-mode)) + ;;;###autoload -(defun inferior-erlang () +(defun inferior-erlang (&optional command) "Run an inferior Erlang. +With prefix command, prompt for command to start Erlang with. This is just like running Erlang in a normal shell, except that an Emacs buffer is used for input and output. @@ -4913,17 +4944,37 @@ Entry to this mode calls the functions in the variables The following commands imitate the usual Unix interrupt and editing control characters: \\{erlang-shell-mode-map}" - (interactive) + (interactive + (when current-prefix-arg + (list (if (fboundp 'read-shell-command) + ;; `read-shell-command' is a new function in Emacs 23. + (read-shell-command "Erlang command: ") + (read-string "Erlang command: "))))) (require 'comint) - (let ((opts inferior-erlang-machine-options)) - (cond ((eq inferior-erlang-shell-type 'oldshell) - (setq opts (cons "-oldshell" opts))) - ((eq inferior-erlang-shell-type 'newshell) - (setq opts (append '("-newshell" "-env" "TERM" "vt100") opts)))) - (setq inferior-erlang-buffer - (apply 'make-comint - inferior-erlang-process-name inferior-erlang-machine - nil opts))) + (let (cmd opts) + (if command + (setq cmd "sh" + opts (list "-c" command)) + (setq cmd inferior-erlang-machine + opts inferior-erlang-machine-options) + (cond ((eq inferior-erlang-shell-type 'oldshell) + (setq opts (cons "-oldshell" opts))) + ((eq inferior-erlang-shell-type 'newshell) + (setq opts (append '("-newshell" "-env" "TERM" "vt100") opts))))) + + ;; Using create-file-buffer and list-buffers-directory in this way + ;; makes uniquify give each buffer a unique name based on the + ;; directory. + (let ((fake-file-name (expand-file-name inferior-erlang-buffer-name default-directory))) + (setq inferior-erlang-buffer (create-file-buffer fake-file-name)) + (apply 'make-comint-in-buffer + inferior-erlang-process-name + inferior-erlang-buffer + cmd + nil opts) + (with-current-buffer inferior-erlang-buffer + (setq list-buffers-directory fake-file-name)))) + (setq inferior-erlang-process (get-buffer-process inferior-erlang-buffer)) (if (> 21 erlang-emacs-major-version) ; funcalls to avoid compiler warnings @@ -4936,10 +4987,6 @@ editing control characters: (if (and (not (eq system-type 'windows-nt)) (eq inferior-erlang-shell-type 'newshell)) (setq comint-process-echoes t)) - ;; `rename-buffer' takes only one argument in Emacs 18. - (condition-case nil - (rename-buffer inferior-erlang-buffer-name t) - (error (rename-buffer inferior-erlang-buffer-name))) (erlang-shell-mode)) diff --git a/lib/tools/emacs/test.erl.indented b/lib/tools/emacs/test.erl.indented index 1ccced9177..2948ccf1b5 100644 --- a/lib/tools/emacs/test.erl.indented +++ b/lib/tools/emacs/test.erl.indented @@ -1,20 +1,20 @@ %% -*- erlang -*- %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009. All Rights Reserved. -%% +%% +%% 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% %%%------------------------------------------------------------------- @@ -93,11 +93,27 @@ -type t13() :: maybe_improper_list(integer(), t11()). -type t14() :: [erl_scan:foo() | %% Should be highlighted - non_neg_integer() | nonempty_list() | + term() | + bool() | + byte() | + char() | + non_neg_integer() | nonempty_list() | + pos_integer() | + neg_integer() | + number() | + list() | nonempty_improper_list() | nonempty_maybe_improper_list() | + maybe_improper_list() | string() | iolist() | byte() | + module() | + mfa() | + node() | + timeout() | + no_return() | %% Should not be highlighted nonempty_() | nonlist() | - erl_scan:bar(34, 92) | t13() | m:f(integer() | <<_:_*16>>)]. + erl_scan:bar(34, 92) | t13() | m:f(integer() | <<_:_*16>>)]. + + -type t15() :: {binary(),<<>>,<<_:34>>,<<_:_*42>>, <<_:3,_:_*14>>,<<>>} | [<<>>|<<_:34>>|<<_:16>>| <<_:3,_:_*1472>>|<<_:19,_:_*14>>| <<_:34>>| @@ -146,6 +162,8 @@ | {'del_member', name(), pid()}, #state{}) -> {'noreply', #state{}}. +-spec all(fun((T) -> boolean()), List :: [T]) -> + boolean() when is_subtype(T, term()). % (*) -spec get_closest_pid(term()) -> Return :: pid() @@ -170,6 +188,9 @@ f19 = 3 :: integer()|undefined, f5 = 3 :: undefined|integer()}). +-record(state, { + sequence_number = 1 :: integer() + }). highlighting(X) % Function definitions should be highlighted @@ -349,6 +370,14 @@ indent_basics(X, Y, Z) % AD added clause foo. + +indent_nested() -> + [ + {foo, 2, "string"}, + {bar, 3, "another string"} + ]. + + indent_icr(Z) -> % icr = if case receive %% If if Z >= 0 -> @@ -483,7 +512,9 @@ indent_try_catch() -> file:close(Xfile) end; indent_try_catch() -> - try foo(bar) of + try + foo(bar) + of X when true andalso kalle -> io:format(stdout, "Parsing file ~s, ", @@ -541,14 +572,57 @@ indent_catch() -> C = catch B + float(43.1), - case catch (X) of + case catch foo(X) of + A -> + B + end, + + case + catch foo(X) + of A -> B end, + + case + foo(X) + of + A -> + catch B, + X + end, + try sune of _ -> foo catch _:_ -> baf - end. + end, + + try + sune + of + _ -> + X = 5, + (catch foo(X)), + X + 10 + catch _:_ -> baf + end, + + try + (catch sune) + of + _ -> + catch foo() %% BUGBUG can't handle catch inside try without parentheses + catch _:_ -> + baf + end, + + try + (catch exit()) + catch + _ -> + catch baf() + end, + ok. indent_binary() -> X = lists:foldr(fun(M) -> @@ -578,3 +652,8 @@ indent_comprehensions() -> true = (X rem 2) >>, ok. + +%% This causes an error in earlier erlang-mode versions. +foo() -> + [#foo{ + foo = foo}]. diff --git a/lib/tools/emacs/test.erl.orig b/lib/tools/emacs/test.erl.orig index 9b4203120b..1221c5655e 100644 --- a/lib/tools/emacs/test.erl.orig +++ b/lib/tools/emacs/test.erl.orig @@ -1,20 +1,20 @@ %% -*- erlang -*- %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009. All Rights Reserved. -%% +%% +%% 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% %%%------------------------------------------------------------------- @@ -93,11 +93,27 @@ -type t13() :: maybe_improper_list(integer(), t11()). -type t14() :: [erl_scan:foo() | %% Should be highlighted - non_neg_integer() | nonempty_list() | + term() | + bool() | + byte() | + char() | + non_neg_integer() | nonempty_list() | + pos_integer() | + neg_integer() | + number() | + list() | nonempty_improper_list() | nonempty_maybe_improper_list() | + maybe_improper_list() | string() | iolist() | byte() | + module() | + mfa() | + node() | + timeout() | + no_return() | %% Should not be highlighted nonempty_() | nonlist() | -erl_scan:bar(34, 92) | t13() | m:f(integer() | <<_:_*16>>)]. + erl_scan:bar(34, 92) | t13() | m:f(integer() | <<_:_*16>>)]. + + -type t15() :: {binary(),<<>>,<<_:34>>,<<_:_*42>>, <<_:3,_:_*14>>,<<>>} | [<<>>|<<_:34>>|<<_:16>>| <<_:3,_:_*1472>>|<<_:19,_:_*14>>| <<_:34>>| @@ -146,6 +162,8 @@ t15(),t20(),t21(), t22(),t25()}. | {'del_member', name(), pid()}, #state{}) -> {'noreply', #state{}}. +-spec all(fun((T) -> boolean()), List :: [T]) -> + boolean() when is_subtype(T, term()). % (*) -spec get_closest_pid(term()) -> Return :: pid() @@ -170,6 +188,9 @@ f18 :: 1 | 2 | 'undefined', f19 = 3 :: integer()|undefined, f5 = 3 :: undefined|integer()}). +-record(state, { + sequence_number = 1 :: integer() + }). highlighting(X) % Function definitions should be highlighted @@ -349,6 +370,14 @@ indent_basics(X, Y, Z) % AD added clause foo. + +indent_nested() -> + [ + {foo, 2, "string"}, + {bar, 3, "another string"} + ]. + + indent_icr(Z) -> % icr = if case receive %% If if Z >= 0 -> @@ -483,7 +512,9 @@ indent_try_catch() -> file:close(Xfile) end; indent_try_catch() -> - try foo(bar) of + try + foo(bar) + of X when true andalso kalle -> io:format(stdout, "Parsing file ~s, ", @@ -541,14 +572,57 @@ indent_catch() -> C = catch B + float(43.1), - case catch (X) of + case catch foo(X) of A -> B end, + + case + catch foo(X) + of + A -> + B + end, + + case + foo(X) + of + A -> + catch B, + X + end, + try sune of - _ -> foo - catch _:_ -> baf - end. + _ -> foo + catch _:_ -> baf + end, + + try +sune + of + _ -> + X = 5, + (catch foo(X)), + X + 10 + catch _:_ -> baf + end, + + try + (catch sune) + of + _ -> + catch foo() %% BUGBUG can't handle catch inside try without parentheses + catch _:_ -> + baf + end, + + try +(catch exit()) + catch +_ -> + catch baf() + end, + ok. indent_binary() -> X = lists:foldr(fun(M) -> @@ -578,3 +652,8 @@ Binary2 = << <<X:8>> || <<X:32,_:32>> <= <<0:512>>, true = (X rem 2) >>, ok. + +%% This causes an error in earlier erlang-mode versions. +foo() -> +[#foo{ +foo = foo}]. diff --git a/lib/tools/src/cover.erl b/lib/tools/src/cover.erl index 1a7ebdc69a..c4d1bd1d2f 100644 --- a/lib/tools/src/cover.erl +++ b/lib/tools/src/cover.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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(cover). @@ -689,6 +689,7 @@ main_process_loop(State) -> end, State#main_state.nodes), reload_originals(State#main_state.compiled), + unregister(?SERVER), reply(From, ok); {From, {Request, Module}} -> @@ -869,6 +870,7 @@ remote_process_loop(State) -> {remote,stop} -> reload_originals(State#remote_state.compiled), + unregister(?SERVER), remote_reply(State#remote_state.main_node, ok); get_status -> @@ -2172,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/src/eprof.erl b/lib/tools/src/eprof.erl index b4313d6888..f7c1b76364 100644 --- a/lib/tools/src/eprof.erl +++ b/lib/tools/src/eprof.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-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% %% %% Purpose: Profile a system in order to figure out where the @@ -23,456 +23,464 @@ -module(eprof). -behaviour(gen_server). --export([start/0, stop/0, dump/0, total_analyse/0, - start_profiling/1, profile/2, profile/4, profile/1, - stop_profiling/0, analyse/0, log/1]). +-export([start/0, + stop/0, + dump/0, + start_profiling/1, start_profiling/2, + profile/1, profile/2, profile/3, profile/4, profile/5, + stop_profiling/0, + analyze/0, analyze/1, analyze/2, + log/1]). %% Internal exports -export([init/1, - call/4, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). +-record(bpd, { + n = 0, % number of total calls + us = 0, % sum of uS for all calls + p = gb_trees:empty(), % tree of {Pid, {Mfa, {Count, Us}}} + mfa = [] % list of {Mfa, {Count, Us}} + }). + +-record(state, { + profiling = false, + pattern = {'_','_','_'}, + rootset = [], + fd = undefined, + start_ts = undefined, + reply = undefined, + bpd = #bpd{} + }). + + + +%% -------------------------------------------------------------------- %% +%% +%% API +%% +%% -------------------------------------------------------------------- %% --include_lib("stdlib/include/qlc.hrl"). - --import(lists, [flatten/1,reverse/1,keysort/2]). - - --record(state, {table = notable, - proc = noproc, - profiling = false, - pfunc = undefined, - pop = running, - ptime = 0, - overhead = 0, - rootset = []}). - -%%%%%%%%%%%%%% - -start() -> gen_server:start({local, eprof}, eprof, [], []). -stop() -> gen_server:call(eprof, stop, infinity). +start() -> gen_server:start({local, ?MODULE}, ?MODULE, [], []). +stop() -> gen_server:call(?MODULE, stop, infinity). +profile(Fun) when is_function(Fun) -> + profile([], Fun); +profile(Rs) when is_list(Rs) -> + start_profiling(Rs). profile(Pids, Fun) -> - start(), - gen_server:call(eprof, {profile,Pids,erlang,apply,[Fun,[]]},infinity). + profile(Pids, Fun, {'_','_','_'}). + +profile(Pids, Fun, Pattern) -> + profile(Pids, erlang, apply, [Fun,[]], Pattern). profile(Pids, M, F, A) -> + profile(Pids, M, F, A, {'_','_','_'}). + +profile(Pids, M, F, A, Pattern) -> start(), - gen_server:call(eprof, {profile,Pids,M,F,A},infinity). + gen_server:call(?MODULE, {profile,Pids,Pattern,M,F,A},infinity). dump() -> - gen_server:call(eprof, dump, infinity). + gen_server:call(?MODULE, dump, infinity). -analyse() -> - gen_server:call(eprof, analyse, infinity). +analyze() -> + analyze(procs). -log(File) -> - gen_server:call(eprof, {logfile, File}, infinity). +analyze(Type) when is_atom(Type) -> + analyze(Type, []); +analyze(Opts) when is_list(Opts) -> + analyze(procs, Opts). +analyze(Type, Opts) when is_list(Opts) -> + gen_server:call(?MODULE, {analyze, Type, Opts}, infinity). -total_analyse() -> - gen_server:call(eprof, total_analyse, infinity). +log(File) -> + gen_server:call(?MODULE, {logfile, File}, infinity). start_profiling(Rootset) -> + start_profiling(Rootset, {'_','_','_'}). +start_profiling(Rootset, Pattern) -> start(), - gen_server:call(eprof, {profile, Rootset}, infinity). + gen_server:call(?MODULE, {profile, Rootset, Pattern}, infinity). stop_profiling() -> - gen_server:call(eprof, stop_profiling, infinity). + gen_server:call(?MODULE, stop_profiling, infinity). -profile(Rs) -> - start_profiling(Rs). -%%%%%%%%%%%%%%%% +%% -------------------------------------------------------------------- %% +%% +%% init +%% +%% -------------------------------------------------------------------- %% -init(_) -> +init([]) -> process_flag(trap_exit, true), - process_flag(priority, max), - put(three_one, {3,1}), %To avoid building garbage. {ok, #state{}}. -subtr({X1,Y1,Z1}, {X1,Y1,Z2}) -> - Z1 - Z2; -subtr({X1,Y1,Z1}, {X2,Y2,Z2}) -> - (((X1-X2) * 1000000) + Y1 - Y2) * 1000000 + Z1 - Z2. +%% -------------------------------------------------------------------- %% +%% +%% handle_call +%% +%% -------------------------------------------------------------------- %% -update_call_statistics(Tab, Key, Time) -> - try ets:update_counter(Tab, Key, Time) of - NewTime when is_integer(NewTime) -> - ets:update_counter(Tab, Key, get(three_one)) - catch - error:badarg -> - ets:insert(Tab, {Key,Time,1}) - end. +%% analyze -update_other_statistics(Tab, Key, Time) -> - try - ets:update_counter(Tab, Key, Time) - catch - error:badarg -> - ets:insert(Tab, {Key,Time,0}) - end. +handle_call({analyze, _, _}, _, #state{ bpd = #bpd{ p = {0,nil}, us = 0, n = 0} = Bpd } = S) when is_record(Bpd, bpd) -> + {reply, nothing_to_analyze, S}; -do_messages({trace_ts,From,Op,Mfa,Time}, Tab, undefined,_PrevOp0,_PrevTime0) -> - PrevFunc = [From|Mfa], - receive - {trace_ts,_,_,_,_}=Ts -> do_messages(Ts, Tab, PrevFunc, Op, Time) - after 0 -> - {PrevFunc,Op,Time} - end; -do_messages({trace_ts,From,Op,Mfa,Time}, Tab, PrevFunc0, call, PrevTime0) -> - update_call_statistics(Tab, PrevFunc0, subtr(Time, PrevTime0)), - PrevFunc = case Op of - exit -> undefined; - out -> undefined; - _ -> [From|Mfa] - end, - receive - {trace_ts,_,_,_,_}=Ts -> do_messages(Ts, Tab, PrevFunc, Op, Time) - after 0 -> - {PrevFunc,Op,Time} - end; -do_messages({trace_ts,From,Op,Mfa,Time}, Tab, PrevFunc0, _PrevOp0, PrevTime0) -> - update_other_statistics(Tab, PrevFunc0, subtr(Time, PrevTime0)), - PrevFunc = case Op of - exit -> undefined; - out -> undefined; - _ -> [From|Mfa] - end, - receive - {trace_ts,_,_,_,_}=Ts -> do_messages(Ts, Tab, PrevFunc, Op, Time) - after 0 -> - {PrevFunc,Op,Time} - end. +handle_call({analyze, procs, Opts}, _, #state{ bpd = #bpd{ p = Ps, us = Tus} = Bpd, fd = Fd} = S) when is_record(Bpd, bpd) -> + lists:foreach(fun + ({Pid, Mfas}) -> + {Pn, Pus} = sum_bp_total_n_us(Mfas), + format(Fd, "~n****** Process ~w -- ~s % of profiled time *** ~n", [Pid, s("~.2f", [100.0*(Pus/Tus)])]), + print_bp_mfa(Mfas, {Pn,Pus}, Fd, Opts), + ok + end, gb_trees:to_list(Ps)), + {reply, ok, S}; -%%%%%%%%%%%%%%%%%% +handle_call({analyze, total, Opts}, _, #state{ bpd = #bpd{ mfa = Mfas, n = Tn, us = Tus} = Bpd, fd = Fd} = S) when is_record(Bpd, bpd) -> + print_bp_mfa(Mfas, {Tn, Tus}, Fd, Opts), + {reply, ok, S}; -handle_cast(_Req, S) -> {noreply, S}. +handle_call({analyze, Type, _Opts}, _, S) -> + {reply, {error, {undefined, Type}}, S}; -terminate(_Reason,_S) -> - call_trace_for_all(false), - normal. +%% profile -%%%%%%%%%%%%%%%%%% +handle_call({profile, _Rootset, _Pattern, _M,_F,_A}, _From, #state{ profiling = true } = S) -> + {reply, {error, already_profiling}, S}; -handle_call({logfile, F}, _FromTag, Status) -> - case file:open(F, [write]) of - {ok, Fd} -> - case get(fd) of - undefined -> ok; - FdOld -> file:close(FdOld) - end, - put(fd, Fd), - {reply, ok, Status}; - {error, _} -> - {reply, error, Status} - end; +handle_call({profile, Rootset, Pattern, M,F,A}, From, #state{fd = Fd } = S) -> -handle_call({profile, Rootset}, {From, _Tag}, S) -> - link(From), - maybe_delete(S#state.table), - io:format("eprof: Starting profiling ..... ~n",[]), - ptrac(S#state.rootset, false, all()), - flush_receive(), - Tab = ets:new(eprof, [set, public]), - case ptrac(Rootset, true, all()) of - false -> - {reply, error, #state{}}; + set_pattern_trace(false, S#state.pattern), + set_process_trace(false, S#state.rootset), + + Pid = setup_profiling(M,F,A), + case set_process_trace(true, [Pid|Rootset]) of true -> - uni_schedule(), - call_trace_for_all(true), - erase(replyto), - {reply, profiling, #state{table = Tab, - proc = From, - profiling = true, - rootset = Rootset}} + set_pattern_trace(true, Pattern), + T0 = now(), + execute_profiling(Pid), + {noreply, #state{ + profiling = true, + rootset = [Pid|Rootset], + start_ts = T0, + reply = From, + fd = Fd, + pattern = Pattern + }}; + false -> + exit(Pid, eprof_kill), + {reply, error, #state{ fd = Fd}} end; -handle_call(stop_profiling, _FromTag, S) when S#state.profiling -> - ptrac(S#state.rootset, false, all()), - call_trace_for_all(false), - multi_schedule(), - io:format("eprof: Stop profiling~n",[]), - ets:delete(S#state.table, nofunc), - {reply, profiling_stopped, S#state{profiling = false}}; +handle_call({profile, _Rootset, _Pattern}, _From, #state{ profiling = true } = S) -> + {reply, {error, already_profiling}, S}; -handle_call(stop_profiling, _FromTag, S) -> - {reply, profiling_already_stopped, S}; +handle_call({profile, Rootset, Pattern}, From, #state{ fd = Fd } = S) -> + + set_pattern_trace(false, S#state.pattern), + set_process_trace(false, S#state.rootset), -handle_call({profile, Rootset, M, F, A}, FromTag, S) -> - io:format("eprof: Starting profiling..... ~n", []), - maybe_delete(S#state.table), - ptrac(S#state.rootset, false, all()), - flush_receive(), - put(replyto, FromTag), - Tab = ets:new(eprof, [set, public]), - P = spawn_link(eprof, call, [self(), M, F, A]), - case ptrac([P|Rootset], true, all()) of + case set_process_trace(true, Rootset) of true -> - uni_schedule(), - call_trace_for_all(true), - P ! {self(),go}, - {noreply, #state{table = Tab, - profiling = true, - rootset = [P|Rootset]}}; + T0 = now(), + set_pattern_trace(true, Pattern), + {reply, profiling, #state{ + profiling = true, + rootset = Rootset, + start_ts = T0, + reply = From, + fd = Fd, + pattern = Pattern + }}; false -> - exit(P, kill), - erase(replyto), - {reply, error, #state{}} + {reply, error, #state{ fd = Fd }} end; -handle_call(dump, _FromTag, S) -> - {reply, dump(S#state.table), S}; - -handle_call(analyse, _FromTag, S) -> - {reply, analyse(S), S}; +handle_call(stop_profiling, _From, #state{ profiling = false } = S) -> + {reply, profiling_already_stopped, S}; -handle_call(total_analyse, _FromTag, S) -> - {reply, total_analyse(S), S}; +handle_call(stop_profiling, _From, #state{ profiling = true } = S) -> -handle_call(stop, _FromTag, S) -> - multi_schedule(), - {stop, normal, stopped, S}. + set_pattern_trace(pause, S#state.pattern), -%%%%%%%%%%%%%%%%%%% + Bpd = collect_bpd(), -handle_info({trace_ts,_From,_Op,_Func,_Time}=M, S0) when S0#state.profiling -> - Start = erlang:now(), - #state{table=Tab,pop=PrevOp0,ptime=PrevTime0,pfunc=PrevFunc0, - overhead=Overhead0} = S0, - {PrevFunc,PrevOp,PrevTime} = do_messages(M, Tab, PrevFunc0, PrevOp0, PrevTime0), - Overhead = Overhead0 + subtr(erlang:now(), Start), - S = S0#state{overhead=Overhead,pfunc=PrevFunc,pop=PrevOp,ptime=PrevTime}, - {noreply,S}; + set_process_trace(false, S#state.rootset), + set_pattern_trace(false, S#state.pattern), -handle_info({trace_ts, From, _, _, _}, S) when not S#state.profiling -> - ptrac([From], false, all()), - {noreply, S}; + {reply, profiling_stopped, S#state{ + profiling = false, + rootset = [], + pattern = {'_','_','_'}, + bpd = Bpd + }}; -handle_info({_P, {answer, A}}, S) -> - ptrac(S#state.rootset, false, all()), - io:format("eprof: Stop profiling~n",[]), - {From,_Tag} = get(replyto), - catch unlink(From), - ets:delete(S#state.table, nofunc), - gen_server:reply(erase(replyto), {ok, A}), - multi_schedule(), - {noreply, S#state{profiling = false, - rootset = []}}; - -handle_info({'EXIT', P, Reason}, - #state{profiling=true,proc=P,table=T,rootset=RootSet}) -> - maybe_delete(T), - ptrac(RootSet, false, all()), - multi_schedule(), - io:format("eprof: Profiling failed\n",[]), - case erase(replyto) of - undefined -> - {noreply, #state{}}; - FromTag -> - gen_server:reply(FromTag, {error, Reason}), - {noreply, #state{}} +%% logfile +handle_call({logfile, File}, _From, #state{ fd = OldFd } = S) -> + case file:open(File, [write]) of + {ok, Fd} -> + case OldFd of + undefined -> ok; + OldFd -> file:close(OldFd) + end, + {reply, ok, S#state{ fd = Fd}}; + Error -> + {reply, Error, S} end; -handle_info({'EXIT',_P,_Reason}, S) -> - {noreply, S}. +handle_call(dump, _From, #state{ bpd = Bpd } = S) when is_record(Bpd, bpd) -> + {reply, gb_trees:to_list(Bpd#bpd.p), S}; -uni_schedule() -> - erlang:system_flag(multi_scheduling, block). +handle_call(stop, _FromTag, S) -> + {stop, normal, stopped, S}. -multi_schedule() -> - erlang:system_flag(multi_scheduling, unblock). +%% -------------------------------------------------------------------- %% +%% +%% handle_cast +%% +%% -------------------------------------------------------------------- %% -%%%%%%%%%%%%%%%%%% +handle_cast(_Msg, State) -> + {noreply, State}. -call(Top, M, F, A) -> - receive - {Top,go} -> - Top ! {self(), {answer, apply(M,F,A)}} - end. +%% -------------------------------------------------------------------- %% +%% +%% handle_info +%% +%% -------------------------------------------------------------------- %% -call_trace_for_all(Flag) -> - erlang:trace_pattern(on_load, Flag, [local]), - erlang:trace_pattern({'_','_','_'}, Flag, [local]). +handle_info({'EXIT', _, normal}, S) -> + {noreply, S}; +handle_info({'EXIT', _, eprof_kill}, S) -> + {noreply, S}; +handle_info({'EXIT', _, Reason}, #state{ reply = FromTag } = S) -> -ptrac([P|T], How, Flags) when is_pid(P) -> - case dotrace(P, How, Flags) of - true -> - ptrac(T, How, Flags); - false when How -> - false; - false -> - ptrac(T, How, Flags) - end; + set_process_trace(false, S#state.rootset), + set_pattern_trace(false, S#state.pattern), -ptrac([P|T], How, Flags) when is_atom(P) -> - case whereis(P) of - undefined when How -> - false; - undefined when not How -> - ptrac(T, How, Flags); - Pid -> - ptrac([Pid|T], How, Flags) - end; + gen_server:reply(FromTag, {error, Reason}), + {noreply, S#state{ + profiling = false, + rootset = [], + pattern = {'_','_','_'} + }}; -ptrac([H|_],_How,_Flags) -> - io:format("** eprof bad process ~w~n",[H]), - false; +% check if Pid is spawned process? +handle_info({_Pid, {answer, Result}}, #state{ reply = {From,_} = FromTag} = S) -> -ptrac([],_,_) -> true. + set_pattern_trace(pause, S#state.pattern), -dotrace(P, How, What) -> - case (catch erlang:trace(P, How, What)) of - 1 -> - true; - _Other when not How -> - true; - _Other -> - io:format("** eprof: bad process: ~p,~p,~p~n", [P,How,What]), - false - end. + Bpd = collect_bpd(), -all() -> [call,arity,return_to,running,timestamp,set_on_spawn]. - -total_analyse(#state{table=notable}) -> - nothing_to_analyse; -total_analyse(S) -> - #state{table = T, overhead = Overhead} = S, - QH = qlc:q([{{From,Mfa},Time,Count} || - {[From|Mfa],Time,Count} <- ets:table(T)]), - Pcalls = reverse(keysort(2, replicas(qlc:eval(QH)))), - Time = collect_times(Pcalls), - format("FUNCTION~44s TIME ~n", ["CALLS"]), - printit(Pcalls, Time), - format("\nTotal time: ~.2f\n", [Time / 1000000]), - format("Measurement overhead: ~.2f\n", [Overhead / 1000000]). - -analyse(#state{table=notable}) -> - nothing_to_analyse; -analyse(S) -> - #state{table = T, overhead = Overhead} = S, - Pids = ordsets:from_list(flatten(ets:match(T, {['$1'|'_'],'_', '_'}))), - Times = sum(ets:match(T, {'_','$1', '_'})), - format("FUNCTION~44s TIME ~n", ["CALLS"]), - do_pids(Pids, T, 0, Times), - format("\nTotal time: ~.2f\n", [Times / 1000000]), - format("Measurement overhead: ~.2f\n", [Overhead / 1000000]). - -do_pids([Pid|Tail], T, AckTime, Total) -> - Pcalls = - reverse(keysort(2, to_tups(ets:match(T, {[Pid|'$1'], '$2','$3'})))), - Time = collect_times(Pcalls), - PercentTotal = 100 * (divide(Time, Total)), - format("~n****** Process ~w -- ~s % of profiled time *** ~n", - [Pid, fpf(PercentTotal)]), - printit(Pcalls, Time), - do_pids(Tail, T, AckTime + Time, Total); -do_pids([], _, _, _) -> - ok. + set_process_trace(false, S#state.rootset), + set_pattern_trace(false, S#state.pattern), -printit([],_) -> ok; -printit([{{Mod,Fun,Arity}, Time, Calls} |Tail], ProcTime) -> - format("~s ~s ~s % ~n", [ff(Mod,Fun,Arity), fint(Calls), - fpf(100*(divide(Time,ProcTime)))]), - printit(Tail, ProcTime); -printit([{{_,{Mod,Fun,Arity}}, Time, Calls} |Tail], ProcTime) -> - format("~s ~s ~s % ~n", [ff(Mod,Fun,Arity), fint(Calls), - fpf(100*(divide(Time,ProcTime)))]), - printit(Tail, ProcTime); -printit([_|T], Time) -> - printit(T, Time). - -ff(Mod,Fun,Arity) -> - pad(flatten(io_lib:format("~w:~w/~w", [Mod,Fun, Arity])),45). - -pad(Str, Len) -> - Strlen = length(Str), - if - Strlen > Len -> strip_tail(Str, 45); - true -> lists:append(Str, mklist(Len-Strlen)) - end. + catch unlink(From), + gen_server:reply(FromTag, {ok, Result}), + {noreply, S#state{ + profiling = false, + rootset = [], + pattern = {'_','_','_'}, + bpd = Bpd + }}. + +%% -------------------------------------------------------------------- %% +%% +%% termination +%% +%% -------------------------------------------------------------------- %% + +terminate(_Reason, #state{ fd = undefined }) -> + set_pattern_trace(false, {'_','_','_'}), + ok; +terminate(_Reason, #state{ fd = Fd }) -> + file:close(Fd), + set_pattern_trace(false, {'_','_','_'}), + ok. -strip_tail([_|_], 0) ->[]; -strip_tail([H|T], I) -> [H|strip_tail(T, I-1)]; -strip_tail([],_I) -> []. +%% -------------------------------------------------------------------- %% +%% +%% code_change +%% +%% -------------------------------------------------------------------- %% -fpf(F) -> strip_tail(flatten(io_lib:format("~w", [round(F)])), 5). -fint(Int) -> pad(flatten(io_lib:format("~w",[Int])), 10). +code_change(_OldVsn, State, _Extra) -> + {ok, State}. -mklist(0) -> []; -mklist(I) -> [$ |mklist(I-1)]. -to_tups(L) -> lists:map(fun(List) -> erlang:list_to_tuple(List) end, L). +%% -------------------------------------------------------------------- %% +%% +%% AUX Functions +%% +%% -------------------------------------------------------------------- %% -divide(X,Y) -> X / Y. +setup_profiling(M,F,A) -> + spawn_link(fun() -> spin_profile(M,F,A) end). -collect_times([]) -> 0; -collect_times([Tup|Tail]) -> element(2, Tup) + collect_times(Tail). +spin_profile(M, F, A) -> + receive + {Pid, execute} -> + Pid ! {self(), {answer, erlang:apply(M,F,A)}} + end. -dump(T) -> - L = ets:tab2list(T), - format(L). +execute_profiling(Pid) -> + Pid ! {self(), execute}. -format([H|T]) -> - format("~p~n", [H]), format(T); -format([]) -> ok. +set_pattern_trace(Flag, Pattern) -> + erlang:system_flag(multi_scheduling, block), + erlang:trace_pattern(on_load, Flag, [call_time]), + erlang:trace_pattern(Pattern, Flag, [call_time]), + erlang:system_flag(multi_scheduling, unblock), + ok. -format(F, A) -> - io:format(F,A), - case get(fd) of - undefined -> ok; - Fd -> io:format(Fd, F,A) +set_process_trace(Flag, Pids) -> + % do we need procs for meta info? + % could be useful + set_process_trace(Flag, Pids, [call, set_on_spawn]). +set_process_trace(_, [], _) -> true; +set_process_trace(Flag, [Pid|Pids], Options) when is_pid(Pid) -> + try + erlang:trace(Pid, Flag, Options), + set_process_trace(Flag, Pids, Options) + catch + _:_ -> + false + end; +set_process_trace(Flag, [Name|Pids], Options) when is_atom(Name) -> + case whereis(Name) of + undefined -> + set_process_trace(Flag, Pids, Options); + Pid -> + set_process_trace(Flag, [Pid|Pids], Options) end. -maybe_delete(T) -> - catch ets:delete(T). - -sum([[H]|T]) -> H + sum(T); -sum([]) -> 0. +collect_bpd() -> + collect_bpd([M || M <- [element(1, Mi) || Mi <- code:all_loaded()], M =/= ?MODULE]). + +collect_bpd(Ms) when is_list(Ms) -> + collect_bpdf(collect_mfas(Ms) ++ erlang:system_info(snifs)). + +collect_mfas(Ms) -> + lists:foldl(fun + (M, Mfas) -> + Mfas ++ [{M, F, A} || {F, A} <- M:module_info(functions)] + end, [], Ms). + +collect_bpdf(Mfas) -> + collect_bpdf(Mfas, #bpd{}). +collect_bpdf([], Bpd) -> + Bpd; +collect_bpdf([Mfa|Mfas], #bpd{n = N, us = Us, p = Tree, mfa = Code } = Bpd) -> + case erlang:trace_info(Mfa, call_time) of + {call_time, []} -> + collect_bpdf(Mfas, Bpd); + {call_time, Data} when is_list(Data) -> + {CTn, CTus, CTree} = collect_bpdfp(Mfa, Tree, Data), + collect_bpdf(Mfas, Bpd#bpd{ + n = CTn + N, + us = CTus + Us, + p = CTree, + mfa = [{Mfa, {CTn, CTus}}|Code] + }); + {call_time, false} -> + collect_bpdf(Mfas, Bpd); + {call_time, _Other} -> + collect_bpdf(Mfas, Bpd) + end. -replicas(L) -> - replicas(L, []). +collect_bpdfp(Mfa, Tree, Data) -> + lists:foldl(fun + ({Pid, Ni, Si, Usi}, {PTno, PTuso, To}) -> + Time = Si * 1000000 + Usi, + Ti1 = case gb_trees:lookup(Pid, To) of + none -> + gb_trees:enter(Pid, [{Mfa, {Ni, Time}}], To); + {value, Pmfas} -> + gb_trees:enter(Pid, [{Mfa, {Ni, Time}}|Pmfas], To) + end, + {PTno + Ni, PTuso + Time, Ti1} + end, {0,0, Tree}, Data). + +%% manipulators +sort_mfa(Bpfs, mfa) when is_list(Bpfs) -> + lists:sort(fun + ({A,_}, {B,_}) when A < B -> true; + (_, _) -> false + end, Bpfs); +sort_mfa(Bpfs, time) when is_list(Bpfs) -> + lists:sort(fun + ({_,{A,_}}, {_,{B,_}}) when A < B -> true; + (_, _) -> false + end, Bpfs); +sort_mfa(Bpfs, calls) when is_list(Bpfs) -> + lists:sort(fun + ({_,{_,A}}, {_,{_,B}}) when A < B -> true; + (_, _) -> false + end, Bpfs); +sort_mfa(Bpfs, _) when is_list(Bpfs) -> sort_mfa(Bpfs, calls). + +filter_mfa(Bpfs, Ts) when is_list(Ts) -> + filter_mfa(Bpfs, [], proplists:get_value(calls, Ts, 0), proplists:get_value(time, Ts, 0)); +filter_mfa(Bpfs, _) -> Bpfs. +filter_mfa([], Out, _, _) -> lists:reverse(Out); +filter_mfa([{_, {C, T}}=Bpf|Bpfs], Out, Ct, Tt) when C >= Ct, T >= Tt -> filter_mfa(Bpfs, [Bpf|Out], Ct, Tt); +filter_mfa([_|Bpfs], Out, Ct, Tt) -> filter_mfa(Bpfs, Out, Ct, Tt). + +sum_bp_total_n_us(Mfas) -> + lists:foldl(fun ({_, {Ci,Usi}}, {Co, Uso}) -> {Co + Ci, Uso + Usi} end, {0,0}, Mfas). + +%% strings and format + +string_bp_mfa(Mfas, Tus) -> string_bp_mfa(Mfas, Tus, {0,0,0,0,0}, []). +string_bp_mfa([], _, Ws, Strings) -> {Ws, lists:reverse(Strings)}; +string_bp_mfa([{Mfa, {Count, Time}}|Mfas], Tus, {MfaW, CountW, PercW, TimeW, TpCW}, Strings) -> + Smfa = s(Mfa), + Scount = s(Count), + Stime = s(Time), + Sperc = s("~.2f", [100*(Time/Tus)]), + Stpc = s("~.2f", [Time/Count]), + + string_bp_mfa(Mfas, Tus, { + erlang:max(MfaW, length(Smfa)), + erlang:max(CountW,length(Scount)), + erlang:max(PercW, length(Sperc)), + erlang:max(TimeW, length(Stime)), + erlang:max(TpCW, length(Stpc)) + }, [[Smfa, Scount, Sperc, Stime, Stpc] | Strings]). + +print_bp_mfa(Mfas, {_Tn, Tus}, Fd, Opts) -> + Fmfas = filter_mfa(sort_mfa(Mfas, proplists:get_value(sort, Opts)), proplists:get_value(filter, Opts)), + {{MfaW, CountW, PercW, TimeW, TpCW}, Strs} = string_bp_mfa(Fmfas, Tus), + Ws = { + erlang:max(length("FUNCTION"), MfaW), + erlang:max(length("CALLS"), CountW), + erlang:max(length(" %"), PercW), + erlang:max(length("TIME"), TimeW), + erlang:max(length("uS / CALLS"), TpCW) + }, + format(Fd, Ws, ["FUNCTION", "CALLS", " %", "TIME", "uS / CALLS"]), + format(Fd, Ws, ["--------", "-----", "---", "----", "----------"]), + + lists:foreach(fun (String) -> format(Fd, Ws, String) end, Strs), + ok. -replicas([{{Pid, {Mod,Fun,Arity}}, Ack,Calls} |Tail], Result) -> - case search({Mod,Fun,Arity},Result) of - false -> - replicas(Tail, [{{Pid, {Mod,Fun,Arity}}, Ack,Calls} |Result]); - {Ack2, Calls2} -> - Result2 = del({Mod,Fun,Arity}, Result), - replicas(Tail, [{{Pid, {Mod,Fun,Arity}}, - Ack+Ack2,Calls+Calls2} |Result2]) - end; +s({M,F,A}) -> s("~w:~w/~w",[M,F,A]); +s(Term) -> s("~p", [Term]). +s(Format, Terms) -> lists:flatten(io_lib:format(Format, Terms)). -replicas([_|T], Ack) -> %% Whimpy - replicas(T, Ack); - -replicas([], Res) -> Res. - -search(Key, [{{_,Key}, Ack, Calls}|_]) -> - {Ack, Calls}; -search(Key, [_|T]) -> - search(Key, T); -search(_Key,[]) -> false. - -del(Key, [{{_,Key},_Ack,_Calls}|T]) -> - T; -del(Key, [H | Tail]) -> - [H|del(Key, Tail)]; -del(_Key,[]) -> []. - -flush_receive() -> - receive - {trace_ts, From, _, _, _} when is_pid(From) -> - ptrac([From], false, all()), - flush_receive(); - _ -> - flush_receive() - after 0 -> - ok - end. -code_change(_OldVsn, State, _Extra) -> - {ok,State}. +format(Fd, {MfaW, CountW, PercW, TimeW, TpCW}, Strings) -> + format(Fd, s("~~.~ps ~~~ps ~~~ps ~~~ps [~~~ps]~~n", [MfaW, CountW, PercW, TimeW, TpCW]), Strings); +format(undefined, Format, Strings) -> + io:format(Format, Strings), + ok; +format(Fd, Format, Strings) -> + io:format(Fd, Format, Strings), + io:format(Format, Strings), + ok. diff --git a/lib/tools/src/xref_base.erl b/lib/tools/src/xref_base.erl index d0dbf4a2b4..93f0e9c0c8 100644 --- a/lib/tools/src/xref_base.erl +++ b/lib/tools/src/xref_base.erl @@ -1,24 +1,26 @@ %% %% %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 %% 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(xref_base). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([new/0, new/1, delete/1, add_directory/2, add_directory/3, add_module/2, add_module/3, @@ -29,7 +31,7 @@ add_release/2, add_release/3, get_library_path/1, set_library_path/2, set_library_path/3, set_up/1, set_up/2, - q/2, q/3, info/1, info/2, info/3, update/1, update/2, + q/2, q/3, info/1, info/2, info/3, update/1, update/2, forget/1, forget/2, variables/1, variables/2, analyze/2, analyze/3, analysis/1, get_default/2, set_default/3, @@ -38,14 +40,14 @@ -export([format_error/1]). %% The following functions are exported for testing purposes only: --export([do_add_module/4, do_add_application/2, do_add_release/2, +-export([do_add_module/4, do_add_application/2, do_add_release/2, do_remove_module/2]). --import(lists, - [filter/2, flatten/1, foldl/3, keysearch/3, map/2, mapfoldl/3, - member/2, reverse/1, sort/1, usort/1]). +-import(lists, + [filter/2, flatten/1, foldl/3, foreach/2, keysearch/3, map/2, + mapfoldl/3, member/2, reverse/1, sort/1, usort/1]). --import(sofs, +-import(sofs, [constant_function/2, converse/1, difference/2, domain/1, empty_set/0, family/1, family_difference/2, intersection/2, family_projection/2, family_to_relation/1, family_union/1, @@ -103,12 +105,12 @@ delete(State) -> ok end end, - map(Fun, dict:to_list(State#xref.variables)), + foreach(Fun, dict:to_list(State#xref.variables)), ok. add_directory(State, Dir) -> add_directory(State, Dir, []). - + %% -> {ok, Modules, NewState} | Error add_directory(State, Dir, Options) -> ValOptions = option_values([builtins, recurse, verbose, warnings], State), @@ -277,7 +279,7 @@ q(S, Q, Options) when is_atom(Q) -> q(S, atom_to_list(Q), Options); q(S, Q, Options) -> case xref_utils:is_string(Q, 1) of - true -> + true -> case set_up(S, Options) of {ok, S1} -> case xref_compiler:compile(Q, S1#xref.variables) of @@ -336,7 +338,7 @@ forget(State, Variable) when is_atom(Variable) -> forget(State, Variables) -> Vars = State#xref.variables, do_forget(Variables, Vars, Variables, State). - + variables(State) -> variables(State, [user]). @@ -350,9 +352,9 @@ variables(State, Options) -> {ok, NewState} -> {U, P} = do_variables(NewState), R1 = if User -> [{user, U}]; true -> [] end, - R = if - Predef -> [{predefined,P} | R1]; - true -> R1 + R = if + Predef -> [{predefined,P} | R1]; + true -> R1 end, {{ok, R}, NewState}; Error -> @@ -368,7 +370,7 @@ analyze(State, Analysis) -> %% -> {{ok, Answer}, NewState} | {Error, NewState} analyze(State, Analysis, Options) -> case analysis(Analysis, State#xref.mode) of - P when is_list(P) -> + P when is_list(P) -> q(State, P, Options); error -> R = case analysis(Analysis, functions) of @@ -461,7 +463,7 @@ get_default(State, Option) -> %% -> [{Option, Value}] get_default(State) -> - Fun = fun(O) -> V = current_default(State, O), {O, V} end, + Fun = fun(O) -> V = current_default(State, O), {O, V} end, map(Fun, [builtins, recurse, verbose, warnings]). %% -> {ok, NewState} -> Error @@ -478,7 +480,7 @@ set_default(State, Options) -> format_error({error, Module, Error}) -> Module:format_error(Error); format_error({invalid_options, Options}) -> - io_lib:format("Unknown option(s) or invalid option value(s): ~p~n", + io_lib:format("Unknown option(s) or invalid option value(s): ~p~n", [Options]); format_error({invalid_filename, Term}) -> io_lib:format("A file name (a string) was expected: ~p~n", [Term]); @@ -540,7 +542,7 @@ updated_modules(State) -> case xref_utils:file_info(File) of {ok, {_, file, readable, MTime}} when MTime =/= RTime -> [{M,File} | L]; - _Else -> + _Else -> L end end, @@ -591,7 +593,7 @@ do_add_release(Dir, RelName, OB, OV, OW, State) -> case xref_utils:release_directory(Dir, true, "ebin") of {ok, ReleaseDirName, ApplDir, Dirs} -> ApplDirs = xref_utils:select_last_application_version(Dirs), - Release = case RelName of + Release = case RelName of [[]] -> ReleaseDirName; [Name] -> Name end, @@ -615,7 +617,7 @@ do_add_release(S, XRel) -> end. add_rel_appls([ApplDir | ApplDirs], Release, OB, OV, OW, State) -> - {ok, _AppName, NewState} = + {ok, _AppName, NewState} = add_appldir(ApplDir, Release, [[]], OB, OV, OW, State), add_rel_appls(ApplDirs, Release, OB, OV, OW, NewState); add_rel_appls([], [Release], _OB, _OV, _OW, NewState) -> @@ -637,10 +639,10 @@ add_appldir(ApplDir, Release, Name, OB, OV, OW, OldState) -> [[]] -> AppName0; [N] -> N end, - AppInfo = #xref_app{name = AppName, rel_name = Release, + AppInfo = #xref_app{name = AppName, rel_name = Release, vsn = Vsn, dir = Dir}, State1 = do_add_application(OldState, AppInfo), - {ok, _Modules, NewState} = + {ok, _Modules, NewState} = do_add_directory(Dir, [AppName], OB, false, OV, OW, State1), {ok, AppName, NewState}. @@ -662,7 +664,7 @@ do_add_directory(Dir, AppName, Bui, Rec, Ver, War, State) -> ok = is_filename(Dir), {FileNames, Errors, Jams, Unreadable} = xref_utils:scan_directory(Dir, Rec, [?Suffix], [".jam"]), - warnings(War, jam, Jams), + warnings(War, jam, Jams), warnings(War, unreadable, Unreadable), case Errors of [] -> @@ -683,7 +685,7 @@ do_add_a_module(File, AppName, Builtins, Verbose, Warnings, State) -> false -> throw_error({invalid_filename, File}); Splitname -> - do_add_module(Splitname, AppName, Builtins, Verbose, + do_add_module(Splitname, AppName, Builtins, Verbose, Warnings, State) end. @@ -691,7 +693,7 @@ do_add_a_module(File, AppName, Builtins, Verbose, Warnings, State) -> %% Options: verbose, warnings, builtins do_add_module({Dir, Basename}, AppName, Builtins, Verbose, Warnings, State) -> File = filename:join(Dir, Basename), - {ok, M, Bad, NewState} = + {ok, M, Bad, NewState} = do_add_module1(Dir, File, AppName, Builtins, Verbose, Warnings, State), filter(fun({Tag,B}) -> warnings(Warnings, Tag, [[File,B]]) end, Bad), {ok, M, NewState}. @@ -723,7 +725,7 @@ do_add_module1(Dir, File, AppName, Builtins, Verbose, Warnings, State) -> {ok, {_, _, _, Time}} -> Time; Error -> throw(Error) end, - XMod = #xref_mod{name = M, app_name = AppName, dir = Dir, + XMod = #xref_mod{name = M, app_name = AppName, dir = Dir, mtime = T, builtins = Builtins, no_unresolved = NoUnresCalls}, do_add_module(State, XMod, UnresCalls, Data); @@ -736,13 +738,13 @@ abst(File, Builtins, Mode) when Mode =:= functions -> case beam_lib:chunks(File, [abstract_code, exports, attributes]) of {ok, {M,[{abstract_code,NoA},_X,_A]}} when NoA =:= no_abstract_code -> {ok, M, NoA}; - {ok, {M, [{abstract_code, {abstract_v1, Forms}}, + {ok, {M, [{abstract_code, {abstract_v1, Forms}}, {exports,X0}, {attributes,A}]}} -> %% R7. X = xref_utils:fa_to_mfa(X0, M), D = deprecated(A, X, M), xref_reader:module(M, Forms, Builtins, X, D); - {ok, {M, [{abstract_code, {abstract_v2, Forms}}, + {ok, {M, [{abstract_code, {abstract_v2, Forms}}, {exports,X0}, {attributes,A}]}} -> %% R8-R9B. X = xref_utils:fa_to_mfa(X0, M), @@ -769,8 +771,8 @@ abst(File, Builtins, Mode) when Mode =:= modules -> true -> I0; false -> - Fun = fun({M,F,A}) -> - not xref_utils:is_builtin(M, F, A) + Fun = fun({M,F,A}) -> + not xref_utils:is_builtin(M, F, A) end, filter(Fun, I0) end, @@ -790,7 +792,7 @@ mfa_exports(X0, Attributes, M) -> xref_utils:fa_to_mfa(X1, M). adjust_arity(F, A) -> - case xref_utils:is_static_function(F, A) of + case xref_utils:is_static_function(F, A) of true -> A; false -> A - 1 end. @@ -885,7 +887,7 @@ do_add_module(S, M, XMod, Unres0, Data) when S#xref.mode =:= functions -> Unres = domain(UnresCalls), DefinedFuns = domain(DefAt), - {AXC, ALC, Bad1, LPreCAt2, XPreCAt2} = + {AXC, ALC, Bad1, LPreCAt2, XPreCAt2} = extra_edges(AXC1, ALC1, Bad0, DefinedFuns), Bad = map(fun(B) -> {xref_attr, B} end, Bad1), LPreCAt = union(LPreCAt1, LPreCAt2), @@ -904,8 +906,8 @@ do_add_module(S, M, XMod, Unres0, Data) when S#xref.mode =:= functions -> %% {EE, ECallAt} = inter_graph(X, L, LC, XC, LCallAt, XCallAt), Self = self(), - Fun = fun() -> inter_graph(Self, X, L, LC, XC, CallAt) end, - {EE, ECallAt} = + Fun = fun() -> inter_graph(Self, X, L, LC, XC, CallAt) end, + {EE, ECallAt} = xref_utils:subprocess(Fun, [link, {min_heap_size,100000}]), [DefAt2,L2,X2,LCallAt2,XCallAt2,CallAt2,LC2,XC2,EE2,ECallAt2, @@ -977,13 +979,13 @@ extra_edges(CAX, CAL, Bad0, F) -> ALC = restriction(2, restriction(ALC0, F), F), LPreCAt2 = restriction(CAL, ALC), XPreCAt2 = restriction(CAX, AXC), - Bad = Bad0 ++ to_external(difference(AXC0, AXC)) + Bad = Bad0 ++ to_external(difference(AXC0, AXC)) ++ to_external(difference(ALC0, ALC)), {AXC, ALC, Bad, LPreCAt2, XPreCAt2}. no_info(X, L, LC, XC, EE, Unres, NoCalls, NoUnresCalls) -> NoUnres = no_elements(Unres), - [{no_calls, {NoCalls-NoUnresCalls, NoUnresCalls}}, + [{no_calls, {NoCalls-NoUnresCalls, NoUnresCalls}}, {no_function_calls, {no_elements(LC), no_elements(XC)-NoUnres, NoUnres}}, {no_functions, {no_elements(L), no_elements(X)}}, %% Note: this is overwritten in do_set_up(): @@ -1011,10 +1013,10 @@ inter_graph(X, L, LC, XC, CallAt) -> Es = union(LEs, XEs), E1 = to_external(restriction(difference(LC, LEs), XL)), - R0 = xref_utils:xset(reachable(E1, G, []), + R0 = xref_utils:xset(reachable(E1, G, []), [{tspec(func), tspec(fun_edge)}]), true = digraph:delete(G), - + % RL is a set of indirect local calls to exports. RL = restriction(R0, XL), % RX is a set of indirect external calls to exports. @@ -1033,7 +1035,7 @@ inter_graph(X, L, LC, XC, CallAt) -> ?FORMAT("XL=~p~nXEs=~p~nLEs=~p~nE1=~p~nR0=~p~nRL=~p~nRX=~p~nR=~p~n" "EE=~p~nECallAt1=~p~nECallAt2=~p~nECallAt=~p~n~n", - [XL, XEs, LEs, E1, R0, RL, RX, R, EE, + [XL, XEs, LEs, E1, R0, RL, RX, R, EE, ECallAt1, ECallAt2, ECallAt]), {EE, ECallAt}. @@ -1121,7 +1123,7 @@ remove_erase([], D) -> do_add_libraries(Path, Verbose, State) -> message(Verbose, lib_search, []), - {C, E} = xref_utils:list_path(Path, [?Suffix]), + {C, E} = xref_utils:list_path(Path, [?Suffix]), message(Verbose, done, []), MDs = to_external(relation_to_family(relation(C))), %% message(Verbose, lib_check, []), @@ -1160,23 +1162,23 @@ do_set_up(S, VerboseOpt) -> Reply. %% If data has been supplied using add_module/9 (and that is the only -%% sanctioned way), then DefAt, L, X, LCallAt, XCallAt, CallAt, XC, LC, -%% and LU are guaranteed to be functions (with all supplied -%% modules as domain (disregarding unknown modules, that is, modules +%% sanctioned way), then DefAt, L, X, LCallAt, XCallAt, CallAt, XC, LC, +%% and LU are guaranteed to be functions (with all supplied +%% modules as domain (disregarding unknown modules, that is, modules %% not supplied but hosting unknown functions)). %% As a consequence, V and E are also functions. V is defined for unknown %% modules also. %% UU is also a function (thanks to sofs:family_difference/2...). -%% XU on the other hand can be a partial function (that is, not defined +%% XU on the other hand can be a partial function (that is, not defined %% for all modules). U is derived from XU, so U is also partial. %% The inverse variables - LC_1, XC_1, E_1 and EE_1 - are all partial. %% B is also partial. do_set_up(S) when S#xref.mode =:= functions -> ModDictList = dict:to_list(S#xref.modules), - [DefAt0, L, X0, LCallAt, XCallAt, CallAt, LC, XC, LU, + [DefAt0, L, X0, LCallAt, XCallAt, CallAt, LC, XC, LU, EE0, ECallAt, UC, LPredefined, Mod_DF,Mod_DF_1,Mod_DF_2,Mod_DF_3] = make_families(ModDictList, 18), - + {XC_1, XU, XPredefined} = do_set_up_1(XC), LC_1 = user_family(union_of_family(LC)), E_1 = family_union(XC_1, LC_1), @@ -1206,7 +1208,7 @@ do_set_up(S) when S#xref.mode =:= functions -> AM = domain(F1), %% Undef is the union of U0 and Lib: - {Undef, U0, Lib, Lib_DF, Lib_DF_1, Lib_DF_2, Lib_DF_3} = + {Undef, U0, Lib, Lib_DF, Lib_DF_1, Lib_DF_2, Lib_DF_3} = make_libs(XU, F1, AM, S#xref.library_path, S#xref.libraries), {B, U} = make_builtins(U0), X1_B = family_union(X1, B), @@ -1228,22 +1230,22 @@ do_set_up(S) when S#xref.mode =:= functions -> %% way to discard calls to local functions in other modules. EE_conv = converse(union_of_family(EE0)), EE_exported = restriction(EE_conv, union_of_family(X)), - EE_local = + EE_local = specification({external, fun({{M1,_,_},{M2,_,_}}) -> M1 =:= M2 end}, EE_conv), EE_0 = converse(union(EE_local, EE_exported)), EE_1 = user_family(EE_0), - EE1 = partition_family({external, fun({{M1,_,_}, _MFA2}) -> M1 end}, + EE1 = partition_family({external, fun({{M1,_,_}, _MFA2}) -> M1 end}, EE_0), %% Make sure EE is defined for all modules: EE = family_union(family_difference(EE0, EE0), EE1), - IFun = - fun({Mod,EE_M}, XMods) -> - IMFun = + IFun = + fun({Mod,EE_M}, XMods) -> + IMFun = fun(XrefMod) -> - [NoCalls, NoFunctionCalls, + [NoCalls, NoFunctionCalls, NoFunctions, _NoInter] = XrefMod#xref_mod.info, - NewInfo = [NoCalls, NoFunctionCalls, NoFunctions, + NewInfo = [NoCalls, NoFunctionCalls, NoFunctions, {no_inter_function_calls,length(EE_M)}], XrefMod#xref_mod{info = NewInfo} end, @@ -1274,11 +1276,11 @@ do_set_up(S) when S#xref.mode =:= functions -> finish_set_up(S1, Vs); do_set_up(S) when S#xref.mode =:= modules -> ModDictList = dict:to_list(S#xref.modules), - [X0, I0, Mod_DF, Mod_DF_1, Mod_DF_2, Mod_DF_3] = + [X0, I0, Mod_DF, Mod_DF_1, Mod_DF_2, Mod_DF_3] = make_families(ModDictList, 7), I = union_of_family(I0), AM = domain(X0), - + {XU, Predefined} = make_predefined(I, AM), %% Add "hidden" functions to the exports. X1 = family_union(X0, Predefined), @@ -1288,8 +1290,8 @@ do_set_up(S) when S#xref.mode =:= modules -> M2A = make_M2A(ModDictList), {A2R,A} = make_A2R(S#xref.applications), R = set(dict:fetch_keys(S#xref.releases)), - - ME = projection({external, fun({M1,{M2,_F2,_A2}}) -> {M1,M2} end}, + + ME = projection({external, fun({M1,{M2,_F2,_A2}}) -> {M1,M2} end}, family_to_relation(I0)), ME2AE = multiple_relative_product({M2A, M2A}, ME), @@ -1298,7 +1300,7 @@ do_set_up(S) when S#xref.mode =:= modules -> RE = range(AE2RE), %% Undef is the union of U0 and Lib: - {_Undef, U0, Lib, Lib_DF, Lib_DF_1, Lib_DF_2, Lib_DF_3} = + {_Undef, U0, Lib, Lib_DF, Lib_DF_1, Lib_DF_2, Lib_DF_3} = make_libs(XU, X1, AM, S#xref.library_path, S#xref.libraries), {B, U} = make_builtins(U0), X1_B = family_union(X1, B), @@ -1312,7 +1314,7 @@ do_set_up(S) when S#xref.mode =:= modules -> X = family_union(X1, Lib), Empty = empty_set(), - Vs = [{'X',X},{'U',U},{'B',B},{'XU',XU},{v,V}, + Vs = [{'X',X},{'U',U},{'B',B},{'XU',XU},{v,V}, {e,{Empty,Empty}}, {'M',M},{'A',A},{'R',R}, {'AM',AM},{'UM',UM},{'LM',LM}, @@ -1328,10 +1330,10 @@ finish_set_up(S, Vs) -> S1 = S#xref{variables = T}, %% io:format("~p <= state <= ~p~n", [pack:lsize(S), pack:usize(S)]), {ok, S1}. - + do_finish_set_up([{Key, Value} | Vs], T) -> {Type, OType} = var_type(Key), - Val = #xref_var{name = Key, value = Value, vtype = predef, + Val = #xref_var{name = Key, value = Value, vtype = predef, otype = OType, type = Type}, T1 = dict:store(Key, Val, T), do_finish_set_up(Vs, T1); @@ -1362,15 +1364,15 @@ var_type('EE') -> {function, edge}; var_type('LC') -> {function, edge}; var_type('UC') -> {function, edge}; var_type('XC') -> {function, edge}; -var_type('AE') -> {application, edge}; -var_type('ME') -> {module, edge}; +var_type('AE') -> {application, edge}; +var_type('ME') -> {module, edge}; var_type('RE') -> {release, edge}; var_type(_) -> {foo, bar}. make_families(ModDictList, N) -> Fun1 = fun({_,XMod}) -> XMod#xref_mod.data end, Ss = from_sets(map(Fun1, ModDictList)), - %% io:format("~n~p <= module data <= ~p~n", + %% io:format("~n~p <= module data <= ~p~n", %% [pack:lsize(Ss), pack:usize(Ss)]), make_fams(N, Ss, []). @@ -1389,7 +1391,7 @@ make_M2A(ModDictList) -> make_A2R(ApplDict) -> AppDict = dict:to_list(ApplDict), Fun = fun({A,XApp}) -> {A, XApp#xref_app.rel_name} end, - Appl0 = family(map(Fun, AppDict)), + Appl0 = family(map(Fun, AppDict)), AllApps = domain(Appl0), Appl = family_to_relation(Appl0), {Appl, AllApps}. @@ -1445,13 +1447,13 @@ make_libs(XU, F, AM, LibPath, LibDict) -> false -> Libraries = dict:to_list(LibDict), Lb = restriction(a_function(Libraries), UM), - MFun = fun({M,XLib}) -> + MFun = fun({M,XLib}) -> #xref_lib{dir = Dir} = XLib, xref_utils:module_filename(Dir, M) end, map(MFun, to_external(Lb)) end, - Fun = fun(FileName, Deprs) -> + Fun = fun(FileName, Deprs) -> case beam_lib:chunks(FileName, [exports, attributes]) of {ok, {M, [{exports,X}, {attributes,A}]}} -> Exports = mfa_exports(X, A, M), @@ -1496,14 +1498,14 @@ user_family(R) -> partition_family({external, fun({_MFA1, {M2,_,_}}) -> M2 end}, R). do_variables(State) -> - Fun = fun({Name, #xref_var{vtype = user}}, {P,U}) -> + Fun = fun({Name, #xref_var{vtype = user}}, {P,U}) -> {P,[Name | U]}; - ({Name, #xref_var{vtype = predef}}, A={P,U}) -> + ({Name, #xref_var{vtype = predef}}, A={P,U}) -> case atom_to_list(Name) of [H|_] when H>= $a, H=<$z -> A; _Else -> {[Name | P], U} end; - ({{tmp, V}, _}, A) -> + ({{tmp, V}, _}, A) -> io:format("Bug in ~p: temporary ~p~n", [?MODULE, V]), A; (_V, A) -> A end, @@ -1565,7 +1567,7 @@ do_info(S, libraries) -> map(fun({_L,XLib}) -> lib_info(XLib) end, D); do_info(_S, I) -> error({no_such_info, I}). - + do_info(S, Type, E) when is_atom(E) -> do_info(S, Type, [E]); do_info(S, modules, Modules0) when is_list(Modules0) -> @@ -1598,7 +1600,7 @@ find_info([E | Es], Dict, Error) -> {ok, X} -> [X | find_info(Es, Dict, Error)] end; -find_info([], _Dict, _Error) -> +find_info([], _Dict, _Error) -> []. %% -> {[{AppName, RelName}], [{RelName, XApp}]} @@ -1618,7 +1620,7 @@ rel_apps(S) -> rel_apps_sums(AR, RRA0, S) -> AppMods = app_mods(S), % [{AppName, XMod}] RRA1 = relation_to_family(relation(RRA0)), - RRA = inverse(substitution(1, RRA1)), + RRA = inverse(substitution(1, RRA1)), %% RRA is [{RelName,{RelName,[XApp]}}] RelMods = relative_product1(relation(AR), relation(AppMods)), RelAppsMods = relative_product1(RRA, RelMods), @@ -1630,7 +1632,7 @@ rel_apps_sums(AR, RRA0, S) -> %% -> [{AppName, XMod}] app_mods(S) -> D = sort(dict:to_list(S#xref.modules)), - Fun = fun({_M,XMod}, Acc) -> + Fun = fun({_M,XMod}, Acc) -> case XMod#xref_mod.app_name of [] -> Acc; [AppName] -> [{AppName, XMod} | Acc] @@ -1639,7 +1641,7 @@ app_mods(S) -> foldl(Fun, [], D). mod_info(XMod) -> - #xref_mod{name = M, app_name = AppName, builtins = BuiltIns, + #xref_mod{name = M, app_name = AppName, builtins = BuiltIns, dir = Dir, info = Info} = XMod, App = sup_info(AppName), {M, [{application, App}, {builtins, BuiltIns}, {directory, Dir} | Info]}. @@ -1649,7 +1651,7 @@ app_info({AppName, ModSums}, S) -> #xref_app{rel_name = RelName, vsn = Vsn, dir = Dir} = XApp, Release = sup_info(RelName), {AppName, [{directory,Dir}, {release, Release}, {version,Vsn} | ModSums]}. - + rel_info({{RelName, XApps}, ModSums}, S) -> NoApps = length(XApps), XRel = dict:fetch(RelName, S#xref.releases), @@ -1678,16 +1680,16 @@ no_sum(S, L) when S#xref.mode =:= modules -> [{no_analyzed_modules, length(L)}]. no_sum([XMod | D], C0, UC0, LC0, XC0, UFC0, L0, X0, EV0, NoM) -> - [{no_calls, {C,UC}}, + [{no_calls, {C,UC}}, {no_function_calls, {LC,XC,UFC}}, {no_functions, {L,X}}, {no_inter_function_calls, EV}] = XMod#xref_mod.info, no_sum(D, C0+C, UC0+UC, LC0+LC, XC0+XC, UFC0+UFC, L0+L, X0+X, EV0+EV, NoM); no_sum([], C, UC, LC, XC, UFC, L, X, EV, NoM) -> [{no_analyzed_modules, NoM}, - {no_calls, {C,UC}}, + {no_calls, {C,UC}}, {no_function_calls, {LC,XC,UFC}}, - {no_functions, {L,X}}, + {no_functions, {L,X}}, {no_inter_function_calls, EV}]. %% -> ok | throw(Error) @@ -1712,20 +1714,20 @@ warnings(Flag, Message, [F | Fs]) -> %% pack(term()) -> term() %% %% The identify function. The returned term does not use more heap -%% than the given term. Tuples that are equal (=:=/2) are made +%% than the given term. Tuples that are equal (=:=/2) are made %% "the same". %% %% The process dictionary is used because it seems to be faster than %% anything else right now... %% %pack(T) -> T; -pack(T) -> +pack(T) -> PD = erase(), NT = pack1(T), %% true = T =:= NT, %% io:format("erasing ~p elements...~n", [length(erase())]), erase(), % wasting heap (and time)... - map(fun({K,V}) -> put(K, V) end, PD), + foreach(fun({K,V}) -> put(K, V) end, PD), NT. pack1(C) when not is_tuple(C), not is_list(C) -> diff --git a/lib/tools/src/xref_compiler.erl b/lib/tools/src/xref_compiler.erl index 67ac8c617d..1445e135be 100644 --- a/lib/tools/src/xref_compiler.erl +++ b/lib/tools/src/xref_compiler.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -31,21 +31,23 @@ -define(CALL(F), ok). -endif. +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([compile/2]). -export([update_graph_counter/3]). -export([format_error/1]). --import(lists, +-import(lists, [concat/1, foldl/3, nthtail/2, reverse/1, sort/1, sublist/2]). -import(sofs, [composite/2, difference/2, empty_set/0, from_term/1, intersection/2, is_empty_set/1, multiple_relative_product/2, projection/2, relation/1, relation_to_family/1, - restriction/2, substitution/2, to_external/1, union/2, - union_of_family/1]). + restriction/2, specification/2, substitution/2, + to_external/1, union/2, union_of_family/1]). %% %% Exported functions @@ -75,7 +77,7 @@ compile(Chars, Table) -> {error, Info, Line} -> error({parse_error, Line, Info}) end. - + format_error({error, Module, Error}) -> Module:format_error(Error); format_error({parse_error, Line, Error}) -> @@ -115,7 +117,7 @@ statements([Stmt={assign, VarType, Name, E} | Stmts0], Table, L, UV) -> throw_error({variable_reassigned, xref_parser:t2s(Stmt)}); error -> {Type, OType, NewE} = t_expr(E, Table), - Val = #xref_var{name = Name, vtype = VarType, + Val = #xref_var{name = Name, vtype = VarType, otype = OType, type = Type}, NewTable = dict:store(Name, Val, Table), Stmts = if Stmts0 =:= [] -> [{variable, Name}]; true -> Stmts0 end, @@ -128,9 +130,9 @@ statements([Expr], Table, L, UV) -> E1 = un_familiarize(Type, OType, NewE), NE = case {Type, OType} of %% Edges with empty sets of line numbers are removed. - {{line, _}, edge} -> + {{line, _}, edge} -> {relation_to_family, E1}; - {_Type, edge_closure} -> + {_Type, edge_closure} -> %% Fake a closure usage, just to make sure it is destroyed. E2 = {fun graph_access/2, E1, E1}, {fun(_E) -> 'closure()' end, E2}; @@ -163,7 +165,7 @@ t_expr(E, Table) -> %%% Constant = atom() | {atom(), atom()} | MFA | {MFA, MFA} %%% Call = atom() % function in the sofs module %%% | fun() -%%% Type = {line, LineType} | function | module | application | release +%%% Type = {line, LineType} | function | module | application | release %%% | number %%% LineType = line | local_call | external_call | export_call | all_line_call %%% VarType = predef | user | tmp @@ -182,7 +184,7 @@ check_expr({variable, Name}, Table) -> case dict:find(Name, Table) of {ok, #xref_var{vtype = VarType, otype = OType, type = Type}} -> V0 = {variable, {VarType, Name}}, - V = case {VarType, Type, OType} of + V = case {VarType, Type, OType} of {predef, release, _} -> V0; {predef, application, _} -> V0; {predef, module, _} -> V0; @@ -212,7 +214,7 @@ check_expr(Expr={set, SOp, E}, Table) -> {edge_set, domain} -> vertex_set; {edge_set, weak} -> edge_set; {edge_set, strict} -> edge_set; - _ -> + _ -> throw_error({type_error, xref_parser:t2s(Expr)}) end, Op = set_op(SOp), @@ -223,10 +225,10 @@ check_expr(Expr={graph, Op, E}, Table) -> case Type of {line, _LineType} -> throw_error({type_error, xref_parser:t2s(Expr)}); - _Else -> + _Else -> ok end, - OType = + OType = case {NOType, Op} of {edge, components} -> vertex_set; {edge, condensation} -> edge_set; @@ -237,7 +239,7 @@ check_expr(Expr={graph, Op, E}, Table) -> %% Neither need nor want these ones: %% {edge_set, closure} -> edge_set_closure; %% {edge_set, components} -> vertex_set_set; - _ -> + _ -> throw_error({type_error, xref_parser:t2s(Expr)}) end, E2 = {convert, NOType, edge_closure, E1}, @@ -271,10 +273,10 @@ check_expr(Expr={set, SOp, E1, E2}, Table) -> number -> {expr, number, number, {call, ari_op(SOp), NE1, NE2}}; _Else -> % set - {Type, NewE1, NewE2} = + {Type, NewE1, NewE2} = case {type_ord(Type1), type_ord(Type2)} of {T1, T2} when T1 =:= T2 -> - %% Example: if Type1 = {line, line} and + %% Example: if Type1 = {line, line} and %% Type2 = {line, export_line}, then this is not %% correct, but works: {Type1, NE1, NE2}; @@ -296,7 +298,7 @@ check_expr(Expr={restr, ROp, E1, E2}, Table) -> throw_error({type_error, xref_parser:t2s(Expr)}); {_Type1, {line, _LineType2}} -> throw_error({type_error, xref_parser:t2s(Expr)}); - _ -> + _ -> ok end, case {OType1, OType2} of @@ -307,14 +309,14 @@ check_expr(Expr={restr, ROp, E1, E2}, Table) -> {edge, vertex} -> restriction(ROp, E1, Type1, NE1, Type2, NE2); {edge_closure, vertex} when ROp =:= '|||' -> - {expr, _, _, R1} = + {expr, _, _, R1} = closure_restriction('|', Type1, Type2, OType2, NE1, NE2), - {expr, _, _, R2} = + {expr, _, _, R2} = closure_restriction('||', Type1, Type2, OType2, NE1, NE2), {expr, Type1, edge, {call, intersection, R1, R2}}; - {edge_closure, vertex} -> + {edge_closure, vertex} -> closure_restriction(ROp, Type1, Type2, OType2, NE1, NE2); - _ -> + _ -> throw_error({type_error, xref_parser:t2s(Expr)}) end; check_expr(Expr={path, E1, E2}, Table) -> @@ -330,7 +332,7 @@ check_expr(Expr={path, E1, E2}, Table) -> end, E2b = {convert, OType2, Type2, Type1, E2a}, {OType1, NE1} = path_arg(OType1a, E1a), - NE2 = case {OType1, OType2} of + NE2 = case {OType1, OType2} of {path, edge} -> {convert, OType2, edge_closure, E2b}; {path, edge_closure} when Type1 =:= Type2 -> E2b; _ -> throw_error({type_error, xref_parser:t2s(Expr)}) @@ -347,7 +349,7 @@ check_expr({regexpr, RExpr, Type0}, _Table) -> release -> 'R' end, Var = {variable, {predef, V}}, - Call = {call, fun(E, V2) -> xref_utils:regexpr(E, V2) end, + Call = {call, fun(E, V2) -> xref_utils:regexpr(E, V2) end, {constants, RExpr}, Var}, {expr, Type, vertex, Call}; check_expr(C={constant, _Type, _OType, _C}, Table) -> @@ -368,15 +370,15 @@ check_conversion(OType, Type1, Type2, Expr) -> end. %% Allowed conversions. -conversions(_OType, {line, LineType}, {line, LineType}) -> ok; +conversions(_OType, {line, LineType}, {line, LineType}) -> ok; conversions(edge, {line, _}, {line, all_line_call}) -> ok; -conversions(edge, From, {line, Line}) +conversions(edge, From, {line, Line}) when is_atom(From), Line =/= all_line_call -> ok; conversions(vertex, From, {line, line}) when is_atom(From) -> ok; conversions(vertex, From, To) when is_atom(From), is_atom(To) -> ok; conversions(edge, From, To) when is_atom(From), is_atom(To) -> ok; %% "Extra": -conversions(edge, {line, Line}, To) +conversions(edge, {line, Line}, To) when is_atom(To), Line =/= all_line_call -> ok; conversions(vertex, {line, line}, To) when is_atom(To) -> ok; conversions(_OType, _From, _To) -> not_ok. @@ -399,7 +401,7 @@ ari_op(difference) -> fun(X, Y) -> X - Y end. restriction(ROp, E1, Type1, NE1, Type2, NE2) -> {Column, _} = restr_op(ROp), - case NE1 of + case NE1 of {call, union_of_family, _E} when ROp =:= '|' -> restriction(Column, Type1, E1, Type2, NE2); {call, union_of_family, _E} when ROp =:= '||' -> @@ -455,8 +457,8 @@ check_constants(Cs=[C={constant, Type0, OType, _Con} | Cs1], Table) -> E = function_vertices_to_family(Type, OType, {constants, S}), {expr, Type, OType, E}; [{Type1, [C1|_]}, {Type2, [C2|_]} | _] -> - throw_error({type_mismatch, - make_vertex(Type1, C1), + throw_error({type_mismatch, + make_vertex(Type1, C1), make_vertex(Type2, C2)}) end. @@ -467,7 +469,7 @@ check_mix([C={constant, Type, OType, _Con} | Cs], Type0, OType, _C0) check_mix(Cs, Type, OType, C); check_mix([C | _], _Type0, _OType0, C0) -> throw_error({type_mismatch, xref_parser:t2s(C0), xref_parser:t2s(C)}); -check_mix([], _Type0, _OType0, _C0) -> +check_mix([], _Type0, _OType0, _C0) -> ok. split(Types, Cs, Table) -> @@ -478,11 +480,11 @@ split([Type | Types], Vs, AllSoFar, _Type, Table, L) -> S0 = known_vertices(Type, Vs, Table), S = difference(S0, AllSoFar), case is_empty_set(S) of - true -> + true -> split(Types, Vs, AllSoFar, Type, Table, L); - false -> + false -> All = union(AllSoFar, S0), - split(Types, Vs, All, Type, Table, + split(Types, Vs, All, Type, Table, [{Type, to_external(S)} | L]) end; split([], Vs, All, Type, _Table, L) -> @@ -491,7 +493,7 @@ split([], Vs, All, Type, _Table, L) -> [C|_] -> throw_error({unknown_constant, make_vertex(Type, C)}) end. -make_vertex(Type, C) -> +make_vertex(Type, C) -> xref_parser:t2s({constant, Type, vertex, C}). constant_vertices([{constant, _Type, edge, {A,B}} | Cs], L) -> @@ -504,7 +506,7 @@ constant_vertices([], L) -> known_vertices('Fun', Cs, T) -> M = projection(1, Cs), F = union_of_family(restriction(fetch_value(v, T), M)), - intersection(Cs, F); + union(bifs(Cs), intersection(Cs, F)); known_vertices('Mod', Cs, T) -> intersection(Cs, fetch_value('M', T)); known_vertices('App', Cs, T) -> @@ -512,6 +514,11 @@ known_vertices('App', Cs, T) -> known_vertices('Rel', Cs, T) -> intersection(Cs, fetch_value('R', T)). +bifs(Cs) -> + specification({external, + fun({M,F,A}) -> xref_utils:is_builtin(M, F, A) end}, + Cs). + function_vertices_to_family(function, vertex, E) -> {call, partition_family, 1, E}; function_vertices_to_family(_Type, _OType, E) -> @@ -567,11 +574,11 @@ convert(E, OType, FromType, ToType) -> general(_ObjectType, FromType, ToType, X) when FromType =:= ToType -> X; -general(edge, {line, _LineType}, ToType, LEs) -> +general(edge, {line, _LineType}, ToType, LEs) -> VEs = {projection, ?Q({external, fun({V1V2,_Ls}) -> V1V2 end}), LEs}, general(edge, function, ToType, VEs); general(edge, function, ToType, VEs) -> - MEs = {projection, + MEs = {projection, ?Q({external, fun({{M1,_,_},{M2,_,_}}) -> {M1,M2} end}), VEs}, general(edge, module, ToType, MEs); @@ -580,7 +587,7 @@ general(edge, module, ToType, MEs) -> general(edge, application, ToType, AEs); general(edge, application, release, AEs) -> {image, {get, ae}, AEs}; -general(vertex, {line, _LineType}, ToType, L) -> +general(vertex, {line, _LineType}, ToType, L) -> V = {partition_family, ?Q(1), {domain, L}}, general(vertex, function, ToType, V); general(vertex, function, ToType, V) -> @@ -595,18 +602,18 @@ general(vertex, application, release, A) -> special(_ObjectType, FromType, ToType, X) when FromType =:= ToType -> X; special(edge, {line, _LineType}, {line, all_line_call}, Calls) -> - {put, ?T(mods), - {projection, - ?Q({external, fun({{{M1,_,_},{M2,_,_}},_}) -> {M1,M2} end}), + {put, ?T(mods), + {projection, + ?Q({external, fun({{{M1,_,_},{M2,_,_}},_}) -> {M1,M2} end}), Calls}, - {put, ?T(def_at), + {put, ?T(def_at), {union, {image, {get, def_at}, - {union, {domain, {get, ?T(mods)}}, + {union, {domain, {get, ?T(mods)}}, {range, {get, ?T(mods)}}}}}, {fun funs_to_lines/2, {get, ?T(def_at)}, Calls}}}; special(edge, function, {line, LineType}, VEs) -> - Var = if + Var = if LineType =:= line -> call_at; LineType =:= export_call -> e_call_at; LineType =:= local_call -> l_call_at; @@ -615,9 +622,9 @@ special(edge, function, {line, LineType}, VEs) -> line_edges(VEs, Var); special(edge, module, ToType, MEs) -> VEs = {image, - {projection, + {projection, ?Q({external, fun(FE={{M1,_,_},{M2,_,_}}) -> {{M1,M2},FE} end}), - {union, + {union, {image, {get, e}, {projection, ?Q({external, fun({M1,_M2}) -> M1 end}), MEs}}}}, MEs}, @@ -629,7 +636,7 @@ special(edge, release, ToType, REs) -> AEs = {inverse_image, {get, ae}, REs}, special(edge, application, ToType, AEs); special(vertex, function, {line, _LineType}, V) -> - {restriction, + {restriction, {union_of_family, {restriction, {get, def_at}, {domain, V}}}, {union_of_family, V}}; special(vertex, module, ToType, M) -> @@ -643,15 +650,15 @@ special(vertex, release, ToType, R) -> special(vertex, application, ToType, A). line_edges(VEs, CallAt) -> - {put, ?T(ves), VEs, - {put, ?T(m1), - {projection, ?Q({external, fun({{M1,_,_},_}) -> M1 end}), + {put, ?T(ves), VEs, + {put, ?T(m1), + {projection, ?Q({external, fun({{M1,_,_},_}) -> M1 end}), {get, ?T(ves)}}, {image, {projection, ?Q({external, fun(C={VV,_L}) -> {VV,C} end}), {union, {image, {get, CallAt}, {get, ?T(m1)}}}}, {get, ?T(ves)}}}}. -%% {(((v1,l1),(v2,l2)),l) : +%% {(((v1,l1),(v2,l2)),l) : %% (v1,l1) in DefAt and (v2,l2) in DefAt and ((v1,v2),L) in CallAt} funs_to_lines(DefAt, CallAt) -> T1 = multiple_relative_product({DefAt, DefAt}, projection(1, CallAt)), @@ -765,7 +772,7 @@ save_vars([], _D, Vs, UVs, L) -> %% Traverses the expression again, this time using more or less the %% inverse of the table created by find_nodes. The first time a node -%% is visited, its children are traversed, the following times a +%% is visited, its children are traversed, the following times a %% get instructions are inserted (using the saved value). make_instructions(N, UserVars, D) -> {D1, Is0} = make_instrs(N, D, []), @@ -777,9 +784,9 @@ make_instructions(N, UserVars, D) -> make_more_instrs([UV | UVs], D, Is) -> case dict:find(UV, D) of - error -> + error -> make_more_instrs(UVs, D, Is); - _Else -> + _Else -> {ND, NIs} = make_instrs(UV, D, Is), make_more_instrs(UVs, ND, [pop | NIs]) end; @@ -844,17 +851,17 @@ evaluate([{quote, Val} | P], T, S) -> evaluate(P, T, [Val | S]); evaluate([{get, Var} | P], T, S) when is_atom(Var) -> % predefined Value = fetch_value(Var, T), - Val = case Value of + Val = case Value of {R, _} -> R; % relation _ -> Value % simple set end, - evaluate(P, T, [Val | S]); + evaluate(P, T, [Val | S]); evaluate([{get, {inverse, Var}} | P], T, S) -> % predefined, inverse {_, R} = fetch_value(Var, T), - evaluate(P, T, [R | S]); + evaluate(P, T, [R | S]); evaluate([{get, {user, Var}} | P], T, S) -> Val = fetch_value(Var, T), - evaluate(P, T, [Val | S]); + evaluate(P, T, [Val | S]); evaluate([{get, Var} | P], T, S) -> % tmp evaluate(P, T, [dict:fetch(Var, T) | S]); evaluate([{save, Var={tmp, _}} | P], T, S=[Val | _]) -> @@ -862,7 +869,7 @@ evaluate([{save, Var={tmp, _}} | P], T, S=[Val | _]) -> evaluate(P, dict:store(Var, Val, T1), S); evaluate([{save, {user, Name}} | P], T, S=[Val | _]) -> #xref_var{vtype = user, otype = OType, type = Type} = dict:fetch(Name, T), - NewVar = #xref_var{name = Name, value = Val, + NewVar = #xref_var{name = Name, value = Val, vtype = user, otype = OType, type = Type}, T1 = update_graph_counter(Val, +1, T), NT = dict:store(Name, NewVar, T1), @@ -889,7 +896,7 @@ update_graph_counter(Value, Inc, T) -> error when Inc =:= 1 -> dict:store(Value, 1, T) end; - _EXIT -> + _EXIT -> T end. diff --git a/lib/tools/src/xref_parser.yrl b/lib/tools/src/xref_parser.yrl index e23dce1dec..1279ece061 100644 --- a/lib/tools/src/xref_parser.yrl +++ b/lib/tools/src/xref_parser.yrl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -169,12 +169,11 @@ is_prefix_op('#') -> numeric; is_prefix_op(_) -> false. check_regexp(String) -> - case regexp:parse(String) of + case re:compile(String) of {ok, _Expr} -> {regexpr, String}; - {error, Reason} -> - F = regexp:format_error(Reason), - return_error(0, ["invalid_regexp", String, F]) + {error, {ErrString, Position}} -> + return_error(Position, ["invalid_regexp", String, ErrString]) end. check_regexp_variable('_') -> diff --git a/lib/tools/src/xref_reader.erl b/lib/tools/src/xref_reader.erl index db755c31d8..d22f0df164 100644 --- a/lib/tools/src/xref_reader.erl +++ b/lib/tools/src/xref_reader.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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(xref_reader). @@ -22,7 +22,7 @@ -import(lists, [keysearch/3, member/2, reverse/1]). --record(xrefr, +-record(xrefr, {module=[], function=[], def_at=[], @@ -59,15 +59,15 @@ module(Module, Forms, CollectBuiltins, X, DF) -> Attrs = [{Attr,V} || {attribute,_Line,Attr,V} <- Forms], IsAbstract = xref_utils:is_abstract_module(Attrs), - S = #xrefr{module = Module, builtins_too = CollectBuiltins, + S = #xrefr{module = Module, builtins_too = CollectBuiltins, is_abstr = IsAbstract, x = X, df = DF}, forms(Forms, S). forms([F | Fs], S) -> S1 = form(F, S), forms(Fs, S1); -forms([], S) -> - #xrefr{module = M, def_at = DefAt, +forms([], S) -> + #xrefr{module = M, def_at = DefAt, l_call_at = LCallAt, x_call_at = XCallAt, el = LC, ex = XC, x = X, df = Depr, lattrs = AL, xattrs = AX, battrs = B, unresolved = U} = S, @@ -75,7 +75,7 @@ forms([], S) -> {ok, M, {DefAt, LCallAt, XCallAt, LC, XC, X, Attrs, Depr}, U}. form({attribute, Line, xref, Calls}, S) -> % experimental - #xrefr{module = M, function = Fun, + #xrefr{module = M, function = Fun, lattrs = L, xattrs = X, battrs = B} = S, attr(Calls, Line, M, Fun, L, X, B, S); form({attribute, _Line, _Attr, _Val}, S) -> @@ -110,12 +110,12 @@ clauses([{clause, _Line, _H, G, B} | Cs], FunVars, Matches, S) -> S2 = expr(B, S1), S3 = S2#xrefr{funvars = FunVars, matches = Matches}, clauses(Cs, S3); -clauses([], _FunVars, _Matches, S) -> +clauses([], _FunVars, _Matches, S) -> S. attr([E={From, To} | As], Ln, M, Fun, AL, AX, B, S) -> case mfa(From, M) of - {_, _, MFA} when MFA =:= Fun; [] =:= Fun -> + {_, _, MFA} when MFA =:= Fun; [] =:= Fun -> attr(From, To, Ln, M, Fun, AL, AX, B, S, As, E); {_, _, _} -> attr(As, Ln, M, Fun, AL, AX, [E | B], S); @@ -164,7 +164,7 @@ expr({call, Line, %% Added in R10B-6. M:F/A. expr({'fun', Line, {function, Mod, Fun, Arity}}, S); expr({'fun', Line, {function, Mod, Name, Arity}}, S) -> - %% Added in R10B-6. M:F/A. + %% Added in R10B-6. M:F/A. As = lists:duplicate(Arity, {atom, Line, foo}), external_call(Mod, Name, As, Line, false, S); expr({'fun', Line, {function, Name, Arity}, _Extra}, S) -> @@ -183,7 +183,7 @@ expr({call, Line, {remote, _Line, Mod, Name}, As}, S) -> expr({call, Line, F, As}, S) -> external_call(erlang, apply, [F, list2term(As)], Line, true, S); expr({match, _Line, {var,_,Var}, {'fun', _, {clauses, Cs}, _Extra}}, S) -> - %% This is what is needed in R7 to avoid warnings for the functions + %% This is what is needed in R7 to avoid warnings for the functions %% that are passed around by the "expansion" of list comprehension. S1 = S#xrefr{funvars = [Var | S#xrefr.funvars]}, clauses(Cs, S1); @@ -192,6 +192,14 @@ expr({match, _Line, {var,_,Var}, E}, S) -> %% Args = [A,B], apply(m, f, Args) S1 = S#xrefr{matches = [{Var, E} | S#xrefr.matches]}, expr(E, S1); +expr({op, _Line, 'orelse', Op1, Op2}, S) -> + expr([Op1, Op2], S); +expr({op, _Line, 'andalso', Op1, Op2}, S) -> + expr([Op1, Op2], S); +expr({op, Line, Op, Operand1, Operand2}, S) -> + external_call(erlang, Op, [Operand1, Operand2], Line, false, S); +expr({op, Line, Op, Operand}, S) -> + external_call(erlang, Op, [Operand], Line, false, S); expr(T, S) when is_tuple(T) -> expr(tuple_to_list(T), S); expr([E | Es], S) -> @@ -241,13 +249,13 @@ external_call(Mod, Fun, ArgsList, Line, X, S) -> _Else -> % apply2, 1 or 2 check_funarg(W, ArgsList, Line, S1) end. - + eval_args(Mod, Fun, ArgsTerm, Line, S, ArgsList, Extra) -> {IsSimpleCall, M, F} = mod_fun(Mod, Fun), case term2list(ArgsTerm, [], S) of undefined -> S1 = unresolved(M, F, -1, Line, S), - expr(ArgsList, S1); + expr(ArgsList, S1); ArgsList2 when not IsSimpleCall -> S1 = unresolved(M, F, length(ArgsList2), Line, S), expr(ArgsList, S1); @@ -288,14 +296,14 @@ fun_args(apply2, [FunArg, Args]) -> {FunArg, Args}; fun_args(1, [FunArg | Args]) -> {FunArg, Args}; fun_args(2, [_Node, FunArg | Args]) -> {FunArg, Args}. -list2term([A | As]) -> +list2term([A | As]) -> {cons, 0, A, list2term(As)}; -list2term([]) -> +list2term([]) -> {nil, 0}. term2list({cons, _Line, H, T}, L, S) -> term2list(T, [H | L], S); -term2list({nil, _Line}, L, _S) -> +term2list({nil, _Line}, L, _S) -> reverse(L); term2list({var, _, Var}, L, S) -> case keysearch(Var, 1, S#xrefr.matches) of @@ -332,11 +340,11 @@ handle_call(Locality, To0, Line, S, IsUnres) -> true -> S end, - case Locality of - local -> + case Locality of + local -> S1#xrefr{el = [Call | S1#xrefr.el], l_call_at = [CallAt | S1#xrefr.l_call_at]}; - external -> + external -> S1#xrefr{ex = [Call | S1#xrefr.ex], x_call_at = [CallAt | S1#xrefr.x_call_at]} end. diff --git a/lib/tools/src/xref_utils.erl b/lib/tools/src/xref_utils.erl index 680b7e8aac..9d4a175d88 100644 --- a/lib/tools/src/xref_utils.erl +++ b/lib/tools/src/xref_utils.erl @@ -18,6 +18,8 @@ %% -module(xref_utils). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([xset/2]). -export([is_directory/1, file_info/1, fa_to_mfa/2]). @@ -640,22 +642,22 @@ neighbours([], G, Fun, VT, L, _V, Vs) -> neighbours(Vs, G, Fun, VT, L). match_list(L, RExpr) -> - {ok, Expr} = regexp:parse(RExpr), + {ok, Expr} = re:compile(RExpr), filter(fun(E) -> match(E, Expr) end, L). match_one(VarL, Con, Col) -> select_each(VarL, fun(E) -> Con =:= element(Col, E) end). match_many(VarL, RExpr, Col) -> - {ok, Expr} = regexp:parse(RExpr), + {ok, Expr} = re:compile(RExpr), select_each(VarL, fun(E) -> match(element(Col, E), Expr) end). match(I, Expr) when is_integer(I) -> S = integer_to_list(I), - {match, 1, length(S)} =:= regexp:first_match(S, Expr); + {match, [{0,length(S)}]} =:= re:run(S, Expr, [{capture, first}]); match(A, Expr) when is_atom(A) -> S = atom_to_list(A), - {match, 1, length(S)} =:= regexp:first_match(S, Expr). + {match, [{0,length(S)}]} =:= re:run(S, Expr, [{capture, first}]). select_each([{Mod,Funs} | L], Pred) -> case filter(Pred, Funs) of diff --git a/lib/tools/test/eprof_SUITE.erl b/lib/tools/test/eprof_SUITE.erl index 028fea8fe1..67607c6cf2 100644 --- a/lib/tools/test/eprof_SUITE.erl +++ b/lib/tools/test/eprof_SUITE.erl @@ -20,10 +20,89 @@ -include("test_server.hrl"). --export([all/1,tiny/1,eed/1]). +-export([all/1,tiny/1,eed/1,basic/1]). -all(suite) -> [tiny,eed]. +all(suite) -> [basic,tiny,eed]. +basic(suite) -> []; +basic(Config) when is_list(Config) -> + + %% load eprof_test and change directory + + ?line {ok, OldCurDir} = file:get_cwd(), + Datadir = ?config(data_dir, Config), + Privdir = ?config(priv_dir, Config), + ?line {ok,eprof_test} = compile:file(filename:join(Datadir, "eprof_test"), + [trace,{outdir, Privdir}]), + ?line ok = file:set_cwd(Privdir), + ?line code:purge(eprof_test), + ?line {module,eprof_test} = code:load_file(eprof_test), + + %% rootset profiling + + ?line ensure_eprof_stopped(), + ?line profiling = eprof:profile([self()]), + ?line {error, already_profiling} = eprof:profile([self()]), + ?line profiling_stopped = eprof:stop_profiling(), + ?line profiling_already_stopped = eprof:stop_profiling(), + ?line profiling = eprof:start_profiling([self(),self(),self()]), + ?line profiling_stopped = eprof:stop_profiling(), + + %% with patterns + + ?line profiling = eprof:start_profiling([self()], {?MODULE, '_', '_'}), + ?line {error, already_profiling} = eprof:start_profiling([self()], {?MODULE, '_', '_'}), + ?line profiling_stopped = eprof:stop_profiling(), + ?line profiling = eprof:start_profiling([self()], {?MODULE, start_stop, '_'}), + ?line profiling_stopped = eprof:stop_profiling(), + ?line profiling = eprof:start_profiling([self()], {?MODULE, start_stop, 1}), + ?line profiling_stopped = eprof:stop_profiling(), + + %% with fun + + ?line {ok, _} = eprof:profile(fun() -> eprof_test:go(10) end), + ?line profiling = eprof:profile([self()]), + ?line {error, already_profiling} = eprof:profile(fun() -> eprof_test:go(10) end), + ?line profiling_stopped = eprof:stop_profiling(), + ?line {ok, _} = eprof:profile(fun() -> eprof_test:go(10) end), + ?line {ok, _} = eprof:profile([], fun() -> eprof_test:go(10) end), + ?line Pid = whereis(eprof), + ?line {ok, _} = eprof:profile(erlang:processes() -- [Pid], fun() -> eprof_test:go(10) end), + ?line {ok, _} = eprof:profile([], fun() -> eprof_test:go(10) end, {eprof_test, '_', '_'}), + ?line {ok, _} = eprof:profile([], fun() -> eprof_test:go(10) end, {eprof_test, go, '_'}), + ?line {ok, _} = eprof:profile([], fun() -> eprof_test:go(10) end, {eprof_test, go, 1}), + ?line {ok, _} = eprof:profile([], fun() -> eprof_test:go(10) end, {eprof_test, dec, 1}), + + %% error case + + ?line error = eprof:profile([Pid], fun() -> eprof_test:go(10) end), + ?line Pid = whereis(eprof), + ?line error = eprof:profile([Pid], fun() -> eprof_test:go(10) end), + ?line A = spawn(fun() -> receive _ -> ok end end), + ?line profiling = eprof:profile([A]), + ?line true = exit(A, kill_it), + ?line profiling_stopped = eprof:stop_profiling(), + ?line {error,_} = eprof:profile(fun() -> a = b end), + + %% with mfa + + ?line {ok, _} = eprof:profile([], eprof_test, go, [10]), + ?line {ok, _} = eprof:profile([], eprof_test, go, [10], {eprof_test, dec, 1}), + + %% dump + + ?line {ok, _} = eprof:profile([], fun() -> eprof_test:go(10) end, {eprof_test, '_', '_'}), + ?line [{_, Mfas}] = eprof:dump(), + ?line Dec_mfa = {eprof_test, dec, 1}, + ?line Go_mfa = {eprof_test, go, 1}, + ?line {value, {Go_mfa, { 1, _Time1}}} = lists:keysearch(Go_mfa, 1, Mfas), + ?line {value, {Dec_mfa, {11, _Time2}}} = lists:keysearch(Dec_mfa, 1, Mfas), + + %% change current working directory + + ?line ok = file:set_cwd(OldCurDir), + ?line stopped = eprof:stop(), + ok. tiny(suite) -> []; tiny(Config) when is_list(Config) -> @@ -40,11 +119,11 @@ tiny(Config) when is_list(Config) -> ?line code:purge(eprof_suite_test), ?line {module,eprof_suite_test} = code:load_file(eprof_suite_test), ?line {ok,_Pid} = eprof:start(), - ?line nothing_to_analyse = eprof:analyse(), - ?line nothing_to_analyse = eprof:total_analyse(), + ?line nothing_to_analyze = eprof:analyze(), + ?line nothing_to_analyze = eprof:analyze(total), ?line eprof:profile([], eprof_suite_test, test, [Config]), - ?line ok = eprof:analyse(), - ?line ok = eprof:total_analyse(), + ?line ok = eprof:analyze(), + ?line ok = eprof:analyze(total), ?line ok = eprof:log("eprof_SUITE_logfile"), ?line stopped = eprof:stop(), ?line ?t:timetrap_cancel(TTrap), @@ -79,8 +158,8 @@ eed(Config) when is_list(Config) -> ?line {ok,ok} = eprof:profile([], eed, file, [Script]), ?line {T3,_} = statistics(runtime), ?line profiling_already_stopped = eprof:stop_profiling(), - ?line ok = eprof:analyse(), - ?line ok = eprof:total_analyse(), + ?line ok = eprof:analyze(), + ?line ok = eprof:analyze(total), ?line ok = eprof:log("eprof_SUITE_logfile"), ?line stopped = eprof:stop(), ?line ?t:timetrap_cancel(TTrap), diff --git a/lib/tools/test/eprof_SUITE_data/eprof_test.erl b/lib/tools/test/eprof_SUITE_data/eprof_test.erl new file mode 100644 index 0000000000..33c428e893 --- /dev/null +++ b/lib/tools/test/eprof_SUITE_data/eprof_test.erl @@ -0,0 +1,9 @@ +-module(eprof_test). +-export([go/1]). + +go(N) -> + 0 = dec(N), + ok. + +dec(0) -> 0; +dec(N) -> dec(N - 1). diff --git a/lib/tools/test/fprof_SUITE.erl b/lib/tools/test/fprof_SUITE.erl index e437007e76..1cd9ac7824 100644 --- a/lib/tools/test/fprof_SUITE.erl +++ b/lib/tools/test/fprof_SUITE.erl @@ -356,7 +356,7 @@ imm_tail_seq(Config) when is_list(Config) -> ?line profiling_stopped = eprof:stop_profiling(), ?line R2 = R0, %% - ?line eprof:analyse(), + ?line eprof:analyze(), ?line stopped = eprof:stop(), %% ?line {ok, Tracer} = fprof:profile(start), @@ -471,7 +471,7 @@ imm_compile(Config) when is_list(Config) -> ?line TS3 = erlang:now(), ?line profiling_stopped = eprof:stop_profiling(), %% - ?line eprof:analyse(), + ?line eprof:analyze(), ?line stopped = eprof:stop(), %% ?line {ok, Tracer} = fprof:profile(start), diff --git a/lib/tools/test/xref_SUITE.erl b/lib/tools/test/xref_SUITE.erl index b4684140ca..f9d062ef85 100644 --- a/lib/tools/test/xref_SUITE.erl +++ b/lib/tools/test/xref_SUITE.erl @@ -39,11 +39,11 @@ -export([all/1, init/1, fini/1]). -export([xref/1, - addrem/1, convert/1, intergraph/1, lines/1, loops/1, + addrem/1, convert/1, intergraph/1, lines/1, loops/1, no_data/1, modules/1]). -export([files/1, - add/1, default/1, info/1, lib/1, read/1, read2/1, remove/1, + add/1, default/1, info/1, lib/1, read/1, read2/1, remove/1, replace/1, update/1, deprecated/1, trycatch/1, abstract_modules/1, fun_mfa/1, qlc/1]). @@ -82,7 +82,7 @@ init(Conf) when is_list(Conf) -> ?line ok = erl_tar:extract(TarFile, [compressed]), ?line ok = file:delete(TarFile), [{copy_dir, CopyDir} | Conf]. - + fini(Conf) when is_list(Conf) -> %% Nothing. Conf. @@ -120,7 +120,7 @@ addrem(Conf) when is_list(Conf) -> LCallAt_m1 = [], XCallAt_m1 = [{E1,13}], Info1 = #xref_mod{name = m1, app_name = [a1]}, - ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1, + ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1, XC_m1, LC_m1), D2 = {F2,7}, @@ -132,7 +132,7 @@ addrem(Conf) when is_list(Conf) -> LCallAt_m2 = [], XCallAt_m2 = [{E2,96}], Info2 = #xref_mod{name = m2, app_name = [a2]}, - ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2, + ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2, XC_m2, LC_m2), ?line S5 = set_up(S2), @@ -142,7 +142,7 @@ addrem(Conf) when is_list(Conf) -> ?line {ok, XMod2, S6a} = remove_module(S6, m2), ?line [a2] = XMod2#xref_mod.app_name, ?line S7 = set_up(S6a), - + ?line AppInfo1 = #xref_app{name = a1, rel_name = [r1]}, ?line S9 = add_application(S7, AppInfo1), ?line S10 = set_up(S9), @@ -186,7 +186,7 @@ convert(Conf) when is_list(Conf) -> LCallAt_m1 = [], XCallAt_m1 = [{E1,13},{E2,17},{E4,7}], Info1 = #xref_mod{name = m1, app_name = [a1]}, - ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1, + ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1, XC_m1, LC_m1), D2 = {F2,7}, @@ -200,7 +200,7 @@ convert(Conf) when is_list(Conf) -> LCallAt_m2 = [], XCallAt_m2 = [{E3,96},{E6,12},{UE1,77}], Info2 = #xref_mod{name = m2, app_name = [a2]}, - ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2, + ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2, XC_m2, LC_m2), D4 = {F4,6}, @@ -213,7 +213,7 @@ convert(Conf) when is_list(Conf) -> LCallAt_m3 = [{E5,19}], XCallAt_m3 = [{UE2,22}], Info3 = #xref_mod{name = m3, app_name = [a3]}, - ?line S3 = add_module(S2, Info3, DefAt_m3, X_m3, LCallAt_m3, XCallAt_m3, + ?line S3 = add_module(S2, Info3, DefAt_m3, X_m3, LCallAt_m3, XCallAt_m3, XC_m3, LC_m3), Info4 = #xref_mod{name = m4, app_name = [a2]}, @@ -303,7 +303,7 @@ convert(Conf) when is_list(Conf) -> ?line {ok, _} = eval("(XXL) (Lin) (Fun) E", AllCallAt, S), ?line {ok, _} = eval("(XXL) (XXL) (Lin) (Fun) E", AllCallAt, S), - ?line {ok, _} = eval(f("(XXL) (Lin) ~p", [[E1, E6]]), + ?line {ok, _} = eval(f("(XXL) (Lin) ~p", [[E1, E6]]), [{{D1,D3},[13]}, {{D7,D4},[12]}], S), ?line {ok, _} = eval(f("(Fun) ~p", [AllMs]), AllE, S), ?line {ok, _} = eval("(Fun) [m1->m2,m2->m3]", [E1,E2,E6], S), @@ -323,7 +323,7 @@ intergraph(Conf) when is_list(Conf) -> F3 = {m1,f3,3}, F4 = {m1,f4,4}, F5 = {m1,f5,5}, - + F6 = {m2,f1,6}, % X F7 = {m2,f1,7}, F8 = {m2,f1,8}, @@ -339,7 +339,7 @@ intergraph(Conf) when is_list(Conf) -> E5 = {F4,F2}, E6 = {F5,F4}, E7 = {F4,F5}, - + E8 = {F6,F7}, E9 = {F7,F8}, E10 = {F8,F1}, % X @@ -363,9 +363,9 @@ intergraph(Conf) when is_list(Conf) -> LCallAt_m1 = [{E1,1},{E2,2},{E3,3},{E5,5},{E6,6},{E7,7}], XCallAt_m1 = [{E1,4}], Info1 = #xref_mod{name = m1, app_name = [a1]}, - ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1, + ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1, XC_m1, LC_m1), - + D6 = {F6,6}, D7 = {F7,7}, D8 = {F8,8}, @@ -380,7 +380,7 @@ intergraph(Conf) when is_list(Conf) -> LCallAt_m2 = [{E8,8},{E9,9},{E11,11},{E12,12},{E13,13},{E14,14}], XCallAt_m2 = [{E10,10},{E15,15}], Info2 = #xref_mod{name = m2, app_name = [a2]}, - ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2, + ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2, XC_m2, LC_m2), AppInfo1 = #xref_app{name = a1, rel_name = [r1]}, @@ -397,13 +397,13 @@ intergraph(Conf) when is_list(Conf) -> ?line {ok, _} = eval("EE | m2", [{F6,F1}], S), ?line {ok, _} = eval("EE | m2 + EE | m2", [{F6,F1}], S), - ?line {ok, _} = eval("(Fun)(Lin)(E | m1)", + ?line {ok, _} = eval("(Fun)(Lin)(E | m1)", to_external(union(set(XC_m1), set(LC_m1))), S), - ?line {ok, _} = eval("(XXL)(ELin) (EE | m1)", - [{{D2,D1},[1,2,4]},{{D4,D2},[5]},{{D5,D4},[6]},{{D4,D5},[7]}], + ?line {ok, _} = eval("(XXL)(ELin) (EE | m1)", + [{{D2,D1},[1,2,4]},{{D4,D2},[5]},{{D5,D4},[6]},{{D4,D5},[7]}], S), ?line {ok, _} = eval("(XXL)(ELin)(EE | m2)", [{{D6,D1},[8,11,12]}], S), - ?line {ok, _} = eval("(XXL)(ELin)(ELin)(EE | m2)", + ?line {ok, _} = eval("(XXL)(ELin)(ELin)(EE | m2)", [{{D6,D1},[8,11,12]}], S), %% Combining graphs (equal or different): @@ -420,15 +420,15 @@ intergraph(Conf) when is_list(Conf) -> ?line {ok, _} = eval("EE | m1 + E | m1", LC_m1, S), ?line {ok, _} = eval(f("EE | ~p + E | ~p", [F2, F2]), [E1,E2], S), %% [1,4] from 'calls' is a subset of [1,2,4] from Inter Call Graph: - ?line {ok, _} = eval(f("(XXL)(Lin) (E | ~p)", [F2]), + ?line {ok, _} = eval(f("(XXL)(Lin) (E | ~p)", [F2]), [{{D2,D1},[1,4]},{{D2,D3},[2]}], S), - ?line {ok, _} = eval(f("(XXL)(ELin) (EE | ~p)", [F2]), + ?line {ok, _} = eval(f("(XXL)(ELin) (EE | ~p)", [F2]), [{{D2,D1},[1,2,4]}], S), ?line {ok, _} = eval(f("(XXL)((ELin)(EE | ~p) + (Lin)(E | ~p))", [F2, F2]), [{{D2,D1},[1,2,4]},{{D2,D3},[2]}], S), - ?line {ok, _} = - eval(f("(XXL)((ELin) ~p + (Lin) ~p)", [{F2, F1}, {F2, F1}]), + ?line {ok, _} = + eval(f("(XXL)((ELin) ~p + (Lin) ~p)", [{F2, F1}, {F2, F1}]), [{{D2,D1},[1,2,4]}], S), ?line {ok, _} = eval(f("(Fun)(Lin) ~p", [{F2, F1}]), [E1], S), %% The external call E4 is included in the reply: @@ -438,7 +438,7 @@ intergraph(Conf) when is_list(Conf) -> %% The local call E1 is included in the reply: ?line {ok, _} = eval("(XXL)(Lin)(XC | m1)", [{{D2,D1},[1,4]}], S), - ?line {ok, _} = eval(f("(LLin) (E | ~p || ~p) + (XLin) (E | ~p || ~p)", + ?line {ok, _} = eval(f("(LLin) (E | ~p || ~p) + (XLin) (E | ~p || ~p)", [F2, F1, F2, F1]), [{E4,[1,4]}], S), ?line {ok, _} = eval("# (ELin) E", 6, S), @@ -449,7 +449,7 @@ lines(suite) -> []; lines(doc) -> ["More test of Inter Call Graph, and regular expressions"]; lines(Conf) when is_list(Conf) -> S0 = new(), - + F1 = {m1,f1,1}, % X F2 = {m1,f2,2}, F3 = {m1,f3,3}, @@ -464,14 +464,14 @@ lines(Conf) when is_list(Conf) -> E5 = {F2,F4}, % X E6 = {F5,F6}, E7 = {F6,F4}, % X - + D1 = {F1,1}, D2 = {F2,2}, D3 = {F3,3}, D4 = {F4,4}, D5 = {F5,5}, D6 = {F6,6}, - + DefAt_m1 = [D1,D2,D3,D5,D6], X_m1 = [F1,F5], % L_m1 = [F2,F3,F6], @@ -480,7 +480,7 @@ lines(Conf) when is_list(Conf) -> LCallAt_m1 = [{E1,1},{E3,3},{E6,6}], XCallAt_m1 = [{E2,2},{E4,4},{E5,5},{E7,7}], Info1 = #xref_mod{name = m1, app_name = [a1]}, - ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1, + ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1, XC_m1, LC_m1), DefAt_m2 = [D4], @@ -491,9 +491,9 @@ lines(Conf) when is_list(Conf) -> LCallAt_m2 = [], XCallAt_m2 = [], Info2 = #xref_mod{name = m2, app_name = [a2]}, - ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2, + ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2, XC_m2, LC_m2), - + AppInfo1 = #xref_app{name = a1, rel_name = [r1]}, ?line S5 = add_application(S2, AppInfo1), AppInfo2 = #xref_app{name = a2, rel_name = [r1]}, @@ -509,10 +509,10 @@ lines(Conf) when is_list(Conf) -> {{D5,D4},[6]}], S), ?line {ok, _} = eval("(XXL)(Lin) (E | m1)", [{{D1,D2},[1]},{{D1,D4},[4]},{{D2,D1},[2]}, - {{D2,D4},[5]},{{D3,D2},[3]},{{D5,D6},[6]},{{D6,D4},[7]}], + {{D2,D4},[5]},{{D3,D2},[3]},{{D5,D6},[6]},{{D6,D4},[7]}], S), ?line {ok, _} = eval("(E | m1) + (EE | m1)", - [E1,E2,E3,E4,E5,E6,E7,{F1,F1},{F3,F1},{F3,F4},{F5,F4}], + [E1,E2,E3,E4,E5,E6,E7,{F1,F1},{F3,F1},{F3,F4},{F5,F4}], S), ?line {ok, _} = eval("(Lin)(E | m1)", [{E4,[4]},{E1,[1]},{E2,[2]},{E5,[5]}, @@ -567,7 +567,7 @@ lines(Conf) when is_list(Conf) -> loops(suite) -> []; loops(doc) -> ["More Inter Call Graph, loops and \"unusual\" cases"]; loops(Conf) when is_list(Conf) -> - S0 = new(), + S0 = new(), F1 = {m1,f1,1}, % X F2 = {m1,f2,2}, @@ -582,7 +582,7 @@ loops(Conf) when is_list(Conf) -> E3 = {F3,F4}, E4 = {F4,F5}, E5 = {F5,F3}, % X - + D1 = {F1,1}, D2 = {F2,2}, D3 = {F3,3}, @@ -598,7 +598,7 @@ loops(Conf) when is_list(Conf) -> LCallAt_m1 = [{E2,2},{E3,3},{E4,4}], XCallAt_m1 = [{E1,1},{E5,5}], Info1 = #xref_mod{name = m1, app_name = [a1]}, - ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1, + ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1, XC_m1, LC_m1), ?line S = set_up(S1), @@ -659,16 +659,16 @@ modules(Conf) when is_list(Conf) -> ?line {ok, y} = compile:file(Y, [debug_info, {outdir,EB1_1}]), ?line {ok, S0} = xref_base:new([{xref_mode, modules}]), - ?line {ok, release2, S1} = + ?line {ok, release2, S1} = xref_base:add_release(S0, Dir, [{name,release2}]), ?line S = set_up(S1), ?line {{error, _, {unavailable_analysis, undefined_function_calls}}, _} = xref_base:analyze(S, undefined_function_calls), - ?line {{error, _, {unavailable_analysis, locals_not_used}}, _} = + ?line {{error, _, {unavailable_analysis, locals_not_used}}, _} = xref_base:analyze(S, locals_not_used), - ?line {{error, _, {unavailable_analysis, {call, foo}}}, _} = + ?line {{error, _, {unavailable_analysis, {call, foo}}}, _} = xref_base:analyze(S, {call, foo}), - ?line {{error, _, {unavailable_analysis, {use, foo}}}, _} = + ?line {{error, _, {unavailable_analysis, {use, foo}}}, _} = xref_base:analyze(S, {use, foo}), ?line analyze(undefined_functions, [{x,undef,0}], S), ?line 5 = length(xref_base:info(S)), @@ -681,7 +681,7 @@ modules(Conf) when is_list(Conf) -> ok. files(suite) -> - [add, default, info, lib, read, read2, remove, replace, update, + [add, default, info, lib, read, read2, remove, replace, update, deprecated, trycatch, abstract_modules, fun_mfa, qlc]. add(suite) -> []; @@ -708,7 +708,7 @@ add(Conf) when is_list(Conf) -> {unix, _} -> ?line make_udir(UDir), ?line make_ufile(UFile); - _ -> + _ -> true end, @@ -743,20 +743,20 @@ add(Conf) when is_list(Conf) -> xref_base:add_release(S, foo, [{builtins,not_a_value}]), ?line {error, _, {invalid_filename,{foo,bar}}} = xref_base:add_release(S, {foo,bar}, []), - ?line {ok, S1} = + ?line {ok, S1} = xref_base:set_default(S, [{verbose,false}, {warnings, false}]), ?line case os:type() of {unix, _} -> - ?line {error, _, {file_error, _, _}} = + ?line {error, _, {file_error, _, _}} = xref_base:add_release(S, UDir); _ -> true end, - ?line {error, _, {file_error, _, _}} = + ?line {error, _, {file_error, _, _}} = xref_base:add_release(S, fname(["/a/b/c/d/e/f","__foo"])), - ?line {ok, release2, S2} = + ?line {ok, release2, S2} = xref_base:add_release(S1, Dir, [{name,release2}]), - ?line {error, _, {module_clash, {x, _, _}}} = + ?line {error, _, {module_clash, {x, _, _}}} = xref_base:add_module(S2, Xbeam), ?line {ok, S3} = xref_base:remove_release(S2, release2), ?line {ok, rel2, S4} = xref_base:add_release(S3, Dir), @@ -764,11 +764,11 @@ add(Conf) when is_list(Conf) -> xref_base:add_release(S4, Dir), ?line {ok, S5} = xref_base:remove_release(S4, rel2), %% One unreadable file and one JAM file found (no verification here): - ?line {ok, [], S6} = xref_base:add_directory(S5, fname(CopyDir,"dir"), + ?line {ok, [], S6} = xref_base:add_directory(S5, fname(CopyDir,"dir"), [{recurse,true}, {warnings,true}]), ?line case os:type() of {unix, _} -> - ?line {error, _, {file_error, _, _}} = + ?line {error, _, {file_error, _, _}} = xref_base:add_directory(S6, UDir); _ -> true @@ -803,7 +803,7 @@ default(Conf) when is_list(Conf) -> xref_base:set_default(S, [not_an_option]), ?line D = xref_base:get_default(S), - ?line [{builtins,false},{recurse,false},{verbose,false},{warnings,true}] = + ?line [{builtins,false},{recurse,false},{verbose,false},{warnings,true}] = D, ?line ok = xref_base:delete(S), @@ -831,7 +831,7 @@ info(Conf) when is_list(Conf) -> ?line {error, _, {no_such_info, release}} = xref:info(s, release), ?line {error, _, {no_such_info, release}} = xref:info(s, release, rel), ?line {error, _, {no_such_module, mod}} = xref:info(s, modules, mod), - ?line {error, _, {no_such_application, app}} = + ?line {error, _, {no_such_application, app}} = xref:info(s, applications, app), ?line {error, _, {no_such_release, rel}} = xref:info(s, releases, rel), ?line ok = xref:set_default(s, [{verbose,false}, {warnings, false}]), @@ -845,9 +845,9 @@ info(Conf) when is_list(Conf) -> ?line [{rel2,_}] = xref:info(s, releases, rel2), ?line {error, _, {no_such_library, foo}} = xref:info(s, libraries, [foo]), - ?line {ok, lib1} = + ?line {ok, lib1} = compile:file(fname(LDir,lib1),[debug_info,{outdir,LDir}]), - ?line {ok, lib2} = + ?line {ok, lib2} = compile:file(fname(LDir,lib2),[debug_info,{outdir,LDir}]), ?line ok = xref:set_library_path(s, [LDir], [{verbose,false}]), ?line [{lib1,_}, {lib2, _}] = xref:info(s, libraries), @@ -883,13 +883,13 @@ lib(Conf) when is_list(Conf) -> xref:set_library_path(s, ["foo"], [not_an_option]), ?line {error, _, {invalid_path,otp}} = xref:set_library_path(s,otp), ?line {error, _, {invalid_path,[""]}} = xref:set_library_path(s,[""]), - ?line {error, _, {invalid_path,[[$a | $b]]}} = + ?line {error, _, {invalid_path,[[$a | $b]]}} = xref:set_library_path(s,[[$a | $b]]), ?line {error, _, {invalid_path,[otp]}} = xref:set_library_path(s,[otp]), ?line {ok, []} = xref:get_library_path(s), ?line ok = xref:set_library_path(s, [Dir], [{verbose,false}]), ?line {ok, UnknownFunctions} = xref:q(s, "U"), - ?line [{lib1,unknown,0}, {lib2,local,0}, + ?line [{lib1,unknown,0}, {lib2,local,0}, {lib2,unknown,0}, {unknown,unknown,0}] = UnknownFunctions, ?line {ok, [{lib2,f,0},{lib3,f,0}]} = xref:q(s, "DF"), @@ -934,7 +934,7 @@ lib(Conf) when is_list(Conf) -> ?line ok = xref:set_default(s, [{verbose,false}, {warnings, false}]), ?line {ok, cp} = xref:add_module(s, fname(Dir,"cp.beam")), ?line {ok, [{lists, sort, 1}]} = xref:q(s, "U"), - ?line ok = xref:set_library_path(s, code_path), + ?line ok = xref:set_library_path(s, code_path), ?line {ok, []} = xref:q(s, "U"), ?line check_state(s), ?line xref:stop(s), @@ -1010,18 +1010,18 @@ do_read(File, Version) -> ?line {ok, CallsB} = xref:q(s, "(Lin) (E - UC) "), ?line ok = check_state(s), ?line {ok, XU} = xref:q(s, "XU"), - ?line Erl = set([{erlang,length,1},{erlang,integer,1}, + ?line Erl = set([{erlang,length,1},{erlang,integer,1}, {erlang,binary_to_term,1}]), - ?line [{erlang,binary_to_term,1},{erlang,length,1}] = + ?line [{erlang,binary_to_term,1},{erlang,length,1}] = to_external(intersection(set(XU), Erl)), - ?line xref:stop(s). + ?line xref:stop(s). %% What is expected when xref_SUITE_data/read/read.erl is added: read_expected(Version) -> %% Line positions in xref_SUITE_data/read/read.erl: - POS1 = 28, POS2 = POS1+10, POS3 = POS2+6, POS4 = POS3+6, POS5 = POS4+10, - POS6 = POS5+5, POS7 = POS6+6, POS8 = POS7+6, POS9 = POS8+8, - POS10 = POS9+10, POS11 = POS10+7, POS12 = POS11+8, POS13 = POS12+10, + POS1 = 28, POS2 = POS1+10, POS3 = POS2+6, POS4 = POS3+6, POS5 = POS4+10, + POS6 = POS5+5, POS7 = POS6+6, POS8 = POS7+6, POS9 = POS8+8, + POS10 = POS9+10, POS11 = POS10+7, POS12 = POS11+8, POS13 = POS12+10, POS14 = POS13+18, % POS15 = POS14+23, FF = {read,funfuns,0}, @@ -1162,7 +1162,7 @@ read_expected(Version) -> {POS14+17,{{read,bi,0},{read,bi,0}}}], OK = case Version of - abstract_v1 -> + abstract_v1 -> [{POS8+3, {FF,{erlang,apply,3}}}, {POS10+1, {FF,{erlang,apply,3}}}, {POS10+6, {FF,{erlang,apply,3}}}] @@ -1170,7 +1170,7 @@ read_expected(Version) -> [{0,{FF,{read,'$F_EXPR',178}}}, {0,{FF,{modul,'$F_EXPR',179}}}] ++ O1; - _ -> + _ -> % [{POS15+2,{{read,bi,0},{foo,t,0}}}, % {POS15+3,{{read,bi,0},{bar,t,0}}}, % {POS15+6,{{read,bi,0},{read,local,0}}}, @@ -1183,18 +1183,34 @@ read_expected(Version) -> end, %% When builtins =:= true: - OKB = [{POS13+1,{FF,{erts_debug,apply,4}}}, - {POS13+2,{FF,{erts_debug,apply,4}}}, - {POS13+3,{FF,{erts_debug,apply,4}}}, - {POS1+3, {FF,{erlang,binary_to_term,1}}}, - {POS3+1, {FF,{erlang,spawn,3}}}, - {POS3+2, {FF,{erlang,spawn,3}}}, - {POS3+3, {FF,{erlang,spawn_link,3}}}, - {POS3+4, {FF,{erlang,spawn_link,3}}}, - {POS6+4, {FF,{erlang,spawn,3}}}, - {POS13+5, {{read,bi,0},{erlang,length,1}}}, - {POS14+3, {{read,bi,0},{erlang,length,1}}}] - ++ OK, + OKB1 = [{POS13+1,{FF,{erts_debug,apply,4}}}, + {POS13+2,{FF,{erts_debug,apply,4}}}, + {POS13+3,{FF,{erts_debug,apply,4}}}, + {POS1+3, {FF,{erlang,binary_to_term,1}}}, + {POS3+1, {FF,{erlang,spawn,3}}}, + {POS3+2, {FF,{erlang,spawn,3}}}, + {POS3+3, {FF,{erlang,spawn_link,3}}}, + {POS3+4, {FF,{erlang,spawn_link,3}}}, + {POS6+4, {FF,{erlang,spawn,3}}}, + {POS13+5, {{read,bi,0},{erlang,length,1}}}, + {POS14+3, {{read,bi,0},{erlang,length,1}}}], + + %% Operators (OTP-8647): + OKB = case Version of + abstract_v1 -> + []; + _ -> + [{POS13+16, {{read,bi,0},{erlang,'!',2}}}, + {POS13+16, {{read,bi,0},{erlang,'-',1}}}, + {POS13+16, {{read,bi,0},{erlang,self,0}}}] + end + ++ [{POS14+19, {{read,bi,0},{erlang,'+',2}}}, + {POS14+21, {{read,bi,0},{erlang,'+',2}}}, + {POS13+16, {{read,bi,0},{erlang,'==',2}}}, + {POS14+15, {{read,bi,0},{erlang,'==',2}}}, + {POS13+5, {{read,bi,0},{erlang,'>',2}}}, + {POS14+3, {{read,bi,0},{erlang,'>',2}}}] + ++ OKB1 ++ OK, {U, OK, OKB}. @@ -1217,9 +1233,9 @@ read2(Conf) when is_list(Conf) -> spawn_opt(fun() -> foo end, [link]), spawn_opt(f(), {read2,f}, [{min_heap_size,1000}]), - spawn_opt(f(), + spawn_opt(f(), fun() -> f() end, [flopp]), - spawn_opt(f(), + spawn_opt(f(), read2, f, [], []); f() -> %% Duplicated unresolved calls are ignored: @@ -1237,7 +1253,7 @@ read2(Conf) when is_list(Conf) -> ?line {ok, U2} = xref:q(s, "(Lin) UC"), ?line {ok, OK2} = xref:q(s, "(Lin) (E - UC)"), ?line true = U =:= U2, - ?line true = OK =:= OK2, + ?line true = OK =:= OK2, ?line ok = check_state(s), ?line xref:stop(s), @@ -1304,7 +1320,7 @@ replace(Conf) when is_list(Conf) -> ?line {ok, true} = xref:set_default(s, warnings, false), ?line {ok, rel2} = xref:add_release(s, Dir, []), ?line {error, _, _} = xref:replace_application(s, app1, "no_data"), - ?line {error, _, {no_such_application, app12}} = + ?line {error, _, {no_such_application, app12}} = xref:replace_application(s, app12, A1_0, []), ?line {error, _, {invalid_filename,{foo,bar}}} = xref:replace_application(s, app1, {foo,bar}, []), @@ -1312,7 +1328,7 @@ replace(Conf) when is_list(Conf) -> xref:replace_application(s, foo, bar, [not_an_option]), ?line {error, _, {invalid_options,[{builtins,not_a_value}]}} = xref:replace_application(s, foo, bar, [{builtins,not_a_value}]), - ?line {ok, app1} = + ?line {ok, app1} = xref:replace_application(s, app1, A1_0), ?line [{_, AppInfo}] = xref:info(s, applications, app1), ?line {value, {release, [rel2]}} = keysearch(release, 1, AppInfo), @@ -1332,14 +1348,14 @@ replace(Conf) when is_list(Conf) -> ?line {ok, x} = compile:file(X, [no_debug_info, {outdir,EB1_1}]), ?line {error, _, {no_debug_info, _}} = xref:replace_module(s, x, Xbeam), - ?line {error, _, {module_mismatch, x,y}} = + ?line {error, _, {module_mismatch, x,y}} = xref:replace_module(s, x, Ybeam), ?line case os:type() of {unix, _} -> ?line hide_file(Ybeam), - ?line {error, _, {file_error, _, _}} = + ?line {error, _, {file_error, _, _}} = xref:replace_module(s, x, Ybeam); - _ -> + _ -> true end, ?line ok = xref:remove_module(s, x), @@ -1362,16 +1378,16 @@ update(Conf) when is_list(Conf) -> Source = fname(Dir, "x.erl"), Beam = fname(Dir, "x.beam"), ?line copy_file(fname(Dir, "x.erl.1"), Source), - ?line {ok, x} = compile:file(Source, [debug_info, {outdir,Dir}]), - + ?line {ok, x} = compile:file(Source, [debug_info, {outdir,Dir}]), + ?line {ok, _} = start(s), - ?line ok = xref:set_default(s, [{verbose,false}, {warnings, false}]), + ?line ok = xref:set_default(s, [{verbose,false}, {warnings, false}]), ?line {ok, [x]} = xref:add_directory(s, Dir, [{builtins,true}]), ?line {error, _, {invalid_options,[not_an_option]}} = xref:update(s, [not_an_option]), ?line {ok, []} = xref:update(s), ?line {ok, [{erlang,atom_to_list,1}]} = xref:q(s, "XU"), - + ?line [{x, ModInfo}] = xref:info(s, modules, x), ?line case keysearch(directory, 1, ModInfo) of {value, {directory, Dir}} -> ok @@ -1379,7 +1395,7 @@ update(Conf) when is_list(Conf) -> timer:sleep(2000), % make sure modification time has changed ?line copy_file(fname(Dir, "x.erl.2"), Source), - ?line {ok, x} = compile:file(Source, [debug_info, {outdir,Dir}]), + ?line {ok, x} = compile:file(Source, [debug_info, {outdir,Dir}]), ?line {ok, [x]} = xref:update(s, []), ?line {ok, [{erlang,list_to_atom,1}]} = xref:q(s, "XU"), @@ -1454,11 +1470,11 @@ deprecated(Conf) when is_list(Conf) -> DF = usort(DF_3++[{{M9,t,0},{M9,f,1}}]), ?line {ok,DF} = xref:analyze(s, deprecated_function_calls), - ?line {ok,DF_1} = + ?line {ok,DF_1} = xref:analyze(s, {deprecated_function_calls,next_version}), - ?line {ok,DF_2} = + ?line {ok,DF_2} = xref:analyze(s, {deprecated_function_calls,next_major_release}), - ?line {ok,DF_3} = + ?line {ok,DF_3} = xref:analyze(s, {deprecated_function_calls,eventually}), D = to_external(range(from_term(DF))), @@ -1467,11 +1483,11 @@ deprecated(Conf) when is_list(Conf) -> D_3 = to_external(range(from_term(DF_3))), ?line {ok,D} = xref:analyze(s, deprecated_functions), - ?line {ok,D_1} = + ?line {ok,D_1} = xref:analyze(s, {deprecated_functions,next_version}), - ?line {ok,D_2} = + ?line {ok,D_2} = xref:analyze(s, {deprecated_functions,next_major_release}), - ?line {ok,D_3} = + ?line {ok,D_3} = xref:analyze(s, {deprecated_functions,eventually}), ?line ok = check_state(s), @@ -1516,11 +1532,11 @@ deprecated(Conf) when is_list(Conf) -> DFa = DFa_3, ?line {ok,DFa} = xref:analyze(s, deprecated_function_calls), - ?line {ok,DFa_1} = + ?line {ok,DFa_1} = xref:analyze(s, {deprecated_function_calls,next_version}), - ?line {ok,DFa_2} = + ?line {ok,DFa_2} = xref:analyze(s, {deprecated_function_calls,next_major_release}), - ?line {ok,DFa_3} = + ?line {ok,DFa_3} = xref:analyze(s, {deprecated_function_calls,eventually}), ?line ok = check_state(s), @@ -1564,11 +1580,11 @@ deprecated(Conf) when is_list(Conf) -> DFb = usort(DFb_2++[{{M,bar,2},{M,t,0}},{{M,g,3},{M,bar,2}}]), ?line {ok,DFb} = xref:analyze(s, deprecated_function_calls), - ?line {ok,DFb_1} = + ?line {ok,DFb_1} = xref:analyze(s, {deprecated_function_calls,next_version}), - ?line {ok,DFb_2} = + ?line {ok,DFb_2} = xref:analyze(s, {deprecated_function_calls,next_major_release}), - ?line {ok,DFb_3} = + ?line {ok,DFb_3} = xref:analyze(s, {deprecated_function_calls,eventually}), ?line ok = check_state(s), @@ -1599,7 +1615,7 @@ trycatch(Conf) when is_list(Conf) -> catch error:a -> err:e1(); error:b -> err:e2() - after + after fini:shed() end. ">>, @@ -1616,7 +1632,7 @@ trycatch(Conf) when is_list(Conf) -> {{{A,A,0},{err,e2,0}},[13]}, {{{A,A,0},{fini,shed,0}},[15]}, {{{A,A,0},{foo,bar,0}},[7]}, - {{{A,A,0},{foo,foo,0}},[9]}]} = + {{{A,A,0},{foo,foo,0}},[9]}]} = xref:q(s, "(Lin) (E | trycatch:trycatch/0)"), ?line ok = check_state(s), @@ -1662,7 +1678,7 @@ abstract_modules(Conf) when is_list(Conf) -> {{{A,args,1},{A,local,1}},[6]}, {{{A,args,1},{A,new,2}},[8]}, {{{A,local,1},{A,module_info,1}},[12]}, - {{{param,new,2},{param,instance,2}},[0]}]} = + {{{param,new,2},{param,instance,2}},[0]}]} = xref:q(s, "(Lin) E"), ?line {ok,[{param,args,1}, {param,instance,2}, @@ -1747,10 +1763,10 @@ qlc(Conf) when is_list(Conf) -> t() -> dets:open_file(t, []), dets:insert(t, [{1,a},{2,b},{3,c},{4,d}]), - MS = ets:fun2ms(fun({X,Y}) when (X > 1) or (X < 5) -> {Y} + MS = ets:fun2ms(fun({X,Y}) when (X > 1) or (X < 5) -> {Y} end), QH1 = dets:table(t, [{traverse, {select, MS}}]), - QH2 = qlc:q([{Y} || {X,Y} <- dets:table(t), + QH2 = qlc:q([{Y} || {X,Y} <- dets:table(t), (X > 1) or (X < 5)]), true = qlc:info(QH1) =:= qlc:info(QH2), dets:close(t), @@ -1783,7 +1799,7 @@ analyze(Conf) when is_list(Conf) -> xref_base:analyze(S0, undefined_function_calls, [not_an_option]), ?line {{error, _, {invalid_query,{q}}}, _} = xref_base:q(S0,{q}), ?line {{error, _, {unknown_analysis,foo}}, _} = xref_base:analyze(S0, foo), - ?line {{error, _, {unknown_constant,"foo:bar/-1"}}, _} = + ?line {{error, _, {unknown_constant,"foo:bar/-1"}}, _} = xref_base:analyze(S0, {use,{foo,bar,-1}}), CopyDir = ?copydir, @@ -1803,30 +1819,30 @@ analyze(Conf) when is_list(Conf) -> ?line {ok, rel2, S1} = xref_base:add_release(S0, Dir, [{verbose,false}]), ?line S = set_up(S1), - ?line {ok, _} = + ?line {ok, _} = analyze(undefined_function_calls, [{{x,xx,0},{x,undef,0}}], S), ?line {ok, _} = analyze(undefined_functions, [{x,undef,0}], S), ?line {ok, _} = analyze(locals_not_used, [{x,l,0},{x,l1,0}], S), ?line {ok, _} = analyze(exports_not_used, [{x,xx,0},{y,t,0}], S), - ?line {ok, _} = + ?line {ok, _} = analyze(deprecated_function_calls, [{{y,t,0},{x,t,0}}], S), ?line {ok, _} = analyze({deprecated_function_calls,next_version}, [], S), - ?line {ok, _} = + ?line {ok, _} = analyze({deprecated_function_calls,next_major_release}, [], S), - ?line {ok, _} = analyze({deprecated_function_calls,eventually}, + ?line {ok, _} = analyze({deprecated_function_calls,eventually}, [{{y,t,0},{x,t,0}}], S), ?line {ok, _} = analyze(deprecated_functions, [{x,t,0}], S), ?line {ok, _} = analyze({deprecated_functions,next_version}, [], S), - ?line {ok, _} = + ?line {ok, _} = analyze({deprecated_functions,next_major_release}, [], S), ?line {ok, _} = analyze({deprecated_functions,eventually}, [{x,t,0}], S), ?line {ok, _} = analyze({call, {x,xx,0}}, [{x,undef,0}], S), - ?line {ok, _} = + ?line {ok, _} = analyze({call, [{x,xx,0},{x,l,0}]}, [{x,l1,0},{x,undef,0}], S), ?line {ok, _} = analyze({use, {x,l,0}}, [{x,l1,0}], S), - ?line {ok, _} = + ?line {ok, _} = analyze({use, [{x,l,0},{x,l1,0}]}, [{x,l,0},{x,l1,0}], S), ?line {ok, _} = analyze({module_call, x}, [x], S), @@ -1881,7 +1897,7 @@ basic(Conf) when is_list(Conf) -> LCallAt_m1 = [{E7,12}], XCallAt_m1 = [{E1,13},{E2,17},{E4,7}], Info1 = #xref_mod{name = m1, app_name = [a1]}, - ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1, + ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1, XC_m1, LC_m1), D2 = {F2,7}, @@ -1895,7 +1911,7 @@ basic(Conf) when is_list(Conf) -> LCallAt_m2 = [], XCallAt_m2 = [{E3,96},{E6,12},{UE1,77}], Info2 = #xref_mod{name = m2, app_name = [a2]}, - ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2, + ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2, XC_m2, LC_m2), D4 = {F4,6}, @@ -1908,7 +1924,7 @@ basic(Conf) when is_list(Conf) -> LCallAt_m3 = [{E5,19}], XCallAt_m3 = [{UE2,22}], Info3 = #xref_mod{name = m3, app_name = [a3]}, - ?line S3 = add_module(S2, Info3, DefAt_m3, X_m3, LCallAt_m3, XCallAt_m3, + ?line S3 = add_module(S2, Info3, DefAt_m3, X_m3, LCallAt_m3, XCallAt_m3, XC_m3, LC_m3), Info4 = #xref_mod{name = m4, app_name = [a2]}, @@ -1955,7 +1971,7 @@ basic(Conf) when is_list(Conf) -> ?line {ok, _} = eval(f("(Mod) ~p", [[F1,F6,F5]]), [m1,m3], S), ?line {ok, _} = eval("(Lin) M - (Lin) m1", [{F2,7},{F3,9},{F7,19},{F4,6},{F5,97},{UF2,0}], S), - ?line {ok, _} = eval(f("(Lin) M * (Lin) ~p", [[F1,F6]]), + ?line {ok, _} = eval(f("(Lin) M * (Lin) ~p", [[F1,F6]]), [{F1,12},{F6,3}], S), ?line {ok, _} = eval(f("X * ~p", [[F1, F2, F3, F4, F5]]), [F3, F4], S), @@ -1976,7 +1992,7 @@ basic(Conf) when is_list(Conf) -> ?line {ok, _} = eval(f("(XXL) (Lin) (XC | ~p)", [F1]), [{{D1,D3},[13]},{{D1,D4},[7]}],S), ?line {ok, _} = eval(f("XC | (~p + ~p)", [F1, F2]), [E1,E4,E3,UE1], S), - ?line {ok, _} = eval(f("(XXL) (Lin) (XC | ~p)", [F1]), + ?line {ok, _} = eval(f("(XXL) (Lin) (XC | ~p)", [F1]), [{{D1,D3},[13]},{{D1,D4},[7]}], S), ?line {ok, _} = eval("LC | m3", [E5], S), ?line {ok, _} = eval(f("LC | ~p", [F1]), [E7], S), @@ -1984,7 +2000,7 @@ basic(Conf) when is_list(Conf) -> ?line {ok, _} = eval("E | m1", [E1,E2,E4,E7], S), ?line {ok, _} = eval(f("E | ~p", [F1]), [E1,E7,E4], S), ?line {ok, _} = eval(f("E | (~p + ~p)", [F1, F2]), [E1,E7,E4,E3,UE1], S), - + ?line {ok, _} = eval("XC || m1", [E3,UE2], S), ?line {ok, _} = eval(f("XC || ~p", [F6]), [E3], S), ?line {ok, _} = eval(f("XC || (~p + ~p)", [F4, UF2]), [UE1,E4,E6], S), @@ -2012,18 +2028,18 @@ basic(Conf) when is_list(Conf) -> ?line {ok, _} = eval("components V", type_error, S), ?line {ok, _} = eval("components E + components E", type_error, S), - ?line {ok, _} = eval(f("range (closure E | ~p)", [[F1,F2]]), + ?line {ok, _} = eval(f("range (closure E | ~p)", [[F1,F2]]), [F6,F3,F7,F4,F5,UF1,UF2], S), - ?line {ok, _} = + ?line {ok, _} = eval(f("domain (closure E || ~p)", [[UF2,F7]]), [F1,F2,F6], S), ?line {ok, _} = eval("components E", [], S), ?line {ok, _} = eval("components (Mod) E", [[m1,m2,m3]], S), ?line {ok, _} = eval("components closure (Mod) E", [[m1,m2,m3]], S), - ?line {ok, _} = eval("condensation (Mod) E", + ?line {ok, _} = eval("condensation (Mod) E", [{[m1,m2,m3],[m1,m2,m3]},{[m1,m2,m3],[m17]}], S), - ?line {ok, _} = eval("condensation closure (Mod) E", + ?line {ok, _} = eval("condensation closure (Mod) E", [{[m1,m2,m3],[m1,m2,m3]},{[m1,m2,m3],[m17]}], S), - ?line {ok, _} = eval("condensation closure closure closure (Mod) E", + ?line {ok, _} = eval("condensation closure closure closure (Mod) E", [{[m1,m2,m3],[m1,m2,m3]},{[m1,m2,m3],[m17]}], S), ?line {ok, _} = eval("weak condensation (Mod) E", [{[m1,m2,m3],[m1,m2,m3]},{[m1,m2,m3],[m17]},{[m17],[m17]}], S), @@ -2035,11 +2051,11 @@ basic(Conf) when is_list(Conf) -> [[m1,m2,m3]], S), %% |, ||, ||| - ?line {ok, _} = eval("(Lin) E || V", type_error, S), - ?line {ok, _} = eval("E ||| (Lin) V", type_error, S), + ?line {ok, _} = eval("(Lin) E || V", type_error, S), + ?line {ok, _} = eval("E ||| (Lin) V", type_error, S), ?line {ok, _} = eval("E ||| m1", [E7], S), ?line {ok, _} = eval("closure E ||| m1", [E7,{F1,UF1},{F6,UF1}], S), - ?line {ok, _} = eval("closure E ||| [m1,m2]", + ?line {ok, _} = eval("closure E ||| [m1,m2]", [{F1,UF1},{F2,F7},{F1,F7},{F6,UF1},{F2,UF1},{F7,UF1},E7,E1,E2,E3], S), ?line {ok, _} = eval("AE | a1", [{a1,a1},{a1,a2},{a1,a3}], S), @@ -2095,7 +2111,7 @@ md(Conf) when is_list(Conf) -> Y = fname(Dir, "y__y.erl"), Xbeam = fname(Dir, "x__x.beam"), Ybeam = fname(Dir, "y__y.beam"), - + ?line {error, _, {invalid_filename,{foo,bar}}} = xref:m({foo,bar}), ?line {error, _, {invalid_filename,{foo,bar}}} = xref:d({foo,bar}), @@ -2171,7 +2187,7 @@ variables(Conf) when is_list(Conf) -> LCallAt_m1 = [], XCallAt_m1 = [{E1,13},{E3,17}], Info1 = #xref_mod{name = m1, app_name = [a1]}, - ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1, + ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1, XC_m1, LC_m1), D2 = {F2,7}, @@ -2183,11 +2199,11 @@ variables(Conf) when is_list(Conf) -> LCallAt_m2 = [], XCallAt_m2 = [{E2,96}], Info2 = #xref_mod{name = m2, app_name = [a2]}, - ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2, + ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2, XC_m2, LC_m2), ?line S = set_up(S2), - + ?line eval("T1=E, T2=E*T1, T3 = T2*T2, T4=range T3, T5=T3|T4, T5", [E1,E2,E3], S), ?line eval("((E*E)*(E*E)) | (range ((E*E)*(E*E)))", @@ -2202,16 +2218,16 @@ variables(Conf) when is_list(Conf) -> ?line {ok, S102} = eval("T2 := E | m2", [E2], S101), ?line {{ok, [{user, ['T0', 'T1', 'T2']}]}, _} = xref_base:variables(S102), ?line {ok, S103} = xref_base:forget(S102, 'T0'), - ?line {{ok, [{user, ['T1', 'T2']}]}, S104} = + ?line {{ok, [{user, ['T1', 'T2']}]}, S104} = xref_base:variables(S103, [user]), ?line {ok, S105} = xref_base:forget(S104), ?line {{ok, [{user, []}]}, S106} = xref_base:variables(S105), - ?line {{ok, [{predefined,_}]}, S107_0} = + ?line {{ok, [{predefined,_}]}, S107_0} = xref_base:variables(S106, [predefined]), - ?line {ok, S107_1} = + ?line {ok, S107_1} = eval("TT := E, TT2 := V, TT1 := TT * TT", [E1,E2,E3], S107_0), - ?line {{ok, [{user, ['TT', 'TT1', 'TT2']}]}, _} = + ?line {{ok, [{user, ['TT', 'TT1', 'TT2']}]}, _} = xref_base:variables(S107_1), ?line {ok, S107} = xref_base:forget(S107_1), @@ -2220,14 +2236,14 @@ variables(Conf) when is_list(Conf) -> Beam = fname(Dir, "lib1.beam"), ?line copy_file(fname(Dir, "lib1.erl"), Beam), - ?line {ok, S108} = + ?line {ok, S108} = xref_base:set_library_path(S107, [Dir], [{verbose,false}]), ?line {{error, _, _}, _} = xref_base:variables(S108, [{verbose,false}]), ?line {ok, S109} = xref_base:set_library_path(S108, [], [{verbose,false}]), ?line Tabs = length(ets:all()), - ?line {ok, S110} = eval("Eplus := closure E, TT := Eplus", + ?line {ok, S110} = eval("Eplus := closure E, TT := Eplus", 'closure()', S109), ?line {{ok, [{user, ['Eplus','TT']}]}, S111} = xref_base:variables(S110), ?line {ok, S112} = xref_base:forget(S111, ['TT','Eplus']), @@ -2289,7 +2305,7 @@ unused_locals(Conf) when is_list(Conf) -> ?line {ok, []} = xref:analyse(s, locals_not_used), ?line ok = check_state(s), ?line xref:stop(s), - + ?line ok = file:delete(File1), ?line ok = file:delete(Beam1), ?line ok = file:delete(File2), @@ -2303,11 +2319,11 @@ format_error(suite) -> []; format_error(doc) -> ["Format error messages"]; format_error(Conf) when is_list(Conf) -> ?line {ok, _Pid} = start(s), - ?line ok = xref:set_default(s, [{verbose,false}, {warnings, false}]), + ?line ok = xref:set_default(s, [{verbose,false}, {warnings, false}]), %% Parse error messages. - ?line 'Invalid regular expression "add(": unterminated \`(\'\n' - = fatom(xref:q(s,'"add("')), + ?line "Invalid regular expression \"add(\"" ++ _ = + fstring(xref:q(s,'"add("')), ?line 'Invalid operator foo\n' = fatom(xref:q(s,'foo E')), ?line 'Invalid wildcard variable \'_Var\' (only \'_\' is allowed)\n' @@ -2332,7 +2348,7 @@ format_error(Conf) when is_list(Conf) -> %% Other messages ?line 'Variable \'QQ\' used before set\n' = fatom(xref:q(s,"QQ")), - ?line 'Unknown constant a\n' = + ?line 'Unknown constant a\n' = fatom(xref:q(s,"{a} of E")), %% Testing xref_parser:t2s/1. @@ -2341,12 +2357,12 @@ format_error(Conf) when is_list(Conf) -> ?line 'Variable assigned more than once: E = E + E\n' = fatom(xref:q(s,"E=E + E")), ?line "Operator applied to argument(s) of different or invalid type(s): " - "E + V * V\n" = + "E + V * V\n" = flatten(xref:format_error(xref:q(s,"E + (V * V)"))), ?line {error,xref_compiler,{type_error,"(V + V) * E"}} = xref:q(s,"(V + V) * E"), ?line "Type does not match structure of constant: [m:f/3 -> g:h/17] : " - "App\n" = + "App\n" = flatten(xref:format_error(xref:q(s,"[{{m,f,3},{g,h,17}}] : App"))), ?line 'Type does not match structure of constant: [m -> f, g -> h] : Fun\n' = fatom(xref:q(s,"[{m,f},g->h] : Fun")), @@ -2360,11 +2376,11 @@ format_error(Conf) when is_list(Conf) -> xref:q(s,"condensation (# E + # V)"), ?line {error,xref_compiler,{type_error,"range (# E + # E)"}} = xref:q(s,"range (#E + #E)"), - ?line {error,xref_compiler,{type_error,"range (# E)"}} = + ?line {error,xref_compiler,{type_error,"range (# E)"}} = xref:q(s,"range #E"), % Hm... ?line {error,xref_compiler,{type_error,"E + # E"}} = xref:q(s,"E + #E + #E"), % Hm... - ?line {error,xref_compiler,{type_error,"V * E || V | V"}} = + ?line {error,xref_compiler,{type_error,"V * E || V | V"}} = xref:q(s,"V * (E || V) | V"), ?line {error,xref_compiler,{type_error,"E || (E | V)"}} = xref:q(s,"V * E || (E | V)"), @@ -2421,7 +2437,7 @@ eval(Query, E, S) -> ?format("------------------------------~n", []), ?format("Evaluating ~p~n", [Query]), ?line {Answer, NewState} = xref_base:q(S, Query, [{verbose, false}]), - {Reply, Expected} = + {Reply, Expected} = case Answer of {ok, R} when is_list(E) -> {unsetify(R), sort(E)}; @@ -2430,7 +2446,7 @@ eval(Query, E, S) -> {error, _Module, Reason} -> {element(1, Reason), E} end, - if + if Reply =:= Expected -> ?format("As expected, got ~n~p~n", [Expected]), {ok, NewState}; @@ -2442,7 +2458,7 @@ eval(Query, E, S) -> analyze(Query, E, S) -> ?format("------------------------------~n", []), ?format("Evaluating ~p~n", [Query]), - ?line {{ok, L}, NewState} = + ?line {{ok, L}, NewState} = xref_base:analyze(S, Query, [{verbose, false}]), case {unsetify(L), sort(E)} of {X,X} -> @@ -2461,7 +2477,7 @@ unsetify(S) -> %% Note: assumes S has been set up; the new state is not returned eval(Query, S) -> - ?line {{ok, Answer}, _NewState} = + ?line {{ok, Answer}, _NewState} = xref_base:q(S, Query, [{verbose, false}]), unsetify(Answer). @@ -2514,7 +2530,7 @@ check_state(S) -> functions_mode_check(S, Info) end. -%% The manual mentions some facts that should always hold. +%% The manual mentions some facts that should always hold. %% Here they are again. functions_mode_check(S, Info) -> %% F = L + X, @@ -2526,7 +2542,7 @@ functions_mode_check(S, Info) -> ?line {ok, V} = xref:q(S, "X + L + B + U"), %% X, L, B and U are disjoint. - ?line {ok, []} = + ?line {ok, []} = xref:q(S, "X * L + X * B + X * U + L * B + L * U + B * U"), %% V = UU + XU + LU, @@ -2577,11 +2593,11 @@ functions_mode_check(S, Info) -> ?line {Local, Exported} = info(Info, no_functions), ?line LX = Local+Exported, - ?line {ok, LXs} = xref:q(S, 'Extra = _:module_info/"(0|1)" + LM, + ?line {ok, LXs} = xref:q(S, 'Extra = _:module_info/"(0|1)" + LM, # (F - Extra)'), ?line true = LX =:= LXs, - ?line {LocalCalls, ExternalCalls, UnresCalls} = + ?line {LocalCalls, ExternalCalls, UnresCalls} = info(Info, no_function_calls), ?line LEU = LocalCalls + ExternalCalls + UnresCalls, ?line {ok, LEU} = xref:q(S, "# LC + # XC"), @@ -2635,7 +2651,7 @@ check_count(S) -> %% {ok, A} = xref:q(S, 'A'), {ok, M} = xref:q(S, 'AM'), - {ok, _} = xref:q(S, + {ok, _} = xref:q(S, "Extra := _:module_info/\"(0|1)\" + LM"), %% info/1: @@ -2670,7 +2686,7 @@ check_count(S) -> ok. info_module([M | Ms], S) -> - {ok, NoCalls} = per_module("T = (E | ~p : Mod), # (XLin) T + # (LLin) T", + {ok, NoCalls} = per_module("T = (E | ~p : Mod), # (XLin) T + # (LLin) T", M, S), {ok, NoFunCalls} = per_module("# (E | ~p : Mod)", M, S), {ok, NoXCalls} = per_module("# (XC | ~p : Mod)", M, S), @@ -2705,7 +2721,10 @@ f(S, A) -> flatten(io_lib:format(S, A)). fatom(R) -> - list_to_atom(flatten(xref:format_error(R))). + list_to_atom(fstring(R)). + +fstring(R) -> + flatten(xref:format_error(R)). start(Server) -> ?line case xref:start(Server) of @@ -2716,14 +2735,14 @@ start(Server) -> end. add_erts_code_path(KernelPath) -> - VersionDirs = + VersionDirs = filelib:is_dir( filename:join( [code:lib_dir(), lists:flatten( ["kernel-", - [X || - {kernel,_,X} <- + [X || + {kernel,_,X} <- application_controller:which_applications()]])])), case VersionDirs of true -> @@ -2743,5 +2762,5 @@ add_erts_code_path(KernelPath) -> [KernelPath] end end. - - + + diff --git a/lib/tools/test/xref_SUITE_data/read/read.erl b/lib/tools/test/xref_SUITE_data/read/read.erl index 4a0cc280c3..19694c9e25 100644 --- a/lib/tools/test/xref_SUITE_data/read/read.erl +++ b/lib/tools/test/xref_SUITE_data/read/read.erl @@ -106,13 +106,13 @@ funfuns() -> apply(m,f,a), % {m,f,-1} 3(a), % {'$M_EXPR','$F_EXPR',1} apply(3,[a]), % {'$M_EXPR','$F_EXPR',1} - + %% POS12=POS11+8 apply(A, A), % number of arguments is not known, {'$M_EXPR','$F_EXPR',-1} Args0 = [list], Args = [a | Args0], % number of arguments is known apply(A, Args), % {'$M_EXPR','$F_EXPR',2} - apply(m3, f3, Args), % + apply(m3, f3, Args), % NotArgs = [is_not, a | list], % number of arguments is not known apply(A, NotArgs), % {'$M_EXPR','$F_EXPR',-1} apply(m4, f4, NotArgs), % {m4,f4,-1} @@ -125,7 +125,7 @@ funfuns() -> bi() when length([]) > 17 -> foo:module_info(), module_info(), - A = tjo, + A = true andalso tjo , t:foo(A), case true of true when integer(1) -> @@ -133,7 +133,7 @@ bi() when length([]) > 17 -> false -> X = flopp end, - X == A; + self() ! X == -A orelse false; bi() -> %% POS14=POS13+18 Z = fun(Y) -> Y end, @@ -159,7 +159,7 @@ bi() -> D + E + F. %bi() -> % %% POS15=POS14+13 -% try +% try % foo:t(), % bar:t() % of @@ -169,7 +169,7 @@ bi() -> % foo:t() % catch % {'EXIT',_} -> bar:t() -% end. +% end. local() -> true. diff --git a/lib/tools/vsn.mk b/lib/tools/vsn.mk index faea408cc2..77b5254eaa 100644 --- a/lib/tools/vsn.mk +++ b/lib/tools/vsn.mk @@ -1 +1 @@ -TOOLS_VSN = 2.6.5.1 +TOOLS_VSN = 2.6.6.1 diff --git a/lib/tv/doc/src/notes.xml b/lib/tv/doc/src/notes.xml index 62fab2f0f1..388bb82c91 100644 --- a/lib/tv/doc/src/notes.xml +++ b/lib/tv/doc/src/notes.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> @@ -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>TV Release Notes</title> @@ -30,6 +30,38 @@ </header> <p>This document describes the changes made to the TV application.</p> +<section><title>TV 2.1.4.6</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + With some window managers (e.g. stumpwm), <c>tv</c> would + constantly restart while trying to open a table. (Thanks + to Dmitriy Budashny.)</p> + <p> + Own Id: OTP-8751</p> + </item> + </list> + </section> + +</section> + +<section><title>TV 2.1.4.5</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Warnings due to new autoimported BIFs removed</p> + <p> + Own Id: OTP-8674 Aux Id: OTP-8579 </p> + </item> + </list> + </section> + +</section> + <section><title>TV 2.1.4.4</title> <section><title>Improvements and New Features</title> diff --git a/lib/tv/src/tv_io_lib_format.erl b/lib/tv/src/tv_io_lib_format.erl index 5042fd3f9d..e043d9296e 100644 --- a/lib/tv/src/tv_io_lib_format.erl +++ b/lib/tv/src/tv_io_lib_format.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1998-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(tv_io_lib_format). @@ -188,7 +188,7 @@ indentation([], I) -> I. term(T, none, _Adj, none, _Pad) -> T; term(T, none, Adj, P, Pad) -> term(T, P, Adj, P, Pad); -term(T, F, Adj, none, Pad) -> term(T, F, Adj, min(flat_length(T), F), Pad); +term(T, F, Adj, none, Pad) -> term(T, F, Adj, erlang:min(flat_length(T), F), Pad); term(T, F, Adj, P, Pad) when F >= P -> adjust_error(T, F, Adj, P, Pad). @@ -316,7 +316,7 @@ fwrite_g(Fl, F, Adj, P, Pad) -> string(S, none, _Adj, none, _Pad) -> S; string(S, F, Adj, none, Pad) -> - string(S, F, Adj, min(flat_length(S), F), Pad); + string(S, F, Adj, erlang:min(flat_length(S), F), Pad); string(S, none, _Adj, P, Pad) -> string:left(flatten(S), P, Pad); string(S, F, Adj, P, Pad) when F >= P -> @@ -362,9 +362,6 @@ reverse([H|T], Stack) -> reverse(T, [H|Stack]); reverse([], Stack) -> Stack. -min(L, R) when L < R -> L; -min(_, R) -> R. - %% flatten(List) %% Flatten a list. diff --git a/lib/tv/src/tv_pb.erl b/lib/tv/src/tv_pb.erl index 34db8d0772..78a27185dc 100644 --- a/lib/tv/src/tv_pb.erl +++ b/lib/tv/src/tv_pb.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% -module(tv_pb). @@ -522,7 +522,7 @@ handle_col_resizing(RbtnId, RealCol, VirtualCol, Xpos, ProcVars) -> get_xdiff(Id, Btn, LastXdiff, LineId, LineXpos, MinAllowedXdiff) -> receive {gs, Id, motion, {resbtn, _RealCol, _VirtCol, _OldXpos}, [NewXdiff | _T]} -> - UsedXdiff = max(MinAllowedXdiff, NewXdiff), + UsedXdiff = erlang:max(MinAllowedXdiff, NewXdiff), gs:config(LineId, [{x, LineXpos + UsedXdiff}]), get_xdiff(Id, Btn, UsedXdiff, LineId, LineXpos, MinAllowedXdiff); {gs, Id, buttonrelease, _Data, [Btn | _T]} -> @@ -658,28 +658,3 @@ update_vbtns(Msg, ProcVars) -> update_keys(Msg, ProcVars) -> #pb_key_info{list_of_keys = KeyList} = Msg, tv_pb_funcs:update_keys(KeyList, ProcVars). - - - - - - - - -%%====================================================================== -%% Function: -%% -%% Return Value: -%% -%% Description: -%% -%% Parameters: -%%====================================================================== - - -max(A, B) when A >= B -> - A; -max(_, B) -> - B. - - diff --git a/lib/tv/src/tv_pg_gridfcns.erl b/lib/tv/src/tv_pg_gridfcns.erl index 809403fd96..3d23c8a69f 100644 --- a/lib/tv/src/tv_pg_gridfcns.erl +++ b/lib/tv/src/tv_pg_gridfcns.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% -module(tv_pg_gridfcns). @@ -98,7 +98,7 @@ init_grid(GridParentId, GridWidth, nof_rows_shown = NofRowsShown }, - NewNofCols = max(length(ColsShown), NofCols), + NewNofCols = erlang:max(length(ColsShown), NofCols), % The GridColWidths list shall contain the current width of each frame. NewColWidths = update_col_widths(ColsShown, ColWidths, FirstColShown, @@ -205,8 +205,8 @@ resize_grid(NewWidth, NewHeight, ProcVars) -> check_nof_cols(ColsShown, (NofColsShown - NofCols), ColFrameIds, ColIds, RowIds, NofRows, RowHeight, FgColor, BgColor ), - clear_fields(lists:nthtail(NofColsShown, NewColIds), - lists:nthtail(NofRowsShown, NewRowIds)), + clear_fields(safe_nthtail(NofColsShown, NewColIds), + safe_nthtail(NofRowsShown, NewRowIds)), RowsToUpdate = lists:sublist(NewRowIds, NofRowsShown), @@ -270,7 +270,7 @@ resize_grid_column(RealCol, VirtualCol, Xdiff, ProcVars) -> lists_as_strings = ListAsStr} = GridP, % Get new width! - Width = min(MaxColWidth, max((lists:nth(VirtualCol, ColWidths) + Xdiff), + Width = erlang:min(MaxColWidth, erlang:max((lists:nth(VirtualCol, ColWidths) + Xdiff), MinColWidth)), % Resize the column. @@ -279,7 +279,7 @@ resize_grid_column(RealCol, VirtualCol, Xdiff, ProcVars) -> % Update the ColWidths list. TempColWidths = lists:sublist(ColWidths, VirtualCol - 1) ++ - [NewWidthOfCol | lists:nthtail(VirtualCol, ColWidths)], + [NewWidthOfCol | safe_nthtail(VirtualCol, ColWidths)], % Check the other columns, whether a new column has to be created. ColsShown = compute_cols_shown(FirstColShown, TempColWidths, GridWidth, @@ -455,8 +455,8 @@ scroll_grid_horizontally(NewFirstColShown, ProcVars) -> refresh_visible_rows(RowsToUpdate, NewFirstColShown, NofColsShown, RowDataList, ListAsStr), % Clear fields currently not visible. - clear_fields(lists:nthtail(NofColsShown, NewColIds), - lists:nthtail(NofRowsShown, NewRowIds)), + clear_fields(safe_nthtail(NofColsShown, NewColIds), + safe_nthtail(NofRowsShown, NewRowIds)), NewGridP = GridP#grid_params{nof_cols = NewNofCols, @@ -1336,7 +1336,7 @@ resize_all_grid_columns(RealCol, [ColWidth | Tail], ColFrameIds, MaxColWidth, Mi resize_one_column(RealCol, Width, ColFrameIds, MaxW, MinW) -> - NewWidthOfCol = min(MaxW, max(Width, MinW)), + NewWidthOfCol = erlang:min(MaxW, erlang:max(Width, MinW)), case length(ColFrameIds) of RealCol -> done; @@ -1565,7 +1565,7 @@ update_col_widths(ColsShown, ColWidths, FirstColShown, DefaultColWidth) -> if NecessaryNofVirtualCols > NofVirtualCols -> TailNo = NofVirtualCols - FirstColShown + 1, % Always >= 0 !!! - NewColWidths ++ lists:nthtail(TailNo, ColsShown); + NewColWidths ++ safe_nthtail(TailNo, ColsShown); true -> NewColWidths end. @@ -1653,7 +1653,7 @@ compute_cols_shown(FirstColShown, ColWidths, GridWidth, _NofCols, DefaultColWidt ColWidthsLength < FirstColShown -> []; true -> - lists:nthtail(FirstColShown - 1, ColWidths) + safe_nthtail(FirstColShown - 1, ColWidths) end, compute_cols_shown(UsedColWidths, GridWidth, DefaultColWidth). @@ -1896,44 +1896,19 @@ extract_ids_for_one_row(N, [ColIds | Tail]) -> %%%--------------------------------------------------------------------- - - - -%%====================================================================== -%% Function: -%% -%% Return Value: -%% -%% Description: -%% -%% Parameters: -%%====================================================================== - - -max(A, B) when A > B -> - A; -max(_, B) -> - B. - - - - - - - %%====================================================================== -%% Function: +%% Function: %% -%% Return Value: +%% Return Value: %% -%% Description: +%% Description: %% -%% Parameters: +%% Parameters: %%====================================================================== -min(A, B) when A < B -> - A; -min(_, B) -> - B. - +safe_nthtail(_, []) -> []; +safe_nthtail(1, [_|T]) -> T; +safe_nthtail(N, [_|T]) when N > 1 -> + safe_nthtail(N - 1, T); +safe_nthtail(0, L) when is_list(L) -> L. diff --git a/lib/tv/vsn.mk b/lib/tv/vsn.mk index 9b8c1a68c7..958aa0ea42 100644 --- a/lib/tv/vsn.mk +++ b/lib/tv/vsn.mk @@ -1 +1 @@ -TV_VSN = 2.1.4.4 +TV_VSN = 2.1.4.6 diff --git a/lib/typer/src/typer.erl b/lib/typer/src/typer.erl index cebe6ea488..e19614f911 100644 --- a/lib/typer/src/typer.erl +++ b/lib/typer/src/typer.erl @@ -2,7 +2,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 @@ -26,6 +26,8 @@ -module(typer). +%% Avoid warning for local function error/1 clashing with autoimported BIF. +-compile({no_auto_import,[error/1]}). -export([start/0]). -export([error/1, compile_error/1]). % for error reporting diff --git a/lib/typer/vsn.mk b/lib/typer/vsn.mk index 285fa62da3..7f4aabb335 100644 --- a/lib/typer/vsn.mk +++ b/lib/typer/vsn.mk @@ -1 +1 @@ -TYPER_VSN = 0.1.7.4 +TYPER_VSN = 0.1.7.5 diff --git a/lib/webtool/doc/src/notes.xml b/lib/webtool/doc/src/notes.xml index dc325b5b61..5179f37db2 100644 --- a/lib/webtool/doc/src/notes.xml +++ b/lib/webtool/doc/src/notes.xml @@ -31,6 +31,23 @@ <p>This document describes the changes made to the Webtool application.</p> +<section><title>WebTool 0.8.7</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Up until now Netscape has been the default web browser on + Unix/Linux. Webtool has now been updated to start Firefox + as default browser instead.</p> + <p> + Own Id: OTP-8651 Aux Id: OTP-8650 </p> + </item> + </list> + </section> + +</section> + <section><title>WebTool 0.8.6</title> <section><title>Improvements and New Features</title> diff --git a/lib/webtool/doc/src/start_webtool.xml b/lib/webtool/doc/src/start_webtool.xml index 184285c631..b525b38845 100644 --- a/lib/webtool/doc/src/start_webtool.xml +++ b/lib/webtool/doc/src/start_webtool.xml @@ -4,7 +4,7 @@ <comref> <header> <copyright> - <year>2003</year><year>2009</year> + <year>2003</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -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>start_webtool</title> @@ -56,7 +56,7 @@ Or http://127.0.0.1:8888/ Usage: start_webtool application [ browser ] Available applications are: [orber,appmon,crashdump_viewer,webcover] -Default browser is 'iexplore' (Internet Explorer) on Windows or else 'netscape' </pre> +Default browser is 'iexplore' (Internet Explorer) on Windows or else 'firefox' </pre> <p>To start any of the listed applications, give the application name as the first argument, e.g.</p> <pre> @@ -68,7 +68,7 @@ Starting webcover... Sending URL to netscape...done </pre> <p>The WebTool application WebCover is then started and the default browser is used. The default browser is Internet - Explorer on Windows or else Netscape. + Explorer on Windows or else Firefox. </p> <p>To use another browser, give the browser's start command as the second argument, e.g.</p> diff --git a/lib/webtool/src/webtool.erl b/lib/webtool/src/webtool.erl index 51d821751c..1be903b827 100644 --- a/lib/webtool/src/webtool.erl +++ b/lib/webtool/src/webtool.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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(webtool). @@ -139,7 +139,7 @@ script_start([App]) -> DefaultBrowser = case os:type() of {win32,_} -> iexplore; - _ -> netscape + _ -> firefox end, script_start([App,DefaultBrowser]); script_start([App,Browser]) -> @@ -159,6 +159,8 @@ script_start([App,Browser]) -> "http://localhost:" ++ PortStr ++ "/" ++ StartPage end, case Browser of + none -> + ok; iexplore when OSType == win32-> io:format("Starting internet explorer...\n"), {ok,R} = win32reg:open(""), @@ -170,7 +172,7 @@ script_start([App,Browser]) -> _ when OSType == win32 -> io:format("Starting ~w...\n",[Browser]), os:cmd("\"" ++ atom_to_list(Browser) ++ "\" " ++ Url); - B when B==netscape; B==mozilla -> + B when B==firefox; B==mozilla -> io:format("Sending URL to ~w...",[Browser]), BStr = atom_to_list(Browser), SendCmd = BStr ++ " -raise -remote \'openUrl(" ++ @@ -209,7 +211,7 @@ usage() -> "\nUsage: start_webtool application [ browser ]\n" "\nAvailable applications are: ~p\n" "Default browser is \'iexplore\' (Internet Explorer) on Windows " - "or else \'netscape\'\n", + "or else \'firefox\'\n", [Apps]), stop(). diff --git a/lib/webtool/vsn.mk b/lib/webtool/vsn.mk index 712e3abbaf..6b76883330 100644 --- a/lib/webtool/vsn.mk +++ b/lib/webtool/vsn.mk @@ -1 +1 @@ -WEBTOOL_VSN=0.8.6 +WEBTOOL_VSN=0.8.7 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/README b/lib/wx/api_gen/README index 3c49f7b2a5..10b5209789 100644 --- a/lib/wx/api_gen/README +++ b/lib/wx/api_gen/README @@ -2,16 +2,20 @@ API GENERATION: Most of the code in wx is generated. Users of wxErlang should not normally need to regenerate the generated code, as it is checked in by wxErlang developers, when changes are made. - 2008-09-29 Code checked in is currently generated from wxwidgets 2.8.7. + + Code checked in is currently generated from wxwidgets 2.8.10. REQUIREMENTS: The code generation requires doxygen (1.4.6) which is used to parse wxWidgets c++ headers and generate xml files (in wx_xml/). - (2008-09-29 doxygen 1.4.6 is required. - Later versions of Doxygen - up to 1.5.6 at least - have a bug in the xml generation - which causes us problems. This has been logged and we are waiting for a fix.) + 2008-09-29 doxygen 1.4.6 is required. + Later versions of Doxygen - up to 1.5.6 at least - have a bug in the xml generation + which causes us problems. This has been logged and we are waiting for a fix. + + doxygen 1.6.1 and doxygen 1.6.3 might work but is not what I use, i.e. + review the diffs. CONFIGURATION: wxapi.conf contains the specification to the code generator. The code @@ -22,5 +26,11 @@ CONFIGURATION: and running make. Sometimes the code generator will require changes, I havn't thought of everything yet. +RUNNING: + I use the following alias wxgen='make WXGTK_DIR=/opt/local/include/wx-2.8/ GL_DIR=/home/dgud/opengl' + + I keep the opengl headers separate so I don't go backwards in version when generating the code + from another machine. + CONTRIBUTION: Send me patches or update the svn version. diff --git a/lib/wx/api_gen/gl_doxygen.conf b/lib/wx/api_gen/gl_doxygen.conf index e29a3654b5..c9bdb6a408 100644 --- a/lib/wx/api_gen/gl_doxygen.conf +++ b/lib/wx/api_gen/gl_doxygen.conf @@ -8,7 +8,7 @@ PROJECT_NUMBER = 0.1 OUTPUT_DIRECTORY = ./ CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English -USE_WINDOWS_ENCODING = NO +#USE_WINDOWS_ENCODING = NO BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES ABBREVIATE_BRIEF = @@ -20,7 +20,7 @@ STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO -DETAILS_AT_TOP = NO +# DETAILS_AT_TOP = NO INHERIT_DOCS = YES DISTRIBUTE_GROUP_DOC = NO SEPARATE_MEMBER_PAGES = NO @@ -175,17 +175,20 @@ PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES MACRO_EXPANSION = YES -EXPAND_ONLY_PREDEF = NO +EXPAND_ONLY_PREDEF = YES SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = PREDEFINED = \ APIENTRY="" \ + APIENTRYP="*" \ + GLAPIENTRY="" \ + GLAPIENTRYP="*" \ WINGDIAPI="" \ GLAPI="" \ GL_GLEXT_PROTOTYPES="1" -EXPAND_AS_DEFINED = YES +EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references @@ -214,9 +217,9 @@ DIRECTORY_GRAPH = YES DOT_IMAGE_FORMAT = png DOT_PATH = DOTFILE_DIRS = -MAX_DOT_GRAPH_WIDTH = 1024 -MAX_DOT_GRAPH_HEIGHT = 1024 -MAX_DOT_GRAPH_DEPTH = 0 +#MAX_DOT_GRAPH_WIDTH = 1024 +#MAX_DOT_GRAPH_HEIGHT = 1024 +#MAX_DOT_GRAPH_DEPTH = 0 DOT_TRANSPARENT = NO DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES diff --git a/lib/wx/api_gen/gl_gen.erl b/lib/wx/api_gen/gl_gen.erl index 91a6a1adbf..42802c6de7 100644 --- a/lib/wx/api_gen/gl_gen.erl +++ b/lib/wx/api_gen/gl_gen.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% %%%------------------------------------------------------------------- @@ -47,9 +47,9 @@ safe(What, QuitOnErr) -> io:format("Completed succesfully~n~n", []), QuitOnErr andalso gen_util:halt(0) catch Err:Reason -> - catch gen_util:close(), io:format("Error ~p: ~p:~p~n ~p~n", [get(current_func),Err,Reason,erlang:get_stacktrace()]), + (catch gen_util:close()), timer:sleep(1999), QuitOnErr andalso gen_util:halt(1) end. @@ -605,7 +605,7 @@ is_equal(F1=#func{type=T1,params=A1},F2=#func{type=T2,params=A2}) -> true -> ok; false -> %% io:format("A1: ~p~nA2: ~p~n",[A1,A2]), - ?warning("Skipped Ext Not Equal ~p ~p~n", + ?warning("Keeping Ext Not Equal ~p ~p~n", [F1#func.name,F2#func.name]) end, Equal. diff --git a/lib/wx/api_gen/gl_gen_c.erl b/lib/wx/api_gen/gl_gen_c.erl index 864ce8b1ac..3293050ab9 100644 --- a/lib/wx/api_gen/gl_gen_c.erl +++ b/lib/wx/api_gen/gl_gen_c.erl @@ -136,8 +136,7 @@ declare_var(A=#arg{name=N,in=false,type=#type{name=T,base=binary,size=Sz}}) -> true = is_number(Sz), %% Assert w(" ~s ~s[~p];~n", [T,N,Sz]), A; -declare_var(A=#arg{name=N,in=false, - type=#type{name=T="GLUquadric",base=B,by_val=false,single=true}}) -> +declare_var(A=#arg{in=false, type=#type{name="GLUquadric",by_val=false,single=true}}) -> A; declare_var(A=#arg{name=N,in=false, type=#type{name=T,base=B,by_val=false,single=true}}) -> diff --git a/lib/wx/api_gen/gl_gen_erl.erl b/lib/wx/api_gen/gl_gen_erl.erl index 07e4d6f783..ce35484561 100644 --- a/lib/wx/api_gen/gl_gen_erl.erl +++ b/lib/wx/api_gen/gl_gen_erl.erl @@ -178,9 +178,16 @@ gen_funcs(F) -> erase(current_func), w(".~n~n",[]). -gen_export([F|_]) when is_list(F) -> +gen_export(F) -> + try gen_export_1(F) + catch E:R -> + io:format("Crash ~p:~p in ~p ~n",[E,R, erlang:get_stacktrace()]), + io:format("Func = ~p~n ~p", [F, get(F)]) + end. + +gen_export_1([F|_]) when is_list(F) -> gen_export2(get(F)); -gen_export(F) when is_list(F) -> +gen_export_1(F) when is_list(F) -> gen_export2(get(F)). gen_export2(#func{name=Name,alt={vector,VecPos,Vec}}) -> diff --git a/lib/wx/api_gen/wx_doxygen.conf b/lib/wx/api_gen/wx_doxygen.conf index 1fc57486e6..df150fd154 100644 --- a/lib/wx/api_gen/wx_doxygen.conf +++ b/lib/wx/api_gen/wx_doxygen.conf @@ -8,7 +8,7 @@ PROJECT_NUMBER = 0.1 OUTPUT_DIRECTORY = ./ CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English -USE_WINDOWS_ENCODING = NO +#USE_WINDOWS_ENCODING = NO BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES ABBREVIATE_BRIEF = @@ -20,7 +20,7 @@ STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO -DETAILS_AT_TOP = NO +# DETAILS_AT_TOP = NO INHERIT_DOCS = YES DISTRIBUTE_GROUP_DOC = NO SEPARATE_MEMBER_PAGES = NO @@ -73,11 +73,11 @@ WARN_LOGFILE = # configuration options related to the input files #--------------------------------------------------------------------------- INPUT = @WXGTK_DIR@/wx/ wx_extra/ -#FILE_PATTERNS = *.h +# FILE_PATTERNS = *.h RECURSIVE = YES EXCLUDE = EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = mac/* mgl/* msw/* os2/* x11/* gtk1/* cocoa/* motif/* msdos/* palmos/* private/* +EXCLUDE_PATTERNS = mac/* mgl/* msw/* os2/* x11/* gtk1/* cocoa/* motif/* msdos/* palmos/* private/* vms_x_fix.h EXAMPLE_PATH = EXAMPLE_PATTERNS = EXAMPLE_RECURSIVE = NO @@ -176,10 +176,11 @@ PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES MACRO_EXPANSION = YES -EXPAND_ONLY_PREDEF = NO +EXPAND_ONLY_PREDEF = YES SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = + PREDEFINED = \ wxUSE_MENUS=1 \ wxUSE_TOOLBAR=1 \ @@ -215,6 +216,7 @@ PREDEFINED = \ wxUSE_LISTBOX=1 \ wxUSE_BMPBUTTON=1 \ wxUSE_CHECKBOX=1 \ + wxUSE_CHECKLISTBOX=1 \ wxUSE_TREECTRL=1 \ wxUSE_LISTCTRL=1 \ wxUSE_BOOKCTRL=1 \ @@ -251,15 +253,17 @@ PREDEFINED = \ wxUSE_CLIPBOARD=1 \ wxABI_VERSION=20809 \ __WXGTK24__=1 \ + __WXGTK20__=1 \ __WXGTK__=1 \ + wxCHECKLBOX_CHECKED="" \ WXDLLEXPORT="" # WXWIN_COMPATIBILITY_2_6=1 \ - -EXPAND_AS_DEFINED = YES + +EXPAND_AS_DEFINED = WX_FORWARD_TO_SCROLL_HELPER SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- -# Configuration::additions related to external references +# Configuration::additions related to external references #--------------------------------------------------------------------------- TAGFILES = GENERATE_TAGFILE = @@ -285,9 +289,6 @@ DIRECTORY_GRAPH = YES DOT_IMAGE_FORMAT = png DOT_PATH = DOTFILE_DIRS = -MAX_DOT_GRAPH_WIDTH = 1024 -MAX_DOT_GRAPH_HEIGHT = 1024 -MAX_DOT_GRAPH_DEPTH = 0 DOT_TRANSPARENT = NO DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES diff --git a/lib/wx/api_gen/wx_gen.erl b/lib/wx/api_gen/wx_gen.erl index 2ed4476440..c075324c1f 100644 --- a/lib/wx/api_gen/wx_gen.erl +++ b/lib/wx/api_gen/wx_gen.erl @@ -255,19 +255,24 @@ parse_attr(Defs, Class, Ev, Info = #hs{acc=AccList0}) -> parse_attr1([{{attr,_}, #xmlElement{content=C, attributes=Attrs}}|R], AttrList0, Opts, Res) -> Parse = fun(Con, Ac) -> parse_param(Con, Opts, Ac) end, Param0 = foldl(Parse, #param{}, drop_empty(C)), - case keysearch(prot, #xmlAttribute.name, Attrs) of - {value, #xmlAttribute{value = "public"}} -> - {Acc,AttrList} = attr_acc(Param0, AttrList0), - parse_attr1(R,AttrList,Opts, - [Param0#param{in=false,prot=public,acc=Acc}|Res]); - {value, #xmlAttribute{value = "protected"}} -> - {Acc,AttrList} = attr_acc(Param0, AttrList0), - parse_attr1(R,AttrList,Opts, - [Param0#param{in=false,prot=protected,acc=Acc}|Res]); - {value, #xmlAttribute{value = "private"}} -> - {Acc,AttrList} = attr_acc(Param0, AttrList0), - parse_attr1(R,AttrList,Opts, - [Param0#param{in=false,prot=private,acc=Acc}|Res]) + case Param0 of + #param{where=nowhere} -> + parse_attr1(R,AttrList0,Opts,Res); + _ -> + case keysearch(prot, #xmlAttribute.name, Attrs) of + {value, #xmlAttribute{value = "public"}} -> + {Acc,AttrList} = attr_acc(Param0, AttrList0), + parse_attr1(R,AttrList,Opts, + [Param0#param{in=false,prot=public,acc=Acc}|Res]); + {value, #xmlAttribute{value = "protected"}} -> + {Acc,AttrList} = attr_acc(Param0, AttrList0), + parse_attr1(R,AttrList,Opts, + [Param0#param{in=false,prot=protected,acc=Acc}|Res]); + {value, #xmlAttribute{value = "private"}} -> + {Acc,AttrList} = attr_acc(Param0, AttrList0), + parse_attr1(R,AttrList,Opts, + [Param0#param{in=false,prot=private,acc=Acc}|Res]) + end end; parse_attr1([{_Id,_}|R],AttrList,Info, Res) -> parse_attr1(R,AttrList,Info, Res); @@ -591,17 +596,17 @@ parse_param(#xmlElement{name=array,content=C},_Opts, T = #param{type=Type0}) -> [#xmlText{value=RealVar}] = C, [Name] = string:tokens(RealVar, "() "), T#param{name=Name}; -%% #type{mod=[const]} -> -%% T#param{type=Type0#type{single=array, by_val=true}}; -%% _ -> -%% T#param{type=Type0#type{single=array, by_val=false}} _ -> T#param{type=Type0#type{single=array, by_val=true}} end; parse_param(#xmlElement{name=name,content=[C]}, _, T) -> %% Attributes have this - #xmlText{value=Name} = C, - T#param{name=Name}; + case C of + #xmlText{value=Name="ms_classInfo"} -> + T#param{name=Name, where=nowhere}; + #xmlText{value=Name} -> + T#param{name=Name} + end; %% Skipped: Attributes have this parse_param(#xmlElement{name=definition}, _, T) -> T; parse_param(#xmlElement{name=argsstring}, _, T) -> T; @@ -610,6 +615,7 @@ parse_param(#xmlElement{name=detaileddescription}, _, T) -> T; parse_param(#xmlElement{name=inbodydescription}, _, T) -> T; parse_param(#xmlElement{name=location}, _, T) -> T; parse_param(#xmlElement{name=referencedby}, _, T) -> T; +parse_param(#xmlElement{name=reimplements}, _, T) -> T; parse_param(Other=#xmlElement{name=Name}, _, T) -> io:format("Unhandled Param ~p ~p ~n in ~p~n", [Name,Other,T]), ?error(unhandled_param). @@ -1274,11 +1280,11 @@ extract_enum(#xmlElement{name=memberdef,content=C}, Class, File) -> undefined -> %% io:format("1Enum name ~p~n", [Name]), %% [io:format(" ~s ~p~n", [D,V]) || {D,V} <- Vals], - put({enum, Name}, #enum{vals=Vals}); + put({enum, Name}, #enum{vals=Vals, from={File,Class,Name0}}); E = #enum{vals=undefined} -> %% io:format("2Enum name ~p~n", [Name]), %% [io:format(" ~s ~p~n", [D,V]) || {D,V} <- Vals], - put({enum, Name}, E#enum{vals=Vals}); + put({enum, Name}, E#enum{vals=Vals, from={File,Class,Name0}}); #enum{vals=Vals} -> ok; %% io:format("Same? ~p ~n", [PVals == Vals]) #enum{vals=OldVals} -> @@ -1352,7 +1358,7 @@ extract_defs(Defs, File) -> {Vals,_Skip} -> %% io:format("Defs file ~p~n", [File]), %% [io:format(" ~s ~p~n", [D,V]) || {D,V} <- Vals, not is_integer(V)] - put({enum, {define,"From " ++ File ++ ".h"}}, #enum{vals=Vals}) + put({enum, {define,"From " ++ File ++ ".h"}}, #enum{vals=Vals, from={File, undefined, "@define"}}) end. extract_defs2(#xmlElement{name=memberdef,content=C},{Acc,Skip}) -> diff --git a/lib/wx/api_gen/wx_gen.hrl b/lib/wx/api_gen/wx_gen.hrl index b34d399358..17265a2842 100644 --- a/lib/wx/api_gen/wx_gen.hrl +++ b/lib/wx/api_gen/wx_gen.hrl @@ -1,19 +1,19 @@ %% %% %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 %% 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% -record(class, { @@ -72,7 +72,7 @@ } ). --record(enum, {skip="", as_atom=false, vals}). +-record(enum, {from, skip="", as_atom=false, vals}). -record(const,{name,val,enum,is_const}). -define(error(What), diff --git a/lib/wx/api_gen/wx_gen_cpp.erl b/lib/wx/api_gen/wx_gen_cpp.erl index 9e9f8799c7..846cec46c4 100644 --- a/lib/wx/api_gen/wx_gen_cpp.erl +++ b/lib/wx/api_gen/wx_gen_cpp.erl @@ -1010,6 +1010,11 @@ gen_macros() -> w("#include <wx/filename.h>~n"), w("~n~n", []), + w("#ifndef wxICON_DEFAULT_BITMAP_TYPE~n",[]), + w(" #define wxICON_DEFAULT_BITMAP_TYPE wxBITMAP_TYPE_ICO_RESOURCE~n",[]), + w("#endif~n", []), + w("~n~n", []), + [w("#define ~s_~s ~p~n", [Class,Name,Id]) || {Class,Name,_,Id} <- wx_gen_erl:get_unique_names()], w("~n~n"). diff --git a/lib/wx/api_gen/wx_gen_erl.erl b/lib/wx/api_gen/wx_gen_erl.erl index d75442d307..7962dd9fbf 100644 --- a/lib/wx/api_gen/wx_gen_erl.erl +++ b/lib/wx/api_gen/wx_gen_erl.erl @@ -1035,29 +1035,34 @@ gen_enums_ints() -> " href, target %% string()~n" " }).~n", []), w("~n%% Hardcoded Defines~n", []), - Enums = [E || E = {{enum,_},#enum{as_atom=false}} <- get()], + Enums = [E || {{enum,_},E = #enum{as_atom=false}} <- get()], w("-define(wxDefaultSize, {-1,-1}).~n", []), w("-define(wxDefaultPosition, {-1,-1}).~n", []), w("~n%% Global Variables~n", []), [w("-define(~s, wxe_util:get_const(~s)).~n", [Gvar, Gvar]) || {Gvar,_,_Id} <- get(gvars)], w("~n%% Enum and defines~n", []), - foldl(fun({{enum,Type},Enum= #enum{as_atom=false}}, Done) -> - build_enum_ints(Type,Enum,Done); + foldl(fun(Enum= #enum{vals=Vals}, Done) when Vals =/= [] -> + build_enum_ints(Enum,Done); (_,Done) -> Done end, gb_sets:empty(), lists:sort(Enums)), close(). -build_enum_ints(Type,#enum{vals=Vals},Done) -> - case Type of - [$@|_] -> ok; % anonymous - {Class,[$@|_]} when Vals =/= [] -> w("% From class ~s~n", [Class]); - {Class,Enum} when Vals =/= [] -> w("% From ~s::~s~n", [Class,Enum]); - _ when Vals =/= [] -> w("% Type ~s~n", [Type]); - _ -> ok +build_enum_ints(#enum{from=From, vals=Vals},Done) -> + case From of + {File, undefined, [$@|_]} -> + w("% From \"~s.h\"~n",[File]); + {File, undefined, Name} -> + w("% From \"~s.h\": ~s~n",[File, Name]); + {_File, Class,[$@|_]} -> + w("% From class ~s~n",[Class]); + {_File, Class, Name} -> + w("% From class ~s::~s~n",[Class, Name]) end, - Format = fun(#const{name=Name,val=Value,is_const=true}) when is_integer(Value) -> + Format = fun(#const{name="wxEVT_" ++ _}) -> + ignore; %% Ignore event macros they are not valid in our event model + (#const{name=Name,val=Value,is_const=true}) when is_integer(Value) -> w("-define(~s, ~p).~n", [enum_name(Name),Value]); (#const{name=Name,val=Value,is_const=false}) when is_integer(Value) -> w("-define(~s, wxe_util:get_const(~s)).~n", [enum_name(Name),enum_name(Name)]); diff --git a/lib/wx/api_gen/wxapi.conf b/lib/wx/api_gen/wxapi.conf index 4f7bbfedef..6bafda5b9d 100644 --- a/lib/wx/api_gen/wxapi.conf +++ b/lib/wx/api_gen/wxapi.conf @@ -27,7 +27,11 @@ wxFONTENCODING_UTF32,wxFONTENCODING_UTF16, wxDEFAULT_CONTROL_BORDER,wxMOD_CMD, wxMAJOR_VERSION, wxMINOR_VERSION, - wxRELEASE_NUMBER,wxSUBRELEASE_NUMBER,wxBETA_NUMBER + wxRELEASE_NUMBER,wxSUBRELEASE_NUMBER,wxBETA_NUMBER, + %% + wxALWAYS_NATIVE_DOUBLE_BUFFER, + wxGAUGE_EMULATE_INDETERMINATE_MODE, + wxTR_DEFAULT_STYLE ]}. {gvars, @@ -702,7 +706,7 @@ ['wxCheckBox','~wxCheckBox','Create','GetValue','Get3StateValue', 'Is3rdStateAllowedForUser','Is3State','IsChecked','SetValue', 'Set3StateValue']}. -{class, wxCheckListBox, wxListBox, [{skip,[{wxCheckListBox,8}]}], +{class, wxCheckListBox, wxListBox, [{skip,[{wxCheckListBox,8}]}], [{'wxCheckListBox',[{"pos",{def, "wxDefaultPosition"}}, {"size",{def, "wxDefaultSize"}}, {"choices",{def, ""}}]}, @@ -898,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]}]}, @@ -1686,7 +1690,7 @@ {class, wxSplitterEvent, wxNotifyEvent, - [ + [{acc, [{x, skip}, {y, skip}, {pos, skip}, {win, skip}, {pt, skip}]}, %% arrgh doxygen bugs {event, [wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED, wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGING, @@ -1736,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/Makefile.in b/lib/wx/c_src/Makefile.in index 5a0b4ce8ef..8710641b57 100644 --- a/lib/wx/c_src/Makefile.in +++ b/lib/wx/c_src/Makefile.in @@ -167,7 +167,7 @@ release_spec: opt $(INSTALL_DIR) $(RELSYSDIR)/priv/$(SYS_TYPE) $(INSTALL_DATA) ../priv/erlang-logo32.png $(RELSYSDIR)/priv/ $(INSTALL_DATA) ../priv/erlang-logo64.png $(RELSYSDIR)/priv/ - $(INSTALL_DATA) $(TARGET_DIR)/$(TARGET_API)$(SO_EXT) $(RELSYSDIR)/priv/$(SYS_TYPE) + $(INSTALL_PROGRAM) $(TARGET_DIR)/$(TARGET_API)$(SO_EXT) $(RELSYSDIR)/priv/$(SYS_TYPE) release_docs_spec: diff --git a/lib/wx/c_src/gen/gl_fdefs.h b/lib/wx/c_src/gen/gl_fdefs.h index f8851ddb83..2096f7a413 100644 --- a/lib/wx/c_src/gen/gl_fdefs.h +++ b/lib/wx/c_src/gen/gl_fdefs.h @@ -16,7 +16,7 @@ * * %CopyrightEnd% */ -/***** This file is generated do not edit ****/ +/***** This file is generated do not edit ****/ #ifdef WX_DEF_EXTS # define WXE_EXTERN diff --git a/lib/wx/c_src/gen/gl_finit.h b/lib/wx/c_src/gen/gl_finit.h index a22192d06a..ef29f05c4d 100644 --- a/lib/wx/c_src/gen/gl_finit.h +++ b/lib/wx/c_src/gen/gl_finit.h @@ -16,7 +16,7 @@ * * %CopyrightEnd% */ -/***** This file is generated do not edit ****/ +/***** This file is generated do not edit ****/ static struct { const char * name; diff --git a/lib/wx/c_src/gen/gl_funcs.cpp b/lib/wx/c_src/gen/gl_funcs.cpp index 41a5524891..95d3c23b23 100644 --- a/lib/wx/c_src/gen/gl_funcs.cpp +++ b/lib/wx/c_src/gen/gl_funcs.cpp @@ -16,7 +16,7 @@ * * %CopyrightEnd% */ -/***** This file is generated do not edit ****/ +/***** This file is generated do not edit ****/ #include <stdio.h> #include <string.h> @@ -41,10 +41,10 @@ void gl_dispatch(int op, char *bp,ErlDrvTermData caller,WXEBinRef *bins[]){ } }; - switch(op) + switch(op) { - case 5000: - wxe_tess_impl(bp, caller); + case 5000: + wxe_tess_impl(bp, caller); break; case WXE_BIN_INCR: driver_binary_inc_refc(bins[0]->bin); @@ -52,7 +52,7 @@ void gl_dispatch(int op, char *bp,ErlDrvTermData caller,WXEBinRef *bins[]){ case WXE_BIN_DECR: driver_binary_dec_refc(bins[0]->bin); break; -case 5010: { // gluBuild1DMipmapLevels +case 5010: { // gluBuild1DMipmapLevels GLenum *target = (GLenum *) bp; bp += 4; GLint *internalFormat = (GLint *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; @@ -69,8 +69,8 @@ case 5010: { // gluBuild1DMipmapLevels rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5011: { // gluBuild1DMipmaps +}; break; +case 5011: { // gluBuild1DMipmaps GLenum *target = (GLenum *) bp; bp += 4; GLint *internalFormat = (GLint *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; @@ -84,8 +84,8 @@ case 5011: { // gluBuild1DMipmaps rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5012: { // gluBuild2DMipmapLevels +}; break; +case 5012: { // gluBuild2DMipmapLevels GLenum *target = (GLenum *) bp; bp += 4; GLint *internalFormat = (GLint *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; @@ -103,8 +103,8 @@ case 5012: { // gluBuild2DMipmapLevels rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5013: { // gluBuild2DMipmaps +}; break; +case 5013: { // gluBuild2DMipmaps GLenum *target = (GLenum *) bp; bp += 4; GLint *internalFormat = (GLint *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; @@ -119,8 +119,8 @@ case 5013: { // gluBuild2DMipmaps rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5014: { // gluBuild3DMipmapLevels +}; break; +case 5014: { // gluBuild3DMipmapLevels GLenum *target = (GLenum *) bp; bp += 4; GLint *internalFormat = (GLint *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; @@ -139,8 +139,8 @@ case 5014: { // gluBuild3DMipmapLevels rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5015: { // gluBuild3DMipmaps +}; break; +case 5015: { // gluBuild3DMipmaps GLenum *target = (GLenum *) bp; bp += 4; GLint *internalFormat = (GLint *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; @@ -156,8 +156,8 @@ case 5015: { // gluBuild3DMipmaps rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5016: { // gluCheckExtension +}; break; +case 5016: { // gluCheckExtension int * extNameLen = (int *) bp; bp += 4; GLubyte * extName = (GLubyte *) bp; bp += (8-((*extNameLen*1+4)%8))%8; int * extStringLen = (int *) bp; bp += 4; @@ -169,8 +169,8 @@ case 5016: { // gluCheckExtension rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5017: { // gluCylinder +}; break; +case 5017: { // gluCylinder GLUquadric * quad = (GLUquadric *) * (GLuint64EXT *) bp; bp += 8; GLdouble *base = (GLdouble *) bp; bp += 8; GLdouble *top = (GLdouble *) bp; bp += 8; @@ -178,20 +178,20 @@ case 5017: { // gluCylinder GLint *slices = (GLint *) bp; bp += 4; GLint *stacks = (GLint *) bp; bp += 4; wegluCylinder(quad,*base,*top,*height,*slices,*stacks); -}; break; -case 5018: { // gluDeleteQuadric +}; break; +case 5018: { // gluDeleteQuadric GLUquadric * quad = (GLUquadric *) * (GLuint64EXT *) bp; bp += 8; wegluDeleteQuadric(quad); -}; break; -case 5019: { // gluDisk +}; break; +case 5019: { // gluDisk GLUquadric * quad = (GLUquadric *) * (GLuint64EXT *) bp; bp += 8; GLdouble *inner = (GLdouble *) bp; bp += 8; GLdouble *outer = (GLdouble *) bp; bp += 8; GLint *slices = (GLint *) bp; bp += 4; GLint *loops = (GLint *) bp; bp += 4; wegluDisk(quad,*inner,*outer,*slices,*loops); -}; break; -case 5020: { // gluErrorString +}; break; +case 5020: { // gluErrorString GLenum *error = (GLenum *) bp; bp += 4; const GLubyte * result = wegluErrorString(*error); int AP = 0; ErlDrvTermData rt[7]; @@ -200,8 +200,8 @@ case 5020: { // gluErrorString rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5021: { // gluGetString +}; break; +case 5021: { // gluGetString GLenum *name = (GLenum *) bp; bp += 4; const GLubyte * result = wegluGetString(*name); int AP = 0; ErlDrvTermData rt[7]; @@ -210,8 +210,8 @@ case 5021: { // gluGetString rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5022: { // gluLookAt +}; break; +case 5022: { // gluLookAt GLdouble *eyeX = (GLdouble *) bp; bp += 8; GLdouble *eyeY = (GLdouble *) bp; bp += 8; GLdouble *eyeZ = (GLdouble *) bp; bp += 8; @@ -222,8 +222,8 @@ case 5022: { // gluLookAt GLdouble *upY = (GLdouble *) bp; bp += 8; GLdouble *upZ = (GLdouble *) bp; bp += 8; wegluLookAt(*eyeX,*eyeY,*eyeZ,*centerX,*centerY,*centerZ,*upX,*upY,*upZ); -}; break; -case 5023: { // gluNewQuadric +}; break; +case 5023: { // gluNewQuadric GLUquadric * result = wegluNewQuadric(); int AP = 0; ErlDrvTermData rt[6]; rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); @@ -231,15 +231,15 @@ case 5023: { // gluNewQuadric rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5024: { // gluOrtho2D +}; break; +case 5024: { // gluOrtho2D GLdouble *left = (GLdouble *) bp; bp += 8; GLdouble *right = (GLdouble *) bp; bp += 8; GLdouble *bottom = (GLdouble *) bp; bp += 8; GLdouble *top = (GLdouble *) bp; bp += 8; wegluOrtho2D(*left,*right,*bottom,*top); -}; break; -case 5025: { // gluPartialDisk +}; break; +case 5025: { // gluPartialDisk GLUquadric * quad = (GLUquadric *) * (GLuint64EXT *) bp; bp += 8; GLdouble *inner = (GLdouble *) bp; bp += 8; GLdouble *outer = (GLdouble *) bp; bp += 8; @@ -248,23 +248,23 @@ case 5025: { // gluPartialDisk GLdouble *start = (GLdouble *) bp; bp += 8; GLdouble *sweep = (GLdouble *) bp; bp += 8; wegluPartialDisk(quad,*inner,*outer,*slices,*loops,*start,*sweep); -}; break; -case 5026: { // gluPerspective +}; break; +case 5026: { // gluPerspective GLdouble *fovy = (GLdouble *) bp; bp += 8; GLdouble *aspect = (GLdouble *) bp; bp += 8; GLdouble *zNear = (GLdouble *) bp; bp += 8; GLdouble *zFar = (GLdouble *) bp; bp += 8; wegluPerspective(*fovy,*aspect,*zNear,*zFar); -}; break; -case 5027: { // gluPickMatrix +}; break; +case 5027: { // gluPickMatrix GLdouble *x = (GLdouble *) bp; bp += 8; GLdouble *y = (GLdouble *) bp; bp += 8; GLdouble *delX = (GLdouble *) bp; bp += 8; GLdouble *delY = (GLdouble *) bp; bp += 8; GLint * viewport = (GLint *) bp; bp += 16; wegluPickMatrix(*x,*y,*delX,*delY,viewport); -}; break; -case 5028: { // gluProject +}; break; +case 5028: { // gluProject GLdouble *objX = (GLdouble *) bp; bp += 8; GLdouble *objY = (GLdouble *) bp; bp += 8; GLdouble *objZ = (GLdouble *) bp; bp += 8; @@ -285,28 +285,28 @@ case 5028: { // gluProject rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5029: { // gluQuadricDrawStyle +}; break; +case 5029: { // gluQuadricDrawStyle GLUquadric * quad = (GLUquadric *) * (GLuint64EXT *) bp; bp += 8; GLenum *draw = (GLenum *) bp; bp += 4; wegluQuadricDrawStyle(quad,*draw); -}; break; -case 5030: { // gluQuadricNormals +}; break; +case 5030: { // gluQuadricNormals GLUquadric * quad = (GLUquadric *) * (GLuint64EXT *) bp; bp += 8; GLenum *normal = (GLenum *) bp; bp += 4; wegluQuadricNormals(quad,*normal); -}; break; -case 5031: { // gluQuadricOrientation +}; break; +case 5031: { // gluQuadricOrientation GLUquadric * quad = (GLUquadric *) * (GLuint64EXT *) bp; bp += 8; GLenum *orientation = (GLenum *) bp; bp += 4; wegluQuadricOrientation(quad,*orientation); -}; break; -case 5032: { // gluQuadricTexture +}; break; +case 5032: { // gluQuadricTexture GLUquadric * quad = (GLUquadric *) * (GLuint64EXT *) bp; bp += 8; GLboolean *texture = (GLboolean *) bp; bp += 1; wegluQuadricTexture(quad,*texture); -}; break; -case 5033: { // gluScaleImage +}; break; +case 5033: { // gluScaleImage GLenum *format = (GLenum *) bp; bp += 4; GLsizei *wIn = (GLsizei *) bp; bp += 4; GLsizei *hIn = (GLsizei *) bp; bp += 4; @@ -323,15 +323,15 @@ case 5033: { // gluScaleImage rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5034: { // gluSphere +}; break; +case 5034: { // gluSphere GLUquadric * quad = (GLUquadric *) * (GLuint64EXT *) bp; bp += 8; GLdouble *radius = (GLdouble *) bp; bp += 8; GLint *slices = (GLint *) bp; bp += 4; GLint *stacks = (GLint *) bp; bp += 4; wegluSphere(quad,*radius,*slices,*stacks); -}; break; -case 5035: { // gluUnProject +}; break; +case 5035: { // gluUnProject GLdouble *winX = (GLdouble *) bp; bp += 8; GLdouble *winY = (GLdouble *) bp; bp += 8; GLdouble *winZ = (GLdouble *) bp; bp += 8; @@ -352,8 +352,8 @@ case 5035: { // gluUnProject rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5036: { // gluUnProject4 +}; break; +case 5036: { // gluUnProject4 GLdouble *winX = (GLdouble *) bp; bp += 8; GLdouble *winY = (GLdouble *) bp; bp += 8; GLdouble *winZ = (GLdouble *) bp; bp += 8; @@ -379,18 +379,18 @@ case 5036: { // gluUnProject4 rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 16 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,16); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5037: { // glAccum +}; break; +case 5037: { // glAccum GLenum *op = (GLenum *) bp; bp += 4; GLfloat *value = (GLfloat *) bp; bp += 4; weglAccum(*op,*value); -}; break; -case 5038: { // glAlphaFunc +}; break; +case 5038: { // glAlphaFunc GLenum *func = (GLenum *) bp; bp += 4; GLclampf *ref = (GLclampf *) bp; bp += 4; weglAlphaFunc(*func,*ref); -}; break; -case 5039: { // glAreTexturesResident +}; break; +case 5039: { // glAreTexturesResident int * texturesLen = (int *) bp; bp += 4; GLuint * textures = (GLuint *) bp; bp += (8-((*texturesLen*4+4)%8))%8; GLboolean *residences; @@ -407,23 +407,23 @@ case 5039: { // glAreTexturesResident rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 11 + (*texturesLen)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,11 + (*texturesLen)*2); driver_send_term(WXE_DRV_PORT,caller,rt,AP); - driver_free(rt); + driver_free(rt); driver_free(residences); -}; break; -case 5040: { // glArrayElement +}; break; +case 5040: { // glArrayElement GLint *i = (GLint *) bp; bp += 4; weglArrayElement(*i); -}; break; -case 5041: { // glBegin +}; break; +case 5041: { // glBegin GLenum *mode = (GLenum *) bp; bp += 4; weglBegin(*mode); -}; break; -case 5042: { // glBindTexture +}; break; +case 5042: { // glBindTexture GLenum *target = (GLenum *) bp; bp += 4; GLuint *texture = (GLuint *) bp; bp += 4; weglBindTexture(*target,*texture); -}; break; -case 5043: { // glBitmap +}; break; +case 5043: { // glBitmap GLsizei *width = (GLsizei *) bp; bp += 4; GLsizei *height = (GLsizei *) bp; bp += 4; GLfloat *xorig = (GLfloat *) bp; bp += 4; @@ -432,8 +432,8 @@ case 5043: { // glBitmap GLfloat *ymove = (GLfloat *) bp; bp += 4; GLubyte *bitmap = (GLubyte *) * (int *) bp; bp += 4; weglBitmap(*width,*height,*xorig,*yorig,*xmove,*ymove,bitmap); -}; break; -case 5044: { // glBitmap +}; break; +case 5044: { // glBitmap GLsizei *width = (GLsizei *) bp; bp += 4; GLsizei *height = (GLsizei *) bp; bp += 4; GLfloat *xorig = (GLfloat *) bp; bp += 4; @@ -442,156 +442,156 @@ case 5044: { // glBitmap GLfloat *ymove = (GLfloat *) bp; bp += 4; GLubyte *bitmap = (GLubyte *) bins[0]->base; weglBitmap(*width,*height,*xorig,*yorig,*xmove,*ymove,bitmap); -}; break; -case 5045: { // glBlendFunc +}; break; +case 5045: { // glBlendFunc GLenum *sfactor = (GLenum *) bp; bp += 4; GLenum *dfactor = (GLenum *) bp; bp += 4; weglBlendFunc(*sfactor,*dfactor); -}; break; -case 5046: { // glCallList +}; break; +case 5046: { // glCallList GLuint *list = (GLuint *) bp; bp += 4; weglCallList(*list); -}; break; -case 5047: { // glCallLists +}; break; +case 5047: { // glCallLists int * listsLen = (int *) bp; bp += 4; GLuint * lists = (GLuint *) bp; bp += (8-((*listsLen*4+4)%8))%8; weglCallLists(*listsLen,GL_UNSIGNED_INT,lists); -}; break; -case 5048: { // glClear +}; break; +case 5048: { // glClear GLbitfield *mask = (GLbitfield *) bp; bp += 4; weglClear(*mask); -}; break; -case 5049: { // glClearAccum +}; break; +case 5049: { // glClearAccum GLfloat *red = (GLfloat *) bp; bp += 4; GLfloat *green = (GLfloat *) bp; bp += 4; GLfloat *blue = (GLfloat *) bp; bp += 4; GLfloat *alpha = (GLfloat *) bp; bp += 4; weglClearAccum(*red,*green,*blue,*alpha); -}; break; -case 5050: { // glClearColor +}; break; +case 5050: { // glClearColor GLclampf *red = (GLclampf *) bp; bp += 4; GLclampf *green = (GLclampf *) bp; bp += 4; GLclampf *blue = (GLclampf *) bp; bp += 4; GLclampf *alpha = (GLclampf *) bp; bp += 4; weglClearColor(*red,*green,*blue,*alpha); -}; break; -case 5051: { // glClearDepth +}; break; +case 5051: { // glClearDepth GLclampd *depth = (GLclampd *) bp; bp += 8; weglClearDepth(*depth); -}; break; -case 5052: { // glClearIndex +}; break; +case 5052: { // glClearIndex GLfloat *c = (GLfloat *) bp; bp += 4; weglClearIndex(*c); -}; break; -case 5053: { // glClearStencil +}; break; +case 5053: { // glClearStencil GLint *s = (GLint *) bp; bp += 4; weglClearStencil(*s); -}; break; -case 5054: { // glClipPlane +}; break; +case 5054: { // glClipPlane GLenum *plane = (GLenum *) bp; bp += 4; bp += 4; GLdouble * equation = (GLdouble *) bp; bp += 32; weglClipPlane(*plane,equation); -}; break; -case 5055: { // glColor3bv +}; break; +case 5055: { // glColor3bv GLbyte *v = (GLbyte *) bp; bp += 1; weglColor3bv(v); -}; break; -case 5056: { // glColor3dv +}; break; +case 5056: { // glColor3dv GLdouble *v = (GLdouble *) bp; bp += 8; weglColor3dv(v); -}; break; -case 5057: { // glColor3fv +}; break; +case 5057: { // glColor3fv GLfloat *v = (GLfloat *) bp; bp += 4; weglColor3fv(v); -}; break; -case 5058: { // glColor3iv +}; break; +case 5058: { // glColor3iv GLint *v = (GLint *) bp; bp += 4; weglColor3iv(v); -}; break; -case 5059: { // glColor3sv +}; break; +case 5059: { // glColor3sv GLshort *v = (GLshort *) bp; bp += 2; weglColor3sv(v); -}; break; -case 5060: { // glColor3ubv +}; break; +case 5060: { // glColor3ubv GLubyte *v = (GLubyte *) bp; bp += 1; weglColor3ubv(v); -}; break; -case 5061: { // glColor3uiv +}; break; +case 5061: { // glColor3uiv GLuint *v = (GLuint *) bp; bp += 4; weglColor3uiv(v); -}; break; -case 5062: { // glColor3usv +}; break; +case 5062: { // glColor3usv GLushort *v = (GLushort *) bp; bp += 2; weglColor3usv(v); -}; break; -case 5063: { // glColor4bv +}; break; +case 5063: { // glColor4bv GLbyte *v = (GLbyte *) bp; bp += 1; weglColor4bv(v); -}; break; -case 5064: { // glColor4dv +}; break; +case 5064: { // glColor4dv GLdouble *v = (GLdouble *) bp; bp += 8; weglColor4dv(v); -}; break; -case 5065: { // glColor4fv +}; break; +case 5065: { // glColor4fv GLfloat *v = (GLfloat *) bp; bp += 4; weglColor4fv(v); -}; break; -case 5066: { // glColor4iv +}; break; +case 5066: { // glColor4iv GLint *v = (GLint *) bp; bp += 4; weglColor4iv(v); -}; break; -case 5067: { // glColor4sv +}; break; +case 5067: { // glColor4sv GLshort *v = (GLshort *) bp; bp += 2; weglColor4sv(v); -}; break; -case 5068: { // glColor4ubv +}; break; +case 5068: { // glColor4ubv GLubyte *v = (GLubyte *) bp; bp += 1; weglColor4ubv(v); -}; break; -case 5069: { // glColor4uiv +}; break; +case 5069: { // glColor4uiv GLuint *v = (GLuint *) bp; bp += 4; weglColor4uiv(v); -}; break; -case 5070: { // glColor4usv +}; break; +case 5070: { // glColor4usv GLushort *v = (GLushort *) bp; bp += 2; weglColor4usv(v); -}; break; -case 5071: { // glColorMask +}; break; +case 5071: { // glColorMask GLboolean *red = (GLboolean *) bp; bp += 1; GLboolean *green = (GLboolean *) bp; bp += 1; GLboolean *blue = (GLboolean *) bp; bp += 1; GLboolean *alpha = (GLboolean *) bp; bp += 1; weglColorMask(*red,*green,*blue,*alpha); -}; break; -case 5072: { // glColorMaterial +}; break; +case 5072: { // glColorMaterial GLenum *face = (GLenum *) bp; bp += 4; GLenum *mode = (GLenum *) bp; bp += 4; weglColorMaterial(*face,*mode); -}; break; -case 5073: { // glColorPointer +}; break; +case 5073: { // glColorPointer GLint *size = (GLint *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; GLvoid *pointer = (GLvoid *) * (int *) bp; bp += 4; weglColorPointer(*size,*type,*stride,pointer); -}; break; -case 5074: { // glColorPointer +}; break; +case 5074: { // glColorPointer GLint *size = (GLint *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; GLvoid *pointer = (GLvoid *) bins[0]->base; weglColorPointer(*size,*type,*stride,pointer); -}; break; -case 5075: { // glCopyPixels +}; break; +case 5075: { // glCopyPixels GLint *x = (GLint *) bp; bp += 4; GLint *y = (GLint *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; GLsizei *height = (GLsizei *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; weglCopyPixels(*x,*y,*width,*height,*type); -}; break; -case 5076: { // glCopyTexImage1D +}; break; +case 5076: { // glCopyTexImage1D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLenum *internalFormat = (GLenum *) bp; bp += 4; @@ -600,8 +600,8 @@ case 5076: { // glCopyTexImage1D GLsizei *width = (GLsizei *) bp; bp += 4; GLint *border = (GLint *) bp; bp += 4; weglCopyTexImage1D(*target,*level,*internalFormat,*x,*y,*width,*border); -}; break; -case 5077: { // glCopyTexImage2D +}; break; +case 5077: { // glCopyTexImage2D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLenum *internalFormat = (GLenum *) bp; bp += 4; @@ -611,8 +611,8 @@ case 5077: { // glCopyTexImage2D GLsizei *height = (GLsizei *) bp; bp += 4; GLint *border = (GLint *) bp; bp += 4; weglCopyTexImage2D(*target,*level,*internalFormat,*x,*y,*width,*height,*border); -}; break; -case 5078: { // glCopyTexSubImage1D +}; break; +case 5078: { // glCopyTexSubImage1D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLint *xoffset = (GLint *) bp; bp += 4; @@ -620,8 +620,8 @@ case 5078: { // glCopyTexSubImage1D GLint *y = (GLint *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; weglCopyTexSubImage1D(*target,*level,*xoffset,*x,*y,*width); -}; break; -case 5079: { // glCopyTexSubImage2D +}; break; +case 5079: { // glCopyTexSubImage2D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLint *xoffset = (GLint *) bp; bp += 4; @@ -631,150 +631,150 @@ case 5079: { // glCopyTexSubImage2D GLsizei *width = (GLsizei *) bp; bp += 4; GLsizei *height = (GLsizei *) bp; bp += 4; weglCopyTexSubImage2D(*target,*level,*xoffset,*yoffset,*x,*y,*width,*height); -}; break; -case 5080: { // glCullFace +}; break; +case 5080: { // glCullFace GLenum *mode = (GLenum *) bp; bp += 4; weglCullFace(*mode); -}; break; -case 5081: { // glDeleteLists +}; break; +case 5081: { // glDeleteLists GLuint *list = (GLuint *) bp; bp += 4; GLsizei *range = (GLsizei *) bp; bp += 4; weglDeleteLists(*list,*range); -}; break; -case 5082: { // glDeleteTextures +}; break; +case 5082: { // glDeleteTextures int * texturesLen = (int *) bp; bp += 4; GLuint * textures = (GLuint *) bp; bp += (8-((*texturesLen*4+4)%8))%8; weglDeleteTextures(*texturesLen,textures); -}; break; -case 5083: { // glDepthFunc +}; break; +case 5083: { // glDepthFunc GLenum *func = (GLenum *) bp; bp += 4; weglDepthFunc(*func); -}; break; -case 5084: { // glDepthMask +}; break; +case 5084: { // glDepthMask GLboolean *flag = (GLboolean *) bp; bp += 1; weglDepthMask(*flag); -}; break; -case 5085: { // glDepthRange +}; break; +case 5085: { // glDepthRange GLclampd *zNear = (GLclampd *) bp; bp += 8; GLclampd *zFar = (GLclampd *) bp; bp += 8; weglDepthRange(*zNear,*zFar); -}; break; -case 5086: { // glDisable +}; break; +case 5086: { // glDisable GLenum *cap = (GLenum *) bp; bp += 4; weglDisable(*cap); -}; break; -case 5087: { // glDisableClientState +}; break; +case 5087: { // glDisableClientState GLenum *array = (GLenum *) bp; bp += 4; weglDisableClientState(*array); -}; break; -case 5088: { // glDrawArrays +}; break; +case 5088: { // glDrawArrays GLenum *mode = (GLenum *) bp; bp += 4; GLint *first = (GLint *) bp; bp += 4; GLsizei *count = (GLsizei *) bp; bp += 4; weglDrawArrays(*mode,*first,*count); -}; break; -case 5089: { // glDrawBuffer +}; break; +case 5089: { // glDrawBuffer GLenum *mode = (GLenum *) bp; bp += 4; weglDrawBuffer(*mode); -}; break; -case 5090: { // glDrawElements +}; break; +case 5090: { // glDrawElements GLenum *mode = (GLenum *) bp; bp += 4; GLsizei *count = (GLsizei *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; GLvoid *indices = (GLvoid *) * (int *) bp; bp += 4; weglDrawElements(*mode,*count,*type,indices); -}; break; -case 5091: { // glDrawElements +}; break; +case 5091: { // glDrawElements GLenum *mode = (GLenum *) bp; bp += 4; GLsizei *count = (GLsizei *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; GLvoid *indices = (GLvoid *) bins[0]->base; weglDrawElements(*mode,*count,*type,indices); -}; break; -case 5092: { // glDrawPixels +}; break; +case 5092: { // glDrawPixels GLsizei *width = (GLsizei *) bp; bp += 4; GLsizei *height = (GLsizei *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; GLvoid *pixels = (GLvoid *) * (int *) bp; bp += 4; weglDrawPixels(*width,*height,*format,*type,pixels); -}; break; -case 5093: { // glDrawPixels +}; break; +case 5093: { // glDrawPixels GLsizei *width = (GLsizei *) bp; bp += 4; GLsizei *height = (GLsizei *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; GLvoid *pixels = (GLvoid *) bins[0]->base; weglDrawPixels(*width,*height,*format,*type,pixels); -}; break; -case 5094: { // glEdgeFlagv +}; break; +case 5094: { // glEdgeFlagv GLboolean *flag = (GLboolean *) bp; bp += 1; weglEdgeFlagv(flag); -}; break; -case 5095: { // glEdgeFlagPointer +}; break; +case 5095: { // glEdgeFlagPointer GLsizei *stride = (GLsizei *) bp; bp += 4; GLvoid *pointer = (GLvoid *) * (int *) bp; bp += 4; weglEdgeFlagPointer(*stride,pointer); -}; break; -case 5096: { // glEdgeFlagPointer +}; break; +case 5096: { // glEdgeFlagPointer GLsizei *stride = (GLsizei *) bp; bp += 4; GLvoid *pointer = (GLvoid *) bins[0]->base; weglEdgeFlagPointer(*stride,pointer); -}; break; -case 5097: { // glEnable +}; break; +case 5097: { // glEnable GLenum *cap = (GLenum *) bp; bp += 4; weglEnable(*cap); -}; break; -case 5098: { // glEnableClientState +}; break; +case 5098: { // glEnableClientState GLenum *array = (GLenum *) bp; bp += 4; weglEnableClientState(*array); -}; break; -case 5099: { // glEnd +}; break; +case 5099: { // glEnd weglEnd(); -}; break; -case 5100: { // glEndList +}; break; +case 5100: { // glEndList weglEndList(); -}; break; -case 5101: { // glEvalCoord1dv +}; break; +case 5101: { // glEvalCoord1dv GLdouble *u = (GLdouble *) bp; bp += 8; weglEvalCoord1dv(u); -}; break; -case 5102: { // glEvalCoord1fv +}; break; +case 5102: { // glEvalCoord1fv GLfloat *u = (GLfloat *) bp; bp += 4; weglEvalCoord1fv(u); -}; break; -case 5103: { // glEvalCoord2dv +}; break; +case 5103: { // glEvalCoord2dv GLdouble *u = (GLdouble *) bp; bp += 8; weglEvalCoord2dv(u); -}; break; -case 5104: { // glEvalCoord2fv +}; break; +case 5104: { // glEvalCoord2fv GLfloat *u = (GLfloat *) bp; bp += 4; weglEvalCoord2fv(u); -}; break; -case 5105: { // glEvalMesh1 +}; break; +case 5105: { // glEvalMesh1 GLenum *mode = (GLenum *) bp; bp += 4; GLint *i1 = (GLint *) bp; bp += 4; GLint *i2 = (GLint *) bp; bp += 4; weglEvalMesh1(*mode,*i1,*i2); -}; break; -case 5106: { // glEvalMesh2 +}; break; +case 5106: { // glEvalMesh2 GLenum *mode = (GLenum *) bp; bp += 4; GLint *i1 = (GLint *) bp; bp += 4; GLint *i2 = (GLint *) bp; bp += 4; GLint *j1 = (GLint *) bp; bp += 4; GLint *j2 = (GLint *) bp; bp += 4; weglEvalMesh2(*mode,*i1,*i2,*j1,*j2); -}; break; -case 5107: { // glEvalPoint1 +}; break; +case 5107: { // glEvalPoint1 GLint *i = (GLint *) bp; bp += 4; weglEvalPoint1(*i); -}; break; -case 5108: { // glEvalPoint2 +}; break; +case 5108: { // glEvalPoint2 GLint *i = (GLint *) bp; bp += 4; GLint *j = (GLint *) bp; bp += 4; weglEvalPoint2(*i,*j); -}; break; -case 5109: { // glFeedbackBuffer +}; break; +case 5109: { // glFeedbackBuffer GLsizei *size = (GLsizei *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; GLfloat *buffer = (GLfloat *) bins[0]->base; @@ -784,40 +784,40 @@ case 5109: { // glFeedbackBuffer rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5110: { // glFinish +}; break; +case 5110: { // glFinish weglFinish(); -}; break; -case 5111: { // glFlush +}; break; +case 5111: { // glFlush weglFlush(); -}; break; -case 5112: { // glFogf +}; break; +case 5112: { // glFogf GLenum *pname = (GLenum *) bp; bp += 4; GLfloat *param = (GLfloat *) bp; bp += 4; weglFogf(*pname,*param); -}; break; -case 5113: { // glFogfv +}; break; +case 5113: { // glFogfv GLenum *pname = (GLenum *) bp; bp += 4; int *paramsLen = (int *) bp; bp += 4; GLfloat *params = (GLfloat *) bp; bp += *paramsLen*4+((*paramsLen)+0)%2*4; weglFogfv(*pname,params); -}; break; -case 5114: { // glFogi +}; break; +case 5114: { // glFogi GLenum *pname = (GLenum *) bp; bp += 4; GLint *param = (GLint *) bp; bp += 4; weglFogi(*pname,*param); -}; break; -case 5115: { // glFogiv +}; break; +case 5115: { // glFogiv GLenum *pname = (GLenum *) bp; bp += 4; int *paramsLen = (int *) bp; bp += 4; GLint *params = (GLint *) bp; bp += *paramsLen*4+((*paramsLen)+0)%2*4; weglFogiv(*pname,params); -}; break; -case 5116: { // glFrontFace +}; break; +case 5116: { // glFrontFace GLenum *mode = (GLenum *) bp; bp += 4; weglFrontFace(*mode); -}; break; -case 5117: { // glFrustum +}; break; +case 5117: { // glFrustum GLdouble *left = (GLdouble *) bp; bp += 8; GLdouble *right = (GLdouble *) bp; bp += 8; GLdouble *bottom = (GLdouble *) bp; bp += 8; @@ -825,8 +825,8 @@ case 5117: { // glFrustum GLdouble *zNear = (GLdouble *) bp; bp += 8; GLdouble *zFar = (GLdouble *) bp; bp += 8; weglFrustum(*left,*right,*bottom,*top,*zNear,*zFar); -}; break; -case 5118: { // glGenLists +}; break; +case 5118: { // glGenLists GLsizei *range = (GLsizei *) bp; bp += 4; GLuint result = weglGenLists(*range); int AP = 0; ErlDrvTermData rt[6]; @@ -835,8 +835,8 @@ case 5118: { // glGenLists rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5119: { // glGenTextures +}; break; +case 5119: { // glGenTextures GLsizei *n = (GLsizei *) bp; bp += 4; GLuint *textures; textures = (GLuint *) driver_alloc(sizeof(GLuint) * *n); @@ -850,10 +850,10 @@ case 5119: { // glGenTextures rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 7 + (*n)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*n)*2); driver_send_term(WXE_DRV_PORT,caller,rt,AP); - driver_free(rt); + driver_free(rt); driver_free(textures); -}; break; -case 5120: { // glGetBooleanv +}; break; +case 5120: { // glGetBooleanv GLenum *pname = (GLenum *) bp; bp += 4; GLboolean params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; weglGetBooleanv(*pname,params); @@ -880,8 +880,8 @@ case 5120: { // glGetBooleanv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 39 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,39); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5121: { // glGetClipPlane +}; break; +case 5121: { // glGetClipPlane GLenum *plane = (GLenum *) bp; bp += 4; GLdouble equation[4] = {0.0,0.0,0.0,0.0}; weglGetClipPlane(*plane,equation); @@ -896,8 +896,8 @@ case 5121: { // glGetClipPlane rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5122: { // glGetDoublev +}; break; +case 5122: { // glGetDoublev GLenum *pname = (GLenum *) bp; bp += 4; GLdouble params[16] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; weglGetDoublev(*pname,params); @@ -924,8 +924,8 @@ case 5122: { // glGetDoublev rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 39 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,39); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5123: { // glGetError +}; break; +case 5123: { // glGetError GLenum result = weglGetError(); int AP = 0; ErlDrvTermData rt[6]; rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); @@ -933,8 +933,8 @@ case 5123: { // glGetError rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5124: { // glGetFloatv +}; break; +case 5124: { // glGetFloatv GLenum *pname = (GLenum *) bp; bp += 4; GLfloat params[16] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; weglGetFloatv(*pname,params); @@ -962,8 +962,8 @@ case 5124: { // glGetFloatv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 39 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,39); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5125: { // glGetIntegerv +}; break; +case 5125: { // glGetIntegerv GLenum *pname = (GLenum *) bp; bp += 4; GLint params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; weglGetIntegerv(*pname,params); @@ -990,8 +990,8 @@ case 5125: { // glGetIntegerv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 39 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,39); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5126: { // glGetLightfv +}; break; +case 5126: { // glGetLightfv GLenum *light = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLfloat params[4] = {0.0,0.0,0.0,0.0}; @@ -1008,8 +1008,8 @@ case 5126: { // glGetLightfv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5127: { // glGetLightiv +}; break; +case 5127: { // glGetLightiv GLenum *light = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint params[4] = {0,0,0,0}; @@ -1025,8 +1025,8 @@ case 5127: { // glGetLightiv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5128: { // glGetMapdv +}; break; +case 5128: { // glGetMapdv GLenum *target = (GLenum *) bp; bp += 4; GLenum *query = (GLenum *) bp; bp += 4; GLdouble *v = (GLdouble *) bins[0]->base; @@ -1036,8 +1036,8 @@ case 5128: { // glGetMapdv rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5129: { // glGetMapfv +}; break; +case 5129: { // glGetMapfv GLenum *target = (GLenum *) bp; bp += 4; GLenum *query = (GLenum *) bp; bp += 4; GLfloat *v = (GLfloat *) bins[0]->base; @@ -1047,8 +1047,8 @@ case 5129: { // glGetMapfv rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5130: { // glGetMapiv +}; break; +case 5130: { // glGetMapiv GLenum *target = (GLenum *) bp; bp += 4; GLenum *query = (GLenum *) bp; bp += 4; GLint *v = (GLint *) bins[0]->base; @@ -1058,8 +1058,8 @@ case 5130: { // glGetMapiv rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5131: { // glGetMaterialfv +}; break; +case 5131: { // glGetMaterialfv GLenum *face = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLfloat params[4] = {0.0,0.0,0.0,0.0}; @@ -1076,8 +1076,8 @@ case 5131: { // glGetMaterialfv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5132: { // glGetMaterialiv +}; break; +case 5132: { // glGetMaterialiv GLenum *face = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint params[4] = {0,0,0,0}; @@ -1093,8 +1093,8 @@ case 5132: { // glGetMaterialiv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5133: { // glGetPixelMapfv +}; break; +case 5133: { // glGetPixelMapfv GLenum *map = (GLenum *) bp; bp += 4; GLfloat *values = (GLfloat *) bins[0]->base; weglGetPixelMapfv(*map,values); @@ -1103,8 +1103,8 @@ case 5133: { // glGetPixelMapfv rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5134: { // glGetPixelMapuiv +}; break; +case 5134: { // glGetPixelMapuiv GLenum *map = (GLenum *) bp; bp += 4; GLuint *values = (GLuint *) bins[0]->base; weglGetPixelMapuiv(*map,values); @@ -1113,8 +1113,8 @@ case 5134: { // glGetPixelMapuiv rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5135: { // glGetPixelMapusv +}; break; +case 5135: { // glGetPixelMapusv GLenum *map = (GLenum *) bp; bp += 4; GLushort *values = (GLushort *) bins[0]->base; weglGetPixelMapusv(*map,values); @@ -1123,8 +1123,8 @@ case 5135: { // glGetPixelMapusv rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5136: { // glGetPolygonStipple +}; break; +case 5136: { // glGetPolygonStipple GLubyte mask[128]; weglGetPolygonStipple(mask); int AP = 0; ErlDrvTermData rt[8]; @@ -1136,8 +1136,8 @@ case 5136: { // glGetPolygonStipple if (AP != 8 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,8); driver_send_term(WXE_DRV_PORT,caller,rt,AP); driver_free_binary(BinCopy); -}; break; -case 5137: { // glGetString +}; break; +case 5137: { // glGetString GLenum *name = (GLenum *) bp; bp += 4; const GLubyte * result = weglGetString(*name); int AP = 0; ErlDrvTermData rt[7]; @@ -1146,8 +1146,8 @@ case 5137: { // glGetString rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5138: { // glGetTexEnvfv +}; break; +case 5138: { // glGetTexEnvfv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLfloat params[4] = {0.0,0.0,0.0,0.0}; @@ -1164,8 +1164,8 @@ case 5138: { // glGetTexEnvfv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5139: { // glGetTexEnviv +}; break; +case 5139: { // glGetTexEnviv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint params[4] = {0,0,0,0}; @@ -1181,8 +1181,8 @@ case 5139: { // glGetTexEnviv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5140: { // glGetTexGendv +}; break; +case 5140: { // glGetTexGendv GLenum *coord = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLdouble params[4] = {0.0,0.0,0.0,0.0}; @@ -1198,8 +1198,8 @@ case 5140: { // glGetTexGendv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5141: { // glGetTexGenfv +}; break; +case 5141: { // glGetTexGenfv GLenum *coord = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLfloat params[4] = {0.0,0.0,0.0,0.0}; @@ -1216,8 +1216,8 @@ case 5141: { // glGetTexGenfv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5142: { // glGetTexGeniv +}; break; +case 5142: { // glGetTexGeniv GLenum *coord = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint params[4] = {0,0,0,0}; @@ -1233,8 +1233,8 @@ case 5142: { // glGetTexGeniv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5143: { // glGetTexImage +}; break; +case 5143: { // glGetTexImage GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; @@ -1246,8 +1246,8 @@ case 5143: { // glGetTexImage rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5144: { // glGetTexLevelParameterfv +}; break; +case 5144: { // glGetTexLevelParameterfv GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; @@ -1262,8 +1262,8 @@ case 5144: { // glGetTexLevelParameterfv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 8 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,8); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5145: { // glGetTexLevelParameteriv +}; break; +case 5145: { // glGetTexLevelParameteriv GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; @@ -1277,8 +1277,8 @@ case 5145: { // glGetTexLevelParameteriv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 8 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,8); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5146: { // glGetTexParameterfv +}; break; +case 5146: { // glGetTexParameterfv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLfloat params[4] = {0.0,0.0,0.0,0.0}; @@ -1295,8 +1295,8 @@ case 5146: { // glGetTexParameterfv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5147: { // glGetTexParameteriv +}; break; +case 5147: { // glGetTexParameteriv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint params[4] = {0,0,0,0}; @@ -1312,64 +1312,64 @@ case 5147: { // glGetTexParameteriv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5148: { // glHint +}; break; +case 5148: { // glHint GLenum *target = (GLenum *) bp; bp += 4; GLenum *mode = (GLenum *) bp; bp += 4; weglHint(*target,*mode); -}; break; -case 5149: { // glIndexMask +}; break; +case 5149: { // glIndexMask GLuint *mask = (GLuint *) bp; bp += 4; weglIndexMask(*mask); -}; break; -case 5150: { // glIndexPointer +}; break; +case 5150: { // glIndexPointer GLenum *type = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; GLvoid *pointer = (GLvoid *) * (int *) bp; bp += 4; weglIndexPointer(*type,*stride,pointer); -}; break; -case 5151: { // glIndexPointer +}; break; +case 5151: { // glIndexPointer GLenum *type = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; GLvoid *pointer = (GLvoid *) bins[0]->base; weglIndexPointer(*type,*stride,pointer); -}; break; -case 5152: { // glIndexdv +}; break; +case 5152: { // glIndexdv GLdouble *c = (GLdouble *) bp; bp += 8; weglIndexdv(c); -}; break; -case 5153: { // glIndexfv +}; break; +case 5153: { // glIndexfv GLfloat *c = (GLfloat *) bp; bp += 4; weglIndexfv(c); -}; break; -case 5154: { // glIndexiv +}; break; +case 5154: { // glIndexiv GLint *c = (GLint *) bp; bp += 4; weglIndexiv(c); -}; break; -case 5155: { // glIndexsv +}; break; +case 5155: { // glIndexsv GLshort *c = (GLshort *) bp; bp += 2; weglIndexsv(c); -}; break; -case 5156: { // glIndexubv +}; break; +case 5156: { // glIndexubv GLubyte *c = (GLubyte *) bp; bp += 1; weglIndexubv(c); -}; break; -case 5157: { // glInitNames +}; break; +case 5157: { // glInitNames weglInitNames(); -}; break; -case 5158: { // glInterleavedArrays +}; break; +case 5158: { // glInterleavedArrays GLenum *format = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; GLvoid *pointer = (GLvoid *) * (int *) bp; bp += 4; weglInterleavedArrays(*format,*stride,pointer); -}; break; -case 5159: { // glInterleavedArrays +}; break; +case 5159: { // glInterleavedArrays GLenum *format = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; GLvoid *pointer = (GLvoid *) bins[0]->base; weglInterleavedArrays(*format,*stride,pointer); -}; break; -case 5160: { // glIsEnabled +}; break; +case 5160: { // glIsEnabled GLenum *cap = (GLenum *) bp; bp += 4; GLboolean result = weglIsEnabled(*cap); int AP = 0; ErlDrvTermData rt[6]; @@ -1378,8 +1378,8 @@ case 5160: { // glIsEnabled rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5161: { // glIsList +}; break; +case 5161: { // glIsList GLuint *list = (GLuint *) bp; bp += 4; GLboolean result = weglIsList(*list); int AP = 0; ErlDrvTermData rt[6]; @@ -1388,8 +1388,8 @@ case 5161: { // glIsList rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5162: { // glIsTexture +}; break; +case 5162: { // glIsTexture GLuint *texture = (GLuint *) bp; bp += 4; GLboolean result = weglIsTexture(*texture); int AP = 0; ErlDrvTermData rt[6]; @@ -1398,88 +1398,88 @@ case 5162: { // glIsTexture rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5163: { // glLightModelf +}; break; +case 5163: { // glLightModelf GLenum *pname = (GLenum *) bp; bp += 4; GLfloat *param = (GLfloat *) bp; bp += 4; weglLightModelf(*pname,*param); -}; break; -case 5164: { // glLightModelfv +}; break; +case 5164: { // glLightModelfv GLenum *pname = (GLenum *) bp; bp += 4; int *paramsLen = (int *) bp; bp += 4; GLfloat *params = (GLfloat *) bp; bp += *paramsLen*4+((*paramsLen)+0)%2*4; weglLightModelfv(*pname,params); -}; break; -case 5165: { // glLightModeli +}; break; +case 5165: { // glLightModeli GLenum *pname = (GLenum *) bp; bp += 4; GLint *param = (GLint *) bp; bp += 4; weglLightModeli(*pname,*param); -}; break; -case 5166: { // glLightModeliv +}; break; +case 5166: { // glLightModeliv GLenum *pname = (GLenum *) bp; bp += 4; int *paramsLen = (int *) bp; bp += 4; GLint *params = (GLint *) bp; bp += *paramsLen*4+((*paramsLen)+0)%2*4; weglLightModeliv(*pname,params); -}; break; -case 5167: { // glLightf +}; break; +case 5167: { // glLightf GLenum *light = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLfloat *param = (GLfloat *) bp; bp += 4; weglLightf(*light,*pname,*param); -}; break; -case 5168: { // glLightfv +}; break; +case 5168: { // glLightfv GLenum *light = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; int *paramsLen = (int *) bp; bp += 4; GLfloat *params = (GLfloat *) bp; bp += *paramsLen*4+((*paramsLen)+1)%2*4; weglLightfv(*light,*pname,params); -}; break; -case 5169: { // glLighti +}; break; +case 5169: { // glLighti GLenum *light = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint *param = (GLint *) bp; bp += 4; weglLighti(*light,*pname,*param); -}; break; -case 5170: { // glLightiv +}; break; +case 5170: { // glLightiv GLenum *light = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; int *paramsLen = (int *) bp; bp += 4; GLint *params = (GLint *) bp; bp += *paramsLen*4+((*paramsLen)+1)%2*4; weglLightiv(*light,*pname,params); -}; break; -case 5171: { // glLineStipple +}; break; +case 5171: { // glLineStipple GLint *factor = (GLint *) bp; bp += 4; GLushort *pattern = (GLushort *) bp; bp += 2; weglLineStipple(*factor,*pattern); -}; break; -case 5172: { // glLineWidth +}; break; +case 5172: { // glLineWidth GLfloat *width = (GLfloat *) bp; bp += 4; weglLineWidth(*width); -}; break; -case 5173: { // glListBase +}; break; +case 5173: { // glListBase GLuint *base = (GLuint *) bp; bp += 4; weglListBase(*base); -}; break; -case 5174: { // glLoadIdentity +}; break; +case 5174: { // glLoadIdentity weglLoadIdentity(); -}; break; -case 5175: { // glLoadMatrixd +}; break; +case 5175: { // glLoadMatrixd GLdouble * m = (GLdouble *) bp; bp += 128; weglLoadMatrixd(m); -}; break; -case 5176: { // glLoadMatrixf +}; break; +case 5176: { // glLoadMatrixf GLfloat * m = (GLfloat *) bp; bp += 64; weglLoadMatrixf(m); -}; break; -case 5177: { // glLoadName +}; break; +case 5177: { // glLoadName GLuint *name = (GLuint *) bp; bp += 4; weglLoadName(*name); -}; break; -case 5178: { // glLogicOp +}; break; +case 5178: { // glLogicOp GLenum *opcode = (GLenum *) bp; bp += 4; weglLogicOp(*opcode); -}; break; -case 5179: { // glMap1d +}; break; +case 5179: { // glMap1d GLenum *target = (GLenum *) bp; bp += 4; bp += 4; GLdouble *u1 = (GLdouble *) bp; bp += 8; @@ -1488,8 +1488,8 @@ case 5179: { // glMap1d GLint *order = (GLint *) bp; bp += 4; GLdouble *points = (GLdouble *) bins[0]->base; weglMap1d(*target,*u1,*u2,*stride,*order,points); -}; break; -case 5180: { // glMap1f +}; break; +case 5180: { // glMap1f GLenum *target = (GLenum *) bp; bp += 4; GLfloat *u1 = (GLfloat *) bp; bp += 4; GLfloat *u2 = (GLfloat *) bp; bp += 4; @@ -1497,8 +1497,8 @@ case 5180: { // glMap1f GLint *order = (GLint *) bp; bp += 4; GLfloat *points = (GLfloat *) bins[0]->base; weglMap1f(*target,*u1,*u2,*stride,*order,points); -}; break; -case 5181: { // glMap2d +}; break; +case 5181: { // glMap2d GLenum *target = (GLenum *) bp; bp += 4; bp += 4; GLdouble *u1 = (GLdouble *) bp; bp += 8; @@ -1511,8 +1511,8 @@ case 5181: { // glMap2d GLint *vorder = (GLint *) bp; bp += 4; GLdouble *points = (GLdouble *) bins[0]->base; weglMap2d(*target,*u1,*u2,*ustride,*uorder,*v1,*v2,*vstride,*vorder,points); -}; break; -case 5182: { // glMap2f +}; break; +case 5182: { // glMap2f GLenum *target = (GLenum *) bp; bp += 4; GLfloat *u1 = (GLfloat *) bp; bp += 4; GLfloat *u2 = (GLfloat *) bp; bp += 4; @@ -1524,21 +1524,21 @@ case 5182: { // glMap2f GLint *vorder = (GLint *) bp; bp += 4; GLfloat *points = (GLfloat *) bins[0]->base; weglMap2f(*target,*u1,*u2,*ustride,*uorder,*v1,*v2,*vstride,*vorder,points); -}; break; -case 5183: { // glMapGrid1d +}; break; +case 5183: { // glMapGrid1d GLint *un = (GLint *) bp; bp += 4; bp += 4; GLdouble *u1 = (GLdouble *) bp; bp += 8; GLdouble *u2 = (GLdouble *) bp; bp += 8; weglMapGrid1d(*un,*u1,*u2); -}; break; -case 5184: { // glMapGrid1f +}; break; +case 5184: { // glMapGrid1f GLint *un = (GLint *) bp; bp += 4; GLfloat *u1 = (GLfloat *) bp; bp += 4; GLfloat *u2 = (GLfloat *) bp; bp += 4; weglMapGrid1f(*un,*u1,*u2); -}; break; -case 5185: { // glMapGrid2d +}; break; +case 5185: { // glMapGrid2d GLint *un = (GLint *) bp; bp += 4; bp += 4; GLdouble *u1 = (GLdouble *) bp; bp += 8; @@ -1548,8 +1548,8 @@ case 5185: { // glMapGrid2d GLdouble *v1 = (GLdouble *) bp; bp += 8; GLdouble *v2 = (GLdouble *) bp; bp += 8; weglMapGrid2d(*un,*u1,*u2,*vn,*v1,*v2); -}; break; -case 5186: { // glMapGrid2f +}; break; +case 5186: { // glMapGrid2f GLint *un = (GLint *) bp; bp += 4; GLfloat *u1 = (GLfloat *) bp; bp += 4; GLfloat *u2 = (GLfloat *) bp; bp += 4; @@ -1557,83 +1557,83 @@ case 5186: { // glMapGrid2f GLfloat *v1 = (GLfloat *) bp; bp += 4; GLfloat *v2 = (GLfloat *) bp; bp += 4; weglMapGrid2f(*un,*u1,*u2,*vn,*v1,*v2); -}; break; -case 5187: { // glMaterialf +}; break; +case 5187: { // glMaterialf GLenum *face = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLfloat *param = (GLfloat *) bp; bp += 4; weglMaterialf(*face,*pname,*param); -}; break; -case 5188: { // glMaterialfv +}; break; +case 5188: { // glMaterialfv GLenum *face = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; int *paramsLen = (int *) bp; bp += 4; GLfloat *params = (GLfloat *) bp; bp += *paramsLen*4+((*paramsLen)+1)%2*4; weglMaterialfv(*face,*pname,params); -}; break; -case 5189: { // glMateriali +}; break; +case 5189: { // glMateriali GLenum *face = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint *param = (GLint *) bp; bp += 4; weglMateriali(*face,*pname,*param); -}; break; -case 5190: { // glMaterialiv +}; break; +case 5190: { // glMaterialiv GLenum *face = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; int *paramsLen = (int *) bp; bp += 4; GLint *params = (GLint *) bp; bp += *paramsLen*4+((*paramsLen)+1)%2*4; weglMaterialiv(*face,*pname,params); -}; break; -case 5191: { // glMatrixMode +}; break; +case 5191: { // glMatrixMode GLenum *mode = (GLenum *) bp; bp += 4; weglMatrixMode(*mode); -}; break; -case 5192: { // glMultMatrixd +}; break; +case 5192: { // glMultMatrixd GLdouble * m = (GLdouble *) bp; bp += 128; weglMultMatrixd(m); -}; break; -case 5193: { // glMultMatrixf +}; break; +case 5193: { // glMultMatrixf GLfloat * m = (GLfloat *) bp; bp += 64; weglMultMatrixf(m); -}; break; -case 5194: { // glNewList +}; break; +case 5194: { // glNewList GLuint *list = (GLuint *) bp; bp += 4; GLenum *mode = (GLenum *) bp; bp += 4; weglNewList(*list,*mode); -}; break; -case 5195: { // glNormal3bv +}; break; +case 5195: { // glNormal3bv GLbyte *v = (GLbyte *) bp; bp += 1; weglNormal3bv(v); -}; break; -case 5196: { // glNormal3dv +}; break; +case 5196: { // glNormal3dv GLdouble *v = (GLdouble *) bp; bp += 8; weglNormal3dv(v); -}; break; -case 5197: { // glNormal3fv +}; break; +case 5197: { // glNormal3fv GLfloat *v = (GLfloat *) bp; bp += 4; weglNormal3fv(v); -}; break; -case 5198: { // glNormal3iv +}; break; +case 5198: { // glNormal3iv GLint *v = (GLint *) bp; bp += 4; weglNormal3iv(v); -}; break; -case 5199: { // glNormal3sv +}; break; +case 5199: { // glNormal3sv GLshort *v = (GLshort *) bp; bp += 2; weglNormal3sv(v); -}; break; -case 5200: { // glNormalPointer +}; break; +case 5200: { // glNormalPointer GLenum *type = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; GLvoid *pointer = (GLvoid *) * (int *) bp; bp += 4; weglNormalPointer(*type,*stride,pointer); -}; break; -case 5201: { // glNormalPointer +}; break; +case 5201: { // glNormalPointer GLenum *type = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; GLvoid *pointer = (GLvoid *) bins[0]->base; weglNormalPointer(*type,*stride,pointer); -}; break; -case 5202: { // glOrtho +}; break; +case 5202: { // glOrtho GLdouble *left = (GLdouble *) bp; bp += 8; GLdouble *right = (GLdouble *) bp; bp += 8; GLdouble *bottom = (GLdouble *) bp; bp += 8; @@ -1641,159 +1641,159 @@ case 5202: { // glOrtho GLdouble *zNear = (GLdouble *) bp; bp += 8; GLdouble *zFar = (GLdouble *) bp; bp += 8; weglOrtho(*left,*right,*bottom,*top,*zNear,*zFar); -}; break; -case 5203: { // glPassThrough +}; break; +case 5203: { // glPassThrough GLfloat *token = (GLfloat *) bp; bp += 4; weglPassThrough(*token); -}; break; -case 5204: { // glPixelMapfv +}; break; +case 5204: { // glPixelMapfv GLenum *map = (GLenum *) bp; bp += 4; GLsizei *mapsize = (GLsizei *) bp; bp += 4; GLfloat *values = (GLfloat *) bins[0]->base; weglPixelMapfv(*map,*mapsize,values); -}; break; -case 5205: { // glPixelMapuiv +}; break; +case 5205: { // glPixelMapuiv GLenum *map = (GLenum *) bp; bp += 4; GLsizei *mapsize = (GLsizei *) bp; bp += 4; GLuint *values = (GLuint *) bins[0]->base; weglPixelMapuiv(*map,*mapsize,values); -}; break; -case 5206: { // glPixelMapusv +}; break; +case 5206: { // glPixelMapusv GLenum *map = (GLenum *) bp; bp += 4; GLsizei *mapsize = (GLsizei *) bp; bp += 4; GLushort *values = (GLushort *) bins[0]->base; weglPixelMapusv(*map,*mapsize,values); -}; break; -case 5207: { // glPixelStoref +}; break; +case 5207: { // glPixelStoref GLenum *pname = (GLenum *) bp; bp += 4; GLfloat *param = (GLfloat *) bp; bp += 4; weglPixelStoref(*pname,*param); -}; break; -case 5208: { // glPixelStorei +}; break; +case 5208: { // glPixelStorei GLenum *pname = (GLenum *) bp; bp += 4; GLint *param = (GLint *) bp; bp += 4; weglPixelStorei(*pname,*param); -}; break; -case 5209: { // glPixelTransferf +}; break; +case 5209: { // glPixelTransferf GLenum *pname = (GLenum *) bp; bp += 4; GLfloat *param = (GLfloat *) bp; bp += 4; weglPixelTransferf(*pname,*param); -}; break; -case 5210: { // glPixelTransferi +}; break; +case 5210: { // glPixelTransferi GLenum *pname = (GLenum *) bp; bp += 4; GLint *param = (GLint *) bp; bp += 4; weglPixelTransferi(*pname,*param); -}; break; -case 5211: { // glPixelZoom +}; break; +case 5211: { // glPixelZoom GLfloat *xfactor = (GLfloat *) bp; bp += 4; GLfloat *yfactor = (GLfloat *) bp; bp += 4; weglPixelZoom(*xfactor,*yfactor); -}; break; -case 5212: { // glPointSize +}; break; +case 5212: { // glPointSize GLfloat *size = (GLfloat *) bp; bp += 4; weglPointSize(*size); -}; break; -case 5213: { // glPolygonMode +}; break; +case 5213: { // glPolygonMode GLenum *face = (GLenum *) bp; bp += 4; GLenum *mode = (GLenum *) bp; bp += 4; weglPolygonMode(*face,*mode); -}; break; -case 5214: { // glPolygonOffset +}; break; +case 5214: { // glPolygonOffset GLfloat *factor = (GLfloat *) bp; bp += 4; GLfloat *units = (GLfloat *) bp; bp += 4; weglPolygonOffset(*factor,*units); -}; break; -case 5215: { // glPolygonStipple +}; break; +case 5215: { // glPolygonStipple GLubyte *mask = (GLubyte *) bins[0]->base; weglPolygonStipple(mask); -}; break; -case 5216: { // glPopAttrib +}; break; +case 5216: { // glPopAttrib weglPopAttrib(); -}; break; -case 5217: { // glPopClientAttrib +}; break; +case 5217: { // glPopClientAttrib weglPopClientAttrib(); -}; break; -case 5218: { // glPopMatrix +}; break; +case 5218: { // glPopMatrix weglPopMatrix(); -}; break; -case 5219: { // glPopName +}; break; +case 5219: { // glPopName weglPopName(); -}; break; -case 5220: { // glPrioritizeTextures +}; break; +case 5220: { // glPrioritizeTextures int * texturesLen = (int *) bp; bp += 4; GLuint * textures = (GLuint *) bp; bp += (8-((*texturesLen*4+4)%8))%8; int * prioritiesLen = (int *) bp; bp += 4; GLclampf * priorities = (GLclampf *) bp; bp += (8-((*prioritiesLen*4+4)%8))%8; weglPrioritizeTextures(*texturesLen,textures,priorities); -}; break; -case 5221: { // glPushAttrib +}; break; +case 5221: { // glPushAttrib GLbitfield *mask = (GLbitfield *) bp; bp += 4; weglPushAttrib(*mask); -}; break; -case 5222: { // glPushClientAttrib +}; break; +case 5222: { // glPushClientAttrib GLbitfield *mask = (GLbitfield *) bp; bp += 4; weglPushClientAttrib(*mask); -}; break; -case 5223: { // glPushMatrix +}; break; +case 5223: { // glPushMatrix weglPushMatrix(); -}; break; -case 5224: { // glPushName +}; break; +case 5224: { // glPushName GLuint *name = (GLuint *) bp; bp += 4; weglPushName(*name); -}; break; -case 5225: { // glRasterPos2dv +}; break; +case 5225: { // glRasterPos2dv GLdouble *v = (GLdouble *) bp; bp += 8; weglRasterPos2dv(v); -}; break; -case 5226: { // glRasterPos2fv +}; break; +case 5226: { // glRasterPos2fv GLfloat *v = (GLfloat *) bp; bp += 4; weglRasterPos2fv(v); -}; break; -case 5227: { // glRasterPos2iv +}; break; +case 5227: { // glRasterPos2iv GLint *v = (GLint *) bp; bp += 4; weglRasterPos2iv(v); -}; break; -case 5228: { // glRasterPos2sv +}; break; +case 5228: { // glRasterPos2sv GLshort *v = (GLshort *) bp; bp += 2; weglRasterPos2sv(v); -}; break; -case 5229: { // glRasterPos3dv +}; break; +case 5229: { // glRasterPos3dv GLdouble *v = (GLdouble *) bp; bp += 8; weglRasterPos3dv(v); -}; break; -case 5230: { // glRasterPos3fv +}; break; +case 5230: { // glRasterPos3fv GLfloat *v = (GLfloat *) bp; bp += 4; weglRasterPos3fv(v); -}; break; -case 5231: { // glRasterPos3iv +}; break; +case 5231: { // glRasterPos3iv GLint *v = (GLint *) bp; bp += 4; weglRasterPos3iv(v); -}; break; -case 5232: { // glRasterPos3sv +}; break; +case 5232: { // glRasterPos3sv GLshort *v = (GLshort *) bp; bp += 2; weglRasterPos3sv(v); -}; break; -case 5233: { // glRasterPos4dv +}; break; +case 5233: { // glRasterPos4dv GLdouble *v = (GLdouble *) bp; bp += 8; weglRasterPos4dv(v); -}; break; -case 5234: { // glRasterPos4fv +}; break; +case 5234: { // glRasterPos4fv GLfloat *v = (GLfloat *) bp; bp += 4; weglRasterPos4fv(v); -}; break; -case 5235: { // glRasterPos4iv +}; break; +case 5235: { // glRasterPos4iv GLint *v = (GLint *) bp; bp += 4; weglRasterPos4iv(v); -}; break; -case 5236: { // glRasterPos4sv +}; break; +case 5236: { // glRasterPos4sv GLshort *v = (GLshort *) bp; bp += 2; weglRasterPos4sv(v); -}; break; -case 5237: { // glReadBuffer +}; break; +case 5237: { // glReadBuffer GLenum *mode = (GLenum *) bp; bp += 4; weglReadBuffer(*mode); -}; break; -case 5238: { // glReadPixels +}; break; +case 5238: { // glReadPixels GLint *x = (GLint *) bp; bp += 4; GLint *y = (GLint *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; @@ -1807,56 +1807,56 @@ case 5238: { // glReadPixels rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5239: { // glRectd +}; break; +case 5239: { // glRectd GLdouble *x1 = (GLdouble *) bp; bp += 8; GLdouble *y1 = (GLdouble *) bp; bp += 8; GLdouble *x2 = (GLdouble *) bp; bp += 8; GLdouble *y2 = (GLdouble *) bp; bp += 8; weglRectd(*x1,*y1,*x2,*y2); -}; break; -case 5240: { // glRectdv +}; break; +case 5240: { // glRectdv GLdouble * v1 = (GLdouble *) bp; bp += 16; GLdouble * v2 = (GLdouble *) bp; bp += 16; weglRectdv(v1,v2); -}; break; -case 5241: { // glRectf +}; break; +case 5241: { // glRectf GLfloat *x1 = (GLfloat *) bp; bp += 4; GLfloat *y1 = (GLfloat *) bp; bp += 4; GLfloat *x2 = (GLfloat *) bp; bp += 4; GLfloat *y2 = (GLfloat *) bp; bp += 4; weglRectf(*x1,*y1,*x2,*y2); -}; break; -case 5242: { // glRectfv +}; break; +case 5242: { // glRectfv GLfloat * v1 = (GLfloat *) bp; bp += 8; GLfloat * v2 = (GLfloat *) bp; bp += 8; weglRectfv(v1,v2); -}; break; -case 5243: { // glRecti +}; break; +case 5243: { // glRecti GLint *x1 = (GLint *) bp; bp += 4; GLint *y1 = (GLint *) bp; bp += 4; GLint *x2 = (GLint *) bp; bp += 4; GLint *y2 = (GLint *) bp; bp += 4; weglRecti(*x1,*y1,*x2,*y2); -}; break; -case 5244: { // glRectiv +}; break; +case 5244: { // glRectiv GLint * v1 = (GLint *) bp; bp += 8; GLint * v2 = (GLint *) bp; bp += 8; weglRectiv(v1,v2); -}; break; -case 5245: { // glRects +}; break; +case 5245: { // glRects GLshort *x1 = (GLshort *) bp; bp += 2; GLshort *y1 = (GLshort *) bp; bp += 2; GLshort *x2 = (GLshort *) bp; bp += 2; GLshort *y2 = (GLshort *) bp; bp += 2; weglRects(*x1,*y1,*x2,*y2); -}; break; -case 5246: { // glRectsv +}; break; +case 5246: { // glRectsv GLshort * v1 = (GLshort *) bp; bp += 4; GLshort * v2 = (GLshort *) bp; bp += 4; weglRectsv(v1,v2); -}; break; -case 5247: { // glRenderMode +}; break; +case 5247: { // glRenderMode GLenum *mode = (GLenum *) bp; bp += 4; GLint result = weglRenderMode(*mode); int AP = 0; ErlDrvTermData rt[6]; @@ -1865,41 +1865,41 @@ case 5247: { // glRenderMode rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5248: { // glRotated +}; break; +case 5248: { // glRotated GLdouble *angle = (GLdouble *) bp; bp += 8; GLdouble *x = (GLdouble *) bp; bp += 8; GLdouble *y = (GLdouble *) bp; bp += 8; GLdouble *z = (GLdouble *) bp; bp += 8; weglRotated(*angle,*x,*y,*z); -}; break; -case 5249: { // glRotatef +}; break; +case 5249: { // glRotatef GLfloat *angle = (GLfloat *) bp; bp += 4; GLfloat *x = (GLfloat *) bp; bp += 4; GLfloat *y = (GLfloat *) bp; bp += 4; GLfloat *z = (GLfloat *) bp; bp += 4; weglRotatef(*angle,*x,*y,*z); -}; break; -case 5250: { // glScaled +}; break; +case 5250: { // glScaled GLdouble *x = (GLdouble *) bp; bp += 8; GLdouble *y = (GLdouble *) bp; bp += 8; GLdouble *z = (GLdouble *) bp; bp += 8; weglScaled(*x,*y,*z); -}; break; -case 5251: { // glScalef +}; break; +case 5251: { // glScalef GLfloat *x = (GLfloat *) bp; bp += 4; GLfloat *y = (GLfloat *) bp; bp += 4; GLfloat *z = (GLfloat *) bp; bp += 4; weglScalef(*x,*y,*z); -}; break; -case 5252: { // glScissor +}; break; +case 5252: { // glScissor GLint *x = (GLint *) bp; bp += 4; GLint *y = (GLint *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; GLsizei *height = (GLsizei *) bp; bp += 4; weglScissor(*x,*y,*width,*height); -}; break; -case 5253: { // glSelectBuffer +}; break; +case 5253: { // glSelectBuffer GLsizei *size = (GLsizei *) bp; bp += 4; GLuint *buffer = (GLuint *) bins[0]->base; weglSelectBuffer(*size,buffer); @@ -1908,171 +1908,171 @@ case 5253: { // glSelectBuffer rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5254: { // glShadeModel +}; break; +case 5254: { // glShadeModel GLenum *mode = (GLenum *) bp; bp += 4; weglShadeModel(*mode); -}; break; -case 5255: { // glStencilFunc +}; break; +case 5255: { // glStencilFunc GLenum *func = (GLenum *) bp; bp += 4; GLint *ref = (GLint *) bp; bp += 4; GLuint *mask = (GLuint *) bp; bp += 4; weglStencilFunc(*func,*ref,*mask); -}; break; -case 5256: { // glStencilMask +}; break; +case 5256: { // glStencilMask GLuint *mask = (GLuint *) bp; bp += 4; weglStencilMask(*mask); -}; break; -case 5257: { // glStencilOp +}; break; +case 5257: { // glStencilOp GLenum *fail = (GLenum *) bp; bp += 4; GLenum *zfail = (GLenum *) bp; bp += 4; GLenum *zpass = (GLenum *) bp; bp += 4; weglStencilOp(*fail,*zfail,*zpass); -}; break; -case 5258: { // glTexCoord1dv +}; break; +case 5258: { // glTexCoord1dv GLdouble *v = (GLdouble *) bp; bp += 8; weglTexCoord1dv(v); -}; break; -case 5259: { // glTexCoord1fv +}; break; +case 5259: { // glTexCoord1fv GLfloat *v = (GLfloat *) bp; bp += 4; weglTexCoord1fv(v); -}; break; -case 5260: { // glTexCoord1iv +}; break; +case 5260: { // glTexCoord1iv GLint *v = (GLint *) bp; bp += 4; weglTexCoord1iv(v); -}; break; -case 5261: { // glTexCoord1sv +}; break; +case 5261: { // glTexCoord1sv GLshort *v = (GLshort *) bp; bp += 2; weglTexCoord1sv(v); -}; break; -case 5262: { // glTexCoord2dv +}; break; +case 5262: { // glTexCoord2dv GLdouble *v = (GLdouble *) bp; bp += 8; weglTexCoord2dv(v); -}; break; -case 5263: { // glTexCoord2fv +}; break; +case 5263: { // glTexCoord2fv GLfloat *v = (GLfloat *) bp; bp += 4; weglTexCoord2fv(v); -}; break; -case 5264: { // glTexCoord2iv +}; break; +case 5264: { // glTexCoord2iv GLint *v = (GLint *) bp; bp += 4; weglTexCoord2iv(v); -}; break; -case 5265: { // glTexCoord2sv +}; break; +case 5265: { // glTexCoord2sv GLshort *v = (GLshort *) bp; bp += 2; weglTexCoord2sv(v); -}; break; -case 5266: { // glTexCoord3dv +}; break; +case 5266: { // glTexCoord3dv GLdouble *v = (GLdouble *) bp; bp += 8; weglTexCoord3dv(v); -}; break; -case 5267: { // glTexCoord3fv +}; break; +case 5267: { // glTexCoord3fv GLfloat *v = (GLfloat *) bp; bp += 4; weglTexCoord3fv(v); -}; break; -case 5268: { // glTexCoord3iv +}; break; +case 5268: { // glTexCoord3iv GLint *v = (GLint *) bp; bp += 4; weglTexCoord3iv(v); -}; break; -case 5269: { // glTexCoord3sv +}; break; +case 5269: { // glTexCoord3sv GLshort *v = (GLshort *) bp; bp += 2; weglTexCoord3sv(v); -}; break; -case 5270: { // glTexCoord4dv +}; break; +case 5270: { // glTexCoord4dv GLdouble *v = (GLdouble *) bp; bp += 8; weglTexCoord4dv(v); -}; break; -case 5271: { // glTexCoord4fv +}; break; +case 5271: { // glTexCoord4fv GLfloat *v = (GLfloat *) bp; bp += 4; weglTexCoord4fv(v); -}; break; -case 5272: { // glTexCoord4iv +}; break; +case 5272: { // glTexCoord4iv GLint *v = (GLint *) bp; bp += 4; weglTexCoord4iv(v); -}; break; -case 5273: { // glTexCoord4sv +}; break; +case 5273: { // glTexCoord4sv GLshort *v = (GLshort *) bp; bp += 2; weglTexCoord4sv(v); -}; break; -case 5274: { // glTexCoordPointer +}; break; +case 5274: { // glTexCoordPointer GLint *size = (GLint *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; GLvoid *pointer = (GLvoid *) * (int *) bp; bp += 4; weglTexCoordPointer(*size,*type,*stride,pointer); -}; break; -case 5275: { // glTexCoordPointer +}; break; +case 5275: { // glTexCoordPointer GLint *size = (GLint *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; GLvoid *pointer = (GLvoid *) bins[0]->base; weglTexCoordPointer(*size,*type,*stride,pointer); -}; break; -case 5276: { // glTexEnvf +}; break; +case 5276: { // glTexEnvf GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLfloat *param = (GLfloat *) bp; bp += 4; weglTexEnvf(*target,*pname,*param); -}; break; -case 5277: { // glTexEnvfv +}; break; +case 5277: { // glTexEnvfv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; int *paramsLen = (int *) bp; bp += 4; GLfloat *params = (GLfloat *) bp; bp += *paramsLen*4+((*paramsLen)+1)%2*4; weglTexEnvfv(*target,*pname,params); -}; break; -case 5278: { // glTexEnvi +}; break; +case 5278: { // glTexEnvi GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint *param = (GLint *) bp; bp += 4; weglTexEnvi(*target,*pname,*param); -}; break; -case 5279: { // glTexEnviv +}; break; +case 5279: { // glTexEnviv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; int *paramsLen = (int *) bp; bp += 4; GLint *params = (GLint *) bp; bp += *paramsLen*4+((*paramsLen)+1)%2*4; weglTexEnviv(*target,*pname,params); -}; break; -case 5280: { // glTexGend +}; break; +case 5280: { // glTexGend GLenum *coord = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLdouble *param = (GLdouble *) bp; bp += 8; weglTexGend(*coord,*pname,*param); -}; break; -case 5281: { // glTexGendv +}; break; +case 5281: { // glTexGendv GLenum *coord = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; int *paramsLen = (int *) bp; bp += 8; GLdouble *params = (GLdouble *) bp; bp += *paramsLen*8; weglTexGendv(*coord,*pname,params); -}; break; -case 5282: { // glTexGenf +}; break; +case 5282: { // glTexGenf GLenum *coord = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLfloat *param = (GLfloat *) bp; bp += 4; weglTexGenf(*coord,*pname,*param); -}; break; -case 5283: { // glTexGenfv +}; break; +case 5283: { // glTexGenfv GLenum *coord = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; int *paramsLen = (int *) bp; bp += 4; GLfloat *params = (GLfloat *) bp; bp += *paramsLen*4+((*paramsLen)+1)%2*4; weglTexGenfv(*coord,*pname,params); -}; break; -case 5284: { // glTexGeni +}; break; +case 5284: { // glTexGeni GLenum *coord = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint *param = (GLint *) bp; bp += 4; weglTexGeni(*coord,*pname,*param); -}; break; -case 5285: { // glTexGeniv +}; break; +case 5285: { // glTexGeniv GLenum *coord = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; int *paramsLen = (int *) bp; bp += 4; GLint *params = (GLint *) bp; bp += *paramsLen*4+((*paramsLen)+1)%2*4; weglTexGeniv(*coord,*pname,params); -}; break; -case 5286: { // glTexImage1D +}; break; +case 5286: { // glTexImage1D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLint *internalformat = (GLint *) bp; bp += 4; @@ -2082,8 +2082,8 @@ case 5286: { // glTexImage1D GLenum *type = (GLenum *) bp; bp += 4; GLvoid *pixels = (GLvoid *) * (int *) bp; bp += 4; weglTexImage1D(*target,*level,*internalformat,*width,*border,*format,*type,pixels); -}; break; -case 5287: { // glTexImage1D +}; break; +case 5287: { // glTexImage1D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLint *internalformat = (GLint *) bp; bp += 4; @@ -2093,8 +2093,8 @@ case 5287: { // glTexImage1D GLenum *type = (GLenum *) bp; bp += 4; GLvoid *pixels = (GLvoid *) bins[0]->base; weglTexImage1D(*target,*level,*internalformat,*width,*border,*format,*type,pixels); -}; break; -case 5288: { // glTexImage2D +}; break; +case 5288: { // glTexImage2D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLint *internalformat = (GLint *) bp; bp += 4; @@ -2105,8 +2105,8 @@ case 5288: { // glTexImage2D GLenum *type = (GLenum *) bp; bp += 4; GLvoid *pixels = (GLvoid *) * (int *) bp; bp += 4; weglTexImage2D(*target,*level,*internalformat,*width,*height,*border,*format,*type,pixels); -}; break; -case 5289: { // glTexImage2D +}; break; +case 5289: { // glTexImage2D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLint *internalformat = (GLint *) bp; bp += 4; @@ -2117,34 +2117,34 @@ case 5289: { // glTexImage2D GLenum *type = (GLenum *) bp; bp += 4; GLvoid *pixels = (GLvoid *) bins[0]->base; weglTexImage2D(*target,*level,*internalformat,*width,*height,*border,*format,*type,pixels); -}; break; -case 5290: { // glTexParameterf +}; break; +case 5290: { // glTexParameterf GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLfloat *param = (GLfloat *) bp; bp += 4; weglTexParameterf(*target,*pname,*param); -}; break; -case 5291: { // glTexParameterfv +}; break; +case 5291: { // glTexParameterfv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; int *paramsLen = (int *) bp; bp += 4; GLfloat *params = (GLfloat *) bp; bp += *paramsLen*4+((*paramsLen)+1)%2*4; weglTexParameterfv(*target,*pname,params); -}; break; -case 5292: { // glTexParameteri +}; break; +case 5292: { // glTexParameteri GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint *param = (GLint *) bp; bp += 4; weglTexParameteri(*target,*pname,*param); -}; break; -case 5293: { // glTexParameteriv +}; break; +case 5293: { // glTexParameteriv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; int *paramsLen = (int *) bp; bp += 4; GLint *params = (GLint *) bp; bp += *paramsLen*4+((*paramsLen)+1)%2*4; weglTexParameteriv(*target,*pname,params); -}; break; -case 5294: { // glTexSubImage1D +}; break; +case 5294: { // glTexSubImage1D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLint *xoffset = (GLint *) bp; bp += 4; @@ -2153,8 +2153,8 @@ case 5294: { // glTexSubImage1D GLenum *type = (GLenum *) bp; bp += 4; GLvoid *pixels = (GLvoid *) * (int *) bp; bp += 4; weglTexSubImage1D(*target,*level,*xoffset,*width,*format,*type,pixels); -}; break; -case 5295: { // glTexSubImage1D +}; break; +case 5295: { // glTexSubImage1D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLint *xoffset = (GLint *) bp; bp += 4; @@ -2163,8 +2163,8 @@ case 5295: { // glTexSubImage1D GLenum *type = (GLenum *) bp; bp += 4; GLvoid *pixels = (GLvoid *) bins[0]->base; weglTexSubImage1D(*target,*level,*xoffset,*width,*format,*type,pixels); -}; break; -case 5296: { // glTexSubImage2D +}; break; +case 5296: { // glTexSubImage2D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLint *xoffset = (GLint *) bp; bp += 4; @@ -2175,8 +2175,8 @@ case 5296: { // glTexSubImage2D GLenum *type = (GLenum *) bp; bp += 4; GLvoid *pixels = (GLvoid *) * (int *) bp; bp += 4; weglTexSubImage2D(*target,*level,*xoffset,*yoffset,*width,*height,*format,*type,pixels); -}; break; -case 5297: { // glTexSubImage2D +}; break; +case 5297: { // glTexSubImage2D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLint *xoffset = (GLint *) bp; bp += 4; @@ -2187,100 +2187,100 @@ case 5297: { // glTexSubImage2D GLenum *type = (GLenum *) bp; bp += 4; GLvoid *pixels = (GLvoid *) bins[0]->base; weglTexSubImage2D(*target,*level,*xoffset,*yoffset,*width,*height,*format,*type,pixels); -}; break; -case 5298: { // glTranslated +}; break; +case 5298: { // glTranslated GLdouble *x = (GLdouble *) bp; bp += 8; GLdouble *y = (GLdouble *) bp; bp += 8; GLdouble *z = (GLdouble *) bp; bp += 8; weglTranslated(*x,*y,*z); -}; break; -case 5299: { // glTranslatef +}; break; +case 5299: { // glTranslatef GLfloat *x = (GLfloat *) bp; bp += 4; GLfloat *y = (GLfloat *) bp; bp += 4; GLfloat *z = (GLfloat *) bp; bp += 4; weglTranslatef(*x,*y,*z); -}; break; -case 5300: { // glVertex2dv +}; break; +case 5300: { // glVertex2dv GLdouble *v = (GLdouble *) bp; bp += 8; weglVertex2dv(v); -}; break; -case 5301: { // glVertex2fv +}; break; +case 5301: { // glVertex2fv GLfloat *v = (GLfloat *) bp; bp += 4; weglVertex2fv(v); -}; break; -case 5302: { // glVertex2iv +}; break; +case 5302: { // glVertex2iv GLint *v = (GLint *) bp; bp += 4; weglVertex2iv(v); -}; break; -case 5303: { // glVertex2sv +}; break; +case 5303: { // glVertex2sv GLshort *v = (GLshort *) bp; bp += 2; weglVertex2sv(v); -}; break; -case 5304: { // glVertex3dv +}; break; +case 5304: { // glVertex3dv GLdouble *v = (GLdouble *) bp; bp += 8; weglVertex3dv(v); -}; break; -case 5305: { // glVertex3fv +}; break; +case 5305: { // glVertex3fv GLfloat *v = (GLfloat *) bp; bp += 4; weglVertex3fv(v); -}; break; -case 5306: { // glVertex3iv +}; break; +case 5306: { // glVertex3iv GLint *v = (GLint *) bp; bp += 4; weglVertex3iv(v); -}; break; -case 5307: { // glVertex3sv +}; break; +case 5307: { // glVertex3sv GLshort *v = (GLshort *) bp; bp += 2; weglVertex3sv(v); -}; break; -case 5308: { // glVertex4dv +}; break; +case 5308: { // glVertex4dv GLdouble *v = (GLdouble *) bp; bp += 8; weglVertex4dv(v); -}; break; -case 5309: { // glVertex4fv +}; break; +case 5309: { // glVertex4fv GLfloat *v = (GLfloat *) bp; bp += 4; weglVertex4fv(v); -}; break; -case 5310: { // glVertex4iv +}; break; +case 5310: { // glVertex4iv GLint *v = (GLint *) bp; bp += 4; weglVertex4iv(v); -}; break; -case 5311: { // glVertex4sv +}; break; +case 5311: { // glVertex4sv GLshort *v = (GLshort *) bp; bp += 2; weglVertex4sv(v); -}; break; -case 5312: { // glVertexPointer +}; break; +case 5312: { // glVertexPointer GLint *size = (GLint *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; GLvoid *pointer = (GLvoid *) * (int *) bp; bp += 4; weglVertexPointer(*size,*type,*stride,pointer); -}; break; -case 5313: { // glVertexPointer +}; break; +case 5313: { // glVertexPointer GLint *size = (GLint *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; GLvoid *pointer = (GLvoid *) bins[0]->base; weglVertexPointer(*size,*type,*stride,pointer); -}; break; -case 5314: { // glViewport +}; break; +case 5314: { // glViewport GLint *x = (GLint *) bp; bp += 4; GLint *y = (GLint *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; GLsizei *height = (GLsizei *) bp; bp += 4; weglViewport(*x,*y,*width,*height); -}; break; -case 5315: { // glBlendColor +}; break; +case 5315: { // glBlendColor GLclampf *red = (GLclampf *) bp; bp += 4; GLclampf *green = (GLclampf *) bp; bp += 4; GLclampf *blue = (GLclampf *) bp; bp += 4; GLclampf *alpha = (GLclampf *) bp; bp += 4; weglBlendColor(*red,*green,*blue,*alpha); -}; break; -case 5316: { // glBlendEquation +}; break; +case 5316: { // glBlendEquation GLenum *mode = (GLenum *) bp; bp += 4; weglBlendEquation(*mode); -}; break; -case 5317: { // glDrawRangeElements +}; break; +case 5317: { // glDrawRangeElements GLenum *mode = (GLenum *) bp; bp += 4; GLuint *start = (GLuint *) bp; bp += 4; GLuint *end = (GLuint *) bp; bp += 4; @@ -2288,8 +2288,8 @@ case 5317: { // glDrawRangeElements GLenum *type = (GLenum *) bp; bp += 4; GLvoid *indices = (GLvoid *) * (int *) bp; bp += 4; weglDrawRangeElements(*mode,*start,*end,*count,*type,indices); -}; break; -case 5318: { // glDrawRangeElements +}; break; +case 5318: { // glDrawRangeElements GLenum *mode = (GLenum *) bp; bp += 4; GLuint *start = (GLuint *) bp; bp += 4; GLuint *end = (GLuint *) bp; bp += 4; @@ -2297,8 +2297,8 @@ case 5318: { // glDrawRangeElements GLenum *type = (GLenum *) bp; bp += 4; GLvoid *indices = (GLvoid *) bins[0]->base; weglDrawRangeElements(*mode,*start,*end,*count,*type,indices); -}; break; -case 5319: { // glTexImage3D +}; break; +case 5319: { // glTexImage3D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLint *internalformat = (GLint *) bp; bp += 4; @@ -2310,8 +2310,8 @@ case 5319: { // glTexImage3D GLenum *type = (GLenum *) bp; bp += 4; GLvoid *pixels = (GLvoid *) * (int *) bp; bp += 4; weglTexImage3D(*target,*level,*internalformat,*width,*height,*depth,*border,*format,*type,pixels); -}; break; -case 5320: { // glTexImage3D +}; break; +case 5320: { // glTexImage3D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLint *internalformat = (GLint *) bp; bp += 4; @@ -2323,8 +2323,8 @@ case 5320: { // glTexImage3D GLenum *type = (GLenum *) bp; bp += 4; GLvoid *pixels = (GLvoid *) bins[0]->base; weglTexImage3D(*target,*level,*internalformat,*width,*height,*depth,*border,*format,*type,pixels); -}; break; -case 5321: { // glTexSubImage3D +}; break; +case 5321: { // glTexSubImage3D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLint *xoffset = (GLint *) bp; bp += 4; @@ -2337,8 +2337,8 @@ case 5321: { // glTexSubImage3D GLenum *type = (GLenum *) bp; bp += 4; GLvoid *pixels = (GLvoid *) * (int *) bp; bp += 4; weglTexSubImage3D(*target,*level,*xoffset,*yoffset,*zoffset,*width,*height,*depth,*format,*type,pixels); -}; break; -case 5322: { // glTexSubImage3D +}; break; +case 5322: { // glTexSubImage3D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLint *xoffset = (GLint *) bp; bp += 4; @@ -2351,8 +2351,8 @@ case 5322: { // glTexSubImage3D GLenum *type = (GLenum *) bp; bp += 4; GLvoid *pixels = (GLvoid *) bins[0]->base; weglTexSubImage3D(*target,*level,*xoffset,*yoffset,*zoffset,*width,*height,*depth,*format,*type,pixels); -}; break; -case 5323: { // glCopyTexSubImage3D +}; break; +case 5323: { // glCopyTexSubImage3D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLint *xoffset = (GLint *) bp; bp += 4; @@ -2363,8 +2363,8 @@ case 5323: { // glCopyTexSubImage3D GLsizei *width = (GLsizei *) bp; bp += 4; GLsizei *height = (GLsizei *) bp; bp += 4; weglCopyTexSubImage3D(*target,*level,*xoffset,*yoffset,*zoffset,*x,*y,*width,*height); -}; break; -case 5324: { // glColorTable +}; break; +case 5324: { // glColorTable GLenum *target = (GLenum *) bp; bp += 4; GLenum *internalformat = (GLenum *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; @@ -2372,8 +2372,8 @@ case 5324: { // glColorTable GLenum *type = (GLenum *) bp; bp += 4; GLvoid *table = (GLvoid *) * (int *) bp; bp += 4; weglColorTable(*target,*internalformat,*width,*format,*type,table); -}; break; -case 5325: { // glColorTable +}; break; +case 5325: { // glColorTable GLenum *target = (GLenum *) bp; bp += 4; GLenum *internalformat = (GLenum *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; @@ -2381,28 +2381,28 @@ case 5325: { // glColorTable GLenum *type = (GLenum *) bp; bp += 4; GLvoid *table = (GLvoid *) bins[0]->base; weglColorTable(*target,*internalformat,*width,*format,*type,table); -}; break; -case 5326: { // glColorTableParameterfv +}; break; +case 5326: { // glColorTableParameterfv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLfloat * params = (GLfloat *) bp; bp += 16; weglColorTableParameterfv(*target,*pname,params); -}; break; -case 5327: { // glColorTableParameteriv +}; break; +case 5327: { // glColorTableParameteriv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint * params = (GLint *) bp; bp += 16; weglColorTableParameteriv(*target,*pname,params); -}; break; -case 5328: { // glCopyColorTable +}; break; +case 5328: { // glCopyColorTable GLenum *target = (GLenum *) bp; bp += 4; GLenum *internalformat = (GLenum *) bp; bp += 4; GLint *x = (GLint *) bp; bp += 4; GLint *y = (GLint *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; weglCopyColorTable(*target,*internalformat,*x,*y,*width); -}; break; -case 5329: { // glGetColorTable +}; break; +case 5329: { // glGetColorTable GLenum *target = (GLenum *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; @@ -2413,8 +2413,8 @@ case 5329: { // glGetColorTable rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5330: { // glGetColorTableParameterfv +}; break; +case 5330: { // glGetColorTableParameterfv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLfloat params[4] = {0.0,0.0,0.0,0.0}; @@ -2431,8 +2431,8 @@ case 5330: { // glGetColorTableParameterfv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5331: { // glGetColorTableParameteriv +}; break; +case 5331: { // glGetColorTableParameteriv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint params[4] = {0,0,0,0}; @@ -2448,8 +2448,8 @@ case 5331: { // glGetColorTableParameteriv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5332: { // glColorSubTable +}; break; +case 5332: { // glColorSubTable GLenum *target = (GLenum *) bp; bp += 4; GLsizei *start = (GLsizei *) bp; bp += 4; GLsizei *count = (GLsizei *) bp; bp += 4; @@ -2457,8 +2457,8 @@ case 5332: { // glColorSubTable GLenum *type = (GLenum *) bp; bp += 4; GLvoid *data = (GLvoid *) * (int *) bp; bp += 4; weglColorSubTable(*target,*start,*count,*format,*type,data); -}; break; -case 5333: { // glColorSubTable +}; break; +case 5333: { // glColorSubTable GLenum *target = (GLenum *) bp; bp += 4; GLsizei *start = (GLsizei *) bp; bp += 4; GLsizei *count = (GLsizei *) bp; bp += 4; @@ -2466,16 +2466,16 @@ case 5333: { // glColorSubTable GLenum *type = (GLenum *) bp; bp += 4; GLvoid *data = (GLvoid *) bins[0]->base; weglColorSubTable(*target,*start,*count,*format,*type,data); -}; break; -case 5334: { // glCopyColorSubTable +}; break; +case 5334: { // glCopyColorSubTable GLenum *target = (GLenum *) bp; bp += 4; GLsizei *start = (GLsizei *) bp; bp += 4; GLint *x = (GLint *) bp; bp += 4; GLint *y = (GLint *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; weglCopyColorSubTable(*target,*start,*x,*y,*width); -}; break; -case 5335: { // glConvolutionFilter1D +}; break; +case 5335: { // glConvolutionFilter1D GLenum *target = (GLenum *) bp; bp += 4; GLenum *internalformat = (GLenum *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; @@ -2483,8 +2483,8 @@ case 5335: { // glConvolutionFilter1D GLenum *type = (GLenum *) bp; bp += 4; GLvoid *image = (GLvoid *) * (int *) bp; bp += 4; weglConvolutionFilter1D(*target,*internalformat,*width,*format,*type,image); -}; break; -case 5336: { // glConvolutionFilter1D +}; break; +case 5336: { // glConvolutionFilter1D GLenum *target = (GLenum *) bp; bp += 4; GLenum *internalformat = (GLenum *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; @@ -2492,8 +2492,8 @@ case 5336: { // glConvolutionFilter1D GLenum *type = (GLenum *) bp; bp += 4; GLvoid *image = (GLvoid *) bins[0]->base; weglConvolutionFilter1D(*target,*internalformat,*width,*format,*type,image); -}; break; -case 5337: { // glConvolutionFilter2D +}; break; +case 5337: { // glConvolutionFilter2D GLenum *target = (GLenum *) bp; bp += 4; GLenum *internalformat = (GLenum *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; @@ -2502,8 +2502,8 @@ case 5337: { // glConvolutionFilter2D GLenum *type = (GLenum *) bp; bp += 4; GLvoid *image = (GLvoid *) * (int *) bp; bp += 4; weglConvolutionFilter2D(*target,*internalformat,*width,*height,*format,*type,image); -}; break; -case 5338: { // glConvolutionFilter2D +}; break; +case 5338: { // glConvolutionFilter2D GLenum *target = (GLenum *) bp; bp += 4; GLenum *internalformat = (GLenum *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; @@ -2512,30 +2512,30 @@ case 5338: { // glConvolutionFilter2D GLenum *type = (GLenum *) bp; bp += 4; GLvoid *image = (GLvoid *) bins[0]->base; weglConvolutionFilter2D(*target,*internalformat,*width,*height,*format,*type,image); -}; break; -case 5339: { // glConvolutionParameterfv +}; break; +case 5339: { // glConvolutionParameterfv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; int *paramsLen = (int *) bp; bp += 4; GLfloat *params = (GLfloat *) bp; bp += *paramsLen*4+((*paramsLen)+1)%2*4; weglConvolutionParameterfv(*target,*pname,params); -}; break; -case 5340: { // glConvolutionParameteriv +}; break; +case 5340: { // glConvolutionParameteriv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; int *paramsLen = (int *) bp; bp += 4; GLint *params = (GLint *) bp; bp += *paramsLen*4+((*paramsLen)+1)%2*4; weglConvolutionParameteriv(*target,*pname,params); -}; break; -case 5341: { // glCopyConvolutionFilter1D +}; break; +case 5341: { // glCopyConvolutionFilter1D GLenum *target = (GLenum *) bp; bp += 4; GLenum *internalformat = (GLenum *) bp; bp += 4; GLint *x = (GLint *) bp; bp += 4; GLint *y = (GLint *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; weglCopyConvolutionFilter1D(*target,*internalformat,*x,*y,*width); -}; break; -case 5342: { // glCopyConvolutionFilter2D +}; break; +case 5342: { // glCopyConvolutionFilter2D GLenum *target = (GLenum *) bp; bp += 4; GLenum *internalformat = (GLenum *) bp; bp += 4; GLint *x = (GLint *) bp; bp += 4; @@ -2543,8 +2543,8 @@ case 5342: { // glCopyConvolutionFilter2D GLsizei *width = (GLsizei *) bp; bp += 4; GLsizei *height = (GLsizei *) bp; bp += 4; weglCopyConvolutionFilter2D(*target,*internalformat,*x,*y,*width,*height); -}; break; -case 5343: { // glGetConvolutionFilter +}; break; +case 5343: { // glGetConvolutionFilter GLenum *target = (GLenum *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; @@ -2555,8 +2555,8 @@ case 5343: { // glGetConvolutionFilter rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5344: { // glGetConvolutionParameterfv +}; break; +case 5344: { // glGetConvolutionParameterfv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLfloat params[4] = {0.0,0.0,0.0,0.0}; @@ -2573,8 +2573,8 @@ case 5344: { // glGetConvolutionParameterfv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5345: { // glGetConvolutionParameteriv +}; break; +case 5345: { // glGetConvolutionParameteriv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint params[4] = {0,0,0,0}; @@ -2590,8 +2590,8 @@ case 5345: { // glGetConvolutionParameteriv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5346: { // glSeparableFilter2D +}; break; +case 5346: { // glSeparableFilter2D GLenum *target = (GLenum *) bp; bp += 4; GLenum *internalformat = (GLenum *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; @@ -2601,8 +2601,8 @@ case 5346: { // glSeparableFilter2D GLvoid *row = (GLvoid *) * (int *) bp; bp += 4; GLvoid *column = (GLvoid *) * (int *) bp; bp += 4; weglSeparableFilter2D(*target,*internalformat,*width,*height,*format,*type,row,column); -}; break; -case 5347: { // glSeparableFilter2D +}; break; +case 5347: { // glSeparableFilter2D GLenum *target = (GLenum *) bp; bp += 4; GLenum *internalformat = (GLenum *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; @@ -2612,8 +2612,8 @@ case 5347: { // glSeparableFilter2D GLvoid *row = (GLvoid *) bins[0]->base; GLvoid *column = (GLvoid *) bins[1]->base; weglSeparableFilter2D(*target,*internalformat,*width,*height,*format,*type,row,column); -}; break; -case 5348: { // glGetHistogram +}; break; +case 5348: { // glGetHistogram GLenum *target = (GLenum *) bp; bp += 4; GLboolean *reset = (GLboolean *) bp; bp += 1; bp += 3; @@ -2626,8 +2626,8 @@ case 5348: { // glGetHistogram rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5349: { // glGetHistogramParameterfv +}; break; +case 5349: { // glGetHistogramParameterfv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLfloat params[1] = {0.0}; @@ -2641,8 +2641,8 @@ case 5349: { // glGetHistogramParameterfv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 8 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,8); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5350: { // glGetHistogramParameteriv +}; break; +case 5350: { // glGetHistogramParameteriv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint params[1] = {0}; @@ -2655,8 +2655,8 @@ case 5350: { // glGetHistogramParameteriv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 8 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,8); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5351: { // glGetMinmax +}; break; +case 5351: { // glGetMinmax GLenum *target = (GLenum *) bp; bp += 4; GLboolean *reset = (GLboolean *) bp; bp += 1; bp += 3; @@ -2669,8 +2669,8 @@ case 5351: { // glGetMinmax rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5352: { // glGetMinmaxParameterfv +}; break; +case 5352: { // glGetMinmaxParameterfv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLfloat params[1] = {0.0}; @@ -2684,8 +2684,8 @@ case 5352: { // glGetMinmaxParameterfv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 8 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,8); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5353: { // glGetMinmaxParameteriv +}; break; +case 5353: { // glGetMinmaxParameteriv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint params[1] = {0}; @@ -2698,38 +2698,38 @@ case 5353: { // glGetMinmaxParameteriv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 8 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,8); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5354: { // glHistogram +}; break; +case 5354: { // glHistogram GLenum *target = (GLenum *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; GLenum *internalformat = (GLenum *) bp; bp += 4; GLboolean *sink = (GLboolean *) bp; bp += 1; weglHistogram(*target,*width,*internalformat,*sink); -}; break; -case 5355: { // glMinmax +}; break; +case 5355: { // glMinmax GLenum *target = (GLenum *) bp; bp += 4; GLenum *internalformat = (GLenum *) bp; bp += 4; GLboolean *sink = (GLboolean *) bp; bp += 1; weglMinmax(*target,*internalformat,*sink); -}; break; -case 5356: { // glResetHistogram +}; break; +case 5356: { // glResetHistogram GLenum *target = (GLenum *) bp; bp += 4; weglResetHistogram(*target); -}; break; -case 5357: { // glResetMinmax +}; break; +case 5357: { // glResetMinmax GLenum *target = (GLenum *) bp; bp += 4; weglResetMinmax(*target); -}; break; -case 5358: { // glActiveTexture +}; break; +case 5358: { // glActiveTexture GLenum *texture = (GLenum *) bp; bp += 4; weglActiveTexture(*texture); -}; break; -case 5359: { // glSampleCoverage +}; break; +case 5359: { // glSampleCoverage GLclampf *value = (GLclampf *) bp; bp += 4; GLboolean *invert = (GLboolean *) bp; bp += 1; weglSampleCoverage(*value,*invert); -}; break; -case 5360: { // glCompressedTexImage3D +}; break; +case 5360: { // glCompressedTexImage3D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLenum *internalformat = (GLenum *) bp; bp += 4; @@ -2740,8 +2740,8 @@ case 5360: { // glCompressedTexImage3D GLsizei *imageSize = (GLsizei *) bp; bp += 4; GLvoid *data = (GLvoid *) * (int *) bp; bp += 4; weglCompressedTexImage3D(*target,*level,*internalformat,*width,*height,*depth,*border,*imageSize,data); -}; break; -case 5361: { // glCompressedTexImage3D +}; break; +case 5361: { // glCompressedTexImage3D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLenum *internalformat = (GLenum *) bp; bp += 4; @@ -2752,8 +2752,8 @@ case 5361: { // glCompressedTexImage3D GLsizei *imageSize = (GLsizei *) bp; bp += 4; GLvoid *data = (GLvoid *) bins[0]->base; weglCompressedTexImage3D(*target,*level,*internalformat,*width,*height,*depth,*border,*imageSize,data); -}; break; -case 5362: { // glCompressedTexImage2D +}; break; +case 5362: { // glCompressedTexImage2D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLenum *internalformat = (GLenum *) bp; bp += 4; @@ -2763,8 +2763,8 @@ case 5362: { // glCompressedTexImage2D GLsizei *imageSize = (GLsizei *) bp; bp += 4; GLvoid *data = (GLvoid *) * (int *) bp; bp += 4; weglCompressedTexImage2D(*target,*level,*internalformat,*width,*height,*border,*imageSize,data); -}; break; -case 5363: { // glCompressedTexImage2D +}; break; +case 5363: { // glCompressedTexImage2D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLenum *internalformat = (GLenum *) bp; bp += 4; @@ -2774,8 +2774,8 @@ case 5363: { // glCompressedTexImage2D GLsizei *imageSize = (GLsizei *) bp; bp += 4; GLvoid *data = (GLvoid *) bins[0]->base; weglCompressedTexImage2D(*target,*level,*internalformat,*width,*height,*border,*imageSize,data); -}; break; -case 5364: { // glCompressedTexImage1D +}; break; +case 5364: { // glCompressedTexImage1D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLenum *internalformat = (GLenum *) bp; bp += 4; @@ -2784,8 +2784,8 @@ case 5364: { // glCompressedTexImage1D GLsizei *imageSize = (GLsizei *) bp; bp += 4; GLvoid *data = (GLvoid *) * (int *) bp; bp += 4; weglCompressedTexImage1D(*target,*level,*internalformat,*width,*border,*imageSize,data); -}; break; -case 5365: { // glCompressedTexImage1D +}; break; +case 5365: { // glCompressedTexImage1D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLenum *internalformat = (GLenum *) bp; bp += 4; @@ -2794,8 +2794,8 @@ case 5365: { // glCompressedTexImage1D GLsizei *imageSize = (GLsizei *) bp; bp += 4; GLvoid *data = (GLvoid *) bins[0]->base; weglCompressedTexImage1D(*target,*level,*internalformat,*width,*border,*imageSize,data); -}; break; -case 5366: { // glCompressedTexSubImage3D +}; break; +case 5366: { // glCompressedTexSubImage3D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLint *xoffset = (GLint *) bp; bp += 4; @@ -2808,8 +2808,8 @@ case 5366: { // glCompressedTexSubImage3D GLsizei *imageSize = (GLsizei *) bp; bp += 4; GLvoid *data = (GLvoid *) * (int *) bp; bp += 4; weglCompressedTexSubImage3D(*target,*level,*xoffset,*yoffset,*zoffset,*width,*height,*depth,*format,*imageSize,data); -}; break; -case 5367: { // glCompressedTexSubImage3D +}; break; +case 5367: { // glCompressedTexSubImage3D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLint *xoffset = (GLint *) bp; bp += 4; @@ -2822,8 +2822,8 @@ case 5367: { // glCompressedTexSubImage3D GLsizei *imageSize = (GLsizei *) bp; bp += 4; GLvoid *data = (GLvoid *) bins[0]->base; weglCompressedTexSubImage3D(*target,*level,*xoffset,*yoffset,*zoffset,*width,*height,*depth,*format,*imageSize,data); -}; break; -case 5368: { // glCompressedTexSubImage2D +}; break; +case 5368: { // glCompressedTexSubImage2D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLint *xoffset = (GLint *) bp; bp += 4; @@ -2834,8 +2834,8 @@ case 5368: { // glCompressedTexSubImage2D GLsizei *imageSize = (GLsizei *) bp; bp += 4; GLvoid *data = (GLvoid *) * (int *) bp; bp += 4; weglCompressedTexSubImage2D(*target,*level,*xoffset,*yoffset,*width,*height,*format,*imageSize,data); -}; break; -case 5369: { // glCompressedTexSubImage2D +}; break; +case 5369: { // glCompressedTexSubImage2D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLint *xoffset = (GLint *) bp; bp += 4; @@ -2846,8 +2846,8 @@ case 5369: { // glCompressedTexSubImage2D GLsizei *imageSize = (GLsizei *) bp; bp += 4; GLvoid *data = (GLvoid *) bins[0]->base; weglCompressedTexSubImage2D(*target,*level,*xoffset,*yoffset,*width,*height,*format,*imageSize,data); -}; break; -case 5370: { // glCompressedTexSubImage1D +}; break; +case 5370: { // glCompressedTexSubImage1D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLint *xoffset = (GLint *) bp; bp += 4; @@ -2856,8 +2856,8 @@ case 5370: { // glCompressedTexSubImage1D GLsizei *imageSize = (GLsizei *) bp; bp += 4; GLvoid *data = (GLvoid *) * (int *) bp; bp += 4; weglCompressedTexSubImage1D(*target,*level,*xoffset,*width,*format,*imageSize,data); -}; break; -case 5371: { // glCompressedTexSubImage1D +}; break; +case 5371: { // glCompressedTexSubImage1D GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLint *xoffset = (GLint *) bp; bp += 4; @@ -2866,8 +2866,8 @@ case 5371: { // glCompressedTexSubImage1D GLsizei *imageSize = (GLsizei *) bp; bp += 4; GLvoid *data = (GLvoid *) bins[0]->base; weglCompressedTexSubImage1D(*target,*level,*xoffset,*width,*format,*imageSize,data); -}; break; -case 5372: { // glGetCompressedTexImage +}; break; +case 5372: { // glGetCompressedTexImage GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLvoid *img = (GLvoid *) bins[0]->base; @@ -2877,247 +2877,247 @@ case 5372: { // glGetCompressedTexImage rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5373: { // glClientActiveTexture +}; break; +case 5373: { // glClientActiveTexture GLenum *texture = (GLenum *) bp; bp += 4; weglClientActiveTexture(*texture); -}; break; -case 5374: { // glMultiTexCoord1dv +}; break; +case 5374: { // glMultiTexCoord1dv GLenum *target = (GLenum *) bp; bp += 4; bp += 4; GLdouble *v = (GLdouble *) bp; bp += 8; weglMultiTexCoord1dv(*target,v); -}; break; -case 5375: { // glMultiTexCoord1fv +}; break; +case 5375: { // glMultiTexCoord1fv GLenum *target = (GLenum *) bp; bp += 4; GLfloat *v = (GLfloat *) bp; bp += 4; weglMultiTexCoord1fv(*target,v); -}; break; -case 5376: { // glMultiTexCoord1iv +}; break; +case 5376: { // glMultiTexCoord1iv GLenum *target = (GLenum *) bp; bp += 4; GLint *v = (GLint *) bp; bp += 4; weglMultiTexCoord1iv(*target,v); -}; break; -case 5377: { // glMultiTexCoord1sv +}; break; +case 5377: { // glMultiTexCoord1sv GLenum *target = (GLenum *) bp; bp += 4; GLshort *v = (GLshort *) bp; bp += 2; weglMultiTexCoord1sv(*target,v); -}; break; -case 5378: { // glMultiTexCoord2dv +}; break; +case 5378: { // glMultiTexCoord2dv GLenum *target = (GLenum *) bp; bp += 4; bp += 4; GLdouble *v = (GLdouble *) bp; bp += 8; weglMultiTexCoord2dv(*target,v); -}; break; -case 5379: { // glMultiTexCoord2fv +}; break; +case 5379: { // glMultiTexCoord2fv GLenum *target = (GLenum *) bp; bp += 4; GLfloat *v = (GLfloat *) bp; bp += 4; weglMultiTexCoord2fv(*target,v); -}; break; -case 5380: { // glMultiTexCoord2iv +}; break; +case 5380: { // glMultiTexCoord2iv GLenum *target = (GLenum *) bp; bp += 4; GLint *v = (GLint *) bp; bp += 4; weglMultiTexCoord2iv(*target,v); -}; break; -case 5381: { // glMultiTexCoord2sv +}; break; +case 5381: { // glMultiTexCoord2sv GLenum *target = (GLenum *) bp; bp += 4; GLshort *v = (GLshort *) bp; bp += 2; weglMultiTexCoord2sv(*target,v); -}; break; -case 5382: { // glMultiTexCoord3dv +}; break; +case 5382: { // glMultiTexCoord3dv GLenum *target = (GLenum *) bp; bp += 4; bp += 4; GLdouble *v = (GLdouble *) bp; bp += 8; weglMultiTexCoord3dv(*target,v); -}; break; -case 5383: { // glMultiTexCoord3fv +}; break; +case 5383: { // glMultiTexCoord3fv GLenum *target = (GLenum *) bp; bp += 4; GLfloat *v = (GLfloat *) bp; bp += 4; weglMultiTexCoord3fv(*target,v); -}; break; -case 5384: { // glMultiTexCoord3iv +}; break; +case 5384: { // glMultiTexCoord3iv GLenum *target = (GLenum *) bp; bp += 4; GLint *v = (GLint *) bp; bp += 4; weglMultiTexCoord3iv(*target,v); -}; break; -case 5385: { // glMultiTexCoord3sv +}; break; +case 5385: { // glMultiTexCoord3sv GLenum *target = (GLenum *) bp; bp += 4; GLshort *v = (GLshort *) bp; bp += 2; weglMultiTexCoord3sv(*target,v); -}; break; -case 5386: { // glMultiTexCoord4dv +}; break; +case 5386: { // glMultiTexCoord4dv GLenum *target = (GLenum *) bp; bp += 4; bp += 4; GLdouble *v = (GLdouble *) bp; bp += 8; weglMultiTexCoord4dv(*target,v); -}; break; -case 5387: { // glMultiTexCoord4fv +}; break; +case 5387: { // glMultiTexCoord4fv GLenum *target = (GLenum *) bp; bp += 4; GLfloat *v = (GLfloat *) bp; bp += 4; weglMultiTexCoord4fv(*target,v); -}; break; -case 5388: { // glMultiTexCoord4iv +}; break; +case 5388: { // glMultiTexCoord4iv GLenum *target = (GLenum *) bp; bp += 4; GLint *v = (GLint *) bp; bp += 4; weglMultiTexCoord4iv(*target,v); -}; break; -case 5389: { // glMultiTexCoord4sv +}; break; +case 5389: { // glMultiTexCoord4sv GLenum *target = (GLenum *) bp; bp += 4; GLshort *v = (GLshort *) bp; bp += 2; weglMultiTexCoord4sv(*target,v); -}; break; -case 5390: { // glLoadTransposeMatrixf +}; break; +case 5390: { // glLoadTransposeMatrixf GLfloat * m = (GLfloat *) bp; bp += 64; weglLoadTransposeMatrixf(m); -}; break; -case 5391: { // glLoadTransposeMatrixd +}; break; +case 5391: { // glLoadTransposeMatrixd GLdouble * m = (GLdouble *) bp; bp += 128; weglLoadTransposeMatrixd(m); -}; break; -case 5392: { // glMultTransposeMatrixf +}; break; +case 5392: { // glMultTransposeMatrixf GLfloat * m = (GLfloat *) bp; bp += 64; weglMultTransposeMatrixf(m); -}; break; -case 5393: { // glMultTransposeMatrixd +}; break; +case 5393: { // glMultTransposeMatrixd GLdouble * m = (GLdouble *) bp; bp += 128; weglMultTransposeMatrixd(m); -}; break; -case 5394: { // glBlendFuncSeparate +}; break; +case 5394: { // glBlendFuncSeparate GLenum *sfactorRGB = (GLenum *) bp; bp += 4; GLenum *dfactorRGB = (GLenum *) bp; bp += 4; GLenum *sfactorAlpha = (GLenum *) bp; bp += 4; GLenum *dfactorAlpha = (GLenum *) bp; bp += 4; weglBlendFuncSeparate(*sfactorRGB,*dfactorRGB,*sfactorAlpha,*dfactorAlpha); -}; break; -case 5395: { // glMultiDrawArrays +}; break; +case 5395: { // glMultiDrawArrays GLenum *mode = (GLenum *) bp; bp += 4; int * firstLen = (int *) bp; bp += 4; GLint * first = (GLint *) bp; bp += (8-((*firstLen*4+0)%8))%8; int * countLen = (int *) bp; bp += 4; GLsizei * count = (GLsizei *) bp; bp += (8-((*countLen*4+4)%8))%8; weglMultiDrawArrays(*mode,first,count,*firstLen); -}; break; -case 5396: { // glPointParameterf +}; break; +case 5396: { // glPointParameterf GLenum *pname = (GLenum *) bp; bp += 4; GLfloat *param = (GLfloat *) bp; bp += 4; weglPointParameterf(*pname,*param); -}; break; -case 5397: { // glPointParameterfv +}; break; +case 5397: { // glPointParameterfv GLenum *pname = (GLenum *) bp; bp += 4; int *paramsLen = (int *) bp; bp += 4; GLfloat *params = (GLfloat *) bp; bp += *paramsLen*4+((*paramsLen)+0)%2*4; weglPointParameterfv(*pname,params); -}; break; -case 5398: { // glPointParameteri +}; break; +case 5398: { // glPointParameteri GLenum *pname = (GLenum *) bp; bp += 4; GLint *param = (GLint *) bp; bp += 4; weglPointParameteri(*pname,*param); -}; break; -case 5399: { // glPointParameteriv +}; break; +case 5399: { // glPointParameteriv GLenum *pname = (GLenum *) bp; bp += 4; int *paramsLen = (int *) bp; bp += 4; GLint *params = (GLint *) bp; bp += *paramsLen*4+((*paramsLen)+0)%2*4; weglPointParameteriv(*pname,params); -}; break; -case 5400: { // glFogCoordfv +}; break; +case 5400: { // glFogCoordfv GLfloat *coord = (GLfloat *) bp; bp += 4; weglFogCoordfv(coord); -}; break; -case 5401: { // glFogCoorddv +}; break; +case 5401: { // glFogCoorddv GLdouble *coord = (GLdouble *) bp; bp += 8; weglFogCoorddv(coord); -}; break; -case 5402: { // glFogCoordPointer +}; break; +case 5402: { // glFogCoordPointer GLenum *type = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; GLvoid *pointer = (GLvoid *) * (int *) bp; bp += 4; weglFogCoordPointer(*type,*stride,pointer); -}; break; -case 5403: { // glFogCoordPointer +}; break; +case 5403: { // glFogCoordPointer GLenum *type = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; GLvoid *pointer = (GLvoid *) bins[0]->base; weglFogCoordPointer(*type,*stride,pointer); -}; break; -case 5404: { // glSecondaryColor3bv +}; break; +case 5404: { // glSecondaryColor3bv GLbyte *v = (GLbyte *) bp; bp += 1; weglSecondaryColor3bv(v); -}; break; -case 5405: { // glSecondaryColor3dv +}; break; +case 5405: { // glSecondaryColor3dv GLdouble *v = (GLdouble *) bp; bp += 8; weglSecondaryColor3dv(v); -}; break; -case 5406: { // glSecondaryColor3fv +}; break; +case 5406: { // glSecondaryColor3fv GLfloat *v = (GLfloat *) bp; bp += 4; weglSecondaryColor3fv(v); -}; break; -case 5407: { // glSecondaryColor3iv +}; break; +case 5407: { // glSecondaryColor3iv GLint *v = (GLint *) bp; bp += 4; weglSecondaryColor3iv(v); -}; break; -case 5408: { // glSecondaryColor3sv +}; break; +case 5408: { // glSecondaryColor3sv GLshort *v = (GLshort *) bp; bp += 2; weglSecondaryColor3sv(v); -}; break; -case 5409: { // glSecondaryColor3ubv +}; break; +case 5409: { // glSecondaryColor3ubv GLubyte *v = (GLubyte *) bp; bp += 1; weglSecondaryColor3ubv(v); -}; break; -case 5410: { // glSecondaryColor3uiv +}; break; +case 5410: { // glSecondaryColor3uiv GLuint *v = (GLuint *) bp; bp += 4; weglSecondaryColor3uiv(v); -}; break; -case 5411: { // glSecondaryColor3usv +}; break; +case 5411: { // glSecondaryColor3usv GLushort *v = (GLushort *) bp; bp += 2; weglSecondaryColor3usv(v); -}; break; -case 5412: { // glSecondaryColorPointer +}; break; +case 5412: { // glSecondaryColorPointer GLint *size = (GLint *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; GLvoid *pointer = (GLvoid *) * (int *) bp; bp += 4; weglSecondaryColorPointer(*size,*type,*stride,pointer); -}; break; -case 5413: { // glSecondaryColorPointer +}; break; +case 5413: { // glSecondaryColorPointer GLint *size = (GLint *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; GLvoid *pointer = (GLvoid *) bins[0]->base; weglSecondaryColorPointer(*size,*type,*stride,pointer); -}; break; -case 5414: { // glWindowPos2dv +}; break; +case 5414: { // glWindowPos2dv GLdouble *v = (GLdouble *) bp; bp += 8; weglWindowPos2dv(v); -}; break; -case 5415: { // glWindowPos2fv +}; break; +case 5415: { // glWindowPos2fv GLfloat *v = (GLfloat *) bp; bp += 4; weglWindowPos2fv(v); -}; break; -case 5416: { // glWindowPos2iv +}; break; +case 5416: { // glWindowPos2iv GLint *v = (GLint *) bp; bp += 4; weglWindowPos2iv(v); -}; break; -case 5417: { // glWindowPos2sv +}; break; +case 5417: { // glWindowPos2sv GLshort *v = (GLshort *) bp; bp += 2; weglWindowPos2sv(v); -}; break; -case 5418: { // glWindowPos3dv +}; break; +case 5418: { // glWindowPos3dv GLdouble *v = (GLdouble *) bp; bp += 8; weglWindowPos3dv(v); -}; break; -case 5419: { // glWindowPos3fv +}; break; +case 5419: { // glWindowPos3fv GLfloat *v = (GLfloat *) bp; bp += 4; weglWindowPos3fv(v); -}; break; -case 5420: { // glWindowPos3iv +}; break; +case 5420: { // glWindowPos3iv GLint *v = (GLint *) bp; bp += 4; weglWindowPos3iv(v); -}; break; -case 5421: { // glWindowPos3sv +}; break; +case 5421: { // glWindowPos3sv GLshort *v = (GLshort *) bp; bp += 2; weglWindowPos3sv(v); -}; break; -case 5422: { // glGenQueries +}; break; +case 5422: { // glGenQueries GLsizei *n = (GLsizei *) bp; bp += 4; GLuint *ids; ids = (GLuint *) driver_alloc(sizeof(GLuint) * *n); @@ -3131,15 +3131,15 @@ case 5422: { // glGenQueries rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 7 + (*n)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*n)*2); driver_send_term(WXE_DRV_PORT,caller,rt,AP); - driver_free(rt); + driver_free(rt); driver_free(ids); -}; break; -case 5423: { // glDeleteQueries +}; break; +case 5423: { // glDeleteQueries int * idsLen = (int *) bp; bp += 4; GLuint * ids = (GLuint *) bp; bp += (8-((*idsLen*4+4)%8))%8; weglDeleteQueries(*idsLen,ids); -}; break; -case 5424: { // glIsQuery +}; break; +case 5424: { // glIsQuery GLuint *id = (GLuint *) bp; bp += 4; GLboolean result = weglIsQuery(*id); int AP = 0; ErlDrvTermData rt[6]; @@ -3148,17 +3148,17 @@ case 5424: { // glIsQuery rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5425: { // glBeginQuery +}; break; +case 5425: { // glBeginQuery GLenum *target = (GLenum *) bp; bp += 4; GLuint *id = (GLuint *) bp; bp += 4; weglBeginQuery(*target,*id); -}; break; -case 5426: { // glEndQuery +}; break; +case 5426: { // glEndQuery GLenum *target = (GLenum *) bp; bp += 4; weglEndQuery(*target); -}; break; -case 5427: { // glGetQueryiv +}; break; +case 5427: { // glGetQueryiv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint params[1] = {0}; @@ -3169,8 +3169,8 @@ case 5427: { // glGetQueryiv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5428: { // glGetQueryObjectiv +}; break; +case 5428: { // glGetQueryObjectiv GLuint *id = (GLuint *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint params[1] = {0}; @@ -3181,8 +3181,8 @@ case 5428: { // glGetQueryObjectiv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5429: { // glGetQueryObjectuiv +}; break; +case 5429: { // glGetQueryObjectuiv GLuint *id = (GLuint *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLuint params[1] = {0}; @@ -3193,18 +3193,18 @@ case 5429: { // glGetQueryObjectuiv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5430: { // glBindBuffer +}; break; +case 5430: { // glBindBuffer GLenum *target = (GLenum *) bp; bp += 4; GLuint *buffer = (GLuint *) bp; bp += 4; weglBindBuffer(*target,*buffer); -}; break; -case 5431: { // glDeleteBuffers +}; break; +case 5431: { // glDeleteBuffers int * buffersLen = (int *) bp; bp += 4; GLuint * buffers = (GLuint *) bp; bp += (8-((*buffersLen*4+4)%8))%8; weglDeleteBuffers(*buffersLen,buffers); -}; break; -case 5432: { // glGenBuffers +}; break; +case 5432: { // glGenBuffers GLsizei *n = (GLsizei *) bp; bp += 4; GLuint *buffers; buffers = (GLuint *) driver_alloc(sizeof(GLuint) * *n); @@ -3218,10 +3218,10 @@ case 5432: { // glGenBuffers rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 7 + (*n)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*n)*2); driver_send_term(WXE_DRV_PORT,caller,rt,AP); - driver_free(rt); + driver_free(rt); driver_free(buffers); -}; break; -case 5433: { // glIsBuffer +}; break; +case 5433: { // glIsBuffer GLuint *buffer = (GLuint *) bp; bp += 4; GLboolean result = weglIsBuffer(*buffer); int AP = 0; ErlDrvTermData rt[6]; @@ -3230,40 +3230,40 @@ case 5433: { // glIsBuffer rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5434: { // glBufferData +}; break; +case 5434: { // glBufferData GLenum *target = (GLenum *) bp; bp += 4; bp += 4; GLsizeiptr size = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8; GLvoid *data = (GLvoid *) * (int *) bp; bp += 4; GLenum *usage = (GLenum *) bp; bp += 4; weglBufferData(*target,size,data,*usage); -}; break; -case 5435: { // glBufferData +}; break; +case 5435: { // glBufferData GLenum *target = (GLenum *) bp; bp += 4; bp += 4; GLsizeiptr size = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8; GLvoid *data = (GLvoid *) bins[0]->base; GLenum *usage = (GLenum *) bp; bp += 4; weglBufferData(*target,size,data,*usage); -}; break; -case 5436: { // glBufferSubData +}; break; +case 5436: { // glBufferSubData GLenum *target = (GLenum *) bp; bp += 4; bp += 4; GLintptr offset = (GLintptr) * (GLuint64EXT *) bp; bp += 8; GLsizeiptr size = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8; GLvoid *data = (GLvoid *) * (int *) bp; bp += 4; weglBufferSubData(*target,offset,size,data); -}; break; -case 5437: { // glBufferSubData +}; break; +case 5437: { // glBufferSubData GLenum *target = (GLenum *) bp; bp += 4; bp += 4; GLintptr offset = (GLintptr) * (GLuint64EXT *) bp; bp += 8; GLsizeiptr size = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8; GLvoid *data = (GLvoid *) bins[0]->base; weglBufferSubData(*target,offset,size,data); -}; break; -case 5438: { // glGetBufferSubData +}; break; +case 5438: { // glGetBufferSubData GLenum *target = (GLenum *) bp; bp += 4; bp += 4; GLintptr offset = (GLintptr) * (GLuint64EXT *) bp; bp += 8; @@ -3275,8 +3275,8 @@ case 5438: { // glGetBufferSubData rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5439: { // glGetBufferParameteriv +}; break; +case 5439: { // glGetBufferParameteriv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint params[1] = {0}; @@ -3287,53 +3287,53 @@ case 5439: { // glGetBufferParameteriv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5440: { // glBlendEquationSeparate +}; break; +case 5440: { // glBlendEquationSeparate GLenum *modeRGB = (GLenum *) bp; bp += 4; GLenum *modeAlpha = (GLenum *) bp; bp += 4; weglBlendEquationSeparate(*modeRGB,*modeAlpha); -}; break; -case 5441: { // glDrawBuffers +}; break; +case 5441: { // glDrawBuffers int * bufsLen = (int *) bp; bp += 4; GLenum * bufs = (GLenum *) bp; bp += (8-((*bufsLen*4+4)%8))%8; weglDrawBuffers(*bufsLen,bufs); -}; break; -case 5442: { // glStencilOpSeparate +}; break; +case 5442: { // glStencilOpSeparate GLenum *face = (GLenum *) bp; bp += 4; GLenum *sfail = (GLenum *) bp; bp += 4; GLenum *dpfail = (GLenum *) bp; bp += 4; GLenum *dppass = (GLenum *) bp; bp += 4; weglStencilOpSeparate(*face,*sfail,*dpfail,*dppass); -}; break; -case 5443: { // glStencilFuncSeparate +}; break; +case 5443: { // glStencilFuncSeparate GLenum *frontfunc = (GLenum *) bp; bp += 4; GLenum *backfunc = (GLenum *) bp; bp += 4; GLint *ref = (GLint *) bp; bp += 4; GLuint *mask = (GLuint *) bp; bp += 4; weglStencilFuncSeparate(*frontfunc,*backfunc,*ref,*mask); -}; break; -case 5444: { // glStencilMaskSeparate +}; break; +case 5444: { // glStencilMaskSeparate GLenum *face = (GLenum *) bp; bp += 4; GLuint *mask = (GLuint *) bp; bp += 4; weglStencilMaskSeparate(*face,*mask); -}; break; -case 5445: { // glAttachShader +}; break; +case 5445: { // glAttachShader GLuint *program = (GLuint *) bp; bp += 4; GLuint *shader = (GLuint *) bp; bp += 4; weglAttachShader(*program,*shader); -}; break; -case 5446: { // glBindAttribLocation +}; break; +case 5446: { // glBindAttribLocation GLuint *program = (GLuint *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLchar *name = (GLchar *) bp; int nameLen = strlen((char *)name); bp += nameLen+1+((8-((1+nameLen+0)%8))%8); weglBindAttribLocation(*program,*index,name); -}; break; -case 5447: { // glCompileShader +}; break; +case 5447: { // glCompileShader GLuint *shader = (GLuint *) bp; bp += 4; weglCompileShader(*shader); -}; break; -case 5448: { // glCreateProgram +}; break; +case 5448: { // glCreateProgram GLuint result = weglCreateProgram(); int AP = 0; ErlDrvTermData rt[6]; rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); @@ -3341,8 +3341,8 @@ case 5448: { // glCreateProgram rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5449: { // glCreateShader +}; break; +case 5449: { // glCreateShader GLenum *type = (GLenum *) bp; bp += 4; GLuint result = weglCreateShader(*type); int AP = 0; ErlDrvTermData rt[6]; @@ -3351,29 +3351,29 @@ case 5449: { // glCreateShader rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5450: { // glDeleteProgram +}; break; +case 5450: { // glDeleteProgram GLuint *program = (GLuint *) bp; bp += 4; weglDeleteProgram(*program); -}; break; -case 5451: { // glDeleteShader +}; break; +case 5451: { // glDeleteShader GLuint *shader = (GLuint *) bp; bp += 4; weglDeleteShader(*shader); -}; break; -case 5452: { // glDetachShader +}; break; +case 5452: { // glDetachShader GLuint *program = (GLuint *) bp; bp += 4; GLuint *shader = (GLuint *) bp; bp += 4; weglDetachShader(*program,*shader); -}; break; -case 5453: { // glDisableVertexAttribArray +}; break; +case 5453: { // glDisableVertexAttribArray GLuint *index = (GLuint *) bp; bp += 4; weglDisableVertexAttribArray(*index); -}; break; -case 5454: { // glEnableVertexAttribArray +}; break; +case 5454: { // glEnableVertexAttribArray GLuint *index = (GLuint *) bp; bp += 4; weglEnableVertexAttribArray(*index); -}; break; -case 5455: { // glGetActiveAttrib +}; break; +case 5455: { // glGetActiveAttrib GLuint *program = (GLuint *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLsizei *bufSize = (GLsizei *) bp; bp += 4; @@ -3393,8 +3393,8 @@ case 5455: { // glGetActiveAttrib if (AP != 13 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,13); driver_send_term(WXE_DRV_PORT,caller,rt,AP); driver_free(name); -}; break; -case 5456: { // glGetActiveUniform +}; break; +case 5456: { // glGetActiveUniform GLuint *program = (GLuint *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLsizei *bufSize = (GLsizei *) bp; bp += 4; @@ -3414,8 +3414,8 @@ case 5456: { // glGetActiveUniform if (AP != 13 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,13); driver_send_term(WXE_DRV_PORT,caller,rt,AP); driver_free(name); -}; break; -case 5457: { // glGetAttachedShaders +}; break; +case 5457: { // glGetAttachedShaders GLuint *program = (GLuint *) bp; bp += 4; GLsizei *maxCount = (GLsizei *) bp; bp += 4; GLsizei count[1] = {0}; @@ -3431,10 +3431,10 @@ case 5457: { // glGetAttachedShaders rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 7 + (*count)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*count)*2); driver_send_term(WXE_DRV_PORT,caller,rt,AP); - driver_free(rt); + driver_free(rt); driver_free(obj); -}; break; -case 5458: { // glGetAttribLocation +}; break; +case 5458: { // glGetAttribLocation GLuint *program = (GLuint *) bp; bp += 4; GLchar *name = (GLchar *) bp; int nameLen = strlen((char *)name); bp += nameLen+1+((8-((1+nameLen+4)%8))%8); @@ -3445,8 +3445,8 @@ case 5458: { // glGetAttribLocation rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5459: { // glGetProgramiv +}; break; +case 5459: { // glGetProgramiv GLuint *program = (GLuint *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint params[1] = {0}; @@ -3457,8 +3457,8 @@ case 5459: { // glGetProgramiv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5460: { // glGetProgramInfoLog +}; break; +case 5460: { // glGetProgramInfoLog GLuint *program = (GLuint *) bp; bp += 4; GLsizei *bufSize = (GLsizei *) bp; bp += 4; GLsizei length[1] = {0}; @@ -3472,8 +3472,8 @@ case 5460: { // glGetProgramInfoLog if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7); driver_send_term(WXE_DRV_PORT,caller,rt,AP); driver_free(infoLog); -}; break; -case 5461: { // glGetShaderiv +}; break; +case 5461: { // glGetShaderiv GLuint *shader = (GLuint *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint params[1] = {0}; @@ -3484,8 +3484,8 @@ case 5461: { // glGetShaderiv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5462: { // glGetShaderInfoLog +}; break; +case 5462: { // glGetShaderInfoLog GLuint *shader = (GLuint *) bp; bp += 4; GLsizei *bufSize = (GLsizei *) bp; bp += 4; GLsizei length[1] = {0}; @@ -3499,8 +3499,8 @@ case 5462: { // glGetShaderInfoLog if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7); driver_send_term(WXE_DRV_PORT,caller,rt,AP); driver_free(infoLog); -}; break; -case 5463: { // glGetShaderSource +}; break; +case 5463: { // glGetShaderSource GLuint *shader = (GLuint *) bp; bp += 4; GLsizei *bufSize = (GLsizei *) bp; bp += 4; GLsizei length[1] = {0}; @@ -3514,8 +3514,8 @@ case 5463: { // glGetShaderSource if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7); driver_send_term(WXE_DRV_PORT,caller,rt,AP); driver_free(source); -}; break; -case 5464: { // glGetUniformLocation +}; break; +case 5464: { // glGetUniformLocation GLuint *program = (GLuint *) bp; bp += 4; GLchar *name = (GLchar *) bp; int nameLen = strlen((char *)name); bp += nameLen+1+((8-((1+nameLen+4)%8))%8); @@ -3526,8 +3526,8 @@ case 5464: { // glGetUniformLocation rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5465: { // glGetUniformfv +}; break; +case 5465: { // glGetUniformfv GLuint *program = (GLuint *) bp; bp += 4; GLint *location = (GLint *) bp; bp += 4; GLfloat params[16] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; @@ -3556,8 +3556,8 @@ case 5465: { // glGetUniformfv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 38 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,38); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5466: { // glGetUniformiv +}; break; +case 5466: { // glGetUniformiv GLuint *program = (GLuint *) bp; bp += 4; GLint *location = (GLint *) bp; bp += 4; GLint params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; @@ -3585,8 +3585,8 @@ case 5466: { // glGetUniformiv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 38 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,38); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5467: { // glGetVertexAttribdv +}; break; +case 5467: { // glGetVertexAttribdv GLuint *index = (GLuint *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLdouble params[4] = {0.0,0.0,0.0,0.0}; @@ -3602,8 +3602,8 @@ case 5467: { // glGetVertexAttribdv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5468: { // glGetVertexAttribfv +}; break; +case 5468: { // glGetVertexAttribfv GLuint *index = (GLuint *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLfloat params[4] = {0.0,0.0,0.0,0.0}; @@ -3620,8 +3620,8 @@ case 5468: { // glGetVertexAttribfv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5469: { // glGetVertexAttribiv +}; break; +case 5469: { // glGetVertexAttribiv GLuint *index = (GLuint *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint params[4] = {0,0,0,0}; @@ -3637,8 +3637,8 @@ case 5469: { // glGetVertexAttribiv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5470: { // glIsProgram +}; break; +case 5470: { // glIsProgram GLuint *program = (GLuint *) bp; bp += 4; GLboolean result = weglIsProgram(*program); int AP = 0; ErlDrvTermData rt[6]; @@ -3647,8 +3647,8 @@ case 5470: { // glIsProgram rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5471: { // glIsShader +}; break; +case 5471: { // glIsShader GLuint *shader = (GLuint *) bp; bp += 4; GLboolean result = weglIsShader(*shader); int AP = 0; ErlDrvTermData rt[6]; @@ -3657,275 +3657,275 @@ case 5471: { // glIsShader rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5472: { // glLinkProgram +}; break; +case 5472: { // glLinkProgram GLuint *program = (GLuint *) bp; bp += 4; weglLinkProgram(*program); -}; break; -case 5473: { // glShaderSource +}; break; +case 5473: { // glShaderSource GLuint *shader = (GLuint *) bp; bp += 4; int * stringLen = (int *) bp; bp += 4; int * stringTotSize = (int *) bp; bp += 4; GLchar **string; - string = (GLchar **) driver_alloc(sizeof(GLchar *) * *stringLen); + string = (GLchar **) driver_alloc(sizeof(GLchar *) * *stringLen); for(int i=0;i<*stringLen;i++) { string[i] = (GLchar *) bp; bp += 1+strlen(bp);}; bp += (8 - ((0 + *stringTotSize) % 8)) % 8; weglShaderSource(*shader,*stringLen,(const GLchar **) string,NULL); driver_free(string); -}; break; -case 5474: { // glUseProgram +}; break; +case 5474: { // glUseProgram GLuint *program = (GLuint *) bp; bp += 4; weglUseProgram(*program); -}; break; -case 5475: { // glUniform1f +}; break; +case 5475: { // glUniform1f GLint *location = (GLint *) bp; bp += 4; GLfloat *v0 = (GLfloat *) bp; bp += 4; weglUniform1f(*location,*v0); -}; break; -case 5476: { // glUniform2f +}; break; +case 5476: { // glUniform2f GLint *location = (GLint *) bp; bp += 4; GLfloat *v0 = (GLfloat *) bp; bp += 4; GLfloat *v1 = (GLfloat *) bp; bp += 4; weglUniform2f(*location,*v0,*v1); -}; break; -case 5477: { // glUniform3f +}; break; +case 5477: { // glUniform3f GLint *location = (GLint *) bp; bp += 4; GLfloat *v0 = (GLfloat *) bp; bp += 4; GLfloat *v1 = (GLfloat *) bp; bp += 4; GLfloat *v2 = (GLfloat *) bp; bp += 4; weglUniform3f(*location,*v0,*v1,*v2); -}; break; -case 5478: { // glUniform4f +}; break; +case 5478: { // glUniform4f GLint *location = (GLint *) bp; bp += 4; GLfloat *v0 = (GLfloat *) bp; bp += 4; GLfloat *v1 = (GLfloat *) bp; bp += 4; GLfloat *v2 = (GLfloat *) bp; bp += 4; GLfloat *v3 = (GLfloat *) bp; bp += 4; weglUniform4f(*location,*v0,*v1,*v2,*v3); -}; break; -case 5479: { // glUniform1i +}; break; +case 5479: { // glUniform1i GLint *location = (GLint *) bp; bp += 4; GLint *v0 = (GLint *) bp; bp += 4; weglUniform1i(*location,*v0); -}; break; -case 5480: { // glUniform2i +}; break; +case 5480: { // glUniform2i GLint *location = (GLint *) bp; bp += 4; GLint *v0 = (GLint *) bp; bp += 4; GLint *v1 = (GLint *) bp; bp += 4; weglUniform2i(*location,*v0,*v1); -}; break; -case 5481: { // glUniform3i +}; break; +case 5481: { // glUniform3i GLint *location = (GLint *) bp; bp += 4; GLint *v0 = (GLint *) bp; bp += 4; GLint *v1 = (GLint *) bp; bp += 4; GLint *v2 = (GLint *) bp; bp += 4; weglUniform3i(*location,*v0,*v1,*v2); -}; break; -case 5482: { // glUniform4i +}; break; +case 5482: { // glUniform4i GLint *location = (GLint *) bp; bp += 4; GLint *v0 = (GLint *) bp; bp += 4; GLint *v1 = (GLint *) bp; bp += 4; GLint *v2 = (GLint *) bp; bp += 4; GLint *v3 = (GLint *) bp; bp += 4; weglUniform4i(*location,*v0,*v1,*v2,*v3); -}; break; -case 5483: { // glUniform1fv +}; break; +case 5483: { // glUniform1fv GLint *location = (GLint *) bp; bp += 4; int * valueLen = (int *) bp; bp += 4; GLfloat * value = (GLfloat *) bp; bp += (8-((*valueLen*4+0)%8))%8; weglUniform1fv(*location,*valueLen,value); -}; break; -case 5484: { // glUniform2fv +}; break; +case 5484: { // glUniform2fv GLint *location = (GLint *) bp; bp += 4; int *valueLen = (int *) bp; bp += 4; GLfloat * value = (GLfloat *) bp; bp += *valueLen*8; weglUniform2fv(*location,*valueLen,value); -}; break; -case 5485: { // glUniform3fv +}; break; +case 5485: { // glUniform3fv GLint *location = (GLint *) bp; bp += 4; int *valueLen = (int *) bp; bp += 4; GLfloat * value = (GLfloat *) bp; bp += *valueLen*12; weglUniform3fv(*location,*valueLen,value); -}; break; -case 5486: { // glUniform4fv +}; break; +case 5486: { // glUniform4fv GLint *location = (GLint *) bp; bp += 4; int *valueLen = (int *) bp; bp += 4; GLfloat * value = (GLfloat *) bp; bp += *valueLen*16; weglUniform4fv(*location,*valueLen,value); -}; break; -case 5487: { // glUniform1iv +}; break; +case 5487: { // glUniform1iv GLint *location = (GLint *) bp; bp += 4; int * valueLen = (int *) bp; bp += 4; GLint * value = (GLint *) bp; bp += (8-((*valueLen*4+0)%8))%8; weglUniform1iv(*location,*valueLen,value); -}; break; -case 5488: { // glUniform2iv +}; break; +case 5488: { // glUniform2iv GLint *location = (GLint *) bp; bp += 4; int *valueLen = (int *) bp; bp += 4; GLint * value = (GLint *) bp; bp += *valueLen*8; weglUniform2iv(*location,*valueLen,value); -}; break; -case 5489: { // glUniform3iv +}; break; +case 5489: { // glUniform3iv GLint *location = (GLint *) bp; bp += 4; int *valueLen = (int *) bp; bp += 4; GLint * value = (GLint *) bp; bp += *valueLen*12; weglUniform3iv(*location,*valueLen,value); -}; break; -case 5490: { // glUniform4iv +}; break; +case 5490: { // glUniform4iv GLint *location = (GLint *) bp; bp += 4; int *valueLen = (int *) bp; bp += 4; GLint * value = (GLint *) bp; bp += *valueLen*16; weglUniform4iv(*location,*valueLen,value); -}; break; -case 5491: { // glUniformMatrix2fv +}; break; +case 5491: { // glUniformMatrix2fv GLint *location = (GLint *) bp; bp += 4; GLboolean *transpose = (GLboolean *) bp; bp += 1; bp += 3; int *valueLen = (int *) bp; bp += 4; GLfloat * value = (GLfloat *) bp; bp += *valueLen*16; weglUniformMatrix2fv(*location,*valueLen,*transpose,value); -}; break; -case 5492: { // glUniformMatrix3fv +}; break; +case 5492: { // glUniformMatrix3fv GLint *location = (GLint *) bp; bp += 4; GLboolean *transpose = (GLboolean *) bp; bp += 1; bp += 3; int *valueLen = (int *) bp; bp += 4; GLfloat * value = (GLfloat *) bp; bp += *valueLen*36; weglUniformMatrix3fv(*location,*valueLen,*transpose,value); -}; break; -case 5493: { // glUniformMatrix4fv +}; break; +case 5493: { // glUniformMatrix4fv GLint *location = (GLint *) bp; bp += 4; GLboolean *transpose = (GLboolean *) bp; bp += 1; bp += 3; int *valueLen = (int *) bp; bp += 4; GLfloat * value = (GLfloat *) bp; bp += *valueLen*64; weglUniformMatrix4fv(*location,*valueLen,*transpose,value); -}; break; -case 5494: { // glValidateProgram +}; break; +case 5494: { // glValidateProgram GLuint *program = (GLuint *) bp; bp += 4; weglValidateProgram(*program); -}; break; -case 5495: { // glVertexAttrib1dv +}; break; +case 5495: { // glVertexAttrib1dv GLuint *index = (GLuint *) bp; bp += 4; bp += 4; GLdouble *v = (GLdouble *) bp; bp += 8; weglVertexAttrib1dv(*index,v); -}; break; -case 5496: { // glVertexAttrib1fv +}; break; +case 5496: { // glVertexAttrib1fv GLuint *index = (GLuint *) bp; bp += 4; GLfloat *v = (GLfloat *) bp; bp += 4; weglVertexAttrib1fv(*index,v); -}; break; -case 5497: { // glVertexAttrib1sv +}; break; +case 5497: { // glVertexAttrib1sv GLuint *index = (GLuint *) bp; bp += 4; GLshort *v = (GLshort *) bp; bp += 2; weglVertexAttrib1sv(*index,v); -}; break; -case 5498: { // glVertexAttrib2dv +}; break; +case 5498: { // glVertexAttrib2dv GLuint *index = (GLuint *) bp; bp += 4; bp += 4; GLdouble *v = (GLdouble *) bp; bp += 8; weglVertexAttrib2dv(*index,v); -}; break; -case 5499: { // glVertexAttrib2fv +}; break; +case 5499: { // glVertexAttrib2fv GLuint *index = (GLuint *) bp; bp += 4; GLfloat *v = (GLfloat *) bp; bp += 4; weglVertexAttrib2fv(*index,v); -}; break; -case 5500: { // glVertexAttrib2sv +}; break; +case 5500: { // glVertexAttrib2sv GLuint *index = (GLuint *) bp; bp += 4; GLshort *v = (GLshort *) bp; bp += 2; weglVertexAttrib2sv(*index,v); -}; break; -case 5501: { // glVertexAttrib3dv +}; break; +case 5501: { // glVertexAttrib3dv GLuint *index = (GLuint *) bp; bp += 4; bp += 4; GLdouble *v = (GLdouble *) bp; bp += 8; weglVertexAttrib3dv(*index,v); -}; break; -case 5502: { // glVertexAttrib3fv +}; break; +case 5502: { // glVertexAttrib3fv GLuint *index = (GLuint *) bp; bp += 4; GLfloat *v = (GLfloat *) bp; bp += 4; weglVertexAttrib3fv(*index,v); -}; break; -case 5503: { // glVertexAttrib3sv +}; break; +case 5503: { // glVertexAttrib3sv GLuint *index = (GLuint *) bp; bp += 4; GLshort *v = (GLshort *) bp; bp += 2; weglVertexAttrib3sv(*index,v); -}; break; -case 5504: { // glVertexAttrib4Nbv +}; break; +case 5504: { // glVertexAttrib4Nbv GLuint *index = (GLuint *) bp; bp += 4; GLbyte * v = (GLbyte *) bp; bp += 4; weglVertexAttrib4Nbv(*index,v); -}; break; -case 5505: { // glVertexAttrib4Niv +}; break; +case 5505: { // glVertexAttrib4Niv GLuint *index = (GLuint *) bp; bp += 4; GLint * v = (GLint *) bp; bp += 16; weglVertexAttrib4Niv(*index,v); -}; break; -case 5506: { // glVertexAttrib4Nsv +}; break; +case 5506: { // glVertexAttrib4Nsv GLuint *index = (GLuint *) bp; bp += 4; GLshort * v = (GLshort *) bp; bp += 8; weglVertexAttrib4Nsv(*index,v); -}; break; -case 5507: { // glVertexAttrib4Nubv +}; break; +case 5507: { // glVertexAttrib4Nubv GLuint *index = (GLuint *) bp; bp += 4; GLubyte * v = (GLubyte *) bp; bp += 4; weglVertexAttrib4Nubv(*index,v); -}; break; -case 5508: { // glVertexAttrib4Nuiv +}; break; +case 5508: { // glVertexAttrib4Nuiv GLuint *index = (GLuint *) bp; bp += 4; GLuint * v = (GLuint *) bp; bp += 16; weglVertexAttrib4Nuiv(*index,v); -}; break; -case 5509: { // glVertexAttrib4Nusv +}; break; +case 5509: { // glVertexAttrib4Nusv GLuint *index = (GLuint *) bp; bp += 4; GLushort * v = (GLushort *) bp; bp += 8; weglVertexAttrib4Nusv(*index,v); -}; break; -case 5510: { // glVertexAttrib4bv +}; break; +case 5510: { // glVertexAttrib4bv GLuint *index = (GLuint *) bp; bp += 4; GLbyte * v = (GLbyte *) bp; bp += 4; weglVertexAttrib4bv(*index,v); -}; break; -case 5511: { // glVertexAttrib4dv +}; break; +case 5511: { // glVertexAttrib4dv GLuint *index = (GLuint *) bp; bp += 4; bp += 4; GLdouble * v = (GLdouble *) bp; bp += 32; weglVertexAttrib4dv(*index,v); -}; break; -case 5512: { // glVertexAttrib4fv +}; break; +case 5512: { // glVertexAttrib4fv GLuint *index = (GLuint *) bp; bp += 4; GLfloat * v = (GLfloat *) bp; bp += 16; weglVertexAttrib4fv(*index,v); -}; break; -case 5513: { // glVertexAttrib4iv +}; break; +case 5513: { // glVertexAttrib4iv GLuint *index = (GLuint *) bp; bp += 4; GLint * v = (GLint *) bp; bp += 16; weglVertexAttrib4iv(*index,v); -}; break; -case 5514: { // glVertexAttrib4sv +}; break; +case 5514: { // glVertexAttrib4sv GLuint *index = (GLuint *) bp; bp += 4; GLshort * v = (GLshort *) bp; bp += 8; weglVertexAttrib4sv(*index,v); -}; break; -case 5515: { // glVertexAttrib4ubv +}; break; +case 5515: { // glVertexAttrib4ubv GLuint *index = (GLuint *) bp; bp += 4; GLubyte * v = (GLubyte *) bp; bp += 4; weglVertexAttrib4ubv(*index,v); -}; break; -case 5516: { // glVertexAttrib4uiv +}; break; +case 5516: { // glVertexAttrib4uiv GLuint *index = (GLuint *) bp; bp += 4; GLuint * v = (GLuint *) bp; bp += 16; weglVertexAttrib4uiv(*index,v); -}; break; -case 5517: { // glVertexAttrib4usv +}; break; +case 5517: { // glVertexAttrib4usv GLuint *index = (GLuint *) bp; bp += 4; GLushort * v = (GLushort *) bp; bp += 8; weglVertexAttrib4usv(*index,v); -}; break; -case 5518: { // glVertexAttribPointer +}; break; +case 5518: { // glVertexAttribPointer GLuint *index = (GLuint *) bp; bp += 4; GLint *size = (GLint *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; @@ -3934,8 +3934,8 @@ case 5518: { // glVertexAttribPointer GLsizei *stride = (GLsizei *) bp; bp += 4; GLvoid *pointer = (GLvoid *) * (int *) bp; bp += 4; weglVertexAttribPointer(*index,*size,*type,*normalized,*stride,pointer); -}; break; -case 5519: { // glVertexAttribPointer +}; break; +case 5519: { // glVertexAttribPointer GLuint *index = (GLuint *) bp; bp += 4; GLint *size = (GLint *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; @@ -3944,64 +3944,64 @@ case 5519: { // glVertexAttribPointer GLsizei *stride = (GLsizei *) bp; bp += 4; GLvoid *pointer = (GLvoid *) bins[0]->base; weglVertexAttribPointer(*index,*size,*type,*normalized,*stride,pointer); -}; break; -case 5520: { // glUniformMatrix2x3fv +}; break; +case 5520: { // glUniformMatrix2x3fv GLint *location = (GLint *) bp; bp += 4; GLboolean *transpose = (GLboolean *) bp; bp += 1; bp += 3; int *valueLen = (int *) bp; bp += 4; GLfloat * value = (GLfloat *) bp; bp += *valueLen*24; weglUniformMatrix2x3fv(*location,*valueLen,*transpose,value); -}; break; -case 5521: { // glUniformMatrix3x2fv +}; break; +case 5521: { // glUniformMatrix3x2fv GLint *location = (GLint *) bp; bp += 4; GLboolean *transpose = (GLboolean *) bp; bp += 1; bp += 3; int *valueLen = (int *) bp; bp += 4; GLfloat * value = (GLfloat *) bp; bp += *valueLen*24; weglUniformMatrix3x2fv(*location,*valueLen,*transpose,value); -}; break; -case 5522: { // glUniformMatrix2x4fv +}; break; +case 5522: { // glUniformMatrix2x4fv GLint *location = (GLint *) bp; bp += 4; GLboolean *transpose = (GLboolean *) bp; bp += 1; bp += 3; int *valueLen = (int *) bp; bp += 4; GLfloat * value = (GLfloat *) bp; bp += *valueLen*32; weglUniformMatrix2x4fv(*location,*valueLen,*transpose,value); -}; break; -case 5523: { // glUniformMatrix4x2fv +}; break; +case 5523: { // glUniformMatrix4x2fv GLint *location = (GLint *) bp; bp += 4; GLboolean *transpose = (GLboolean *) bp; bp += 1; bp += 3; int *valueLen = (int *) bp; bp += 4; GLfloat * value = (GLfloat *) bp; bp += *valueLen*32; weglUniformMatrix4x2fv(*location,*valueLen,*transpose,value); -}; break; -case 5524: { // glUniformMatrix3x4fv +}; break; +case 5524: { // glUniformMatrix3x4fv GLint *location = (GLint *) bp; bp += 4; GLboolean *transpose = (GLboolean *) bp; bp += 1; bp += 3; int *valueLen = (int *) bp; bp += 4; GLfloat * value = (GLfloat *) bp; bp += *valueLen*48; weglUniformMatrix3x4fv(*location,*valueLen,*transpose,value); -}; break; -case 5525: { // glUniformMatrix4x3fv +}; break; +case 5525: { // glUniformMatrix4x3fv GLint *location = (GLint *) bp; bp += 4; GLboolean *transpose = (GLboolean *) bp; bp += 1; bp += 3; int *valueLen = (int *) bp; bp += 4; GLfloat * value = (GLfloat *) bp; bp += *valueLen*48; weglUniformMatrix4x3fv(*location,*valueLen,*transpose,value); -}; break; -case 5526: { // glColorMaski +}; break; +case 5526: { // glColorMaski GLuint *index = (GLuint *) bp; bp += 4; GLboolean *r = (GLboolean *) bp; bp += 1; GLboolean *g = (GLboolean *) bp; bp += 1; GLboolean *b = (GLboolean *) bp; bp += 1; GLboolean *a = (GLboolean *) bp; bp += 1; weglColorMaski(*index,*r,*g,*b,*a); -}; break; -case 5527: { // glGetBooleani_v +}; break; +case 5527: { // glGetBooleani_v GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLboolean data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; @@ -4029,8 +4029,8 @@ case 5527: { // glGetBooleani_v rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 39 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,39); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5528: { // glGetIntegeri_v +}; break; +case 5528: { // glGetIntegeri_v GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLint data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; @@ -4058,18 +4058,18 @@ case 5528: { // glGetIntegeri_v rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 39 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,39); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5529: { // glEnablei +}; break; +case 5529: { // glEnablei GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; weglEnablei(*target,*index); -}; break; -case 5530: { // glDisablei +}; break; +case 5530: { // glDisablei GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; weglDisablei(*target,*index); -}; break; -case 5531: { // glIsEnabledi +}; break; +case 5531: { // glIsEnabledi GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLboolean result = weglIsEnabledi(*target,*index); @@ -4079,15 +4079,15 @@ case 5531: { // glIsEnabledi rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5532: { // glBeginTransformFeedback +}; break; +case 5532: { // glBeginTransformFeedback GLenum *primitiveMode = (GLenum *) bp; bp += 4; weglBeginTransformFeedback(*primitiveMode); -}; break; -case 5533: { // glEndTransformFeedback +}; break; +case 5533: { // glEndTransformFeedback weglEndTransformFeedback(); -}; break; -case 5534: { // glBindBufferRange +}; break; +case 5534: { // glBindBufferRange GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLuint *buffer = (GLuint *) bp; bp += 4; @@ -4095,27 +4095,27 @@ case 5534: { // glBindBufferRange GLintptr offset = (GLintptr) * (GLuint64EXT *) bp; bp += 8; GLsizeiptr size = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8; weglBindBufferRange(*target,*index,*buffer,offset,size); -}; break; -case 5535: { // glBindBufferBase +}; break; +case 5535: { // glBindBufferBase GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLuint *buffer = (GLuint *) bp; bp += 4; weglBindBufferBase(*target,*index,*buffer); -}; break; -case 5536: { // glTransformFeedbackVaryings +}; break; +case 5536: { // glTransformFeedbackVaryings GLuint *program = (GLuint *) bp; bp += 4; int * varyingsLen = (int *) bp; bp += 4; int * varyingsTotSize = (int *) bp; bp += 4; GLchar **varyings; - varyings = (GLchar **) driver_alloc(sizeof(GLchar *) * *varyingsLen); + varyings = (GLchar **) driver_alloc(sizeof(GLchar *) * *varyingsLen); for(int i=0;i<*varyingsLen;i++) { varyings[i] = (GLchar *) bp; bp += 1+strlen(bp);}; bp += (8 - ((0 + *varyingsTotSize) % 8)) % 8; GLenum *bufferMode = (GLenum *) bp; bp += 4; weglTransformFeedbackVaryings(*program,*varyingsLen,(const GLchar **) varyings,*bufferMode); driver_free(varyings); -}; break; -case 5537: { // glGetTransformFeedbackVarying +}; break; +case 5537: { // glGetTransformFeedbackVarying GLuint *program = (GLuint *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLsizei *bufSize = (GLsizei *) bp; bp += 4; @@ -4135,37 +4135,37 @@ case 5537: { // glGetTransformFeedbackVarying if (AP != 13 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,13); driver_send_term(WXE_DRV_PORT,caller,rt,AP); driver_free(name); -}; break; -case 5538: { // glClampColor +}; break; +case 5538: { // glClampColor GLenum *target = (GLenum *) bp; bp += 4; GLenum *clamp = (GLenum *) bp; bp += 4; weglClampColor(*target,*clamp); -}; break; -case 5539: { // glBeginConditionalRender +}; break; +case 5539: { // glBeginConditionalRender GLuint *id = (GLuint *) bp; bp += 4; GLenum *mode = (GLenum *) bp; bp += 4; weglBeginConditionalRender(*id,*mode); -}; break; -case 5540: { // glEndConditionalRender +}; break; +case 5540: { // glEndConditionalRender weglEndConditionalRender(); -}; break; -case 5541: { // glVertexAttribIPointer +}; break; +case 5541: { // glVertexAttribIPointer GLuint *index = (GLuint *) bp; bp += 4; GLint *size = (GLint *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; GLvoid *pointer = (GLvoid *) * (int *) bp; bp += 4; weglVertexAttribIPointer(*index,*size,*type,*stride,pointer); -}; break; -case 5542: { // glVertexAttribIPointer +}; break; +case 5542: { // glVertexAttribIPointer GLuint *index = (GLuint *) bp; bp += 4; GLint *size = (GLint *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; GLvoid *pointer = (GLvoid *) bins[0]->base; weglVertexAttribIPointer(*index,*size,*type,*stride,pointer); -}; break; -case 5543: { // glGetVertexAttribIiv +}; break; +case 5543: { // glGetVertexAttribIiv GLuint *index = (GLuint *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint params[4] = {0,0,0,0}; @@ -4181,8 +4181,8 @@ case 5543: { // glGetVertexAttribIiv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5544: { // glGetVertexAttribIuiv +}; break; +case 5544: { // glGetVertexAttribIuiv GLuint *index = (GLuint *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLuint params[4] = {0,0,0,0}; @@ -4198,8 +4198,8 @@ case 5544: { // glGetVertexAttribIuiv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5545: { // glGetUniformuiv +}; break; +case 5545: { // glGetUniformuiv GLuint *program = (GLuint *) bp; bp += 4; GLint *location = (GLint *) bp; bp += 4; GLuint params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; @@ -4227,15 +4227,15 @@ case 5545: { // glGetUniformuiv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 38 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,38); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5546: { // glBindFragDataLocation +}; break; +case 5546: { // glBindFragDataLocation GLuint *program = (GLuint *) bp; bp += 4; GLuint *color = (GLuint *) bp; bp += 4; GLchar *name = (GLchar *) bp; int nameLen = strlen((char *)name); bp += nameLen+1+((8-((1+nameLen+0)%8))%8); weglBindFragDataLocation(*program,*color,name); -}; break; -case 5547: { // glGetFragDataLocation +}; break; +case 5547: { // glGetFragDataLocation GLuint *program = (GLuint *) bp; bp += 4; GLchar *name = (GLchar *) bp; int nameLen = strlen((char *)name); bp += nameLen+1+((8-((1+nameLen+4)%8))%8); @@ -4246,72 +4246,72 @@ case 5547: { // glGetFragDataLocation rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5548: { // glUniform1ui +}; break; +case 5548: { // glUniform1ui GLint *location = (GLint *) bp; bp += 4; GLuint *v0 = (GLuint *) bp; bp += 4; weglUniform1ui(*location,*v0); -}; break; -case 5549: { // glUniform2ui +}; break; +case 5549: { // glUniform2ui GLint *location = (GLint *) bp; bp += 4; GLuint *v0 = (GLuint *) bp; bp += 4; GLuint *v1 = (GLuint *) bp; bp += 4; weglUniform2ui(*location,*v0,*v1); -}; break; -case 5550: { // glUniform3ui +}; break; +case 5550: { // glUniform3ui GLint *location = (GLint *) bp; bp += 4; GLuint *v0 = (GLuint *) bp; bp += 4; GLuint *v1 = (GLuint *) bp; bp += 4; GLuint *v2 = (GLuint *) bp; bp += 4; weglUniform3ui(*location,*v0,*v1,*v2); -}; break; -case 5551: { // glUniform4ui +}; break; +case 5551: { // glUniform4ui GLint *location = (GLint *) bp; bp += 4; GLuint *v0 = (GLuint *) bp; bp += 4; GLuint *v1 = (GLuint *) bp; bp += 4; GLuint *v2 = (GLuint *) bp; bp += 4; GLuint *v3 = (GLuint *) bp; bp += 4; weglUniform4ui(*location,*v0,*v1,*v2,*v3); -}; break; -case 5552: { // glUniform1uiv +}; break; +case 5552: { // glUniform1uiv GLint *location = (GLint *) bp; bp += 4; int * valueLen = (int *) bp; bp += 4; GLuint * value = (GLuint *) bp; bp += (8-((*valueLen*4+0)%8))%8; weglUniform1uiv(*location,*valueLen,value); -}; break; -case 5553: { // glUniform2uiv +}; break; +case 5553: { // glUniform2uiv GLint *location = (GLint *) bp; bp += 4; int *valueLen = (int *) bp; bp += 4; GLuint * value = (GLuint *) bp; bp += *valueLen*8; weglUniform2uiv(*location,*valueLen,value); -}; break; -case 5554: { // glUniform3uiv +}; break; +case 5554: { // glUniform3uiv GLint *location = (GLint *) bp; bp += 4; int *valueLen = (int *) bp; bp += 4; GLuint * value = (GLuint *) bp; bp += *valueLen*12; weglUniform3uiv(*location,*valueLen,value); -}; break; -case 5555: { // glUniform4uiv +}; break; +case 5555: { // glUniform4uiv GLint *location = (GLint *) bp; bp += 4; int *valueLen = (int *) bp; bp += 4; GLuint * value = (GLuint *) bp; bp += *valueLen*16; weglUniform4uiv(*location,*valueLen,value); -}; break; -case 5556: { // glTexParameterIiv +}; break; +case 5556: { // glTexParameterIiv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; int *paramsLen = (int *) bp; bp += 4; GLint *params = (GLint *) bp; bp += *paramsLen*4+((*paramsLen)+1)%2*4; weglTexParameterIiv(*target,*pname,params); -}; break; -case 5557: { // glTexParameterIuiv +}; break; +case 5557: { // glTexParameterIuiv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; int *paramsLen = (int *) bp; bp += 4; GLuint *params = (GLuint *) bp; bp += *paramsLen*4+((*paramsLen)+1)%2*4; weglTexParameterIuiv(*target,*pname,params); -}; break; -case 5558: { // glGetTexParameterIiv +}; break; +case 5558: { // glGetTexParameterIiv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint params[4] = {0,0,0,0}; @@ -4327,8 +4327,8 @@ case 5558: { // glGetTexParameterIiv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5559: { // glGetTexParameterIuiv +}; break; +case 5559: { // glGetTexParameterIuiv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLuint params[4] = {0,0,0,0}; @@ -4344,36 +4344,36 @@ case 5559: { // glGetTexParameterIuiv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5560: { // glClearBufferiv +}; break; +case 5560: { // glClearBufferiv GLenum *buffer = (GLenum *) bp; bp += 4; GLint *drawbuffer = (GLint *) bp; bp += 4; int *valueLen = (int *) bp; bp += 4; GLint *value = (GLint *) bp; bp += *valueLen*4+((*valueLen)+1)%2*4; weglClearBufferiv(*buffer,*drawbuffer,value); -}; break; -case 5561: { // glClearBufferuiv +}; break; +case 5561: { // glClearBufferuiv GLenum *buffer = (GLenum *) bp; bp += 4; GLint *drawbuffer = (GLint *) bp; bp += 4; int *valueLen = (int *) bp; bp += 4; GLuint *value = (GLuint *) bp; bp += *valueLen*4+((*valueLen)+1)%2*4; weglClearBufferuiv(*buffer,*drawbuffer,value); -}; break; -case 5562: { // glClearBufferfv +}; break; +case 5562: { // glClearBufferfv GLenum *buffer = (GLenum *) bp; bp += 4; GLint *drawbuffer = (GLint *) bp; bp += 4; int *valueLen = (int *) bp; bp += 4; GLfloat *value = (GLfloat *) bp; bp += *valueLen*4+((*valueLen)+1)%2*4; weglClearBufferfv(*buffer,*drawbuffer,value); -}; break; -case 5563: { // glClearBufferfi +}; break; +case 5563: { // glClearBufferfi GLenum *buffer = (GLenum *) bp; bp += 4; GLint *drawbuffer = (GLint *) bp; bp += 4; GLfloat *depth = (GLfloat *) bp; bp += 4; GLint *stencil = (GLint *) bp; bp += 4; weglClearBufferfi(*buffer,*drawbuffer,*depth,*stencil); -}; break; -case 5564: { // glGetStringi +}; break; +case 5564: { // glGetStringi GLenum *name = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; const GLubyte * result = weglGetStringi(*name,*index); @@ -4383,197 +4383,197 @@ case 5564: { // glGetStringi rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5565: { // glVertexAttribI1iv +}; break; +case 5565: { // glVertexAttribI1iv GLuint *index = (GLuint *) bp; bp += 4; GLint *v = (GLint *) bp; bp += 4; weglVertexAttribI1iv(*index,v); -}; break; -case 5566: { // glVertexAttribI2iv +}; break; +case 5566: { // glVertexAttribI2iv GLuint *index = (GLuint *) bp; bp += 4; GLint *v = (GLint *) bp; bp += 4; weglVertexAttribI2iv(*index,v); -}; break; -case 5567: { // glVertexAttribI3iv +}; break; +case 5567: { // glVertexAttribI3iv GLuint *index = (GLuint *) bp; bp += 4; GLint *v = (GLint *) bp; bp += 4; weglVertexAttribI3iv(*index,v); -}; break; -case 5568: { // glVertexAttribI4iv +}; break; +case 5568: { // glVertexAttribI4iv GLuint *index = (GLuint *) bp; bp += 4; GLint * v = (GLint *) bp; bp += 16; weglVertexAttribI4iv(*index,v); -}; break; -case 5569: { // glVertexAttribI1uiv +}; break; +case 5569: { // glVertexAttribI1uiv GLuint *index = (GLuint *) bp; bp += 4; GLuint *v = (GLuint *) bp; bp += 4; weglVertexAttribI1uiv(*index,v); -}; break; -case 5570: { // glVertexAttribI2uiv +}; break; +case 5570: { // glVertexAttribI2uiv GLuint *index = (GLuint *) bp; bp += 4; GLuint *v = (GLuint *) bp; bp += 4; weglVertexAttribI2uiv(*index,v); -}; break; -case 5571: { // glVertexAttribI3uiv +}; break; +case 5571: { // glVertexAttribI3uiv GLuint *index = (GLuint *) bp; bp += 4; GLuint *v = (GLuint *) bp; bp += 4; weglVertexAttribI3uiv(*index,v); -}; break; -case 5572: { // glVertexAttribI4uiv +}; break; +case 5572: { // glVertexAttribI4uiv GLuint *index = (GLuint *) bp; bp += 4; GLuint * v = (GLuint *) bp; bp += 16; weglVertexAttribI4uiv(*index,v); -}; break; -case 5573: { // glVertexAttribI4bv +}; break; +case 5573: { // glVertexAttribI4bv GLuint *index = (GLuint *) bp; bp += 4; GLbyte * v = (GLbyte *) bp; bp += 4; weglVertexAttribI4bv(*index,v); -}; break; -case 5574: { // glVertexAttribI4sv +}; break; +case 5574: { // glVertexAttribI4sv GLuint *index = (GLuint *) bp; bp += 4; GLshort * v = (GLshort *) bp; bp += 8; weglVertexAttribI4sv(*index,v); -}; break; -case 5575: { // glVertexAttribI4ubv +}; break; +case 5575: { // glVertexAttribI4ubv GLuint *index = (GLuint *) bp; bp += 4; GLubyte * v = (GLubyte *) bp; bp += 4; weglVertexAttribI4ubv(*index,v); -}; break; -case 5576: { // glVertexAttribI4usv +}; break; +case 5576: { // glVertexAttribI4usv GLuint *index = (GLuint *) bp; bp += 4; GLushort * v = (GLushort *) bp; bp += 8; weglVertexAttribI4usv(*index,v); -}; break; -case 5577: { // glDrawArraysInstanced +}; break; +case 5577: { // glDrawArraysInstanced GLenum *mode = (GLenum *) bp; bp += 4; GLint *first = (GLint *) bp; bp += 4; GLsizei *count = (GLsizei *) bp; bp += 4; GLsizei *primcount = (GLsizei *) bp; bp += 4; weglDrawArraysInstanced(*mode,*first,*count,*primcount); -}; break; -case 5578: { // glDrawElementsInstanced +}; break; +case 5578: { // glDrawElementsInstanced GLenum *mode = (GLenum *) bp; bp += 4; GLsizei *count = (GLsizei *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; GLvoid *indices = (GLvoid *) * (int *) bp; bp += 4; GLsizei *primcount = (GLsizei *) bp; bp += 4; weglDrawElementsInstanced(*mode,*count,*type,indices,*primcount); -}; break; -case 5579: { // glDrawElementsInstanced +}; break; +case 5579: { // glDrawElementsInstanced GLenum *mode = (GLenum *) bp; bp += 4; GLsizei *count = (GLsizei *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; GLvoid *indices = (GLvoid *) bins[0]->base; GLsizei *primcount = (GLsizei *) bp; bp += 4; weglDrawElementsInstanced(*mode,*count,*type,indices,*primcount); -}; break; -case 5580: { // glTexBuffer +}; break; +case 5580: { // glTexBuffer GLenum *target = (GLenum *) bp; bp += 4; GLenum *internalformat = (GLenum *) bp; bp += 4; GLuint *buffer = (GLuint *) bp; bp += 4; weglTexBuffer(*target,*internalformat,*buffer); -}; break; -case 5581: { // glPrimitiveRestartIndex +}; break; +case 5581: { // glPrimitiveRestartIndex GLuint *index = (GLuint *) bp; bp += 4; weglPrimitiveRestartIndex(*index); -}; break; -case 5582: { // glLoadTransposeMatrixfARB +}; break; +case 5582: { // glLoadTransposeMatrixfARB GLfloat * m = (GLfloat *) bp; bp += 64; weglLoadTransposeMatrixfARB(m); -}; break; -case 5583: { // glLoadTransposeMatrixdARB +}; break; +case 5583: { // glLoadTransposeMatrixdARB GLdouble * m = (GLdouble *) bp; bp += 128; weglLoadTransposeMatrixdARB(m); -}; break; -case 5584: { // glMultTransposeMatrixfARB +}; break; +case 5584: { // glMultTransposeMatrixfARB GLfloat * m = (GLfloat *) bp; bp += 64; weglMultTransposeMatrixfARB(m); -}; break; -case 5585: { // glMultTransposeMatrixdARB +}; break; +case 5585: { // glMultTransposeMatrixdARB GLdouble * m = (GLdouble *) bp; bp += 128; weglMultTransposeMatrixdARB(m); -}; break; -case 5586: { // glWeightbvARB +}; break; +case 5586: { // glWeightbvARB int * weightsLen = (int *) bp; bp += 4; GLbyte * weights = (GLbyte *) bp; bp += (8-((*weightsLen*1+4)%8))%8; weglWeightbvARB(*weightsLen,weights); -}; break; -case 5587: { // glWeightsvARB +}; break; +case 5587: { // glWeightsvARB int * weightsLen = (int *) bp; bp += 4; GLshort * weights = (GLshort *) bp; bp += (8-((*weightsLen*2+4)%8))%8; weglWeightsvARB(*weightsLen,weights); -}; break; -case 5588: { // glWeightivARB +}; break; +case 5588: { // glWeightivARB int * weightsLen = (int *) bp; bp += 4; GLint * weights = (GLint *) bp; bp += (8-((*weightsLen*4+4)%8))%8; weglWeightivARB(*weightsLen,weights); -}; break; -case 5589: { // glWeightfvARB +}; break; +case 5589: { // glWeightfvARB int * weightsLen = (int *) bp; bp += 4; GLfloat * weights = (GLfloat *) bp; bp += (8-((*weightsLen*4+4)%8))%8; weglWeightfvARB(*weightsLen,weights); -}; break; -case 5590: { // glWeightdvARB +}; break; +case 5590: { // glWeightdvARB int * weightsLen = (int *) bp; bp += 8; GLdouble * weights = (GLdouble *) bp; bp += (8-((*weightsLen*8+0)%8))%8; weglWeightdvARB(*weightsLen,weights); -}; break; -case 5591: { // glWeightubvARB +}; break; +case 5591: { // glWeightubvARB int * weightsLen = (int *) bp; bp += 4; GLubyte * weights = (GLubyte *) bp; bp += (8-((*weightsLen*1+4)%8))%8; weglWeightubvARB(*weightsLen,weights); -}; break; -case 5592: { // glWeightusvARB +}; break; +case 5592: { // glWeightusvARB int * weightsLen = (int *) bp; bp += 4; GLushort * weights = (GLushort *) bp; bp += (8-((*weightsLen*2+4)%8))%8; weglWeightusvARB(*weightsLen,weights); -}; break; -case 5593: { // glWeightuivARB +}; break; +case 5593: { // glWeightuivARB int * weightsLen = (int *) bp; bp += 4; GLuint * weights = (GLuint *) bp; bp += (8-((*weightsLen*4+4)%8))%8; weglWeightuivARB(*weightsLen,weights); -}; break; -case 5594: { // glVertexBlendARB +}; break; +case 5594: { // glVertexBlendARB GLint *count = (GLint *) bp; bp += 4; weglVertexBlendARB(*count); -}; break; -case 5595: { // glCurrentPaletteMatrixARB +}; break; +case 5595: { // glCurrentPaletteMatrixARB GLint *index = (GLint *) bp; bp += 4; weglCurrentPaletteMatrixARB(*index); -}; break; -case 5596: { // glMatrixIndexubvARB +}; break; +case 5596: { // glMatrixIndexubvARB int * indicesLen = (int *) bp; bp += 4; GLubyte * indices = (GLubyte *) bp; bp += (8-((*indicesLen*1+4)%8))%8; weglMatrixIndexubvARB(*indicesLen,indices); -}; break; -case 5597: { // glMatrixIndexusvARB +}; break; +case 5597: { // glMatrixIndexusvARB int * indicesLen = (int *) bp; bp += 4; GLushort * indices = (GLushort *) bp; bp += (8-((*indicesLen*2+4)%8))%8; weglMatrixIndexusvARB(*indicesLen,indices); -}; break; -case 5598: { // glMatrixIndexuivARB +}; break; +case 5598: { // glMatrixIndexuivARB int * indicesLen = (int *) bp; bp += 4; GLuint * indices = (GLuint *) bp; bp += (8-((*indicesLen*4+4)%8))%8; weglMatrixIndexuivARB(*indicesLen,indices); -}; break; -case 5599: { // glProgramStringARB +}; break; +case 5599: { // glProgramStringARB GLenum *target = (GLenum *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLvoid *string = (GLvoid *) bp; int stringLen = strlen((char *)string); bp += stringLen+1+((8-((1+stringLen+0)%8))%8); weglProgramStringARB(*target,*format,stringLen,string); -}; break; -case 5600: { // glBindProgramARB +}; break; +case 5600: { // glBindProgramARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *program = (GLuint *) bp; bp += 4; weglBindProgramARB(*target,*program); -}; break; -case 5601: { // glDeleteProgramsARB +}; break; +case 5601: { // glDeleteProgramsARB int * programsLen = (int *) bp; bp += 4; GLuint * programs = (GLuint *) bp; bp += (8-((*programsLen*4+4)%8))%8; weglDeleteProgramsARB(*programsLen,programs); -}; break; -case 5602: { // glGenProgramsARB +}; break; +case 5602: { // glGenProgramsARB GLsizei *n = (GLsizei *) bp; bp += 4; GLuint *programs; programs = (GLuint *) driver_alloc(sizeof(GLuint) * *n); @@ -4587,10 +4587,10 @@ case 5602: { // glGenProgramsARB rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 7 + (*n)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*n)*2); driver_send_term(WXE_DRV_PORT,caller,rt,AP); - driver_free(rt); + driver_free(rt); driver_free(programs); -}; break; -case 5603: { // glProgramEnvParameter4dARB +}; break; +case 5603: { // glProgramEnvParameter4dARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLdouble *x = (GLdouble *) bp; bp += 8; @@ -4598,14 +4598,14 @@ case 5603: { // glProgramEnvParameter4dARB GLdouble *z = (GLdouble *) bp; bp += 8; GLdouble *w = (GLdouble *) bp; bp += 8; weglProgramEnvParameter4dARB(*target,*index,*x,*y,*z,*w); -}; break; -case 5604: { // glProgramEnvParameter4dvARB +}; break; +case 5604: { // glProgramEnvParameter4dvARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLdouble * params = (GLdouble *) bp; bp += 32; weglProgramEnvParameter4dvARB(*target,*index,params); -}; break; -case 5605: { // glProgramEnvParameter4fARB +}; break; +case 5605: { // glProgramEnvParameter4fARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLfloat *x = (GLfloat *) bp; bp += 4; @@ -4613,14 +4613,14 @@ case 5605: { // glProgramEnvParameter4fARB GLfloat *z = (GLfloat *) bp; bp += 4; GLfloat *w = (GLfloat *) bp; bp += 4; weglProgramEnvParameter4fARB(*target,*index,*x,*y,*z,*w); -}; break; -case 5606: { // glProgramEnvParameter4fvARB +}; break; +case 5606: { // glProgramEnvParameter4fvARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLfloat * params = (GLfloat *) bp; bp += 16; weglProgramEnvParameter4fvARB(*target,*index,params); -}; break; -case 5607: { // glProgramLocalParameter4dARB +}; break; +case 5607: { // glProgramLocalParameter4dARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLdouble *x = (GLdouble *) bp; bp += 8; @@ -4628,14 +4628,14 @@ case 5607: { // glProgramLocalParameter4dARB GLdouble *z = (GLdouble *) bp; bp += 8; GLdouble *w = (GLdouble *) bp; bp += 8; weglProgramLocalParameter4dARB(*target,*index,*x,*y,*z,*w); -}; break; -case 5608: { // glProgramLocalParameter4dvARB +}; break; +case 5608: { // glProgramLocalParameter4dvARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLdouble * params = (GLdouble *) bp; bp += 32; weglProgramLocalParameter4dvARB(*target,*index,params); -}; break; -case 5609: { // glProgramLocalParameter4fARB +}; break; +case 5609: { // glProgramLocalParameter4fARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLfloat *x = (GLfloat *) bp; bp += 4; @@ -4643,14 +4643,14 @@ case 5609: { // glProgramLocalParameter4fARB GLfloat *z = (GLfloat *) bp; bp += 4; GLfloat *w = (GLfloat *) bp; bp += 4; weglProgramLocalParameter4fARB(*target,*index,*x,*y,*z,*w); -}; break; -case 5610: { // glProgramLocalParameter4fvARB +}; break; +case 5610: { // glProgramLocalParameter4fvARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLfloat * params = (GLfloat *) bp; bp += 16; weglProgramLocalParameter4fvARB(*target,*index,params); -}; break; -case 5611: { // glGetProgramEnvParameterdvARB +}; break; +case 5611: { // glGetProgramEnvParameterdvARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLdouble params[4] = {0.0,0.0,0.0,0.0}; @@ -4666,8 +4666,8 @@ case 5611: { // glGetProgramEnvParameterdvARB rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5612: { // glGetProgramEnvParameterfvARB +}; break; +case 5612: { // glGetProgramEnvParameterfvARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLfloat params[4] = {0.0,0.0,0.0,0.0}; @@ -4684,8 +4684,8 @@ case 5612: { // glGetProgramEnvParameterfvARB rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5613: { // glGetProgramLocalParameterdvARB +}; break; +case 5613: { // glGetProgramLocalParameterdvARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLdouble params[4] = {0.0,0.0,0.0,0.0}; @@ -4701,8 +4701,8 @@ case 5613: { // glGetProgramLocalParameterdvARB rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5614: { // glGetProgramLocalParameterfvARB +}; break; +case 5614: { // glGetProgramLocalParameterfvARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLfloat params[4] = {0.0,0.0,0.0,0.0}; @@ -4719,8 +4719,8 @@ case 5614: { // glGetProgramLocalParameterfvARB rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5615: { // glGetProgramStringARB +}; break; +case 5615: { // glGetProgramStringARB GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLvoid *string = (GLvoid *) bins[0]->base; @@ -4730,12 +4730,12 @@ case 5615: { // glGetProgramStringARB rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5616: { // glDeleteObjectARB +}; break; +case 5616: { // glDeleteObjectARB GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; weglDeleteObjectARB(obj); -}; break; -case 5617: { // glGetHandleARB +}; break; +case 5617: { // glGetHandleARB GLenum *pname = (GLenum *) bp; bp += 4; GLhandleARB result = weglGetHandleARB(*pname); int AP = 0; ErlDrvTermData rt[6]; @@ -4744,13 +4744,13 @@ case 5617: { // glGetHandleARB rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5618: { // glDetachObjectARB +}; break; +case 5618: { // glDetachObjectARB GLhandleARB containerObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLhandleARB attachedObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; weglDetachObjectARB(containerObj,attachedObj); -}; break; -case 5619: { // glCreateShaderObjectARB +}; break; +case 5619: { // glCreateShaderObjectARB GLenum *shaderType = (GLenum *) bp; bp += 4; GLhandleARB result = weglCreateShaderObjectARB(*shaderType); int AP = 0; ErlDrvTermData rt[6]; @@ -4759,24 +4759,24 @@ case 5619: { // glCreateShaderObjectARB rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5620: { // glShaderSourceARB +}; break; +case 5620: { // glShaderSourceARB GLhandleARB shaderObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; int * stringLen = (int *) bp; bp += 4; int * stringTotSize = (int *) bp; bp += 4; GLchar **string; - string = (GLchar **) driver_alloc(sizeof(GLchar *) * *stringLen); + string = (GLchar **) driver_alloc(sizeof(GLchar *) * *stringLen); for(int i=0;i<*stringLen;i++) { string[i] = (GLchar *) bp; bp += 1+strlen(bp);}; bp += (8 - ((4 + *stringTotSize) % 8)) % 8; weglShaderSourceARB(shaderObj,*stringLen,(const GLchar **) string,NULL); driver_free(string); -}; break; -case 5621: { // glCompileShaderARB +}; break; +case 5621: { // glCompileShaderARB GLhandleARB shaderObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; weglCompileShaderARB(shaderObj); -}; break; -case 5622: { // glCreateProgramObjectARB +}; break; +case 5622: { // glCreateProgramObjectARB GLhandleARB result = weglCreateProgramObjectARB(); int AP = 0; ErlDrvTermData rt[6]; rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); @@ -4784,25 +4784,25 @@ case 5622: { // glCreateProgramObjectARB rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5623: { // glAttachObjectARB +}; break; +case 5623: { // glAttachObjectARB GLhandleARB containerObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; weglAttachObjectARB(containerObj,obj); -}; break; -case 5624: { // glLinkProgramARB +}; break; +case 5624: { // glLinkProgramARB GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; weglLinkProgramARB(programObj); -}; break; -case 5625: { // glUseProgramObjectARB +}; break; +case 5625: { // glUseProgramObjectARB GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; weglUseProgramObjectARB(programObj); -}; break; -case 5626: { // glValidateProgramARB +}; break; +case 5626: { // glValidateProgramARB GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; weglValidateProgramARB(programObj); -}; break; -case 5627: { // glGetObjectParameterfvARB +}; break; +case 5627: { // glGetObjectParameterfvARB GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLenum *pname = (GLenum *) bp; bp += 4; GLfloat params[1] = {0.0}; @@ -4814,8 +4814,8 @@ case 5627: { // glGetObjectParameterfvARB rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5628: { // glGetObjectParameterivARB +}; break; +case 5628: { // glGetObjectParameterivARB GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLenum *pname = (GLenum *) bp; bp += 4; GLint params[1] = {0}; @@ -4826,8 +4826,8 @@ case 5628: { // glGetObjectParameterivARB rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5629: { // glGetInfoLogARB +}; break; +case 5629: { // glGetInfoLogARB GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLsizei *maxLength = (GLsizei *) bp; bp += 4; GLsizei length[1] = {0}; @@ -4841,8 +4841,8 @@ case 5629: { // glGetInfoLogARB if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7); driver_send_term(WXE_DRV_PORT,caller,rt,AP); driver_free(infoLog); -}; break; -case 5630: { // glGetAttachedObjectsARB +}; break; +case 5630: { // glGetAttachedObjectsARB GLhandleARB containerObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLsizei *maxCount = (GLsizei *) bp; bp += 4; GLsizei count[1] = {0}; @@ -4858,10 +4858,10 @@ case 5630: { // glGetAttachedObjectsARB rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 7 + (*count)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*count)*2); driver_send_term(WXE_DRV_PORT,caller,rt,AP); - driver_free(rt); + driver_free(rt); driver_free(obj); -}; break; -case 5631: { // glGetUniformLocationARB +}; break; +case 5631: { // glGetUniformLocationARB GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLchar *name = (GLchar *) bp; int nameLen = strlen((char *)name); bp += nameLen+1+((8-((1+nameLen+0)%8))%8); @@ -4872,8 +4872,8 @@ case 5631: { // glGetUniformLocationARB rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5632: { // glGetActiveUniformARB +}; break; +case 5632: { // glGetActiveUniformARB GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLuint *index = (GLuint *) bp; bp += 4; GLsizei *maxLength = (GLsizei *) bp; bp += 4; @@ -4893,8 +4893,8 @@ case 5632: { // glGetActiveUniformARB if (AP != 13 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,13); driver_send_term(WXE_DRV_PORT,caller,rt,AP); driver_free(name); -}; break; -case 5633: { // glGetUniformfvARB +}; break; +case 5633: { // glGetUniformfvARB GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLint *location = (GLint *) bp; bp += 4; GLfloat params[16] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; @@ -4923,8 +4923,8 @@ case 5633: { // glGetUniformfvARB rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 38 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,38); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5634: { // glGetUniformivARB +}; break; +case 5634: { // glGetUniformivARB GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLint *location = (GLint *) bp; bp += 4; GLint params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; @@ -4952,8 +4952,8 @@ case 5634: { // glGetUniformivARB rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 38 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,38); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5635: { // glGetShaderSourceARB +}; break; +case 5635: { // glGetShaderSourceARB GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLsizei *maxLength = (GLsizei *) bp; bp += 4; GLsizei length[1] = {0}; @@ -4967,15 +4967,15 @@ case 5635: { // glGetShaderSourceARB if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7); driver_send_term(WXE_DRV_PORT,caller,rt,AP); driver_free(source); -}; break; -case 5636: { // glBindAttribLocationARB +}; break; +case 5636: { // glBindAttribLocationARB GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLuint *index = (GLuint *) bp; bp += 4; GLchar *name = (GLchar *) bp; int nameLen = strlen((char *)name); bp += nameLen+1+((8-((1+nameLen+4)%8))%8); weglBindAttribLocationARB(programObj,*index,name); -}; break; -case 5637: { // glGetActiveAttribARB +}; break; +case 5637: { // glGetActiveAttribARB GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLuint *index = (GLuint *) bp; bp += 4; GLsizei *maxLength = (GLsizei *) bp; bp += 4; @@ -4995,8 +4995,8 @@ case 5637: { // glGetActiveAttribARB if (AP != 13 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,13); driver_send_term(WXE_DRV_PORT,caller,rt,AP); driver_free(name); -}; break; -case 5638: { // glGetAttribLocationARB +}; break; +case 5638: { // glGetAttribLocationARB GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLchar *name = (GLchar *) bp; int nameLen = strlen((char *)name); bp += nameLen+1+((8-((1+nameLen+0)%8))%8); @@ -5007,8 +5007,8 @@ case 5638: { // glGetAttribLocationARB rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5639: { // glIsRenderbuffer +}; break; +case 5639: { // glIsRenderbuffer GLuint *renderbuffer = (GLuint *) bp; bp += 4; GLboolean result = weglIsRenderbuffer(*renderbuffer); int AP = 0; ErlDrvTermData rt[6]; @@ -5017,18 +5017,18 @@ case 5639: { // glIsRenderbuffer rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5640: { // glBindRenderbuffer +}; break; +case 5640: { // glBindRenderbuffer GLenum *target = (GLenum *) bp; bp += 4; GLuint *renderbuffer = (GLuint *) bp; bp += 4; weglBindRenderbuffer(*target,*renderbuffer); -}; break; -case 5641: { // glDeleteRenderbuffers +}; break; +case 5641: { // glDeleteRenderbuffers int * renderbuffersLen = (int *) bp; bp += 4; GLuint * renderbuffers = (GLuint *) bp; bp += (8-((*renderbuffersLen*4+4)%8))%8; weglDeleteRenderbuffers(*renderbuffersLen,renderbuffers); -}; break; -case 5642: { // glGenRenderbuffers +}; break; +case 5642: { // glGenRenderbuffers GLsizei *n = (GLsizei *) bp; bp += 4; GLuint *renderbuffers; renderbuffers = (GLuint *) driver_alloc(sizeof(GLuint) * *n); @@ -5042,17 +5042,17 @@ case 5642: { // glGenRenderbuffers rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 7 + (*n)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*n)*2); driver_send_term(WXE_DRV_PORT,caller,rt,AP); - driver_free(rt); + driver_free(rt); driver_free(renderbuffers); -}; break; -case 5643: { // glRenderbufferStorage +}; break; +case 5643: { // glRenderbufferStorage GLenum *target = (GLenum *) bp; bp += 4; GLenum *internalformat = (GLenum *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; GLsizei *height = (GLsizei *) bp; bp += 4; weglRenderbufferStorage(*target,*internalformat,*width,*height); -}; break; -case 5644: { // glGetRenderbufferParameteriv +}; break; +case 5644: { // glGetRenderbufferParameteriv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint params[1] = {0}; @@ -5063,8 +5063,8 @@ case 5644: { // glGetRenderbufferParameteriv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5645: { // glIsFramebuffer +}; break; +case 5645: { // glIsFramebuffer GLuint *framebuffer = (GLuint *) bp; bp += 4; GLboolean result = weglIsFramebuffer(*framebuffer); int AP = 0; ErlDrvTermData rt[6]; @@ -5073,18 +5073,18 @@ case 5645: { // glIsFramebuffer rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5646: { // glBindFramebuffer +}; break; +case 5646: { // glBindFramebuffer GLenum *target = (GLenum *) bp; bp += 4; GLuint *framebuffer = (GLuint *) bp; bp += 4; weglBindFramebuffer(*target,*framebuffer); -}; break; -case 5647: { // glDeleteFramebuffers +}; break; +case 5647: { // glDeleteFramebuffers int * framebuffersLen = (int *) bp; bp += 4; GLuint * framebuffers = (GLuint *) bp; bp += (8-((*framebuffersLen*4+4)%8))%8; weglDeleteFramebuffers(*framebuffersLen,framebuffers); -}; break; -case 5648: { // glGenFramebuffers +}; break; +case 5648: { // glGenFramebuffers GLsizei *n = (GLsizei *) bp; bp += 4; GLuint *framebuffers; framebuffers = (GLuint *) driver_alloc(sizeof(GLuint) * *n); @@ -5098,10 +5098,10 @@ case 5648: { // glGenFramebuffers rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 7 + (*n)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*n)*2); driver_send_term(WXE_DRV_PORT,caller,rt,AP); - driver_free(rt); + driver_free(rt); driver_free(framebuffers); -}; break; -case 5649: { // glCheckFramebufferStatus +}; break; +case 5649: { // glCheckFramebufferStatus GLenum *target = (GLenum *) bp; bp += 4; GLenum result = weglCheckFramebufferStatus(*target); int AP = 0; ErlDrvTermData rt[6]; @@ -5110,24 +5110,24 @@ case 5649: { // glCheckFramebufferStatus rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5650: { // glFramebufferTexture1D +}; break; +case 5650: { // glFramebufferTexture1D GLenum *target = (GLenum *) bp; bp += 4; GLenum *attachment = (GLenum *) bp; bp += 4; GLenum *textarget = (GLenum *) bp; bp += 4; GLuint *texture = (GLuint *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; weglFramebufferTexture1D(*target,*attachment,*textarget,*texture,*level); -}; break; -case 5651: { // glFramebufferTexture2D +}; break; +case 5651: { // glFramebufferTexture2D GLenum *target = (GLenum *) bp; bp += 4; GLenum *attachment = (GLenum *) bp; bp += 4; GLenum *textarget = (GLenum *) bp; bp += 4; GLuint *texture = (GLuint *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; weglFramebufferTexture2D(*target,*attachment,*textarget,*texture,*level); -}; break; -case 5652: { // glFramebufferTexture3D +}; break; +case 5652: { // glFramebufferTexture3D GLenum *target = (GLenum *) bp; bp += 4; GLenum *attachment = (GLenum *) bp; bp += 4; GLenum *textarget = (GLenum *) bp; bp += 4; @@ -5135,15 +5135,15 @@ case 5652: { // glFramebufferTexture3D GLint *level = (GLint *) bp; bp += 4; GLint *zoffset = (GLint *) bp; bp += 4; weglFramebufferTexture3D(*target,*attachment,*textarget,*texture,*level,*zoffset); -}; break; -case 5653: { // glFramebufferRenderbuffer +}; break; +case 5653: { // glFramebufferRenderbuffer GLenum *target = (GLenum *) bp; bp += 4; GLenum *attachment = (GLenum *) bp; bp += 4; GLenum *renderbuffertarget = (GLenum *) bp; bp += 4; GLuint *renderbuffer = (GLuint *) bp; bp += 4; weglFramebufferRenderbuffer(*target,*attachment,*renderbuffertarget,*renderbuffer); -}; break; -case 5654: { // glGetFramebufferAttachmentParameteriv +}; break; +case 5654: { // glGetFramebufferAttachmentParameteriv GLenum *target = (GLenum *) bp; bp += 4; GLenum *attachment = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; @@ -5155,12 +5155,12 @@ case 5654: { // glGetFramebufferAttachmentParameteriv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5655: { // glGenerateMipmap +}; break; +case 5655: { // glGenerateMipmap GLenum *target = (GLenum *) bp; bp += 4; weglGenerateMipmap(*target); -}; break; -case 5656: { // glBlitFramebuffer +}; break; +case 5656: { // glBlitFramebuffer GLint *srcX0 = (GLint *) bp; bp += 4; GLint *srcY0 = (GLint *) bp; bp += 4; GLint *srcX1 = (GLint *) bp; bp += 4; @@ -5172,66 +5172,66 @@ case 5656: { // glBlitFramebuffer GLbitfield *mask = (GLbitfield *) bp; bp += 4; GLenum *filter = (GLenum *) bp; bp += 4; weglBlitFramebuffer(*srcX0,*srcY0,*srcX1,*srcY1,*dstX0,*dstY0,*dstX1,*dstY1,*mask,*filter); -}; break; -case 5657: { // glRenderbufferStorageMultisample +}; break; +case 5657: { // glRenderbufferStorageMultisample GLenum *target = (GLenum *) bp; bp += 4; GLsizei *samples = (GLsizei *) bp; bp += 4; GLenum *internalformat = (GLenum *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; GLsizei *height = (GLsizei *) bp; bp += 4; weglRenderbufferStorageMultisample(*target,*samples,*internalformat,*width,*height); -}; break; -case 5658: { // glFramebufferTextureLayer +}; break; +case 5658: { // glFramebufferTextureLayer GLenum *target = (GLenum *) bp; bp += 4; GLenum *attachment = (GLenum *) bp; bp += 4; GLuint *texture = (GLuint *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLint *layer = (GLint *) bp; bp += 4; weglFramebufferTextureLayer(*target,*attachment,*texture,*level,*layer); -}; break; -case 5659: { // glProgramParameteriARB +}; break; +case 5659: { // glProgramParameteriARB GLuint *program = (GLuint *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint *value = (GLint *) bp; bp += 4; weglProgramParameteriARB(*program,*pname,*value); -}; break; -case 5660: { // glFramebufferTextureARB +}; break; +case 5660: { // glFramebufferTextureARB GLenum *target = (GLenum *) bp; bp += 4; GLenum *attachment = (GLenum *) bp; bp += 4; GLuint *texture = (GLuint *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; weglFramebufferTextureARB(*target,*attachment,*texture,*level); -}; break; -case 5661: { // glFramebufferTextureFaceARB +}; break; +case 5661: { // glFramebufferTextureFaceARB GLenum *target = (GLenum *) bp; bp += 4; GLenum *attachment = (GLenum *) bp; bp += 4; GLuint *texture = (GLuint *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLenum *face = (GLenum *) bp; bp += 4; weglFramebufferTextureFaceARB(*target,*attachment,*texture,*level,*face); -}; break; -case 5662: { // glVertexAttribDivisorARB +}; break; +case 5662: { // glVertexAttribDivisorARB GLuint *index = (GLuint *) bp; bp += 4; GLuint *divisor = (GLuint *) bp; bp += 4; weglVertexAttribDivisorARB(*index,*divisor); -}; break; -case 5663: { // glFlushMappedBufferRange +}; break; +case 5663: { // glFlushMappedBufferRange GLenum *target = (GLenum *) bp; bp += 4; bp += 4; GLintptr offset = (GLintptr) * (GLuint64EXT *) bp; bp += 8; GLsizeiptr length = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8; weglFlushMappedBufferRange(*target,offset,length); -}; break; -case 5664: { // glBindVertexArray +}; break; +case 5664: { // glBindVertexArray GLuint *array = (GLuint *) bp; bp += 4; weglBindVertexArray(*array); -}; break; -case 5665: { // glDeleteVertexArrays +}; break; +case 5665: { // glDeleteVertexArrays int * arraysLen = (int *) bp; bp += 4; GLuint * arrays = (GLuint *) bp; bp += (8-((*arraysLen*4+4)%8))%8; weglDeleteVertexArrays(*arraysLen,arrays); -}; break; -case 5666: { // glGenVertexArrays +}; break; +case 5666: { // glGenVertexArrays GLsizei *n = (GLsizei *) bp; bp += 4; GLuint *arrays; arrays = (GLuint *) driver_alloc(sizeof(GLuint) * *n); @@ -5245,10 +5245,10 @@ case 5666: { // glGenVertexArrays rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 7 + (*n)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*n)*2); driver_send_term(WXE_DRV_PORT,caller,rt,AP); - driver_free(rt); + driver_free(rt); driver_free(arrays); -}; break; -case 5667: { // glIsVertexArray +}; break; +case 5667: { // glIsVertexArray GLuint *array = (GLuint *) bp; bp += 4; GLboolean result = weglIsVertexArray(*array); int AP = 0; ErlDrvTermData rt[6]; @@ -5257,13 +5257,13 @@ case 5667: { // glIsVertexArray rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5668: { // glGetUniformIndices +}; break; +case 5668: { // glGetUniformIndices GLuint *program = (GLuint *) bp; bp += 4; int * uniformNamesLen = (int *) bp; bp += 4; int * uniformNamesTotSize = (int *) bp; bp += 4; GLchar **uniformNames; - uniformNames = (GLchar **) driver_alloc(sizeof(GLchar *) * *uniformNamesLen); + uniformNames = (GLchar **) driver_alloc(sizeof(GLchar *) * *uniformNamesLen); for(int i=0;i<*uniformNamesLen;i++) { uniformNames[i] = (GLchar *) bp; bp += 1+strlen(bp);}; bp += (8 - ((0 + *uniformNamesTotSize) % 8)) % 8; @@ -5279,11 +5279,11 @@ case 5668: { // glGetUniformIndices rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 7 + (*uniformNamesLen)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*uniformNamesLen)*2); driver_send_term(WXE_DRV_PORT,caller,rt,AP); - driver_free(rt); + driver_free(rt); driver_free(uniformIndices); driver_free(uniformNames); -}; break; -case 5669: { // glGetActiveUniformsiv +}; break; +case 5669: { // glGetActiveUniformsiv GLuint *program = (GLuint *) bp; bp += 4; int * uniformIndicesLen = (int *) bp; bp += 4; GLuint * uniformIndices = (GLuint *) bp; bp += (8-((*uniformIndicesLen*4+0)%8))%8; @@ -5300,10 +5300,10 @@ case 5669: { // glGetActiveUniformsiv rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 7 + (*uniformIndicesLen)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*uniformIndicesLen)*2); driver_send_term(WXE_DRV_PORT,caller,rt,AP); - driver_free(rt); + driver_free(rt); driver_free(params); -}; break; -case 5670: { // glGetActiveUniformName +}; break; +case 5670: { // glGetActiveUniformName GLuint *program = (GLuint *) bp; bp += 4; GLuint *uniformIndex = (GLuint *) bp; bp += 4; GLsizei *bufSize = (GLsizei *) bp; bp += 4; @@ -5318,8 +5318,8 @@ case 5670: { // glGetActiveUniformName if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7); driver_send_term(WXE_DRV_PORT,caller,rt,AP); driver_free(uniformName); -}; break; -case 5671: { // glGetUniformBlockIndex +}; break; +case 5671: { // glGetUniformBlockIndex GLuint *program = (GLuint *) bp; bp += 4; GLchar *uniformBlockName = (GLchar *) bp; int uniformBlockNameLen = strlen((char *)uniformBlockName); bp += uniformBlockNameLen+1+((8-((1+uniformBlockNameLen+4)%8))%8); @@ -5330,8 +5330,8 @@ case 5671: { // glGetUniformBlockIndex rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5672: { // glGetActiveUniformBlockiv +}; break; +case 5672: { // glGetActiveUniformBlockiv GLuint *program = (GLuint *) bp; bp += 4; GLuint *uniformBlockIndex = (GLuint *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; @@ -5342,8 +5342,8 @@ case 5672: { // glGetActiveUniformBlockiv rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5673: { // glGetActiveUniformBlockName +}; break; +case 5673: { // glGetActiveUniformBlockName GLuint *program = (GLuint *) bp; bp += 4; GLuint *uniformBlockIndex = (GLuint *) bp; bp += 4; GLsizei *bufSize = (GLsizei *) bp; bp += 4; @@ -5358,49 +5358,49 @@ case 5673: { // glGetActiveUniformBlockName if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7); driver_send_term(WXE_DRV_PORT,caller,rt,AP); driver_free(uniformBlockName); -}; break; -case 5674: { // glUniformBlockBinding +}; break; +case 5674: { // glUniformBlockBinding GLuint *program = (GLuint *) bp; bp += 4; GLuint *uniformBlockIndex = (GLuint *) bp; bp += 4; GLuint *uniformBlockBinding = (GLuint *) bp; bp += 4; weglUniformBlockBinding(*program,*uniformBlockIndex,*uniformBlockBinding); -}; break; -case 5675: { // glCopyBufferSubData +}; break; +case 5675: { // glCopyBufferSubData GLenum *readTarget = (GLenum *) bp; bp += 4; GLenum *writeTarget = (GLenum *) bp; bp += 4; GLintptr readOffset = (GLintptr) * (GLuint64EXT *) bp; bp += 8; GLintptr writeOffset = (GLintptr) * (GLuint64EXT *) bp; bp += 8; GLsizeiptr size = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8; weglCopyBufferSubData(*readTarget,*writeTarget,readOffset,writeOffset,size); -}; break; -case 5676: { // glResizeBuffersMESA +}; break; +case 5676: { // glResizeBuffersMESA weglResizeBuffersMESA(); -}; break; -case 5677: { // glWindowPos4dvMESA +}; break; +case 5677: { // glWindowPos4dvMESA GLdouble *v = (GLdouble *) bp; bp += 8; weglWindowPos4dvMESA(v); -}; break; -case 5678: { // glWindowPos4fvMESA +}; break; +case 5678: { // glWindowPos4fvMESA GLfloat *v = (GLfloat *) bp; bp += 4; weglWindowPos4fvMESA(v); -}; break; -case 5679: { // glWindowPos4ivMESA +}; break; +case 5679: { // glWindowPos4ivMESA GLint *v = (GLint *) bp; bp += 4; weglWindowPos4ivMESA(v); -}; break; -case 5680: { // glWindowPos4svMESA +}; break; +case 5680: { // glWindowPos4svMESA GLshort *v = (GLshort *) bp; bp += 2; weglWindowPos4svMESA(v); -}; break; -case 5681: { // glDepthBoundsEXT +}; break; +case 5681: { // glDepthBoundsEXT GLclampd *zmin = (GLclampd *) bp; bp += 8; GLclampd *zmax = (GLclampd *) bp; bp += 8; weglDepthBoundsEXT(*zmin,*zmax); -}; break; -case 5682: { // glStencilClearTagEXT +}; break; +case 5682: { // glStencilClearTagEXT GLsizei *stencilTagBits = (GLsizei *) bp; bp += 4; GLuint *stencilClearTag = (GLuint *) bp; bp += 4; weglStencilClearTagEXT(*stencilTagBits,*stencilClearTag); -}; break; +}; break; }} /* The End */ diff --git a/lib/wx/c_src/gen/glu_finit.h b/lib/wx/c_src/gen/glu_finit.h index 2f0e2d15e4..63e9c2fc78 100644 --- a/lib/wx/c_src/gen/glu_finit.h +++ b/lib/wx/c_src/gen/glu_finit.h @@ -16,7 +16,7 @@ * * %CopyrightEnd% */ -/***** This file is generated do not edit ****/ +/***** This file is generated do not edit ****/ static struct { const char * name; 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 c8549d0716..8c056bbb91 100644 --- a/lib/wx/c_src/gen/wxe_funcs.cpp +++ b/lib/wx/c_src/gen/wxe_funcs.cpp @@ -2209,7 +2209,7 @@ case wxScrolledWindow_new_2: { // wxScrolledWindow::wxScrolledWindow wxWindowID winid=wxID_ANY; wxPoint pos= wxDefaultPosition; wxSize size= wxDefaultSize; - long style=(wxHSCROLL|wxVSCROLL); + long style=wxScrolledWindowStyle; wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4; bp += 4; /* Align */ while( * (int*) bp) { switch (* (int*) bp) { @@ -2385,7 +2385,7 @@ case wxSashWindow_new_2: { // wxSashWindow::wxSashWindow wxWindowID id=wxID_ANY; wxPoint pos= wxDefaultPosition; wxSize size= wxDefaultSize; - long style=(0x0040|0x0080)|wxCLIP_CHILDREN; + long style=wxSW_3D|wxCLIP_CHILDREN; wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4; bp += 4; /* Align */ while( * (int*) bp) { switch (* (int*) bp) { @@ -5930,7 +5930,7 @@ case wxBufferedDC_new_0: { // wxBufferedDC::wxBufferedDC } case wxBufferedDC_new_2: { // wxBufferedDC::wxBufferedDC wxBitmap * buffer= &wxNullBitmap; - int style=0x02; + int style=wxBUFFER_CLIENT_AREA; wxDC *dc = (wxDC *) getPtr(bp,memenv); bp += 4; bp += 4; /* Align */ while( * (int*) bp) { switch (* (int*) bp) { @@ -5947,7 +5947,7 @@ buffer = (wxBitmap *) getPtr(bp,memenv); bp += 4; break; } case wxBufferedDC_new_3: { // wxBufferedDC::wxBufferedDC - int style=0x02; + int style=wxBUFFER_CLIENT_AREA; wxDC *dc = (wxDC *) getPtr(bp,memenv); bp += 4; int * areaW = (int *) bp; bp += 4; int * areaH = (int *) bp; bp += 4; @@ -5965,7 +5965,7 @@ case wxBufferedDC_new_3: { // wxBufferedDC::wxBufferedDC } case wxBufferedDC_Init_2: { // wxBufferedDC::Init wxBitmap * buffer= &wxNullBitmap; - int style=0x02; + int style=wxBUFFER_CLIENT_AREA; wxBufferedDC *This = (wxBufferedDC *) getPtr(bp,memenv); bp += 4; wxDC *dc = (wxDC *) getPtr(bp,memenv); bp += 4; while( * (int*) bp) { switch (* (int*) bp) { @@ -5981,7 +5981,7 @@ buffer = (wxBitmap *) getPtr(bp,memenv); bp += 4; break; } case wxBufferedDC_Init_3: { // wxBufferedDC::Init - int style=0x02; + int style=wxBUFFER_CLIENT_AREA; wxBufferedDC *This = (wxBufferedDC *) getPtr(bp,memenv); bp += 4; wxDC *dc = (wxDC *) getPtr(bp,memenv); bp += 4; int * areaW = (int *) bp; bp += 4; @@ -5997,7 +5997,7 @@ case wxBufferedDC_Init_3: { // wxBufferedDC::Init break; } case wxBufferedPaintDC_new_3: { // wxBufferedPaintDC::wxBufferedPaintDC - int style=0x02; + int style=wxBUFFER_CLIENT_AREA; wxWindow *window = (wxWindow *) getPtr(bp,memenv); bp += 4; wxBitmap *buffer = (wxBitmap *) getPtr(bp,memenv); bp += 4; while( * (int*) bp) { switch (* (int*) bp) { @@ -6011,7 +6011,7 @@ case wxBufferedPaintDC_new_3: { // wxBufferedPaintDC::wxBufferedPaintDC break; } case wxBufferedPaintDC_new_2: { // wxBufferedPaintDC::wxBufferedPaintDC - int style=0x02; + int style=wxBUFFER_CLIENT_AREA; wxWindow *window = (wxWindow *) getPtr(bp,memenv); bp += 4; bp += 4; /* Align */ while( * (int*) bp) { switch (* (int*) bp) { @@ -9163,7 +9163,7 @@ case wxIcon_new_0: { // wxIcon::wxIcon break; } case wxIcon_new_2: { // wxIcon::wxIcon - wxBitmapType type=wxBITMAP_TYPE_XPM; + wxBitmapType type=wxICON_DEFAULT_BITMAP_TYPE; int desiredWidth=-1; int desiredHeight=-1; int * filenameLen = (int *) bp; bp += 4; @@ -16404,7 +16404,7 @@ case wxTextAttr_SetFlags: { // wxTextAttr::SetFlags break; } case wxTextAttr_SetFont: { // wxTextAttr::SetFont - long flags=(0x0004|0x0008|0x0010|0x0020|0x0040); + long flags=wxTEXT_ATTR_FONT; wxTextAttr *This = (wxTextAttr *) getPtr(bp,memenv); bp += 4; wxFont *font = (wxFont *) getPtr(bp,memenv); bp += 4; while( * (int*) bp) { switch (* (int*) bp) { @@ -16739,7 +16739,7 @@ case wxTextCtrl_IsSingleLine: { // wxTextCtrl::IsSingleLine break; } case wxTextCtrl_LoadFile: { // wxTextCtrl::LoadFile - int fileType=0; + int fileType=wxTEXT_TYPE_ANY; wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4; int * fileLen = (int *) bp; bp += 4; wxString file = wxString(bp, wxConvUTF8); @@ -16806,7 +16806,7 @@ case wxTextCtrl_Replace: { // wxTextCtrl::Replace } case wxTextCtrl_SaveFile: { // wxTextCtrl::SaveFile wxString file= wxEmptyString; - int fileType=0; + int fileType=wxTEXT_TYPE_ANY; wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4; bp += 4; /* Align */ while( * (int*) bp) { switch (* (int*) bp) { @@ -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 */ @@ -20467,7 +20476,7 @@ case wxPalette_IsOk: { // wxPalette::IsOk case wxDirDialog_new: { // wxDirDialog::wxDirDialog wxString title= wxDirSelectorPromptStr; wxString defaultPath= wxEmptyString; - long style=(wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); + long style=wxDD_DEFAULT_STYLE; wxPoint pos= wxDefaultPosition; wxSize sz= wxDefaultSize; wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4; @@ -20541,7 +20550,7 @@ case wxFileDialog_new: { // wxFileDialog::wxFileDialog wxString defaultDir= wxEmptyString; wxString defaultFile= wxEmptyString; wxString wildCard= wxFileSelectorDefaultWildcardStr; - long style=wxFD_OPEN; + long style=wxFD_DEFAULT_STYLE; wxPoint pos= wxDefaultPosition; wxSize sz= wxDefaultSize; wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4; @@ -20806,7 +20815,7 @@ case wxFilePickerCtrl_new_3: { // wxFilePickerCtrl::wxFilePickerCtrl wxString wildcard= wxFileSelectorDefaultWildcardStr; wxPoint pos= wxDefaultPosition; wxSize size= wxDefaultSize; - long style=(0x0400|0x2000); + long style=wxFLP_DEFAULT_STYLE; const wxValidator * validator= &wxDefaultValidator; wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4; int * id = (int *) bp; bp += 4; @@ -20856,7 +20865,7 @@ case wxFilePickerCtrl_Create: { // wxFilePickerCtrl::Create wxString wildcard= wxFileSelectorDefaultWildcardStr; wxPoint pos= wxDefaultPosition; wxSize size= wxDefaultSize; - long style=(0x0400|0x2000); + long style=wxFLP_DEFAULT_STYLE; const wxValidator * validator= &wxDefaultValidator; wxFilePickerCtrl *This = (wxFilePickerCtrl *) getPtr(bp,memenv); bp += 4; wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4; @@ -20929,7 +20938,7 @@ case wxDirPickerCtrl_new_3: { // wxDirPickerCtrl::wxDirPickerCtrl wxString message= wxDirSelectorPromptStr; wxPoint pos= wxDefaultPosition; wxSize size= wxDefaultSize; - long style=(0x0008); + long style=wxDIRP_DEFAULT_STYLE; const wxValidator * validator= &wxDefaultValidator; wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4; int * id = (int *) bp; bp += 4; @@ -20973,7 +20982,7 @@ case wxDirPickerCtrl_Create: { // wxDirPickerCtrl::Create wxString message= wxDirSelectorPromptStr; wxPoint pos= wxDefaultPosition; wxSize size= wxDefaultSize; - long style=(0x0008); + long style=wxDIRP_DEFAULT_STYLE; const wxValidator * validator= &wxDefaultValidator; wxDirPickerCtrl *This = (wxDirPickerCtrl *) getPtr(bp,memenv); bp += 4; wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4; @@ -21040,7 +21049,7 @@ case wxColourPickerCtrl_new_3: { // wxColourPickerCtrl::wxColourPickerCtrl wxColour col= *wxBLACK; wxPoint pos= wxDefaultPosition; wxSize size= wxDefaultSize; - long style=0; + long style=wxCLRP_DEFAULT_STYLE; const wxValidator * validator= &wxDefaultValidator; wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4; int * id = (int *) bp; bp += 4; @@ -21081,7 +21090,7 @@ case wxColourPickerCtrl_Create: { // wxColourPickerCtrl::Create wxColour col= *wxBLACK; wxPoint pos= wxDefaultPosition; wxSize size= wxDefaultSize; - long style=0; + long style=wxCLRP_DEFAULT_STYLE; const wxValidator * validator= &wxDefaultValidator; wxColourPickerCtrl *This = (wxColourPickerCtrl *) getPtr(bp,memenv); bp += 4; wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4; @@ -21268,7 +21277,7 @@ case wxFontPickerCtrl_new_3: { // wxFontPickerCtrl::wxFontPickerCtrl const wxFont * initial= &wxNullFont; wxPoint pos= wxDefaultPosition; wxSize size= wxDefaultSize; - long style=(0x0008|0x0010); + long style=wxFNTP_DEFAULT_STYLE; const wxValidator * validator= &wxDefaultValidator; wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4; int * id = (int *) bp; bp += 4; @@ -21304,7 +21313,7 @@ case wxFontPickerCtrl_Create: { // wxFontPickerCtrl::Create const wxFont * initial= &wxNullFont; wxPoint pos= wxDefaultPosition; wxSize size= wxDefaultSize; - long style=(0x0008|0x0010); + long style=wxFNTP_DEFAULT_STYLE; const wxValidator * validator= &wxDefaultValidator; wxFontPickerCtrl *This = (wxFontPickerCtrl *) getPtr(bp,memenv); bp += 4; wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4; @@ -21480,7 +21489,7 @@ case wxMultiChoiceDialog_new_0: { // wxMultiChoiceDialog::wxMultiChoiceDialog break; } case wxMultiChoiceDialog_new_5: { // wxMultiChoiceDialog::wxMultiChoiceDialog - long style=(wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxOK|wxCANCEL|wxCENTRE); + long style=wxCHOICEDLG_STYLE; wxPoint pos= wxDefaultPosition; wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4; int * messageLen = (int *) bp; bp += 4; @@ -21540,7 +21549,7 @@ case wxSingleChoiceDialog_new_0: { // wxSingleChoiceDialog::wxSingleChoiceDialog } case wxSingleChoiceDialog_new_5: { // wxSingleChoiceDialog::wxSingleChoiceDialog char ** clientData = (char **) NULL; - long style=(wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxOK|wxCANCEL|wxCENTRE); + long style=wxCHOICEDLG_STYLE; wxPoint pos= wxDefaultPosition; wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4; int * messageLen = (int *) bp; bp += 4; @@ -21599,7 +21608,7 @@ case wxSingleChoiceDialog_SetSelection: { // wxSingleChoiceDialog::SetSelection case wxTextEntryDialog_new: { // wxTextEntryDialog::wxTextEntryDialog wxString caption= wxGetTextFromUserPromptStr; wxString value= wxEmptyString; - long style=(wxOK|wxCANCEL|wxCENTRE|wxWS_EX_VALIDATE_RECURSIVELY); + long style=wxTextEntryDialogStyle; wxPoint pos= wxDefaultPosition; wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4; int * messageLen = (int *) bp; bp += 4; @@ -21650,7 +21659,7 @@ case wxTextEntryDialog_SetValue: { // wxTextEntryDialog::SetValue case wxPasswordEntryDialog_new: { // wxPasswordEntryDialog::wxPasswordEntryDialog wxString caption= wxGetPasswordFromUserPromptStr; wxString value= wxEmptyString; - long style=(wxOK|wxCANCEL|wxCENTRE|wxWS_EX_VALIDATE_RECURSIVELY); + long style=wxTextEntryDialogStyle; wxPoint pos= wxDefaultPosition; wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4; int * messageLen = (int *) bp; bp += 4; @@ -30758,7 +30767,7 @@ case wxHtmlWindow_new_2: { // wxHtmlWindow::wxHtmlWindow wxWindowID id=wxID_ANY; wxPoint pos= wxDefaultPosition; wxSize size= wxDefaultSize; - long style=0x0004; + long style=wxHW_DEFAULT_STYLE; wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4; bp += 4; /* Align */ while( * (int*) bp) { switch (* (int*) bp) { @@ -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_init.cpp b/lib/wx/c_src/gen/wxe_init.cpp index 96c775c4c0..bab3261be4 100644 --- a/lib/wx/c_src/gen/wxe_init.cpp +++ b/lib/wx/c_src/gen/wxe_init.cpp @@ -24,6 +24,8 @@ void WxeApp::init_nonconsts(wxeMemEnv *memenv, ErlDrvTermData caller) { wxeReturn rt = wxeReturn(WXE_DRV_PORT, caller); rt.addAtom((char*)"wx_consts"); + rt.addAtom("wxALWAYS_NATIVE_DOUBLE_BUFFER"); rt.addInt(wxALWAYS_NATIVE_DOUBLE_BUFFER); + rt.addTupleCount(2); rt.addAtom("wxBYTE_ORDER"); rt.addInt(wxBYTE_ORDER); rt.addTupleCount(2); rt.addAtom("wxDEFAULT_CONTROL_BORDER"); rt.addInt(wxDEFAULT_CONTROL_BORDER); @@ -32,6 +34,10 @@ void WxeApp::init_nonconsts(wxeMemEnv *memenv, ErlDrvTermData caller) { rt.addTupleCount(2); rt.addAtom("wxRETAINED"); rt.addInt(wxRETAINED); rt.addTupleCount(2); + rt.addAtom("wxGAUGE_EMULATE_INDETERMINATE_MODE"); rt.addInt(wxGAUGE_EMULATE_INDETERMINATE_MODE); + rt.addTupleCount(2); + rt.addAtom("wxTR_DEFAULT_STYLE"); rt.addInt(wxTR_DEFAULT_STYLE); + rt.addTupleCount(2); rt.addAtom("wxBETA_NUMBER"); rt.addInt(wxBETA_NUMBER); rt.addTupleCount(2); rt.addAtom("wxMAJOR_VERSION"); rt.addInt(wxMAJOR_VERSION); @@ -130,7 +136,7 @@ void WxeApp::init_nonconsts(wxeMemEnv *memenv, ErlDrvTermData caller) { rt.addTupleCount(2); rt.addAtom("wxWHITE_PEN"); rt.addRef(getRef((void *)wxWHITE_PEN,memenv),"wxPen"); rt.addTupleCount(2); - rt.endList(53); + rt.endList(56); rt.addTupleCount(2); rt.send(); } diff --git a/lib/wx/c_src/gen/wxe_macros.h b/lib/wx/c_src/gen/wxe_macros.h index cb5a4f3c41..4fb76f960b 100644 --- a/lib/wx/c_src/gen/wxe_macros.h +++ b/lib/wx/c_src/gen/wxe_macros.h @@ -62,6 +62,11 @@ #include <wx/filename.h> +#ifndef wxICON_DEFAULT_BITMAP_TYPE + #define wxICON_DEFAULT_BITMAP_TYPE wxBITMAP_TYPE_ICO_RESOURCE +#endif + + #define wxEvtHandler_Connect 100 #define wxEvtHandler_Disconnect_2 101 #define wxEvtHandler_Disconnect_1 102 @@ -810,2511 +815,2516 @@ #define wxControlWithItems_Clear 882 #define wxControlWithItems_Delete 883 #define wxControlWithItems_FindString 884 -#define wxControlWithItems_getClientData 886 -#define wxControlWithItems_setClientData 888 -#define wxControlWithItems_GetCount 889 -#define wxControlWithItems_GetSelection 890 -#define wxControlWithItems_GetString 891 -#define wxControlWithItems_GetStringSelection 892 -#define wxControlWithItems_Insert_2 893 -#define wxControlWithItems_Insert_3 894 -#define wxControlWithItems_IsEmpty 895 -#define wxControlWithItems_Select 896 -#define wxControlWithItems_SetSelection 897 -#define wxControlWithItems_SetString 898 -#define wxControlWithItems_SetStringSelection 899 -#define wxMenu_new_2 902 -#define wxMenu_new_1 903 -#define wxMenu_destruct 905 -#define wxMenu_Append_3 906 -#define wxMenu_Append_1 907 -#define wxMenu_Append_4_0 908 -#define wxMenu_Append_4_1 909 -#define wxMenu_AppendCheckItem 910 -#define wxMenu_AppendRadioItem 911 -#define wxMenu_AppendSeparator 912 -#define wxMenu_Break 913 -#define wxMenu_Check 914 -#define wxMenu_Delete_1_0 915 -#define wxMenu_Delete_1_1 916 -#define wxMenu_Destroy_1_0 917 -#define wxMenu_Destroy_1_1 918 -#define wxMenu_Enable 919 -#define wxMenu_FindItem_1 920 -#define wxMenu_FindItem_2 921 -#define wxMenu_FindItemByPosition 922 -#define wxMenu_GetHelpString 923 -#define wxMenu_GetLabel 924 -#define wxMenu_GetMenuItemCount 925 -#define wxMenu_GetMenuItems 926 -#define wxMenu_GetTitle 928 -#define wxMenu_Insert_2 929 -#define wxMenu_Insert_3 930 -#define wxMenu_Insert_5_1 931 -#define wxMenu_Insert_5_0 932 -#define wxMenu_InsertCheckItem 933 -#define wxMenu_InsertRadioItem 934 -#define wxMenu_InsertSeparator 935 -#define wxMenu_IsChecked 936 -#define wxMenu_IsEnabled 937 -#define wxMenu_Prepend_1 938 -#define wxMenu_Prepend_2 939 -#define wxMenu_Prepend_4_1 940 -#define wxMenu_Prepend_4_0 941 -#define wxMenu_PrependCheckItem 942 -#define wxMenu_PrependRadioItem 943 -#define wxMenu_PrependSeparator 944 -#define wxMenu_Remove_1_0 945 -#define wxMenu_Remove_1_1 946 -#define wxMenu_SetHelpString 947 -#define wxMenu_SetLabel 948 -#define wxMenu_SetTitle 949 -#define wxMenuItem_new 950 -#define wxMenuItem_destruct 952 -#define wxMenuItem_Check 953 -#define wxMenuItem_Enable 954 -#define wxMenuItem_GetBitmap 955 -#define wxMenuItem_GetHelp 956 -#define wxMenuItem_GetId 957 -#define wxMenuItem_GetKind 958 -#define wxMenuItem_GetLabel 959 -#define wxMenuItem_GetLabelFromText 960 -#define wxMenuItem_GetMenu 961 -#define wxMenuItem_GetText 962 -#define wxMenuItem_GetSubMenu 963 -#define wxMenuItem_IsCheckable 964 -#define wxMenuItem_IsChecked 965 -#define wxMenuItem_IsEnabled 966 -#define wxMenuItem_IsSeparator 967 -#define wxMenuItem_IsSubMenu 968 -#define wxMenuItem_SetBitmap 969 -#define wxMenuItem_SetHelp 970 -#define wxMenuItem_SetMenu 971 -#define wxMenuItem_SetSubMenu 972 -#define wxMenuItem_SetText 973 -#define wxToolBar_AddControl 974 -#define wxToolBar_AddSeparator 975 -#define wxToolBar_AddTool_5 976 -#define wxToolBar_AddTool_4_0 977 -#define wxToolBar_AddTool_1 978 -#define wxToolBar_AddTool_4_1 979 -#define wxToolBar_AddTool_3 980 -#define wxToolBar_AddTool_6 981 -#define wxToolBar_AddCheckTool 982 -#define wxToolBar_AddRadioTool 983 -#define wxToolBar_DeleteTool 984 -#define wxToolBar_DeleteToolByPos 985 -#define wxToolBar_EnableTool 986 -#define wxToolBar_FindById 987 -#define wxToolBar_FindControl 988 -#define wxToolBar_FindToolForPosition 989 -#define wxToolBar_GetToolSize 990 -#define wxToolBar_GetToolBitmapSize 991 -#define wxToolBar_GetMargins 992 -#define wxToolBar_GetToolEnabled 993 -#define wxToolBar_GetToolLongHelp 994 -#define wxToolBar_GetToolPacking 995 -#define wxToolBar_GetToolPos 996 -#define wxToolBar_GetToolSeparation 997 -#define wxToolBar_GetToolShortHelp 998 -#define wxToolBar_GetToolState 999 -#define wxToolBar_InsertControl 1000 -#define wxToolBar_InsertSeparator 1001 -#define wxToolBar_InsertTool_5 1002 -#define wxToolBar_InsertTool_2 1003 -#define wxToolBar_InsertTool_4 1004 -#define wxToolBar_Realize 1005 -#define wxToolBar_RemoveTool 1006 -#define wxToolBar_SetMargins 1007 -#define wxToolBar_SetToolBitmapSize 1008 -#define wxToolBar_SetToolLongHelp 1009 -#define wxToolBar_SetToolPacking 1010 -#define wxToolBar_SetToolShortHelp 1011 -#define wxToolBar_SetToolSeparation 1012 -#define wxToolBar_ToggleTool 1013 -#define wxStatusBar_new_0 1015 -#define wxStatusBar_new_2 1016 -#define wxStatusBar_destruct 1018 -#define wxStatusBar_Create 1019 -#define wxStatusBar_GetFieldRect 1020 -#define wxStatusBar_GetFieldsCount 1021 -#define wxStatusBar_GetStatusText 1022 -#define wxStatusBar_PopStatusText 1023 -#define wxStatusBar_PushStatusText 1024 -#define wxStatusBar_SetFieldsCount 1025 -#define wxStatusBar_SetMinHeight 1026 -#define wxStatusBar_SetStatusText 1027 -#define wxStatusBar_SetStatusWidths 1028 -#define wxStatusBar_SetStatusStyles 1029 -#define wxBitmap_new_0 1030 -#define wxBitmap_new_3 1031 -#define wxBitmap_new_4 1032 -#define wxBitmap_new_2_0 1033 -#define wxBitmap_new_2_1 1034 -#define wxBitmap_destruct 1035 -#define wxBitmap_ConvertToImage 1036 -#define wxBitmap_CopyFromIcon 1037 -#define wxBitmap_Create 1038 -#define wxBitmap_GetDepth 1039 -#define wxBitmap_GetHeight 1040 -#define wxBitmap_GetPalette 1041 -#define wxBitmap_GetMask 1042 -#define wxBitmap_GetWidth 1043 -#define wxBitmap_GetSubBitmap 1044 -#define wxBitmap_LoadFile 1045 -#define wxBitmap_Ok 1046 -#define wxBitmap_SaveFile 1047 -#define wxBitmap_SetDepth 1048 -#define wxBitmap_SetHeight 1049 -#define wxBitmap_SetMask 1050 -#define wxBitmap_SetPalette 1051 -#define wxBitmap_SetWidth 1052 -#define wxIcon_new_0 1053 -#define wxIcon_new_2 1054 -#define wxIcon_new_1 1055 -#define wxIcon_CopyFromBitmap 1056 -#define wxIcon_destroy 1057 -#define wxIconBundle_new_0 1058 -#define wxIconBundle_new_2 1059 -#define wxIconBundle_new_1_0 1060 -#define wxIconBundle_new_1_1 1061 -#define wxIconBundle_destruct 1062 -#define wxIconBundle_AddIcon_2 1063 -#define wxIconBundle_AddIcon_1 1064 -#define wxIconBundle_GetIcon_1_1 1065 -#define wxIconBundle_GetIcon_1_0 1066 -#define wxCursor_new_0 1067 -#define wxCursor_new_1_0 1068 -#define wxCursor_new_1_1 1069 -#define wxCursor_new_4 1070 -#define wxCursor_destruct 1071 -#define wxCursor_Ok 1072 -#define wxMask_new_0 1073 -#define wxMask_new_2_1 1074 -#define wxMask_new_2_0 1075 -#define wxMask_new_1 1076 -#define wxMask_destruct 1077 -#define wxMask_Create_2_1 1078 -#define wxMask_Create_2_0 1079 -#define wxMask_Create_1 1080 -#define wxImage_new_0 1081 -#define wxImage_new_3_0 1082 -#define wxImage_new_4 1083 -#define wxImage_new_5 1084 -#define wxImage_new_2 1085 -#define wxImage_new_3_1 1086 -#define wxImage_Blur 1087 -#define wxImage_BlurHorizontal 1088 -#define wxImage_BlurVertical 1089 -#define wxImage_ConvertAlphaToMask 1090 -#define wxImage_ConvertToGreyscale 1091 -#define wxImage_ConvertToMono 1092 -#define wxImage_Copy 1093 -#define wxImage_Create_3 1094 -#define wxImage_Create_4 1095 -#define wxImage_Create_5 1096 -#define wxImage_Destroy 1097 -#define wxImage_FindFirstUnusedColour 1098 -#define wxImage_GetImageExtWildcard 1099 -#define wxImage_GetAlpha_2 1100 -#define wxImage_GetAlpha_0 1101 -#define wxImage_GetBlue 1102 -#define wxImage_GetData 1103 -#define wxImage_GetGreen 1104 -#define wxImage_GetImageCount 1105 -#define wxImage_GetHeight 1106 -#define wxImage_GetMaskBlue 1107 -#define wxImage_GetMaskGreen 1108 -#define wxImage_GetMaskRed 1109 -#define wxImage_GetOrFindMaskColour 1110 -#define wxImage_GetPalette 1111 -#define wxImage_GetRed 1112 -#define wxImage_GetSubImage 1113 -#define wxImage_GetWidth 1114 -#define wxImage_HasAlpha 1115 -#define wxImage_HasMask 1116 -#define wxImage_GetOption 1117 -#define wxImage_GetOptionInt 1118 -#define wxImage_HasOption 1119 -#define wxImage_InitAlpha 1120 -#define wxImage_InitStandardHandlers 1121 -#define wxImage_IsTransparent 1122 -#define wxImage_LoadFile_2 1123 -#define wxImage_LoadFile_3 1124 -#define wxImage_Ok 1125 -#define wxImage_RemoveHandler 1126 -#define wxImage_Mirror 1127 -#define wxImage_Replace 1128 -#define wxImage_Rescale 1129 -#define wxImage_Resize 1130 -#define wxImage_Rotate 1131 -#define wxImage_RotateHue 1132 -#define wxImage_Rotate90 1133 -#define wxImage_SaveFile_1 1134 -#define wxImage_SaveFile_2_0 1135 -#define wxImage_SaveFile_2_1 1136 -#define wxImage_Scale 1137 -#define wxImage_Size 1138 -#define wxImage_SetAlpha_3 1139 -#define wxImage_SetAlpha_2 1140 -#define wxImage_SetData_2 1141 -#define wxImage_SetData_4 1142 -#define wxImage_SetMask 1143 -#define wxImage_SetMaskColour 1144 -#define wxImage_SetMaskFromImage 1145 -#define wxImage_SetOption_2_1 1146 -#define wxImage_SetOption_2_0 1147 -#define wxImage_SetPalette 1148 -#define wxImage_SetRGB_5 1149 -#define wxImage_SetRGB_4 1150 -#define wxImage_destroy 1151 -#define wxBrush_new_0 1152 -#define wxBrush_new_2 1153 -#define wxBrush_new_1 1154 -#define wxBrush_destruct 1156 -#define wxBrush_GetColour 1157 -#define wxBrush_GetStipple 1158 -#define wxBrush_GetStyle 1159 -#define wxBrush_IsHatch 1160 -#define wxBrush_IsOk 1161 -#define wxBrush_SetColour_1 1162 -#define wxBrush_SetColour_3 1163 -#define wxBrush_SetStipple 1164 -#define wxBrush_SetStyle 1165 -#define wxPen_new_0 1166 -#define wxPen_new_2 1167 -#define wxPen_destruct 1168 -#define wxPen_GetCap 1169 -#define wxPen_GetColour 1170 -#define wxPen_GetJoin 1171 -#define wxPen_GetStyle 1172 -#define wxPen_GetWidth 1173 -#define wxPen_IsOk 1174 -#define wxPen_SetCap 1175 -#define wxPen_SetColour_1 1176 -#define wxPen_SetColour_3 1177 -#define wxPen_SetJoin 1178 -#define wxPen_SetStyle 1179 -#define wxPen_SetWidth 1180 -#define wxRegion_new_0 1181 -#define wxRegion_new_4 1182 -#define wxRegion_new_2 1183 -#define wxRegion_new_1_1 1184 -#define wxRegion_new_1_0 1186 -#define wxRegion_destruct 1188 -#define wxRegion_Clear 1189 -#define wxRegion_Contains_2 1190 -#define wxRegion_Contains_1_0 1191 -#define wxRegion_Contains_4 1192 -#define wxRegion_Contains_1_1 1193 -#define wxRegion_ConvertToBitmap 1194 -#define wxRegion_GetBox 1195 -#define wxRegion_Intersect_4 1196 -#define wxRegion_Intersect_1_1 1197 -#define wxRegion_Intersect_1_0 1198 -#define wxRegion_IsEmpty 1199 -#define wxRegion_Subtract_4 1200 -#define wxRegion_Subtract_1_1 1201 -#define wxRegion_Subtract_1_0 1202 -#define wxRegion_Offset_2 1203 -#define wxRegion_Offset_1 1204 -#define wxRegion_Union_4 1205 -#define wxRegion_Union_1_2 1206 -#define wxRegion_Union_1_1 1207 -#define wxRegion_Union_1_0 1208 -#define wxRegion_Union_3 1209 -#define wxRegion_Xor_4 1210 -#define wxRegion_Xor_1_1 1211 -#define wxRegion_Xor_1_0 1212 -#define wxAcceleratorTable_new_0 1213 -#define wxAcceleratorTable_new_2 1214 -#define wxAcceleratorTable_destruct 1215 -#define wxAcceleratorTable_Ok 1216 -#define wxAcceleratorEntry_new_1_0 1217 -#define wxAcceleratorEntry_new_1_1 1218 -#define wxAcceleratorEntry_GetCommand 1219 -#define wxAcceleratorEntry_GetFlags 1220 -#define wxAcceleratorEntry_GetKeyCode 1221 -#define wxAcceleratorEntry_Set 1222 -#define wxAcceleratorEntry_destroy 1223 -#define wxCaret_new_3 1228 -#define wxCaret_new_2 1229 -#define wxCaret_destruct 1231 -#define wxCaret_Create_3 1232 -#define wxCaret_Create_2 1233 -#define wxCaret_GetBlinkTime 1234 -#define wxCaret_GetPosition 1236 -#define wxCaret_GetSize 1238 -#define wxCaret_GetWindow 1239 -#define wxCaret_Hide 1240 -#define wxCaret_IsOk 1241 -#define wxCaret_IsVisible 1242 -#define wxCaret_Move_2 1243 -#define wxCaret_Move_1 1244 -#define wxCaret_SetBlinkTime 1245 -#define wxCaret_SetSize_2 1246 -#define wxCaret_SetSize_1 1247 -#define wxCaret_Show 1248 -#define wxSizer_Add_2_1 1249 -#define wxSizer_Add_2_0 1250 -#define wxSizer_Add_3 1251 -#define wxSizer_Add_2_3 1252 -#define wxSizer_Add_2_2 1253 -#define wxSizer_AddSpacer 1254 -#define wxSizer_AddStretchSpacer 1255 -#define wxSizer_CalcMin 1256 -#define wxSizer_Clear 1257 -#define wxSizer_Detach_1_2 1258 -#define wxSizer_Detach_1_1 1259 -#define wxSizer_Detach_1_0 1260 -#define wxSizer_Fit 1261 -#define wxSizer_FitInside 1262 -#define wxSizer_GetChildren 1263 -#define wxSizer_GetItem_2_1 1264 -#define wxSizer_GetItem_2_0 1265 -#define wxSizer_GetItem_1 1266 -#define wxSizer_GetSize 1267 -#define wxSizer_GetPosition 1268 -#define wxSizer_GetMinSize 1269 -#define wxSizer_Hide_2_0 1270 -#define wxSizer_Hide_2_1 1271 -#define wxSizer_Hide_1 1272 -#define wxSizer_Insert_3_1 1273 -#define wxSizer_Insert_3_0 1274 -#define wxSizer_Insert_4 1275 -#define wxSizer_Insert_3_3 1276 -#define wxSizer_Insert_3_2 1277 -#define wxSizer_Insert_2 1278 -#define wxSizer_InsertSpacer 1279 -#define wxSizer_InsertStretchSpacer 1280 -#define wxSizer_IsShown_1_2 1281 -#define wxSizer_IsShown_1_1 1282 -#define wxSizer_IsShown_1_0 1283 -#define wxSizer_Layout 1284 -#define wxSizer_Prepend_2_1 1285 -#define wxSizer_Prepend_2_0 1286 -#define wxSizer_Prepend_3 1287 -#define wxSizer_Prepend_2_3 1288 -#define wxSizer_Prepend_2_2 1289 -#define wxSizer_Prepend_1 1290 -#define wxSizer_PrependSpacer 1291 -#define wxSizer_PrependStretchSpacer 1292 -#define wxSizer_RecalcSizes 1293 -#define wxSizer_Remove_1_1 1294 -#define wxSizer_Remove_1_0 1295 -#define wxSizer_Replace_3_1 1296 -#define wxSizer_Replace_3_0 1297 -#define wxSizer_Replace_2 1298 -#define wxSizer_SetDimension 1299 -#define wxSizer_SetMinSize_2 1300 -#define wxSizer_SetMinSize_1 1301 -#define wxSizer_SetItemMinSize_3_2 1302 -#define wxSizer_SetItemMinSize_2_2 1303 -#define wxSizer_SetItemMinSize_3_1 1304 -#define wxSizer_SetItemMinSize_2_1 1305 -#define wxSizer_SetItemMinSize_3_0 1306 -#define wxSizer_SetItemMinSize_2_0 1307 -#define wxSizer_SetSizeHints 1308 -#define wxSizer_SetVirtualSizeHints 1309 -#define wxSizer_Show_2_2 1310 -#define wxSizer_Show_2_1 1311 -#define wxSizer_Show_2_0 1312 -#define wxSizer_Show_1 1313 -#define wxSizerFlags_new 1314 -#define wxSizerFlags_Align 1315 -#define wxSizerFlags_Border_2 1316 -#define wxSizerFlags_Border_1 1317 -#define wxSizerFlags_Center 1318 -#define wxSizerFlags_Centre 1319 -#define wxSizerFlags_Expand 1320 -#define wxSizerFlags_Left 1321 -#define wxSizerFlags_Proportion 1322 -#define wxSizerFlags_Right 1323 -#define wxSizerFlags_destroy 1324 -#define wxSizerItem_new_5_1 1325 -#define wxSizerItem_new_2_1 1326 -#define wxSizerItem_new_5_0 1327 -#define wxSizerItem_new_2_0 1328 -#define wxSizerItem_new_6 1329 -#define wxSizerItem_new_3 1330 -#define wxSizerItem_new_0 1331 -#define wxSizerItem_destruct 1332 -#define wxSizerItem_CalcMin 1333 -#define wxSizerItem_DeleteWindows 1334 -#define wxSizerItem_DetachSizer 1335 -#define wxSizerItem_GetBorder 1336 -#define wxSizerItem_GetFlag 1337 -#define wxSizerItem_GetMinSize 1338 -#define wxSizerItem_GetPosition 1339 -#define wxSizerItem_GetProportion 1340 -#define wxSizerItem_GetRatio 1341 -#define wxSizerItem_GetRect 1342 -#define wxSizerItem_GetSize 1343 -#define wxSizerItem_GetSizer 1344 -#define wxSizerItem_GetSpacer 1345 -#define wxSizerItem_GetUserData 1346 -#define wxSizerItem_GetWindow 1347 -#define wxSizerItem_IsSizer 1348 -#define wxSizerItem_IsShown 1349 -#define wxSizerItem_IsSpacer 1350 -#define wxSizerItem_IsWindow 1351 -#define wxSizerItem_SetBorder 1352 -#define wxSizerItem_SetDimension 1353 -#define wxSizerItem_SetFlag 1354 -#define wxSizerItem_SetInitSize 1355 -#define wxSizerItem_SetMinSize_1 1356 -#define wxSizerItem_SetMinSize_2 1357 -#define wxSizerItem_SetProportion 1358 -#define wxSizerItem_SetRatio_2 1359 -#define wxSizerItem_SetRatio_1_1 1360 -#define wxSizerItem_SetRatio_1_0 1361 -#define wxSizerItem_SetSizer 1362 -#define wxSizerItem_SetSpacer_1 1363 -#define wxSizerItem_SetSpacer_2 1364 -#define wxSizerItem_SetWindow 1365 -#define wxSizerItem_Show 1366 -#define wxBoxSizer_new 1367 -#define wxBoxSizer_GetOrientation 1368 -#define wxBoxSizer_destroy 1369 -#define wxStaticBoxSizer_new_2 1370 -#define wxStaticBoxSizer_new_3 1371 -#define wxStaticBoxSizer_GetStaticBox 1372 -#define wxStaticBoxSizer_destroy 1373 -#define wxGridSizer_new_4 1374 -#define wxGridSizer_new_2 1375 -#define wxGridSizer_GetCols 1376 -#define wxGridSizer_GetHGap 1377 -#define wxGridSizer_GetRows 1378 -#define wxGridSizer_GetVGap 1379 -#define wxGridSizer_SetCols 1380 -#define wxGridSizer_SetHGap 1381 -#define wxGridSizer_SetRows 1382 -#define wxGridSizer_SetVGap 1383 -#define wxGridSizer_destroy 1384 -#define wxFlexGridSizer_new_4 1385 -#define wxFlexGridSizer_new_2 1386 -#define wxFlexGridSizer_AddGrowableCol 1387 -#define wxFlexGridSizer_AddGrowableRow 1388 -#define wxFlexGridSizer_GetFlexibleDirection 1389 -#define wxFlexGridSizer_GetNonFlexibleGrowMode 1390 -#define wxFlexGridSizer_RemoveGrowableCol 1391 -#define wxFlexGridSizer_RemoveGrowableRow 1392 -#define wxFlexGridSizer_SetFlexibleDirection 1393 -#define wxFlexGridSizer_SetNonFlexibleGrowMode 1394 -#define wxFlexGridSizer_destroy 1395 -#define wxGridBagSizer_new 1396 -#define wxGridBagSizer_Add_3_2 1397 -#define wxGridBagSizer_Add_3_1 1398 -#define wxGridBagSizer_Add_4 1399 -#define wxGridBagSizer_Add_1_0 1400 -#define wxGridBagSizer_Add_2_1 1401 -#define wxGridBagSizer_Add_2_0 1402 -#define wxGridBagSizer_Add_3_0 1403 -#define wxGridBagSizer_Add_1_1 1404 -#define wxGridBagSizer_CalcMin 1405 -#define wxGridBagSizer_CheckForIntersection_2 1406 -#define wxGridBagSizer_CheckForIntersection_3 1407 -#define wxGridBagSizer_FindItem_1_1 1408 -#define wxGridBagSizer_FindItem_1_0 1409 -#define wxGridBagSizer_FindItemAtPoint 1410 -#define wxGridBagSizer_FindItemAtPosition 1411 -#define wxGridBagSizer_FindItemWithData 1412 -#define wxGridBagSizer_GetCellSize 1413 -#define wxGridBagSizer_GetEmptyCellSize 1414 -#define wxGridBagSizer_GetItemPosition_1_2 1415 -#define wxGridBagSizer_GetItemPosition_1_1 1416 -#define wxGridBagSizer_GetItemPosition_1_0 1417 -#define wxGridBagSizer_GetItemSpan_1_2 1418 -#define wxGridBagSizer_GetItemSpan_1_1 1419 -#define wxGridBagSizer_GetItemSpan_1_0 1420 -#define wxGridBagSizer_SetEmptyCellSize 1421 -#define wxGridBagSizer_SetItemPosition_2_2 1422 -#define wxGridBagSizer_SetItemPosition_2_1 1423 -#define wxGridBagSizer_SetItemPosition_2_0 1424 -#define wxGridBagSizer_SetItemSpan_2_2 1425 -#define wxGridBagSizer_SetItemSpan_2_1 1426 -#define wxGridBagSizer_SetItemSpan_2_0 1427 -#define wxGridBagSizer_destroy 1428 -#define wxStdDialogButtonSizer_new 1429 -#define wxStdDialogButtonSizer_AddButton 1430 -#define wxStdDialogButtonSizer_Realize 1431 -#define wxStdDialogButtonSizer_SetAffirmativeButton 1432 -#define wxStdDialogButtonSizer_SetCancelButton 1433 -#define wxStdDialogButtonSizer_SetNegativeButton 1434 -#define wxStdDialogButtonSizer_destroy 1435 -#define wxFont_new_0 1436 -#define wxFont_new_1 1437 -#define wxFont_new_5 1438 -#define wxFont_destruct 1440 -#define wxFont_IsFixedWidth 1441 -#define wxFont_GetDefaultEncoding 1442 -#define wxFont_GetFaceName 1443 -#define wxFont_GetFamily 1444 -#define wxFont_GetNativeFontInfoDesc 1445 -#define wxFont_GetNativeFontInfoUserDesc 1446 -#define wxFont_GetPointSize 1447 -#define wxFont_GetStyle 1448 -#define wxFont_GetUnderlined 1449 -#define wxFont_GetWeight 1450 -#define wxFont_Ok 1451 -#define wxFont_SetDefaultEncoding 1452 -#define wxFont_SetFaceName 1453 -#define wxFont_SetFamily 1454 -#define wxFont_SetPointSize 1455 -#define wxFont_SetStyle 1456 -#define wxFont_SetUnderlined 1457 -#define wxFont_SetWeight 1458 -#define wxToolTip_Enable 1459 -#define wxToolTip_SetDelay 1460 -#define wxToolTip_new 1461 -#define wxToolTip_SetTip 1462 -#define wxToolTip_GetTip 1463 -#define wxToolTip_GetWindow 1464 -#define wxToolTip_destroy 1465 -#define wxButton_new_3 1467 -#define wxButton_new_0 1468 -#define wxButton_destruct 1469 -#define wxButton_Create 1470 -#define wxButton_GetDefaultSize 1471 -#define wxButton_SetDefault 1472 -#define wxButton_SetLabel 1473 -#define wxBitmapButton_new_4 1475 -#define wxBitmapButton_new_0 1476 -#define wxBitmapButton_Create 1477 -#define wxBitmapButton_GetBitmapDisabled 1478 -#define wxBitmapButton_GetBitmapFocus 1480 -#define wxBitmapButton_GetBitmapLabel 1482 -#define wxBitmapButton_GetBitmapSelected 1484 -#define wxBitmapButton_SetBitmapDisabled 1486 -#define wxBitmapButton_SetBitmapFocus 1487 -#define wxBitmapButton_SetBitmapLabel 1488 -#define wxBitmapButton_SetBitmapSelected 1489 -#define wxBitmapButton_destroy 1490 -#define wxToggleButton_new_0 1491 -#define wxToggleButton_new_4 1492 -#define wxToggleButton_Create 1493 -#define wxToggleButton_GetValue 1494 -#define wxToggleButton_SetValue 1495 -#define wxToggleButton_destroy 1496 -#define wxCalendarCtrl_new_0 1497 -#define wxCalendarCtrl_new_3 1498 -#define wxCalendarCtrl_Create 1499 -#define wxCalendarCtrl_destruct 1500 -#define wxCalendarCtrl_SetDate 1501 -#define wxCalendarCtrl_GetDate 1502 -#define wxCalendarCtrl_EnableYearChange 1503 -#define wxCalendarCtrl_EnableMonthChange 1504 -#define wxCalendarCtrl_EnableHolidayDisplay 1505 -#define wxCalendarCtrl_SetHeaderColours 1506 -#define wxCalendarCtrl_GetHeaderColourFg 1507 -#define wxCalendarCtrl_GetHeaderColourBg 1508 -#define wxCalendarCtrl_SetHighlightColours 1509 -#define wxCalendarCtrl_GetHighlightColourFg 1510 -#define wxCalendarCtrl_GetHighlightColourBg 1511 -#define wxCalendarCtrl_SetHolidayColours 1512 -#define wxCalendarCtrl_GetHolidayColourFg 1513 -#define wxCalendarCtrl_GetHolidayColourBg 1514 -#define wxCalendarCtrl_GetAttr 1515 -#define wxCalendarCtrl_SetAttr 1516 -#define wxCalendarCtrl_SetHoliday 1517 -#define wxCalendarCtrl_ResetAttr 1518 -#define wxCalendarCtrl_HitTest 1519 -#define wxCalendarDateAttr_new_0 1520 -#define wxCalendarDateAttr_new_2_1 1521 -#define wxCalendarDateAttr_new_2_0 1522 -#define wxCalendarDateAttr_SetTextColour 1523 -#define wxCalendarDateAttr_SetBackgroundColour 1524 -#define wxCalendarDateAttr_SetBorderColour 1525 -#define wxCalendarDateAttr_SetFont 1526 -#define wxCalendarDateAttr_SetBorder 1527 -#define wxCalendarDateAttr_SetHoliday 1528 -#define wxCalendarDateAttr_HasTextColour 1529 -#define wxCalendarDateAttr_HasBackgroundColour 1530 -#define wxCalendarDateAttr_HasBorderColour 1531 -#define wxCalendarDateAttr_HasFont 1532 -#define wxCalendarDateAttr_HasBorder 1533 -#define wxCalendarDateAttr_IsHoliday 1534 -#define wxCalendarDateAttr_GetTextColour 1535 -#define wxCalendarDateAttr_GetBackgroundColour 1536 -#define wxCalendarDateAttr_GetBorderColour 1537 -#define wxCalendarDateAttr_GetFont 1538 -#define wxCalendarDateAttr_GetBorder 1539 -#define wxCalendarDateAttr_destroy 1540 -#define wxCheckBox_new_4 1542 -#define wxCheckBox_new_0 1543 -#define wxCheckBox_Create 1544 -#define wxCheckBox_GetValue 1545 -#define wxCheckBox_Get3StateValue 1546 -#define wxCheckBox_Is3rdStateAllowedForUser 1547 -#define wxCheckBox_Is3State 1548 -#define wxCheckBox_IsChecked 1549 -#define wxCheckBox_SetValue 1550 -#define wxCheckBox_Set3StateValue 1551 -#define wxCheckBox_destroy 1552 -#define wxCheckListBox_new_0 1553 -#define wxCheckListBox_new_3 1555 -#define wxCheckListBox_Check 1556 -#define wxCheckListBox_IsChecked 1557 -#define wxCheckListBox_destroy 1558 -#define wxChoice_new_3 1561 -#define wxChoice_new_0 1562 -#define wxChoice_destruct 1564 -#define wxChoice_Create 1566 -#define wxChoice_Delete 1567 -#define wxChoice_GetColumns 1568 -#define wxChoice_SetColumns 1569 -#define wxComboBox_new_0 1570 -#define wxComboBox_new_3 1572 -#define wxComboBox_destruct 1573 -#define wxComboBox_Create 1575 -#define wxComboBox_CanCopy 1576 -#define wxComboBox_CanCut 1577 -#define wxComboBox_CanPaste 1578 -#define wxComboBox_CanRedo 1579 -#define wxComboBox_CanUndo 1580 -#define wxComboBox_Copy 1581 -#define wxComboBox_Cut 1582 -#define wxComboBox_GetInsertionPoint 1583 -#define wxComboBox_GetLastPosition 1584 -#define wxComboBox_GetValue 1585 -#define wxComboBox_Paste 1586 -#define wxComboBox_Redo 1587 -#define wxComboBox_Replace 1588 -#define wxComboBox_Remove 1589 -#define wxComboBox_SetInsertionPoint 1590 -#define wxComboBox_SetInsertionPointEnd 1591 -#define wxComboBox_SetSelection_1 1592 -#define wxComboBox_SetSelection_2 1593 -#define wxComboBox_SetValue 1594 -#define wxComboBox_Undo 1595 -#define wxGauge_new_0 1596 -#define wxGauge_new_4 1597 -#define wxGauge_Create 1598 -#define wxGauge_GetBezelFace 1599 -#define wxGauge_GetRange 1600 -#define wxGauge_GetShadowWidth 1601 -#define wxGauge_GetValue 1602 -#define wxGauge_IsVertical 1603 -#define wxGauge_SetBezelFace 1604 -#define wxGauge_SetRange 1605 -#define wxGauge_SetShadowWidth 1606 -#define wxGauge_SetValue 1607 -#define wxGauge_Pulse 1608 -#define wxGauge_destroy 1609 -#define wxGenericDirCtrl_new_0 1610 -#define wxGenericDirCtrl_new_2 1611 -#define wxGenericDirCtrl_destruct 1612 -#define wxGenericDirCtrl_Create 1613 -#define wxGenericDirCtrl_Init 1614 -#define wxGenericDirCtrl_CollapseTree 1615 -#define wxGenericDirCtrl_ExpandPath 1616 -#define wxGenericDirCtrl_GetDefaultPath 1617 -#define wxGenericDirCtrl_GetPath 1618 -#define wxGenericDirCtrl_GetFilePath 1619 -#define wxGenericDirCtrl_GetFilter 1620 -#define wxGenericDirCtrl_GetFilterIndex 1621 -#define wxGenericDirCtrl_GetRootId 1622 -#define wxGenericDirCtrl_GetTreeCtrl 1623 -#define wxGenericDirCtrl_ReCreateTree 1624 -#define wxGenericDirCtrl_SetDefaultPath 1625 -#define wxGenericDirCtrl_SetFilter 1626 -#define wxGenericDirCtrl_SetFilterIndex 1627 -#define wxGenericDirCtrl_SetPath 1628 -#define wxStaticBox_new_4 1630 -#define wxStaticBox_new_0 1631 -#define wxStaticBox_Create 1632 -#define wxStaticBox_destroy 1633 -#define wxStaticLine_new_2 1635 -#define wxStaticLine_new_0 1636 -#define wxStaticLine_Create 1637 -#define wxStaticLine_IsVertical 1638 -#define wxStaticLine_GetDefaultSize 1639 -#define wxStaticLine_destroy 1640 -#define wxListBox_new_3 1643 -#define wxListBox_new_0 1644 -#define wxListBox_destruct 1646 -#define wxListBox_Create 1648 -#define wxListBox_Deselect 1649 -#define wxListBox_GetSelections 1650 -#define wxListBox_InsertItems 1651 -#define wxListBox_IsSelected 1652 -#define wxListBox_Set 1654 -#define wxListBox_HitTest 1655 -#define wxListBox_SetFirstItem_1_0 1656 -#define wxListBox_SetFirstItem_1_1 1657 -#define wxListCtrl_new_0 1658 -#define wxListCtrl_new_2 1659 -#define wxListCtrl_Arrange 1660 -#define wxListCtrl_AssignImageList 1661 -#define wxListCtrl_ClearAll 1662 -#define wxListCtrl_Create 1663 -#define wxListCtrl_DeleteAllItems 1664 -#define wxListCtrl_DeleteColumn 1665 -#define wxListCtrl_DeleteItem 1666 -#define wxListCtrl_EditLabel 1667 -#define wxListCtrl_EnsureVisible 1668 -#define wxListCtrl_FindItem_3_0 1669 -#define wxListCtrl_FindItem_3_1 1670 -#define wxListCtrl_GetColumn 1671 -#define wxListCtrl_GetColumnCount 1672 -#define wxListCtrl_GetColumnWidth 1673 -#define wxListCtrl_GetCountPerPage 1674 -#define wxListCtrl_GetEditControl 1675 -#define wxListCtrl_GetImageList 1676 -#define wxListCtrl_GetItem 1677 -#define wxListCtrl_GetItemBackgroundColour 1678 -#define wxListCtrl_GetItemCount 1679 -#define wxListCtrl_GetItemData 1680 -#define wxListCtrl_GetItemFont 1681 -#define wxListCtrl_GetItemPosition 1682 -#define wxListCtrl_GetItemRect 1683 -#define wxListCtrl_GetItemSpacing 1684 -#define wxListCtrl_GetItemState 1685 -#define wxListCtrl_GetItemText 1686 -#define wxListCtrl_GetItemTextColour 1687 -#define wxListCtrl_GetNextItem 1688 -#define wxListCtrl_GetSelectedItemCount 1689 -#define wxListCtrl_GetTextColour 1690 -#define wxListCtrl_GetTopItem 1691 -#define wxListCtrl_GetViewRect 1692 -#define wxListCtrl_HitTest 1693 -#define wxListCtrl_InsertColumn_2 1694 -#define wxListCtrl_InsertColumn_3 1695 -#define wxListCtrl_InsertItem_1 1696 -#define wxListCtrl_InsertItem_2_1 1697 -#define wxListCtrl_InsertItem_2_0 1698 -#define wxListCtrl_InsertItem_3 1699 -#define wxListCtrl_RefreshItem 1700 -#define wxListCtrl_RefreshItems 1701 -#define wxListCtrl_ScrollList 1702 -#define wxListCtrl_SetBackgroundColour 1703 -#define wxListCtrl_SetColumn 1704 -#define wxListCtrl_SetColumnWidth 1705 -#define wxListCtrl_SetImageList 1706 -#define wxListCtrl_SetItem_1 1707 -#define wxListCtrl_SetItem_4 1708 -#define wxListCtrl_SetItemBackgroundColour 1709 -#define wxListCtrl_SetItemCount 1710 -#define wxListCtrl_SetItemData 1711 -#define wxListCtrl_SetItemFont 1712 -#define wxListCtrl_SetItemImage 1713 -#define wxListCtrl_SetItemColumnImage 1714 -#define wxListCtrl_SetItemPosition 1715 -#define wxListCtrl_SetItemState 1716 -#define wxListCtrl_SetItemText 1717 -#define wxListCtrl_SetItemTextColour 1718 -#define wxListCtrl_SetSingleStyle 1719 -#define wxListCtrl_SetTextColour 1720 -#define wxListCtrl_SetWindowStyleFlag 1721 -#define wxListCtrl_SortItems 1722 -#define wxListCtrl_destroy 1723 -#define wxListView_ClearColumnImage 1724 -#define wxListView_Focus 1725 -#define wxListView_GetFirstSelected 1726 -#define wxListView_GetFocusedItem 1727 -#define wxListView_GetNextSelected 1728 -#define wxListView_IsSelected 1729 -#define wxListView_Select 1730 -#define wxListView_SetColumnImage 1731 -#define wxListItem_new_0 1732 -#define wxListItem_new_1 1733 -#define wxListItem_destruct 1734 -#define wxListItem_Clear 1735 -#define wxListItem_GetAlign 1736 -#define wxListItem_GetBackgroundColour 1737 -#define wxListItem_GetColumn 1738 -#define wxListItem_GetFont 1739 -#define wxListItem_GetId 1740 -#define wxListItem_GetImage 1741 -#define wxListItem_GetMask 1742 -#define wxListItem_GetState 1743 -#define wxListItem_GetText 1744 -#define wxListItem_GetTextColour 1745 -#define wxListItem_GetWidth 1746 -#define wxListItem_SetAlign 1747 -#define wxListItem_SetBackgroundColour 1748 -#define wxListItem_SetColumn 1749 -#define wxListItem_SetFont 1750 -#define wxListItem_SetId 1751 -#define wxListItem_SetImage 1752 -#define wxListItem_SetMask 1753 -#define wxListItem_SetState 1754 -#define wxListItem_SetStateMask 1755 -#define wxListItem_SetText 1756 -#define wxListItem_SetTextColour 1757 -#define wxListItem_SetWidth 1758 -#define wxImageList_new_0 1759 -#define wxImageList_new_3 1760 -#define wxImageList_Add_1 1761 -#define wxImageList_Add_2_0 1762 -#define wxImageList_Add_2_1 1763 -#define wxImageList_Create 1764 -#define wxImageList_Draw 1766 -#define wxImageList_GetBitmap 1767 -#define wxImageList_GetIcon 1768 -#define wxImageList_GetImageCount 1769 -#define wxImageList_GetSize 1770 -#define wxImageList_Remove 1771 -#define wxImageList_RemoveAll 1772 -#define wxImageList_Replace_2 1773 -#define wxImageList_Replace_3 1774 -#define wxImageList_destroy 1775 -#define wxTextAttr_new_0 1776 -#define wxTextAttr_new_2 1777 -#define wxTextAttr_GetAlignment 1778 -#define wxTextAttr_GetBackgroundColour 1779 -#define wxTextAttr_GetFont 1780 -#define wxTextAttr_GetLeftIndent 1781 -#define wxTextAttr_GetLeftSubIndent 1782 -#define wxTextAttr_GetRightIndent 1783 -#define wxTextAttr_GetTabs 1784 -#define wxTextAttr_GetTextColour 1785 -#define wxTextAttr_HasBackgroundColour 1786 -#define wxTextAttr_HasFont 1787 -#define wxTextAttr_HasTextColour 1788 -#define wxTextAttr_GetFlags 1789 -#define wxTextAttr_IsDefault 1790 -#define wxTextAttr_SetAlignment 1791 -#define wxTextAttr_SetBackgroundColour 1792 -#define wxTextAttr_SetFlags 1793 -#define wxTextAttr_SetFont 1794 -#define wxTextAttr_SetLeftIndent 1795 -#define wxTextAttr_SetRightIndent 1796 -#define wxTextAttr_SetTabs 1797 -#define wxTextAttr_SetTextColour 1798 -#define wxTextAttr_destroy 1799 -#define wxTextCtrl_new_3 1801 -#define wxTextCtrl_new_0 1802 -#define wxTextCtrl_destruct 1804 -#define wxTextCtrl_AppendText 1805 -#define wxTextCtrl_CanCopy 1806 -#define wxTextCtrl_CanCut 1807 -#define wxTextCtrl_CanPaste 1808 -#define wxTextCtrl_CanRedo 1809 -#define wxTextCtrl_CanUndo 1810 -#define wxTextCtrl_Clear 1811 -#define wxTextCtrl_Copy 1812 -#define wxTextCtrl_Create 1813 -#define wxTextCtrl_Cut 1814 -#define wxTextCtrl_DiscardEdits 1815 -#define wxTextCtrl_EmulateKeyPress 1816 -#define wxTextCtrl_GetDefaultStyle 1817 -#define wxTextCtrl_GetInsertionPoint 1818 -#define wxTextCtrl_GetLastPosition 1819 -#define wxTextCtrl_GetLineLength 1820 -#define wxTextCtrl_GetLineText 1821 -#define wxTextCtrl_GetNumberOfLines 1822 -#define wxTextCtrl_GetRange 1823 -#define wxTextCtrl_GetSelection 1824 -#define wxTextCtrl_GetStringSelection 1825 -#define wxTextCtrl_GetStyle 1826 -#define wxTextCtrl_GetValue 1827 -#define wxTextCtrl_IsEditable 1828 -#define wxTextCtrl_IsModified 1829 -#define wxTextCtrl_IsMultiLine 1830 -#define wxTextCtrl_IsSingleLine 1831 -#define wxTextCtrl_LoadFile 1832 -#define wxTextCtrl_MarkDirty 1833 -#define wxTextCtrl_Paste 1834 -#define wxTextCtrl_PositionToXY 1835 -#define wxTextCtrl_Redo 1836 -#define wxTextCtrl_Remove 1837 -#define wxTextCtrl_Replace 1838 -#define wxTextCtrl_SaveFile 1839 -#define wxTextCtrl_SetDefaultStyle 1840 -#define wxTextCtrl_SetEditable 1841 -#define wxTextCtrl_SetInsertionPoint 1842 -#define wxTextCtrl_SetInsertionPointEnd 1843 -#define wxTextCtrl_SetMaxLength 1845 -#define wxTextCtrl_SetSelection 1846 -#define wxTextCtrl_SetStyle 1847 -#define wxTextCtrl_SetValue 1848 -#define wxTextCtrl_ShowPosition 1849 -#define wxTextCtrl_Undo 1850 -#define wxTextCtrl_WriteText 1851 -#define wxTextCtrl_XYToPosition 1852 -#define wxNotebook_new_0 1855 -#define wxNotebook_new_3 1856 -#define wxNotebook_destruct 1857 -#define wxNotebook_AddPage 1858 -#define wxNotebook_AdvanceSelection 1859 -#define wxNotebook_AssignImageList 1860 -#define wxNotebook_Create 1861 -#define wxNotebook_DeleteAllPages 1862 -#define wxNotebook_DeletePage 1863 -#define wxNotebook_RemovePage 1864 -#define wxNotebook_GetCurrentPage 1865 -#define wxNotebook_GetImageList 1866 -#define wxNotebook_GetPage 1868 -#define wxNotebook_GetPageCount 1869 -#define wxNotebook_GetPageImage 1870 -#define wxNotebook_GetPageText 1871 -#define wxNotebook_GetRowCount 1872 -#define wxNotebook_GetSelection 1873 -#define wxNotebook_GetThemeBackgroundColour 1874 -#define wxNotebook_HitTest 1876 -#define wxNotebook_InsertPage 1878 -#define wxNotebook_SetImageList 1879 -#define wxNotebook_SetPadding 1880 -#define wxNotebook_SetPageSize 1881 -#define wxNotebook_SetPageImage 1882 -#define wxNotebook_SetPageText 1883 -#define wxNotebook_SetSelection 1884 -#define wxNotebook_ChangeSelection 1885 -#define wxChoicebook_new_0 1886 -#define wxChoicebook_new_3 1887 -#define wxChoicebook_AddPage 1888 -#define wxChoicebook_AdvanceSelection 1889 -#define wxChoicebook_AssignImageList 1890 -#define wxChoicebook_Create 1891 -#define wxChoicebook_DeleteAllPages 1892 -#define wxChoicebook_DeletePage 1893 -#define wxChoicebook_RemovePage 1894 -#define wxChoicebook_GetCurrentPage 1895 -#define wxChoicebook_GetImageList 1896 -#define wxChoicebook_GetPage 1898 -#define wxChoicebook_GetPageCount 1899 -#define wxChoicebook_GetPageImage 1900 -#define wxChoicebook_GetPageText 1901 -#define wxChoicebook_GetSelection 1902 -#define wxChoicebook_HitTest 1903 -#define wxChoicebook_InsertPage 1904 -#define wxChoicebook_SetImageList 1905 -#define wxChoicebook_SetPageSize 1906 -#define wxChoicebook_SetPageImage 1907 -#define wxChoicebook_SetPageText 1908 -#define wxChoicebook_SetSelection 1909 -#define wxChoicebook_ChangeSelection 1910 -#define wxChoicebook_destroy 1911 -#define wxToolbook_new_0 1912 -#define wxToolbook_new_3 1913 -#define wxToolbook_AddPage 1914 -#define wxToolbook_AdvanceSelection 1915 -#define wxToolbook_AssignImageList 1916 -#define wxToolbook_Create 1917 -#define wxToolbook_DeleteAllPages 1918 -#define wxToolbook_DeletePage 1919 -#define wxToolbook_RemovePage 1920 -#define wxToolbook_GetCurrentPage 1921 -#define wxToolbook_GetImageList 1922 -#define wxToolbook_GetPage 1924 -#define wxToolbook_GetPageCount 1925 -#define wxToolbook_GetPageImage 1926 -#define wxToolbook_GetPageText 1927 -#define wxToolbook_GetSelection 1928 -#define wxToolbook_HitTest 1930 -#define wxToolbook_InsertPage 1931 -#define wxToolbook_SetImageList 1932 -#define wxToolbook_SetPageSize 1933 -#define wxToolbook_SetPageImage 1934 -#define wxToolbook_SetPageText 1935 -#define wxToolbook_SetSelection 1936 -#define wxToolbook_ChangeSelection 1937 -#define wxToolbook_destroy 1938 -#define wxListbook_new_0 1939 -#define wxListbook_new_3 1940 -#define wxListbook_AddPage 1941 -#define wxListbook_AdvanceSelection 1942 -#define wxListbook_AssignImageList 1943 -#define wxListbook_Create 1944 -#define wxListbook_DeleteAllPages 1945 -#define wxListbook_DeletePage 1946 -#define wxListbook_RemovePage 1947 -#define wxListbook_GetCurrentPage 1948 -#define wxListbook_GetImageList 1949 -#define wxListbook_GetPage 1951 -#define wxListbook_GetPageCount 1952 -#define wxListbook_GetPageImage 1953 -#define wxListbook_GetPageText 1954 -#define wxListbook_GetSelection 1955 -#define wxListbook_HitTest 1957 -#define wxListbook_InsertPage 1958 -#define wxListbook_SetImageList 1959 -#define wxListbook_SetPageSize 1960 -#define wxListbook_SetPageImage 1961 -#define wxListbook_SetPageText 1962 -#define wxListbook_SetSelection 1963 -#define wxListbook_ChangeSelection 1964 -#define wxListbook_destroy 1965 -#define wxTreebook_new_0 1966 -#define wxTreebook_new_3 1967 -#define wxTreebook_AddPage 1968 -#define wxTreebook_AdvanceSelection 1969 -#define wxTreebook_AssignImageList 1970 -#define wxTreebook_Create 1971 -#define wxTreebook_DeleteAllPages 1972 -#define wxTreebook_DeletePage 1973 -#define wxTreebook_RemovePage 1974 -#define wxTreebook_GetCurrentPage 1975 -#define wxTreebook_GetImageList 1976 -#define wxTreebook_GetPage 1978 -#define wxTreebook_GetPageCount 1979 -#define wxTreebook_GetPageImage 1980 -#define wxTreebook_GetPageText 1981 -#define wxTreebook_GetSelection 1982 -#define wxTreebook_ExpandNode 1983 -#define wxTreebook_IsNodeExpanded 1984 -#define wxTreebook_HitTest 1986 -#define wxTreebook_InsertPage 1987 -#define wxTreebook_InsertSubPage 1988 -#define wxTreebook_SetImageList 1989 -#define wxTreebook_SetPageSize 1990 -#define wxTreebook_SetPageImage 1991 -#define wxTreebook_SetPageText 1992 -#define wxTreebook_SetSelection 1993 -#define wxTreebook_ChangeSelection 1994 -#define wxTreebook_destroy 1995 -#define wxTreeCtrl_new_2 1998 -#define wxTreeCtrl_new_0 1999 -#define wxTreeCtrl_destruct 2001 -#define wxTreeCtrl_AddRoot 2002 -#define wxTreeCtrl_AppendItem 2003 -#define wxTreeCtrl_AssignImageList 2004 -#define wxTreeCtrl_AssignStateImageList 2005 -#define wxTreeCtrl_Collapse 2006 -#define wxTreeCtrl_CollapseAndReset 2007 -#define wxTreeCtrl_Create 2008 -#define wxTreeCtrl_Delete 2009 -#define wxTreeCtrl_DeleteAllItems 2010 -#define wxTreeCtrl_DeleteChildren 2011 -#define wxTreeCtrl_EnsureVisible 2012 -#define wxTreeCtrl_Expand 2013 -#define wxTreeCtrl_GetBoundingRect 2014 -#define wxTreeCtrl_GetChildrenCount 2016 -#define wxTreeCtrl_GetCount 2017 -#define wxTreeCtrl_GetEditControl 2018 -#define wxTreeCtrl_GetFirstChild 2019 -#define wxTreeCtrl_GetNextChild 2020 -#define wxTreeCtrl_GetFirstVisibleItem 2021 -#define wxTreeCtrl_GetImageList 2022 -#define wxTreeCtrl_GetIndent 2023 -#define wxTreeCtrl_GetItemBackgroundColour 2024 -#define wxTreeCtrl_GetItemData 2025 -#define wxTreeCtrl_GetItemFont 2026 -#define wxTreeCtrl_GetItemImage_1 2027 -#define wxTreeCtrl_GetItemImage_2 2028 -#define wxTreeCtrl_GetItemText 2029 -#define wxTreeCtrl_GetItemTextColour 2030 -#define wxTreeCtrl_GetLastChild 2031 -#define wxTreeCtrl_GetNextSibling 2032 -#define wxTreeCtrl_GetNextVisible 2033 -#define wxTreeCtrl_GetItemParent 2034 -#define wxTreeCtrl_GetPrevSibling 2035 -#define wxTreeCtrl_GetPrevVisible 2036 -#define wxTreeCtrl_GetRootItem 2037 -#define wxTreeCtrl_GetSelection 2038 -#define wxTreeCtrl_GetSelections 2039 -#define wxTreeCtrl_GetStateImageList 2040 -#define wxTreeCtrl_HitTest 2041 -#define wxTreeCtrl_InsertItem 2043 -#define wxTreeCtrl_IsBold 2044 -#define wxTreeCtrl_IsExpanded 2045 -#define wxTreeCtrl_IsSelected 2046 -#define wxTreeCtrl_IsVisible 2047 -#define wxTreeCtrl_ItemHasChildren 2048 -#define wxTreeCtrl_PrependItem 2049 -#define wxTreeCtrl_ScrollTo 2050 -#define wxTreeCtrl_SelectItem_1 2051 -#define wxTreeCtrl_SelectItem_2 2052 -#define wxTreeCtrl_SetIndent 2053 -#define wxTreeCtrl_SetImageList 2054 -#define wxTreeCtrl_SetItemBackgroundColour 2055 -#define wxTreeCtrl_SetItemBold 2056 -#define wxTreeCtrl_SetItemData 2057 -#define wxTreeCtrl_SetItemDropHighlight 2058 -#define wxTreeCtrl_SetItemFont 2059 -#define wxTreeCtrl_SetItemHasChildren 2060 -#define wxTreeCtrl_SetItemImage_2 2061 -#define wxTreeCtrl_SetItemImage_3 2062 -#define wxTreeCtrl_SetItemText 2063 -#define wxTreeCtrl_SetItemTextColour 2064 -#define wxTreeCtrl_SetStateImageList 2065 -#define wxTreeCtrl_SetWindowStyle 2066 -#define wxTreeCtrl_SortChildren 2067 -#define wxTreeCtrl_Toggle 2068 -#define wxTreeCtrl_ToggleItemSelection 2069 -#define wxTreeCtrl_Unselect 2070 -#define wxTreeCtrl_UnselectAll 2071 -#define wxTreeCtrl_UnselectItem 2072 -#define wxScrollBar_new_0 2073 -#define wxScrollBar_new_3 2074 -#define wxScrollBar_destruct 2075 -#define wxScrollBar_Create 2076 -#define wxScrollBar_GetRange 2077 -#define wxScrollBar_GetPageSize 2078 -#define wxScrollBar_GetThumbPosition 2079 -#define wxScrollBar_GetThumbSize 2080 -#define wxScrollBar_SetThumbPosition 2081 -#define wxScrollBar_SetScrollbar 2082 -#define wxSpinButton_new_2 2084 -#define wxSpinButton_new_0 2085 -#define wxSpinButton_Create 2086 -#define wxSpinButton_GetMax 2087 -#define wxSpinButton_GetMin 2088 -#define wxSpinButton_GetValue 2089 -#define wxSpinButton_SetRange 2090 -#define wxSpinButton_SetValue 2091 -#define wxSpinButton_destroy 2092 -#define wxSpinCtrl_new_0 2093 -#define wxSpinCtrl_new_2 2094 -#define wxSpinCtrl_Create 2096 -#define wxSpinCtrl_SetValue_1_1 2099 -#define wxSpinCtrl_SetValue_1_0 2100 -#define wxSpinCtrl_GetValue 2102 -#define wxSpinCtrl_SetRange 2104 -#define wxSpinCtrl_SetSelection 2105 -#define wxSpinCtrl_GetMin 2107 -#define wxSpinCtrl_GetMax 2109 -#define wxSpinCtrl_destroy 2110 -#define wxStaticText_new_0 2111 -#define wxStaticText_new_4 2112 -#define wxStaticText_Create 2113 -#define wxStaticText_GetLabel 2114 -#define wxStaticText_SetLabel 2115 -#define wxStaticText_Wrap 2116 -#define wxStaticText_destroy 2117 -#define wxStaticBitmap_new_0 2118 -#define wxStaticBitmap_new_4 2119 -#define wxStaticBitmap_Create 2120 -#define wxStaticBitmap_GetBitmap 2121 -#define wxStaticBitmap_SetBitmap 2122 -#define wxStaticBitmap_destroy 2123 -#define wxRadioBox_new 2124 -#define wxRadioBox_destruct 2126 -#define wxRadioBox_Create 2127 -#define wxRadioBox_Enable_2 2128 -#define wxRadioBox_Enable_1 2129 -#define wxRadioBox_GetSelection 2130 -#define wxRadioBox_GetString 2131 -#define wxRadioBox_SetSelection 2132 -#define wxRadioBox_Show_2 2133 -#define wxRadioBox_Show_1 2134 -#define wxRadioBox_GetColumnCount 2135 -#define wxRadioBox_GetItemHelpText 2136 -#define wxRadioBox_GetItemToolTip 2137 -#define wxRadioBox_GetItemFromPoint 2139 -#define wxRadioBox_GetRowCount 2140 -#define wxRadioBox_IsItemEnabled 2141 -#define wxRadioBox_IsItemShown 2142 -#define wxRadioBox_SetItemHelpText 2143 -#define wxRadioBox_SetItemToolTip 2144 -#define wxRadioButton_new_0 2145 -#define wxRadioButton_new_4 2146 -#define wxRadioButton_Create 2147 -#define wxRadioButton_GetValue 2148 -#define wxRadioButton_SetValue 2149 -#define wxRadioButton_destroy 2150 -#define wxSlider_new_6 2152 -#define wxSlider_new_0 2153 -#define wxSlider_Create 2154 -#define wxSlider_GetLineSize 2155 -#define wxSlider_GetMax 2156 -#define wxSlider_GetMin 2157 -#define wxSlider_GetPageSize 2158 -#define wxSlider_GetThumbLength 2159 -#define wxSlider_GetValue 2160 -#define wxSlider_SetLineSize 2161 -#define wxSlider_SetPageSize 2162 -#define wxSlider_SetRange 2163 -#define wxSlider_SetThumbLength 2164 -#define wxSlider_SetValue 2165 -#define wxSlider_destroy 2166 -#define wxDialog_new_4 2168 -#define wxDialog_new_0 2169 -#define wxDialog_destruct 2171 -#define wxDialog_Create 2172 -#define wxDialog_CreateButtonSizer 2173 -#define wxDialog_CreateStdDialogButtonSizer 2174 -#define wxDialog_EndModal 2175 -#define wxDialog_GetAffirmativeId 2176 -#define wxDialog_GetReturnCode 2177 -#define wxDialog_IsModal 2178 -#define wxDialog_SetAffirmativeId 2179 -#define wxDialog_SetReturnCode 2180 -#define wxDialog_Show 2181 -#define wxDialog_ShowModal 2182 -#define wxColourDialog_new_0 2183 -#define wxColourDialog_new_2 2184 -#define wxColourDialog_destruct 2185 -#define wxColourDialog_Create 2186 -#define wxColourDialog_GetColourData 2187 -#define wxColourData_new_0 2188 -#define wxColourData_new_1 2189 -#define wxColourData_destruct 2190 -#define wxColourData_GetChooseFull 2191 -#define wxColourData_GetColour 2192 -#define wxColourData_GetCustomColour 2194 -#define wxColourData_SetChooseFull 2195 -#define wxColourData_SetColour 2196 -#define wxColourData_SetCustomColour 2197 -#define wxPalette_new_0 2198 -#define wxPalette_new_4 2199 -#define wxPalette_destruct 2201 -#define wxPalette_Create 2202 -#define wxPalette_GetColoursCount 2203 -#define wxPalette_GetPixel 2204 -#define wxPalette_GetRGB 2205 -#define wxPalette_IsOk 2206 -#define wxDirDialog_new 2210 -#define wxDirDialog_destruct 2211 -#define wxDirDialog_GetPath 2212 -#define wxDirDialog_GetMessage 2213 -#define wxDirDialog_SetMessage 2214 -#define wxDirDialog_SetPath 2215 -#define wxFileDialog_new 2219 -#define wxFileDialog_destruct 2220 -#define wxFileDialog_GetDirectory 2221 -#define wxFileDialog_GetFilename 2222 -#define wxFileDialog_GetFilenames 2223 -#define wxFileDialog_GetFilterIndex 2224 -#define wxFileDialog_GetMessage 2225 -#define wxFileDialog_GetPath 2226 -#define wxFileDialog_GetPaths 2227 -#define wxFileDialog_GetWildcard 2228 -#define wxFileDialog_SetDirectory 2229 -#define wxFileDialog_SetFilename 2230 -#define wxFileDialog_SetFilterIndex 2231 -#define wxFileDialog_SetMessage 2232 -#define wxFileDialog_SetPath 2233 -#define wxFileDialog_SetWildcard 2234 -#define wxPickerBase_SetInternalMargin 2235 -#define wxPickerBase_GetInternalMargin 2236 -#define wxPickerBase_SetTextCtrlProportion 2237 -#define wxPickerBase_SetPickerCtrlProportion 2238 -#define wxPickerBase_GetTextCtrlProportion 2239 -#define wxPickerBase_GetPickerCtrlProportion 2240 -#define wxPickerBase_HasTextCtrl 2241 -#define wxPickerBase_GetTextCtrl 2242 -#define wxPickerBase_IsTextCtrlGrowable 2243 -#define wxPickerBase_SetPickerCtrlGrowable 2244 -#define wxPickerBase_SetTextCtrlGrowable 2245 -#define wxPickerBase_IsPickerCtrlGrowable 2246 -#define wxFilePickerCtrl_new_0 2247 -#define wxFilePickerCtrl_new_3 2248 -#define wxFilePickerCtrl_Create 2249 -#define wxFilePickerCtrl_GetPath 2250 -#define wxFilePickerCtrl_SetPath 2251 -#define wxFilePickerCtrl_destroy 2252 -#define wxDirPickerCtrl_new_0 2253 -#define wxDirPickerCtrl_new_3 2254 -#define wxDirPickerCtrl_Create 2255 -#define wxDirPickerCtrl_GetPath 2256 -#define wxDirPickerCtrl_SetPath 2257 -#define wxDirPickerCtrl_destroy 2258 -#define wxColourPickerCtrl_new_0 2259 -#define wxColourPickerCtrl_new_3 2260 -#define wxColourPickerCtrl_Create 2261 -#define wxColourPickerCtrl_GetColour 2262 -#define wxColourPickerCtrl_SetColour_1_1 2263 -#define wxColourPickerCtrl_SetColour_1_0 2264 -#define wxColourPickerCtrl_destroy 2265 -#define wxDatePickerCtrl_new_0 2266 -#define wxDatePickerCtrl_new_3 2267 -#define wxDatePickerCtrl_GetRange 2268 -#define wxDatePickerCtrl_GetValue 2269 -#define wxDatePickerCtrl_SetRange 2270 -#define wxDatePickerCtrl_SetValue 2271 -#define wxDatePickerCtrl_destroy 2272 -#define wxFontPickerCtrl_new_0 2273 -#define wxFontPickerCtrl_new_3 2274 -#define wxFontPickerCtrl_Create 2275 -#define wxFontPickerCtrl_GetSelectedFont 2276 -#define wxFontPickerCtrl_SetSelectedFont 2277 -#define wxFontPickerCtrl_GetMaxPointSize 2278 -#define wxFontPickerCtrl_SetMaxPointSize 2279 -#define wxFontPickerCtrl_destroy 2280 -#define wxFindReplaceDialog_new_0 2283 -#define wxFindReplaceDialog_new_4 2284 -#define wxFindReplaceDialog_destruct 2285 -#define wxFindReplaceDialog_Create 2286 -#define wxFindReplaceDialog_GetData 2287 -#define wxFindReplaceData_new_0 2288 -#define wxFindReplaceData_new_1 2289 -#define wxFindReplaceData_GetFindString 2290 -#define wxFindReplaceData_GetReplaceString 2291 -#define wxFindReplaceData_GetFlags 2292 -#define wxFindReplaceData_SetFlags 2293 -#define wxFindReplaceData_SetFindString 2294 -#define wxFindReplaceData_SetReplaceString 2295 -#define wxFindReplaceData_destroy 2296 -#define wxMultiChoiceDialog_new_0 2297 -#define wxMultiChoiceDialog_new_5 2299 -#define wxMultiChoiceDialog_GetSelections 2300 -#define wxMultiChoiceDialog_SetSelections 2301 -#define wxMultiChoiceDialog_destroy 2302 -#define wxSingleChoiceDialog_new_0 2303 -#define wxSingleChoiceDialog_new_5 2305 -#define wxSingleChoiceDialog_GetSelection 2306 -#define wxSingleChoiceDialog_GetStringSelection 2307 -#define wxSingleChoiceDialog_SetSelection 2308 -#define wxSingleChoiceDialog_destroy 2309 -#define wxTextEntryDialog_new 2310 -#define wxTextEntryDialog_GetValue 2311 -#define wxTextEntryDialog_SetValue 2312 -#define wxTextEntryDialog_destroy 2313 -#define wxPasswordEntryDialog_new 2314 -#define wxPasswordEntryDialog_destroy 2315 -#define wxFontData_new_0 2316 -#define wxFontData_new_1 2317 -#define wxFontData_destruct 2318 -#define wxFontData_EnableEffects 2319 -#define wxFontData_GetAllowSymbols 2320 -#define wxFontData_GetColour 2321 -#define wxFontData_GetChosenFont 2322 -#define wxFontData_GetEnableEffects 2323 -#define wxFontData_GetInitialFont 2324 -#define wxFontData_GetShowHelp 2325 -#define wxFontData_SetAllowSymbols 2326 -#define wxFontData_SetChosenFont 2327 -#define wxFontData_SetColour 2328 -#define wxFontData_SetInitialFont 2329 -#define wxFontData_SetRange 2330 -#define wxFontData_SetShowHelp 2331 -#define wxFontDialog_new_0 2335 -#define wxFontDialog_new_2 2337 -#define wxFontDialog_Create 2339 -#define wxFontDialog_GetFontData 2340 -#define wxFontDialog_destroy 2342 -#define wxProgressDialog_new 2343 -#define wxProgressDialog_destruct 2344 -#define wxProgressDialog_Resume 2345 -#define wxProgressDialog_Update_2 2346 -#define wxProgressDialog_Update_0 2347 -#define wxMessageDialog_new 2348 -#define wxMessageDialog_destruct 2349 -#define wxPageSetupDialog_new 2350 -#define wxPageSetupDialog_destruct 2351 -#define wxPageSetupDialog_GetPageSetupData 2352 -#define wxPageSetupDialog_ShowModal 2353 -#define wxPageSetupDialogData_new_0 2354 -#define wxPageSetupDialogData_new_1_0 2355 -#define wxPageSetupDialogData_new_1_1 2356 -#define wxPageSetupDialogData_destruct 2357 -#define wxPageSetupDialogData_EnableHelp 2358 -#define wxPageSetupDialogData_EnableMargins 2359 -#define wxPageSetupDialogData_EnableOrientation 2360 -#define wxPageSetupDialogData_EnablePaper 2361 -#define wxPageSetupDialogData_EnablePrinter 2362 -#define wxPageSetupDialogData_GetDefaultMinMargins 2363 -#define wxPageSetupDialogData_GetEnableMargins 2364 -#define wxPageSetupDialogData_GetEnableOrientation 2365 -#define wxPageSetupDialogData_GetEnablePaper 2366 -#define wxPageSetupDialogData_GetEnablePrinter 2367 -#define wxPageSetupDialogData_GetEnableHelp 2368 -#define wxPageSetupDialogData_GetDefaultInfo 2369 -#define wxPageSetupDialogData_GetMarginTopLeft 2370 -#define wxPageSetupDialogData_GetMarginBottomRight 2371 -#define wxPageSetupDialogData_GetMinMarginTopLeft 2372 -#define wxPageSetupDialogData_GetMinMarginBottomRight 2373 -#define wxPageSetupDialogData_GetPaperId 2374 -#define wxPageSetupDialogData_GetPaperSize 2375 -#define wxPageSetupDialogData_GetPrintData 2377 -#define wxPageSetupDialogData_IsOk 2378 -#define wxPageSetupDialogData_SetDefaultInfo 2379 -#define wxPageSetupDialogData_SetDefaultMinMargins 2380 -#define wxPageSetupDialogData_SetMarginTopLeft 2381 -#define wxPageSetupDialogData_SetMarginBottomRight 2382 -#define wxPageSetupDialogData_SetMinMarginTopLeft 2383 -#define wxPageSetupDialogData_SetMinMarginBottomRight 2384 -#define wxPageSetupDialogData_SetPaperId 2385 -#define wxPageSetupDialogData_SetPaperSize_1_1 2386 -#define wxPageSetupDialogData_SetPaperSize_1_0 2387 -#define wxPageSetupDialogData_SetPrintData 2388 -#define wxPrintDialog_new_2_0 2389 -#define wxPrintDialog_new_2_1 2390 -#define wxPrintDialog_destruct 2391 -#define wxPrintDialog_GetPrintDialogData 2392 -#define wxPrintDialog_GetPrintDC 2393 -#define wxPrintDialogData_new_0 2394 -#define wxPrintDialogData_new_1_1 2395 -#define wxPrintDialogData_new_1_0 2396 -#define wxPrintDialogData_destruct 2397 -#define wxPrintDialogData_EnableHelp 2398 -#define wxPrintDialogData_EnablePageNumbers 2399 -#define wxPrintDialogData_EnablePrintToFile 2400 -#define wxPrintDialogData_EnableSelection 2401 -#define wxPrintDialogData_GetAllPages 2402 -#define wxPrintDialogData_GetCollate 2403 -#define wxPrintDialogData_GetFromPage 2404 -#define wxPrintDialogData_GetMaxPage 2405 -#define wxPrintDialogData_GetMinPage 2406 -#define wxPrintDialogData_GetNoCopies 2407 -#define wxPrintDialogData_GetPrintData 2408 -#define wxPrintDialogData_GetPrintToFile 2409 -#define wxPrintDialogData_GetSelection 2410 -#define wxPrintDialogData_GetToPage 2411 -#define wxPrintDialogData_IsOk 2412 -#define wxPrintDialogData_SetCollate 2413 -#define wxPrintDialogData_SetFromPage 2414 -#define wxPrintDialogData_SetMaxPage 2415 -#define wxPrintDialogData_SetMinPage 2416 -#define wxPrintDialogData_SetNoCopies 2417 -#define wxPrintDialogData_SetPrintData 2418 -#define wxPrintDialogData_SetPrintToFile 2419 -#define wxPrintDialogData_SetSelection 2420 -#define wxPrintDialogData_SetToPage 2421 -#define wxPrintData_new_0 2422 -#define wxPrintData_new_1 2423 -#define wxPrintData_destruct 2424 -#define wxPrintData_GetCollate 2425 -#define wxPrintData_GetBin 2426 -#define wxPrintData_GetColour 2427 -#define wxPrintData_GetDuplex 2428 -#define wxPrintData_GetNoCopies 2429 -#define wxPrintData_GetOrientation 2430 -#define wxPrintData_GetPaperId 2431 -#define wxPrintData_GetPrinterName 2432 -#define wxPrintData_GetQuality 2433 -#define wxPrintData_IsOk 2434 -#define wxPrintData_SetBin 2435 -#define wxPrintData_SetCollate 2436 -#define wxPrintData_SetColour 2437 -#define wxPrintData_SetDuplex 2438 -#define wxPrintData_SetNoCopies 2439 -#define wxPrintData_SetOrientation 2440 -#define wxPrintData_SetPaperId 2441 -#define wxPrintData_SetPrinterName 2442 -#define wxPrintData_SetQuality 2443 -#define wxPrintPreview_new_2 2446 -#define wxPrintPreview_new_3 2447 -#define wxPrintPreview_destruct 2449 -#define wxPrintPreview_GetCanvas 2450 -#define wxPrintPreview_GetCurrentPage 2451 -#define wxPrintPreview_GetFrame 2452 -#define wxPrintPreview_GetMaxPage 2453 -#define wxPrintPreview_GetMinPage 2454 -#define wxPrintPreview_GetPrintout 2455 -#define wxPrintPreview_GetPrintoutForPrinting 2456 -#define wxPrintPreview_IsOk 2457 -#define wxPrintPreview_PaintPage 2458 -#define wxPrintPreview_Print 2459 -#define wxPrintPreview_RenderPage 2460 -#define wxPrintPreview_SetCanvas 2461 -#define wxPrintPreview_SetCurrentPage 2462 -#define wxPrintPreview_SetFrame 2463 -#define wxPrintPreview_SetPrintout 2464 -#define wxPrintPreview_SetZoom 2465 -#define wxPreviewFrame_new 2466 -#define wxPreviewFrame_destruct 2467 -#define wxPreviewFrame_CreateControlBar 2468 -#define wxPreviewFrame_CreateCanvas 2469 -#define wxPreviewFrame_Initialize 2470 -#define wxPreviewFrame_OnCloseWindow 2471 -#define wxPreviewControlBar_new 2472 -#define wxPreviewControlBar_destruct 2473 -#define wxPreviewControlBar_CreateButtons 2474 -#define wxPreviewControlBar_GetPrintPreview 2475 -#define wxPreviewControlBar_GetZoomControl 2476 -#define wxPreviewControlBar_SetZoomControl 2477 -#define wxPrinter_new 2479 -#define wxPrinter_CreateAbortWindow 2480 -#define wxPrinter_GetAbort 2481 -#define wxPrinter_GetLastError 2482 -#define wxPrinter_GetPrintDialogData 2483 -#define wxPrinter_Print 2484 -#define wxPrinter_PrintDialog 2485 -#define wxPrinter_ReportError 2486 -#define wxPrinter_Setup 2487 -#define wxPrinter_destroy 2488 -#define wxXmlResource_new_1 2489 -#define wxXmlResource_new_2 2490 -#define wxXmlResource_destruct 2491 -#define wxXmlResource_AttachUnknownControl 2492 -#define wxXmlResource_ClearHandlers 2493 -#define wxXmlResource_CompareVersion 2494 -#define wxXmlResource_Get 2495 -#define wxXmlResource_GetFlags 2496 -#define wxXmlResource_GetVersion 2497 -#define wxXmlResource_GetXRCID 2498 -#define wxXmlResource_InitAllHandlers 2499 -#define wxXmlResource_Load 2500 -#define wxXmlResource_LoadBitmap 2501 -#define wxXmlResource_LoadDialog_2 2502 -#define wxXmlResource_LoadDialog_3 2503 -#define wxXmlResource_LoadFrame_2 2504 -#define wxXmlResource_LoadFrame_3 2505 -#define wxXmlResource_LoadIcon 2506 -#define wxXmlResource_LoadMenu 2507 -#define wxXmlResource_LoadMenuBar_2 2508 -#define wxXmlResource_LoadMenuBar_1 2509 -#define wxXmlResource_LoadPanel_2 2510 -#define wxXmlResource_LoadPanel_3 2511 -#define wxXmlResource_LoadToolBar 2512 -#define wxXmlResource_Set 2513 -#define wxXmlResource_SetFlags 2514 -#define wxXmlResource_Unload 2515 -#define wxXmlResource_xrcctrl 2516 -#define wxHtmlEasyPrinting_new 2517 -#define wxHtmlEasyPrinting_destruct 2518 -#define wxHtmlEasyPrinting_GetPrintData 2519 -#define wxHtmlEasyPrinting_GetPageSetupData 2520 -#define wxHtmlEasyPrinting_PreviewFile 2521 -#define wxHtmlEasyPrinting_PreviewText 2522 -#define wxHtmlEasyPrinting_PrintFile 2523 -#define wxHtmlEasyPrinting_PrintText 2524 -#define wxHtmlEasyPrinting_PageSetup 2525 -#define wxHtmlEasyPrinting_SetFonts 2526 -#define wxHtmlEasyPrinting_SetHeader 2527 -#define wxHtmlEasyPrinting_SetFooter 2528 -#define wxGLCanvas_new_2 2530 -#define wxGLCanvas_new_3_1 2531 -#define wxGLCanvas_new_3_0 2532 -#define wxGLCanvas_GetContext 2533 -#define wxGLCanvas_SetCurrent 2535 -#define wxGLCanvas_SwapBuffers 2536 -#define wxGLCanvas_destroy 2537 -#define wxAuiManager_new 2538 -#define wxAuiManager_destruct 2539 -#define wxAuiManager_AddPane_2_1 2540 -#define wxAuiManager_AddPane_3 2541 -#define wxAuiManager_AddPane_2_0 2542 -#define wxAuiManager_DetachPane 2543 -#define wxAuiManager_GetAllPanes 2544 -#define wxAuiManager_GetArtProvider 2545 -#define wxAuiManager_GetDockSizeConstraint 2546 -#define wxAuiManager_GetFlags 2547 -#define wxAuiManager_GetManagedWindow 2548 -#define wxAuiManager_GetManager 2549 -#define wxAuiManager_GetPane_1_1 2550 -#define wxAuiManager_GetPane_1_0 2551 -#define wxAuiManager_HideHint 2552 -#define wxAuiManager_InsertPane 2553 -#define wxAuiManager_LoadPaneInfo 2554 -#define wxAuiManager_LoadPerspective 2555 -#define wxAuiManager_SavePaneInfo 2556 -#define wxAuiManager_SavePerspective 2557 -#define wxAuiManager_SetArtProvider 2558 -#define wxAuiManager_SetDockSizeConstraint 2559 -#define wxAuiManager_SetFlags 2560 -#define wxAuiManager_SetManagedWindow 2561 -#define wxAuiManager_ShowHint 2562 -#define wxAuiManager_UnInit 2563 -#define wxAuiManager_Update 2564 -#define wxAuiPaneInfo_new_0 2565 -#define wxAuiPaneInfo_new_1 2566 -#define wxAuiPaneInfo_destruct 2567 -#define wxAuiPaneInfo_BestSize_1 2568 -#define wxAuiPaneInfo_BestSize_2 2569 -#define wxAuiPaneInfo_Bottom 2570 -#define wxAuiPaneInfo_BottomDockable 2571 -#define wxAuiPaneInfo_Caption 2572 -#define wxAuiPaneInfo_CaptionVisible 2573 -#define wxAuiPaneInfo_Centre 2574 -#define wxAuiPaneInfo_CentrePane 2575 -#define wxAuiPaneInfo_CloseButton 2576 -#define wxAuiPaneInfo_DefaultPane 2577 -#define wxAuiPaneInfo_DestroyOnClose 2578 -#define wxAuiPaneInfo_Direction 2579 -#define wxAuiPaneInfo_Dock 2580 -#define wxAuiPaneInfo_Dockable 2581 -#define wxAuiPaneInfo_Fixed 2582 -#define wxAuiPaneInfo_Float 2583 -#define wxAuiPaneInfo_Floatable 2584 -#define wxAuiPaneInfo_FloatingPosition_1 2585 -#define wxAuiPaneInfo_FloatingPosition_2 2586 -#define wxAuiPaneInfo_FloatingSize_1 2587 -#define wxAuiPaneInfo_FloatingSize_2 2588 -#define wxAuiPaneInfo_Gripper 2589 -#define wxAuiPaneInfo_GripperTop 2590 -#define wxAuiPaneInfo_HasBorder 2591 -#define wxAuiPaneInfo_HasCaption 2592 -#define wxAuiPaneInfo_HasCloseButton 2593 -#define wxAuiPaneInfo_HasFlag 2594 -#define wxAuiPaneInfo_HasGripper 2595 -#define wxAuiPaneInfo_HasGripperTop 2596 -#define wxAuiPaneInfo_HasMaximizeButton 2597 -#define wxAuiPaneInfo_HasMinimizeButton 2598 -#define wxAuiPaneInfo_HasPinButton 2599 -#define wxAuiPaneInfo_Hide 2600 -#define wxAuiPaneInfo_IsBottomDockable 2601 -#define wxAuiPaneInfo_IsDocked 2602 -#define wxAuiPaneInfo_IsFixed 2603 -#define wxAuiPaneInfo_IsFloatable 2604 -#define wxAuiPaneInfo_IsFloating 2605 -#define wxAuiPaneInfo_IsLeftDockable 2606 -#define wxAuiPaneInfo_IsMovable 2607 -#define wxAuiPaneInfo_IsOk 2608 -#define wxAuiPaneInfo_IsResizable 2609 -#define wxAuiPaneInfo_IsRightDockable 2610 -#define wxAuiPaneInfo_IsShown 2611 -#define wxAuiPaneInfo_IsToolbar 2612 -#define wxAuiPaneInfo_IsTopDockable 2613 -#define wxAuiPaneInfo_Layer 2614 -#define wxAuiPaneInfo_Left 2615 -#define wxAuiPaneInfo_LeftDockable 2616 -#define wxAuiPaneInfo_MaxSize_1 2617 -#define wxAuiPaneInfo_MaxSize_2 2618 -#define wxAuiPaneInfo_MaximizeButton 2619 -#define wxAuiPaneInfo_MinSize_1 2620 -#define wxAuiPaneInfo_MinSize_2 2621 -#define wxAuiPaneInfo_MinimizeButton 2622 -#define wxAuiPaneInfo_Movable 2623 -#define wxAuiPaneInfo_Name 2624 -#define wxAuiPaneInfo_PaneBorder 2625 -#define wxAuiPaneInfo_PinButton 2626 -#define wxAuiPaneInfo_Position 2627 -#define wxAuiPaneInfo_Resizable 2628 -#define wxAuiPaneInfo_Right 2629 -#define wxAuiPaneInfo_RightDockable 2630 -#define wxAuiPaneInfo_Row 2631 -#define wxAuiPaneInfo_SafeSet 2632 -#define wxAuiPaneInfo_SetFlag 2633 -#define wxAuiPaneInfo_Show 2634 -#define wxAuiPaneInfo_ToolbarPane 2635 -#define wxAuiPaneInfo_Top 2636 -#define wxAuiPaneInfo_TopDockable 2637 -#define wxAuiPaneInfo_Window 2638 -#define wxAuiNotebook_new_0 2639 -#define wxAuiNotebook_new_2 2640 -#define wxAuiNotebook_AddPage 2641 -#define wxAuiNotebook_Create 2642 -#define wxAuiNotebook_DeletePage 2643 -#define wxAuiNotebook_GetArtProvider 2644 -#define wxAuiNotebook_GetPage 2645 -#define wxAuiNotebook_GetPageBitmap 2646 -#define wxAuiNotebook_GetPageCount 2647 -#define wxAuiNotebook_GetPageIndex 2648 -#define wxAuiNotebook_GetPageText 2649 -#define wxAuiNotebook_GetSelection 2650 -#define wxAuiNotebook_InsertPage 2651 -#define wxAuiNotebook_RemovePage 2652 -#define wxAuiNotebook_SetArtProvider 2653 -#define wxAuiNotebook_SetFont 2654 -#define wxAuiNotebook_SetPageBitmap 2655 -#define wxAuiNotebook_SetPageText 2656 -#define wxAuiNotebook_SetSelection 2657 -#define wxAuiNotebook_SetTabCtrlHeight 2658 -#define wxAuiNotebook_SetUniformBitmapSize 2659 -#define wxAuiNotebook_destroy 2660 -#define wxMDIParentFrame_new_0 2661 -#define wxMDIParentFrame_new_4 2662 -#define wxMDIParentFrame_destruct 2663 -#define wxMDIParentFrame_ActivateNext 2664 -#define wxMDIParentFrame_ActivatePrevious 2665 -#define wxMDIParentFrame_ArrangeIcons 2666 -#define wxMDIParentFrame_Cascade 2667 -#define wxMDIParentFrame_Create 2668 -#define wxMDIParentFrame_GetActiveChild 2669 -#define wxMDIParentFrame_GetClientWindow 2670 -#define wxMDIParentFrame_Tile 2671 -#define wxMDIChildFrame_new_0 2672 -#define wxMDIChildFrame_new_4 2673 -#define wxMDIChildFrame_destruct 2674 -#define wxMDIChildFrame_Activate 2675 -#define wxMDIChildFrame_Create 2676 -#define wxMDIChildFrame_Maximize 2677 -#define wxMDIChildFrame_Restore 2678 -#define wxMDIClientWindow_new_0 2679 -#define wxMDIClientWindow_new_2 2680 -#define wxMDIClientWindow_destruct 2681 -#define wxMDIClientWindow_CreateClient 2682 -#define wxLayoutAlgorithm_new 2683 -#define wxLayoutAlgorithm_LayoutFrame 2684 -#define wxLayoutAlgorithm_LayoutMDIFrame 2685 -#define wxLayoutAlgorithm_LayoutWindow 2686 -#define wxLayoutAlgorithm_destroy 2687 -#define wxEvent_GetId 2688 -#define wxEvent_GetSkipped 2689 -#define wxEvent_GetTimestamp 2690 -#define wxEvent_IsCommandEvent 2691 -#define wxEvent_ResumePropagation 2692 -#define wxEvent_ShouldPropagate 2693 -#define wxEvent_Skip 2694 -#define wxEvent_StopPropagation 2695 -#define wxCommandEvent_getClientData 2696 -#define wxCommandEvent_GetExtraLong 2697 -#define wxCommandEvent_GetInt 2698 -#define wxCommandEvent_GetSelection 2699 -#define wxCommandEvent_GetString 2700 -#define wxCommandEvent_IsChecked 2701 -#define wxCommandEvent_IsSelection 2702 -#define wxCommandEvent_SetInt 2703 -#define wxCommandEvent_SetString 2704 -#define wxScrollEvent_GetOrientation 2705 -#define wxScrollEvent_GetPosition 2706 -#define wxScrollWinEvent_GetOrientation 2707 -#define wxScrollWinEvent_GetPosition 2708 -#define wxMouseEvent_AltDown 2709 -#define wxMouseEvent_Button 2710 -#define wxMouseEvent_ButtonDClick 2711 -#define wxMouseEvent_ButtonDown 2712 -#define wxMouseEvent_ButtonUp 2713 -#define wxMouseEvent_CmdDown 2714 -#define wxMouseEvent_ControlDown 2715 -#define wxMouseEvent_Dragging 2716 -#define wxMouseEvent_Entering 2717 -#define wxMouseEvent_GetButton 2718 -#define wxMouseEvent_GetPosition 2721 -#define wxMouseEvent_GetLogicalPosition 2722 -#define wxMouseEvent_GetLinesPerAction 2723 -#define wxMouseEvent_GetWheelRotation 2724 -#define wxMouseEvent_GetWheelDelta 2725 -#define wxMouseEvent_GetX 2726 -#define wxMouseEvent_GetY 2727 -#define wxMouseEvent_IsButton 2728 -#define wxMouseEvent_IsPageScroll 2729 -#define wxMouseEvent_Leaving 2730 -#define wxMouseEvent_LeftDClick 2731 -#define wxMouseEvent_LeftDown 2732 -#define wxMouseEvent_LeftIsDown 2733 -#define wxMouseEvent_LeftUp 2734 -#define wxMouseEvent_MetaDown 2735 -#define wxMouseEvent_MiddleDClick 2736 -#define wxMouseEvent_MiddleDown 2737 -#define wxMouseEvent_MiddleIsDown 2738 -#define wxMouseEvent_MiddleUp 2739 -#define wxMouseEvent_Moving 2740 -#define wxMouseEvent_RightDClick 2741 -#define wxMouseEvent_RightDown 2742 -#define wxMouseEvent_RightIsDown 2743 -#define wxMouseEvent_RightUp 2744 -#define wxMouseEvent_ShiftDown 2745 -#define wxSetCursorEvent_GetCursor 2746 -#define wxSetCursorEvent_GetX 2747 -#define wxSetCursorEvent_GetY 2748 -#define wxSetCursorEvent_HasCursor 2749 -#define wxSetCursorEvent_SetCursor 2750 -#define wxKeyEvent_AltDown 2751 -#define wxKeyEvent_CmdDown 2752 -#define wxKeyEvent_ControlDown 2753 -#define wxKeyEvent_GetKeyCode 2754 -#define wxKeyEvent_GetModifiers 2755 -#define wxKeyEvent_GetPosition 2758 -#define wxKeyEvent_GetRawKeyCode 2759 -#define wxKeyEvent_GetRawKeyFlags 2760 -#define wxKeyEvent_GetUnicodeKey 2761 -#define wxKeyEvent_GetX 2762 -#define wxKeyEvent_GetY 2763 -#define wxKeyEvent_HasModifiers 2764 -#define wxKeyEvent_MetaDown 2765 -#define wxKeyEvent_ShiftDown 2766 -#define wxSizeEvent_GetSize 2767 -#define wxMoveEvent_GetPosition 2768 -#define wxEraseEvent_GetDC 2769 -#define wxFocusEvent_GetWindow 2770 -#define wxChildFocusEvent_GetWindow 2771 -#define wxMenuEvent_GetMenu 2772 -#define wxMenuEvent_GetMenuId 2773 -#define wxMenuEvent_IsPopup 2774 -#define wxCloseEvent_CanVeto 2775 -#define wxCloseEvent_GetLoggingOff 2776 -#define wxCloseEvent_SetCanVeto 2777 -#define wxCloseEvent_SetLoggingOff 2778 -#define wxCloseEvent_Veto 2779 -#define wxShowEvent_SetShow 2780 -#define wxShowEvent_GetShow 2781 -#define wxIconizeEvent_Iconized 2782 -#define wxJoystickEvent_ButtonDown 2783 -#define wxJoystickEvent_ButtonIsDown 2784 -#define wxJoystickEvent_ButtonUp 2785 -#define wxJoystickEvent_GetButtonChange 2786 -#define wxJoystickEvent_GetButtonState 2787 -#define wxJoystickEvent_GetJoystick 2788 -#define wxJoystickEvent_GetPosition 2789 -#define wxJoystickEvent_GetZPosition 2790 -#define wxJoystickEvent_IsButton 2791 -#define wxJoystickEvent_IsMove 2792 -#define wxJoystickEvent_IsZMove 2793 -#define wxUpdateUIEvent_CanUpdate 2794 -#define wxUpdateUIEvent_Check 2795 -#define wxUpdateUIEvent_Enable 2796 -#define wxUpdateUIEvent_Show 2797 -#define wxUpdateUIEvent_GetChecked 2798 -#define wxUpdateUIEvent_GetEnabled 2799 -#define wxUpdateUIEvent_GetShown 2800 -#define wxUpdateUIEvent_GetSetChecked 2801 -#define wxUpdateUIEvent_GetSetEnabled 2802 -#define wxUpdateUIEvent_GetSetShown 2803 -#define wxUpdateUIEvent_GetSetText 2804 -#define wxUpdateUIEvent_GetText 2805 -#define wxUpdateUIEvent_GetMode 2806 -#define wxUpdateUIEvent_GetUpdateInterval 2807 -#define wxUpdateUIEvent_ResetUpdateTime 2808 -#define wxUpdateUIEvent_SetMode 2809 -#define wxUpdateUIEvent_SetText 2810 -#define wxUpdateUIEvent_SetUpdateInterval 2811 -#define wxMouseCaptureChangedEvent_GetCapturedWindow 2812 -#define wxPaletteChangedEvent_SetChangedWindow 2813 -#define wxPaletteChangedEvent_GetChangedWindow 2814 -#define wxQueryNewPaletteEvent_SetPaletteRealized 2815 -#define wxQueryNewPaletteEvent_GetPaletteRealized 2816 -#define wxNavigationKeyEvent_GetDirection 2817 -#define wxNavigationKeyEvent_SetDirection 2818 -#define wxNavigationKeyEvent_IsWindowChange 2819 -#define wxNavigationKeyEvent_SetWindowChange 2820 -#define wxNavigationKeyEvent_IsFromTab 2821 -#define wxNavigationKeyEvent_SetFromTab 2822 -#define wxNavigationKeyEvent_GetCurrentFocus 2823 -#define wxNavigationKeyEvent_SetCurrentFocus 2824 -#define wxHelpEvent_GetOrigin 2825 -#define wxHelpEvent_GetPosition 2826 -#define wxHelpEvent_SetOrigin 2827 -#define wxHelpEvent_SetPosition 2828 -#define wxContextMenuEvent_GetPosition 2829 -#define wxContextMenuEvent_SetPosition 2830 -#define wxIdleEvent_CanSend 2831 -#define wxIdleEvent_GetMode 2832 -#define wxIdleEvent_RequestMore 2833 -#define wxIdleEvent_MoreRequested 2834 -#define wxIdleEvent_SetMode 2835 -#define wxGridEvent_AltDown 2836 -#define wxGridEvent_ControlDown 2837 -#define wxGridEvent_GetCol 2838 -#define wxGridEvent_GetPosition 2839 -#define wxGridEvent_GetRow 2840 -#define wxGridEvent_MetaDown 2841 -#define wxGridEvent_Selecting 2842 -#define wxGridEvent_ShiftDown 2843 -#define wxNotifyEvent_Allow 2844 -#define wxNotifyEvent_IsAllowed 2845 -#define wxNotifyEvent_Veto 2846 -#define wxSashEvent_GetEdge 2847 -#define wxSashEvent_GetDragRect 2848 -#define wxSashEvent_GetDragStatus 2849 -#define wxListEvent_GetCacheFrom 2850 -#define wxListEvent_GetCacheTo 2851 -#define wxListEvent_GetKeyCode 2852 -#define wxListEvent_GetIndex 2853 -#define wxListEvent_GetColumn 2854 -#define wxListEvent_GetPoint 2855 -#define wxListEvent_GetLabel 2856 -#define wxListEvent_GetText 2857 -#define wxListEvent_GetImage 2858 -#define wxListEvent_GetData 2859 -#define wxListEvent_GetMask 2860 -#define wxListEvent_GetItem 2861 -#define wxListEvent_IsEditCancelled 2862 -#define wxDateEvent_GetDate 2863 -#define wxCalendarEvent_GetWeekDay 2864 -#define wxFileDirPickerEvent_GetPath 2865 -#define wxColourPickerEvent_GetColour 2866 -#define wxFontPickerEvent_GetFont 2867 -#define wxStyledTextEvent_GetPosition 2868 -#define wxStyledTextEvent_GetKey 2869 -#define wxStyledTextEvent_GetModifiers 2870 -#define wxStyledTextEvent_GetModificationType 2871 -#define wxStyledTextEvent_GetText 2872 -#define wxStyledTextEvent_GetLength 2873 -#define wxStyledTextEvent_GetLinesAdded 2874 -#define wxStyledTextEvent_GetLine 2875 -#define wxStyledTextEvent_GetFoldLevelNow 2876 -#define wxStyledTextEvent_GetFoldLevelPrev 2877 -#define wxStyledTextEvent_GetMargin 2878 -#define wxStyledTextEvent_GetMessage 2879 -#define wxStyledTextEvent_GetWParam 2880 -#define wxStyledTextEvent_GetLParam 2881 -#define wxStyledTextEvent_GetListType 2882 -#define wxStyledTextEvent_GetX 2883 -#define wxStyledTextEvent_GetY 2884 -#define wxStyledTextEvent_GetDragText 2885 -#define wxStyledTextEvent_GetDragAllowMove 2886 -#define wxStyledTextEvent_GetDragResult 2887 -#define wxStyledTextEvent_GetShift 2888 -#define wxStyledTextEvent_GetControl 2889 -#define wxStyledTextEvent_GetAlt 2890 -#define utils_wxGetKeyState 2891 -#define utils_wxGetMousePosition 2892 -#define utils_wxGetMouseState 2893 -#define utils_wxSetDetectableAutoRepeat 2894 -#define utils_wxBell 2895 -#define utils_wxFindMenuItemId 2896 -#define utils_wxGenericFindWindowAtPoint 2897 -#define utils_wxFindWindowAtPoint 2898 -#define utils_wxBeginBusyCursor 2899 -#define utils_wxEndBusyCursor 2900 -#define utils_wxIsBusy 2901 -#define utils_wxShutdown 2902 -#define utils_wxShell 2903 -#define utils_wxLaunchDefaultBrowser 2904 -#define utils_wxGetEmailAddress 2905 -#define utils_wxGetUserId 2906 -#define utils_wxGetHomeDir 2907 -#define utils_wxNewId 2908 -#define utils_wxRegisterId 2909 -#define utils_wxGetCurrentId 2910 -#define utils_wxGetOsDescription 2911 -#define utils_wxIsPlatformLittleEndian 2912 -#define utils_wxIsPlatform64Bit 2913 -#define wxPrintout_new 2914 -#define wxPrintout_destruct 2915 -#define wxPrintout_GetDC 2916 -#define wxPrintout_GetPageSizeMM 2917 -#define wxPrintout_GetPageSizePixels 2918 -#define wxPrintout_GetPaperRectPixels 2919 -#define wxPrintout_GetPPIPrinter 2920 -#define wxPrintout_GetPPIScreen 2921 -#define wxPrintout_GetTitle 2922 -#define wxPrintout_IsPreview 2923 -#define wxPrintout_FitThisSizeToPaper 2924 -#define wxPrintout_FitThisSizeToPage 2925 -#define wxPrintout_FitThisSizeToPageMargins 2926 -#define wxPrintout_MapScreenSizeToPaper 2927 -#define wxPrintout_MapScreenSizeToPage 2928 -#define wxPrintout_MapScreenSizeToPageMargins 2929 -#define wxPrintout_MapScreenSizeToDevice 2930 -#define wxPrintout_GetLogicalPaperRect 2931 -#define wxPrintout_GetLogicalPageRect 2932 -#define wxPrintout_GetLogicalPageMarginsRect 2933 -#define wxPrintout_SetLogicalOrigin 2934 -#define wxPrintout_OffsetLogicalOrigin 2935 -#define wxStyledTextCtrl_new_2 2936 -#define wxStyledTextCtrl_new_0 2937 -#define wxStyledTextCtrl_destruct 2938 -#define wxStyledTextCtrl_Create 2939 -#define wxStyledTextCtrl_AddText 2940 -#define wxStyledTextCtrl_AddStyledText 2941 -#define wxStyledTextCtrl_InsertText 2942 -#define wxStyledTextCtrl_ClearAll 2943 -#define wxStyledTextCtrl_ClearDocumentStyle 2944 -#define wxStyledTextCtrl_GetLength 2945 -#define wxStyledTextCtrl_GetCharAt 2946 -#define wxStyledTextCtrl_GetCurrentPos 2947 -#define wxStyledTextCtrl_GetAnchor 2948 -#define wxStyledTextCtrl_GetStyleAt 2949 -#define wxStyledTextCtrl_Redo 2950 -#define wxStyledTextCtrl_SetUndoCollection 2951 -#define wxStyledTextCtrl_SelectAll 2952 -#define wxStyledTextCtrl_SetSavePoint 2953 -#define wxStyledTextCtrl_GetStyledText 2954 -#define wxStyledTextCtrl_CanRedo 2955 -#define wxStyledTextCtrl_MarkerLineFromHandle 2956 -#define wxStyledTextCtrl_MarkerDeleteHandle 2957 -#define wxStyledTextCtrl_GetUndoCollection 2958 -#define wxStyledTextCtrl_GetViewWhiteSpace 2959 -#define wxStyledTextCtrl_SetViewWhiteSpace 2960 -#define wxStyledTextCtrl_PositionFromPoint 2961 -#define wxStyledTextCtrl_PositionFromPointClose 2962 -#define wxStyledTextCtrl_GotoLine 2963 -#define wxStyledTextCtrl_GotoPos 2964 -#define wxStyledTextCtrl_SetAnchor 2965 -#define wxStyledTextCtrl_GetCurLine 2966 -#define wxStyledTextCtrl_GetEndStyled 2967 -#define wxStyledTextCtrl_ConvertEOLs 2968 -#define wxStyledTextCtrl_GetEOLMode 2969 -#define wxStyledTextCtrl_SetEOLMode 2970 -#define wxStyledTextCtrl_StartStyling 2971 -#define wxStyledTextCtrl_SetStyling 2972 -#define wxStyledTextCtrl_GetBufferedDraw 2973 -#define wxStyledTextCtrl_SetBufferedDraw 2974 -#define wxStyledTextCtrl_SetTabWidth 2975 -#define wxStyledTextCtrl_GetTabWidth 2976 -#define wxStyledTextCtrl_SetCodePage 2977 -#define wxStyledTextCtrl_MarkerDefine 2978 -#define wxStyledTextCtrl_MarkerSetForeground 2979 -#define wxStyledTextCtrl_MarkerSetBackground 2980 -#define wxStyledTextCtrl_MarkerAdd 2981 -#define wxStyledTextCtrl_MarkerDelete 2982 -#define wxStyledTextCtrl_MarkerDeleteAll 2983 -#define wxStyledTextCtrl_MarkerGet 2984 -#define wxStyledTextCtrl_MarkerNext 2985 -#define wxStyledTextCtrl_MarkerPrevious 2986 -#define wxStyledTextCtrl_MarkerDefineBitmap 2987 -#define wxStyledTextCtrl_MarkerAddSet 2988 -#define wxStyledTextCtrl_MarkerSetAlpha 2989 -#define wxStyledTextCtrl_SetMarginType 2990 -#define wxStyledTextCtrl_GetMarginType 2991 -#define wxStyledTextCtrl_SetMarginWidth 2992 -#define wxStyledTextCtrl_GetMarginWidth 2993 -#define wxStyledTextCtrl_SetMarginMask 2994 -#define wxStyledTextCtrl_GetMarginMask 2995 -#define wxStyledTextCtrl_SetMarginSensitive 2996 -#define wxStyledTextCtrl_GetMarginSensitive 2997 -#define wxStyledTextCtrl_StyleClearAll 2998 -#define wxStyledTextCtrl_StyleSetForeground 2999 -#define wxStyledTextCtrl_StyleSetBackground 3000 -#define wxStyledTextCtrl_StyleSetBold 3001 -#define wxStyledTextCtrl_StyleSetItalic 3002 -#define wxStyledTextCtrl_StyleSetSize 3003 -#define wxStyledTextCtrl_StyleSetFaceName 3004 -#define wxStyledTextCtrl_StyleSetEOLFilled 3005 -#define wxStyledTextCtrl_StyleResetDefault 3006 -#define wxStyledTextCtrl_StyleSetUnderline 3007 -#define wxStyledTextCtrl_StyleSetCase 3008 -#define wxStyledTextCtrl_StyleSetHotSpot 3009 -#define wxStyledTextCtrl_SetSelForeground 3010 -#define wxStyledTextCtrl_SetSelBackground 3011 -#define wxStyledTextCtrl_GetSelAlpha 3012 -#define wxStyledTextCtrl_SetSelAlpha 3013 -#define wxStyledTextCtrl_SetCaretForeground 3014 -#define wxStyledTextCtrl_CmdKeyAssign 3015 -#define wxStyledTextCtrl_CmdKeyClear 3016 -#define wxStyledTextCtrl_CmdKeyClearAll 3017 -#define wxStyledTextCtrl_SetStyleBytes 3018 -#define wxStyledTextCtrl_StyleSetVisible 3019 -#define wxStyledTextCtrl_GetCaretPeriod 3020 -#define wxStyledTextCtrl_SetCaretPeriod 3021 -#define wxStyledTextCtrl_SetWordChars 3022 -#define wxStyledTextCtrl_BeginUndoAction 3023 -#define wxStyledTextCtrl_EndUndoAction 3024 -#define wxStyledTextCtrl_IndicatorSetStyle 3025 -#define wxStyledTextCtrl_IndicatorGetStyle 3026 -#define wxStyledTextCtrl_IndicatorSetForeground 3027 -#define wxStyledTextCtrl_IndicatorGetForeground 3028 -#define wxStyledTextCtrl_SetWhitespaceForeground 3029 -#define wxStyledTextCtrl_SetWhitespaceBackground 3030 -#define wxStyledTextCtrl_GetStyleBits 3031 -#define wxStyledTextCtrl_SetLineState 3032 -#define wxStyledTextCtrl_GetLineState 3033 -#define wxStyledTextCtrl_GetMaxLineState 3034 -#define wxStyledTextCtrl_GetCaretLineVisible 3035 -#define wxStyledTextCtrl_SetCaretLineVisible 3036 -#define wxStyledTextCtrl_GetCaretLineBackground 3037 -#define wxStyledTextCtrl_SetCaretLineBackground 3038 -#define wxStyledTextCtrl_AutoCompShow 3039 -#define wxStyledTextCtrl_AutoCompCancel 3040 -#define wxStyledTextCtrl_AutoCompActive 3041 -#define wxStyledTextCtrl_AutoCompPosStart 3042 -#define wxStyledTextCtrl_AutoCompComplete 3043 -#define wxStyledTextCtrl_AutoCompStops 3044 -#define wxStyledTextCtrl_AutoCompSetSeparator 3045 -#define wxStyledTextCtrl_AutoCompGetSeparator 3046 -#define wxStyledTextCtrl_AutoCompSelect 3047 -#define wxStyledTextCtrl_AutoCompSetCancelAtStart 3048 -#define wxStyledTextCtrl_AutoCompGetCancelAtStart 3049 -#define wxStyledTextCtrl_AutoCompSetFillUps 3050 -#define wxStyledTextCtrl_AutoCompSetChooseSingle 3051 -#define wxStyledTextCtrl_AutoCompGetChooseSingle 3052 -#define wxStyledTextCtrl_AutoCompSetIgnoreCase 3053 -#define wxStyledTextCtrl_AutoCompGetIgnoreCase 3054 -#define wxStyledTextCtrl_UserListShow 3055 -#define wxStyledTextCtrl_AutoCompSetAutoHide 3056 -#define wxStyledTextCtrl_AutoCompGetAutoHide 3057 -#define wxStyledTextCtrl_AutoCompSetDropRestOfWord 3058 -#define wxStyledTextCtrl_AutoCompGetDropRestOfWord 3059 -#define wxStyledTextCtrl_RegisterImage 3060 -#define wxStyledTextCtrl_ClearRegisteredImages 3061 -#define wxStyledTextCtrl_AutoCompGetTypeSeparator 3062 -#define wxStyledTextCtrl_AutoCompSetTypeSeparator 3063 -#define wxStyledTextCtrl_AutoCompSetMaxWidth 3064 -#define wxStyledTextCtrl_AutoCompGetMaxWidth 3065 -#define wxStyledTextCtrl_AutoCompSetMaxHeight 3066 -#define wxStyledTextCtrl_AutoCompGetMaxHeight 3067 -#define wxStyledTextCtrl_SetIndent 3068 -#define wxStyledTextCtrl_GetIndent 3069 -#define wxStyledTextCtrl_SetUseTabs 3070 -#define wxStyledTextCtrl_GetUseTabs 3071 -#define wxStyledTextCtrl_SetLineIndentation 3072 -#define wxStyledTextCtrl_GetLineIndentation 3073 -#define wxStyledTextCtrl_GetLineIndentPosition 3074 -#define wxStyledTextCtrl_GetColumn 3075 -#define wxStyledTextCtrl_SetUseHorizontalScrollBar 3076 -#define wxStyledTextCtrl_GetUseHorizontalScrollBar 3077 -#define wxStyledTextCtrl_SetIndentationGuides 3078 -#define wxStyledTextCtrl_GetIndentationGuides 3079 -#define wxStyledTextCtrl_SetHighlightGuide 3080 -#define wxStyledTextCtrl_GetHighlightGuide 3081 -#define wxStyledTextCtrl_GetLineEndPosition 3082 -#define wxStyledTextCtrl_GetCodePage 3083 -#define wxStyledTextCtrl_GetCaretForeground 3084 -#define wxStyledTextCtrl_GetReadOnly 3085 -#define wxStyledTextCtrl_SetCurrentPos 3086 -#define wxStyledTextCtrl_SetSelectionStart 3087 -#define wxStyledTextCtrl_GetSelectionStart 3088 -#define wxStyledTextCtrl_SetSelectionEnd 3089 -#define wxStyledTextCtrl_GetSelectionEnd 3090 -#define wxStyledTextCtrl_SetPrintMagnification 3091 -#define wxStyledTextCtrl_GetPrintMagnification 3092 -#define wxStyledTextCtrl_SetPrintColourMode 3093 -#define wxStyledTextCtrl_GetPrintColourMode 3094 -#define wxStyledTextCtrl_FindText 3095 -#define wxStyledTextCtrl_FormatRange 3096 -#define wxStyledTextCtrl_GetFirstVisibleLine 3097 -#define wxStyledTextCtrl_GetLine 3098 -#define wxStyledTextCtrl_GetLineCount 3099 -#define wxStyledTextCtrl_SetMarginLeft 3100 -#define wxStyledTextCtrl_GetMarginLeft 3101 -#define wxStyledTextCtrl_SetMarginRight 3102 -#define wxStyledTextCtrl_GetMarginRight 3103 -#define wxStyledTextCtrl_GetModify 3104 -#define wxStyledTextCtrl_SetSelection 3105 -#define wxStyledTextCtrl_GetSelectedText 3106 -#define wxStyledTextCtrl_GetTextRange 3107 -#define wxStyledTextCtrl_HideSelection 3108 -#define wxStyledTextCtrl_LineFromPosition 3109 -#define wxStyledTextCtrl_PositionFromLine 3110 -#define wxStyledTextCtrl_LineScroll 3111 -#define wxStyledTextCtrl_EnsureCaretVisible 3112 -#define wxStyledTextCtrl_ReplaceSelection 3113 -#define wxStyledTextCtrl_SetReadOnly 3114 -#define wxStyledTextCtrl_CanPaste 3115 -#define wxStyledTextCtrl_CanUndo 3116 -#define wxStyledTextCtrl_EmptyUndoBuffer 3117 -#define wxStyledTextCtrl_Undo 3118 -#define wxStyledTextCtrl_Cut 3119 -#define wxStyledTextCtrl_Copy 3120 -#define wxStyledTextCtrl_Paste 3121 -#define wxStyledTextCtrl_Clear 3122 -#define wxStyledTextCtrl_SetText 3123 -#define wxStyledTextCtrl_GetText 3124 -#define wxStyledTextCtrl_GetTextLength 3125 -#define wxStyledTextCtrl_GetOvertype 3126 -#define wxStyledTextCtrl_SetCaretWidth 3127 -#define wxStyledTextCtrl_GetCaretWidth 3128 -#define wxStyledTextCtrl_SetTargetStart 3129 -#define wxStyledTextCtrl_GetTargetStart 3130 -#define wxStyledTextCtrl_SetTargetEnd 3131 -#define wxStyledTextCtrl_GetTargetEnd 3132 -#define wxStyledTextCtrl_ReplaceTarget 3133 -#define wxStyledTextCtrl_SearchInTarget 3134 -#define wxStyledTextCtrl_SetSearchFlags 3135 -#define wxStyledTextCtrl_GetSearchFlags 3136 -#define wxStyledTextCtrl_CallTipShow 3137 -#define wxStyledTextCtrl_CallTipCancel 3138 -#define wxStyledTextCtrl_CallTipActive 3139 -#define wxStyledTextCtrl_CallTipPosAtStart 3140 -#define wxStyledTextCtrl_CallTipSetHighlight 3141 -#define wxStyledTextCtrl_CallTipSetBackground 3142 -#define wxStyledTextCtrl_CallTipSetForeground 3143 -#define wxStyledTextCtrl_CallTipSetForegroundHighlight 3144 -#define wxStyledTextCtrl_CallTipUseStyle 3145 -#define wxStyledTextCtrl_VisibleFromDocLine 3146 -#define wxStyledTextCtrl_DocLineFromVisible 3147 -#define wxStyledTextCtrl_WrapCount 3148 -#define wxStyledTextCtrl_SetFoldLevel 3149 -#define wxStyledTextCtrl_GetFoldLevel 3150 -#define wxStyledTextCtrl_GetLastChild 3151 -#define wxStyledTextCtrl_GetFoldParent 3152 -#define wxStyledTextCtrl_ShowLines 3153 -#define wxStyledTextCtrl_HideLines 3154 -#define wxStyledTextCtrl_GetLineVisible 3155 -#define wxStyledTextCtrl_SetFoldExpanded 3156 -#define wxStyledTextCtrl_GetFoldExpanded 3157 -#define wxStyledTextCtrl_ToggleFold 3158 -#define wxStyledTextCtrl_EnsureVisible 3159 -#define wxStyledTextCtrl_SetFoldFlags 3160 -#define wxStyledTextCtrl_EnsureVisibleEnforcePolicy 3161 -#define wxStyledTextCtrl_SetTabIndents 3162 -#define wxStyledTextCtrl_GetTabIndents 3163 -#define wxStyledTextCtrl_SetBackSpaceUnIndents 3164 -#define wxStyledTextCtrl_GetBackSpaceUnIndents 3165 -#define wxStyledTextCtrl_SetMouseDwellTime 3166 -#define wxStyledTextCtrl_GetMouseDwellTime 3167 -#define wxStyledTextCtrl_WordStartPosition 3168 -#define wxStyledTextCtrl_WordEndPosition 3169 -#define wxStyledTextCtrl_SetWrapMode 3170 -#define wxStyledTextCtrl_GetWrapMode 3171 -#define wxStyledTextCtrl_SetWrapVisualFlags 3172 -#define wxStyledTextCtrl_GetWrapVisualFlags 3173 -#define wxStyledTextCtrl_SetWrapVisualFlagsLocation 3174 -#define wxStyledTextCtrl_GetWrapVisualFlagsLocation 3175 -#define wxStyledTextCtrl_SetWrapStartIndent 3176 -#define wxStyledTextCtrl_GetWrapStartIndent 3177 -#define wxStyledTextCtrl_SetLayoutCache 3178 -#define wxStyledTextCtrl_GetLayoutCache 3179 -#define wxStyledTextCtrl_SetScrollWidth 3180 -#define wxStyledTextCtrl_GetScrollWidth 3181 -#define wxStyledTextCtrl_TextWidth 3182 -#define wxStyledTextCtrl_GetEndAtLastLine 3183 -#define wxStyledTextCtrl_TextHeight 3184 -#define wxStyledTextCtrl_SetUseVerticalScrollBar 3185 -#define wxStyledTextCtrl_GetUseVerticalScrollBar 3186 -#define wxStyledTextCtrl_AppendText 3187 -#define wxStyledTextCtrl_GetTwoPhaseDraw 3188 -#define wxStyledTextCtrl_SetTwoPhaseDraw 3189 -#define wxStyledTextCtrl_TargetFromSelection 3190 -#define wxStyledTextCtrl_LinesJoin 3191 -#define wxStyledTextCtrl_LinesSplit 3192 -#define wxStyledTextCtrl_SetFoldMarginColour 3193 -#define wxStyledTextCtrl_SetFoldMarginHiColour 3194 -#define wxStyledTextCtrl_LineDown 3195 -#define wxStyledTextCtrl_LineDownExtend 3196 -#define wxStyledTextCtrl_LineUp 3197 -#define wxStyledTextCtrl_LineUpExtend 3198 -#define wxStyledTextCtrl_CharLeft 3199 -#define wxStyledTextCtrl_CharLeftExtend 3200 -#define wxStyledTextCtrl_CharRight 3201 -#define wxStyledTextCtrl_CharRightExtend 3202 -#define wxStyledTextCtrl_WordLeft 3203 -#define wxStyledTextCtrl_WordLeftExtend 3204 -#define wxStyledTextCtrl_WordRight 3205 -#define wxStyledTextCtrl_WordRightExtend 3206 -#define wxStyledTextCtrl_Home 3207 -#define wxStyledTextCtrl_HomeExtend 3208 -#define wxStyledTextCtrl_LineEnd 3209 -#define wxStyledTextCtrl_LineEndExtend 3210 -#define wxStyledTextCtrl_DocumentStart 3211 -#define wxStyledTextCtrl_DocumentStartExtend 3212 -#define wxStyledTextCtrl_DocumentEnd 3213 -#define wxStyledTextCtrl_DocumentEndExtend 3214 -#define wxStyledTextCtrl_PageUp 3215 -#define wxStyledTextCtrl_PageUpExtend 3216 -#define wxStyledTextCtrl_PageDown 3217 -#define wxStyledTextCtrl_PageDownExtend 3218 -#define wxStyledTextCtrl_EditToggleOvertype 3219 -#define wxStyledTextCtrl_Cancel 3220 -#define wxStyledTextCtrl_DeleteBack 3221 -#define wxStyledTextCtrl_Tab 3222 -#define wxStyledTextCtrl_BackTab 3223 -#define wxStyledTextCtrl_NewLine 3224 -#define wxStyledTextCtrl_FormFeed 3225 -#define wxStyledTextCtrl_VCHome 3226 -#define wxStyledTextCtrl_VCHomeExtend 3227 -#define wxStyledTextCtrl_ZoomIn 3228 -#define wxStyledTextCtrl_ZoomOut 3229 -#define wxStyledTextCtrl_DelWordLeft 3230 -#define wxStyledTextCtrl_DelWordRight 3231 -#define wxStyledTextCtrl_LineCut 3232 -#define wxStyledTextCtrl_LineDelete 3233 -#define wxStyledTextCtrl_LineTranspose 3234 -#define wxStyledTextCtrl_LineDuplicate 3235 -#define wxStyledTextCtrl_LowerCase 3236 -#define wxStyledTextCtrl_UpperCase 3237 -#define wxStyledTextCtrl_LineScrollDown 3238 -#define wxStyledTextCtrl_LineScrollUp 3239 -#define wxStyledTextCtrl_DeleteBackNotLine 3240 -#define wxStyledTextCtrl_HomeDisplay 3241 -#define wxStyledTextCtrl_HomeDisplayExtend 3242 -#define wxStyledTextCtrl_LineEndDisplay 3243 -#define wxStyledTextCtrl_LineEndDisplayExtend 3244 -#define wxStyledTextCtrl_HomeWrapExtend 3245 -#define wxStyledTextCtrl_LineEndWrap 3246 -#define wxStyledTextCtrl_LineEndWrapExtend 3247 -#define wxStyledTextCtrl_VCHomeWrap 3248 -#define wxStyledTextCtrl_VCHomeWrapExtend 3249 -#define wxStyledTextCtrl_LineCopy 3250 -#define wxStyledTextCtrl_MoveCaretInsideView 3251 -#define wxStyledTextCtrl_LineLength 3252 -#define wxStyledTextCtrl_BraceHighlight 3253 -#define wxStyledTextCtrl_BraceBadLight 3254 -#define wxStyledTextCtrl_BraceMatch 3255 -#define wxStyledTextCtrl_GetViewEOL 3256 -#define wxStyledTextCtrl_SetViewEOL 3257 -#define wxStyledTextCtrl_SetModEventMask 3258 -#define wxStyledTextCtrl_GetEdgeColumn 3259 -#define wxStyledTextCtrl_SetEdgeColumn 3260 -#define wxStyledTextCtrl_GetEdgeMode 3261 -#define wxStyledTextCtrl_GetEdgeColour 3262 -#define wxStyledTextCtrl_SetEdgeColour 3263 -#define wxStyledTextCtrl_SearchAnchor 3264 -#define wxStyledTextCtrl_SearchNext 3265 -#define wxStyledTextCtrl_SearchPrev 3266 -#define wxStyledTextCtrl_LinesOnScreen 3267 -#define wxStyledTextCtrl_UsePopUp 3268 -#define wxStyledTextCtrl_SelectionIsRectangle 3269 -#define wxStyledTextCtrl_SetZoom 3270 -#define wxStyledTextCtrl_GetZoom 3271 -#define wxStyledTextCtrl_GetModEventMask 3272 -#define wxStyledTextCtrl_SetSTCFocus 3273 -#define wxStyledTextCtrl_GetSTCFocus 3274 -#define wxStyledTextCtrl_SetStatus 3275 -#define wxStyledTextCtrl_GetStatus 3276 -#define wxStyledTextCtrl_SetMouseDownCaptures 3277 -#define wxStyledTextCtrl_GetMouseDownCaptures 3278 -#define wxStyledTextCtrl_SetSTCCursor 3279 -#define wxStyledTextCtrl_GetSTCCursor 3280 -#define wxStyledTextCtrl_SetControlCharSymbol 3281 -#define wxStyledTextCtrl_GetControlCharSymbol 3282 -#define wxStyledTextCtrl_WordPartLeft 3283 -#define wxStyledTextCtrl_WordPartLeftExtend 3284 -#define wxStyledTextCtrl_WordPartRight 3285 -#define wxStyledTextCtrl_WordPartRightExtend 3286 -#define wxStyledTextCtrl_SetVisiblePolicy 3287 -#define wxStyledTextCtrl_DelLineLeft 3288 -#define wxStyledTextCtrl_DelLineRight 3289 -#define wxStyledTextCtrl_GetXOffset 3290 -#define wxStyledTextCtrl_ChooseCaretX 3291 -#define wxStyledTextCtrl_SetXCaretPolicy 3292 -#define wxStyledTextCtrl_SetYCaretPolicy 3293 -#define wxStyledTextCtrl_GetPrintWrapMode 3294 -#define wxStyledTextCtrl_SetHotspotActiveForeground 3295 -#define wxStyledTextCtrl_SetHotspotActiveBackground 3296 -#define wxStyledTextCtrl_SetHotspotActiveUnderline 3297 -#define wxStyledTextCtrl_SetHotspotSingleLine 3298 -#define wxStyledTextCtrl_ParaDownExtend 3299 -#define wxStyledTextCtrl_ParaUp 3300 -#define wxStyledTextCtrl_ParaUpExtend 3301 -#define wxStyledTextCtrl_PositionBefore 3302 -#define wxStyledTextCtrl_PositionAfter 3303 -#define wxStyledTextCtrl_CopyRange 3304 -#define wxStyledTextCtrl_CopyText 3305 -#define wxStyledTextCtrl_SetSelectionMode 3306 -#define wxStyledTextCtrl_GetSelectionMode 3307 -#define wxStyledTextCtrl_LineDownRectExtend 3308 -#define wxStyledTextCtrl_LineUpRectExtend 3309 -#define wxStyledTextCtrl_CharLeftRectExtend 3310 -#define wxStyledTextCtrl_CharRightRectExtend 3311 -#define wxStyledTextCtrl_HomeRectExtend 3312 -#define wxStyledTextCtrl_VCHomeRectExtend 3313 -#define wxStyledTextCtrl_LineEndRectExtend 3314 -#define wxStyledTextCtrl_PageUpRectExtend 3315 -#define wxStyledTextCtrl_PageDownRectExtend 3316 -#define wxStyledTextCtrl_StutteredPageUp 3317 -#define wxStyledTextCtrl_StutteredPageUpExtend 3318 -#define wxStyledTextCtrl_StutteredPageDown 3319 -#define wxStyledTextCtrl_StutteredPageDownExtend 3320 -#define wxStyledTextCtrl_WordLeftEnd 3321 -#define wxStyledTextCtrl_WordLeftEndExtend 3322 -#define wxStyledTextCtrl_WordRightEnd 3323 -#define wxStyledTextCtrl_WordRightEndExtend 3324 -#define wxStyledTextCtrl_SetWhitespaceChars 3325 -#define wxStyledTextCtrl_SetCharsDefault 3326 -#define wxStyledTextCtrl_AutoCompGetCurrent 3327 -#define wxStyledTextCtrl_Allocate 3328 -#define wxStyledTextCtrl_FindColumn 3329 -#define wxStyledTextCtrl_GetCaretSticky 3330 -#define wxStyledTextCtrl_SetCaretSticky 3331 -#define wxStyledTextCtrl_ToggleCaretSticky 3332 -#define wxStyledTextCtrl_SetPasteConvertEndings 3333 -#define wxStyledTextCtrl_GetPasteConvertEndings 3334 -#define wxStyledTextCtrl_SelectionDuplicate 3335 -#define wxStyledTextCtrl_SetCaretLineBackAlpha 3336 -#define wxStyledTextCtrl_GetCaretLineBackAlpha 3337 -#define wxStyledTextCtrl_StartRecord 3338 -#define wxStyledTextCtrl_StopRecord 3339 -#define wxStyledTextCtrl_SetLexer 3340 -#define wxStyledTextCtrl_GetLexer 3341 -#define wxStyledTextCtrl_Colourise 3342 -#define wxStyledTextCtrl_SetProperty 3343 -#define wxStyledTextCtrl_SetKeyWords 3344 -#define wxStyledTextCtrl_SetLexerLanguage 3345 -#define wxStyledTextCtrl_GetProperty 3346 -#define wxStyledTextCtrl_GetStyleBitsNeeded 3347 -#define wxStyledTextCtrl_GetCurrentLine 3348 -#define wxStyledTextCtrl_StyleSetSpec 3349 -#define wxStyledTextCtrl_StyleSetFont 3350 -#define wxStyledTextCtrl_StyleSetFontAttr 3351 -#define wxStyledTextCtrl_StyleSetCharacterSet 3352 -#define wxStyledTextCtrl_StyleSetFontEncoding 3353 -#define wxStyledTextCtrl_CmdKeyExecute 3354 -#define wxStyledTextCtrl_SetMargins 3355 -#define wxStyledTextCtrl_GetSelection 3356 -#define wxStyledTextCtrl_PointFromPosition 3357 -#define wxStyledTextCtrl_ScrollToLine 3358 -#define wxStyledTextCtrl_ScrollToColumn 3359 -#define wxStyledTextCtrl_SendMsg 3360 -#define wxStyledTextCtrl_SetVScrollBar 3361 -#define wxStyledTextCtrl_SetHScrollBar 3362 -#define wxStyledTextCtrl_GetLastKeydownProcessed 3363 -#define wxStyledTextCtrl_SetLastKeydownProcessed 3364 -#define wxStyledTextCtrl_SaveFile 3365 -#define wxStyledTextCtrl_LoadFile 3366 -#define wxStyledTextCtrl_DoDragOver 3367 -#define wxStyledTextCtrl_DoDropText 3368 -#define wxStyledTextCtrl_GetUseAntiAliasing 3369 -#define wxStyledTextCtrl_AddTextRaw 3370 -#define wxStyledTextCtrl_InsertTextRaw 3371 -#define wxStyledTextCtrl_GetCurLineRaw 3372 -#define wxStyledTextCtrl_GetLineRaw 3373 -#define wxStyledTextCtrl_GetSelectedTextRaw 3374 -#define wxStyledTextCtrl_GetTextRangeRaw 3375 -#define wxStyledTextCtrl_SetTextRaw 3376 -#define wxStyledTextCtrl_GetTextRaw 3377 -#define wxStyledTextCtrl_AppendTextRaw 3378 -#define wxArtProvider_GetBitmap 3379 -#define wxArtProvider_GetIcon 3380 -#define wxTreeEvent_GetKeyCode 3381 -#define wxTreeEvent_GetItem 3382 -#define wxTreeEvent_GetKeyEvent 3383 -#define wxTreeEvent_GetLabel 3384 -#define wxTreeEvent_GetOldItem 3385 -#define wxTreeEvent_GetPoint 3386 -#define wxTreeEvent_IsEditCancelled 3387 -#define wxTreeEvent_SetToolTip 3388 -#define wxNotebookEvent_GetOldSelection 3389 -#define wxNotebookEvent_GetSelection 3390 -#define wxNotebookEvent_SetOldSelection 3391 -#define wxNotebookEvent_SetSelection 3392 -#define wxFileDataObject_new 3393 -#define wxFileDataObject_AddFile 3394 -#define wxFileDataObject_GetFilenames 3395 -#define wxFileDataObject_destroy 3396 -#define wxTextDataObject_new 3397 -#define wxTextDataObject_GetTextLength 3398 -#define wxTextDataObject_GetText 3399 -#define wxTextDataObject_SetText 3400 -#define wxTextDataObject_destroy 3401 -#define wxBitmapDataObject_new_1_1 3402 -#define wxBitmapDataObject_new_1_0 3403 -#define wxBitmapDataObject_GetBitmap 3404 -#define wxBitmapDataObject_SetBitmap 3405 -#define wxBitmapDataObject_destroy 3406 -#define wxClipboard_new 3408 -#define wxClipboard_destruct 3409 -#define wxClipboard_AddData 3410 -#define wxClipboard_Clear 3411 -#define wxClipboard_Close 3412 -#define wxClipboard_Flush 3413 -#define wxClipboard_GetData 3414 -#define wxClipboard_IsOpened 3415 -#define wxClipboard_Open 3416 -#define wxClipboard_SetData 3417 -#define wxClipboard_UsePrimarySelection 3419 -#define wxClipboard_IsSupported 3420 -#define wxClipboard_Get 3421 -#define wxSpinEvent_GetPosition 3422 -#define wxSpinEvent_SetPosition 3423 -#define wxSplitterWindow_new_0 3424 -#define wxSplitterWindow_new_2 3425 -#define wxSplitterWindow_destruct 3426 -#define wxSplitterWindow_Create 3427 -#define wxSplitterWindow_GetMinimumPaneSize 3428 -#define wxSplitterWindow_GetSashGravity 3429 -#define wxSplitterWindow_GetSashPosition 3430 -#define wxSplitterWindow_GetSplitMode 3431 -#define wxSplitterWindow_GetWindow1 3432 -#define wxSplitterWindow_GetWindow2 3433 -#define wxSplitterWindow_Initialize 3434 -#define wxSplitterWindow_IsSplit 3435 -#define wxSplitterWindow_ReplaceWindow 3436 -#define wxSplitterWindow_SetSashGravity 3437 -#define wxSplitterWindow_SetSashPosition 3438 -#define wxSplitterWindow_SetSashSize 3439 -#define wxSplitterWindow_SetMinimumPaneSize 3440 -#define wxSplitterWindow_SetSplitMode 3441 -#define wxSplitterWindow_SplitHorizontally 3442 -#define wxSplitterWindow_SplitVertically 3443 -#define wxSplitterWindow_Unsplit 3444 -#define wxSplitterWindow_UpdateSize 3445 -#define wxSplitterEvent_GetSashPosition 3446 -#define wxSplitterEvent_GetX 3447 -#define wxSplitterEvent_GetY 3448 -#define wxSplitterEvent_GetWindowBeingRemoved 3449 -#define wxSplitterEvent_SetSashPosition 3450 -#define wxHtmlWindow_new_0 3451 -#define wxHtmlWindow_new_2 3452 -#define wxHtmlWindow_AppendToPage 3453 -#define wxHtmlWindow_GetOpenedAnchor 3454 -#define wxHtmlWindow_GetOpenedPage 3455 -#define wxHtmlWindow_GetOpenedPageTitle 3456 -#define wxHtmlWindow_GetRelatedFrame 3457 -#define wxHtmlWindow_HistoryBack 3458 -#define wxHtmlWindow_HistoryCanBack 3459 -#define wxHtmlWindow_HistoryCanForward 3460 -#define wxHtmlWindow_HistoryClear 3461 -#define wxHtmlWindow_HistoryForward 3462 -#define wxHtmlWindow_LoadFile 3463 -#define wxHtmlWindow_LoadPage 3464 -#define wxHtmlWindow_SelectAll 3465 -#define wxHtmlWindow_SelectionToText 3466 -#define wxHtmlWindow_SelectLine 3467 -#define wxHtmlWindow_SelectWord 3468 -#define wxHtmlWindow_SetBorders 3469 -#define wxHtmlWindow_SetFonts 3470 -#define wxHtmlWindow_SetPage 3471 -#define wxHtmlWindow_SetRelatedFrame 3472 -#define wxHtmlWindow_SetRelatedStatusBar 3473 -#define wxHtmlWindow_ToText 3474 -#define wxHtmlWindow_destroy 3475 -#define wxHtmlLinkEvent_GetLinkInfo 3476 -#define wxAuiNotebookEvent_SetSelection 3477 -#define wxAuiNotebookEvent_GetSelection 3478 -#define wxAuiNotebookEvent_SetOldSelection 3479 -#define wxAuiNotebookEvent_GetOldSelection 3480 -#define wxAuiNotebookEvent_SetDragSource 3481 -#define wxAuiNotebookEvent_GetDragSource 3482 -#define wxAuiManagerEvent_SetManager 3483 -#define wxAuiManagerEvent_GetManager 3484 -#define wxAuiManagerEvent_SetPane 3485 -#define wxAuiManagerEvent_GetPane 3486 -#define wxAuiManagerEvent_SetButton 3487 -#define wxAuiManagerEvent_GetButton 3488 -#define wxAuiManagerEvent_SetDC 3489 -#define wxAuiManagerEvent_GetDC 3490 -#define wxAuiManagerEvent_Veto 3491 -#define wxAuiManagerEvent_GetVeto 3492 -#define wxAuiManagerEvent_SetCanVeto 3493 -#define wxAuiManagerEvent_CanVeto 3494 -#define wxLogNull_new 3495 -#define wxLogNull_destroy 3496 +#define wxControlWithItems_getClientData 885 +#define wxControlWithItems_setClientData 886 +#define wxControlWithItems_GetCount 887 +#define wxControlWithItems_GetSelection 888 +#define wxControlWithItems_GetString 889 +#define wxControlWithItems_GetStringSelection 890 +#define wxControlWithItems_Insert_2 891 +#define wxControlWithItems_Insert_3 892 +#define wxControlWithItems_IsEmpty 893 +#define wxControlWithItems_Select 894 +#define wxControlWithItems_SetSelection 895 +#define wxControlWithItems_SetString 896 +#define wxControlWithItems_SetStringSelection 897 +#define wxMenu_new_2 900 +#define wxMenu_new_1 901 +#define wxMenu_destruct 903 +#define wxMenu_Append_3 904 +#define wxMenu_Append_1 905 +#define wxMenu_Append_4_0 906 +#define wxMenu_Append_4_1 907 +#define wxMenu_AppendCheckItem 908 +#define wxMenu_AppendRadioItem 909 +#define wxMenu_AppendSeparator 910 +#define wxMenu_Break 911 +#define wxMenu_Check 912 +#define wxMenu_Delete_1_0 913 +#define wxMenu_Delete_1_1 914 +#define wxMenu_Destroy_1_0 915 +#define wxMenu_Destroy_1_1 916 +#define wxMenu_Enable 917 +#define wxMenu_FindItem_1 918 +#define wxMenu_FindItem_2 919 +#define wxMenu_FindItemByPosition 920 +#define wxMenu_GetHelpString 921 +#define wxMenu_GetLabel 922 +#define wxMenu_GetMenuItemCount 923 +#define wxMenu_GetMenuItems 924 +#define wxMenu_GetTitle 926 +#define wxMenu_Insert_2 927 +#define wxMenu_Insert_3 928 +#define wxMenu_Insert_5_1 929 +#define wxMenu_Insert_5_0 930 +#define wxMenu_InsertCheckItem 931 +#define wxMenu_InsertRadioItem 932 +#define wxMenu_InsertSeparator 933 +#define wxMenu_IsChecked 934 +#define wxMenu_IsEnabled 935 +#define wxMenu_Prepend_1 936 +#define wxMenu_Prepend_2 937 +#define wxMenu_Prepend_4_1 938 +#define wxMenu_Prepend_4_0 939 +#define wxMenu_PrependCheckItem 940 +#define wxMenu_PrependRadioItem 941 +#define wxMenu_PrependSeparator 942 +#define wxMenu_Remove_1_0 943 +#define wxMenu_Remove_1_1 944 +#define wxMenu_SetHelpString 945 +#define wxMenu_SetLabel 946 +#define wxMenu_SetTitle 947 +#define wxMenuItem_new 948 +#define wxMenuItem_destruct 950 +#define wxMenuItem_Check 951 +#define wxMenuItem_Enable 952 +#define wxMenuItem_GetBitmap 953 +#define wxMenuItem_GetHelp 954 +#define wxMenuItem_GetId 955 +#define wxMenuItem_GetKind 956 +#define wxMenuItem_GetLabel 957 +#define wxMenuItem_GetLabelFromText 958 +#define wxMenuItem_GetMenu 959 +#define wxMenuItem_GetText 960 +#define wxMenuItem_GetSubMenu 961 +#define wxMenuItem_IsCheckable 962 +#define wxMenuItem_IsChecked 963 +#define wxMenuItem_IsEnabled 964 +#define wxMenuItem_IsSeparator 965 +#define wxMenuItem_IsSubMenu 966 +#define wxMenuItem_SetBitmap 967 +#define wxMenuItem_SetHelp 968 +#define wxMenuItem_SetMenu 969 +#define wxMenuItem_SetSubMenu 970 +#define wxMenuItem_SetText 971 +#define wxToolBar_AddControl 972 +#define wxToolBar_AddSeparator 973 +#define wxToolBar_AddTool_5 974 +#define wxToolBar_AddTool_4_0 975 +#define wxToolBar_AddTool_1 976 +#define wxToolBar_AddTool_4_1 977 +#define wxToolBar_AddTool_3 978 +#define wxToolBar_AddTool_6 979 +#define wxToolBar_AddCheckTool 980 +#define wxToolBar_AddRadioTool 981 +#define wxToolBar_DeleteTool 982 +#define wxToolBar_DeleteToolByPos 983 +#define wxToolBar_EnableTool 984 +#define wxToolBar_FindById 985 +#define wxToolBar_FindControl 986 +#define wxToolBar_FindToolForPosition 987 +#define wxToolBar_GetToolSize 988 +#define wxToolBar_GetToolBitmapSize 989 +#define wxToolBar_GetMargins 990 +#define wxToolBar_GetToolEnabled 991 +#define wxToolBar_GetToolLongHelp 992 +#define wxToolBar_GetToolPacking 993 +#define wxToolBar_GetToolPos 994 +#define wxToolBar_GetToolSeparation 995 +#define wxToolBar_GetToolShortHelp 996 +#define wxToolBar_GetToolState 997 +#define wxToolBar_InsertControl 998 +#define wxToolBar_InsertSeparator 999 +#define wxToolBar_InsertTool_5 1000 +#define wxToolBar_InsertTool_2 1001 +#define wxToolBar_InsertTool_4 1002 +#define wxToolBar_Realize 1003 +#define wxToolBar_RemoveTool 1004 +#define wxToolBar_SetMargins 1005 +#define wxToolBar_SetToolBitmapSize 1006 +#define wxToolBar_SetToolLongHelp 1007 +#define wxToolBar_SetToolPacking 1008 +#define wxToolBar_SetToolShortHelp 1009 +#define wxToolBar_SetToolSeparation 1010 +#define wxToolBar_ToggleTool 1011 +#define wxStatusBar_new_0 1013 +#define wxStatusBar_new_2 1014 +#define wxStatusBar_destruct 1016 +#define wxStatusBar_Create 1017 +#define wxStatusBar_GetFieldRect 1018 +#define wxStatusBar_GetFieldsCount 1019 +#define wxStatusBar_GetStatusText 1020 +#define wxStatusBar_PopStatusText 1021 +#define wxStatusBar_PushStatusText 1022 +#define wxStatusBar_SetFieldsCount 1023 +#define wxStatusBar_SetMinHeight 1024 +#define wxStatusBar_SetStatusText 1025 +#define wxStatusBar_SetStatusWidths 1026 +#define wxStatusBar_SetStatusStyles 1027 +#define wxBitmap_new_0 1028 +#define wxBitmap_new_3 1029 +#define wxBitmap_new_4 1030 +#define wxBitmap_new_2_0 1031 +#define wxBitmap_new_2_1 1032 +#define wxBitmap_destruct 1033 +#define wxBitmap_ConvertToImage 1034 +#define wxBitmap_CopyFromIcon 1035 +#define wxBitmap_Create 1036 +#define wxBitmap_GetDepth 1037 +#define wxBitmap_GetHeight 1038 +#define wxBitmap_GetPalette 1039 +#define wxBitmap_GetMask 1040 +#define wxBitmap_GetWidth 1041 +#define wxBitmap_GetSubBitmap 1042 +#define wxBitmap_LoadFile 1043 +#define wxBitmap_Ok 1044 +#define wxBitmap_SaveFile 1045 +#define wxBitmap_SetDepth 1046 +#define wxBitmap_SetHeight 1047 +#define wxBitmap_SetMask 1048 +#define wxBitmap_SetPalette 1049 +#define wxBitmap_SetWidth 1050 +#define wxIcon_new_0 1051 +#define wxIcon_new_2 1052 +#define wxIcon_new_1 1053 +#define wxIcon_CopyFromBitmap 1054 +#define wxIcon_destroy 1055 +#define wxIconBundle_new_0 1056 +#define wxIconBundle_new_2 1057 +#define wxIconBundle_new_1_0 1058 +#define wxIconBundle_new_1_1 1059 +#define wxIconBundle_destruct 1060 +#define wxIconBundle_AddIcon_2 1061 +#define wxIconBundle_AddIcon_1 1062 +#define wxIconBundle_GetIcon_1_1 1063 +#define wxIconBundle_GetIcon_1_0 1064 +#define wxCursor_new_0 1065 +#define wxCursor_new_1_0 1066 +#define wxCursor_new_1_1 1067 +#define wxCursor_new_4 1068 +#define wxCursor_destruct 1069 +#define wxCursor_Ok 1070 +#define wxMask_new_0 1071 +#define wxMask_new_2_1 1072 +#define wxMask_new_2_0 1073 +#define wxMask_new_1 1074 +#define wxMask_destruct 1075 +#define wxMask_Create_2_1 1076 +#define wxMask_Create_2_0 1077 +#define wxMask_Create_1 1078 +#define wxImage_new_0 1079 +#define wxImage_new_3_0 1080 +#define wxImage_new_4 1081 +#define wxImage_new_5 1082 +#define wxImage_new_2 1083 +#define wxImage_new_3_1 1084 +#define wxImage_Blur 1085 +#define wxImage_BlurHorizontal 1086 +#define wxImage_BlurVertical 1087 +#define wxImage_ConvertAlphaToMask 1088 +#define wxImage_ConvertToGreyscale 1089 +#define wxImage_ConvertToMono 1090 +#define wxImage_Copy 1091 +#define wxImage_Create_3 1092 +#define wxImage_Create_4 1093 +#define wxImage_Create_5 1094 +#define wxImage_Destroy 1095 +#define wxImage_FindFirstUnusedColour 1096 +#define wxImage_GetImageExtWildcard 1097 +#define wxImage_GetAlpha_2 1098 +#define wxImage_GetAlpha_0 1099 +#define wxImage_GetBlue 1100 +#define wxImage_GetData 1101 +#define wxImage_GetGreen 1102 +#define wxImage_GetImageCount 1103 +#define wxImage_GetHeight 1104 +#define wxImage_GetMaskBlue 1105 +#define wxImage_GetMaskGreen 1106 +#define wxImage_GetMaskRed 1107 +#define wxImage_GetOrFindMaskColour 1108 +#define wxImage_GetPalette 1109 +#define wxImage_GetRed 1110 +#define wxImage_GetSubImage 1111 +#define wxImage_GetWidth 1112 +#define wxImage_HasAlpha 1113 +#define wxImage_HasMask 1114 +#define wxImage_GetOption 1115 +#define wxImage_GetOptionInt 1116 +#define wxImage_HasOption 1117 +#define wxImage_InitAlpha 1118 +#define wxImage_InitStandardHandlers 1119 +#define wxImage_IsTransparent 1120 +#define wxImage_LoadFile_2 1121 +#define wxImage_LoadFile_3 1122 +#define wxImage_Ok 1123 +#define wxImage_RemoveHandler 1124 +#define wxImage_Mirror 1125 +#define wxImage_Replace 1126 +#define wxImage_Rescale 1127 +#define wxImage_Resize 1128 +#define wxImage_Rotate 1129 +#define wxImage_RotateHue 1130 +#define wxImage_Rotate90 1131 +#define wxImage_SaveFile_1 1132 +#define wxImage_SaveFile_2_0 1133 +#define wxImage_SaveFile_2_1 1134 +#define wxImage_Scale 1135 +#define wxImage_Size 1136 +#define wxImage_SetAlpha_3 1137 +#define wxImage_SetAlpha_2 1138 +#define wxImage_SetData_2 1139 +#define wxImage_SetData_4 1140 +#define wxImage_SetMask 1141 +#define wxImage_SetMaskColour 1142 +#define wxImage_SetMaskFromImage 1143 +#define wxImage_SetOption_2_1 1144 +#define wxImage_SetOption_2_0 1145 +#define wxImage_SetPalette 1146 +#define wxImage_SetRGB_5 1147 +#define wxImage_SetRGB_4 1148 +#define wxImage_destroy 1149 +#define wxBrush_new_0 1150 +#define wxBrush_new_2 1151 +#define wxBrush_new_1 1152 +#define wxBrush_destruct 1154 +#define wxBrush_GetColour 1155 +#define wxBrush_GetStipple 1156 +#define wxBrush_GetStyle 1157 +#define wxBrush_IsHatch 1158 +#define wxBrush_IsOk 1159 +#define wxBrush_SetColour_1 1160 +#define wxBrush_SetColour_3 1161 +#define wxBrush_SetStipple 1162 +#define wxBrush_SetStyle 1163 +#define wxPen_new_0 1164 +#define wxPen_new_2 1165 +#define wxPen_destruct 1166 +#define wxPen_GetCap 1167 +#define wxPen_GetColour 1168 +#define wxPen_GetJoin 1169 +#define wxPen_GetStyle 1170 +#define wxPen_GetWidth 1171 +#define wxPen_IsOk 1172 +#define wxPen_SetCap 1173 +#define wxPen_SetColour_1 1174 +#define wxPen_SetColour_3 1175 +#define wxPen_SetJoin 1176 +#define wxPen_SetStyle 1177 +#define wxPen_SetWidth 1178 +#define wxRegion_new_0 1179 +#define wxRegion_new_4 1180 +#define wxRegion_new_2 1181 +#define wxRegion_new_1_1 1182 +#define wxRegion_new_1_0 1184 +#define wxRegion_destruct 1186 +#define wxRegion_Clear 1187 +#define wxRegion_Contains_2 1188 +#define wxRegion_Contains_1_0 1189 +#define wxRegion_Contains_4 1190 +#define wxRegion_Contains_1_1 1191 +#define wxRegion_ConvertToBitmap 1192 +#define wxRegion_GetBox 1193 +#define wxRegion_Intersect_4 1194 +#define wxRegion_Intersect_1_1 1195 +#define wxRegion_Intersect_1_0 1196 +#define wxRegion_IsEmpty 1197 +#define wxRegion_Subtract_4 1198 +#define wxRegion_Subtract_1_1 1199 +#define wxRegion_Subtract_1_0 1200 +#define wxRegion_Offset_2 1201 +#define wxRegion_Offset_1 1202 +#define wxRegion_Union_4 1203 +#define wxRegion_Union_1_2 1204 +#define wxRegion_Union_1_1 1205 +#define wxRegion_Union_1_0 1206 +#define wxRegion_Union_3 1207 +#define wxRegion_Xor_4 1208 +#define wxRegion_Xor_1_1 1209 +#define wxRegion_Xor_1_0 1210 +#define wxAcceleratorTable_new_0 1211 +#define wxAcceleratorTable_new_2 1212 +#define wxAcceleratorTable_destruct 1213 +#define wxAcceleratorTable_Ok 1214 +#define wxAcceleratorEntry_new_1_0 1215 +#define wxAcceleratorEntry_new_1_1 1216 +#define wxAcceleratorEntry_GetCommand 1217 +#define wxAcceleratorEntry_GetFlags 1218 +#define wxAcceleratorEntry_GetKeyCode 1219 +#define wxAcceleratorEntry_Set 1220 +#define wxAcceleratorEntry_destroy 1221 +#define wxCaret_new_3 1226 +#define wxCaret_new_2 1227 +#define wxCaret_destruct 1229 +#define wxCaret_Create_3 1230 +#define wxCaret_Create_2 1231 +#define wxCaret_GetBlinkTime 1232 +#define wxCaret_GetPosition 1234 +#define wxCaret_GetSize 1236 +#define wxCaret_GetWindow 1237 +#define wxCaret_Hide 1238 +#define wxCaret_IsOk 1239 +#define wxCaret_IsVisible 1240 +#define wxCaret_Move_2 1241 +#define wxCaret_Move_1 1242 +#define wxCaret_SetBlinkTime 1243 +#define wxCaret_SetSize_2 1244 +#define wxCaret_SetSize_1 1245 +#define wxCaret_Show 1246 +#define wxSizer_Add_2_1 1247 +#define wxSizer_Add_2_0 1248 +#define wxSizer_Add_3 1249 +#define wxSizer_Add_2_3 1250 +#define wxSizer_Add_2_2 1251 +#define wxSizer_AddSpacer 1252 +#define wxSizer_AddStretchSpacer 1253 +#define wxSizer_CalcMin 1254 +#define wxSizer_Clear 1255 +#define wxSizer_Detach_1_2 1256 +#define wxSizer_Detach_1_1 1257 +#define wxSizer_Detach_1_0 1258 +#define wxSizer_Fit 1259 +#define wxSizer_FitInside 1260 +#define wxSizer_GetChildren 1261 +#define wxSizer_GetItem_2_1 1262 +#define wxSizer_GetItem_2_0 1263 +#define wxSizer_GetItem_1 1264 +#define wxSizer_GetSize 1265 +#define wxSizer_GetPosition 1266 +#define wxSizer_GetMinSize 1267 +#define wxSizer_Hide_2_0 1268 +#define wxSizer_Hide_2_1 1269 +#define wxSizer_Hide_1 1270 +#define wxSizer_Insert_3_1 1271 +#define wxSizer_Insert_3_0 1272 +#define wxSizer_Insert_4 1273 +#define wxSizer_Insert_3_3 1274 +#define wxSizer_Insert_3_2 1275 +#define wxSizer_Insert_2 1276 +#define wxSizer_InsertSpacer 1277 +#define wxSizer_InsertStretchSpacer 1278 +#define wxSizer_IsShown_1_2 1279 +#define wxSizer_IsShown_1_1 1280 +#define wxSizer_IsShown_1_0 1281 +#define wxSizer_Layout 1282 +#define wxSizer_Prepend_2_1 1283 +#define wxSizer_Prepend_2_0 1284 +#define wxSizer_Prepend_3 1285 +#define wxSizer_Prepend_2_3 1286 +#define wxSizer_Prepend_2_2 1287 +#define wxSizer_Prepend_1 1288 +#define wxSizer_PrependSpacer 1289 +#define wxSizer_PrependStretchSpacer 1290 +#define wxSizer_RecalcSizes 1291 +#define wxSizer_Remove_1_1 1292 +#define wxSizer_Remove_1_0 1293 +#define wxSizer_Replace_3_1 1294 +#define wxSizer_Replace_3_0 1295 +#define wxSizer_Replace_2 1296 +#define wxSizer_SetDimension 1297 +#define wxSizer_SetMinSize_2 1298 +#define wxSizer_SetMinSize_1 1299 +#define wxSizer_SetItemMinSize_3_2 1300 +#define wxSizer_SetItemMinSize_2_2 1301 +#define wxSizer_SetItemMinSize_3_1 1302 +#define wxSizer_SetItemMinSize_2_1 1303 +#define wxSizer_SetItemMinSize_3_0 1304 +#define wxSizer_SetItemMinSize_2_0 1305 +#define wxSizer_SetSizeHints 1306 +#define wxSizer_SetVirtualSizeHints 1307 +#define wxSizer_Show_2_2 1308 +#define wxSizer_Show_2_1 1309 +#define wxSizer_Show_2_0 1310 +#define wxSizer_Show_1 1311 +#define wxSizerFlags_new 1312 +#define wxSizerFlags_Align 1313 +#define wxSizerFlags_Border_2 1314 +#define wxSizerFlags_Border_1 1315 +#define wxSizerFlags_Center 1316 +#define wxSizerFlags_Centre 1317 +#define wxSizerFlags_Expand 1318 +#define wxSizerFlags_Left 1319 +#define wxSizerFlags_Proportion 1320 +#define wxSizerFlags_Right 1321 +#define wxSizerFlags_destroy 1322 +#define wxSizerItem_new_5_1 1323 +#define wxSizerItem_new_2_1 1324 +#define wxSizerItem_new_5_0 1325 +#define wxSizerItem_new_2_0 1326 +#define wxSizerItem_new_6 1327 +#define wxSizerItem_new_3 1328 +#define wxSizerItem_new_0 1329 +#define wxSizerItem_destruct 1330 +#define wxSizerItem_CalcMin 1331 +#define wxSizerItem_DeleteWindows 1332 +#define wxSizerItem_DetachSizer 1333 +#define wxSizerItem_GetBorder 1334 +#define wxSizerItem_GetFlag 1335 +#define wxSizerItem_GetMinSize 1336 +#define wxSizerItem_GetPosition 1337 +#define wxSizerItem_GetProportion 1338 +#define wxSizerItem_GetRatio 1339 +#define wxSizerItem_GetRect 1340 +#define wxSizerItem_GetSize 1341 +#define wxSizerItem_GetSizer 1342 +#define wxSizerItem_GetSpacer 1343 +#define wxSizerItem_GetUserData 1344 +#define wxSizerItem_GetWindow 1345 +#define wxSizerItem_IsSizer 1346 +#define wxSizerItem_IsShown 1347 +#define wxSizerItem_IsSpacer 1348 +#define wxSizerItem_IsWindow 1349 +#define wxSizerItem_SetBorder 1350 +#define wxSizerItem_SetDimension 1351 +#define wxSizerItem_SetFlag 1352 +#define wxSizerItem_SetInitSize 1353 +#define wxSizerItem_SetMinSize_1 1354 +#define wxSizerItem_SetMinSize_2 1355 +#define wxSizerItem_SetProportion 1356 +#define wxSizerItem_SetRatio_2 1357 +#define wxSizerItem_SetRatio_1_1 1358 +#define wxSizerItem_SetRatio_1_0 1359 +#define wxSizerItem_SetSizer 1360 +#define wxSizerItem_SetSpacer_1 1361 +#define wxSizerItem_SetSpacer_2 1362 +#define wxSizerItem_SetWindow 1363 +#define wxSizerItem_Show 1364 +#define wxBoxSizer_new 1365 +#define wxBoxSizer_GetOrientation 1366 +#define wxBoxSizer_destroy 1367 +#define wxStaticBoxSizer_new_2 1368 +#define wxStaticBoxSizer_new_3 1369 +#define wxStaticBoxSizer_GetStaticBox 1370 +#define wxStaticBoxSizer_destroy 1371 +#define wxGridSizer_new_4 1372 +#define wxGridSizer_new_2 1373 +#define wxGridSizer_GetCols 1374 +#define wxGridSizer_GetHGap 1375 +#define wxGridSizer_GetRows 1376 +#define wxGridSizer_GetVGap 1377 +#define wxGridSizer_SetCols 1378 +#define wxGridSizer_SetHGap 1379 +#define wxGridSizer_SetRows 1380 +#define wxGridSizer_SetVGap 1381 +#define wxGridSizer_destroy 1382 +#define wxFlexGridSizer_new_4 1383 +#define wxFlexGridSizer_new_2 1384 +#define wxFlexGridSizer_AddGrowableCol 1385 +#define wxFlexGridSizer_AddGrowableRow 1386 +#define wxFlexGridSizer_GetFlexibleDirection 1387 +#define wxFlexGridSizer_GetNonFlexibleGrowMode 1388 +#define wxFlexGridSizer_RemoveGrowableCol 1389 +#define wxFlexGridSizer_RemoveGrowableRow 1390 +#define wxFlexGridSizer_SetFlexibleDirection 1391 +#define wxFlexGridSizer_SetNonFlexibleGrowMode 1392 +#define wxFlexGridSizer_destroy 1393 +#define wxGridBagSizer_new 1394 +#define wxGridBagSizer_Add_3_2 1395 +#define wxGridBagSizer_Add_3_1 1396 +#define wxGridBagSizer_Add_4 1397 +#define wxGridBagSizer_Add_1_0 1398 +#define wxGridBagSizer_Add_2_1 1399 +#define wxGridBagSizer_Add_2_0 1400 +#define wxGridBagSizer_Add_3_0 1401 +#define wxGridBagSizer_Add_1_1 1402 +#define wxGridBagSizer_CalcMin 1403 +#define wxGridBagSizer_CheckForIntersection_2 1404 +#define wxGridBagSizer_CheckForIntersection_3 1405 +#define wxGridBagSizer_FindItem_1_1 1406 +#define wxGridBagSizer_FindItem_1_0 1407 +#define wxGridBagSizer_FindItemAtPoint 1408 +#define wxGridBagSizer_FindItemAtPosition 1409 +#define wxGridBagSizer_FindItemWithData 1410 +#define wxGridBagSizer_GetCellSize 1411 +#define wxGridBagSizer_GetEmptyCellSize 1412 +#define wxGridBagSizer_GetItemPosition_1_2 1413 +#define wxGridBagSizer_GetItemPosition_1_1 1414 +#define wxGridBagSizer_GetItemPosition_1_0 1415 +#define wxGridBagSizer_GetItemSpan_1_2 1416 +#define wxGridBagSizer_GetItemSpan_1_1 1417 +#define wxGridBagSizer_GetItemSpan_1_0 1418 +#define wxGridBagSizer_SetEmptyCellSize 1419 +#define wxGridBagSizer_SetItemPosition_2_2 1420 +#define wxGridBagSizer_SetItemPosition_2_1 1421 +#define wxGridBagSizer_SetItemPosition_2_0 1422 +#define wxGridBagSizer_SetItemSpan_2_2 1423 +#define wxGridBagSizer_SetItemSpan_2_1 1424 +#define wxGridBagSizer_SetItemSpan_2_0 1425 +#define wxGridBagSizer_destroy 1426 +#define wxStdDialogButtonSizer_new 1427 +#define wxStdDialogButtonSizer_AddButton 1428 +#define wxStdDialogButtonSizer_Realize 1429 +#define wxStdDialogButtonSizer_SetAffirmativeButton 1430 +#define wxStdDialogButtonSizer_SetCancelButton 1431 +#define wxStdDialogButtonSizer_SetNegativeButton 1432 +#define wxStdDialogButtonSizer_destroy 1433 +#define wxFont_new_0 1434 +#define wxFont_new_1 1435 +#define wxFont_new_5 1436 +#define wxFont_destruct 1438 +#define wxFont_IsFixedWidth 1439 +#define wxFont_GetDefaultEncoding 1440 +#define wxFont_GetFaceName 1441 +#define wxFont_GetFamily 1442 +#define wxFont_GetNativeFontInfoDesc 1443 +#define wxFont_GetNativeFontInfoUserDesc 1444 +#define wxFont_GetPointSize 1445 +#define wxFont_GetStyle 1446 +#define wxFont_GetUnderlined 1447 +#define wxFont_GetWeight 1448 +#define wxFont_Ok 1449 +#define wxFont_SetDefaultEncoding 1450 +#define wxFont_SetFaceName 1451 +#define wxFont_SetFamily 1452 +#define wxFont_SetPointSize 1453 +#define wxFont_SetStyle 1454 +#define wxFont_SetUnderlined 1455 +#define wxFont_SetWeight 1456 +#define wxToolTip_Enable 1457 +#define wxToolTip_SetDelay 1458 +#define wxToolTip_new 1459 +#define wxToolTip_SetTip 1460 +#define wxToolTip_GetTip 1461 +#define wxToolTip_GetWindow 1462 +#define wxToolTip_destroy 1463 +#define wxButton_new_3 1465 +#define wxButton_new_0 1466 +#define wxButton_destruct 1467 +#define wxButton_Create 1468 +#define wxButton_GetDefaultSize 1469 +#define wxButton_SetDefault 1470 +#define wxButton_SetLabel 1471 +#define wxBitmapButton_new_4 1473 +#define wxBitmapButton_new_0 1474 +#define wxBitmapButton_Create 1475 +#define wxBitmapButton_GetBitmapDisabled 1476 +#define wxBitmapButton_GetBitmapFocus 1478 +#define wxBitmapButton_GetBitmapLabel 1480 +#define wxBitmapButton_GetBitmapSelected 1482 +#define wxBitmapButton_SetBitmapDisabled 1484 +#define wxBitmapButton_SetBitmapFocus 1485 +#define wxBitmapButton_SetBitmapLabel 1486 +#define wxBitmapButton_SetBitmapSelected 1487 +#define wxBitmapButton_destroy 1488 +#define wxToggleButton_new_0 1489 +#define wxToggleButton_new_4 1490 +#define wxToggleButton_Create 1491 +#define wxToggleButton_GetValue 1492 +#define wxToggleButton_SetValue 1493 +#define wxToggleButton_destroy 1494 +#define wxCalendarCtrl_new_0 1495 +#define wxCalendarCtrl_new_3 1496 +#define wxCalendarCtrl_Create 1497 +#define wxCalendarCtrl_destruct 1498 +#define wxCalendarCtrl_SetDate 1499 +#define wxCalendarCtrl_GetDate 1500 +#define wxCalendarCtrl_EnableYearChange 1501 +#define wxCalendarCtrl_EnableMonthChange 1502 +#define wxCalendarCtrl_EnableHolidayDisplay 1503 +#define wxCalendarCtrl_SetHeaderColours 1504 +#define wxCalendarCtrl_GetHeaderColourFg 1505 +#define wxCalendarCtrl_GetHeaderColourBg 1506 +#define wxCalendarCtrl_SetHighlightColours 1507 +#define wxCalendarCtrl_GetHighlightColourFg 1508 +#define wxCalendarCtrl_GetHighlightColourBg 1509 +#define wxCalendarCtrl_SetHolidayColours 1510 +#define wxCalendarCtrl_GetHolidayColourFg 1511 +#define wxCalendarCtrl_GetHolidayColourBg 1512 +#define wxCalendarCtrl_GetAttr 1513 +#define wxCalendarCtrl_SetAttr 1514 +#define wxCalendarCtrl_SetHoliday 1515 +#define wxCalendarCtrl_ResetAttr 1516 +#define wxCalendarCtrl_HitTest 1517 +#define wxCalendarDateAttr_new_0 1518 +#define wxCalendarDateAttr_new_2_1 1519 +#define wxCalendarDateAttr_new_2_0 1520 +#define wxCalendarDateAttr_SetTextColour 1521 +#define wxCalendarDateAttr_SetBackgroundColour 1522 +#define wxCalendarDateAttr_SetBorderColour 1523 +#define wxCalendarDateAttr_SetFont 1524 +#define wxCalendarDateAttr_SetBorder 1525 +#define wxCalendarDateAttr_SetHoliday 1526 +#define wxCalendarDateAttr_HasTextColour 1527 +#define wxCalendarDateAttr_HasBackgroundColour 1528 +#define wxCalendarDateAttr_HasBorderColour 1529 +#define wxCalendarDateAttr_HasFont 1530 +#define wxCalendarDateAttr_HasBorder 1531 +#define wxCalendarDateAttr_IsHoliday 1532 +#define wxCalendarDateAttr_GetTextColour 1533 +#define wxCalendarDateAttr_GetBackgroundColour 1534 +#define wxCalendarDateAttr_GetBorderColour 1535 +#define wxCalendarDateAttr_GetFont 1536 +#define wxCalendarDateAttr_GetBorder 1537 +#define wxCalendarDateAttr_destroy 1538 +#define wxCheckBox_new_4 1540 +#define wxCheckBox_new_0 1541 +#define wxCheckBox_Create 1542 +#define wxCheckBox_GetValue 1543 +#define wxCheckBox_Get3StateValue 1544 +#define wxCheckBox_Is3rdStateAllowedForUser 1545 +#define wxCheckBox_Is3State 1546 +#define wxCheckBox_IsChecked 1547 +#define wxCheckBox_SetValue 1548 +#define wxCheckBox_Set3StateValue 1549 +#define wxCheckBox_destroy 1550 +#define wxCheckListBox_new_0 1551 +#define wxCheckListBox_new_3 1553 +#define wxCheckListBox_Check 1554 +#define wxCheckListBox_IsChecked 1555 +#define wxCheckListBox_destroy 1556 +#define wxChoice_new_3 1559 +#define wxChoice_new_0 1560 +#define wxChoice_destruct 1562 +#define wxChoice_Create 1564 +#define wxChoice_Delete 1565 +#define wxChoice_GetColumns 1566 +#define wxChoice_SetColumns 1567 +#define wxComboBox_new_0 1568 +#define wxComboBox_new_3 1570 +#define wxComboBox_destruct 1571 +#define wxComboBox_Create 1573 +#define wxComboBox_CanCopy 1574 +#define wxComboBox_CanCut 1575 +#define wxComboBox_CanPaste 1576 +#define wxComboBox_CanRedo 1577 +#define wxComboBox_CanUndo 1578 +#define wxComboBox_Copy 1579 +#define wxComboBox_Cut 1580 +#define wxComboBox_GetInsertionPoint 1581 +#define wxComboBox_GetLastPosition 1582 +#define wxComboBox_GetValue 1583 +#define wxComboBox_Paste 1584 +#define wxComboBox_Redo 1585 +#define wxComboBox_Replace 1586 +#define wxComboBox_Remove 1587 +#define wxComboBox_SetInsertionPoint 1588 +#define wxComboBox_SetInsertionPointEnd 1589 +#define wxComboBox_SetSelection_1 1590 +#define wxComboBox_SetSelection_2 1591 +#define wxComboBox_SetValue 1592 +#define wxComboBox_Undo 1593 +#define wxGauge_new_0 1594 +#define wxGauge_new_4 1595 +#define wxGauge_Create 1596 +#define wxGauge_GetBezelFace 1597 +#define wxGauge_GetRange 1598 +#define wxGauge_GetShadowWidth 1599 +#define wxGauge_GetValue 1600 +#define wxGauge_IsVertical 1601 +#define wxGauge_SetBezelFace 1602 +#define wxGauge_SetRange 1603 +#define wxGauge_SetShadowWidth 1604 +#define wxGauge_SetValue 1605 +#define wxGauge_Pulse 1606 +#define wxGauge_destroy 1607 +#define wxGenericDirCtrl_new_0 1608 +#define wxGenericDirCtrl_new_2 1609 +#define wxGenericDirCtrl_destruct 1610 +#define wxGenericDirCtrl_Create 1611 +#define wxGenericDirCtrl_Init 1612 +#define wxGenericDirCtrl_CollapseTree 1613 +#define wxGenericDirCtrl_ExpandPath 1614 +#define wxGenericDirCtrl_GetDefaultPath 1615 +#define wxGenericDirCtrl_GetPath 1616 +#define wxGenericDirCtrl_GetFilePath 1617 +#define wxGenericDirCtrl_GetFilter 1618 +#define wxGenericDirCtrl_GetFilterIndex 1619 +#define wxGenericDirCtrl_GetRootId 1620 +#define wxGenericDirCtrl_GetTreeCtrl 1621 +#define wxGenericDirCtrl_ReCreateTree 1622 +#define wxGenericDirCtrl_SetDefaultPath 1623 +#define wxGenericDirCtrl_SetFilter 1624 +#define wxGenericDirCtrl_SetFilterIndex 1625 +#define wxGenericDirCtrl_SetPath 1626 +#define wxStaticBox_new_4 1628 +#define wxStaticBox_new_0 1629 +#define wxStaticBox_Create 1630 +#define wxStaticBox_destroy 1631 +#define wxStaticLine_new_2 1633 +#define wxStaticLine_new_0 1634 +#define wxStaticLine_Create 1635 +#define wxStaticLine_IsVertical 1636 +#define wxStaticLine_GetDefaultSize 1637 +#define wxStaticLine_destroy 1638 +#define wxListBox_new_3 1641 +#define wxListBox_new_0 1642 +#define wxListBox_destruct 1644 +#define wxListBox_Create 1646 +#define wxListBox_Deselect 1647 +#define wxListBox_GetSelections 1648 +#define wxListBox_InsertItems 1649 +#define wxListBox_IsSelected 1650 +#define wxListBox_Set 1652 +#define wxListBox_HitTest 1653 +#define wxListBox_SetFirstItem_1_0 1654 +#define wxListBox_SetFirstItem_1_1 1655 +#define wxListCtrl_new_0 1656 +#define wxListCtrl_new_2 1657 +#define wxListCtrl_Arrange 1658 +#define wxListCtrl_AssignImageList 1659 +#define wxListCtrl_ClearAll 1660 +#define wxListCtrl_Create 1661 +#define wxListCtrl_DeleteAllItems 1662 +#define wxListCtrl_DeleteColumn 1663 +#define wxListCtrl_DeleteItem 1664 +#define wxListCtrl_EditLabel 1665 +#define wxListCtrl_EnsureVisible 1666 +#define wxListCtrl_FindItem_3_0 1667 +#define wxListCtrl_FindItem_3_1 1668 +#define wxListCtrl_GetColumn 1669 +#define wxListCtrl_GetColumnCount 1670 +#define wxListCtrl_GetColumnWidth 1671 +#define wxListCtrl_GetCountPerPage 1672 +#define wxListCtrl_GetEditControl 1673 +#define wxListCtrl_GetImageList 1674 +#define wxListCtrl_GetItem 1675 +#define wxListCtrl_GetItemBackgroundColour 1676 +#define wxListCtrl_GetItemCount 1677 +#define wxListCtrl_GetItemData 1678 +#define wxListCtrl_GetItemFont 1679 +#define wxListCtrl_GetItemPosition 1680 +#define wxListCtrl_GetItemRect 1681 +#define wxListCtrl_GetItemSpacing 1682 +#define wxListCtrl_GetItemState 1683 +#define wxListCtrl_GetItemText 1684 +#define wxListCtrl_GetItemTextColour 1685 +#define wxListCtrl_GetNextItem 1686 +#define wxListCtrl_GetSelectedItemCount 1687 +#define wxListCtrl_GetTextColour 1688 +#define wxListCtrl_GetTopItem 1689 +#define wxListCtrl_GetViewRect 1690 +#define wxListCtrl_HitTest 1691 +#define wxListCtrl_InsertColumn_2 1692 +#define wxListCtrl_InsertColumn_3 1693 +#define wxListCtrl_InsertItem_1 1694 +#define wxListCtrl_InsertItem_2_1 1695 +#define wxListCtrl_InsertItem_2_0 1696 +#define wxListCtrl_InsertItem_3 1697 +#define wxListCtrl_RefreshItem 1698 +#define wxListCtrl_RefreshItems 1699 +#define wxListCtrl_ScrollList 1700 +#define wxListCtrl_SetBackgroundColour 1701 +#define wxListCtrl_SetColumn 1702 +#define wxListCtrl_SetColumnWidth 1703 +#define wxListCtrl_SetImageList 1704 +#define wxListCtrl_SetItem_1 1705 +#define wxListCtrl_SetItem_4 1706 +#define wxListCtrl_SetItemBackgroundColour 1707 +#define wxListCtrl_SetItemCount 1708 +#define wxListCtrl_SetItemData 1709 +#define wxListCtrl_SetItemFont 1710 +#define wxListCtrl_SetItemImage 1711 +#define wxListCtrl_SetItemColumnImage 1712 +#define wxListCtrl_SetItemPosition 1713 +#define wxListCtrl_SetItemState 1714 +#define wxListCtrl_SetItemText 1715 +#define wxListCtrl_SetItemTextColour 1716 +#define wxListCtrl_SetSingleStyle 1717 +#define wxListCtrl_SetTextColour 1718 +#define wxListCtrl_SetWindowStyleFlag 1719 +#define wxListCtrl_SortItems 1720 +#define wxListCtrl_destroy 1721 +#define wxListView_ClearColumnImage 1722 +#define wxListView_Focus 1723 +#define wxListView_GetFirstSelected 1724 +#define wxListView_GetFocusedItem 1725 +#define wxListView_GetNextSelected 1726 +#define wxListView_IsSelected 1727 +#define wxListView_Select 1728 +#define wxListView_SetColumnImage 1729 +#define wxListItem_new_0 1730 +#define wxListItem_new_1 1731 +#define wxListItem_destruct 1732 +#define wxListItem_Clear 1733 +#define wxListItem_GetAlign 1734 +#define wxListItem_GetBackgroundColour 1735 +#define wxListItem_GetColumn 1736 +#define wxListItem_GetFont 1737 +#define wxListItem_GetId 1738 +#define wxListItem_GetImage 1739 +#define wxListItem_GetMask 1740 +#define wxListItem_GetState 1741 +#define wxListItem_GetText 1742 +#define wxListItem_GetTextColour 1743 +#define wxListItem_GetWidth 1744 +#define wxListItem_SetAlign 1745 +#define wxListItem_SetBackgroundColour 1746 +#define wxListItem_SetColumn 1747 +#define wxListItem_SetFont 1748 +#define wxListItem_SetId 1749 +#define wxListItem_SetImage 1750 +#define wxListItem_SetMask 1751 +#define wxListItem_SetState 1752 +#define wxListItem_SetStateMask 1753 +#define wxListItem_SetText 1754 +#define wxListItem_SetTextColour 1755 +#define wxListItem_SetWidth 1756 +#define wxImageList_new_0 1757 +#define wxImageList_new_3 1758 +#define wxImageList_Add_1 1759 +#define wxImageList_Add_2_0 1760 +#define wxImageList_Add_2_1 1761 +#define wxImageList_Create 1762 +#define wxImageList_Draw 1764 +#define wxImageList_GetBitmap 1765 +#define wxImageList_GetIcon 1766 +#define wxImageList_GetImageCount 1767 +#define wxImageList_GetSize 1768 +#define wxImageList_Remove 1769 +#define wxImageList_RemoveAll 1770 +#define wxImageList_Replace_2 1771 +#define wxImageList_Replace_3 1772 +#define wxImageList_destroy 1773 +#define wxTextAttr_new_0 1774 +#define wxTextAttr_new_2 1775 +#define wxTextAttr_GetAlignment 1776 +#define wxTextAttr_GetBackgroundColour 1777 +#define wxTextAttr_GetFont 1778 +#define wxTextAttr_GetLeftIndent 1779 +#define wxTextAttr_GetLeftSubIndent 1780 +#define wxTextAttr_GetRightIndent 1781 +#define wxTextAttr_GetTabs 1782 +#define wxTextAttr_GetTextColour 1783 +#define wxTextAttr_HasBackgroundColour 1784 +#define wxTextAttr_HasFont 1785 +#define wxTextAttr_HasTextColour 1786 +#define wxTextAttr_GetFlags 1787 +#define wxTextAttr_IsDefault 1788 +#define wxTextAttr_SetAlignment 1789 +#define wxTextAttr_SetBackgroundColour 1790 +#define wxTextAttr_SetFlags 1791 +#define wxTextAttr_SetFont 1792 +#define wxTextAttr_SetLeftIndent 1793 +#define wxTextAttr_SetRightIndent 1794 +#define wxTextAttr_SetTabs 1795 +#define wxTextAttr_SetTextColour 1796 +#define wxTextAttr_destroy 1797 +#define wxTextCtrl_new_3 1799 +#define wxTextCtrl_new_0 1800 +#define wxTextCtrl_destruct 1802 +#define wxTextCtrl_AppendText 1803 +#define wxTextCtrl_CanCopy 1804 +#define wxTextCtrl_CanCut 1805 +#define wxTextCtrl_CanPaste 1806 +#define wxTextCtrl_CanRedo 1807 +#define wxTextCtrl_CanUndo 1808 +#define wxTextCtrl_Clear 1809 +#define wxTextCtrl_Copy 1810 +#define wxTextCtrl_Create 1811 +#define wxTextCtrl_Cut 1812 +#define wxTextCtrl_DiscardEdits 1813 +#define wxTextCtrl_EmulateKeyPress 1814 +#define wxTextCtrl_GetDefaultStyle 1815 +#define wxTextCtrl_GetInsertionPoint 1816 +#define wxTextCtrl_GetLastPosition 1817 +#define wxTextCtrl_GetLineLength 1818 +#define wxTextCtrl_GetLineText 1819 +#define wxTextCtrl_GetNumberOfLines 1820 +#define wxTextCtrl_GetRange 1821 +#define wxTextCtrl_GetSelection 1822 +#define wxTextCtrl_GetStringSelection 1823 +#define wxTextCtrl_GetStyle 1824 +#define wxTextCtrl_GetValue 1825 +#define wxTextCtrl_IsEditable 1826 +#define wxTextCtrl_IsModified 1827 +#define wxTextCtrl_IsMultiLine 1828 +#define wxTextCtrl_IsSingleLine 1829 +#define wxTextCtrl_LoadFile 1830 +#define wxTextCtrl_MarkDirty 1831 +#define wxTextCtrl_Paste 1832 +#define wxTextCtrl_PositionToXY 1833 +#define wxTextCtrl_Redo 1834 +#define wxTextCtrl_Remove 1835 +#define wxTextCtrl_Replace 1836 +#define wxTextCtrl_SaveFile 1837 +#define wxTextCtrl_SetDefaultStyle 1838 +#define wxTextCtrl_SetEditable 1839 +#define wxTextCtrl_SetInsertionPoint 1840 +#define wxTextCtrl_SetInsertionPointEnd 1841 +#define wxTextCtrl_SetMaxLength 1843 +#define wxTextCtrl_SetSelection 1844 +#define wxTextCtrl_SetStyle 1845 +#define wxTextCtrl_SetValue 1846 +#define wxTextCtrl_ShowPosition 1847 +#define wxTextCtrl_Undo 1848 +#define wxTextCtrl_WriteText 1849 +#define wxTextCtrl_XYToPosition 1850 +#define wxNotebook_new_0 1853 +#define wxNotebook_new_3 1854 +#define wxNotebook_destruct 1855 +#define wxNotebook_AddPage 1856 +#define wxNotebook_AdvanceSelection 1857 +#define wxNotebook_AssignImageList 1858 +#define wxNotebook_Create 1859 +#define wxNotebook_DeleteAllPages 1860 +#define wxNotebook_DeletePage 1861 +#define wxNotebook_RemovePage 1862 +#define wxNotebook_GetCurrentPage 1863 +#define wxNotebook_GetImageList 1864 +#define wxNotebook_GetPage 1866 +#define wxNotebook_GetPageCount 1867 +#define wxNotebook_GetPageImage 1868 +#define wxNotebook_GetPageText 1869 +#define wxNotebook_GetRowCount 1870 +#define wxNotebook_GetSelection 1871 +#define wxNotebook_GetThemeBackgroundColour 1872 +#define wxNotebook_HitTest 1874 +#define wxNotebook_InsertPage 1876 +#define wxNotebook_SetImageList 1877 +#define wxNotebook_SetPadding 1878 +#define wxNotebook_SetPageSize 1879 +#define wxNotebook_SetPageImage 1880 +#define wxNotebook_SetPageText 1881 +#define wxNotebook_SetSelection 1882 +#define wxNotebook_ChangeSelection 1883 +#define wxChoicebook_new_0 1884 +#define wxChoicebook_new_3 1885 +#define wxChoicebook_AddPage 1886 +#define wxChoicebook_AdvanceSelection 1887 +#define wxChoicebook_AssignImageList 1888 +#define wxChoicebook_Create 1889 +#define wxChoicebook_DeleteAllPages 1890 +#define wxChoicebook_DeletePage 1891 +#define wxChoicebook_RemovePage 1892 +#define wxChoicebook_GetCurrentPage 1893 +#define wxChoicebook_GetImageList 1894 +#define wxChoicebook_GetPage 1896 +#define wxChoicebook_GetPageCount 1897 +#define wxChoicebook_GetPageImage 1898 +#define wxChoicebook_GetPageText 1899 +#define wxChoicebook_GetSelection 1900 +#define wxChoicebook_HitTest 1901 +#define wxChoicebook_InsertPage 1902 +#define wxChoicebook_SetImageList 1903 +#define wxChoicebook_SetPageSize 1904 +#define wxChoicebook_SetPageImage 1905 +#define wxChoicebook_SetPageText 1906 +#define wxChoicebook_SetSelection 1907 +#define wxChoicebook_ChangeSelection 1908 +#define wxChoicebook_destroy 1909 +#define wxToolbook_new_0 1910 +#define wxToolbook_new_3 1911 +#define wxToolbook_AddPage 1912 +#define wxToolbook_AdvanceSelection 1913 +#define wxToolbook_AssignImageList 1914 +#define wxToolbook_Create 1915 +#define wxToolbook_DeleteAllPages 1916 +#define wxToolbook_DeletePage 1917 +#define wxToolbook_RemovePage 1918 +#define wxToolbook_GetCurrentPage 1919 +#define wxToolbook_GetImageList 1920 +#define wxToolbook_GetPage 1922 +#define wxToolbook_GetPageCount 1923 +#define wxToolbook_GetPageImage 1924 +#define wxToolbook_GetPageText 1925 +#define wxToolbook_GetSelection 1926 +#define wxToolbook_HitTest 1928 +#define wxToolbook_InsertPage 1929 +#define wxToolbook_SetImageList 1930 +#define wxToolbook_SetPageSize 1931 +#define wxToolbook_SetPageImage 1932 +#define wxToolbook_SetPageText 1933 +#define wxToolbook_SetSelection 1934 +#define wxToolbook_ChangeSelection 1935 +#define wxToolbook_destroy 1936 +#define wxListbook_new_0 1937 +#define wxListbook_new_3 1938 +#define wxListbook_AddPage 1939 +#define wxListbook_AdvanceSelection 1940 +#define wxListbook_AssignImageList 1941 +#define wxListbook_Create 1942 +#define wxListbook_DeleteAllPages 1943 +#define wxListbook_DeletePage 1944 +#define wxListbook_RemovePage 1945 +#define wxListbook_GetCurrentPage 1946 +#define wxListbook_GetImageList 1947 +#define wxListbook_GetPage 1949 +#define wxListbook_GetPageCount 1950 +#define wxListbook_GetPageImage 1951 +#define wxListbook_GetPageText 1952 +#define wxListbook_GetSelection 1953 +#define wxListbook_HitTest 1955 +#define wxListbook_InsertPage 1956 +#define wxListbook_SetImageList 1957 +#define wxListbook_SetPageSize 1958 +#define wxListbook_SetPageImage 1959 +#define wxListbook_SetPageText 1960 +#define wxListbook_SetSelection 1961 +#define wxListbook_ChangeSelection 1962 +#define wxListbook_destroy 1963 +#define wxTreebook_new_0 1964 +#define wxTreebook_new_3 1965 +#define wxTreebook_AddPage 1966 +#define wxTreebook_AdvanceSelection 1967 +#define wxTreebook_AssignImageList 1968 +#define wxTreebook_Create 1969 +#define wxTreebook_DeleteAllPages 1970 +#define wxTreebook_DeletePage 1971 +#define wxTreebook_RemovePage 1972 +#define wxTreebook_GetCurrentPage 1973 +#define wxTreebook_GetImageList 1974 +#define wxTreebook_GetPage 1976 +#define wxTreebook_GetPageCount 1977 +#define wxTreebook_GetPageImage 1978 +#define wxTreebook_GetPageText 1979 +#define wxTreebook_GetSelection 1980 +#define wxTreebook_ExpandNode 1981 +#define wxTreebook_IsNodeExpanded 1982 +#define wxTreebook_HitTest 1984 +#define wxTreebook_InsertPage 1985 +#define wxTreebook_InsertSubPage 1986 +#define wxTreebook_SetImageList 1987 +#define wxTreebook_SetPageSize 1988 +#define wxTreebook_SetPageImage 1989 +#define wxTreebook_SetPageText 1990 +#define wxTreebook_SetSelection 1991 +#define wxTreebook_ChangeSelection 1992 +#define wxTreebook_destroy 1993 +#define wxTreeCtrl_new_2 1996 +#define wxTreeCtrl_new_0 1997 +#define wxTreeCtrl_destruct 1999 +#define wxTreeCtrl_AddRoot 2000 +#define wxTreeCtrl_AppendItem 2001 +#define wxTreeCtrl_AssignImageList 2002 +#define wxTreeCtrl_AssignStateImageList 2003 +#define wxTreeCtrl_Collapse 2004 +#define wxTreeCtrl_CollapseAndReset 2005 +#define wxTreeCtrl_Create 2006 +#define wxTreeCtrl_Delete 2007 +#define wxTreeCtrl_DeleteAllItems 2008 +#define wxTreeCtrl_DeleteChildren 2009 +#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_driver.c b/lib/wx/c_src/wxe_driver.c index 3b951bec57..310325ea26 100644 --- a/lib/wx/c_src/wxe_driver.c +++ b/lib/wx/c_src/wxe_driver.c @@ -1,19 +1,19 @@ /* * %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 * 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% */ @@ -113,6 +113,7 @@ wxe_driver_start(ErlDrvPort port, char *buff) data->driver_data = NULL; data->bin = NULL; data->port = port; + data->pdl = driver_pdl_create(port); if(WXE_DRV_PORT == 0) { for(; *buff != 32; buff++); buff++; @@ -124,7 +125,7 @@ wxe_driver_start(ErlDrvPort port, char *buff) if(!(start_native_gui(data) == 1)) return(ERL_DRV_ERROR_GENERAL); /* ENOMEM */ } else { - meta_command(CREATE_PORT,data); + meta_command(CREATE_PORT,data); } return (ErlDrvData) data; } diff --git a/lib/wx/c_src/wxe_driver.h b/lib/wx/c_src/wxe_driver.h index 8437b4eb36..13a17e356f 100644 --- a/lib/wx/c_src/wxe_driver.h +++ b/lib/wx/c_src/wxe_driver.h @@ -1,19 +1,19 @@ /* * %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 * 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% */ @@ -45,6 +45,7 @@ typedef struct wxe_data_def { WXEBinRef * bin; /* Argument binaries */ ErlDrvPort port; int is_cbport; + ErlDrvPDL pdl; } wxe_data; diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp index 4486dff63b..6d2926ce4e 100644 --- a/lib/wx/c_src/wxe_impl.cpp +++ b/lib/wx/c_src/wxe_impl.cpp @@ -101,7 +101,7 @@ int start_native_gui(wxe_data *sd) init_caller = driver_connected(sd->port); if((res = erl_drv_thread_create((char *)"wxwidgets", - &wxe_thread,wxe_main_loop,NULL,NULL)) == 0) { + &wxe_thread,wxe_main_loop,(void *) sd->pdl,NULL)) == 0) { erl_drv_mutex_lock(wxe_status_m); for(;wxe_status == WXE_NOT_INITIATED;) { erl_drv_cond_wait(wxe_status_c, wxe_status_m); @@ -179,12 +179,15 @@ void meta_command(int what, wxe_data *sd) { * wxWidgets Thread * ************************************************************/ -void *wxe_main_loop(void * not_used) +void *wxe_main_loop(void *vpdl) { int result; int argc = 1; char * temp = (char *) "Erlang\0"; char ** argv = &temp; + ErlDrvPDL pdl = (ErlDrvPDL) vpdl; + + driver_pdl_inc_refc(pdl); // ErlDrvSysInfo einfo; // driver_system_info(&einfo, sizeof(ErlDrvSysInfo)); @@ -199,6 +202,7 @@ void *wxe_main_loop(void * not_used) if(result >= 0 && wxe_status == WXE_INITIATED) { /* We are done try to make a clean exit */ wxe_status = WXE_EXITED; + driver_pdl_dec_refc(pdl); erl_drv_thread_exit(NULL); return NULL; } else { @@ -206,6 +210,7 @@ void *wxe_main_loop(void * not_used) wxe_status = WXE_ERROR; erl_drv_cond_signal(wxe_status_c); erl_drv_mutex_unlock(wxe_status_m); + driver_pdl_dec_refc(pdl); return NULL; } } @@ -401,11 +406,12 @@ void WxeApp::dispatch_cb(wxList * batch, wxList * temp, ErlDrvTermData process) node = batch->GetFirst()) { wxeCommand *event = (wxeCommand *)node->GetData(); + wxeMemEnv *memenv = getMemEnv(event->port); batch->Erase(node); 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 == driver_connected(event->port)) + (memenv && event->caller == memenv->owner)) { switch(event->op) { case WXE_BATCH_END: @@ -456,6 +462,9 @@ void WxeApp::dispatch_cb(wxList * batch, wxList * temp, ErlDrvTermData process) void WxeApp::newMemEnv(wxeMetaCommand& Ecmd) { wxeMemEnv * memenv = new wxeMemEnv(); + + driver_pdl_inc_refc(Ecmd.pdl); + for(int i = 0; i < global_me->next; i++) { memenv->ref2ptr[i] = global_me->ref2ptr[i]; } @@ -576,6 +585,7 @@ void WxeApp::destroyMemEnv(wxeMetaCommand& Ecmd) { // } // fflush(stderr); delete memenv; + driver_pdl_dec_refc(Ecmd.pdl); refmap.erase((ErlDrvTermData) Ecmd.port); } @@ -659,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/c_src/wxe_impl.h b/lib/wx/c_src/wxe_impl.h index 5e9d596633..39c02f8c1a 100644 --- a/lib/wx/c_src/wxe_impl.h +++ b/lib/wx/c_src/wxe_impl.h @@ -1,19 +1,19 @@ /* * %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 * 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% */ @@ -34,15 +34,16 @@ class wxeMetaCommand : public wxEvent public: wxeMetaCommand(wxe_data *sd, int EvId) : wxEvent(EvId, wxeEVT_META_COMMAND) - { caller = driver_caller(sd->port); port = sd->port; } ; + { caller = driver_caller(sd->port); port = sd->port; pdl = sd->pdl; } ; wxeMetaCommand(const wxeMetaCommand& event) : wxEvent(event) - { caller = event.caller; port = event.port; }; + { caller = event.caller; port = event.port; pdl = event.pdl; }; virtual ~wxeMetaCommand() {}; virtual wxEvent *Clone() const { return new wxeMetaCommand(*this); } ErlDrvTermData caller; ErlDrvPort port; + ErlDrvPDL pdl; }; class wxeCommand : public wxObject diff --git a/lib/wx/doc/src/notes.xml b/lib/wx/doc/src/notes.xml index 92933c348b..8414028106 100644 --- a/lib/wx/doc/src/notes.xml +++ b/lib/wx/doc/src/notes.xml @@ -31,6 +31,52 @@ <p>This document describes the changes made to the wxErlang application.</p> +<section><title>Wx 0.98.7</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix crash (segmentation fault) in callback handling.</p> + <p> + Own Id: OTP-8766</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Add wxSystemSettings module.</p> + <p> + Add wxTreeCtrl:editLabel/2.</p> + <p> + Own Id: OTP-8767</p> + </item> + </list> + </section> + +</section> + +<section><title>Wx 0.98.6</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Calling <c>sys:get_status()</c> for processes that have + globally registered names that were not atoms would cause + a crash. Corrected. (Thanks to Steve Vinoski.)</p> + <p> + Own Id: OTP-8656</p> + </item> + </list> + </section> + +</section> + <section><title>Wx 0.98.5</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/wx/include/wx.hrl b/lib/wx/include/wx.hrl index 6fef625b14..8659b71985 100644 --- a/lib/wx/include/wx.hrl +++ b/lib/wx/include/wx.hrl @@ -325,16 +325,339 @@ -define(wxWHITE_PEN, wxe_util:get_const(wxWHITE_PEN)). %% Enum and defines -% From define::From bookctrl.h --define(wxEVT_COMMAND_BOOKCTRL_PAGE_CHANGING, ?wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING). --define(wxEVT_COMMAND_BOOKCTRL_PAGE_CHANGED, ?wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED). +% From class wxAuiManager +-define(wxAuiManager_actionNone, 0). +-define(wxAuiManager_actionResize, 1). +-define(wxAuiManager_actionClickButton, 2). +-define(wxAuiManager_actionClickCaption, 3). +-define(wxAuiManager_actionDragToolbarPane, 4). +-define(wxAuiManager_actionDragFloatingPane, 5). +% From class wxAuiPaneInfo::wxAuiPaneState +-define(wxAuiPaneInfo_optionFloating, 1). +-define(wxAuiPaneInfo_optionHidden, 2). +-define(wxAuiPaneInfo_optionLeftDockable, 4). +-define(wxAuiPaneInfo_optionRightDockable, 8). +-define(wxAuiPaneInfo_optionTopDockable, 16). +-define(wxAuiPaneInfo_optionBottomDockable, 32). +-define(wxAuiPaneInfo_optionFloatable, 64). +-define(wxAuiPaneInfo_optionMovable, 128). +-define(wxAuiPaneInfo_optionResizable, 256). +-define(wxAuiPaneInfo_optionPaneBorder, 512). +-define(wxAuiPaneInfo_optionCaption, 1024). +-define(wxAuiPaneInfo_optionGripper, 2048). +-define(wxAuiPaneInfo_optionDestroyOnClose, 4096). +-define(wxAuiPaneInfo_optionToolbar, 8192). +-define(wxAuiPaneInfo_optionActive, 16384). +-define(wxAuiPaneInfo_optionGripperTop, 32768). +-define(wxAuiPaneInfo_optionMaximized, 65536). +-define(wxAuiPaneInfo_optionDockFixed, 131072). +-define(wxAuiPaneInfo_buttonClose, 2097152). +-define(wxAuiPaneInfo_buttonMaximize, 4194304). +-define(wxAuiPaneInfo_buttonMinimize, 8388608). +-define(wxAuiPaneInfo_buttonPin, 16777216). +-define(wxAuiPaneInfo_buttonCustom1, 67108864). +-define(wxAuiPaneInfo_buttonCustom2, 134217728). +-define(wxAuiPaneInfo_buttonCustom3, 268435456). +-define(wxAuiPaneInfo_savedHiddenState, 1073741824). +-define(wxAuiPaneInfo_actionPane, 2147483648). +% From class wxBitmap::Representation +-define(wxBitmap_Pixmap, 0). +-define(wxBitmap_Pixbuf, 1). +% From class wxChoicebook +-define(wxChoicebook_SetSelection_SendEvent, 1). +% From class wxDateTime::Calendar +-define(wxDateTime_Gregorian, 0). +-define(wxDateTime_Julian, 1). +% From class wxDateTime::Country +-define(wxDateTime_Country_Unknown, 0). +-define(wxDateTime_Country_Default, 1). +-define(wxDateTime_Country_WesternEurope_Start, 2). +-define(wxDateTime_Country_EEC, ?Country_WesternEurope_Start). +-define(wxDateTime_France, (?Country_WesternEurope_Start+1)). +-define(wxDateTime_Germany, (?Country_WesternEurope_Start+2)). +-define(wxDateTime_UK, (?Country_WesternEurope_Start+3)). +-define(wxDateTime_Country_WesternEurope_End, ?UK). +-define(wxDateTime_Russia, (?UK+1)). +-define(wxDateTime_USA, (?UK+2)). +% From class wxDateTime::GregorianAdoption +-define(wxDateTime_Gr_Unknown, 0). +-define(wxDateTime_Gr_Standard, 1). +-define(wxDateTime_Gr_Alaska, 2). +-define(wxDateTime_Gr_Albania, 3). +-define(wxDateTime_Gr_Austria, ?Gr_Unknown). +-define(wxDateTime_Gr_Austria_Brixen, (?Gr_Unknown+1)). +-define(wxDateTime_Gr_Austria_Salzburg, ?Gr_Austria_Brixen). +-define(wxDateTime_Gr_Austria_Tyrol, ?Gr_Austria_Brixen). +-define(wxDateTime_Gr_Austria_Carinthia, (?Gr_Austria_Brixen+1)). +-define(wxDateTime_Gr_Austria_Styria, ?Gr_Austria_Carinthia). +-define(wxDateTime_Gr_Belgium, (?Gr_Austria_Carinthia+1)). +-define(wxDateTime_Gr_Bulgaria, ?Gr_Unknown). +-define(wxDateTime_Gr_Bulgaria_1, (?Gr_Unknown+1)). +-define(wxDateTime_Gr_Bulgaria_2, (?Gr_Unknown+2)). +-define(wxDateTime_Gr_Bulgaria_3, (?Gr_Unknown+3)). +-define(wxDateTime_Gr_Canada, ?Gr_Unknown). +-define(wxDateTime_Gr_China, ?Gr_Unknown). +-define(wxDateTime_Gr_China_1, (?Gr_Unknown+1)). +-define(wxDateTime_Gr_China_2, (?Gr_Unknown+2)). +-define(wxDateTime_Gr_Czechoslovakia, (?Gr_Unknown+3)). +-define(wxDateTime_Gr_Denmark, (?Gr_Unknown+4)). +-define(wxDateTime_Gr_Egypt, (?Gr_Unknown+5)). +-define(wxDateTime_Gr_Estonia, (?Gr_Unknown+6)). +-define(wxDateTime_Gr_Finland, (?Gr_Unknown+7)). +-define(wxDateTime_Gr_France, (?Gr_Unknown+8)). +-define(wxDateTime_Gr_France_Alsace, (?Gr_Unknown+9)). +-define(wxDateTime_Gr_France_Lorraine, (?Gr_Unknown+10)). +-define(wxDateTime_Gr_France_Strasbourg, (?Gr_Unknown+11)). +-define(wxDateTime_Gr_Germany, ?Gr_Unknown). +-define(wxDateTime_Gr_Germany_Catholic, (?Gr_Unknown+1)). +-define(wxDateTime_Gr_Germany_Prussia, (?Gr_Unknown+2)). +-define(wxDateTime_Gr_Germany_Protestant, (?Gr_Unknown+3)). +-define(wxDateTime_Gr_GreatBritain, (?Gr_Unknown+4)). +-define(wxDateTime_Gr_Greece, (?Gr_Unknown+5)). +-define(wxDateTime_Gr_Hungary, (?Gr_Unknown+6)). +-define(wxDateTime_Gr_Ireland, ?Gr_GreatBritain). +-define(wxDateTime_Gr_Italy, ?Gr_Standard). +-define(wxDateTime_Gr_Japan, ?Gr_Unknown). +-define(wxDateTime_Gr_Japan_1, (?Gr_Unknown+1)). +-define(wxDateTime_Gr_Japan_2, (?Gr_Unknown+2)). +-define(wxDateTime_Gr_Japan_3, (?Gr_Unknown+3)). +-define(wxDateTime_Gr_Latvia, (?Gr_Unknown+4)). +-define(wxDateTime_Gr_Lithuania, (?Gr_Unknown+5)). +-define(wxDateTime_Gr_Luxemburg, (?Gr_Unknown+6)). +-define(wxDateTime_Gr_Netherlands, ?Gr_Belgium). +-define(wxDateTime_Gr_Netherlands_Groningen, (?Gr_Belgium+1)). +-define(wxDateTime_Gr_Netherlands_Gelderland, (?Gr_Belgium+2)). +-define(wxDateTime_Gr_Netherlands_Utrecht, (?Gr_Belgium+3)). +-define(wxDateTime_Gr_Netherlands_Friesland, (?Gr_Belgium+4)). +-define(wxDateTime_Gr_Norway, ?Gr_Denmark). +-define(wxDateTime_Gr_Poland, ?Gr_Standard). +-define(wxDateTime_Gr_Portugal, ?Gr_Standard). +-define(wxDateTime_Gr_Romania, (?Gr_Standard+1)). +-define(wxDateTime_Gr_Russia, (?Gr_Standard+2)). +-define(wxDateTime_Gr_Scotland, ?Gr_GreatBritain). +-define(wxDateTime_Gr_Spain, ?Gr_Standard). +-define(wxDateTime_Gr_Sweden, ?Gr_Finland). +-define(wxDateTime_Gr_Switzerland, ?Gr_Unknown). +-define(wxDateTime_Gr_Switzerland_Catholic, (?Gr_Unknown+1)). +-define(wxDateTime_Gr_Switzerland_Protestant, (?Gr_Unknown+2)). +-define(wxDateTime_Gr_Turkey, (?Gr_Unknown+3)). +-define(wxDateTime_Gr_USA, ?Gr_GreatBritain). +-define(wxDateTime_Gr_Wales, ?Gr_GreatBritain). +-define(wxDateTime_Gr_Yugoslavia, (?Gr_GreatBritain+1)). +% From class wxDateTime::Month +-define(wxDateTime_Jan, 0). +-define(wxDateTime_Feb, 1). +-define(wxDateTime_Mar, 2). +-define(wxDateTime_Apr, 3). +-define(wxDateTime_May, 4). +-define(wxDateTime_Jun, 5). +-define(wxDateTime_Jul, 6). +-define(wxDateTime_Aug, 7). +-define(wxDateTime_Sep, 8). +-define(wxDateTime_Oct, 9). +-define(wxDateTime_Nov, 10). +-define(wxDateTime_Dec, 11). +-define(wxDateTime_Inv_Month, 12). +% From class wxDateTime::NameFlags +-define(wxDateTime_Name_Full, 1). +-define(wxDateTime_Name_Abbr, 2). +% From class wxDateTime::TZ +-define(wxDateTime_Local, 0). +-define(wxDateTime_GMT_12, 1). +-define(wxDateTime_GMT_11, 2). +-define(wxDateTime_GMT_10, 3). +-define(wxDateTime_GMT_9, 4). +-define(wxDateTime_GMT_8, 5). +-define(wxDateTime_GMT_7, 6). +-define(wxDateTime_GMT_6, 7). +-define(wxDateTime_GMT_5, 8). +-define(wxDateTime_GMT_4, 9). +-define(wxDateTime_GMT_3, 10). +-define(wxDateTime_GMT_2, 11). +-define(wxDateTime_GMT_1, 12). +-define(wxDateTime_GMT0, 13). +-define(wxDateTime_GMT1, 14). +-define(wxDateTime_GMT2, 15). +-define(wxDateTime_GMT3, 16). +-define(wxDateTime_GMT4, 17). +-define(wxDateTime_GMT5, 18). +-define(wxDateTime_GMT6, 19). +-define(wxDateTime_GMT7, 20). +-define(wxDateTime_GMT8, 21). +-define(wxDateTime_GMT9, 22). +-define(wxDateTime_GMT10, 23). +-define(wxDateTime_GMT11, 24). +-define(wxDateTime_GMT12, 25). +-define(wxDateTime_GMT13, 26). +-define(wxDateTime_WET, ?GMT0). +-define(wxDateTime_WEST, ?GMT1). +-define(wxDateTime_CET, ?GMT1). +-define(wxDateTime_CEST, ?GMT2). +-define(wxDateTime_EET, ?GMT2). +-define(wxDateTime_EEST, ?GMT3). +-define(wxDateTime_MSK, ?GMT3). +-define(wxDateTime_MSD, ?GMT4). +-define(wxDateTime_AST, ?GMT_4). +-define(wxDateTime_ADT, ?GMT_3). +-define(wxDateTime_EST, ?GMT_5). +-define(wxDateTime_EDT, ?GMT_4). +-define(wxDateTime_CST, ?GMT_6). +-define(wxDateTime_CDT, ?GMT_5). +-define(wxDateTime_MST, ?GMT_7). +-define(wxDateTime_MDT, ?GMT_6). +-define(wxDateTime_PST, ?GMT_8). +-define(wxDateTime_PDT, ?GMT_7). +-define(wxDateTime_HST, ?GMT_10). +-define(wxDateTime_AKST, ?GMT_9). +-define(wxDateTime_AKDT, ?GMT_8). +-define(wxDateTime_A_WST, ?GMT8). +-define(wxDateTime_A_CST, ?GMT13+1). +-define(wxDateTime_A_EST, ?GMT10). +-define(wxDateTime_A_ESST, ?GMT11). +-define(wxDateTime_NZST, ?GMT12). +-define(wxDateTime_NZDT, ?GMT13). +-define(wxDateTime_UTC, ?GMT0). +% From class wxDateTime::WeekDay +-define(wxDateTime_Sun, 0). +-define(wxDateTime_Mon, 1). +-define(wxDateTime_Tue, 2). +-define(wxDateTime_Wed, 3). +-define(wxDateTime_Thu, 4). +-define(wxDateTime_Fri, 5). +-define(wxDateTime_Sat, 6). +-define(wxDateTime_Inv_WeekDay, 7). +% From class wxDateTime::WeekFlags +-define(wxDateTime_Default_First, 0). +-define(wxDateTime_Monday_First, 1). +-define(wxDateTime_Sunday_First, 2). +% From class wxDateTime::Year +-define(wxDateTime_Inv_Year, ?SHRT_MIN). +% From class wxDialog +-define(wxDialog_ButtonSizerFlags, (?wxOK bor ?wxCANCEL bor ?wxYES bor ?wxNO bor ?wxHELP bor ?wxNO_DEFAULT)). +% From class wxGrid +-define(wxGrid_wxGRID_CELLCTRL, 2000). +-define(wxGrid_wxGRID_TOPCTRL, 2001). +% From class wxGrid +-define(wxGrid_wxGRID_TEXTCTRL, 2100). +-define(wxGrid_wxGRID_CHECKBOX, 2101). +-define(wxGrid_wxGRID_CHOICE, 2102). +-define(wxGrid_wxGRID_COMBOBOX, 2103). +% From class wxGrid::CursorMode +-define(wxGrid_WXGRID_CURSOR_SELECT_CELL, 0). +-define(wxGrid_WXGRID_CURSOR_RESIZE_ROW, 1). +-define(wxGrid_WXGRID_CURSOR_RESIZE_COL, 2). +-define(wxGrid_WXGRID_CURSOR_SELECT_ROW, 3). +-define(wxGrid_WXGRID_CURSOR_SELECT_COL, 4). +-define(wxGrid_WXGRID_CURSOR_MOVE_COL, 5). +% From class wxGrid::wxGridSelectionModes +-define(wxGrid_wxGridSelectCells, 0). +-define(wxGrid_wxGridSelectRows, 1). +-define(wxGrid_wxGridSelectColumns, 2). +% From class wxGridCellAttr::wxAttrKind +-define(wxGridCellAttr_Any, 0). +-define(wxGridCellAttr_Default, 1). +-define(wxGridCellAttr_Cell, 2). +-define(wxGridCellAttr_Row, 3). +-define(wxGridCellAttr_Col, 4). +-define(wxGridCellAttr_Merged, 5). +% From class wxGridCellAttr::wxAttrOverflowMode +-define(wxGridCellAttr_UnsetOverflow, -1). +-define(wxGridCellAttr_Overflow, 0). +-define(wxGridCellAttr_SingleCell, 1). +% From class wxGridCellAttr::wxAttrReadMode +-define(wxGridCellAttr_Unset, -1). +-define(wxGridCellAttr_ReadWrite, 0). +-define(wxGridCellAttr_ReadOnly, 1). +% From class wxHelpEvent::Origin +-define(wxHelpEvent_Origin_Unknown, 0). +-define(wxHelpEvent_Origin_Keyboard, 1). +-define(wxHelpEvent_Origin_HelpButton, 2). +% From class wxHtmlEasyPrinting::FontMode +-define(wxHtmlEasyPrinting_FontMode_Explicit, 0). +-define(wxHtmlEasyPrinting_FontMode_Standard, 1). +% From class wxHtmlWindow::ClipboardType +-define(wxHtmlWindow_Primary, 0). +-define(wxHtmlWindow_Secondary, 1). +% From class wxListbook +-define(wxListbook_SetSelection_SendEvent, 1). +% From class wxNavigationKeyEvent +-define(wxNavigationKeyEvent_IsBackward, 0). +-define(wxNavigationKeyEvent_IsForward, 1). +-define(wxNavigationKeyEvent_WinChange, 2). +-define(wxNavigationKeyEvent_FromTab, 4). +% From class wxNotebook +-define(wxNotebook_SetSelection_SendEvent, 1). +% From class wxProgressDialog +-define(wxProgressDialog_Uncancelable, -1). +-define(wxProgressDialog_Canceled, 0). +-define(wxProgressDialog_Continue, 1). +-define(wxProgressDialog_Finished, 2). +% From class wxSizerItem +-define(wxSizerItem_Item_None, 0). +-define(wxSizerItem_Item_Window, 1). +-define(wxSizerItem_Item_Sizer, 2). +-define(wxSizerItem_Item_Spacer, 3). +-define(wxSizerItem_Item_Max, 4). +% From class wxTextCtrl +-define(wxTextCtrl_SetValue_SendEvent, 1). +-define(wxTextCtrl_SetValue_SelectionOnly, 2). +% From class wxToolbook +-define(wxToolbook_SetSelection_SendEvent, 1). +% From class wxTreebook +-define(wxTreebook_SetSelection_SendEvent, 1). +% From class wxWindow::MoveKind +-define(wxWindow_MoveBefore, 0). +-define(wxWindow_MoveAfter, 1). +% From class wxWindowGTK::ScrollDir +-define(wxWindowGTK_ScrollDir_Horz, 0). +-define(wxWindowGTK_ScrollDir_Vert, 1). +-define(wxWindowGTK_ScrollDir_Max, 2). +% From class wxWindowGTK::ScrollUnit +-define(wxWindowGTK_ScrollUnit_Line, 0). +-define(wxWindowGTK_ScrollUnit_Page, 1). +-define(wxWindowGTK_ScrollUnit_Max, 2). +% From "accel.h" +-define(wxACCEL_NORMAL, 0). +-define(wxACCEL_ALT, 1). +-define(wxACCEL_CTRL, 2). +-define(wxACCEL_SHIFT, 4). +-define(wxACCEL_CMD, ?wxACCEL_CTRL). +% From "app.h" +-define(wxPRINT_WINDOWS, 1). +-define(wxPRINT_POSTSCRIPT, 2). +% From "auibook.h": wxAuiNotebookOption +-define(wxAUI_NB_TOP, 1). +-define(wxAUI_NB_LEFT, 2). +-define(wxAUI_NB_RIGHT, 4). +-define(wxAUI_NB_BOTTOM, 8). +-define(wxAUI_NB_TAB_SPLIT, 16). +-define(wxAUI_NB_TAB_MOVE, 32). +-define(wxAUI_NB_TAB_EXTERNAL_MOVE, 64). +-define(wxAUI_NB_TAB_FIXED_WIDTH, 128). +-define(wxAUI_NB_SCROLL_BUTTONS, 256). +-define(wxAUI_NB_WINDOWLIST_BUTTON, 512). +-define(wxAUI_NB_CLOSE_BUTTON, 1024). +-define(wxAUI_NB_CLOSE_ON_ACTIVE_TAB, 2048). +-define(wxAUI_NB_CLOSE_ON_ALL_TABS, 4096). +-define(wxAUI_NB_MIDDLE_CLICK_CLOSE, 8192). +-define(wxAUI_NB_DEFAULT_STYLE, (?wxAUI_NB_TOP bor ?wxAUI_NB_TAB_SPLIT bor ?wxAUI_NB_TAB_MOVE bor ?wxAUI_NB_SCROLL_BUTTONS bor ?wxAUI_NB_CLOSE_ON_ACTIVE_TAB bor ?wxAUI_NB_MIDDLE_CLICK_CLOSE)). +% From "bookctrl.h" +-define(wxBK_HITTEST_NOWHERE, 1). +-define(wxBK_HITTEST_ONICON, 2). +-define(wxBK_HITTEST_ONLABEL, 4). +-define(wxBK_HITTEST_ONITEM, (?wxBK_HITTEST_ONICON bor ?wxBK_HITTEST_ONLABEL)). +-define(wxBK_HITTEST_ONPAGE, 8). +% From "bookctrl.h" -define(wxBK_ALIGN_MASK, (?wxBK_TOP bor ?wxBK_BOTTOM bor ?wxBK_LEFT bor ?wxBK_RIGHT)). -define(wxBK_RIGHT, 128). -define(wxBK_LEFT, 64). -define(wxBK_BOTTOM, 32). -define(wxBK_TOP, 16). -define(wxBK_DEFAULT, 0). -% From define::From button.h +% From "bugs.h": wxSashDragStatus +-define(wxSASH_STATUS_OK, 0). +-define(wxSASH_STATUS_OUT_OF_RANGE, 1). +% From "button.h" -define(wxBU_EXACTFIT, 1). -define(wxBU_AUTODRAW, 4). -define(wxBU_NOAUTODRAW, 0). @@ -343,38 +666,258 @@ -define(wxBU_RIGHT, 256). -define(wxBU_TOP, 128). -define(wxBU_LEFT, 64). -% From define::From checkbox.h +% From "calctrl.h" +-define(wxCAL_SUNDAY_FIRST, 0). +-define(wxCAL_MONDAY_FIRST, 1). +-define(wxCAL_SHOW_HOLIDAYS, 2). +-define(wxCAL_NO_YEAR_CHANGE, 4). +-define(wxCAL_NO_MONTH_CHANGE, 12). +-define(wxCAL_SEQUENTIAL_MONTH_SELECTION, 16). +-define(wxCAL_SHOW_SURROUNDING_WEEKS, 32). +% From "calctrl.h": wxCalendarDateBorder +-define(wxCAL_BORDER_NONE, 0). +-define(wxCAL_BORDER_SQUARE, 1). +-define(wxCAL_BORDER_ROUND, 2). +% From "calctrl.h": wxCalendarHitTestResult +-define(wxCAL_HITTEST_NOWHERE, 0). +-define(wxCAL_HITTEST_HEADER, 1). +-define(wxCAL_HITTEST_DAY, 2). +-define(wxCAL_HITTEST_INCMONTH, 3). +-define(wxCAL_HITTEST_DECMONTH, 4). +-define(wxCAL_HITTEST_SURROUNDING_WEEK, 5). +% From "checkbox.h" -define(wxCHK_ALLOW_3RD_STATE_FOR_USER, 8192). -define(wxCHK_3STATE, 4096). -define(wxCHK_2STATE, 0). -% From define::From choicdgg.h +% From "checkbox.h": wxCheckBoxState +-define(wxCHK_UNCHECKED, 0). +-define(wxCHK_CHECKED, 1). +-define(wxCHK_UNDETERMINED, 2). +% From "choicdgg.h" -define(wxCHOICEDLG_STYLE, (?wxDEFAULT_DIALOG_STYLE bor ?wxRESIZE_BORDER bor ?wxOK bor ?wxCANCEL bor ?wxCENTRE)). -define(wxCHOICE_WIDTH, 200). -define(wxCHOICE_HEIGHT, 150). -% From define::From choicebk.h +% From "choicebk.h" -define(wxCHB_ALIGN_MASK, ?wxBK_ALIGN_MASK). -define(wxCHB_RIGHT, ?wxBK_RIGHT). -define(wxCHB_LEFT, ?wxBK_LEFT). -define(wxCHB_BOTTOM, ?wxBK_BOTTOM). -define(wxCHB_TOP, ?wxBK_TOP). -define(wxCHB_DEFAULT, ?wxBK_DEFAULT). -% From define::From clrpicker.h +% From "clntdata.h": wxClientDataType +-define(wxClientData_None, 0). +-define(wxClientData_Object, 1). +-define(wxClientData_Void, 2). +% From "clrpicker.h" -define(wxCLRP_DEFAULT_STYLE, 0). -define(wxCLRP_USE_TEXTCTRL, ?wxPB_USE_TEXTCTRL). -define(wxCLRP_SHOW_LABEL, 8). -% From define::From colour.h +% From "cmndata.h": wxPrintBin +-define(wxPRINTBIN_DEFAULT, 0). +-define(wxPRINTBIN_ONLYONE, 1). +-define(wxPRINTBIN_LOWER, 2). +-define(wxPRINTBIN_MIDDLE, 3). +-define(wxPRINTBIN_MANUAL, 4). +-define(wxPRINTBIN_ENVELOPE, 5). +-define(wxPRINTBIN_ENVMANUAL, 6). +-define(wxPRINTBIN_AUTO, 7). +-define(wxPRINTBIN_TRACTOR, 8). +-define(wxPRINTBIN_SMALLFMT, 9). +-define(wxPRINTBIN_LARGEFMT, 10). +-define(wxPRINTBIN_LARGECAPACITY, 11). +-define(wxPRINTBIN_CASSETTE, 12). +-define(wxPRINTBIN_FORMSOURCE, 13). +-define(wxPRINTBIN_USER, 14). +% From "colour.h" -define(wxC2S_HTML_SYNTAX, 4). -define(wxC2S_CSS_SYNTAX, 2). -define(wxC2S_NAME, 1). -% From define::From confbase.h +% From "confbase.h" -define(wxCONFIG_CASE_SENSITIVE, 0). -% From define::From datetime.h +% From "datectrl.h" +-define(wxDP_DEFAULT, 0). +-define(wxDP_SPIN, 1). +-define(wxDP_DROPDOWN, 2). +-define(wxDP_SHOWCENTURY, 4). +-define(wxDP_ALLOWNONE, 8). +% From "datetime.h" -define(wxInvalidDateTime, ?wxDefaultDateTime). -% From define::From dcbuffer.h +% From "dcbuffer.h" -define(wxBUFFER_CLIENT_AREA, 2). -define(wxBUFFER_VIRTUAL_AREA, 1). --define(wxALWAYS_NATIVE_DOUBLE_BUFFER, 0). -% From define::From defs.h +-define(wxALWAYS_NATIVE_DOUBLE_BUFFER, wxe_util:get_const(wxALWAYS_NATIVE_DOUBLE_BUFFER)). +% From "defs.h" +-define(wxDefaultCoord, -1). +% From "defs.h" +-define(wxID_NONE, -3). +-define(wxID_SEPARATOR, -2). +-define(wxID_ANY, -1). +-define(wxID_LOWEST, 4999). +-define(wxID_OPEN, 5000). +-define(wxID_CLOSE, 5001). +-define(wxID_NEW, 5002). +-define(wxID_SAVE, 5003). +-define(wxID_SAVEAS, 5004). +-define(wxID_REVERT, 5005). +-define(wxID_EXIT, 5006). +-define(wxID_UNDO, 5007). +-define(wxID_REDO, 5008). +-define(wxID_HELP, 5009). +-define(wxID_PRINT, 5010). +-define(wxID_PRINT_SETUP, 5011). +-define(wxID_PAGE_SETUP, 5012). +-define(wxID_PREVIEW, 5013). +-define(wxID_ABOUT, 5014). +-define(wxID_HELP_CONTENTS, 5015). +-define(wxID_HELP_INDEX, 5016). +-define(wxID_HELP_SEARCH, 5017). +-define(wxID_HELP_COMMANDS, 5018). +-define(wxID_HELP_PROCEDURES, 5019). +-define(wxID_HELP_CONTEXT, 5020). +-define(wxID_CLOSE_ALL, 5021). +-define(wxID_PREFERENCES, 5022). +-define(wxID_EDIT, 5030). +-define(wxID_CUT, 5031). +-define(wxID_COPY, 5032). +-define(wxID_PASTE, 5033). +-define(wxID_CLEAR, 5034). +-define(wxID_FIND, 5035). +-define(wxID_DUPLICATE, 5036). +-define(wxID_SELECTALL, 5037). +-define(wxID_DELETE, 5038). +-define(wxID_REPLACE, 5039). +-define(wxID_REPLACE_ALL, 5040). +-define(wxID_PROPERTIES, 5041). +-define(wxID_VIEW_DETAILS, 5042). +-define(wxID_VIEW_LARGEICONS, 5043). +-define(wxID_VIEW_SMALLICONS, 5044). +-define(wxID_VIEW_LIST, 5045). +-define(wxID_VIEW_SORTDATE, 5046). +-define(wxID_VIEW_SORTNAME, 5047). +-define(wxID_VIEW_SORTSIZE, 5048). +-define(wxID_VIEW_SORTTYPE, 5049). +-define(wxID_FILE, 5050). +-define(wxID_FILE1, 5051). +-define(wxID_FILE2, 5052). +-define(wxID_FILE3, 5053). +-define(wxID_FILE4, 5054). +-define(wxID_FILE5, 5055). +-define(wxID_FILE6, 5056). +-define(wxID_FILE7, 5057). +-define(wxID_FILE8, 5058). +-define(wxID_FILE9, 5059). +-define(wxID_OK, 5100). +-define(wxID_CANCEL, 5101). +-define(wxID_APPLY, 5102). +-define(wxID_YES, 5103). +-define(wxID_NO, 5104). +-define(wxID_STATIC, 5105). +-define(wxID_FORWARD, 5106). +-define(wxID_BACKWARD, 5107). +-define(wxID_DEFAULT, 5108). +-define(wxID_MORE, 5109). +-define(wxID_SETUP, 5110). +-define(wxID_RESET, 5111). +-define(wxID_CONTEXT_HELP, 5112). +-define(wxID_YESTOALL, 5113). +-define(wxID_NOTOALL, 5114). +-define(wxID_ABORT, 5115). +-define(wxID_RETRY, 5116). +-define(wxID_IGNORE, 5117). +-define(wxID_ADD, 5118). +-define(wxID_REMOVE, 5119). +-define(wxID_UP, 5120). +-define(wxID_DOWN, 5121). +-define(wxID_HOME, 5122). +-define(wxID_REFRESH, 5123). +-define(wxID_STOP, 5124). +-define(wxID_INDEX, 5125). +-define(wxID_BOLD, 5126). +-define(wxID_ITALIC, 5127). +-define(wxID_JUSTIFY_CENTER, 5128). +-define(wxID_JUSTIFY_FILL, 5129). +-define(wxID_JUSTIFY_RIGHT, 5130). +-define(wxID_JUSTIFY_LEFT, 5131). +-define(wxID_UNDERLINE, 5132). +-define(wxID_INDENT, 5133). +-define(wxID_UNINDENT, 5134). +-define(wxID_ZOOM_100, 5135). +-define(wxID_ZOOM_FIT, 5136). +-define(wxID_ZOOM_IN, 5137). +-define(wxID_ZOOM_OUT, 5138). +-define(wxID_UNDELETE, 5139). +-define(wxID_REVERT_TO_SAVED, 5140). +-define(wxID_SYSTEM_MENU, 5200). +-define(wxID_CLOSE_FRAME, 5201). +-define(wxID_MOVE_FRAME, 5202). +-define(wxID_RESIZE_FRAME, 5203). +-define(wxID_MAXIMIZE_FRAME, 5204). +-define(wxID_ICONIZE_FRAME, 5205). +-define(wxID_RESTORE_FRAME, 5206). +-define(wxID_FILEDLGG, 5900). +-define(wxID_HIGHEST, 5999). +% From "defs.h" +-define(wxDEFAULT, 70). +-define(wxDECORATIVE, 71). +-define(wxROMAN, 72). +-define(wxSCRIPT, 73). +-define(wxSWISS, 74). +-define(wxMODERN, 75). +-define(wxTELETYPE, 76). +-define(wxVARIABLE, 80). +-define(wxFIXED, 81). +-define(wxNORMAL, 90). +-define(wxLIGHT, 91). +-define(wxBOLD, 92). +-define(wxITALIC, 93). +-define(wxSLANT, 94). +-define(wxSOLID, 100). +-define(wxDOT, 101). +-define(wxLONG_DASH, 102). +-define(wxSHORT_DASH, 103). +-define(wxDOT_DASH, 104). +-define(wxUSER_DASH, 105). +-define(wxTRANSPARENT, 106). +-define(wxSTIPPLE_MASK_OPAQUE, 107). +-define(wxSTIPPLE_MASK, 108). +-define(wxSTIPPLE, 110). +-define(wxBDIAGONAL_HATCH, 111). +-define(wxCROSSDIAG_HATCH, 112). +-define(wxFDIAGONAL_HATCH, 113). +-define(wxCROSS_HATCH, 114). +-define(wxHORIZONTAL_HATCH, 115). +-define(wxVERTICAL_HATCH, 116). +-define(wxFIRST_HATCH, ?wxBDIAGONAL_HATCH). +-define(wxLAST_HATCH, ?wxVERTICAL_HATCH). +-define(wxJOIN_BEVEL, 120). +-define(wxJOIN_MITER, 121). +-define(wxJOIN_ROUND, 122). +-define(wxCAP_ROUND, 130). +-define(wxCAP_PROJECTING, 131). +-define(wxCAP_BUTT, 132). +% From "defs.h" +-define(wxFLOOD_SURFACE, 1). +-define(wxFLOOD_BORDER, 2). +% From "defs.h" +-define(wxODDEVEN_RULE, 1). +-define(wxWINDING_RULE, 2). +% From "defs.h" +-define(wxTOOL_TOP, 1). +-define(wxTOOL_BOTTOM, 2). +-define(wxTOOL_LEFT, 3). +-define(wxTOOL_RIGHT, 4). +% From "defs.h" +-define(wxMM_TEXT, 1). +-define(wxMM_LOMETRIC, 2). +-define(wxMM_HIMETRIC, 3). +-define(wxMM_LOENGLISH, 4). +-define(wxMM_HIENGLISH, 5). +-define(wxMM_TWIPS, 6). +-define(wxMM_ISOTROPIC, 7). +-define(wxMM_ANISOTROPIC, 8). +-define(wxMM_POINTS, 9). +-define(wxMM_METRIC, 10). +% From "defs.h" -define(wxPRINT_QUALITY_DRAFT, -4). -define(wxPRINT_QUALITY_LOW, -3). -define(wxPRINT_QUALITY_MEDIUM, -2). @@ -503,21 +1046,499 @@ -define(wxBIG_ENDIAN, 4321). -define(wxHAS_INT64, wxe_util:get_const(wxHAS_INT64)). -define(wxNOT_FOUND, -1). -% From define::From dialog.h +% From "defs.h": form_ops_t +-define(wxCLEAR, 0). +-define(wxROP_BLACK, ?wxCLEAR). +-define(wxBLIT_BLACKNESS, ?wxCLEAR). +-define(wxXOR, (?wxCLEAR+1)). +-define(wxROP_XORPEN, ?wxXOR). +-define(wxBLIT_SRCINVERT, ?wxXOR). +-define(wxINVERT, (?wxXOR+1)). +-define(wxROP_NOT, ?wxINVERT). +-define(wxBLIT_DSTINVERT, ?wxINVERT). +-define(wxOR_REVERSE, (?wxINVERT+1)). +-define(wxROP_MERGEPENNOT, ?wxOR_REVERSE). +-define(wxBLIT_00DD0228, ?wxOR_REVERSE). +-define(wxAND_REVERSE, (?wxOR_REVERSE+1)). +-define(wxROP_MASKPENNOT, ?wxAND_REVERSE). +-define(wxBLIT_SRCERASE, ?wxAND_REVERSE). +-define(wxCOPY, (?wxAND_REVERSE+1)). +-define(wxROP_COPYPEN, ?wxCOPY). +-define(wxBLIT_SRCCOPY, ?wxCOPY). +-define(wxAND, (?wxCOPY+1)). +-define(wxROP_MASKPEN, ?wxAND). +-define(wxBLIT_SRCAND, ?wxAND). +-define(wxAND_INVERT, (?wxAND+1)). +-define(wxROP_MASKNOTPEN, ?wxAND_INVERT). +-define(wxBLIT_00220326, ?wxAND_INVERT). +-define(wxNO_OP, (?wxAND_INVERT+1)). +-define(wxROP_NOP, ?wxNO_OP). +-define(wxBLIT_00AA0029, ?wxNO_OP). +-define(wxNOR, (?wxNO_OP+1)). +-define(wxROP_NOTMERGEPEN, ?wxNOR). +-define(wxBLIT_NOTSRCERASE, ?wxNOR). +-define(wxEQUIV, (?wxNOR+1)). +-define(wxROP_NOTXORPEN, ?wxEQUIV). +-define(wxBLIT_00990066, ?wxEQUIV). +-define(wxSRC_INVERT, (?wxEQUIV+1)). +-define(wxROP_NOTCOPYPEN, ?wxSRC_INVERT). +-define(wxBLIT_NOTSCRCOPY, ?wxSRC_INVERT). +-define(wxOR_INVERT, (?wxSRC_INVERT+1)). +-define(wxROP_MERGENOTPEN, ?wxOR_INVERT). +-define(wxBLIT_MERGEPAINT, ?wxOR_INVERT). +-define(wxNAND, (?wxOR_INVERT+1)). +-define(wxROP_NOTMASKPEN, ?wxNAND). +-define(wxBLIT_007700E6, ?wxNAND). +-define(wxOR, (?wxNAND+1)). +-define(wxROP_MERGEPEN, ?wxOR). +-define(wxBLIT_SRCPAINT, ?wxOR). +-define(wxSET, (?wxOR+1)). +-define(wxROP_WHITE, ?wxSET). +-define(wxBLIT_WHITENESS, ?wxSET). +% From "defs.h": wxAlignment +-define(wxALIGN_NOT, 0). +-define(wxALIGN_CENTER_HORIZONTAL, 256). +-define(wxALIGN_CENTRE_HORIZONTAL, ?wxALIGN_CENTER_HORIZONTAL). +-define(wxALIGN_LEFT, ?wxALIGN_NOT). +-define(wxALIGN_TOP, ?wxALIGN_NOT). +-define(wxALIGN_RIGHT, 512). +-define(wxALIGN_BOTTOM, 1024). +-define(wxALIGN_CENTER_VERTICAL, 2048). +-define(wxALIGN_CENTRE_VERTICAL, ?wxALIGN_CENTER_VERTICAL). +-define(wxALIGN_CENTER, (?wxALIGN_CENTER_HORIZONTAL bor ?wxALIGN_CENTER_VERTICAL)). +-define(wxALIGN_CENTRE, ?wxALIGN_CENTER). +-define(wxALIGN_MASK, 3840). +% From "defs.h": wxBackgroundStyle +-define(wxBG_STYLE_SYSTEM, 0). +-define(wxBG_STYLE_COLOUR, 1). +-define(wxBG_STYLE_CUSTOM, 2). +% From "defs.h": wxBorder +-define(wxBORDER_DEFAULT, 0). +-define(wxBORDER_NONE, 2097152). +-define(wxBORDER_STATIC, 16777216). +-define(wxBORDER_SIMPLE, 33554432). +-define(wxBORDER_RAISED, 67108864). +-define(wxBORDER_SUNKEN, 134217728). +-define(wxBORDER_DOUBLE, 268435456). +-define(wxBORDER_THEME, 268435456). +-define(wxBORDER_MASK, 522190848). +% From "defs.h": wxDataFormatId +-define(wxDF_INVALID, 0). +-define(wxDF_TEXT, 1). +-define(wxDF_BITMAP, 2). +-define(wxDF_METAFILE, 3). +-define(wxDF_SYLK, 4). +-define(wxDF_DIF, 5). +-define(wxDF_TIFF, 6). +-define(wxDF_OEMTEXT, 7). +-define(wxDF_DIB, 8). +-define(wxDF_PALETTE, 9). +-define(wxDF_PENDATA, 10). +-define(wxDF_RIFF, 11). +-define(wxDF_WAVE, 12). +-define(wxDF_UNICODETEXT, 13). +-define(wxDF_ENHMETAFILE, 14). +-define(wxDF_FILENAME, 15). +-define(wxDF_LOCALE, 16). +-define(wxDF_PRIVATE, 20). +-define(wxDF_HTML, 30). +-define(wxDF_MAX, 31). +% From "defs.h": wxDirection +-define(wxLEFT, 16). +-define(wxRIGHT, 32). +-define(wxUP, 64). +-define(wxDOWN, 128). +-define(wxTOP, ?wxUP). +-define(wxBOTTOM, ?wxDOWN). +-define(wxNORTH, ?wxUP). +-define(wxSOUTH, ?wxDOWN). +-define(wxWEST, ?wxLEFT). +-define(wxEAST, ?wxRIGHT). +-define(wxALL, (?wxUP bor ?wxDOWN bor ?wxRIGHT bor ?wxLEFT)). +% From "defs.h": wxDuplexMode +-define(wxDUPLEX_SIMPLEX, 0). +-define(wxDUPLEX_HORIZONTAL, 1). +-define(wxDUPLEX_VERTICAL, 2). +% From "defs.h": wxGeometryCentre +-define(wxCENTRE, 1). +-define(wxCENTER, ?wxCENTRE). +% From "defs.h": wxHitTest +-define(wxHT_NOWHERE, 0). +-define(wxHT_SCROLLBAR_FIRST, ?wxHT_NOWHERE). +-define(wxHT_SCROLLBAR_ARROW_LINE_1, (?wxHT_NOWHERE+1)). +-define(wxHT_SCROLLBAR_ARROW_LINE_2, (?wxHT_NOWHERE+2)). +-define(wxHT_SCROLLBAR_ARROW_PAGE_1, (?wxHT_NOWHERE+3)). +-define(wxHT_SCROLLBAR_ARROW_PAGE_2, (?wxHT_NOWHERE+4)). +-define(wxHT_SCROLLBAR_THUMB, (?wxHT_NOWHERE+5)). +-define(wxHT_SCROLLBAR_BAR_1, (?wxHT_NOWHERE+6)). +-define(wxHT_SCROLLBAR_BAR_2, (?wxHT_NOWHERE+7)). +-define(wxHT_SCROLLBAR_LAST, (?wxHT_NOWHERE+8)). +-define(wxHT_WINDOW_OUTSIDE, (?wxHT_NOWHERE+9)). +-define(wxHT_WINDOW_INSIDE, (?wxHT_NOWHERE+10)). +-define(wxHT_WINDOW_VERT_SCROLLBAR, (?wxHT_NOWHERE+11)). +-define(wxHT_WINDOW_HORZ_SCROLLBAR, (?wxHT_NOWHERE+12)). +-define(wxHT_WINDOW_CORNER, (?wxHT_NOWHERE+13)). +-define(wxHT_MAX, (?wxHT_NOWHERE+14)). +% From "defs.h": wxItemKind +-define(wxITEM_SEPARATOR, -1). +-define(wxITEM_NORMAL, 0). +-define(wxITEM_CHECK, 1). +-define(wxITEM_RADIO, 2). +-define(wxITEM_MAX, 3). +% From "defs.h": wxKeyCode +-define(WXK_BACK, 8). +-define(WXK_TAB, 9). +-define(WXK_RETURN, 13). +-define(WXK_ESCAPE, 27). +-define(WXK_SPACE, 32). +-define(WXK_DELETE, 127). +-define(WXK_START, 300). +-define(WXK_LBUTTON, 301). +-define(WXK_RBUTTON, 302). +-define(WXK_CANCEL, 303). +-define(WXK_MBUTTON, 304). +-define(WXK_CLEAR, 305). +-define(WXK_SHIFT, 306). +-define(WXK_ALT, 307). +-define(WXK_CONTROL, 308). +-define(WXK_MENU, 309). +-define(WXK_PAUSE, 310). +-define(WXK_CAPITAL, 311). +-define(WXK_END, 312). +-define(WXK_HOME, 313). +-define(WXK_LEFT, 314). +-define(WXK_UP, 315). +-define(WXK_RIGHT, 316). +-define(WXK_DOWN, 317). +-define(WXK_SELECT, 318). +-define(WXK_PRINT, 319). +-define(WXK_EXECUTE, 320). +-define(WXK_SNAPSHOT, 321). +-define(WXK_INSERT, 322). +-define(WXK_HELP, 323). +-define(WXK_NUMPAD0, 324). +-define(WXK_NUMPAD1, 325). +-define(WXK_NUMPAD2, 326). +-define(WXK_NUMPAD3, 327). +-define(WXK_NUMPAD4, 328). +-define(WXK_NUMPAD5, 329). +-define(WXK_NUMPAD6, 330). +-define(WXK_NUMPAD7, 331). +-define(WXK_NUMPAD8, 332). +-define(WXK_NUMPAD9, 333). +-define(WXK_MULTIPLY, 334). +-define(WXK_ADD, 335). +-define(WXK_SEPARATOR, 336). +-define(WXK_SUBTRACT, 337). +-define(WXK_DECIMAL, 338). +-define(WXK_DIVIDE, 339). +-define(WXK_F1, 340). +-define(WXK_F2, 341). +-define(WXK_F3, 342). +-define(WXK_F4, 343). +-define(WXK_F5, 344). +-define(WXK_F6, 345). +-define(WXK_F7, 346). +-define(WXK_F8, 347). +-define(WXK_F9, 348). +-define(WXK_F10, 349). +-define(WXK_F11, 350). +-define(WXK_F12, 351). +-define(WXK_F13, 352). +-define(WXK_F14, 353). +-define(WXK_F15, 354). +-define(WXK_F16, 355). +-define(WXK_F17, 356). +-define(WXK_F18, 357). +-define(WXK_F19, 358). +-define(WXK_F20, 359). +-define(WXK_F21, 360). +-define(WXK_F22, 361). +-define(WXK_F23, 362). +-define(WXK_F24, 363). +-define(WXK_NUMLOCK, 364). +-define(WXK_SCROLL, 365). +-define(WXK_PAGEUP, 366). +-define(WXK_PAGEDOWN, 367). +-define(WXK_NUMPAD_SPACE, 368). +-define(WXK_NUMPAD_TAB, 369). +-define(WXK_NUMPAD_ENTER, 370). +-define(WXK_NUMPAD_F1, 371). +-define(WXK_NUMPAD_F2, 372). +-define(WXK_NUMPAD_F3, 373). +-define(WXK_NUMPAD_F4, 374). +-define(WXK_NUMPAD_HOME, 375). +-define(WXK_NUMPAD_LEFT, 376). +-define(WXK_NUMPAD_UP, 377). +-define(WXK_NUMPAD_RIGHT, 378). +-define(WXK_NUMPAD_DOWN, 379). +-define(WXK_NUMPAD_PAGEUP, 380). +-define(WXK_NUMPAD_PAGEDOWN, 381). +-define(WXK_NUMPAD_END, 382). +-define(WXK_NUMPAD_BEGIN, 383). +-define(WXK_NUMPAD_INSERT, 384). +-define(WXK_NUMPAD_DELETE, 385). +-define(WXK_NUMPAD_EQUAL, 386). +-define(WXK_NUMPAD_MULTIPLY, 387). +-define(WXK_NUMPAD_ADD, 388). +-define(WXK_NUMPAD_SEPARATOR, 389). +-define(WXK_NUMPAD_SUBTRACT, 390). +-define(WXK_NUMPAD_DECIMAL, 391). +-define(WXK_NUMPAD_DIVIDE, 392). +-define(WXK_WINDOWS_LEFT, 393). +-define(WXK_WINDOWS_RIGHT, 394). +-define(WXK_WINDOWS_MENU, 395). +-define(WXK_COMMAND, 396). +-define(WXK_SPECIAL1, 193). +-define(WXK_SPECIAL2, 194). +-define(WXK_SPECIAL3, 195). +-define(WXK_SPECIAL4, 196). +-define(WXK_SPECIAL5, 197). +-define(WXK_SPECIAL6, 198). +-define(WXK_SPECIAL7, 199). +-define(WXK_SPECIAL8, 200). +-define(WXK_SPECIAL9, 201). +-define(WXK_SPECIAL10, 202). +-define(WXK_SPECIAL11, 203). +-define(WXK_SPECIAL12, 204). +-define(WXK_SPECIAL13, 205). +-define(WXK_SPECIAL14, 206). +-define(WXK_SPECIAL15, 207). +-define(WXK_SPECIAL16, 208). +-define(WXK_SPECIAL17, 209). +-define(WXK_SPECIAL18, 210). +-define(WXK_SPECIAL19, 211). +-define(WXK_SPECIAL20, 212). +% From "defs.h": wxKeyModifier +-define(wxMOD_NONE, 0). +-define(wxMOD_ALT, 1). +-define(wxMOD_CONTROL, 2). +-define(wxMOD_ALTGR, (?wxMOD_ALT bor ?wxMOD_CONTROL)). +-define(wxMOD_SHIFT, 4). +-define(wxMOD_META, 8). +-define(wxMOD_WIN, ?wxMOD_META). +-define(wxMOD_CMD, wxe_util:get_const(wxMOD_CMD)). +-define(wxMOD_ALL, 65535). +% From "defs.h": wxNotificationOptions +-define(wxNOTIFY_NONE, 0). +-define(wxNOTIFY_ONCE, 1). +-define(wxNOTIFY_REPEAT, 2). +% From "defs.h": wxOrientation +-define(wxHORIZONTAL, 4). +-define(wxVERTICAL, 8). +-define(wxBOTH, (?wxVERTICAL bor ?wxHORIZONTAL)). +% From "defs.h": wxPaperSize +-define(wxPAPER_NONE, 0). +-define(wxPAPER_LETTER, 1). +-define(wxPAPER_LEGAL, 2). +-define(wxPAPER_A4, 3). +-define(wxPAPER_CSHEET, 4). +-define(wxPAPER_DSHEET, 5). +-define(wxPAPER_ESHEET, 6). +-define(wxPAPER_LETTERSMALL, 7). +-define(wxPAPER_TABLOID, 8). +-define(wxPAPER_LEDGER, 9). +-define(wxPAPER_STATEMENT, 10). +-define(wxPAPER_EXECUTIVE, 11). +-define(wxPAPER_A3, 12). +-define(wxPAPER_A4SMALL, 13). +-define(wxPAPER_A5, 14). +-define(wxPAPER_B4, 15). +-define(wxPAPER_B5, 16). +-define(wxPAPER_FOLIO, 17). +-define(wxPAPER_QUARTO, 18). +-define(wxPAPER_10X14, 19). +-define(wxPAPER_11X17, 20). +-define(wxPAPER_NOTE, 21). +-define(wxPAPER_ENV_9, 22). +-define(wxPAPER_ENV_10, 23). +-define(wxPAPER_ENV_11, 24). +-define(wxPAPER_ENV_12, 25). +-define(wxPAPER_ENV_14, 26). +-define(wxPAPER_ENV_DL, 27). +-define(wxPAPER_ENV_C5, 28). +-define(wxPAPER_ENV_C3, 29). +-define(wxPAPER_ENV_C4, 30). +-define(wxPAPER_ENV_C6, 31). +-define(wxPAPER_ENV_C65, 32). +-define(wxPAPER_ENV_B4, 33). +-define(wxPAPER_ENV_B5, 34). +-define(wxPAPER_ENV_B6, 35). +-define(wxPAPER_ENV_ITALY, 36). +-define(wxPAPER_ENV_MONARCH, 37). +-define(wxPAPER_ENV_PERSONAL, 38). +-define(wxPAPER_FANFOLD_US, 39). +-define(wxPAPER_FANFOLD_STD_GERMAN, 40). +-define(wxPAPER_FANFOLD_LGL_GERMAN, 41). +-define(wxPAPER_ISO_B4, 42). +-define(wxPAPER_JAPANESE_POSTCARD, 43). +-define(wxPAPER_9X11, 44). +-define(wxPAPER_10X11, 45). +-define(wxPAPER_15X11, 46). +-define(wxPAPER_ENV_INVITE, 47). +-define(wxPAPER_LETTER_EXTRA, 48). +-define(wxPAPER_LEGAL_EXTRA, 49). +-define(wxPAPER_TABLOID_EXTRA, 50). +-define(wxPAPER_A4_EXTRA, 51). +-define(wxPAPER_LETTER_TRANSVERSE, 52). +-define(wxPAPER_A4_TRANSVERSE, 53). +-define(wxPAPER_LETTER_EXTRA_TRANSVERSE, 54). +-define(wxPAPER_A_PLUS, 55). +-define(wxPAPER_B_PLUS, 56). +-define(wxPAPER_LETTER_PLUS, 57). +-define(wxPAPER_A4_PLUS, 58). +-define(wxPAPER_A5_TRANSVERSE, 59). +-define(wxPAPER_B5_TRANSVERSE, 60). +-define(wxPAPER_A3_EXTRA, 61). +-define(wxPAPER_A5_EXTRA, 62). +-define(wxPAPER_B5_EXTRA, 63). +-define(wxPAPER_A2, 64). +-define(wxPAPER_A3_TRANSVERSE, 65). +-define(wxPAPER_A3_EXTRA_TRANSVERSE, 66). +-define(wxPAPER_DBL_JAPANESE_POSTCARD, 67). +-define(wxPAPER_A6, 68). +-define(wxPAPER_JENV_KAKU2, 69). +-define(wxPAPER_JENV_KAKU3, 70). +-define(wxPAPER_JENV_CHOU3, 71). +-define(wxPAPER_JENV_CHOU4, 72). +-define(wxPAPER_LETTER_ROTATED, 73). +-define(wxPAPER_A3_ROTATED, 74). +-define(wxPAPER_A4_ROTATED, 75). +-define(wxPAPER_A5_ROTATED, 76). +-define(wxPAPER_B4_JIS_ROTATED, 77). +-define(wxPAPER_B5_JIS_ROTATED, 78). +-define(wxPAPER_JAPANESE_POSTCARD_ROTATED, 79). +-define(wxPAPER_DBL_JAPANESE_POSTCARD_ROTATED, 80). +-define(wxPAPER_A6_ROTATED, 81). +-define(wxPAPER_JENV_KAKU2_ROTATED, 82). +-define(wxPAPER_JENV_KAKU3_ROTATED, 83). +-define(wxPAPER_JENV_CHOU3_ROTATED, 84). +-define(wxPAPER_JENV_CHOU4_ROTATED, 85). +-define(wxPAPER_B6_JIS, 86). +-define(wxPAPER_B6_JIS_ROTATED, 87). +-define(wxPAPER_12X11, 88). +-define(wxPAPER_JENV_YOU4, 89). +-define(wxPAPER_JENV_YOU4_ROTATED, 90). +-define(wxPAPER_P16K, 91). +-define(wxPAPER_P32K, 92). +-define(wxPAPER_P32KBIG, 93). +-define(wxPAPER_PENV_1, 94). +-define(wxPAPER_PENV_2, 95). +-define(wxPAPER_PENV_3, 96). +-define(wxPAPER_PENV_4, 97). +-define(wxPAPER_PENV_5, 98). +-define(wxPAPER_PENV_6, 99). +-define(wxPAPER_PENV_7, 100). +-define(wxPAPER_PENV_8, 101). +-define(wxPAPER_PENV_9, 102). +-define(wxPAPER_PENV_10, 103). +-define(wxPAPER_P16K_ROTATED, 104). +-define(wxPAPER_P32K_ROTATED, 105). +-define(wxPAPER_P32KBIG_ROTATED, 106). +-define(wxPAPER_PENV_1_ROTATED, 107). +-define(wxPAPER_PENV_2_ROTATED, 108). +-define(wxPAPER_PENV_3_ROTATED, 109). +-define(wxPAPER_PENV_4_ROTATED, 110). +-define(wxPAPER_PENV_5_ROTATED, 111). +-define(wxPAPER_PENV_6_ROTATED, 112). +-define(wxPAPER_PENV_7_ROTATED, 113). +-define(wxPAPER_PENV_8_ROTATED, 114). +-define(wxPAPER_PENV_9_ROTATED, 115). +-define(wxPAPER_PENV_10_ROTATED, 116). +% From "defs.h": wxPrintMode +-define(wxPRINT_MODE_NONE, 0). +-define(wxPRINT_MODE_PREVIEW, 1). +-define(wxPRINT_MODE_FILE, 2). +-define(wxPRINT_MODE_PRINTER, 3). +-define(wxPRINT_MODE_STREAM, 4). +% From "defs.h": wxStretch +-define(wxSTRETCH_NOT, 0). +-define(wxSHRINK, 4096). +-define(wxGROW, 8192). +-define(wxEXPAND, ?wxGROW). +-define(wxSHAPED, 16384). +-define(wxFIXED_MINSIZE, 32768). +-define(wxRESERVE_SPACE_EVEN_IF_HIDDEN, 2). +-define(wxTILE, 49152). +-define(wxADJUST_MINSIZE, 0). +% From "defs.h": wxUpdateUI +-define(wxUPDATE_UI_NONE, 0). +-define(wxUPDATE_UI_RECURSE, 1). +-define(wxUPDATE_UI_FROMIDLE, 2). +% From "dialog.h" -define(wxDEFAULT_DIALOG_STYLE, (?wxCAPTION bor ?wxSYSTEM_MENU bor ?wxCLOSE_BOX)). -define(wxDIALOG_NO_PARENT, 1). -% From define::From dirctrlg.h +% From "dirctrlg.h" +-define(wxDIRCTRL_DIR_ONLY, 16). +-define(wxDIRCTRL_SELECT_FIRST, 32). +-define(wxDIRCTRL_SHOW_FILTERS, 64). +-define(wxDIRCTRL_3D_INTERNAL, 128). +-define(wxDIRCTRL_EDIT_LABELS, 256). +% From "dirctrlg.h" -define(wxID_FILTERLISTCTRL, 7001). -define(wxID_TREECTRL, 7000). -% From define::From dirdlg.h +% From "dirdlg.h" -define(wxDD_DEFAULT_STYLE, (?wxDEFAULT_DIALOG_STYLE bor ?wxRESIZE_BORDER)). -define(wxDD_NEW_DIR_BUTTON, 0). -define(wxDD_DIR_MUST_EXIST, 512). -define(wxDD_CHANGE_DIR, 256). -% From define::From dirdlgg.h -% From define::From filedlg.h +% From "dirdlgg.h" +% From "dnd.h" +-define(wxDrag_CopyOnly, 0). +-define(wxDrag_AllowMove, 1). +-define(wxDrag_DefaultMove, 3). +% From "dnd.h": wxDragResult +-define(wxDragError, 0). +-define(wxDragNone, 1). +-define(wxDragCopy, 2). +-define(wxDragMove, 3). +-define(wxDragLink, 4). +-define(wxDragCancel, 5). +% From "event.h" +-define(wxMOUSE_BTN_ANY, -1). +-define(wxMOUSE_BTN_NONE, 0). +-define(wxMOUSE_BTN_LEFT, 1). +-define(wxMOUSE_BTN_MIDDLE, 2). +-define(wxMOUSE_BTN_RIGHT, 3). +% From "event.h" +-define(wxJOYSTICK1, 0). +-define(wxJOYSTICK2, 1). +% From "event.h" +-define(wxJOY_BUTTON_ANY, -1). +-define(wxJOY_BUTTON1, 1). +-define(wxJOY_BUTTON2, 2). +-define(wxJOY_BUTTON3, 4). +-define(wxJOY_BUTTON4, 8). +% From "event.h" +% From "event.h": Propagation_state +-define(wxEVENT_PROPAGATE_NONE, 0). +-define(wxEVENT_PROPAGATE_MAX, ?INT_MAX). +% From "event.h": wxIdleMode +-define(wxIDLE_PROCESS_ALL, 0). +-define(wxIDLE_PROCESS_SPECIFIED, 1). +% From "event.h": wxUpdateUIMode +-define(wxUPDATE_UI_PROCESS_ALL, 0). +-define(wxUPDATE_UI_PROCESS_SPECIFIED, 1). +% From "fdrepdlg.h": wxFindReplaceDialogStyles +-define(wxFR_REPLACEDIALOG, 1). +-define(wxFR_NOUPDOWN, 2). +-define(wxFR_NOMATCHCASE, 4). +-define(wxFR_NOWHOLEWORD, 8). +% From "fdrepdlg.h": wxFindReplaceFlags +-define(wxFR_DOWN, 1). +-define(wxFR_WHOLEWORD, 2). +-define(wxFR_MATCHCASE, 4). +% From "filedlg.h" +-define(wxFD_OPEN, 1). +-define(wxFD_SAVE, 2). +-define(wxFD_OVERWRITE_PROMPT, 4). +-define(wxFD_FILE_MUST_EXIST, 16). +-define(wxFD_MULTIPLE, 32). +-define(wxFD_CHANGE_DIR, 128). +-define(wxFD_PREVIEW, 256). +% From "filedlg.h" -define(wxFD_DEFAULT_STYLE, ?wxFD_OPEN). -% From define::From filepicker.h +% From "filepicker.h" -define(wxDIRP_DEFAULT_STYLE, ?wxDIRP_DIR_MUST_EXIST). -define(wxDIRP_USE_TEXTCTRL, ?wxPB_USE_TEXTCTRL). -define(wxFLP_DEFAULT_STYLE, (?wxFLP_OPEN bor ?wxFLP_FILE_MUST_EXIST)). @@ -529,30 +1550,300 @@ -define(wxFLP_OVERWRITE_PROMPT, 4096). -define(wxFLP_SAVE, 2048). -define(wxFLP_OPEN, 1024). -% From define::From fontpicker.h +% From "font.h" +-define(wxFONTFLAG_DEFAULT, 0). +-define(wxFONTFLAG_ITALIC, 1). +-define(wxFONTFLAG_SLANT, 2). +-define(wxFONTFLAG_LIGHT, 4). +-define(wxFONTFLAG_BOLD, 8). +-define(wxFONTFLAG_ANTIALIASED, 16). +-define(wxFONTFLAG_NOT_ANTIALIASED, 32). +-define(wxFONTFLAG_UNDERLINED, 64). +-define(wxFONTFLAG_STRIKETHROUGH, 128). +-define(wxFONTFLAG_MASK, (?wxFONTFLAG_ITALIC bor ?wxFONTFLAG_SLANT bor ?wxFONTFLAG_LIGHT bor ?wxFONTFLAG_BOLD bor ?wxFONTFLAG_ANTIALIASED bor ?wxFONTFLAG_NOT_ANTIALIASED bor ?wxFONTFLAG_UNDERLINED bor ?wxFONTFLAG_STRIKETHROUGH)). +% From "font.h": wxFontFamily +-define(wxFONTFAMILY_DEFAULT, ?wxDEFAULT). +-define(wxFONTFAMILY_DECORATIVE, ?wxDECORATIVE). +-define(wxFONTFAMILY_ROMAN, ?wxROMAN). +-define(wxFONTFAMILY_SCRIPT, ?wxSCRIPT). +-define(wxFONTFAMILY_SWISS, ?wxSWISS). +-define(wxFONTFAMILY_MODERN, ?wxMODERN). +-define(wxFONTFAMILY_TELETYPE, ?wxTELETYPE). +-define(wxFONTFAMILY_MAX, (?wxTELETYPE+1)). +-define(wxFONTFAMILY_UNKNOWN, ?wxFONTFAMILY_MAX). +% From "font.h": wxFontStyle +-define(wxFONTSTYLE_NORMAL, ?wxNORMAL). +-define(wxFONTSTYLE_ITALIC, ?wxITALIC). +-define(wxFONTSTYLE_SLANT, ?wxSLANT). +-define(wxFONTSTYLE_MAX, (?wxSLANT+1)). +% From "font.h": wxFontWeight +-define(wxFONTWEIGHT_NORMAL, ?wxNORMAL). +-define(wxFONTWEIGHT_LIGHT, ?wxLIGHT). +-define(wxFONTWEIGHT_BOLD, ?wxBOLD). +-define(wxFONTWEIGHT_MAX, (?wxBOLD+1)). +% From "fontenc.h": wxFontEncoding +-define(wxFONTENCODING_SYSTEM, -1). +-define(wxFONTENCODING_DEFAULT, 0). +-define(wxFONTENCODING_ISO8859_1, 1). +-define(wxFONTENCODING_ISO8859_2, 2). +-define(wxFONTENCODING_ISO8859_3, 3). +-define(wxFONTENCODING_ISO8859_4, 4). +-define(wxFONTENCODING_ISO8859_5, 5). +-define(wxFONTENCODING_ISO8859_6, 6). +-define(wxFONTENCODING_ISO8859_7, 7). +-define(wxFONTENCODING_ISO8859_8, 8). +-define(wxFONTENCODING_ISO8859_9, 9). +-define(wxFONTENCODING_ISO8859_10, 10). +-define(wxFONTENCODING_ISO8859_11, 11). +-define(wxFONTENCODING_ISO8859_12, 12). +-define(wxFONTENCODING_ISO8859_13, 13). +-define(wxFONTENCODING_ISO8859_14, 14). +-define(wxFONTENCODING_ISO8859_15, 15). +-define(wxFONTENCODING_ISO8859_MAX, 16). +-define(wxFONTENCODING_KOI8, 17). +-define(wxFONTENCODING_KOI8_U, 18). +-define(wxFONTENCODING_ALTERNATIVE, 19). +-define(wxFONTENCODING_BULGARIAN, 20). +-define(wxFONTENCODING_CP437, 21). +-define(wxFONTENCODING_CP850, 22). +-define(wxFONTENCODING_CP852, 23). +-define(wxFONTENCODING_CP855, 24). +-define(wxFONTENCODING_CP866, 25). +-define(wxFONTENCODING_CP874, 26). +-define(wxFONTENCODING_CP932, 27). +-define(wxFONTENCODING_CP936, 28). +-define(wxFONTENCODING_CP949, 29). +-define(wxFONTENCODING_CP950, 30). +-define(wxFONTENCODING_CP1250, 31). +-define(wxFONTENCODING_CP1251, 32). +-define(wxFONTENCODING_CP1252, 33). +-define(wxFONTENCODING_CP1253, 34). +-define(wxFONTENCODING_CP1254, 35). +-define(wxFONTENCODING_CP1255, 36). +-define(wxFONTENCODING_CP1256, 37). +-define(wxFONTENCODING_CP1257, 38). +-define(wxFONTENCODING_CP12_MAX, 39). +-define(wxFONTENCODING_UTF7, 40). +-define(wxFONTENCODING_UTF8, 41). +-define(wxFONTENCODING_EUC_JP, 42). +-define(wxFONTENCODING_UTF16BE, 43). +-define(wxFONTENCODING_UTF16LE, 44). +-define(wxFONTENCODING_UTF32BE, 45). +-define(wxFONTENCODING_UTF32LE, 46). +-define(wxFONTENCODING_MACROMAN, 47). +-define(wxFONTENCODING_MACJAPANESE, 48). +-define(wxFONTENCODING_MACCHINESETRAD, 49). +-define(wxFONTENCODING_MACKOREAN, 50). +-define(wxFONTENCODING_MACARABIC, 51). +-define(wxFONTENCODING_MACHEBREW, 52). +-define(wxFONTENCODING_MACGREEK, 53). +-define(wxFONTENCODING_MACCYRILLIC, 54). +-define(wxFONTENCODING_MACDEVANAGARI, 55). +-define(wxFONTENCODING_MACGURMUKHI, 56). +-define(wxFONTENCODING_MACGUJARATI, 57). +-define(wxFONTENCODING_MACORIYA, 58). +-define(wxFONTENCODING_MACBENGALI, 59). +-define(wxFONTENCODING_MACTAMIL, 60). +-define(wxFONTENCODING_MACTELUGU, 61). +-define(wxFONTENCODING_MACKANNADA, 62). +-define(wxFONTENCODING_MACMALAJALAM, 63). +-define(wxFONTENCODING_MACSINHALESE, 64). +-define(wxFONTENCODING_MACBURMESE, 65). +-define(wxFONTENCODING_MACKHMER, 66). +-define(wxFONTENCODING_MACTHAI, 67). +-define(wxFONTENCODING_MACLAOTIAN, 68). +-define(wxFONTENCODING_MACGEORGIAN, 69). +-define(wxFONTENCODING_MACARMENIAN, 70). +-define(wxFONTENCODING_MACCHINESESIMP, 71). +-define(wxFONTENCODING_MACTIBETAN, 72). +-define(wxFONTENCODING_MACMONGOLIAN, 73). +-define(wxFONTENCODING_MACETHIOPIC, 74). +-define(wxFONTENCODING_MACCENTRALEUR, 75). +-define(wxFONTENCODING_MACVIATNAMESE, 76). +-define(wxFONTENCODING_MACARABICEXT, 77). +-define(wxFONTENCODING_MACSYMBOL, 78). +-define(wxFONTENCODING_MACDINGBATS, 79). +-define(wxFONTENCODING_MACTURKISH, 80). +-define(wxFONTENCODING_MACCROATIAN, 81). +-define(wxFONTENCODING_MACICELANDIC, 82). +-define(wxFONTENCODING_MACROMANIAN, 83). +-define(wxFONTENCODING_MACCELTIC, 84). +-define(wxFONTENCODING_MACGAELIC, 85). +-define(wxFONTENCODING_MACKEYBOARD, 86). +-define(wxFONTENCODING_MAX, 87). +-define(wxFONTENCODING_MACMIN, ?wxFONTENCODING_MACROMAN). +-define(wxFONTENCODING_MACMAX, ?wxFONTENCODING_MACKEYBOARD). +-define(wxFONTENCODING_UTF16, wxe_util:get_const(wxFONTENCODING_UTF16)). +-define(wxFONTENCODING_UTF32, wxe_util:get_const(wxFONTENCODING_UTF32)). +-define(wxFONTENCODING_UNICODE, ?wxFONTENCODING_UTF32). +-define(wxFONTENCODING_GB2312, ?wxFONTENCODING_CP936). +-define(wxFONTENCODING_BIG5, ?wxFONTENCODING_CP950). +-define(wxFONTENCODING_SHIFT_JIS, ?wxFONTENCODING_CP932). +% From "fontpicker.h" -define(wxFNTP_MAXPOINT_SIZE, 100). -define(wxFNTP_DEFAULT_STYLE, (?wxFNTP_FONTDESC_AS_LABEL bor ?wxFNTP_USEFONT_FOR_LABEL)). -define(wxFNTP_USE_TEXTCTRL, ?wxPB_USE_TEXTCTRL). -define(wxFNTP_USEFONT_FOR_LABEL, 16). -define(wxFNTP_FONTDESC_AS_LABEL, 8). -% From define::From frame.h +% From "frame.h" -define(wxFRAME_SHAPED, 16). -define(wxFRAME_FLOAT_ON_PARENT, 8). -define(wxFRAME_TOOL_WINDOW, 4). -define(wxFRAME_NO_TASKBAR, 2). -% From define::From gauge.h --define(wxGAUGE_EMULATE_INDETERMINATE_MODE, 1). +% From "framemanager.h": wxAuiButtonId +-define(wxAUI_BUTTON_CLOSE, 101). +-define(wxAUI_BUTTON_MAXIMIZE_RESTORE, 102). +-define(wxAUI_BUTTON_MINIMIZE, 103). +-define(wxAUI_BUTTON_PIN, 104). +-define(wxAUI_BUTTON_OPTIONS, 105). +-define(wxAUI_BUTTON_WINDOWLIST, 106). +-define(wxAUI_BUTTON_LEFT, 107). +-define(wxAUI_BUTTON_RIGHT, 108). +-define(wxAUI_BUTTON_UP, 109). +-define(wxAUI_BUTTON_DOWN, 110). +-define(wxAUI_BUTTON_CUSTOM1, 201). +-define(wxAUI_BUTTON_CUSTOM2, 202). +-define(wxAUI_BUTTON_CUSTOM3, 203). +% From "framemanager.h": wxAuiManagerDock +-define(wxAUI_DOCK_NONE, 0). +-define(wxAUI_DOCK_TOP, 1). +-define(wxAUI_DOCK_RIGHT, 2). +-define(wxAUI_DOCK_BOTTOM, 3). +-define(wxAUI_DOCK_LEFT, 4). +-define(wxAUI_DOCK_CENTER, 5). +-define(wxAUI_DOCK_CENTRE, ?wxAUI_DOCK_CENTER). +% From "framemanager.h": wxAuiManagerOption +-define(wxAUI_MGR_ALLOW_FLOATING, 1). +-define(wxAUI_MGR_ALLOW_ACTIVE_PANE, 2). +-define(wxAUI_MGR_TRANSPARENT_DRAG, 4). +-define(wxAUI_MGR_TRANSPARENT_HINT, 8). +-define(wxAUI_MGR_VENETIAN_BLINDS_HINT, 16). +-define(wxAUI_MGR_RECTANGLE_HINT, 32). +-define(wxAUI_MGR_HINT_FADE, 64). +-define(wxAUI_MGR_NO_VENETIAN_BLINDS_FADE, 128). +-define(wxAUI_MGR_LIVE_RESIZE, 256). +-define(wxAUI_MGR_DEFAULT, (?wxAUI_MGR_ALLOW_FLOATING bor ?wxAUI_MGR_TRANSPARENT_HINT bor ?wxAUI_MGR_HINT_FADE bor ?wxAUI_MGR_NO_VENETIAN_BLINDS_FADE)). +% From "framemanager.h": wxAuiPaneButtonState +-define(wxAUI_BUTTON_STATE_NORMAL, 0). +-define(wxAUI_BUTTON_STATE_HOVER, 2). +-define(wxAUI_BUTTON_STATE_PRESSED, 4). +-define(wxAUI_BUTTON_STATE_DISABLED, 8). +-define(wxAUI_BUTTON_STATE_HIDDEN, 16). +-define(wxAUI_BUTTON_STATE_CHECKED, 32). +% From "framemanager.h": wxAuiPaneDockArtGradients +-define(wxAUI_GRADIENT_NONE, 0). +-define(wxAUI_GRADIENT_VERTICAL, 1). +-define(wxAUI_GRADIENT_HORIZONTAL, 2). +% From "framemanager.h": wxAuiPaneDockArtSetting +-define(wxAUI_DOCKART_SASH_SIZE, 0). +-define(wxAUI_DOCKART_CAPTION_SIZE, 1). +-define(wxAUI_DOCKART_GRIPPER_SIZE, 2). +-define(wxAUI_DOCKART_PANE_BORDER_SIZE, 3). +-define(wxAUI_DOCKART_PANE_BUTTON_SIZE, 4). +-define(wxAUI_DOCKART_BACKGROUND_COLOUR, 5). +-define(wxAUI_DOCKART_SASH_COLOUR, 6). +-define(wxAUI_DOCKART_ACTIVE_CAPTION_COLOUR, 7). +-define(wxAUI_DOCKART_ACTIVE_CAPTION_GRADIENT_COLOUR, 8). +-define(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR, 9). +-define(wxAUI_DOCKART_INACTIVE_CAPTION_GRADIENT_COLOUR, 10). +-define(wxAUI_DOCKART_ACTIVE_CAPTION_TEXT_COLOUR, 11). +-define(wxAUI_DOCKART_INACTIVE_CAPTION_TEXT_COLOUR, 12). +-define(wxAUI_DOCKART_BORDER_COLOUR, 13). +-define(wxAUI_DOCKART_GRIPPER_COLOUR, 14). +-define(wxAUI_DOCKART_CAPTION_FONT, 15). +-define(wxAUI_DOCKART_GRADIENT_TYPE, 16). +% From "framemanager.h": wxAuiPaneInsertLevel +-define(wxAUI_INSERT_PANE, 0). +-define(wxAUI_INSERT_ROW, 1). +-define(wxAUI_INSERT_DOCK, 2). +% From "gauge.h" +-define(wxGAUGE_EMULATE_INDETERMINATE_MODE, wxe_util:get_const(wxGAUGE_EMULATE_INDETERMINATE_MODE)). -define(wxGA_SMOOTH, 32). -define(wxGA_VERTICAL, ?wxVERTICAL). -define(wxGA_HORIZONTAL, ?wxHORIZONTAL). -% From define::From gdicmn.h +% From "gdicmn.h" -define(wxGetDisplayDepth, ?wxDisplayDepth). -% From define::From generic_2laywin.h +% From "gdicmn.h": wxBitmapType +-define(wxBITMAP_TYPE_INVALID, 0). +-define(wxBITMAP_TYPE_BMP, 1). +-define(wxBITMAP_TYPE_BMP_RESOURCE, 2). +-define(wxBITMAP_TYPE_RESOURCE, ?wxBITMAP_TYPE_BMP_RESOURCE). +-define(wxBITMAP_TYPE_ICO, (?wxBITMAP_TYPE_BMP_RESOURCE+1)). +-define(wxBITMAP_TYPE_ICO_RESOURCE, (?wxBITMAP_TYPE_BMP_RESOURCE+2)). +-define(wxBITMAP_TYPE_CUR, (?wxBITMAP_TYPE_BMP_RESOURCE+3)). +-define(wxBITMAP_TYPE_CUR_RESOURCE, (?wxBITMAP_TYPE_BMP_RESOURCE+4)). +-define(wxBITMAP_TYPE_XBM, (?wxBITMAP_TYPE_BMP_RESOURCE+5)). +-define(wxBITMAP_TYPE_XBM_DATA, (?wxBITMAP_TYPE_BMP_RESOURCE+6)). +-define(wxBITMAP_TYPE_XPM, (?wxBITMAP_TYPE_BMP_RESOURCE+7)). +-define(wxBITMAP_TYPE_XPM_DATA, (?wxBITMAP_TYPE_BMP_RESOURCE+8)). +-define(wxBITMAP_TYPE_TIF, (?wxBITMAP_TYPE_BMP_RESOURCE+9)). +-define(wxBITMAP_TYPE_TIF_RESOURCE, (?wxBITMAP_TYPE_BMP_RESOURCE+10)). +-define(wxBITMAP_TYPE_GIF, (?wxBITMAP_TYPE_BMP_RESOURCE+11)). +-define(wxBITMAP_TYPE_GIF_RESOURCE, (?wxBITMAP_TYPE_BMP_RESOURCE+12)). +-define(wxBITMAP_TYPE_PNG, (?wxBITMAP_TYPE_BMP_RESOURCE+13)). +-define(wxBITMAP_TYPE_PNG_RESOURCE, (?wxBITMAP_TYPE_BMP_RESOURCE+14)). +-define(wxBITMAP_TYPE_JPEG, (?wxBITMAP_TYPE_BMP_RESOURCE+15)). +-define(wxBITMAP_TYPE_JPEG_RESOURCE, (?wxBITMAP_TYPE_BMP_RESOURCE+16)). +-define(wxBITMAP_TYPE_PNM, (?wxBITMAP_TYPE_BMP_RESOURCE+17)). +-define(wxBITMAP_TYPE_PNM_RESOURCE, (?wxBITMAP_TYPE_BMP_RESOURCE+18)). +-define(wxBITMAP_TYPE_PCX, (?wxBITMAP_TYPE_BMP_RESOURCE+19)). +-define(wxBITMAP_TYPE_PCX_RESOURCE, (?wxBITMAP_TYPE_BMP_RESOURCE+20)). +-define(wxBITMAP_TYPE_PICT, (?wxBITMAP_TYPE_BMP_RESOURCE+21)). +-define(wxBITMAP_TYPE_PICT_RESOURCE, (?wxBITMAP_TYPE_BMP_RESOURCE+22)). +-define(wxBITMAP_TYPE_ICON, (?wxBITMAP_TYPE_BMP_RESOURCE+23)). +-define(wxBITMAP_TYPE_ICON_RESOURCE, (?wxBITMAP_TYPE_BMP_RESOURCE+24)). +-define(wxBITMAP_TYPE_ANI, (?wxBITMAP_TYPE_BMP_RESOURCE+25)). +-define(wxBITMAP_TYPE_IFF, (?wxBITMAP_TYPE_BMP_RESOURCE+26)). +-define(wxBITMAP_TYPE_TGA, (?wxBITMAP_TYPE_BMP_RESOURCE+27)). +-define(wxBITMAP_TYPE_MACCURSOR, (?wxBITMAP_TYPE_BMP_RESOURCE+28)). +-define(wxBITMAP_TYPE_MACCURSOR_RESOURCE, (?wxBITMAP_TYPE_BMP_RESOURCE+29)). +-define(wxBITMAP_TYPE_ANY, 50). +% From "gdicmn.h": wxStockCursor +-define(wxCURSOR_NONE, 0). +-define(wxCURSOR_ARROW, 1). +-define(wxCURSOR_RIGHT_ARROW, 2). +-define(wxCURSOR_BULLSEYE, 3). +-define(wxCURSOR_CHAR, 4). +-define(wxCURSOR_CROSS, 5). +-define(wxCURSOR_HAND, 6). +-define(wxCURSOR_IBEAM, 7). +-define(wxCURSOR_LEFT_BUTTON, 8). +-define(wxCURSOR_MAGNIFIER, 9). +-define(wxCURSOR_MIDDLE_BUTTON, 10). +-define(wxCURSOR_NO_ENTRY, 11). +-define(wxCURSOR_PAINT_BRUSH, 12). +-define(wxCURSOR_PENCIL, 13). +-define(wxCURSOR_POINT_LEFT, 14). +-define(wxCURSOR_POINT_RIGHT, 15). +-define(wxCURSOR_QUESTION_ARROW, 16). +-define(wxCURSOR_RIGHT_BUTTON, 17). +-define(wxCURSOR_SIZENESW, 18). +-define(wxCURSOR_SIZENS, 19). +-define(wxCURSOR_SIZENWSE, 20). +-define(wxCURSOR_SIZEWE, 21). +-define(wxCURSOR_SIZING, 22). +-define(wxCURSOR_SPRAYCAN, 23). +-define(wxCURSOR_WAIT, 24). +-define(wxCURSOR_WATCH, 25). +-define(wxCURSOR_BLANK, 26). +-define(wxCURSOR_DEFAULT, 27). +-define(wxCURSOR_ARROWWAIT, 28). +-define(wxCURSOR_MAX, 29). +% From "generic_2laywin.h" -define(wxLAYOUT_QUERY, 256). -define(wxLAYOUT_MRU_LENGTH, 16). -define(wxLAYOUT_LENGTH_X, 0). -define(wxLAYOUT_LENGTH_Y, 8). -% From define::From generic_2sashwin.h +% From "generic_2laywin.h": wxLayoutAlignment +-define(wxLAYOUT_NONE, 0). +-define(wxLAYOUT_TOP, 1). +-define(wxLAYOUT_LEFT, 2). +-define(wxLAYOUT_RIGHT, 3). +-define(wxLAYOUT_BOTTOM, 4). +% From "generic_2laywin.h": wxLayoutOrientation +-define(wxLAYOUT_HORIZONTAL, 0). +-define(wxLAYOUT_VERTICAL, 1). +% From "generic_2sashwin.h" -define(wxSW_3D, (?wxSW_3DSASH bor ?wxSW_3DBORDER)). -define(wxSW_3DBORDER, 128). -define(wxSW_3DSASH, 64). @@ -561,27 +1852,137 @@ -define(wxSASH_DRAG_LEFT_DOWN, 2). -define(wxSASH_DRAG_DRAGGING, 1). -define(wxSASH_DRAG_NONE, 0). -% From define::From generic_2splash.h +% From "generic_2sashwin.h": wxSashEdgePosition +-define(wxSASH_TOP, 0). +-define(wxSASH_RIGHT, 1). +-define(wxSASH_BOTTOM, 2). +-define(wxSASH_LEFT, 3). +-define(wxSASH_NONE, 100). +% From "generic_2splash.h" -define(wxSPLASH_NO_TIMEOUT, 0). -define(wxSPLASH_TIMEOUT, 4). -define(wxSPLASH_NO_CENTRE, 0). -define(wxSPLASH_CENTRE_ON_SCREEN, 2). -define(wxSPLASH_CENTRE_ON_PARENT, 1). -% From define::From hash.h +% From "generic_2splitter.h" +-define(wxSPLIT_DRAG_NONE, 0). +-define(wxSPLIT_DRAG_DRAGGING, 1). +-define(wxSPLIT_DRAG_LEFT_DOWN, 2). +% From "generic_2splitter.h": wxSplitMode +-define(wxSPLIT_HORIZONTAL, 1). +-define(wxSPLIT_VERTICAL, 2). +% From "glcanvas.h" +-define(WX_GL_RGBA, 1). +-define(WX_GL_BUFFER_SIZE, 2). +-define(WX_GL_LEVEL, 3). +-define(WX_GL_DOUBLEBUFFER, 4). +-define(WX_GL_STEREO, 5). +-define(WX_GL_AUX_BUFFERS, 6). +-define(WX_GL_MIN_RED, 7). +-define(WX_GL_MIN_GREEN, 8). +-define(WX_GL_MIN_BLUE, 9). +-define(WX_GL_MIN_ALPHA, 10). +-define(WX_GL_DEPTH_SIZE, 11). +-define(WX_GL_STENCIL_SIZE, 12). +-define(WX_GL_MIN_ACCUM_RED, 13). +-define(WX_GL_MIN_ACCUM_GREEN, 14). +-define(WX_GL_MIN_ACCUM_BLUE, 15). +-define(WX_GL_MIN_ACCUM_ALPHA, 16). +% From "hash.h" -define(wxHASH_SIZE_DEFAULT, 1000). -% From define::From htmlwin.h +% From "htmlwin.h" -define(wxHW_DEFAULT_STYLE, ?wxHW_SCROLLBAR_AUTO). -define(wxHW_NO_SELECTION, 8). -define(wxHW_SCROLLBAR_AUTO, 4). -define(wxHW_SCROLLBAR_NEVER, 2). -% From define::From imaglist.h +% From "htmlwin.h": wxHtmlOpeningStatus +-define(wxHTML_OPEN, 0). +-define(wxHTML_BLOCK, 1). +-define(wxHTML_REDIRECT, 2). +% From "htmprint.h" +-define(wxPAGE_ODD, 0). +-define(wxPAGE_EVEN, 1). +-define(wxPAGE_ALL, 2). +% From "imagbmp.h" +-define(wxBMP_24BPP, 24). +-define(wxBMP_8BPP, 8). +-define(wxBMP_8BPP_GREY, 9). +-define(wxBMP_8BPP_GRAY, ?wxBMP_8BPP_GREY). +-define(wxBMP_8BPP_RED, 10). +-define(wxBMP_8BPP_PALETTE, 11). +-define(wxBMP_4BPP, 4). +-define(wxBMP_1BPP, 1). +-define(wxBMP_1BPP_BW, 2). +% From "image.h" +-define(wxIMAGE_RESOLUTION_INCHES, 1). +-define(wxIMAGE_RESOLUTION_CM, 2). +% From "image.h" +-define(wxIMAGE_QUALITY_NORMAL, 0). +-define(wxIMAGE_QUALITY_HIGH, 1). +% From "imaglist.h" +-define(wxIMAGE_LIST_NORMAL, 0). +-define(wxIMAGE_LIST_SMALL, 1). +-define(wxIMAGE_LIST_STATE, 2). +% From "imaglist.h" -define(wxIMAGELIST_DRAW_FOCUSED, 8). -define(wxIMAGELIST_DRAW_SELECTED, 4). -define(wxIMAGELIST_DRAW_TRANSPARENT, 2). -define(wxIMAGELIST_DRAW_NORMAL, 1). -% From define::From layout.h +% From "intl.h": wxLayoutDirection +-define(wxLayout_Default, 0). +-define(wxLayout_LeftToRight, 1). +-define(wxLayout_RightToLeft, 2). +% From "layout.h" -define(wxLAYOUT_DEFAULT_MARGIN, 0). -% From define::From listbase.h +% From "layout.h": wxEdge +-define(wxLeft, 0). +-define(wxTop, 1). +-define(wxRight, 2). +-define(wxBottom, 3). +-define(wxWidth, 4). +-define(wxHeight, 5). +-define(wxCentre, 6). +-define(wxCenter, ?wxCentre). +-define(wxCentreX, (?wxCentre+1)). +-define(wxCentreY, (?wxCentre+2)). +% From "layout.h": wxRelationship +-define(wxUnconstrained, 0). +-define(wxAsIs, 1). +-define(wxPercentOf, 2). +-define(wxAbove, 3). +-define(wxBelow, 4). +-define(wxLeftOf, 5). +-define(wxRightOf, 6). +-define(wxSameAs, 7). +-define(wxAbsolute, 8). +% From "list.h": wxKeyType +-define(wxKEY_NONE, 0). +-define(wxKEY_INTEGER, 1). +-define(wxKEY_STRING, 2). +% From "listbase.h" +-define(wxLIST_NEXT_ABOVE, 0). +-define(wxLIST_NEXT_ALL, 1). +-define(wxLIST_NEXT_BELOW, 2). +-define(wxLIST_NEXT_LEFT, 3). +-define(wxLIST_NEXT_RIGHT, 4). +% From "listbase.h" +-define(wxLIST_ALIGN_DEFAULT, 0). +-define(wxLIST_ALIGN_LEFT, 1). +-define(wxLIST_ALIGN_TOP, 2). +-define(wxLIST_ALIGN_SNAP_TO_GRID, 3). +% From "listbase.h" +-define(wxLIST_AUTOSIZE, -1). +-define(wxLIST_AUTOSIZE_USEHEADER, -2). +% From "listbase.h" +-define(wxLIST_RECT_BOUNDS, 0). +-define(wxLIST_RECT_ICON, 1). +-define(wxLIST_RECT_LABEL, 2). +% From "listbase.h" +-define(wxLIST_FIND_UP, 0). +-define(wxLIST_FIND_DOWN, 1). +-define(wxLIST_FIND_LEFT, 2). +-define(wxLIST_FIND_RIGHT, 3). +% From "listbase.h" -define(wxLIST_HITTEST_ONITEM, (?wxLIST_HITTEST_ONITEMICON bor ?wxLIST_HITTEST_ONITEMLABEL bor ?wxLIST_HITTEST_ONITEMSTATEICON)). -define(wxLIST_HITTEST_TORIGHT, 2048). -define(wxLIST_HITTEST_TOLEFT, 1024). @@ -629,20 +2030,31 @@ -define(wxLC_ICON, 4). -define(wxLC_HRULES, 2). -define(wxLC_VRULES, 1). -% From define::From listbook.h +% From "listbase.h": wxListColumnFormat +-define(wxLIST_FORMAT_LEFT, 0). +-define(wxLIST_FORMAT_RIGHT, 1). +-define(wxLIST_FORMAT_CENTRE, 2). +-define(wxLIST_FORMAT_CENTER, ?wxLIST_FORMAT_CENTRE). +% From "listbook.h" -define(wxLB_ALIGN_MASK, ?wxBK_ALIGN_MASK). -define(wxLB_RIGHT, ?wxBK_RIGHT). -define(wxLB_LEFT, ?wxBK_LEFT). -define(wxLB_BOTTOM, ?wxBK_BOTTOM). -define(wxLB_TOP, ?wxBK_TOP). -define(wxLB_DEFAULT, ?wxBK_DEFAULT). -% From define::From log.h +% From "log.h" -define(wxTRACE_OleCalls, ?wxEmptyString). -define(wxTraceRefCount, 8). -define(wxTraceResAlloc, 4). -define(wxTraceMessages, 2). -define(wxTraceMemAlloc, 1). -% From define::From notebook.h +% From "notebook.h" +-define(wxNB_HITTEST_NOWHERE, ?wxBK_HITTEST_NOWHERE). +-define(wxNB_HITTEST_ONICON, ?wxBK_HITTEST_ONICON). +-define(wxNB_HITTEST_ONLABEL, ?wxBK_HITTEST_ONLABEL). +-define(wxNB_HITTEST_ONITEM, ?wxBK_HITTEST_ONITEM). +-define(wxNB_HITTEST_ONPAGE, ?wxBK_HITTEST_ONPAGE). +% From "notebook.h" -define(wxNB_FLAT, 2048). -define(wxNB_NOPAGETHEME, 1024). -define(wxNB_MULTILINE, 512). @@ -652,9 +2064,9 @@ -define(wxNB_BOTTOM, ?wxBK_BOTTOM). -define(wxNB_TOP, ?wxBK_TOP). -define(wxNB_DEFAULT, ?wxBK_DEFAULT). -% From define::From pickerbase.h +% From "pickerbase.h" -define(wxPB_USE_TEXTCTRL, 2). -% From define::From prntbase.h +% From "prntbase.h" -define(wxID_PREVIEW_GOTO, 8). -define(wxID_PREVIEW_LAST, 7). -define(wxID_PREVIEW_FIRST, 6). @@ -671,7 +2083,11 @@ -define(wxPREVIEW_NEXT, 4). -define(wxPREVIEW_PREVIOUS, 2). -define(wxPREVIEW_PRINT, 1). -% From define::From progdlg.h +% From "prntbase.h": wxPrinterError +-define(wxPRINTER_NO_ERROR, 0). +-define(wxPRINTER_CANCELLED, 1). +-define(wxPRINTER_ERROR, 2). +% From "progdlg.h" -define(wxPD_CAN_SKIP, 128). -define(wxPD_REMAINING_TIME, 64). -define(wxPD_SMOOTH, 32). @@ -680,9 +2096,121 @@ -define(wxPD_AUTO_HIDE, 4). -define(wxPD_APP_MODAL, 2). -define(wxPD_CAN_ABORT, 1). -% From define::From scrolwin.h +% From "region.h": wxRegionContain +-define(wxOutRegion, 0). +-define(wxPartRegion, 1). +-define(wxInRegion, 2). +% From "region.h": wxRegionOp +-define(wxRGN_AND, 0). +-define(wxRGN_COPY, 1). +-define(wxRGN_DIFF, 2). +-define(wxRGN_OR, 3). +-define(wxRGN_XOR, 4). +% From "scrolwin.h" -define(wxScrolledWindowStyle, (?wxHSCROLL bor ?wxVSCROLL)). -% From define::From slider.h +% From "settings.h": wxSystemColour +-define(wxSYS_COLOUR_SCROLLBAR, 0). +-define(wxSYS_COLOUR_BACKGROUND, 1). +-define(wxSYS_COLOUR_DESKTOP, ?wxSYS_COLOUR_BACKGROUND). +-define(wxSYS_COLOUR_ACTIVECAPTION, (?wxSYS_COLOUR_BACKGROUND+1)). +-define(wxSYS_COLOUR_INACTIVECAPTION, (?wxSYS_COLOUR_BACKGROUND+2)). +-define(wxSYS_COLOUR_MENU, (?wxSYS_COLOUR_BACKGROUND+3)). +-define(wxSYS_COLOUR_WINDOW, (?wxSYS_COLOUR_BACKGROUND+4)). +-define(wxSYS_COLOUR_WINDOWFRAME, (?wxSYS_COLOUR_BACKGROUND+5)). +-define(wxSYS_COLOUR_MENUTEXT, (?wxSYS_COLOUR_BACKGROUND+6)). +-define(wxSYS_COLOUR_WINDOWTEXT, (?wxSYS_COLOUR_BACKGROUND+7)). +-define(wxSYS_COLOUR_CAPTIONTEXT, (?wxSYS_COLOUR_BACKGROUND+8)). +-define(wxSYS_COLOUR_ACTIVEBORDER, (?wxSYS_COLOUR_BACKGROUND+9)). +-define(wxSYS_COLOUR_INACTIVEBORDER, (?wxSYS_COLOUR_BACKGROUND+10)). +-define(wxSYS_COLOUR_APPWORKSPACE, (?wxSYS_COLOUR_BACKGROUND+11)). +-define(wxSYS_COLOUR_HIGHLIGHT, (?wxSYS_COLOUR_BACKGROUND+12)). +-define(wxSYS_COLOUR_HIGHLIGHTTEXT, (?wxSYS_COLOUR_BACKGROUND+13)). +-define(wxSYS_COLOUR_BTNFACE, (?wxSYS_COLOUR_BACKGROUND+14)). +-define(wxSYS_COLOUR_3DFACE, ?wxSYS_COLOUR_BTNFACE). +-define(wxSYS_COLOUR_BTNSHADOW, (?wxSYS_COLOUR_BTNFACE+1)). +-define(wxSYS_COLOUR_3DSHADOW, ?wxSYS_COLOUR_BTNSHADOW). +-define(wxSYS_COLOUR_GRAYTEXT, (?wxSYS_COLOUR_BTNSHADOW+1)). +-define(wxSYS_COLOUR_BTNTEXT, (?wxSYS_COLOUR_BTNSHADOW+2)). +-define(wxSYS_COLOUR_INACTIVECAPTIONTEXT, (?wxSYS_COLOUR_BTNSHADOW+3)). +-define(wxSYS_COLOUR_BTNHIGHLIGHT, (?wxSYS_COLOUR_BTNSHADOW+4)). +-define(wxSYS_COLOUR_BTNHILIGHT, ?wxSYS_COLOUR_BTNHIGHLIGHT). +-define(wxSYS_COLOUR_3DHIGHLIGHT, ?wxSYS_COLOUR_BTNHIGHLIGHT). +-define(wxSYS_COLOUR_3DHILIGHT, ?wxSYS_COLOUR_BTNHIGHLIGHT). +-define(wxSYS_COLOUR_3DDKSHADOW, (?wxSYS_COLOUR_BTNHIGHLIGHT+1)). +-define(wxSYS_COLOUR_3DLIGHT, (?wxSYS_COLOUR_BTNHIGHLIGHT+2)). +-define(wxSYS_COLOUR_INFOTEXT, (?wxSYS_COLOUR_BTNHIGHLIGHT+3)). +-define(wxSYS_COLOUR_INFOBK, (?wxSYS_COLOUR_BTNHIGHLIGHT+4)). +-define(wxSYS_COLOUR_LISTBOX, (?wxSYS_COLOUR_BTNHIGHLIGHT+5)). +-define(wxSYS_COLOUR_HOTLIGHT, (?wxSYS_COLOUR_BTNHIGHLIGHT+6)). +-define(wxSYS_COLOUR_GRADIENTACTIVECAPTION, (?wxSYS_COLOUR_BTNHIGHLIGHT+7)). +-define(wxSYS_COLOUR_GRADIENTINACTIVECAPTION, (?wxSYS_COLOUR_BTNHIGHLIGHT+8)). +-define(wxSYS_COLOUR_MENUHILIGHT, (?wxSYS_COLOUR_BTNHIGHLIGHT+9)). +-define(wxSYS_COLOUR_MENUBAR, (?wxSYS_COLOUR_BTNHIGHLIGHT+10)). +-define(wxSYS_COLOUR_LISTBOXTEXT, (?wxSYS_COLOUR_BTNHIGHLIGHT+11)). +-define(wxSYS_COLOUR_MAX, (?wxSYS_COLOUR_BTNHIGHLIGHT+12)). +% From "settings.h": wxSystemFeature +-define(wxSYS_CAN_DRAW_FRAME_DECORATIONS, 1). +-define(wxSYS_CAN_ICONIZE_FRAME, 2). +-define(wxSYS_TABLET_PRESENT, 3). +% From "settings.h": wxSystemFont +-define(wxSYS_OEM_FIXED_FONT, 10). +-define(wxSYS_ANSI_FIXED_FONT, 11). +-define(wxSYS_ANSI_VAR_FONT, 12). +-define(wxSYS_SYSTEM_FONT, 13). +-define(wxSYS_DEVICE_DEFAULT_FONT, 14). +-define(wxSYS_DEFAULT_PALETTE, 15). +-define(wxSYS_SYSTEM_FIXED_FONT, 16). +-define(wxSYS_DEFAULT_GUI_FONT, 17). +-define(wxSYS_ICONTITLE_FONT, ?wxSYS_DEFAULT_GUI_FONT). +% From "settings.h": wxSystemMetric +-define(wxSYS_MOUSE_BUTTONS, 1). +-define(wxSYS_BORDER_X, 2). +-define(wxSYS_BORDER_Y, 3). +-define(wxSYS_CURSOR_X, 4). +-define(wxSYS_CURSOR_Y, 5). +-define(wxSYS_DCLICK_X, 6). +-define(wxSYS_DCLICK_Y, 7). +-define(wxSYS_DRAG_X, 8). +-define(wxSYS_DRAG_Y, 9). +-define(wxSYS_EDGE_X, 10). +-define(wxSYS_EDGE_Y, 11). +-define(wxSYS_HSCROLL_ARROW_X, 12). +-define(wxSYS_HSCROLL_ARROW_Y, 13). +-define(wxSYS_HTHUMB_X, 14). +-define(wxSYS_ICON_X, 15). +-define(wxSYS_ICON_Y, 16). +-define(wxSYS_ICONSPACING_X, 17). +-define(wxSYS_ICONSPACING_Y, 18). +-define(wxSYS_WINDOWMIN_X, 19). +-define(wxSYS_WINDOWMIN_Y, 20). +-define(wxSYS_SCREEN_X, 21). +-define(wxSYS_SCREEN_Y, 22). +-define(wxSYS_FRAMESIZE_X, 23). +-define(wxSYS_FRAMESIZE_Y, 24). +-define(wxSYS_SMALLICON_X, 25). +-define(wxSYS_SMALLICON_Y, 26). +-define(wxSYS_HSCROLL_Y, 27). +-define(wxSYS_VSCROLL_X, 28). +-define(wxSYS_VSCROLL_ARROW_X, 29). +-define(wxSYS_VSCROLL_ARROW_Y, 30). +-define(wxSYS_VTHUMB_Y, 31). +-define(wxSYS_CAPTION_Y, 32). +-define(wxSYS_MENU_Y, 33). +-define(wxSYS_NETWORK_PRESENT, 34). +-define(wxSYS_PENWINDOWS_PRESENT, 35). +-define(wxSYS_SHOW_SOUNDS, 36). +-define(wxSYS_SWAP_BUTTONS, 37). +% From "settings.h": wxSystemScreenType +-define(wxSYS_SCREEN_NONE, 0). +-define(wxSYS_SCREEN_TINY, 1). +-define(wxSYS_SCREEN_PDA, 2). +-define(wxSYS_SCREEN_SMALL, 3). +-define(wxSYS_SCREEN_DESKTOP, 4). +% From "sizer.h": wxFlexSizerGrowMode +-define(wxFLEX_GROWMODE_NONE, 0). +-define(wxFLEX_GROWMODE_SPECIFIED, 1). +-define(wxFLEX_GROWMODE_ALL, 2). +% From "slider.h" -define(wxSL_INVERSE, 4096). -define(wxSL_SELRANGE, 2048). -define(wxSL_BOTH, 1024). @@ -695,7 +2223,7 @@ -define(wxSL_TICKS, 16). -define(wxSL_VERTICAL, ?wxVERTICAL). -define(wxSL_HORIZONTAL, ?wxHORIZONTAL). -% From define::From splitter.h +% From "splitter.h" -define(wxSP_3D, (?wxSP_3DBORDER bor ?wxSP_3DSASH)). -define(wxSP_BORDER, ?wxSP_3DBORDER). -define(wxSP_NO_XP_THEME, 1024). @@ -705,11 +2233,11 @@ -define(wxSP_PERMIT_UNSPLIT, 64). -define(wxSP_NOSASH, 16). -define(wxSP_NOBORDER, 0). -% From define::From statusbr.h +% From "statusbr.h" -define(wxSB_RAISED, 2). -define(wxSB_FLAT, 1). -define(wxSB_NORMAL, 0). -% From define::From stc.h +% From "stc.h" -define(wxSTC_CMD_WORDRIGHTENDEXTEND, 2442). -define(wxSTC_CMD_WORDRIGHTEND, 2441). -define(wxSTC_CMD_WORDLEFTENDEXTEND, 2440). @@ -2045,7 +3573,11 @@ -define(wxSTC_START, 2000). -define(wxSTC_INVALID_POSITION, -1). -define(wxSTC_USE_POPUP, 1). -% From define::From textctrl.h +% From "tbarbase.h": wxToolBarToolStyle +-define(wxTOOL_STYLE_BUTTON, 1). +-define(wxTOOL_STYLE_SEPARATOR, 2). +-define(wxTOOL_STYLE_CONTROL, 3). +% From "textctrl.h" -define(wxTEXT_ATTR_TABS, 1024). -define(wxTEXT_ATTR_RIGHT_INDENT, 512). -define(wxTEXT_ATTR_LEFT_INDENT, 256). @@ -2080,11 +3612,51 @@ -define(wxTE_AUTO_SCROLL, 8). -define(wxTE_NO_VSCROLL, 2). -define(wxHAS_TEXT_WINDOW_STREAM, 0). -% From define::From textdlgg.h +% From "textctrl.h": wxTextAttrAlignment +-define(wxTEXT_ALIGNMENT_DEFAULT, 0). +-define(wxTEXT_ALIGNMENT_LEFT, 1). +-define(wxTEXT_ALIGNMENT_CENTRE, 2). +-define(wxTEXT_ALIGNMENT_CENTER, ?wxTEXT_ALIGNMENT_CENTRE). +-define(wxTEXT_ALIGNMENT_RIGHT, (?wxTEXT_ALIGNMENT_CENTRE+1)). +-define(wxTEXT_ALIGNMENT_JUSTIFIED, (?wxTEXT_ALIGNMENT_CENTRE+2)). +% From "textctrl.h": wxTextCtrlHitTestResult +-define(wxTE_HT_UNKNOWN, -2). +-define(wxTE_HT_BEFORE, -1). +-define(wxTE_HT_ON_TEXT, 0). +-define(wxTE_HT_BELOW, 1). +-define(wxTE_HT_BEYOND, 2). +% From "textdlgg.h" -define(wxTextEntryDialogStyle, (?wxOK bor ?wxCANCEL bor ?wxCENTRE bor ?wxWS_EX_VALIDATE_RECURSIVELY)). -% From define::From toolbook.h +% From "toolbar.h" +-define(wxTB_HORIZONTAL, ?wxHORIZONTAL). +-define(wxTB_TOP, ?wxTB_HORIZONTAL). +-define(wxTB_VERTICAL, ?wxVERTICAL). +-define(wxTB_LEFT, ?wxTB_VERTICAL). +-define(wxTB_3DBUTTONS, 16). +-define(wxTB_FLAT, 32). +-define(wxTB_DOCKABLE, 64). +-define(wxTB_NOICONS, 128). +-define(wxTB_TEXT, 256). +-define(wxTB_NODIVIDER, 512). +-define(wxTB_NOALIGN, 1024). +-define(wxTB_HORZ_LAYOUT, 2048). +-define(wxTB_HORZ_TEXT, (?wxTB_HORZ_LAYOUT bor ?wxTB_TEXT)). +-define(wxTB_NO_TOOLTIPS, 4096). +-define(wxTB_BOTTOM, 8192). +-define(wxTB_RIGHT, 16384). +% From "toolbook.h" -define(wxBK_BUTTONBAR, 256). -% From define::From toplevel.h +% From "toplevel.h" +-define(wxFULLSCREEN_NOMENUBAR, 1). +-define(wxFULLSCREEN_NOTOOLBAR, 2). +-define(wxFULLSCREEN_NOSTATUSBAR, 4). +-define(wxFULLSCREEN_NOBORDER, 8). +-define(wxFULLSCREEN_NOCAPTION, 16). +-define(wxFULLSCREEN_ALL, (?wxFULLSCREEN_NOMENUBAR bor ?wxFULLSCREEN_NOTOOLBAR bor ?wxFULLSCREEN_NOSTATUSBAR bor ?wxFULLSCREEN_NOBORDER bor ?wxFULLSCREEN_NOCAPTION)). +% From "toplevel.h" +-define(wxUSER_ATTENTION_INFO, 1). +-define(wxUSER_ATTENTION_ERROR, 2). +% From "toplevel.h" -define(wxTOPLEVEL_EX_DIALOG, 8). -define(wxDEFAULT_FRAME_STYLE, (?wxSYSTEM_MENU bor ?wxRESIZE_BORDER bor ?wxMINIMIZE_BOX bor ?wxMAXIMIZE_BOX bor ?wxCLOSE_BOX bor ?wxCAPTION bor ?wxCLIP_CHILDREN)). -define(wxRESIZE_BORDER, 64). @@ -2098,8 +3670,8 @@ -define(wxMINIMIZE, ?wxICONIZE). -define(wxICONIZE, 16384). -define(wxSTAY_ON_TOP, 32768). -% From define::From treebase.h --define(wxTR_DEFAULT_STYLE, (?wxTR_HAS_BUTTONS bor ?wxTR_LINES_AT_ROOT)). +% From "treebase.h" +-define(wxTR_DEFAULT_STYLE, wxe_util:get_const(wxTR_DEFAULT_STYLE)). -define(wxTR_FULL_ROW_HIGHLIGHT, 8192). -define(wxTR_HIDE_ROOT, 2048). -define(wxTR_ROW_LINES, 1024). @@ -2113,1416 +3685,37 @@ -define(wxTR_NO_LINES, 4). -define(wxTR_HAS_BUTTONS, 1). -define(wxTR_NO_BUTTONS, 0). -% From define::From valtext.h --define(wxFILTER_EXCLUDE_CHAR_LIST, 128). --define(wxFILTER_INCLUDE_CHAR_LIST, 64). --define(wxFILTER_EXCLUDE_LIST, 32). --define(wxFILTER_INCLUDE_LIST, 16). --define(wxFILTER_NUMERIC, 8). --define(wxFILTER_ALPHANUMERIC, 4). --define(wxFILTER_ALPHA, 2). --define(wxFILTER_ASCII, 1). --define(wxFILTER_NONE, 0). -% From define::From version.h --define(wxBETA_NUMBER, wxe_util:get_const(wxBETA_NUMBER)). --define(wxSUBRELEASE_NUMBER, wxe_util:get_const(wxSUBRELEASE_NUMBER)). --define(wxRELEASE_NUMBER, wxe_util:get_const(wxRELEASE_NUMBER)). --define(wxMINOR_VERSION, wxe_util:get_const(wxMINOR_VERSION)). --define(wxMAJOR_VERSION, wxe_util:get_const(wxMAJOR_VERSION)). -% From class wxAuiManager --define(wxAuiManager_actionNone, 0). --define(wxAuiManager_actionResize, 1). --define(wxAuiManager_actionClickButton, 2). --define(wxAuiManager_actionClickCaption, 3). --define(wxAuiManager_actionDragToolbarPane, 4). --define(wxAuiManager_actionDragFloatingPane, 5). -% From wxAuiPaneInfo::wxAuiPaneState --define(wxAuiPaneInfo_optionFloating, 1). --define(wxAuiPaneInfo_optionHidden, 2). --define(wxAuiPaneInfo_optionLeftDockable, 4). --define(wxAuiPaneInfo_optionRightDockable, 8). --define(wxAuiPaneInfo_optionTopDockable, 16). --define(wxAuiPaneInfo_optionBottomDockable, 32). --define(wxAuiPaneInfo_optionFloatable, 64). --define(wxAuiPaneInfo_optionMovable, 128). --define(wxAuiPaneInfo_optionResizable, 256). --define(wxAuiPaneInfo_optionPaneBorder, 512). --define(wxAuiPaneInfo_optionCaption, 1024). --define(wxAuiPaneInfo_optionGripper, 2048). --define(wxAuiPaneInfo_optionDestroyOnClose, 4096). --define(wxAuiPaneInfo_optionToolbar, 8192). --define(wxAuiPaneInfo_optionActive, 16384). --define(wxAuiPaneInfo_optionGripperTop, 32768). --define(wxAuiPaneInfo_optionMaximized, 65536). --define(wxAuiPaneInfo_optionDockFixed, 131072). --define(wxAuiPaneInfo_buttonClose, 2097152). --define(wxAuiPaneInfo_buttonMaximize, 4194304). --define(wxAuiPaneInfo_buttonMinimize, 8388608). --define(wxAuiPaneInfo_buttonPin, 16777216). --define(wxAuiPaneInfo_buttonCustom1, 67108864). --define(wxAuiPaneInfo_buttonCustom2, 134217728). --define(wxAuiPaneInfo_buttonCustom3, 268435456). --define(wxAuiPaneInfo_savedHiddenState, 1073741824). --define(wxAuiPaneInfo_actionPane, 2147483648). -% From wxBitmap::Representation --define(wxBitmap_Pixmap, 0). --define(wxBitmap_Pixbuf, 1). -% From class wxChoicebook --define(wxChoicebook_SetSelection_SendEvent, 1). -% From wxDateTime::Calendar --define(wxDateTime_Gregorian, 0). --define(wxDateTime_Julian, 1). -% From wxDateTime::Country --define(wxDateTime_Country_Unknown, 0). --define(wxDateTime_Country_Default, 1). --define(wxDateTime_Country_WesternEurope_Start, 2). --define(wxDateTime_Country_EEC, ?Country_WesternEurope_Start). --define(wxDateTime_France, (?Country_WesternEurope_Start+1)). --define(wxDateTime_Germany, (?Country_WesternEurope_Start+2)). --define(wxDateTime_UK, (?Country_WesternEurope_Start+3)). --define(wxDateTime_Country_WesternEurope_End, ?UK). --define(wxDateTime_Russia, (?UK+1)). --define(wxDateTime_USA, (?UK+2)). -% From wxDateTime::GregorianAdoption --define(wxDateTime_Gr_Unknown, 0). --define(wxDateTime_Gr_Standard, 1). --define(wxDateTime_Gr_Alaska, 2). --define(wxDateTime_Gr_Albania, 3). --define(wxDateTime_Gr_Austria, ?Gr_Unknown). --define(wxDateTime_Gr_Austria_Brixen, (?Gr_Unknown+1)). --define(wxDateTime_Gr_Austria_Salzburg, ?Gr_Austria_Brixen). --define(wxDateTime_Gr_Austria_Tyrol, ?Gr_Austria_Brixen). --define(wxDateTime_Gr_Austria_Carinthia, (?Gr_Austria_Brixen+1)). --define(wxDateTime_Gr_Austria_Styria, ?Gr_Austria_Carinthia). --define(wxDateTime_Gr_Belgium, (?Gr_Austria_Carinthia+1)). --define(wxDateTime_Gr_Bulgaria, ?Gr_Unknown). --define(wxDateTime_Gr_Bulgaria_1, (?Gr_Unknown+1)). --define(wxDateTime_Gr_Bulgaria_2, (?Gr_Unknown+2)). --define(wxDateTime_Gr_Bulgaria_3, (?Gr_Unknown+3)). --define(wxDateTime_Gr_Canada, ?Gr_Unknown). --define(wxDateTime_Gr_China, ?Gr_Unknown). --define(wxDateTime_Gr_China_1, (?Gr_Unknown+1)). --define(wxDateTime_Gr_China_2, (?Gr_Unknown+2)). --define(wxDateTime_Gr_Czechoslovakia, (?Gr_Unknown+3)). --define(wxDateTime_Gr_Denmark, (?Gr_Unknown+4)). --define(wxDateTime_Gr_Egypt, (?Gr_Unknown+5)). --define(wxDateTime_Gr_Estonia, (?Gr_Unknown+6)). --define(wxDateTime_Gr_Finland, (?Gr_Unknown+7)). --define(wxDateTime_Gr_France, (?Gr_Unknown+8)). --define(wxDateTime_Gr_France_Alsace, (?Gr_Unknown+9)). --define(wxDateTime_Gr_France_Lorraine, (?Gr_Unknown+10)). --define(wxDateTime_Gr_France_Strasbourg, (?Gr_Unknown+11)). --define(wxDateTime_Gr_Germany, ?Gr_Unknown). --define(wxDateTime_Gr_Germany_Catholic, (?Gr_Unknown+1)). --define(wxDateTime_Gr_Germany_Prussia, (?Gr_Unknown+2)). --define(wxDateTime_Gr_Germany_Protestant, (?Gr_Unknown+3)). --define(wxDateTime_Gr_GreatBritain, (?Gr_Unknown+4)). --define(wxDateTime_Gr_Greece, (?Gr_Unknown+5)). --define(wxDateTime_Gr_Hungary, (?Gr_Unknown+6)). --define(wxDateTime_Gr_Ireland, ?Gr_GreatBritain). --define(wxDateTime_Gr_Italy, ?Gr_Standard). --define(wxDateTime_Gr_Japan, ?Gr_Unknown). --define(wxDateTime_Gr_Japan_1, (?Gr_Unknown+1)). --define(wxDateTime_Gr_Japan_2, (?Gr_Unknown+2)). --define(wxDateTime_Gr_Japan_3, (?Gr_Unknown+3)). --define(wxDateTime_Gr_Latvia, (?Gr_Unknown+4)). --define(wxDateTime_Gr_Lithuania, (?Gr_Unknown+5)). --define(wxDateTime_Gr_Luxemburg, (?Gr_Unknown+6)). --define(wxDateTime_Gr_Netherlands, ?Gr_Belgium). --define(wxDateTime_Gr_Netherlands_Groningen, (?Gr_Belgium+1)). --define(wxDateTime_Gr_Netherlands_Gelderland, (?Gr_Belgium+2)). --define(wxDateTime_Gr_Netherlands_Utrecht, (?Gr_Belgium+3)). --define(wxDateTime_Gr_Netherlands_Friesland, (?Gr_Belgium+4)). --define(wxDateTime_Gr_Norway, ?Gr_Denmark). --define(wxDateTime_Gr_Poland, ?Gr_Standard). --define(wxDateTime_Gr_Portugal, ?Gr_Standard). --define(wxDateTime_Gr_Romania, (?Gr_Standard+1)). --define(wxDateTime_Gr_Russia, (?Gr_Standard+2)). --define(wxDateTime_Gr_Scotland, ?Gr_GreatBritain). --define(wxDateTime_Gr_Spain, ?Gr_Standard). --define(wxDateTime_Gr_Sweden, ?Gr_Finland). --define(wxDateTime_Gr_Switzerland, ?Gr_Unknown). --define(wxDateTime_Gr_Switzerland_Catholic, (?Gr_Unknown+1)). --define(wxDateTime_Gr_Switzerland_Protestant, (?Gr_Unknown+2)). --define(wxDateTime_Gr_Turkey, (?Gr_Unknown+3)). --define(wxDateTime_Gr_USA, ?Gr_GreatBritain). --define(wxDateTime_Gr_Wales, ?Gr_GreatBritain). --define(wxDateTime_Gr_Yugoslavia, (?Gr_GreatBritain+1)). -% From wxDateTime::Month --define(wxDateTime_Jan, 0). --define(wxDateTime_Feb, 1). --define(wxDateTime_Mar, 2). --define(wxDateTime_Apr, 3). --define(wxDateTime_May, 4). --define(wxDateTime_Jun, 5). --define(wxDateTime_Jul, 6). --define(wxDateTime_Aug, 7). --define(wxDateTime_Sep, 8). --define(wxDateTime_Oct, 9). --define(wxDateTime_Nov, 10). --define(wxDateTime_Dec, 11). --define(wxDateTime_Inv_Month, 12). -% From wxDateTime::NameFlags --define(wxDateTime_Name_Full, 1). --define(wxDateTime_Name_Abbr, 2). -% From wxDateTime::TZ --define(wxDateTime_Local, 0). --define(wxDateTime_GMT_12, 1). --define(wxDateTime_GMT_11, 2). --define(wxDateTime_GMT_10, 3). --define(wxDateTime_GMT_9, 4). --define(wxDateTime_GMT_8, 5). --define(wxDateTime_GMT_7, 6). --define(wxDateTime_GMT_6, 7). --define(wxDateTime_GMT_5, 8). --define(wxDateTime_GMT_4, 9). --define(wxDateTime_GMT_3, 10). --define(wxDateTime_GMT_2, 11). --define(wxDateTime_GMT_1, 12). --define(wxDateTime_GMT0, 13). --define(wxDateTime_GMT1, 14). --define(wxDateTime_GMT2, 15). --define(wxDateTime_GMT3, 16). --define(wxDateTime_GMT4, 17). --define(wxDateTime_GMT5, 18). --define(wxDateTime_GMT6, 19). --define(wxDateTime_GMT7, 20). --define(wxDateTime_GMT8, 21). --define(wxDateTime_GMT9, 22). --define(wxDateTime_GMT10, 23). --define(wxDateTime_GMT11, 24). --define(wxDateTime_GMT12, 25). --define(wxDateTime_GMT13, 26). --define(wxDateTime_WET, ?GMT0). --define(wxDateTime_WEST, ?GMT1). --define(wxDateTime_CET, ?GMT1). --define(wxDateTime_CEST, ?GMT2). --define(wxDateTime_EET, ?GMT2). --define(wxDateTime_EEST, ?GMT3). --define(wxDateTime_MSK, ?GMT3). --define(wxDateTime_MSD, ?GMT4). --define(wxDateTime_AST, ?GMT_4). --define(wxDateTime_ADT, ?GMT_3). --define(wxDateTime_EST, ?GMT_5). --define(wxDateTime_EDT, ?GMT_4). --define(wxDateTime_CST, ?GMT_6). --define(wxDateTime_CDT, ?GMT_5). --define(wxDateTime_MST, ?GMT_7). --define(wxDateTime_MDT, ?GMT_6). --define(wxDateTime_PST, ?GMT_8). --define(wxDateTime_PDT, ?GMT_7). --define(wxDateTime_HST, ?GMT_10). --define(wxDateTime_AKST, ?GMT_9). --define(wxDateTime_AKDT, ?GMT_8). --define(wxDateTime_A_WST, ?GMT8). --define(wxDateTime_A_CST, ?GMT13+1). --define(wxDateTime_A_EST, ?GMT10). --define(wxDateTime_A_ESST, ?GMT11). --define(wxDateTime_NZST, ?GMT12). --define(wxDateTime_NZDT, ?GMT13). --define(wxDateTime_UTC, ?GMT0). -% From wxDateTime::WeekDay --define(wxDateTime_Sun, 0). --define(wxDateTime_Mon, 1). --define(wxDateTime_Tue, 2). --define(wxDateTime_Wed, 3). --define(wxDateTime_Thu, 4). --define(wxDateTime_Fri, 5). --define(wxDateTime_Sat, 6). --define(wxDateTime_Inv_WeekDay, 7). -% From wxDateTime::WeekFlags --define(wxDateTime_Default_First, 0). --define(wxDateTime_Monday_First, 1). --define(wxDateTime_Sunday_First, 2). -% From wxDateTime::Year --define(wxDateTime_Inv_Year, ?SHRT_MIN). -% From class wxDialog --define(wxDialog_ButtonSizerFlags, (?wxOK bor ?wxCANCEL bor ?wxYES bor ?wxNO bor ?wxHELP bor ?wxNO_DEFAULT)). -% From class wxGrid --define(wxGrid_wxGRID_CELLCTRL, 2000). --define(wxGrid_wxGRID_TOPCTRL, 2001). -% From class wxGrid --define(wxGrid_wxGRID_TEXTCTRL, 2100). --define(wxGrid_wxGRID_CHECKBOX, 2101). --define(wxGrid_wxGRID_CHOICE, 2102). --define(wxGrid_wxGRID_COMBOBOX, 2103). -% From wxGrid::CursorMode --define(wxGrid_WXGRID_CURSOR_SELECT_CELL, 0). --define(wxGrid_WXGRID_CURSOR_RESIZE_ROW, 1). --define(wxGrid_WXGRID_CURSOR_RESIZE_COL, 2). --define(wxGrid_WXGRID_CURSOR_SELECT_ROW, 3). --define(wxGrid_WXGRID_CURSOR_SELECT_COL, 4). --define(wxGrid_WXGRID_CURSOR_MOVE_COL, 5). -% From wxGrid::wxGridSelectionModes --define(wxGrid_wxGridSelectCells, 0). --define(wxGrid_wxGridSelectRows, 1). --define(wxGrid_wxGridSelectColumns, 2). -% From wxGridCellAttr::wxAttrKind --define(wxGridCellAttr_Any, 0). --define(wxGridCellAttr_Default, 1). --define(wxGridCellAttr_Cell, 2). --define(wxGridCellAttr_Row, 3). --define(wxGridCellAttr_Col, 4). --define(wxGridCellAttr_Merged, 5). -% From wxGridCellAttr::wxAttrOverflowMode --define(wxGridCellAttr_UnsetOverflow, -1). --define(wxGridCellAttr_Overflow, 0). --define(wxGridCellAttr_SingleCell, 1). -% From wxGridCellAttr::wxAttrReadMode --define(wxGridCellAttr_Unset, -1). --define(wxGridCellAttr_ReadWrite, 0). --define(wxGridCellAttr_ReadOnly, 1). -% From wxHelpEvent::Origin --define(wxHelpEvent_Origin_Unknown, 0). --define(wxHelpEvent_Origin_Keyboard, 1). --define(wxHelpEvent_Origin_HelpButton, 2). -% From wxHtmlEasyPrinting::FontMode --define(wxHtmlEasyPrinting_FontMode_Explicit, 0). --define(wxHtmlEasyPrinting_FontMode_Standard, 1). -% From wxHtmlWindow::ClipboardType --define(wxHtmlWindow_Primary, 0). --define(wxHtmlWindow_Secondary, 1). -% From class wxListbook --define(wxListbook_SetSelection_SendEvent, 1). -% From class wxNavigationKeyEvent --define(wxNavigationKeyEvent_IsBackward, 0). --define(wxNavigationKeyEvent_IsForward, 1). --define(wxNavigationKeyEvent_WinChange, 2). --define(wxNavigationKeyEvent_FromTab, 4). -% From class wxNotebook --define(wxNotebook_SetSelection_SendEvent, 1). -% From class wxProgressDialog --define(wxProgressDialog_Uncancelable, -1). --define(wxProgressDialog_Canceled, 0). --define(wxProgressDialog_Continue, 1). --define(wxProgressDialog_Finished, 2). -% From class wxSizerItem --define(wxSizerItem_Item_None, 0). --define(wxSizerItem_Item_Window, 1). --define(wxSizerItem_Item_Sizer, 2). --define(wxSizerItem_Item_Spacer, 3). --define(wxSizerItem_Item_Max, 4). -% From class wxTextCtrl --define(wxTextCtrl_SetValue_SendEvent, 1). --define(wxTextCtrl_SetValue_SelectionOnly, 2). -% From class wxToolbook --define(wxToolbook_SetSelection_SendEvent, 1). -% From class wxTreebook --define(wxTreebook_SetSelection_SendEvent, 1). -% From wxWindow::MoveKind --define(wxWindow_MoveBefore, 0). --define(wxWindow_MoveAfter, 1). -% From wxWindowGTK::ScrollDir --define(wxWindowGTK_ScrollDir_Horz, 0). --define(wxWindowGTK_ScrollDir_Vert, 1). --define(wxWindowGTK_ScrollDir_Max, 2). -% From wxWindowGTK::ScrollUnit --define(wxWindowGTK_ScrollUnit_Line, 0). --define(wxWindowGTK_ScrollUnit_Page, 1). --define(wxWindowGTK_ScrollUnit_Max, 2). --define(wxACCEL_NORMAL, 0). --define(wxACCEL_ALT, 1). --define(wxACCEL_CTRL, 2). --define(wxACCEL_SHIFT, 4). --define(wxACCEL_CMD, ?wxACCEL_CTRL). --define(wxPRINT_WINDOWS, 1). --define(wxPRINT_POSTSCRIPT, 2). --define(wxBK_HITTEST_NOWHERE, 1). --define(wxBK_HITTEST_ONICON, 2). --define(wxBK_HITTEST_ONLABEL, 4). --define(wxBK_HITTEST_ONITEM, (?wxBK_HITTEST_ONICON bor ?wxBK_HITTEST_ONLABEL)). --define(wxBK_HITTEST_ONPAGE, 8). --define(wxCAL_SUNDAY_FIRST, 0). --define(wxCAL_MONDAY_FIRST, 1). --define(wxCAL_SHOW_HOLIDAYS, 2). --define(wxCAL_NO_YEAR_CHANGE, 4). --define(wxCAL_NO_MONTH_CHANGE, 12). --define(wxCAL_SEQUENTIAL_MONTH_SELECTION, 16). --define(wxCAL_SHOW_SURROUNDING_WEEKS, 32). --define(wxDP_DEFAULT, 0). --define(wxDP_SPIN, 1). --define(wxDP_DROPDOWN, 2). --define(wxDP_SHOWCENTURY, 4). --define(wxDP_ALLOWNONE, 8). --define(wxDefaultCoord, -1). --define(wxDIRCTRL_DIR_ONLY, 16). --define(wxDIRCTRL_SELECT_FIRST, 32). --define(wxDIRCTRL_SHOW_FILTERS, 64). --define(wxDIRCTRL_3D_INTERNAL, 128). --define(wxDIRCTRL_EDIT_LABELS, 256). --define(wxDrag_CopyOnly, 0). --define(wxDrag_AllowMove, 1). --define(wxDrag_DefaultMove, 3). --define(wxMOUSE_BTN_ANY, -1). --define(wxMOUSE_BTN_NONE, 0). --define(wxMOUSE_BTN_LEFT, 1). --define(wxMOUSE_BTN_MIDDLE, 2). --define(wxMOUSE_BTN_RIGHT, 3). --define(wxFD_OPEN, 1). --define(wxFD_SAVE, 2). --define(wxFD_OVERWRITE_PROMPT, 4). --define(wxFD_FILE_MUST_EXIST, 16). --define(wxFD_MULTIPLE, 32). --define(wxFD_CHANGE_DIR, 128). --define(wxFD_PREVIEW, 256). --define(wxFONTFLAG_DEFAULT, 0). --define(wxFONTFLAG_ITALIC, 1). --define(wxFONTFLAG_SLANT, 2). --define(wxFONTFLAG_LIGHT, 4). --define(wxFONTFLAG_BOLD, 8). --define(wxFONTFLAG_ANTIALIASED, 16). --define(wxFONTFLAG_NOT_ANTIALIASED, 32). --define(wxFONTFLAG_UNDERLINED, 64). --define(wxFONTFLAG_STRIKETHROUGH, 128). --define(wxFONTFLAG_MASK, (?wxFONTFLAG_ITALIC bor ?wxFONTFLAG_SLANT bor ?wxFONTFLAG_LIGHT bor ?wxFONTFLAG_BOLD bor ?wxFONTFLAG_ANTIALIASED bor ?wxFONTFLAG_NOT_ANTIALIASED bor ?wxFONTFLAG_UNDERLINED bor ?wxFONTFLAG_STRIKETHROUGH)). --define(wxSPLIT_DRAG_NONE, 0). --define(wxSPLIT_DRAG_DRAGGING, 1). --define(wxSPLIT_DRAG_LEFT_DOWN, 2). --define(WX_GL_RGBA, 1). --define(WX_GL_BUFFER_SIZE, 2). --define(WX_GL_LEVEL, 3). --define(WX_GL_DOUBLEBUFFER, 4). --define(WX_GL_STEREO, 5). --define(WX_GL_AUX_BUFFERS, 6). --define(WX_GL_MIN_RED, 7). --define(WX_GL_MIN_GREEN, 8). --define(WX_GL_MIN_BLUE, 9). --define(WX_GL_MIN_ALPHA, 10). --define(WX_GL_DEPTH_SIZE, 11). --define(WX_GL_STENCIL_SIZE, 12). --define(WX_GL_MIN_ACCUM_RED, 13). --define(WX_GL_MIN_ACCUM_GREEN, 14). --define(WX_GL_MIN_ACCUM_BLUE, 15). --define(WX_GL_MIN_ACCUM_ALPHA, 16). --define(wxPAGE_ODD, 0). --define(wxPAGE_EVEN, 1). --define(wxPAGE_ALL, 2). --define(wxBMP_24BPP, 24). --define(wxBMP_8BPP, 8). --define(wxBMP_8BPP_GREY, 9). --define(wxBMP_8BPP_GRAY, ?wxBMP_8BPP_GREY). --define(wxBMP_8BPP_RED, 10). --define(wxBMP_8BPP_PALETTE, 11). --define(wxBMP_4BPP, 4). --define(wxBMP_1BPP, 1). --define(wxBMP_1BPP_BW, 2). --define(wxIMAGE_RESOLUTION_INCHES, 1). --define(wxIMAGE_RESOLUTION_CM, 2). --define(wxIMAGE_LIST_NORMAL, 0). --define(wxIMAGE_LIST_SMALL, 1). --define(wxIMAGE_LIST_STATE, 2). --define(wxLIST_NEXT_ABOVE, 0). --define(wxLIST_NEXT_ALL, 1). --define(wxLIST_NEXT_BELOW, 2). --define(wxLIST_NEXT_LEFT, 3). --define(wxLIST_NEXT_RIGHT, 4). --define(wxNB_HITTEST_NOWHERE, ?wxBK_HITTEST_NOWHERE). --define(wxNB_HITTEST_ONICON, ?wxBK_HITTEST_ONICON). --define(wxNB_HITTEST_ONLABEL, ?wxBK_HITTEST_ONLABEL). --define(wxNB_HITTEST_ONITEM, ?wxBK_HITTEST_ONITEM). --define(wxNB_HITTEST_ONPAGE, ?wxBK_HITTEST_ONPAGE). --define(wxTB_HORIZONTAL, ?wxHORIZONTAL). --define(wxTB_TOP, ?wxTB_HORIZONTAL). --define(wxTB_VERTICAL, ?wxVERTICAL). --define(wxTB_LEFT, ?wxTB_VERTICAL). --define(wxTB_3DBUTTONS, 16). --define(wxTB_FLAT, 32). --define(wxTB_DOCKABLE, 64). --define(wxTB_NOICONS, 128). --define(wxTB_TEXT, 256). --define(wxTB_NODIVIDER, 512). --define(wxTB_NOALIGN, 1024). --define(wxTB_HORZ_LAYOUT, 2048). --define(wxTB_HORZ_TEXT, (?wxTB_HORZ_LAYOUT bor ?wxTB_TEXT)). --define(wxTB_NO_TOOLTIPS, 4096). --define(wxTB_BOTTOM, 8192). --define(wxTB_RIGHT, 16384). --define(wxFULLSCREEN_NOMENUBAR, 1). --define(wxFULLSCREEN_NOTOOLBAR, 2). --define(wxFULLSCREEN_NOSTATUSBAR, 4). --define(wxFULLSCREEN_NOBORDER, 8). --define(wxFULLSCREEN_NOCAPTION, 16). --define(wxFULLSCREEN_ALL, (?wxFULLSCREEN_NOMENUBAR bor ?wxFULLSCREEN_NOTOOLBAR bor ?wxFULLSCREEN_NOSTATUSBAR bor ?wxFULLSCREEN_NOBORDER bor ?wxFULLSCREEN_NOCAPTION)). +% From "treebase.h": wxTreeItemIcon +-define(wxTreeItemIcon_Normal, 0). +-define(wxTreeItemIcon_Selected, 1). +-define(wxTreeItemIcon_Expanded, 2). +-define(wxTreeItemIcon_SelectedExpanded, 3). +-define(wxTreeItemIcon_Max, 4). +% From "utils.h" -define(wxEXEC_ASYNC, 0). -define(wxEXEC_SYNC, 1). -define(wxEXEC_NOHIDE, 2). -define(wxEXEC_MAKE_GROUP_LEADER, 4). -define(wxEXEC_NODISABLE, 8). --define(wxID_NONE, -3). --define(wxID_SEPARATOR, -2). --define(wxID_ANY, -1). --define(wxID_LOWEST, 4999). --define(wxID_OPEN, 5000). --define(wxID_CLOSE, 5001). --define(wxID_NEW, 5002). --define(wxID_SAVE, 5003). --define(wxID_SAVEAS, 5004). --define(wxID_REVERT, 5005). --define(wxID_EXIT, 5006). --define(wxID_UNDO, 5007). --define(wxID_REDO, 5008). --define(wxID_HELP, 5009). --define(wxID_PRINT, 5010). --define(wxID_PRINT_SETUP, 5011). --define(wxID_PAGE_SETUP, 5012). --define(wxID_PREVIEW, 5013). --define(wxID_ABOUT, 5014). --define(wxID_HELP_CONTENTS, 5015). --define(wxID_HELP_INDEX, 5016). --define(wxID_HELP_SEARCH, 5017). --define(wxID_HELP_COMMANDS, 5018). --define(wxID_HELP_PROCEDURES, 5019). --define(wxID_HELP_CONTEXT, 5020). --define(wxID_CLOSE_ALL, 5021). --define(wxID_PREFERENCES, 5022). --define(wxID_EDIT, 5030). --define(wxID_CUT, 5031). --define(wxID_COPY, 5032). --define(wxID_PASTE, 5033). --define(wxID_CLEAR, 5034). --define(wxID_FIND, 5035). --define(wxID_DUPLICATE, 5036). --define(wxID_SELECTALL, 5037). --define(wxID_DELETE, 5038). --define(wxID_REPLACE, 5039). --define(wxID_REPLACE_ALL, 5040). --define(wxID_PROPERTIES, 5041). --define(wxID_VIEW_DETAILS, 5042). --define(wxID_VIEW_LARGEICONS, 5043). --define(wxID_VIEW_SMALLICONS, 5044). --define(wxID_VIEW_LIST, 5045). --define(wxID_VIEW_SORTDATE, 5046). --define(wxID_VIEW_SORTNAME, 5047). --define(wxID_VIEW_SORTSIZE, 5048). --define(wxID_VIEW_SORTTYPE, 5049). --define(wxID_FILE, 5050). --define(wxID_FILE1, 5051). --define(wxID_FILE2, 5052). --define(wxID_FILE3, 5053). --define(wxID_FILE4, 5054). --define(wxID_FILE5, 5055). --define(wxID_FILE6, 5056). --define(wxID_FILE7, 5057). --define(wxID_FILE8, 5058). --define(wxID_FILE9, 5059). --define(wxID_OK, 5100). --define(wxID_CANCEL, 5101). --define(wxID_APPLY, 5102). --define(wxID_YES, 5103). --define(wxID_NO, 5104). --define(wxID_STATIC, 5105). --define(wxID_FORWARD, 5106). --define(wxID_BACKWARD, 5107). --define(wxID_DEFAULT, 5108). --define(wxID_MORE, 5109). --define(wxID_SETUP, 5110). --define(wxID_RESET, 5111). --define(wxID_CONTEXT_HELP, 5112). --define(wxID_YESTOALL, 5113). --define(wxID_NOTOALL, 5114). --define(wxID_ABORT, 5115). --define(wxID_RETRY, 5116). --define(wxID_IGNORE, 5117). --define(wxID_ADD, 5118). --define(wxID_REMOVE, 5119). --define(wxID_UP, 5120). --define(wxID_DOWN, 5121). --define(wxID_HOME, 5122). --define(wxID_REFRESH, 5123). --define(wxID_STOP, 5124). --define(wxID_INDEX, 5125). --define(wxID_BOLD, 5126). --define(wxID_ITALIC, 5127). --define(wxID_JUSTIFY_CENTER, 5128). --define(wxID_JUSTIFY_FILL, 5129). --define(wxID_JUSTIFY_RIGHT, 5130). --define(wxID_JUSTIFY_LEFT, 5131). --define(wxID_UNDERLINE, 5132). --define(wxID_INDENT, 5133). --define(wxID_UNINDENT, 5134). --define(wxID_ZOOM_100, 5135). --define(wxID_ZOOM_FIT, 5136). --define(wxID_ZOOM_IN, 5137). --define(wxID_ZOOM_OUT, 5138). --define(wxID_UNDELETE, 5139). --define(wxID_REVERT_TO_SAVED, 5140). --define(wxID_SYSTEM_MENU, 5200). --define(wxID_CLOSE_FRAME, 5201). --define(wxID_MOVE_FRAME, 5202). --define(wxID_RESIZE_FRAME, 5203). --define(wxID_MAXIMIZE_FRAME, 5204). --define(wxID_ICONIZE_FRAME, 5205). --define(wxID_RESTORE_FRAME, 5206). --define(wxID_FILEDLGG, 5900). --define(wxID_HIGHEST, 5999). --define(wxJOYSTICK1, 0). --define(wxJOYSTICK2, 1). --define(wxIMAGE_QUALITY_NORMAL, 0). --define(wxIMAGE_QUALITY_HIGH, 1). --define(wxLIST_ALIGN_DEFAULT, 0). --define(wxLIST_ALIGN_LEFT, 1). --define(wxLIST_ALIGN_TOP, 2). --define(wxLIST_ALIGN_SNAP_TO_GRID, 3). --define(wxUSER_ATTENTION_INFO, 1). --define(wxUSER_ATTENTION_ERROR, 2). +% From "utils.h" -define(wxBROWSER_NEW_WINDOW, 1). --define(wxDEFAULT, 70). --define(wxDECORATIVE, 71). --define(wxROMAN, 72). --define(wxSCRIPT, 73). --define(wxSWISS, 74). --define(wxMODERN, 75). --define(wxTELETYPE, 76). --define(wxVARIABLE, 80). --define(wxFIXED, 81). --define(wxNORMAL, 90). --define(wxLIGHT, 91). --define(wxBOLD, 92). --define(wxITALIC, 93). --define(wxSLANT, 94). --define(wxSOLID, 100). --define(wxDOT, 101). --define(wxLONG_DASH, 102). --define(wxSHORT_DASH, 103). --define(wxDOT_DASH, 104). --define(wxUSER_DASH, 105). --define(wxTRANSPARENT, 106). --define(wxSTIPPLE_MASK_OPAQUE, 107). --define(wxSTIPPLE_MASK, 108). --define(wxSTIPPLE, 110). --define(wxBDIAGONAL_HATCH, 111). --define(wxCROSSDIAG_HATCH, 112). --define(wxFDIAGONAL_HATCH, 113). --define(wxCROSS_HATCH, 114). --define(wxHORIZONTAL_HATCH, 115). --define(wxVERTICAL_HATCH, 116). --define(wxFIRST_HATCH, ?wxBDIAGONAL_HATCH). --define(wxLAST_HATCH, ?wxVERTICAL_HATCH). --define(wxJOIN_BEVEL, 120). --define(wxJOIN_MITER, 121). --define(wxJOIN_ROUND, 122). --define(wxCAP_ROUND, 130). --define(wxCAP_PROJECTING, 131). --define(wxCAP_BUTT, 132). --define(wxJOY_BUTTON_ANY, -1). --define(wxJOY_BUTTON1, 1). --define(wxJOY_BUTTON2, 2). --define(wxJOY_BUTTON3, 4). --define(wxJOY_BUTTON4, 8). --define(wxLIST_AUTOSIZE, -1). --define(wxLIST_AUTOSIZE_USEHEADER, -2). +% From "utils.h" -define(wxStrip_Mnemonics, 1). -define(wxStrip_Accel, 2). -define(wxStrip_All, (?wxStrip_Mnemonics bor ?wxStrip_Accel)). --define(wxFLOOD_SURFACE, 1). --define(wxFLOOD_BORDER, 2). --define(wxLIST_RECT_BOUNDS, 0). --define(wxLIST_RECT_ICON, 1). --define(wxLIST_RECT_LABEL, 2). --define(wxODDEVEN_RULE, 1). --define(wxWINDING_RULE, 2). --define(wxLIST_FIND_UP, 0). --define(wxLIST_FIND_DOWN, 1). --define(wxLIST_FIND_LEFT, 2). --define(wxLIST_FIND_RIGHT, 3). --define(wxTOOL_TOP, 1). --define(wxTOOL_BOTTOM, 2). --define(wxTOOL_LEFT, 3). --define(wxTOOL_RIGHT, 4). --define(wxMM_TEXT, 1). --define(wxMM_LOMETRIC, 2). --define(wxMM_HIMETRIC, 3). --define(wxMM_LOENGLISH, 4). --define(wxMM_HIENGLISH, 5). --define(wxMM_TWIPS, 6). --define(wxMM_ISOTROPIC, 7). --define(wxMM_ANISOTROPIC, 8). --define(wxMM_POINTS, 9). --define(wxMM_METRIC, 10). -% Type Propagation_state --define(wxEVENT_PROPAGATE_NONE, 0). --define(wxEVENT_PROPAGATE_MAX, ?INT_MAX). -% Type form_ops_t --define(wxCLEAR, 0). --define(wxROP_BLACK, ?wxCLEAR). --define(wxBLIT_BLACKNESS, ?wxCLEAR). --define(wxXOR, (?wxCLEAR+1)). --define(wxROP_XORPEN, ?wxXOR). --define(wxBLIT_SRCINVERT, ?wxXOR). --define(wxINVERT, (?wxXOR+1)). --define(wxROP_NOT, ?wxINVERT). --define(wxBLIT_DSTINVERT, ?wxINVERT). --define(wxOR_REVERSE, (?wxINVERT+1)). --define(wxROP_MERGEPENNOT, ?wxOR_REVERSE). --define(wxBLIT_00DD0228, ?wxOR_REVERSE). --define(wxAND_REVERSE, (?wxOR_REVERSE+1)). --define(wxROP_MASKPENNOT, ?wxAND_REVERSE). --define(wxBLIT_SRCERASE, ?wxAND_REVERSE). --define(wxCOPY, (?wxAND_REVERSE+1)). --define(wxROP_COPYPEN, ?wxCOPY). --define(wxBLIT_SRCCOPY, ?wxCOPY). --define(wxAND, (?wxCOPY+1)). --define(wxROP_MASKPEN, ?wxAND). --define(wxBLIT_SRCAND, ?wxAND). --define(wxAND_INVERT, (?wxAND+1)). --define(wxROP_MASKNOTPEN, ?wxAND_INVERT). --define(wxBLIT_00220326, ?wxAND_INVERT). --define(wxNO_OP, (?wxAND_INVERT+1)). --define(wxROP_NOP, ?wxNO_OP). --define(wxBLIT_00AA0029, ?wxNO_OP). --define(wxNOR, (?wxNO_OP+1)). --define(wxROP_NOTMERGEPEN, ?wxNOR). --define(wxBLIT_NOTSRCERASE, ?wxNOR). --define(wxEQUIV, (?wxNOR+1)). --define(wxROP_NOTXORPEN, ?wxEQUIV). --define(wxBLIT_00990066, ?wxEQUIV). --define(wxSRC_INVERT, (?wxEQUIV+1)). --define(wxROP_NOTCOPYPEN, ?wxSRC_INVERT). --define(wxBLIT_NOTSCRCOPY, ?wxSRC_INVERT). --define(wxOR_INVERT, (?wxSRC_INVERT+1)). --define(wxROP_MERGENOTPEN, ?wxOR_INVERT). --define(wxBLIT_MERGEPAINT, ?wxOR_INVERT). --define(wxNAND, (?wxOR_INVERT+1)). --define(wxROP_NOTMASKPEN, ?wxNAND). --define(wxBLIT_007700E6, ?wxNAND). --define(wxOR, (?wxNAND+1)). --define(wxROP_MERGEPEN, ?wxOR). --define(wxBLIT_SRCPAINT, ?wxOR). --define(wxSET, (?wxOR+1)). --define(wxROP_WHITE, ?wxSET). --define(wxBLIT_WHITENESS, ?wxSET). -% Type wxAlignment --define(wxALIGN_NOT, 0). --define(wxALIGN_CENTER_HORIZONTAL, 256). --define(wxALIGN_CENTRE_HORIZONTAL, ?wxALIGN_CENTER_HORIZONTAL). --define(wxALIGN_LEFT, ?wxALIGN_NOT). --define(wxALIGN_TOP, ?wxALIGN_NOT). --define(wxALIGN_RIGHT, 512). --define(wxALIGN_BOTTOM, 1024). --define(wxALIGN_CENTER_VERTICAL, 2048). --define(wxALIGN_CENTRE_VERTICAL, ?wxALIGN_CENTER_VERTICAL). --define(wxALIGN_CENTER, (?wxALIGN_CENTER_HORIZONTAL bor ?wxALIGN_CENTER_VERTICAL)). --define(wxALIGN_CENTRE, ?wxALIGN_CENTER). --define(wxALIGN_MASK, 3840). -% Type wxAuiButtonId --define(wxAUI_BUTTON_CLOSE, 101). --define(wxAUI_BUTTON_MAXIMIZE_RESTORE, 102). --define(wxAUI_BUTTON_MINIMIZE, 103). --define(wxAUI_BUTTON_PIN, 104). --define(wxAUI_BUTTON_OPTIONS, 105). --define(wxAUI_BUTTON_WINDOWLIST, 106). --define(wxAUI_BUTTON_LEFT, 107). --define(wxAUI_BUTTON_RIGHT, 108). --define(wxAUI_BUTTON_UP, 109). --define(wxAUI_BUTTON_DOWN, 110). --define(wxAUI_BUTTON_CUSTOM1, 201). --define(wxAUI_BUTTON_CUSTOM2, 202). --define(wxAUI_BUTTON_CUSTOM3, 203). -% Type wxAuiManagerDock --define(wxAUI_DOCK_NONE, 0). --define(wxAUI_DOCK_TOP, 1). --define(wxAUI_DOCK_RIGHT, 2). --define(wxAUI_DOCK_BOTTOM, 3). --define(wxAUI_DOCK_LEFT, 4). --define(wxAUI_DOCK_CENTER, 5). --define(wxAUI_DOCK_CENTRE, ?wxAUI_DOCK_CENTER). -% Type wxAuiManagerOption --define(wxAUI_MGR_ALLOW_FLOATING, 1). --define(wxAUI_MGR_ALLOW_ACTIVE_PANE, 2). --define(wxAUI_MGR_TRANSPARENT_DRAG, 4). --define(wxAUI_MGR_TRANSPARENT_HINT, 8). --define(wxAUI_MGR_VENETIAN_BLINDS_HINT, 16). --define(wxAUI_MGR_RECTANGLE_HINT, 32). --define(wxAUI_MGR_HINT_FADE, 64). --define(wxAUI_MGR_NO_VENETIAN_BLINDS_FADE, 128). --define(wxAUI_MGR_LIVE_RESIZE, 256). --define(wxAUI_MGR_DEFAULT, (?wxAUI_MGR_ALLOW_FLOATING bor ?wxAUI_MGR_TRANSPARENT_HINT bor ?wxAUI_MGR_HINT_FADE bor ?wxAUI_MGR_NO_VENETIAN_BLINDS_FADE)). -% Type wxAuiNotebookOption --define(wxAUI_NB_TOP, 1). --define(wxAUI_NB_LEFT, 2). --define(wxAUI_NB_RIGHT, 4). --define(wxAUI_NB_BOTTOM, 8). --define(wxAUI_NB_TAB_SPLIT, 16). --define(wxAUI_NB_TAB_MOVE, 32). --define(wxAUI_NB_TAB_EXTERNAL_MOVE, 64). --define(wxAUI_NB_TAB_FIXED_WIDTH, 128). --define(wxAUI_NB_SCROLL_BUTTONS, 256). --define(wxAUI_NB_WINDOWLIST_BUTTON, 512). --define(wxAUI_NB_CLOSE_BUTTON, 1024). --define(wxAUI_NB_CLOSE_ON_ACTIVE_TAB, 2048). --define(wxAUI_NB_CLOSE_ON_ALL_TABS, 4096). --define(wxAUI_NB_MIDDLE_CLICK_CLOSE, 8192). --define(wxAUI_NB_DEFAULT_STYLE, (?wxAUI_NB_TOP bor ?wxAUI_NB_TAB_SPLIT bor ?wxAUI_NB_TAB_MOVE bor ?wxAUI_NB_SCROLL_BUTTONS bor ?wxAUI_NB_CLOSE_ON_ACTIVE_TAB bor ?wxAUI_NB_MIDDLE_CLICK_CLOSE)). -% Type wxAuiPaneButtonState --define(wxAUI_BUTTON_STATE_NORMAL, 0). --define(wxAUI_BUTTON_STATE_HOVER, 2). --define(wxAUI_BUTTON_STATE_PRESSED, 4). --define(wxAUI_BUTTON_STATE_DISABLED, 8). --define(wxAUI_BUTTON_STATE_HIDDEN, 16). --define(wxAUI_BUTTON_STATE_CHECKED, 32). -% Type wxAuiPaneDockArtGradients --define(wxAUI_GRADIENT_NONE, 0). --define(wxAUI_GRADIENT_VERTICAL, 1). --define(wxAUI_GRADIENT_HORIZONTAL, 2). -% Type wxAuiPaneDockArtSetting --define(wxAUI_DOCKART_SASH_SIZE, 0). --define(wxAUI_DOCKART_CAPTION_SIZE, 1). --define(wxAUI_DOCKART_GRIPPER_SIZE, 2). --define(wxAUI_DOCKART_PANE_BORDER_SIZE, 3). --define(wxAUI_DOCKART_PANE_BUTTON_SIZE, 4). --define(wxAUI_DOCKART_BACKGROUND_COLOUR, 5). --define(wxAUI_DOCKART_SASH_COLOUR, 6). --define(wxAUI_DOCKART_ACTIVE_CAPTION_COLOUR, 7). --define(wxAUI_DOCKART_ACTIVE_CAPTION_GRADIENT_COLOUR, 8). --define(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR, 9). --define(wxAUI_DOCKART_INACTIVE_CAPTION_GRADIENT_COLOUR, 10). --define(wxAUI_DOCKART_ACTIVE_CAPTION_TEXT_COLOUR, 11). --define(wxAUI_DOCKART_INACTIVE_CAPTION_TEXT_COLOUR, 12). --define(wxAUI_DOCKART_BORDER_COLOUR, 13). --define(wxAUI_DOCKART_GRIPPER_COLOUR, 14). --define(wxAUI_DOCKART_CAPTION_FONT, 15). --define(wxAUI_DOCKART_GRADIENT_TYPE, 16). -% Type wxAuiPaneInsertLevel --define(wxAUI_INSERT_PANE, 0). --define(wxAUI_INSERT_ROW, 1). --define(wxAUI_INSERT_DOCK, 2). -% Type wxBackgroundStyle --define(wxBG_STYLE_SYSTEM, 0). --define(wxBG_STYLE_COLOUR, 1). --define(wxBG_STYLE_CUSTOM, 2). -% Type wxBitmapType --define(wxBITMAP_TYPE_INVALID, 0). --define(wxBITMAP_TYPE_BMP, 1). --define(wxBITMAP_TYPE_BMP_RESOURCE, 2). --define(wxBITMAP_TYPE_RESOURCE, ?wxBITMAP_TYPE_BMP_RESOURCE). --define(wxBITMAP_TYPE_ICO, (?wxBITMAP_TYPE_BMP_RESOURCE+1)). --define(wxBITMAP_TYPE_ICO_RESOURCE, (?wxBITMAP_TYPE_BMP_RESOURCE+2)). --define(wxBITMAP_TYPE_CUR, (?wxBITMAP_TYPE_BMP_RESOURCE+3)). --define(wxBITMAP_TYPE_CUR_RESOURCE, (?wxBITMAP_TYPE_BMP_RESOURCE+4)). --define(wxBITMAP_TYPE_XBM, (?wxBITMAP_TYPE_BMP_RESOURCE+5)). --define(wxBITMAP_TYPE_XBM_DATA, (?wxBITMAP_TYPE_BMP_RESOURCE+6)). --define(wxBITMAP_TYPE_XPM, (?wxBITMAP_TYPE_BMP_RESOURCE+7)). --define(wxBITMAP_TYPE_XPM_DATA, (?wxBITMAP_TYPE_BMP_RESOURCE+8)). --define(wxBITMAP_TYPE_TIF, (?wxBITMAP_TYPE_BMP_RESOURCE+9)). --define(wxBITMAP_TYPE_TIF_RESOURCE, (?wxBITMAP_TYPE_BMP_RESOURCE+10)). --define(wxBITMAP_TYPE_GIF, (?wxBITMAP_TYPE_BMP_RESOURCE+11)). --define(wxBITMAP_TYPE_GIF_RESOURCE, (?wxBITMAP_TYPE_BMP_RESOURCE+12)). --define(wxBITMAP_TYPE_PNG, (?wxBITMAP_TYPE_BMP_RESOURCE+13)). --define(wxBITMAP_TYPE_PNG_RESOURCE, (?wxBITMAP_TYPE_BMP_RESOURCE+14)). --define(wxBITMAP_TYPE_JPEG, (?wxBITMAP_TYPE_BMP_RESOURCE+15)). --define(wxBITMAP_TYPE_JPEG_RESOURCE, (?wxBITMAP_TYPE_BMP_RESOURCE+16)). --define(wxBITMAP_TYPE_PNM, (?wxBITMAP_TYPE_BMP_RESOURCE+17)). --define(wxBITMAP_TYPE_PNM_RESOURCE, (?wxBITMAP_TYPE_BMP_RESOURCE+18)). --define(wxBITMAP_TYPE_PCX, (?wxBITMAP_TYPE_BMP_RESOURCE+19)). --define(wxBITMAP_TYPE_PCX_RESOURCE, (?wxBITMAP_TYPE_BMP_RESOURCE+20)). --define(wxBITMAP_TYPE_PICT, (?wxBITMAP_TYPE_BMP_RESOURCE+21)). --define(wxBITMAP_TYPE_PICT_RESOURCE, (?wxBITMAP_TYPE_BMP_RESOURCE+22)). --define(wxBITMAP_TYPE_ICON, (?wxBITMAP_TYPE_BMP_RESOURCE+23)). --define(wxBITMAP_TYPE_ICON_RESOURCE, (?wxBITMAP_TYPE_BMP_RESOURCE+24)). --define(wxBITMAP_TYPE_ANI, (?wxBITMAP_TYPE_BMP_RESOURCE+25)). --define(wxBITMAP_TYPE_IFF, (?wxBITMAP_TYPE_BMP_RESOURCE+26)). --define(wxBITMAP_TYPE_TGA, (?wxBITMAP_TYPE_BMP_RESOURCE+27)). --define(wxBITMAP_TYPE_MACCURSOR, (?wxBITMAP_TYPE_BMP_RESOURCE+28)). --define(wxBITMAP_TYPE_MACCURSOR_RESOURCE, (?wxBITMAP_TYPE_BMP_RESOURCE+29)). --define(wxBITMAP_TYPE_ANY, 50). -% Type wxBorder --define(wxBORDER_DEFAULT, 0). --define(wxBORDER_NONE, 2097152). --define(wxBORDER_STATIC, 16777216). --define(wxBORDER_SIMPLE, 33554432). --define(wxBORDER_RAISED, 67108864). --define(wxBORDER_SUNKEN, 134217728). --define(wxBORDER_DOUBLE, 268435456). --define(wxBORDER_THEME, 268435456). --define(wxBORDER_MASK, 522190848). -% Type wxCalendarDateBorder --define(wxCAL_BORDER_NONE, 0). --define(wxCAL_BORDER_SQUARE, 1). --define(wxCAL_BORDER_ROUND, 2). -% Type wxCalendarHitTestResult --define(wxCAL_HITTEST_NOWHERE, 0). --define(wxCAL_HITTEST_HEADER, 1). --define(wxCAL_HITTEST_DAY, 2). --define(wxCAL_HITTEST_INCMONTH, 3). --define(wxCAL_HITTEST_DECMONTH, 4). --define(wxCAL_HITTEST_SURROUNDING_WEEK, 5). -% Type wxCheckBoxState --define(wxCHK_UNCHECKED, 0). --define(wxCHK_CHECKED, 1). --define(wxCHK_UNDETERMINED, 2). -% Type wxClientDataType --define(wxClientData_None, 0). --define(wxClientData_Object, 1). --define(wxClientData_Void, 2). -% Type wxDataFormatId --define(wxDF_INVALID, 0). --define(wxDF_TEXT, 1). --define(wxDF_BITMAP, 2). --define(wxDF_METAFILE, 3). --define(wxDF_SYLK, 4). --define(wxDF_DIF, 5). --define(wxDF_TIFF, 6). --define(wxDF_OEMTEXT, 7). --define(wxDF_DIB, 8). --define(wxDF_PALETTE, 9). --define(wxDF_PENDATA, 10). --define(wxDF_RIFF, 11). --define(wxDF_WAVE, 12). --define(wxDF_UNICODETEXT, 13). --define(wxDF_ENHMETAFILE, 14). --define(wxDF_FILENAME, 15). --define(wxDF_LOCALE, 16). --define(wxDF_PRIVATE, 20). --define(wxDF_HTML, 30). --define(wxDF_MAX, 31). -% Type wxDirection --define(wxLEFT, 16). --define(wxRIGHT, 32). --define(wxUP, 64). --define(wxDOWN, 128). --define(wxTOP, ?wxUP). --define(wxBOTTOM, ?wxDOWN). --define(wxNORTH, ?wxUP). --define(wxSOUTH, ?wxDOWN). --define(wxWEST, ?wxLEFT). --define(wxEAST, ?wxRIGHT). --define(wxALL, (?wxUP bor ?wxDOWN bor ?wxRIGHT bor ?wxLEFT)). -% Type wxDragResult --define(wxDragError, 0). --define(wxDragNone, 1). --define(wxDragCopy, 2). --define(wxDragMove, 3). --define(wxDragLink, 4). --define(wxDragCancel, 5). -% Type wxDuplexMode --define(wxDUPLEX_SIMPLEX, 0). --define(wxDUPLEX_HORIZONTAL, 1). --define(wxDUPLEX_VERTICAL, 2). -% Type wxEdge --define(wxLeft, 0). --define(wxTop, 1). --define(wxRight, 2). --define(wxBottom, 3). --define(wxWidth, 4). --define(wxHeight, 5). --define(wxCentre, 6). --define(wxCenter, ?wxCentre). --define(wxCentreX, (?wxCentre+1)). --define(wxCentreY, (?wxCentre+2)). -% Type wxFindReplaceDialogStyles --define(wxFR_REPLACEDIALOG, 1). --define(wxFR_NOUPDOWN, 2). --define(wxFR_NOMATCHCASE, 4). --define(wxFR_NOWHOLEWORD, 8). -% Type wxFindReplaceFlags --define(wxFR_DOWN, 1). --define(wxFR_WHOLEWORD, 2). --define(wxFR_MATCHCASE, 4). -% Type wxFlexSizerGrowMode --define(wxFLEX_GROWMODE_NONE, 0). --define(wxFLEX_GROWMODE_SPECIFIED, 1). --define(wxFLEX_GROWMODE_ALL, 2). -% Type wxFontEncoding --define(wxFONTENCODING_SYSTEM, -1). --define(wxFONTENCODING_DEFAULT, 0). --define(wxFONTENCODING_ISO8859_1, 1). --define(wxFONTENCODING_ISO8859_2, 2). --define(wxFONTENCODING_ISO8859_3, 3). --define(wxFONTENCODING_ISO8859_4, 4). --define(wxFONTENCODING_ISO8859_5, 5). --define(wxFONTENCODING_ISO8859_6, 6). --define(wxFONTENCODING_ISO8859_7, 7). --define(wxFONTENCODING_ISO8859_8, 8). --define(wxFONTENCODING_ISO8859_9, 9). --define(wxFONTENCODING_ISO8859_10, 10). --define(wxFONTENCODING_ISO8859_11, 11). --define(wxFONTENCODING_ISO8859_12, 12). --define(wxFONTENCODING_ISO8859_13, 13). --define(wxFONTENCODING_ISO8859_14, 14). --define(wxFONTENCODING_ISO8859_15, 15). --define(wxFONTENCODING_ISO8859_MAX, 16). --define(wxFONTENCODING_KOI8, 17). --define(wxFONTENCODING_KOI8_U, 18). --define(wxFONTENCODING_ALTERNATIVE, 19). --define(wxFONTENCODING_BULGARIAN, 20). --define(wxFONTENCODING_CP437, 21). --define(wxFONTENCODING_CP850, 22). --define(wxFONTENCODING_CP852, 23). --define(wxFONTENCODING_CP855, 24). --define(wxFONTENCODING_CP866, 25). --define(wxFONTENCODING_CP874, 26). --define(wxFONTENCODING_CP932, 27). --define(wxFONTENCODING_CP936, 28). --define(wxFONTENCODING_CP949, 29). --define(wxFONTENCODING_CP950, 30). --define(wxFONTENCODING_CP1250, 31). --define(wxFONTENCODING_CP1251, 32). --define(wxFONTENCODING_CP1252, 33). --define(wxFONTENCODING_CP1253, 34). --define(wxFONTENCODING_CP1254, 35). --define(wxFONTENCODING_CP1255, 36). --define(wxFONTENCODING_CP1256, 37). --define(wxFONTENCODING_CP1257, 38). --define(wxFONTENCODING_CP12_MAX, 39). --define(wxFONTENCODING_UTF7, 40). --define(wxFONTENCODING_UTF8, 41). --define(wxFONTENCODING_EUC_JP, 42). --define(wxFONTENCODING_UTF16BE, 43). --define(wxFONTENCODING_UTF16LE, 44). --define(wxFONTENCODING_UTF32BE, 45). --define(wxFONTENCODING_UTF32LE, 46). --define(wxFONTENCODING_MACROMAN, 47). --define(wxFONTENCODING_MACJAPANESE, 48). --define(wxFONTENCODING_MACCHINESETRAD, 49). --define(wxFONTENCODING_MACKOREAN, 50). --define(wxFONTENCODING_MACARABIC, 51). --define(wxFONTENCODING_MACHEBREW, 52). --define(wxFONTENCODING_MACGREEK, 53). --define(wxFONTENCODING_MACCYRILLIC, 54). --define(wxFONTENCODING_MACDEVANAGARI, 55). --define(wxFONTENCODING_MACGURMUKHI, 56). --define(wxFONTENCODING_MACGUJARATI, 57). --define(wxFONTENCODING_MACORIYA, 58). --define(wxFONTENCODING_MACBENGALI, 59). --define(wxFONTENCODING_MACTAMIL, 60). --define(wxFONTENCODING_MACTELUGU, 61). --define(wxFONTENCODING_MACKANNADA, 62). --define(wxFONTENCODING_MACMALAJALAM, 63). --define(wxFONTENCODING_MACSINHALESE, 64). --define(wxFONTENCODING_MACBURMESE, 65). --define(wxFONTENCODING_MACKHMER, 66). --define(wxFONTENCODING_MACTHAI, 67). --define(wxFONTENCODING_MACLAOTIAN, 68). --define(wxFONTENCODING_MACGEORGIAN, 69). --define(wxFONTENCODING_MACARMENIAN, 70). --define(wxFONTENCODING_MACCHINESESIMP, 71). --define(wxFONTENCODING_MACTIBETAN, 72). --define(wxFONTENCODING_MACMONGOLIAN, 73). --define(wxFONTENCODING_MACETHIOPIC, 74). --define(wxFONTENCODING_MACCENTRALEUR, 75). --define(wxFONTENCODING_MACVIATNAMESE, 76). --define(wxFONTENCODING_MACARABICEXT, 77). --define(wxFONTENCODING_MACSYMBOL, 78). --define(wxFONTENCODING_MACDINGBATS, 79). --define(wxFONTENCODING_MACTURKISH, 80). --define(wxFONTENCODING_MACCROATIAN, 81). --define(wxFONTENCODING_MACICELANDIC, 82). --define(wxFONTENCODING_MACROMANIAN, 83). --define(wxFONTENCODING_MACCELTIC, 84). --define(wxFONTENCODING_MACGAELIC, 85). --define(wxFONTENCODING_MACKEYBOARD, 86). --define(wxFONTENCODING_MAX, 87). --define(wxFONTENCODING_MACMIN, ?wxFONTENCODING_MACROMAN). --define(wxFONTENCODING_MACMAX, ?wxFONTENCODING_MACKEYBOARD). --define(wxFONTENCODING_UTF16, wxe_util:get_const(wxFONTENCODING_UTF16)). --define(wxFONTENCODING_UTF32, wxe_util:get_const(wxFONTENCODING_UTF32)). --define(wxFONTENCODING_UNICODE, ?wxFONTENCODING_UTF32). --define(wxFONTENCODING_GB2312, ?wxFONTENCODING_CP936). --define(wxFONTENCODING_BIG5, ?wxFONTENCODING_CP950). --define(wxFONTENCODING_SHIFT_JIS, ?wxFONTENCODING_CP932). -% Type wxFontFamily --define(wxFONTFAMILY_DEFAULT, ?wxDEFAULT). --define(wxFONTFAMILY_DECORATIVE, ?wxDECORATIVE). --define(wxFONTFAMILY_ROMAN, ?wxROMAN). --define(wxFONTFAMILY_SCRIPT, ?wxSCRIPT). --define(wxFONTFAMILY_SWISS, ?wxSWISS). --define(wxFONTFAMILY_MODERN, ?wxMODERN). --define(wxFONTFAMILY_TELETYPE, ?wxTELETYPE). --define(wxFONTFAMILY_MAX, (?wxTELETYPE+1)). --define(wxFONTFAMILY_UNKNOWN, ?wxFONTFAMILY_MAX). -% Type wxFontStyle --define(wxFONTSTYLE_NORMAL, ?wxNORMAL). --define(wxFONTSTYLE_ITALIC, ?wxITALIC). --define(wxFONTSTYLE_SLANT, ?wxSLANT). --define(wxFONTSTYLE_MAX, (?wxSLANT+1)). -% Type wxFontWeight --define(wxFONTWEIGHT_NORMAL, ?wxNORMAL). --define(wxFONTWEIGHT_LIGHT, ?wxLIGHT). --define(wxFONTWEIGHT_BOLD, ?wxBOLD). --define(wxFONTWEIGHT_MAX, (?wxBOLD+1)). -% Type wxGeometryCentre --define(wxCENTRE, 1). --define(wxCENTER, ?wxCENTRE). -% Type wxHitTest --define(wxHT_NOWHERE, 0). --define(wxHT_SCROLLBAR_FIRST, ?wxHT_NOWHERE). --define(wxHT_SCROLLBAR_ARROW_LINE_1, (?wxHT_NOWHERE+1)). --define(wxHT_SCROLLBAR_ARROW_LINE_2, (?wxHT_NOWHERE+2)). --define(wxHT_SCROLLBAR_ARROW_PAGE_1, (?wxHT_NOWHERE+3)). --define(wxHT_SCROLLBAR_ARROW_PAGE_2, (?wxHT_NOWHERE+4)). --define(wxHT_SCROLLBAR_THUMB, (?wxHT_NOWHERE+5)). --define(wxHT_SCROLLBAR_BAR_1, (?wxHT_NOWHERE+6)). --define(wxHT_SCROLLBAR_BAR_2, (?wxHT_NOWHERE+7)). --define(wxHT_SCROLLBAR_LAST, (?wxHT_NOWHERE+8)). --define(wxHT_WINDOW_OUTSIDE, (?wxHT_NOWHERE+9)). --define(wxHT_WINDOW_INSIDE, (?wxHT_NOWHERE+10)). --define(wxHT_WINDOW_VERT_SCROLLBAR, (?wxHT_NOWHERE+11)). --define(wxHT_WINDOW_HORZ_SCROLLBAR, (?wxHT_NOWHERE+12)). --define(wxHT_WINDOW_CORNER, (?wxHT_NOWHERE+13)). --define(wxHT_MAX, (?wxHT_NOWHERE+14)). -% Type wxHtmlOpeningStatus --define(wxHTML_OPEN, 0). --define(wxHTML_BLOCK, 1). --define(wxHTML_REDIRECT, 2). -% Type wxIdleMode --define(wxIDLE_PROCESS_ALL, 0). --define(wxIDLE_PROCESS_SPECIFIED, 1). -% Type wxItemKind --define(wxITEM_SEPARATOR, -1). --define(wxITEM_NORMAL, 0). --define(wxITEM_CHECK, 1). --define(wxITEM_RADIO, 2). --define(wxITEM_MAX, 3). -% Type wxKeyCode --define(WXK_BACK, 8). --define(WXK_TAB, 9). --define(WXK_RETURN, 13). --define(WXK_ESCAPE, 27). --define(WXK_SPACE, 32). --define(WXK_DELETE, 127). --define(WXK_START, 300). --define(WXK_LBUTTON, 301). --define(WXK_RBUTTON, 302). --define(WXK_CANCEL, 303). --define(WXK_MBUTTON, 304). --define(WXK_CLEAR, 305). --define(WXK_SHIFT, 306). --define(WXK_ALT, 307). --define(WXK_CONTROL, 308). --define(WXK_MENU, 309). --define(WXK_PAUSE, 310). --define(WXK_CAPITAL, 311). --define(WXK_END, 312). --define(WXK_HOME, 313). --define(WXK_LEFT, 314). --define(WXK_UP, 315). --define(WXK_RIGHT, 316). --define(WXK_DOWN, 317). --define(WXK_SELECT, 318). --define(WXK_PRINT, 319). --define(WXK_EXECUTE, 320). --define(WXK_SNAPSHOT, 321). --define(WXK_INSERT, 322). --define(WXK_HELP, 323). --define(WXK_NUMPAD0, 324). --define(WXK_NUMPAD1, 325). --define(WXK_NUMPAD2, 326). --define(WXK_NUMPAD3, 327). --define(WXK_NUMPAD4, 328). --define(WXK_NUMPAD5, 329). --define(WXK_NUMPAD6, 330). --define(WXK_NUMPAD7, 331). --define(WXK_NUMPAD8, 332). --define(WXK_NUMPAD9, 333). --define(WXK_MULTIPLY, 334). --define(WXK_ADD, 335). --define(WXK_SEPARATOR, 336). --define(WXK_SUBTRACT, 337). --define(WXK_DECIMAL, 338). --define(WXK_DIVIDE, 339). --define(WXK_F1, 340). --define(WXK_F2, 341). --define(WXK_F3, 342). --define(WXK_F4, 343). --define(WXK_F5, 344). --define(WXK_F6, 345). --define(WXK_F7, 346). --define(WXK_F8, 347). --define(WXK_F9, 348). --define(WXK_F10, 349). --define(WXK_F11, 350). --define(WXK_F12, 351). --define(WXK_F13, 352). --define(WXK_F14, 353). --define(WXK_F15, 354). --define(WXK_F16, 355). --define(WXK_F17, 356). --define(WXK_F18, 357). --define(WXK_F19, 358). --define(WXK_F20, 359). --define(WXK_F21, 360). --define(WXK_F22, 361). --define(WXK_F23, 362). --define(WXK_F24, 363). --define(WXK_NUMLOCK, 364). --define(WXK_SCROLL, 365). --define(WXK_PAGEUP, 366). --define(WXK_PAGEDOWN, 367). --define(WXK_NUMPAD_SPACE, 368). --define(WXK_NUMPAD_TAB, 369). --define(WXK_NUMPAD_ENTER, 370). --define(WXK_NUMPAD_F1, 371). --define(WXK_NUMPAD_F2, 372). --define(WXK_NUMPAD_F3, 373). --define(WXK_NUMPAD_F4, 374). --define(WXK_NUMPAD_HOME, 375). --define(WXK_NUMPAD_LEFT, 376). --define(WXK_NUMPAD_UP, 377). --define(WXK_NUMPAD_RIGHT, 378). --define(WXK_NUMPAD_DOWN, 379). --define(WXK_NUMPAD_PAGEUP, 380). --define(WXK_NUMPAD_PAGEDOWN, 381). --define(WXK_NUMPAD_END, 382). --define(WXK_NUMPAD_BEGIN, 383). --define(WXK_NUMPAD_INSERT, 384). --define(WXK_NUMPAD_DELETE, 385). --define(WXK_NUMPAD_EQUAL, 386). --define(WXK_NUMPAD_MULTIPLY, 387). --define(WXK_NUMPAD_ADD, 388). --define(WXK_NUMPAD_SEPARATOR, 389). --define(WXK_NUMPAD_SUBTRACT, 390). --define(WXK_NUMPAD_DECIMAL, 391). --define(WXK_NUMPAD_DIVIDE, 392). --define(WXK_WINDOWS_LEFT, 393). --define(WXK_WINDOWS_RIGHT, 394). --define(WXK_WINDOWS_MENU, 395). --define(WXK_COMMAND, 396). --define(WXK_SPECIAL1, 193). --define(WXK_SPECIAL2, 194). --define(WXK_SPECIAL3, 195). --define(WXK_SPECIAL4, 196). --define(WXK_SPECIAL5, 197). --define(WXK_SPECIAL6, 198). --define(WXK_SPECIAL7, 199). --define(WXK_SPECIAL8, 200). --define(WXK_SPECIAL9, 201). --define(WXK_SPECIAL10, 202). --define(WXK_SPECIAL11, 203). --define(WXK_SPECIAL12, 204). --define(WXK_SPECIAL13, 205). --define(WXK_SPECIAL14, 206). --define(WXK_SPECIAL15, 207). --define(WXK_SPECIAL16, 208). --define(WXK_SPECIAL17, 209). --define(WXK_SPECIAL18, 210). --define(WXK_SPECIAL19, 211). --define(WXK_SPECIAL20, 212). -% Type wxKeyModifier --define(wxMOD_NONE, 0). --define(wxMOD_ALT, 1). --define(wxMOD_CONTROL, 2). --define(wxMOD_ALTGR, (?wxMOD_ALT bor ?wxMOD_CONTROL)). --define(wxMOD_SHIFT, 4). --define(wxMOD_META, 8). --define(wxMOD_WIN, ?wxMOD_META). --define(wxMOD_CMD, wxe_util:get_const(wxMOD_CMD)). --define(wxMOD_ALL, 65535). -% Type wxKeyType --define(wxKEY_NONE, 0). --define(wxKEY_INTEGER, 1). --define(wxKEY_STRING, 2). -% Type wxKillError +% From "utils.h": wxKillError -define(wxKILL_OK, 0). -define(wxKILL_BAD_SIGNAL, 1). -define(wxKILL_ACCESS_DENIED, 2). -define(wxKILL_NO_PROCESS, 3). -define(wxKILL_ERROR, 4). -% Type wxKillFlags +% From "utils.h": wxKillFlags -define(wxKILL_NOCHILDREN, 0). -define(wxKILL_CHILDREN, 1). -% Type wxLayoutAlignment --define(wxLAYOUT_NONE, 0). --define(wxLAYOUT_TOP, 1). --define(wxLAYOUT_LEFT, 2). --define(wxLAYOUT_RIGHT, 3). --define(wxLAYOUT_BOTTOM, 4). -% Type wxLayoutDirection --define(wxLayout_Default, 0). --define(wxLayout_LeftToRight, 1). --define(wxLayout_RightToLeft, 2). -% Type wxLayoutOrientation --define(wxLAYOUT_HORIZONTAL, 0). --define(wxLAYOUT_VERTICAL, 1). -% Type wxListColumnFormat --define(wxLIST_FORMAT_LEFT, 0). --define(wxLIST_FORMAT_RIGHT, 1). --define(wxLIST_FORMAT_CENTRE, 2). --define(wxLIST_FORMAT_CENTER, ?wxLIST_FORMAT_CENTRE). -% Type wxNotificationOptions --define(wxNOTIFY_NONE, 0). --define(wxNOTIFY_ONCE, 1). --define(wxNOTIFY_REPEAT, 2). -% Type wxOrientation --define(wxHORIZONTAL, 4). --define(wxVERTICAL, 8). --define(wxBOTH, (?wxVERTICAL bor ?wxHORIZONTAL)). -% Type wxPaperSize --define(wxPAPER_NONE, 0). --define(wxPAPER_LETTER, 1). --define(wxPAPER_LEGAL, 2). --define(wxPAPER_A4, 3). --define(wxPAPER_CSHEET, 4). --define(wxPAPER_DSHEET, 5). --define(wxPAPER_ESHEET, 6). --define(wxPAPER_LETTERSMALL, 7). --define(wxPAPER_TABLOID, 8). --define(wxPAPER_LEDGER, 9). --define(wxPAPER_STATEMENT, 10). --define(wxPAPER_EXECUTIVE, 11). --define(wxPAPER_A3, 12). --define(wxPAPER_A4SMALL, 13). --define(wxPAPER_A5, 14). --define(wxPAPER_B4, 15). --define(wxPAPER_B5, 16). --define(wxPAPER_FOLIO, 17). --define(wxPAPER_QUARTO, 18). --define(wxPAPER_10X14, 19). --define(wxPAPER_11X17, 20). --define(wxPAPER_NOTE, 21). --define(wxPAPER_ENV_9, 22). --define(wxPAPER_ENV_10, 23). --define(wxPAPER_ENV_11, 24). --define(wxPAPER_ENV_12, 25). --define(wxPAPER_ENV_14, 26). --define(wxPAPER_ENV_DL, 27). --define(wxPAPER_ENV_C5, 28). --define(wxPAPER_ENV_C3, 29). --define(wxPAPER_ENV_C4, 30). --define(wxPAPER_ENV_C6, 31). --define(wxPAPER_ENV_C65, 32). --define(wxPAPER_ENV_B4, 33). --define(wxPAPER_ENV_B5, 34). --define(wxPAPER_ENV_B6, 35). --define(wxPAPER_ENV_ITALY, 36). --define(wxPAPER_ENV_MONARCH, 37). --define(wxPAPER_ENV_PERSONAL, 38). --define(wxPAPER_FANFOLD_US, 39). --define(wxPAPER_FANFOLD_STD_GERMAN, 40). --define(wxPAPER_FANFOLD_LGL_GERMAN, 41). --define(wxPAPER_ISO_B4, 42). --define(wxPAPER_JAPANESE_POSTCARD, 43). --define(wxPAPER_9X11, 44). --define(wxPAPER_10X11, 45). --define(wxPAPER_15X11, 46). --define(wxPAPER_ENV_INVITE, 47). --define(wxPAPER_LETTER_EXTRA, 48). --define(wxPAPER_LEGAL_EXTRA, 49). --define(wxPAPER_TABLOID_EXTRA, 50). --define(wxPAPER_A4_EXTRA, 51). --define(wxPAPER_LETTER_TRANSVERSE, 52). --define(wxPAPER_A4_TRANSVERSE, 53). --define(wxPAPER_LETTER_EXTRA_TRANSVERSE, 54). --define(wxPAPER_A_PLUS, 55). --define(wxPAPER_B_PLUS, 56). --define(wxPAPER_LETTER_PLUS, 57). --define(wxPAPER_A4_PLUS, 58). --define(wxPAPER_A5_TRANSVERSE, 59). --define(wxPAPER_B5_TRANSVERSE, 60). --define(wxPAPER_A3_EXTRA, 61). --define(wxPAPER_A5_EXTRA, 62). --define(wxPAPER_B5_EXTRA, 63). --define(wxPAPER_A2, 64). --define(wxPAPER_A3_TRANSVERSE, 65). --define(wxPAPER_A3_EXTRA_TRANSVERSE, 66). --define(wxPAPER_DBL_JAPANESE_POSTCARD, 67). --define(wxPAPER_A6, 68). --define(wxPAPER_JENV_KAKU2, 69). --define(wxPAPER_JENV_KAKU3, 70). --define(wxPAPER_JENV_CHOU3, 71). --define(wxPAPER_JENV_CHOU4, 72). --define(wxPAPER_LETTER_ROTATED, 73). --define(wxPAPER_A3_ROTATED, 74). --define(wxPAPER_A4_ROTATED, 75). --define(wxPAPER_A5_ROTATED, 76). --define(wxPAPER_B4_JIS_ROTATED, 77). --define(wxPAPER_B5_JIS_ROTATED, 78). --define(wxPAPER_JAPANESE_POSTCARD_ROTATED, 79). --define(wxPAPER_DBL_JAPANESE_POSTCARD_ROTATED, 80). --define(wxPAPER_A6_ROTATED, 81). --define(wxPAPER_JENV_KAKU2_ROTATED, 82). --define(wxPAPER_JENV_KAKU3_ROTATED, 83). --define(wxPAPER_JENV_CHOU3_ROTATED, 84). --define(wxPAPER_JENV_CHOU4_ROTATED, 85). --define(wxPAPER_B6_JIS, 86). --define(wxPAPER_B6_JIS_ROTATED, 87). --define(wxPAPER_12X11, 88). --define(wxPAPER_JENV_YOU4, 89). --define(wxPAPER_JENV_YOU4_ROTATED, 90). --define(wxPAPER_P16K, 91). --define(wxPAPER_P32K, 92). --define(wxPAPER_P32KBIG, 93). --define(wxPAPER_PENV_1, 94). --define(wxPAPER_PENV_2, 95). --define(wxPAPER_PENV_3, 96). --define(wxPAPER_PENV_4, 97). --define(wxPAPER_PENV_5, 98). --define(wxPAPER_PENV_6, 99). --define(wxPAPER_PENV_7, 100). --define(wxPAPER_PENV_8, 101). --define(wxPAPER_PENV_9, 102). --define(wxPAPER_PENV_10, 103). --define(wxPAPER_P16K_ROTATED, 104). --define(wxPAPER_P32K_ROTATED, 105). --define(wxPAPER_P32KBIG_ROTATED, 106). --define(wxPAPER_PENV_1_ROTATED, 107). --define(wxPAPER_PENV_2_ROTATED, 108). --define(wxPAPER_PENV_3_ROTATED, 109). --define(wxPAPER_PENV_4_ROTATED, 110). --define(wxPAPER_PENV_5_ROTATED, 111). --define(wxPAPER_PENV_6_ROTATED, 112). --define(wxPAPER_PENV_7_ROTATED, 113). --define(wxPAPER_PENV_8_ROTATED, 114). --define(wxPAPER_PENV_9_ROTATED, 115). --define(wxPAPER_PENV_10_ROTATED, 116). -% Type wxPrintBin --define(wxPRINTBIN_DEFAULT, 0). --define(wxPRINTBIN_ONLYONE, 1). --define(wxPRINTBIN_LOWER, 2). --define(wxPRINTBIN_MIDDLE, 3). --define(wxPRINTBIN_MANUAL, 4). --define(wxPRINTBIN_ENVELOPE, 5). --define(wxPRINTBIN_ENVMANUAL, 6). --define(wxPRINTBIN_AUTO, 7). --define(wxPRINTBIN_TRACTOR, 8). --define(wxPRINTBIN_SMALLFMT, 9). --define(wxPRINTBIN_LARGEFMT, 10). --define(wxPRINTBIN_LARGECAPACITY, 11). --define(wxPRINTBIN_CASSETTE, 12). --define(wxPRINTBIN_FORMSOURCE, 13). --define(wxPRINTBIN_USER, 14). -% Type wxPrintMode --define(wxPRINT_MODE_NONE, 0). --define(wxPRINT_MODE_PREVIEW, 1). --define(wxPRINT_MODE_FILE, 2). --define(wxPRINT_MODE_PRINTER, 3). --define(wxPRINT_MODE_STREAM, 4). -% Type wxPrinterError --define(wxPRINTER_NO_ERROR, 0). --define(wxPRINTER_CANCELLED, 1). --define(wxPRINTER_ERROR, 2). -% Type wxRegionContain --define(wxOutRegion, 0). --define(wxPartRegion, 1). --define(wxInRegion, 2). -% Type wxRegionOp --define(wxRGN_AND, 0). --define(wxRGN_COPY, 1). --define(wxRGN_DIFF, 2). --define(wxRGN_OR, 3). --define(wxRGN_XOR, 4). -% Type wxRelationship --define(wxUnconstrained, 0). --define(wxAsIs, 1). --define(wxPercentOf, 2). --define(wxAbove, 3). --define(wxBelow, 4). --define(wxLeftOf, 5). --define(wxRightOf, 6). --define(wxSameAs, 7). --define(wxAbsolute, 8). -% Type wxSashDragStatus --define(wxSASH_STATUS_OK, 0). --define(wxSASH_STATUS_OUT_OF_RANGE, 1). -% Type wxSashEdgePosition --define(wxSASH_TOP, 0). --define(wxSASH_RIGHT, 1). --define(wxSASH_BOTTOM, 2). --define(wxSASH_LEFT, 3). --define(wxSASH_NONE, 100). -% Type wxShutdownFlags +% From "utils.h": wxShutdownFlags -define(wxSHUTDOWN_POWEROFF, 0). -define(wxSHUTDOWN_REBOOT, 1). -% Type wxSignal +% From "utils.h": wxSignal -define(wxSIGNONE, 0). -define(wxSIGHUP, 1). -define(wxSIGINT, 2). @@ -3540,185 +3733,29 @@ -define(wxSIGPIPE, (?wxSIGABRT+7)). -define(wxSIGALRM, (?wxSIGABRT+8)). -define(wxSIGTERM, (?wxSIGABRT+9)). -% Type wxSplitMode --define(wxSPLIT_HORIZONTAL, 1). --define(wxSPLIT_VERTICAL, 2). -% Type wxStockCursor --define(wxCURSOR_NONE, 0). --define(wxCURSOR_ARROW, 1). --define(wxCURSOR_RIGHT_ARROW, 2). --define(wxCURSOR_BULLSEYE, 3). --define(wxCURSOR_CHAR, 4). --define(wxCURSOR_CROSS, 5). --define(wxCURSOR_HAND, 6). --define(wxCURSOR_IBEAM, 7). --define(wxCURSOR_LEFT_BUTTON, 8). --define(wxCURSOR_MAGNIFIER, 9). --define(wxCURSOR_MIDDLE_BUTTON, 10). --define(wxCURSOR_NO_ENTRY, 11). --define(wxCURSOR_PAINT_BRUSH, 12). --define(wxCURSOR_PENCIL, 13). --define(wxCURSOR_POINT_LEFT, 14). --define(wxCURSOR_POINT_RIGHT, 15). --define(wxCURSOR_QUESTION_ARROW, 16). --define(wxCURSOR_RIGHT_BUTTON, 17). --define(wxCURSOR_SIZENESW, 18). --define(wxCURSOR_SIZENS, 19). --define(wxCURSOR_SIZENWSE, 20). --define(wxCURSOR_SIZEWE, 21). --define(wxCURSOR_SIZING, 22). --define(wxCURSOR_SPRAYCAN, 23). --define(wxCURSOR_WAIT, 24). --define(wxCURSOR_WATCH, 25). --define(wxCURSOR_BLANK, 26). --define(wxCURSOR_DEFAULT, 27). --define(wxCURSOR_ARROWWAIT, 28). --define(wxCURSOR_MAX, 29). -% Type wxStretch --define(wxSTRETCH_NOT, 0). --define(wxSHRINK, 4096). --define(wxGROW, 8192). --define(wxEXPAND, ?wxGROW). --define(wxSHAPED, 16384). --define(wxFIXED_MINSIZE, 32768). --define(wxRESERVE_SPACE_EVEN_IF_HIDDEN, 2). --define(wxTILE, 49152). --define(wxADJUST_MINSIZE, 0). -% Type wxSystemColour --define(wxSYS_COLOUR_SCROLLBAR, 0). --define(wxSYS_COLOUR_BACKGROUND, 1). --define(wxSYS_COLOUR_DESKTOP, ?wxSYS_COLOUR_BACKGROUND). --define(wxSYS_COLOUR_ACTIVECAPTION, (?wxSYS_COLOUR_BACKGROUND+1)). --define(wxSYS_COLOUR_INACTIVECAPTION, (?wxSYS_COLOUR_BACKGROUND+2)). --define(wxSYS_COLOUR_MENU, (?wxSYS_COLOUR_BACKGROUND+3)). --define(wxSYS_COLOUR_WINDOW, (?wxSYS_COLOUR_BACKGROUND+4)). --define(wxSYS_COLOUR_WINDOWFRAME, (?wxSYS_COLOUR_BACKGROUND+5)). --define(wxSYS_COLOUR_MENUTEXT, (?wxSYS_COLOUR_BACKGROUND+6)). --define(wxSYS_COLOUR_WINDOWTEXT, (?wxSYS_COLOUR_BACKGROUND+7)). --define(wxSYS_COLOUR_CAPTIONTEXT, (?wxSYS_COLOUR_BACKGROUND+8)). --define(wxSYS_COLOUR_ACTIVEBORDER, (?wxSYS_COLOUR_BACKGROUND+9)). --define(wxSYS_COLOUR_INACTIVEBORDER, (?wxSYS_COLOUR_BACKGROUND+10)). --define(wxSYS_COLOUR_APPWORKSPACE, (?wxSYS_COLOUR_BACKGROUND+11)). --define(wxSYS_COLOUR_HIGHLIGHT, (?wxSYS_COLOUR_BACKGROUND+12)). --define(wxSYS_COLOUR_HIGHLIGHTTEXT, (?wxSYS_COLOUR_BACKGROUND+13)). --define(wxSYS_COLOUR_BTNFACE, (?wxSYS_COLOUR_BACKGROUND+14)). --define(wxSYS_COLOUR_3DFACE, ?wxSYS_COLOUR_BTNFACE). --define(wxSYS_COLOUR_BTNSHADOW, (?wxSYS_COLOUR_BTNFACE+1)). --define(wxSYS_COLOUR_3DSHADOW, ?wxSYS_COLOUR_BTNSHADOW). --define(wxSYS_COLOUR_GRAYTEXT, (?wxSYS_COLOUR_BTNSHADOW+1)). --define(wxSYS_COLOUR_BTNTEXT, (?wxSYS_COLOUR_BTNSHADOW+2)). --define(wxSYS_COLOUR_INACTIVECAPTIONTEXT, (?wxSYS_COLOUR_BTNSHADOW+3)). --define(wxSYS_COLOUR_BTNHIGHLIGHT, (?wxSYS_COLOUR_BTNSHADOW+4)). --define(wxSYS_COLOUR_BTNHILIGHT, ?wxSYS_COLOUR_BTNHIGHLIGHT). --define(wxSYS_COLOUR_3DHIGHLIGHT, ?wxSYS_COLOUR_BTNHIGHLIGHT). --define(wxSYS_COLOUR_3DHILIGHT, ?wxSYS_COLOUR_BTNHIGHLIGHT). --define(wxSYS_COLOUR_3DDKSHADOW, (?wxSYS_COLOUR_BTNHIGHLIGHT+1)). --define(wxSYS_COLOUR_3DLIGHT, (?wxSYS_COLOUR_BTNHIGHLIGHT+2)). --define(wxSYS_COLOUR_INFOTEXT, (?wxSYS_COLOUR_BTNHIGHLIGHT+3)). --define(wxSYS_COLOUR_INFOBK, (?wxSYS_COLOUR_BTNHIGHLIGHT+4)). --define(wxSYS_COLOUR_LISTBOX, (?wxSYS_COLOUR_BTNHIGHLIGHT+5)). --define(wxSYS_COLOUR_HOTLIGHT, (?wxSYS_COLOUR_BTNHIGHLIGHT+6)). --define(wxSYS_COLOUR_GRADIENTACTIVECAPTION, (?wxSYS_COLOUR_BTNHIGHLIGHT+7)). --define(wxSYS_COLOUR_GRADIENTINACTIVECAPTION, (?wxSYS_COLOUR_BTNHIGHLIGHT+8)). --define(wxSYS_COLOUR_MENUHILIGHT, (?wxSYS_COLOUR_BTNHIGHLIGHT+9)). --define(wxSYS_COLOUR_MENUBAR, (?wxSYS_COLOUR_BTNHIGHLIGHT+10)). --define(wxSYS_COLOUR_LISTBOXTEXT, (?wxSYS_COLOUR_BTNHIGHLIGHT+11)). --define(wxSYS_COLOUR_MAX, (?wxSYS_COLOUR_BTNHIGHLIGHT+12)). -% Type wxSystemFeature --define(wxSYS_CAN_DRAW_FRAME_DECORATIONS, 1). --define(wxSYS_CAN_ICONIZE_FRAME, 2). --define(wxSYS_TABLET_PRESENT, 3). -% Type wxSystemFont --define(wxSYS_OEM_FIXED_FONT, 10). --define(wxSYS_ANSI_FIXED_FONT, 11). --define(wxSYS_ANSI_VAR_FONT, 12). --define(wxSYS_SYSTEM_FONT, 13). --define(wxSYS_DEVICE_DEFAULT_FONT, 14). --define(wxSYS_DEFAULT_PALETTE, 15). --define(wxSYS_SYSTEM_FIXED_FONT, 16). --define(wxSYS_DEFAULT_GUI_FONT, 17). --define(wxSYS_ICONTITLE_FONT, ?wxSYS_DEFAULT_GUI_FONT). -% Type wxSystemMetric --define(wxSYS_MOUSE_BUTTONS, 1). --define(wxSYS_BORDER_X, 2). --define(wxSYS_BORDER_Y, 3). --define(wxSYS_CURSOR_X, 4). --define(wxSYS_CURSOR_Y, 5). --define(wxSYS_DCLICK_X, 6). --define(wxSYS_DCLICK_Y, 7). --define(wxSYS_DRAG_X, 8). --define(wxSYS_DRAG_Y, 9). --define(wxSYS_EDGE_X, 10). --define(wxSYS_EDGE_Y, 11). --define(wxSYS_HSCROLL_ARROW_X, 12). --define(wxSYS_HSCROLL_ARROW_Y, 13). --define(wxSYS_HTHUMB_X, 14). --define(wxSYS_ICON_X, 15). --define(wxSYS_ICON_Y, 16). --define(wxSYS_ICONSPACING_X, 17). --define(wxSYS_ICONSPACING_Y, 18). --define(wxSYS_WINDOWMIN_X, 19). --define(wxSYS_WINDOWMIN_Y, 20). --define(wxSYS_SCREEN_X, 21). --define(wxSYS_SCREEN_Y, 22). --define(wxSYS_FRAMESIZE_X, 23). --define(wxSYS_FRAMESIZE_Y, 24). --define(wxSYS_SMALLICON_X, 25). --define(wxSYS_SMALLICON_Y, 26). --define(wxSYS_HSCROLL_Y, 27). --define(wxSYS_VSCROLL_X, 28). --define(wxSYS_VSCROLL_ARROW_X, 29). --define(wxSYS_VSCROLL_ARROW_Y, 30). --define(wxSYS_VTHUMB_Y, 31). --define(wxSYS_CAPTION_Y, 32). --define(wxSYS_MENU_Y, 33). --define(wxSYS_NETWORK_PRESENT, 34). --define(wxSYS_PENWINDOWS_PRESENT, 35). --define(wxSYS_SHOW_SOUNDS, 36). --define(wxSYS_SWAP_BUTTONS, 37). -% Type wxSystemScreenType --define(wxSYS_SCREEN_NONE, 0). --define(wxSYS_SCREEN_TINY, 1). --define(wxSYS_SCREEN_PDA, 2). --define(wxSYS_SCREEN_SMALL, 3). --define(wxSYS_SCREEN_DESKTOP, 4). -% Type wxTextAttrAlignment --define(wxTEXT_ALIGNMENT_DEFAULT, 0). --define(wxTEXT_ALIGNMENT_LEFT, 1). --define(wxTEXT_ALIGNMENT_CENTRE, 2). --define(wxTEXT_ALIGNMENT_CENTER, ?wxTEXT_ALIGNMENT_CENTRE). --define(wxTEXT_ALIGNMENT_RIGHT, (?wxTEXT_ALIGNMENT_CENTRE+1)). --define(wxTEXT_ALIGNMENT_JUSTIFIED, (?wxTEXT_ALIGNMENT_CENTRE+2)). -% Type wxTextCtrlHitTestResult --define(wxTE_HT_UNKNOWN, -2). --define(wxTE_HT_BEFORE, -1). --define(wxTE_HT_ON_TEXT, 0). --define(wxTE_HT_BELOW, 1). --define(wxTE_HT_BEYOND, 2). -% Type wxToolBarToolStyle --define(wxTOOL_STYLE_BUTTON, 1). --define(wxTOOL_STYLE_SEPARATOR, 2). --define(wxTOOL_STYLE_CONTROL, 3). -% Type wxTreeItemIcon --define(wxTreeItemIcon_Normal, 0). --define(wxTreeItemIcon_Selected, 1). --define(wxTreeItemIcon_Expanded, 2). --define(wxTreeItemIcon_SelectedExpanded, 3). --define(wxTreeItemIcon_Max, 4). -% Type wxUpdateUI --define(wxUPDATE_UI_NONE, 0). --define(wxUPDATE_UI_RECURSE, 1). --define(wxUPDATE_UI_FROMIDLE, 2). -% Type wxUpdateUIMode --define(wxUPDATE_UI_PROCESS_ALL, 0). --define(wxUPDATE_UI_PROCESS_SPECIFIED, 1). -% Type wxWindowVariant +% From "valtext.h" +-define(wxFILTER_EXCLUDE_CHAR_LIST, 128). +-define(wxFILTER_INCLUDE_CHAR_LIST, 64). +-define(wxFILTER_EXCLUDE_LIST, 32). +-define(wxFILTER_INCLUDE_LIST, 16). +-define(wxFILTER_NUMERIC, 8). +-define(wxFILTER_ALPHANUMERIC, 4). +-define(wxFILTER_ALPHA, 2). +-define(wxFILTER_ASCII, 1). +-define(wxFILTER_NONE, 0). +% From "version.h" +-define(wxBETA_NUMBER, wxe_util:get_const(wxBETA_NUMBER)). +-define(wxSUBRELEASE_NUMBER, wxe_util:get_const(wxSUBRELEASE_NUMBER)). +-define(wxRELEASE_NUMBER, wxe_util:get_const(wxRELEASE_NUMBER)). +-define(wxMINOR_VERSION, wxe_util:get_const(wxMINOR_VERSION)). +-define(wxMAJOR_VERSION, wxe_util:get_const(wxMAJOR_VERSION)). +% From "window.h": wxWindowVariant -define(wxWINDOW_VARIANT_NORMAL, 0). -define(wxWINDOW_VARIANT_SMALL, 1). -define(wxWINDOW_VARIANT_MINI, 2). -define(wxWINDOW_VARIANT_LARGE, 3). -define(wxWINDOW_VARIANT_MAX, 4). -% Type wxXmlResourceFlags +% From "xmlres.h": wxXmlResourceFlags -define(wxXRC_USE_LOCALE, 1). -define(wxXRC_NO_SUBCLASSING, 2). -define(wxXRC_NO_RELOADING, 4). diff --git a/lib/wx/src/Makefile b/lib/wx/src/Makefile index 6c636bb51f..a9fd468959 100644 --- a/lib/wx/src/Makefile +++ b/lib/wx/src/Makefile @@ -1,19 +1,19 @@ # # %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 # 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% # @@ -44,6 +44,8 @@ GEN_FILES = $(wildcard gen/wx*.erl) \ gen/glu.erl \ gen/gl.erl +GEN_MODS = $(GEN_FILES:gen/%.erl= %,\n ) + GEN_HRL = \ $(EGEN)/gl_debug.hrl \ $(EGEN)/wxe_debug.hrl \ @@ -56,15 +58,25 @@ EXT_HRL = $(ERLINC)/wx.hrl \ TARGET_FILES = $(ErlMods:%=$(EBIN)/%.beam) $(GEN_FILES:gen/%.erl=$(EBIN)/%.beam) HEADER_FILES = $(HRL_FILES) $(GEN_HRL) $(EXT_HRL) +APP_FILE = wx.app +APP_SRC = $(APP_FILE).src +APP_TARGET = $(EBIN)/$(APP_FILE) + +APPUP_FILE = wx.appup +APPUP_SRC = $(APPUP_FILE).src +APPUP_TARGET = $(EBIN)/$(APPUP_FILE) + # Targets -debug opt: $(TARGET_FILES) +debug opt: $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) clean: rm -f $(TARGET_FILES) + rm -f $(APP_TARGET) $(APPUP_TARGET) rm -f *~ complete_clean: rm -f $(TARGET_FILES) + rm -f $(APP_TARGET) $(APPUP_TARGET) rm -f $(GEN_FILES) rm -f $(GenHrl) rm -f *~ @@ -75,6 +87,17 @@ docs: archive: opt (cd ../..; zip -0 wx/$(ARCHIVE) wx wx/ebin wx/ebin/*) +# ---------------------------------------------------- +# Special Build Targets +# ---------------------------------------------------- + +$(APP_TARGET): $(APP_SRC) ../vsn.mk Makefile + sed -e 's;%GEN_MODS%;$(GEN_MODS);' $< > [email protected] + sed -e 's;%VSN%;$(VSN);' [email protected] > $@ + rm [email protected] + +$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk Makefile + sed -e 's;%VSN%;$(VSN);' $< > $@ # Rules $(EBIN)/%.beam: $(ESRC)/%.erl $(HEADER_FILES) @@ -97,6 +120,7 @@ release_spec: opt $(INSTALL_DATA) $(EXT_HRL) $(RELSYSDIR)/include $(INSTALL_DIR) $(RELSYSDIR)/ebin $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DATA) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin # $(INSTALL_DATA) ../$(ARCHIVE) $(RELEASE_PATH)/lib release_docs_spec: diff --git a/lib/wx/src/gen/gl.erl b/lib/wx/src/gen/gl.erl index d789f1b72f..62d0ff6aed 100644 --- a/lib/wx/src/gen/gl.erl +++ b/lib/wx/src/gen/gl.erl @@ -20,15 +20,15 @@ %% This file is generated DO NOT EDIT -%% @doc Standard OpenGL api. +%% @doc Standard OpenGL api. %% See <a href="http://www.opengl.org/sdk/docs/man/">www.opengl.org</a> %% -%% Booleans are represented by integers 0 and 1. +%% Booleans are represented by integers 0 and 1. %% @type wx_mem(). see wx.erl on memory allocation functions %% @type enum(). An integer defined in gl.hrl %% @type offset(). An integer which is an offset in an array -%% @type clamp(). A float clamped between 0.0 - 1.0 +%% @type clamp(). A float clamped between 0.0 - 1.0 -module(gl). -compile(inline). @@ -216,7 +216,7 @@ stencilClearTagEXT/2]). -%% API +%% API %% @spec (Op::enum(),Value::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glAccum.xml">external</a> documentation. diff --git a/lib/wx/src/gen/gl_debug.hrl b/lib/wx/src/gen/gl_debug.hrl index 68225197cf..0b8086f24e 100644 --- a/lib/wx/src/gen/gl_debug.hrl +++ b/lib/wx/src/gen/gl_debug.hrl @@ -17,7 +17,7 @@ %% %CopyrightEnd% %% This file is generated DO NOT EDIT -gldebug_table() -> +gldebug_table() -> [ {5037, {gl, accum, 0}}, {5038, {gl, alphaFunc, 0}}, diff --git a/lib/wx/src/gen/glu.erl b/lib/wx/src/gen/glu.erl index ae4bac4e06..d410c4663d 100644 --- a/lib/wx/src/gen/glu.erl +++ b/lib/wx/src/gen/glu.erl @@ -20,15 +20,15 @@ %% This file is generated DO NOT EDIT -%% @doc A part of the standard OpenGL Utility api. +%% @doc A part of the standard OpenGL Utility api. %% See <a href="http://www.opengl.org/sdk/docs/man/">www.opengl.org</a> %% -%% Booleans are represented by integers 0 and 1. +%% Booleans are represented by integers 0 and 1. %% @type wx_mem(). see wx.erl on memory allocation functions %% @type enum(). An integer defined in gl.hrl %% @type offset(). An integer which is an offset in an array -%% @type clamp(). A float clamped between 0.0 - 1.0 +%% @type clamp(). A float clamped between 0.0 - 1.0 -module(glu). -compile(inline). @@ -60,7 +60,7 @@ scaleImage/9,sphere/4,unProject/6,unProject4/9]). -%% API +%% API %% @spec (Vec3, [Vec3]) -> {Triangles, VertexPos} %% Vec3 = {float(),float(),float()} @@ -69,8 +69,8 @@ %% @doc General purpose polygon triangulation. %% The first argument is the normal and the second a list of %% vertex positions. Returned is a list of indecies of the vertices -%% and a binary (64bit native float) containing an array of -%% vertex positions, it starts with the vertices in Vs and +%% and a binary (64bit native float) containing an array of +%% vertex positions, it starts with the vertices in Vs and %% may contain newly created vertices in the end. tesselate({Nx,Ny,Nz}, Vs) -> wxe_util:call(5000, <<(length(Vs)):32/native,0:32, 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 68a3b4ccd8..3edfa73599 100644 --- a/lib/wx/src/gen/wxe_debug.hrl +++ b/lib/wx/src/gen/wxe_debug.hrl @@ -770,2512 +770,2517 @@ wxdebug_table() -> {882, {wxControlWithItems, clear, 0}}, {883, {wxControlWithItems, delete, 1}}, {884, {wxControlWithItems, findString, 2}}, - {886, {wxControlWithItems, getClientData, 1}}, - {888, {wxControlWithItems, setClientData, 2}}, - {889, {wxControlWithItems, getCount, 0}}, - {890, {wxControlWithItems, getSelection, 0}}, - {891, {wxControlWithItems, getString, 1}}, - {892, {wxControlWithItems, getStringSelection, 0}}, - {893, {wxControlWithItems, insert_2, 2}}, - {894, {wxControlWithItems, insert_3, 3}}, - {895, {wxControlWithItems, isEmpty, 0}}, - {896, {wxControlWithItems, select, 1}}, - {897, {wxControlWithItems, setSelection, 1}}, - {898, {wxControlWithItems, setString, 2}}, - {899, {wxControlWithItems, setStringSelection, 1}}, - {902, {wxMenu, new_2, 2}}, - {903, {wxMenu, new_1, 1}}, - {905, {wxMenu, destruct, 0}}, - {906, {wxMenu, append_3, 3}}, - {907, {wxMenu, append_1, 1}}, - {908, {wxMenu, append_4_0, 4}}, - {909, {wxMenu, append_4_1, 4}}, - {910, {wxMenu, appendCheckItem, 3}}, - {911, {wxMenu, appendRadioItem, 3}}, - {912, {wxMenu, appendSeparator, 0}}, - {913, {wxMenu, break, 0}}, - {914, {wxMenu, check, 2}}, - {915, {wxMenu, delete_1_0, 1}}, - {916, {wxMenu, delete_1_1, 1}}, - {917, {wxMenu, destroy_1_0, 1}}, - {918, {wxMenu, destroy_1_1, 1}}, - {919, {wxMenu, enable, 2}}, - {920, {wxMenu, findItem_1, 1}}, - {921, {wxMenu, findItem_2, 2}}, - {922, {wxMenu, findItemByPosition, 1}}, - {923, {wxMenu, getHelpString, 1}}, - {924, {wxMenu, getLabel, 1}}, - {925, {wxMenu, getMenuItemCount, 0}}, - {926, {wxMenu, getMenuItems, 0}}, - {928, {wxMenu, getTitle, 0}}, - {929, {wxMenu, insert_2, 2}}, - {930, {wxMenu, insert_3, 3}}, - {931, {wxMenu, insert_5_1, 5}}, - {932, {wxMenu, insert_5_0, 5}}, - {933, {wxMenu, insertCheckItem, 4}}, - {934, {wxMenu, insertRadioItem, 4}}, - {935, {wxMenu, insertSeparator, 1}}, - {936, {wxMenu, isChecked, 1}}, - {937, {wxMenu, isEnabled, 1}}, - {938, {wxMenu, prepend_1, 1}}, - {939, {wxMenu, prepend_2, 2}}, - {940, {wxMenu, prepend_4_1, 4}}, - {941, {wxMenu, prepend_4_0, 4}}, - {942, {wxMenu, prependCheckItem, 3}}, - {943, {wxMenu, prependRadioItem, 3}}, - {944, {wxMenu, prependSeparator, 0}}, - {945, {wxMenu, remove_1_0, 1}}, - {946, {wxMenu, remove_1_1, 1}}, - {947, {wxMenu, setHelpString, 2}}, - {948, {wxMenu, setLabel, 2}}, - {949, {wxMenu, setTitle, 1}}, - {950, {wxMenuItem, new, 1}}, - {952, {wxMenuItem, destruct, 0}}, - {953, {wxMenuItem, check, 1}}, - {954, {wxMenuItem, enable, 1}}, - {955, {wxMenuItem, getBitmap, 0}}, - {956, {wxMenuItem, getHelp, 0}}, - {957, {wxMenuItem, getId, 0}}, - {958, {wxMenuItem, getKind, 0}}, - {959, {wxMenuItem, getLabel, 0}}, - {960, {wxMenuItem, getLabelFromText, 1}}, - {961, {wxMenuItem, getMenu, 0}}, - {962, {wxMenuItem, getText, 0}}, - {963, {wxMenuItem, getSubMenu, 0}}, - {964, {wxMenuItem, isCheckable, 0}}, - {965, {wxMenuItem, isChecked, 0}}, - {966, {wxMenuItem, isEnabled, 0}}, - {967, {wxMenuItem, isSeparator, 0}}, - {968, {wxMenuItem, isSubMenu, 0}}, - {969, {wxMenuItem, setBitmap, 1}}, - {970, {wxMenuItem, setHelp, 1}}, - {971, {wxMenuItem, setMenu, 1}}, - {972, {wxMenuItem, setSubMenu, 1}}, - {973, {wxMenuItem, setText, 1}}, - {974, {wxToolBar, addControl, 1}}, - {975, {wxToolBar, addSeparator, 0}}, - {976, {wxToolBar, addTool_5, 5}}, - {977, {wxToolBar, addTool_4_0, 4}}, - {978, {wxToolBar, addTool_1, 1}}, - {979, {wxToolBar, addTool_4_1, 4}}, - {980, {wxToolBar, addTool_3, 3}}, - {981, {wxToolBar, addTool_6, 6}}, - {982, {wxToolBar, addCheckTool, 4}}, - {983, {wxToolBar, addRadioTool, 4}}, - {984, {wxToolBar, deleteTool, 1}}, - {985, {wxToolBar, deleteToolByPos, 1}}, - {986, {wxToolBar, enableTool, 2}}, - {987, {wxToolBar, findById, 1}}, - {988, {wxToolBar, findControl, 1}}, - {989, {wxToolBar, findToolForPosition, 2}}, - {990, {wxToolBar, getToolSize, 0}}, - {991, {wxToolBar, getToolBitmapSize, 0}}, - {992, {wxToolBar, getMargins, 0}}, - {993, {wxToolBar, getToolEnabled, 1}}, - {994, {wxToolBar, getToolLongHelp, 1}}, - {995, {wxToolBar, getToolPacking, 0}}, - {996, {wxToolBar, getToolPos, 1}}, - {997, {wxToolBar, getToolSeparation, 0}}, - {998, {wxToolBar, getToolShortHelp, 1}}, - {999, {wxToolBar, getToolState, 1}}, - {1000, {wxToolBar, insertControl, 2}}, - {1001, {wxToolBar, insertSeparator, 1}}, - {1002, {wxToolBar, insertTool_5, 5}}, - {1003, {wxToolBar, insertTool_2, 2}}, - {1004, {wxToolBar, insertTool_4, 4}}, - {1005, {wxToolBar, realize, 0}}, - {1006, {wxToolBar, removeTool, 1}}, - {1007, {wxToolBar, setMargins, 2}}, - {1008, {wxToolBar, setToolBitmapSize, 1}}, - {1009, {wxToolBar, setToolLongHelp, 2}}, - {1010, {wxToolBar, setToolPacking, 1}}, - {1011, {wxToolBar, setToolShortHelp, 2}}, - {1012, {wxToolBar, setToolSeparation, 1}}, - {1013, {wxToolBar, toggleTool, 2}}, - {1015, {wxStatusBar, new_0, 0}}, - {1016, {wxStatusBar, new_2, 2}}, - {1018, {wxStatusBar, destruct, 0}}, - {1019, {wxStatusBar, create, 2}}, - {1020, {wxStatusBar, getFieldRect, 2}}, - {1021, {wxStatusBar, getFieldsCount, 0}}, - {1022, {wxStatusBar, getStatusText, 1}}, - {1023, {wxStatusBar, popStatusText, 1}}, - {1024, {wxStatusBar, pushStatusText, 2}}, - {1025, {wxStatusBar, setFieldsCount, 2}}, - {1026, {wxStatusBar, setMinHeight, 1}}, - {1027, {wxStatusBar, setStatusText, 2}}, - {1028, {wxStatusBar, setStatusWidths, 2}}, - {1029, {wxStatusBar, setStatusStyles, 2}}, - {1030, {wxBitmap, new_0, 0}}, - {1031, {wxBitmap, new_3, 3}}, - {1032, {wxBitmap, new_4, 4}}, - {1033, {wxBitmap, new_2_0, 2}}, - {1034, {wxBitmap, new_2_1, 2}}, - {1035, {wxBitmap, destruct, 0}}, - {1036, {wxBitmap, convertToImage, 0}}, - {1037, {wxBitmap, copyFromIcon, 1}}, - {1038, {wxBitmap, create, 3}}, - {1039, {wxBitmap, getDepth, 0}}, - {1040, {wxBitmap, getHeight, 0}}, - {1041, {wxBitmap, getPalette, 0}}, - {1042, {wxBitmap, getMask, 0}}, - {1043, {wxBitmap, getWidth, 0}}, - {1044, {wxBitmap, getSubBitmap, 1}}, - {1045, {wxBitmap, loadFile, 2}}, - {1046, {wxBitmap, ok, 0}}, - {1047, {wxBitmap, saveFile, 3}}, - {1048, {wxBitmap, setDepth, 1}}, - {1049, {wxBitmap, setHeight, 1}}, - {1050, {wxBitmap, setMask, 1}}, - {1051, {wxBitmap, setPalette, 1}}, - {1052, {wxBitmap, setWidth, 1}}, - {1053, {wxIcon, new_0, 0}}, - {1054, {wxIcon, new_2, 2}}, - {1055, {wxIcon, new_1, 1}}, - {1056, {wxIcon, copyFromBitmap, 1}}, - {1057, {wxIcon, 'Destroy', undefined}}, - {1058, {wxIconBundle, new_0, 0}}, - {1059, {wxIconBundle, new_2, 2}}, - {1060, {wxIconBundle, new_1_0, 1}}, - {1061, {wxIconBundle, new_1_1, 1}}, - {1062, {wxIconBundle, destruct, 0}}, - {1063, {wxIconBundle, addIcon_2, 2}}, - {1064, {wxIconBundle, addIcon_1, 1}}, - {1065, {wxIconBundle, getIcon_1_1, 1}}, - {1066, {wxIconBundle, getIcon_1_0, 1}}, - {1067, {wxCursor, new_0, 0}}, - {1068, {wxCursor, new_1_0, 1}}, - {1069, {wxCursor, new_1_1, 1}}, - {1070, {wxCursor, new_4, 4}}, - {1071, {wxCursor, destruct, 0}}, - {1072, {wxCursor, ok, 0}}, - {1073, {wxMask, new_0, 0}}, - {1074, {wxMask, new_2_1, 2}}, - {1075, {wxMask, new_2_0, 2}}, - {1076, {wxMask, new_1, 1}}, - {1077, {wxMask, destruct, 0}}, - {1078, {wxMask, create_2_1, 2}}, - {1079, {wxMask, create_2_0, 2}}, - {1080, {wxMask, create_1, 1}}, - {1081, {wxImage, new_0, 0}}, - {1082, {wxImage, new_3_0, 3}}, - {1083, {wxImage, new_4, 4}}, - {1084, {wxImage, new_5, 5}}, - {1085, {wxImage, new_2, 2}}, - {1086, {wxImage, new_3_1, 3}}, - {1087, {wxImage, blur, 1}}, - {1088, {wxImage, blurHorizontal, 1}}, - {1089, {wxImage, blurVertical, 1}}, - {1090, {wxImage, convertAlphaToMask, 1}}, - {1091, {wxImage, convertToGreyscale, 1}}, - {1092, {wxImage, convertToMono, 3}}, - {1093, {wxImage, copy, 0}}, - {1094, {wxImage, create_3, 3}}, - {1095, {wxImage, create_4, 4}}, - {1096, {wxImage, create_5, 5}}, - {1097, {wxImage, 'Destroy', 0}}, - {1098, {wxImage, findFirstUnusedColour, 4}}, - {1099, {wxImage, getImageExtWildcard, 0}}, - {1100, {wxImage, getAlpha_2, 2}}, - {1101, {wxImage, getAlpha_0, 0}}, - {1102, {wxImage, getBlue, 2}}, - {1103, {wxImage, getData, 0}}, - {1104, {wxImage, getGreen, 2}}, - {1105, {wxImage, getImageCount, 2}}, - {1106, {wxImage, getHeight, 0}}, - {1107, {wxImage, getMaskBlue, 0}}, - {1108, {wxImage, getMaskGreen, 0}}, - {1109, {wxImage, getMaskRed, 0}}, - {1110, {wxImage, getOrFindMaskColour, 3}}, - {1111, {wxImage, getPalette, 0}}, - {1112, {wxImage, getRed, 2}}, - {1113, {wxImage, getSubImage, 1}}, - {1114, {wxImage, getWidth, 0}}, - {1115, {wxImage, hasAlpha, 0}}, - {1116, {wxImage, hasMask, 0}}, - {1117, {wxImage, getOption, 1}}, - {1118, {wxImage, getOptionInt, 1}}, - {1119, {wxImage, hasOption, 1}}, - {1120, {wxImage, initAlpha, 0}}, - {1121, {wxImage, initStandardHandlers, 0}}, - {1122, {wxImage, isTransparent, 3}}, - {1123, {wxImage, loadFile_2, 2}}, - {1124, {wxImage, loadFile_3, 3}}, - {1125, {wxImage, ok, 0}}, - {1126, {wxImage, removeHandler, 1}}, - {1127, {wxImage, mirror, 1}}, - {1128, {wxImage, replace, 6}}, - {1129, {wxImage, rescale, 3}}, - {1130, {wxImage, resize, 3}}, - {1131, {wxImage, rotate, 3}}, - {1132, {wxImage, rotateHue, 1}}, - {1133, {wxImage, rotate90, 1}}, - {1134, {wxImage, saveFile_1, 1}}, - {1135, {wxImage, saveFile_2_0, 2}}, - {1136, {wxImage, saveFile_2_1, 2}}, - {1137, {wxImage, scale, 3}}, - {1138, {wxImage, size, 3}}, - {1139, {wxImage, setAlpha_3, 3}}, - {1140, {wxImage, setAlpha_2, 2}}, - {1141, {wxImage, setData_2, 2}}, - {1142, {wxImage, setData_4, 4}}, - {1143, {wxImage, setMask, 1}}, - {1144, {wxImage, setMaskColour, 3}}, - {1145, {wxImage, setMaskFromImage, 4}}, - {1146, {wxImage, setOption_2_1, 2}}, - {1147, {wxImage, setOption_2_0, 2}}, - {1148, {wxImage, setPalette, 1}}, - {1149, {wxImage, setRGB_5, 5}}, - {1150, {wxImage, setRGB_4, 4}}, - {1151, {wxImage, 'Destroy', undefined}}, - {1152, {wxBrush, new_0, 0}}, - {1153, {wxBrush, new_2, 2}}, - {1154, {wxBrush, new_1, 1}}, - {1156, {wxBrush, destruct, 0}}, - {1157, {wxBrush, getColour, 0}}, - {1158, {wxBrush, getStipple, 0}}, - {1159, {wxBrush, getStyle, 0}}, - {1160, {wxBrush, isHatch, 0}}, - {1161, {wxBrush, isOk, 0}}, - {1162, {wxBrush, setColour_1, 1}}, - {1163, {wxBrush, setColour_3, 3}}, - {1164, {wxBrush, setStipple, 1}}, - {1165, {wxBrush, setStyle, 1}}, - {1166, {wxPen, new_0, 0}}, - {1167, {wxPen, new_2, 2}}, - {1168, {wxPen, destruct, 0}}, - {1169, {wxPen, getCap, 0}}, - {1170, {wxPen, getColour, 0}}, - {1171, {wxPen, getJoin, 0}}, - {1172, {wxPen, getStyle, 0}}, - {1173, {wxPen, getWidth, 0}}, - {1174, {wxPen, isOk, 0}}, - {1175, {wxPen, setCap, 1}}, - {1176, {wxPen, setColour_1, 1}}, - {1177, {wxPen, setColour_3, 3}}, - {1178, {wxPen, setJoin, 1}}, - {1179, {wxPen, setStyle, 1}}, - {1180, {wxPen, setWidth, 1}}, - {1181, {wxRegion, new_0, 0}}, - {1182, {wxRegion, new_4, 4}}, - {1183, {wxRegion, new_2, 2}}, - {1184, {wxRegion, new_1_1, 1}}, - {1186, {wxRegion, new_1_0, 1}}, - {1188, {wxRegion, destruct, 0}}, - {1189, {wxRegion, clear, 0}}, - {1190, {wxRegion, contains_2, 2}}, - {1191, {wxRegion, contains_1_0, 1}}, - {1192, {wxRegion, contains_4, 4}}, - {1193, {wxRegion, contains_1_1, 1}}, - {1194, {wxRegion, convertToBitmap, 0}}, - {1195, {wxRegion, getBox, 0}}, - {1196, {wxRegion, intersect_4, 4}}, - {1197, {wxRegion, intersect_1_1, 1}}, - {1198, {wxRegion, intersect_1_0, 1}}, - {1199, {wxRegion, isEmpty, 0}}, - {1200, {wxRegion, subtract_4, 4}}, - {1201, {wxRegion, subtract_1_1, 1}}, - {1202, {wxRegion, subtract_1_0, 1}}, - {1203, {wxRegion, offset_2, 2}}, - {1204, {wxRegion, offset_1, 1}}, - {1205, {wxRegion, union_4, 4}}, - {1206, {wxRegion, union_1_2, 1}}, - {1207, {wxRegion, union_1_1, 1}}, - {1208, {wxRegion, union_1_0, 1}}, - {1209, {wxRegion, union_3, 3}}, - {1210, {wxRegion, xor_4, 4}}, - {1211, {wxRegion, xor_1_1, 1}}, - {1212, {wxRegion, xor_1_0, 1}}, - {1213, {wxAcceleratorTable, new_0, 0}}, - {1214, {wxAcceleratorTable, new_2, 2}}, - {1215, {wxAcceleratorTable, destruct, 0}}, - {1216, {wxAcceleratorTable, ok, 0}}, - {1217, {wxAcceleratorEntry, new_1_0, 1}}, - {1218, {wxAcceleratorEntry, new_1_1, 1}}, - {1219, {wxAcceleratorEntry, getCommand, 0}}, - {1220, {wxAcceleratorEntry, getFlags, 0}}, - {1221, {wxAcceleratorEntry, getKeyCode, 0}}, - {1222, {wxAcceleratorEntry, set, 4}}, - {1223, {wxAcceleratorEntry, 'Destroy', undefined}}, - {1228, {wxCaret, new_3, 3}}, - {1229, {wxCaret, new_2, 2}}, - {1231, {wxCaret, destruct, 0}}, - {1232, {wxCaret, create_3, 3}}, - {1233, {wxCaret, create_2, 2}}, - {1234, {wxCaret, getBlinkTime, 0}}, - {1236, {wxCaret, getPosition, 0}}, - {1238, {wxCaret, getSize, 0}}, - {1239, {wxCaret, getWindow, 0}}, - {1240, {wxCaret, hide, 0}}, - {1241, {wxCaret, isOk, 0}}, - {1242, {wxCaret, isVisible, 0}}, - {1243, {wxCaret, move_2, 2}}, - {1244, {wxCaret, move_1, 1}}, - {1245, {wxCaret, setBlinkTime, 1}}, - {1246, {wxCaret, setSize_2, 2}}, - {1247, {wxCaret, setSize_1, 1}}, - {1248, {wxCaret, show, 1}}, - {1249, {wxSizer, add_2_1, 2}}, - {1250, {wxSizer, add_2_0, 2}}, - {1251, {wxSizer, add_3, 3}}, - {1252, {wxSizer, add_2_3, 2}}, - {1253, {wxSizer, add_2_2, 2}}, - {1254, {wxSizer, addSpacer, 1}}, - {1255, {wxSizer, addStretchSpacer, 1}}, - {1256, {wxSizer, calcMin, 0}}, - {1257, {wxSizer, clear, 1}}, - {1258, {wxSizer, detach_1_2, 1}}, - {1259, {wxSizer, detach_1_1, 1}}, - {1260, {wxSizer, detach_1_0, 1}}, - {1261, {wxSizer, fit, 1}}, - {1262, {wxSizer, fitInside, 1}}, - {1263, {wxSizer, getChildren, 0}}, - {1264, {wxSizer, getItem_2_1, 2}}, - {1265, {wxSizer, getItem_2_0, 2}}, - {1266, {wxSizer, getItem_1, 1}}, - {1267, {wxSizer, getSize, 0}}, - {1268, {wxSizer, getPosition, 0}}, - {1269, {wxSizer, getMinSize, 0}}, - {1270, {wxSizer, hide_2_0, 2}}, - {1271, {wxSizer, hide_2_1, 2}}, - {1272, {wxSizer, hide_1, 1}}, - {1273, {wxSizer, insert_3_1, 3}}, - {1274, {wxSizer, insert_3_0, 3}}, - {1275, {wxSizer, insert_4, 4}}, - {1276, {wxSizer, insert_3_3, 3}}, - {1277, {wxSizer, insert_3_2, 3}}, - {1278, {wxSizer, insert_2, 2}}, - {1279, {wxSizer, insertSpacer, 2}}, - {1280, {wxSizer, insertStretchSpacer, 2}}, - {1281, {wxSizer, isShown_1_2, 1}}, - {1282, {wxSizer, isShown_1_1, 1}}, - {1283, {wxSizer, isShown_1_0, 1}}, - {1284, {wxSizer, layout, 0}}, - {1285, {wxSizer, prepend_2_1, 2}}, - {1286, {wxSizer, prepend_2_0, 2}}, - {1287, {wxSizer, prepend_3, 3}}, - {1288, {wxSizer, prepend_2_3, 2}}, - {1289, {wxSizer, prepend_2_2, 2}}, - {1290, {wxSizer, prepend_1, 1}}, - {1291, {wxSizer, prependSpacer, 1}}, - {1292, {wxSizer, prependStretchSpacer, 1}}, - {1293, {wxSizer, recalcSizes, 0}}, - {1294, {wxSizer, remove_1_1, 1}}, - {1295, {wxSizer, remove_1_0, 1}}, - {1296, {wxSizer, replace_3_1, 3}}, - {1297, {wxSizer, replace_3_0, 3}}, - {1298, {wxSizer, replace_2, 2}}, - {1299, {wxSizer, setDimension, 4}}, - {1300, {wxSizer, setMinSize_2, 2}}, - {1301, {wxSizer, setMinSize_1, 1}}, - {1302, {wxSizer, setItemMinSize_3_2, 3}}, - {1303, {wxSizer, setItemMinSize_2_2, 2}}, - {1304, {wxSizer, setItemMinSize_3_1, 3}}, - {1305, {wxSizer, setItemMinSize_2_1, 2}}, - {1306, {wxSizer, setItemMinSize_3_0, 3}}, - {1307, {wxSizer, setItemMinSize_2_0, 2}}, - {1308, {wxSizer, setSizeHints, 1}}, - {1309, {wxSizer, setVirtualSizeHints, 1}}, - {1310, {wxSizer, show_2_2, 2}}, - {1311, {wxSizer, show_2_1, 2}}, - {1312, {wxSizer, show_2_0, 2}}, - {1313, {wxSizer, show_1, 1}}, - {1314, {wxSizerFlags, new, 1}}, - {1315, {wxSizerFlags, align, 1}}, - {1316, {wxSizerFlags, border_2, 2}}, - {1317, {wxSizerFlags, border_1, 1}}, - {1318, {wxSizerFlags, center, 0}}, - {1319, {wxSizerFlags, centre, 0}}, - {1320, {wxSizerFlags, expand, 0}}, - {1321, {wxSizerFlags, left, 0}}, - {1322, {wxSizerFlags, proportion, 1}}, - {1323, {wxSizerFlags, right, 0}}, - {1324, {wxSizerFlags, 'Destroy', undefined}}, - {1325, {wxSizerItem, new_5_1, 5}}, - {1326, {wxSizerItem, new_2_1, 2}}, - {1327, {wxSizerItem, new_5_0, 5}}, - {1328, {wxSizerItem, new_2_0, 2}}, - {1329, {wxSizerItem, new_6, 6}}, - {1330, {wxSizerItem, new_3, 3}}, - {1331, {wxSizerItem, new_0, 0}}, - {1332, {wxSizerItem, destruct, 0}}, - {1333, {wxSizerItem, calcMin, 0}}, - {1334, {wxSizerItem, deleteWindows, 0}}, - {1335, {wxSizerItem, detachSizer, 0}}, - {1336, {wxSizerItem, getBorder, 0}}, - {1337, {wxSizerItem, getFlag, 0}}, - {1338, {wxSizerItem, getMinSize, 0}}, - {1339, {wxSizerItem, getPosition, 0}}, - {1340, {wxSizerItem, getProportion, 0}}, - {1341, {wxSizerItem, getRatio, 0}}, - {1342, {wxSizerItem, getRect, 0}}, - {1343, {wxSizerItem, getSize, 0}}, - {1344, {wxSizerItem, getSizer, 0}}, - {1345, {wxSizerItem, getSpacer, 0}}, - {1346, {wxSizerItem, getUserData, 0}}, - {1347, {wxSizerItem, getWindow, 0}}, - {1348, {wxSizerItem, isSizer, 0}}, - {1349, {wxSizerItem, isShown, 0}}, - {1350, {wxSizerItem, isSpacer, 0}}, - {1351, {wxSizerItem, isWindow, 0}}, - {1352, {wxSizerItem, setBorder, 1}}, - {1353, {wxSizerItem, setDimension, 2}}, - {1354, {wxSizerItem, setFlag, 1}}, - {1355, {wxSizerItem, setInitSize, 2}}, - {1356, {wxSizerItem, setMinSize_1, 1}}, - {1357, {wxSizerItem, setMinSize_2, 2}}, - {1358, {wxSizerItem, setProportion, 1}}, - {1359, {wxSizerItem, setRatio_2, 2}}, - {1360, {wxSizerItem, setRatio_1_1, 1}}, - {1361, {wxSizerItem, setRatio_1_0, 1}}, - {1362, {wxSizerItem, setSizer, 1}}, - {1363, {wxSizerItem, setSpacer_1, 1}}, - {1364, {wxSizerItem, setSpacer_2, 2}}, - {1365, {wxSizerItem, setWindow, 1}}, - {1366, {wxSizerItem, show, 1}}, - {1367, {wxBoxSizer, new, 1}}, - {1368, {wxBoxSizer, getOrientation, 0}}, - {1369, {wxBoxSizer, 'Destroy', undefined}}, - {1370, {wxStaticBoxSizer, new_2, 2}}, - {1371, {wxStaticBoxSizer, new_3, 3}}, - {1372, {wxStaticBoxSizer, getStaticBox, 0}}, - {1373, {wxStaticBoxSizer, 'Destroy', undefined}}, - {1374, {wxGridSizer, new_4, 4}}, - {1375, {wxGridSizer, new_2, 2}}, - {1376, {wxGridSizer, getCols, 0}}, - {1377, {wxGridSizer, getHGap, 0}}, - {1378, {wxGridSizer, getRows, 0}}, - {1379, {wxGridSizer, getVGap, 0}}, - {1380, {wxGridSizer, setCols, 1}}, - {1381, {wxGridSizer, setHGap, 1}}, - {1382, {wxGridSizer, setRows, 1}}, - {1383, {wxGridSizer, setVGap, 1}}, - {1384, {wxGridSizer, 'Destroy', undefined}}, - {1385, {wxFlexGridSizer, new_4, 4}}, - {1386, {wxFlexGridSizer, new_2, 2}}, - {1387, {wxFlexGridSizer, addGrowableCol, 2}}, - {1388, {wxFlexGridSizer, addGrowableRow, 2}}, - {1389, {wxFlexGridSizer, getFlexibleDirection, 0}}, - {1390, {wxFlexGridSizer, getNonFlexibleGrowMode, 0}}, - {1391, {wxFlexGridSizer, removeGrowableCol, 1}}, - {1392, {wxFlexGridSizer, removeGrowableRow, 1}}, - {1393, {wxFlexGridSizer, setFlexibleDirection, 1}}, - {1394, {wxFlexGridSizer, setNonFlexibleGrowMode, 1}}, - {1395, {wxFlexGridSizer, 'Destroy', undefined}}, - {1396, {wxGridBagSizer, new, 1}}, - {1397, {wxGridBagSizer, add_3_2, 3}}, - {1398, {wxGridBagSizer, add_3_1, 3}}, - {1399, {wxGridBagSizer, add_4, 4}}, - {1400, {wxGridBagSizer, add_1_0, 1}}, - {1401, {wxGridBagSizer, add_2_1, 2}}, - {1402, {wxGridBagSizer, add_2_0, 2}}, - {1403, {wxGridBagSizer, add_3_0, 3}}, - {1404, {wxGridBagSizer, add_1_1, 1}}, - {1405, {wxGridBagSizer, calcMin, 0}}, - {1406, {wxGridBagSizer, checkForIntersection_2, 2}}, - {1407, {wxGridBagSizer, checkForIntersection_3, 3}}, - {1408, {wxGridBagSizer, findItem_1_1, 1}}, - {1409, {wxGridBagSizer, findItem_1_0, 1}}, - {1410, {wxGridBagSizer, findItemAtPoint, 1}}, - {1411, {wxGridBagSizer, findItemAtPosition, 1}}, - {1412, {wxGridBagSizer, findItemWithData, 1}}, - {1413, {wxGridBagSizer, getCellSize, 2}}, - {1414, {wxGridBagSizer, getEmptyCellSize, 0}}, - {1415, {wxGridBagSizer, getItemPosition_1_2, 1}}, - {1416, {wxGridBagSizer, getItemPosition_1_1, 1}}, - {1417, {wxGridBagSizer, getItemPosition_1_0, 1}}, - {1418, {wxGridBagSizer, getItemSpan_1_2, 1}}, - {1419, {wxGridBagSizer, getItemSpan_1_1, 1}}, - {1420, {wxGridBagSizer, getItemSpan_1_0, 1}}, - {1421, {wxGridBagSizer, setEmptyCellSize, 1}}, - {1422, {wxGridBagSizer, setItemPosition_2_2, 2}}, - {1423, {wxGridBagSizer, setItemPosition_2_1, 2}}, - {1424, {wxGridBagSizer, setItemPosition_2_0, 2}}, - {1425, {wxGridBagSizer, setItemSpan_2_2, 2}}, - {1426, {wxGridBagSizer, setItemSpan_2_1, 2}}, - {1427, {wxGridBagSizer, setItemSpan_2_0, 2}}, - {1428, {wxGridBagSizer, 'Destroy', undefined}}, - {1429, {wxStdDialogButtonSizer, new, 0}}, - {1430, {wxStdDialogButtonSizer, addButton, 1}}, - {1431, {wxStdDialogButtonSizer, realize, 0}}, - {1432, {wxStdDialogButtonSizer, setAffirmativeButton, 1}}, - {1433, {wxStdDialogButtonSizer, setCancelButton, 1}}, - {1434, {wxStdDialogButtonSizer, setNegativeButton, 1}}, - {1435, {wxStdDialogButtonSizer, 'Destroy', undefined}}, - {1436, {wxFont, new_0, 0}}, - {1437, {wxFont, new_1, 1}}, - {1438, {wxFont, new_5, 5}}, - {1440, {wxFont, destruct, 0}}, - {1441, {wxFont, isFixedWidth, 0}}, - {1442, {wxFont, getDefaultEncoding, 0}}, - {1443, {wxFont, getFaceName, 0}}, - {1444, {wxFont, getFamily, 0}}, - {1445, {wxFont, getNativeFontInfoDesc, 0}}, - {1446, {wxFont, getNativeFontInfoUserDesc, 0}}, - {1447, {wxFont, getPointSize, 0}}, - {1448, {wxFont, getStyle, 0}}, - {1449, {wxFont, getUnderlined, 0}}, - {1450, {wxFont, getWeight, 0}}, - {1451, {wxFont, ok, 0}}, - {1452, {wxFont, setDefaultEncoding, 1}}, - {1453, {wxFont, setFaceName, 1}}, - {1454, {wxFont, setFamily, 1}}, - {1455, {wxFont, setPointSize, 1}}, - {1456, {wxFont, setStyle, 1}}, - {1457, {wxFont, setUnderlined, 1}}, - {1458, {wxFont, setWeight, 1}}, - {1459, {wxToolTip, enable, 1}}, - {1460, {wxToolTip, setDelay, 1}}, - {1461, {wxToolTip, new, 1}}, - {1462, {wxToolTip, setTip, 1}}, - {1463, {wxToolTip, getTip, 0}}, - {1464, {wxToolTip, getWindow, 0}}, - {1465, {wxToolTip, 'Destroy', undefined}}, - {1467, {wxButton, new_3, 3}}, - {1468, {wxButton, new_0, 0}}, - {1469, {wxButton, destruct, 0}}, - {1470, {wxButton, create, 3}}, - {1471, {wxButton, getDefaultSize, 0}}, - {1472, {wxButton, setDefault, 0}}, - {1473, {wxButton, setLabel, 1}}, - {1475, {wxBitmapButton, new_4, 4}}, - {1476, {wxBitmapButton, new_0, 0}}, - {1477, {wxBitmapButton, create, 4}}, - {1478, {wxBitmapButton, getBitmapDisabled, 0}}, - {1480, {wxBitmapButton, getBitmapFocus, 0}}, - {1482, {wxBitmapButton, getBitmapLabel, 0}}, - {1484, {wxBitmapButton, getBitmapSelected, 0}}, - {1486, {wxBitmapButton, setBitmapDisabled, 1}}, - {1487, {wxBitmapButton, setBitmapFocus, 1}}, - {1488, {wxBitmapButton, setBitmapLabel, 1}}, - {1489, {wxBitmapButton, setBitmapSelected, 1}}, - {1490, {wxBitmapButton, 'Destroy', undefined}}, - {1491, {wxToggleButton, new_0, 0}}, - {1492, {wxToggleButton, new_4, 4}}, - {1493, {wxToggleButton, create, 4}}, - {1494, {wxToggleButton, getValue, 0}}, - {1495, {wxToggleButton, setValue, 1}}, - {1496, {wxToggleButton, 'Destroy', undefined}}, - {1497, {wxCalendarCtrl, new_0, 0}}, - {1498, {wxCalendarCtrl, new_3, 3}}, - {1499, {wxCalendarCtrl, create, 3}}, - {1500, {wxCalendarCtrl, destruct, 0}}, - {1501, {wxCalendarCtrl, setDate, 1}}, - {1502, {wxCalendarCtrl, getDate, 0}}, - {1503, {wxCalendarCtrl, enableYearChange, 1}}, - {1504, {wxCalendarCtrl, enableMonthChange, 1}}, - {1505, {wxCalendarCtrl, enableHolidayDisplay, 1}}, - {1506, {wxCalendarCtrl, setHeaderColours, 2}}, - {1507, {wxCalendarCtrl, getHeaderColourFg, 0}}, - {1508, {wxCalendarCtrl, getHeaderColourBg, 0}}, - {1509, {wxCalendarCtrl, setHighlightColours, 2}}, - {1510, {wxCalendarCtrl, getHighlightColourFg, 0}}, - {1511, {wxCalendarCtrl, getHighlightColourBg, 0}}, - {1512, {wxCalendarCtrl, setHolidayColours, 2}}, - {1513, {wxCalendarCtrl, getHolidayColourFg, 0}}, - {1514, {wxCalendarCtrl, getHolidayColourBg, 0}}, - {1515, {wxCalendarCtrl, getAttr, 1}}, - {1516, {wxCalendarCtrl, setAttr, 2}}, - {1517, {wxCalendarCtrl, setHoliday, 1}}, - {1518, {wxCalendarCtrl, resetAttr, 1}}, - {1519, {wxCalendarCtrl, hitTest, 2}}, - {1520, {wxCalendarDateAttr, new_0, 0}}, - {1521, {wxCalendarDateAttr, new_2_1, 2}}, - {1522, {wxCalendarDateAttr, new_2_0, 2}}, - {1523, {wxCalendarDateAttr, setTextColour, 1}}, - {1524, {wxCalendarDateAttr, setBackgroundColour, 1}}, - {1525, {wxCalendarDateAttr, setBorderColour, 1}}, - {1526, {wxCalendarDateAttr, setFont, 1}}, - {1527, {wxCalendarDateAttr, setBorder, 1}}, - {1528, {wxCalendarDateAttr, setHoliday, 1}}, - {1529, {wxCalendarDateAttr, hasTextColour, 0}}, - {1530, {wxCalendarDateAttr, hasBackgroundColour, 0}}, - {1531, {wxCalendarDateAttr, hasBorderColour, 0}}, - {1532, {wxCalendarDateAttr, hasFont, 0}}, - {1533, {wxCalendarDateAttr, hasBorder, 0}}, - {1534, {wxCalendarDateAttr, isHoliday, 0}}, - {1535, {wxCalendarDateAttr, getTextColour, 0}}, - {1536, {wxCalendarDateAttr, getBackgroundColour, 0}}, - {1537, {wxCalendarDateAttr, getBorderColour, 0}}, - {1538, {wxCalendarDateAttr, getFont, 0}}, - {1539, {wxCalendarDateAttr, getBorder, 0}}, - {1540, {wxCalendarDateAttr, 'Destroy', undefined}}, - {1542, {wxCheckBox, new_4, 4}}, - {1543, {wxCheckBox, new_0, 0}}, - {1544, {wxCheckBox, create, 4}}, - {1545, {wxCheckBox, getValue, 0}}, - {1546, {wxCheckBox, get3StateValue, 0}}, - {1547, {wxCheckBox, is3rdStateAllowedForUser, 0}}, - {1548, {wxCheckBox, is3State, 0}}, - {1549, {wxCheckBox, isChecked, 0}}, - {1550, {wxCheckBox, setValue, 1}}, - {1551, {wxCheckBox, set3StateValue, 1}}, - {1552, {wxCheckBox, 'Destroy', undefined}}, - {1553, {wxCheckListBox, new_0, 0}}, - {1555, {wxCheckListBox, new_3, 3}}, - {1556, {wxCheckListBox, check, 2}}, - {1557, {wxCheckListBox, isChecked, 1}}, - {1558, {wxCheckListBox, 'Destroy', undefined}}, - {1561, {wxChoice, new_3, 3}}, - {1562, {wxChoice, new_0, 0}}, - {1564, {wxChoice, destruct, 0}}, - {1566, {wxChoice, create, 6}}, - {1567, {wxChoice, delete, 1}}, - {1568, {wxChoice, getColumns, 0}}, - {1569, {wxChoice, setColumns, 1}}, - {1570, {wxComboBox, new_0, 0}}, - {1572, {wxComboBox, new_3, 3}}, - {1573, {wxComboBox, destruct, 0}}, - {1575, {wxComboBox, create, 7}}, - {1576, {wxComboBox, canCopy, 0}}, - {1577, {wxComboBox, canCut, 0}}, - {1578, {wxComboBox, canPaste, 0}}, - {1579, {wxComboBox, canRedo, 0}}, - {1580, {wxComboBox, canUndo, 0}}, - {1581, {wxComboBox, copy, 0}}, - {1582, {wxComboBox, cut, 0}}, - {1583, {wxComboBox, getInsertionPoint, 0}}, - {1584, {wxComboBox, getLastPosition, 0}}, - {1585, {wxComboBox, getValue, 0}}, - {1586, {wxComboBox, paste, 0}}, - {1587, {wxComboBox, redo, 0}}, - {1588, {wxComboBox, replace, 3}}, - {1589, {wxComboBox, remove, 2}}, - {1590, {wxComboBox, setInsertionPoint, 1}}, - {1591, {wxComboBox, setInsertionPointEnd, 0}}, - {1592, {wxComboBox, setSelection_1, 1}}, - {1593, {wxComboBox, setSelection_2, 2}}, - {1594, {wxComboBox, setValue, 1}}, - {1595, {wxComboBox, undo, 0}}, - {1596, {wxGauge, new_0, 0}}, - {1597, {wxGauge, new_4, 4}}, - {1598, {wxGauge, create, 4}}, - {1599, {wxGauge, getBezelFace, 0}}, - {1600, {wxGauge, getRange, 0}}, - {1601, {wxGauge, getShadowWidth, 0}}, - {1602, {wxGauge, getValue, 0}}, - {1603, {wxGauge, isVertical, 0}}, - {1604, {wxGauge, setBezelFace, 1}}, - {1605, {wxGauge, setRange, 1}}, - {1606, {wxGauge, setShadowWidth, 1}}, - {1607, {wxGauge, setValue, 1}}, - {1608, {wxGauge, pulse, 0}}, - {1609, {wxGauge, 'Destroy', undefined}}, - {1610, {wxGenericDirCtrl, new_0, 0}}, - {1611, {wxGenericDirCtrl, new_2, 2}}, - {1612, {wxGenericDirCtrl, destruct, 0}}, - {1613, {wxGenericDirCtrl, create, 2}}, - {1614, {wxGenericDirCtrl, init, 0}}, - {1615, {wxGenericDirCtrl, collapseTree, 0}}, - {1616, {wxGenericDirCtrl, expandPath, 1}}, - {1617, {wxGenericDirCtrl, getDefaultPath, 0}}, - {1618, {wxGenericDirCtrl, getPath, 0}}, - {1619, {wxGenericDirCtrl, getFilePath, 0}}, - {1620, {wxGenericDirCtrl, getFilter, 0}}, - {1621, {wxGenericDirCtrl, getFilterIndex, 0}}, - {1622, {wxGenericDirCtrl, getRootId, 0}}, - {1623, {wxGenericDirCtrl, getTreeCtrl, 0}}, - {1624, {wxGenericDirCtrl, reCreateTree, 0}}, - {1625, {wxGenericDirCtrl, setDefaultPath, 1}}, - {1626, {wxGenericDirCtrl, setFilter, 1}}, - {1627, {wxGenericDirCtrl, setFilterIndex, 1}}, - {1628, {wxGenericDirCtrl, setPath, 1}}, - {1630, {wxStaticBox, new_4, 4}}, - {1631, {wxStaticBox, new_0, 0}}, - {1632, {wxStaticBox, create, 4}}, - {1633, {wxStaticBox, 'Destroy', undefined}}, - {1635, {wxStaticLine, new_2, 2}}, - {1636, {wxStaticLine, new_0, 0}}, - {1637, {wxStaticLine, create, 2}}, - {1638, {wxStaticLine, isVertical, 0}}, - {1639, {wxStaticLine, getDefaultSize, 0}}, - {1640, {wxStaticLine, 'Destroy', undefined}}, - {1643, {wxListBox, new_3, 3}}, - {1644, {wxListBox, new_0, 0}}, - {1646, {wxListBox, destruct, 0}}, - {1648, {wxListBox, create, 6}}, - {1649, {wxListBox, deselect, 1}}, - {1650, {wxListBox, getSelections, 1}}, - {1651, {wxListBox, insertItems, 2}}, - {1652, {wxListBox, isSelected, 1}}, - {1654, {wxListBox, set, 2}}, - {1655, {wxListBox, hitTest, 1}}, - {1656, {wxListBox, setFirstItem_1_0, 1}}, - {1657, {wxListBox, setFirstItem_1_1, 1}}, - {1658, {wxListCtrl, new_0, 0}}, - {1659, {wxListCtrl, new_2, 2}}, - {1660, {wxListCtrl, arrange, 1}}, - {1661, {wxListCtrl, assignImageList, 2}}, - {1662, {wxListCtrl, clearAll, 0}}, - {1663, {wxListCtrl, create, 2}}, - {1664, {wxListCtrl, deleteAllItems, 0}}, - {1665, {wxListCtrl, deleteColumn, 1}}, - {1666, {wxListCtrl, deleteItem, 1}}, - {1667, {wxListCtrl, editLabel, 1}}, - {1668, {wxListCtrl, ensureVisible, 1}}, - {1669, {wxListCtrl, findItem_3_0, 3}}, - {1670, {wxListCtrl, findItem_3_1, 3}}, - {1671, {wxListCtrl, getColumn, 2}}, - {1672, {wxListCtrl, getColumnCount, 0}}, - {1673, {wxListCtrl, getColumnWidth, 1}}, - {1674, {wxListCtrl, getCountPerPage, 0}}, - {1675, {wxListCtrl, getEditControl, 0}}, - {1676, {wxListCtrl, getImageList, 1}}, - {1677, {wxListCtrl, getItem, 1}}, - {1678, {wxListCtrl, getItemBackgroundColour, 1}}, - {1679, {wxListCtrl, getItemCount, 0}}, - {1680, {wxListCtrl, getItemData, 1}}, - {1681, {wxListCtrl, getItemFont, 1}}, - {1682, {wxListCtrl, getItemPosition, 2}}, - {1683, {wxListCtrl, getItemRect, 3}}, - {1684, {wxListCtrl, getItemSpacing, 0}}, - {1685, {wxListCtrl, getItemState, 2}}, - {1686, {wxListCtrl, getItemText, 1}}, - {1687, {wxListCtrl, getItemTextColour, 1}}, - {1688, {wxListCtrl, getNextItem, 2}}, - {1689, {wxListCtrl, getSelectedItemCount, 0}}, - {1690, {wxListCtrl, getTextColour, 0}}, - {1691, {wxListCtrl, getTopItem, 0}}, - {1692, {wxListCtrl, getViewRect, 0}}, - {1693, {wxListCtrl, hitTest, 2}}, - {1694, {wxListCtrl, insertColumn_2, 2}}, - {1695, {wxListCtrl, insertColumn_3, 3}}, - {1696, {wxListCtrl, insertItem_1, 1}}, - {1697, {wxListCtrl, insertItem_2_1, 2}}, - {1698, {wxListCtrl, insertItem_2_0, 2}}, - {1699, {wxListCtrl, insertItem_3, 3}}, - {1700, {wxListCtrl, refreshItem, 1}}, - {1701, {wxListCtrl, refreshItems, 2}}, - {1702, {wxListCtrl, scrollList, 2}}, - {1703, {wxListCtrl, setBackgroundColour, 1}}, - {1704, {wxListCtrl, setColumn, 2}}, - {1705, {wxListCtrl, setColumnWidth, 2}}, - {1706, {wxListCtrl, setImageList, 2}}, - {1707, {wxListCtrl, setItem_1, 1}}, - {1708, {wxListCtrl, setItem_4, 4}}, - {1709, {wxListCtrl, setItemBackgroundColour, 2}}, - {1710, {wxListCtrl, setItemCount, 1}}, - {1711, {wxListCtrl, setItemData, 2}}, - {1712, {wxListCtrl, setItemFont, 2}}, - {1713, {wxListCtrl, setItemImage, 3}}, - {1714, {wxListCtrl, setItemColumnImage, 3}}, - {1715, {wxListCtrl, setItemPosition, 2}}, - {1716, {wxListCtrl, setItemState, 3}}, - {1717, {wxListCtrl, setItemText, 2}}, - {1718, {wxListCtrl, setItemTextColour, 2}}, - {1719, {wxListCtrl, setSingleStyle, 2}}, - {1720, {wxListCtrl, setTextColour, 1}}, - {1721, {wxListCtrl, setWindowStyleFlag, 1}}, - {1722, {wxListCtrl, sortItems, 2}}, - {1723, {wxListCtrl, 'Destroy', undefined}}, - {1724, {wxListView, clearColumnImage, 1}}, - {1725, {wxListView, focus, 1}}, - {1726, {wxListView, getFirstSelected, 0}}, - {1727, {wxListView, getFocusedItem, 0}}, - {1728, {wxListView, getNextSelected, 1}}, - {1729, {wxListView, isSelected, 1}}, - {1730, {wxListView, select, 2}}, - {1731, {wxListView, setColumnImage, 2}}, - {1732, {wxListItem, new_0, 0}}, - {1733, {wxListItem, new_1, 1}}, - {1734, {wxListItem, destruct, 0}}, - {1735, {wxListItem, clear, 0}}, - {1736, {wxListItem, getAlign, 0}}, - {1737, {wxListItem, getBackgroundColour, 0}}, - {1738, {wxListItem, getColumn, 0}}, - {1739, {wxListItem, getFont, 0}}, - {1740, {wxListItem, getId, 0}}, - {1741, {wxListItem, getImage, 0}}, - {1742, {wxListItem, getMask, 0}}, - {1743, {wxListItem, getState, 0}}, - {1744, {wxListItem, getText, 0}}, - {1745, {wxListItem, getTextColour, 0}}, - {1746, {wxListItem, getWidth, 0}}, - {1747, {wxListItem, setAlign, 1}}, - {1748, {wxListItem, setBackgroundColour, 1}}, - {1749, {wxListItem, setColumn, 1}}, - {1750, {wxListItem, setFont, 1}}, - {1751, {wxListItem, setId, 1}}, - {1752, {wxListItem, setImage, 1}}, - {1753, {wxListItem, setMask, 1}}, - {1754, {wxListItem, setState, 1}}, - {1755, {wxListItem, setStateMask, 1}}, - {1756, {wxListItem, setText, 1}}, - {1757, {wxListItem, setTextColour, 1}}, - {1758, {wxListItem, setWidth, 1}}, - {1759, {wxImageList, new_0, 0}}, - {1760, {wxImageList, new_3, 3}}, - {1761, {wxImageList, add_1, 1}}, - {1762, {wxImageList, add_2_0, 2}}, - {1763, {wxImageList, add_2_1, 2}}, - {1764, {wxImageList, create, 3}}, - {1766, {wxImageList, draw, 5}}, - {1767, {wxImageList, getBitmap, 1}}, - {1768, {wxImageList, getIcon, 1}}, - {1769, {wxImageList, getImageCount, 0}}, - {1770, {wxImageList, getSize, 3}}, - {1771, {wxImageList, remove, 1}}, - {1772, {wxImageList, removeAll, 0}}, - {1773, {wxImageList, replace_2, 2}}, - {1774, {wxImageList, replace_3, 3}}, - {1775, {wxImageList, 'Destroy', undefined}}, - {1776, {wxTextAttr, new_0, 0}}, - {1777, {wxTextAttr, new_2, 2}}, - {1778, {wxTextAttr, getAlignment, 0}}, - {1779, {wxTextAttr, getBackgroundColour, 0}}, - {1780, {wxTextAttr, getFont, 0}}, - {1781, {wxTextAttr, getLeftIndent, 0}}, - {1782, {wxTextAttr, getLeftSubIndent, 0}}, - {1783, {wxTextAttr, getRightIndent, 0}}, - {1784, {wxTextAttr, getTabs, 0}}, - {1785, {wxTextAttr, getTextColour, 0}}, - {1786, {wxTextAttr, hasBackgroundColour, 0}}, - {1787, {wxTextAttr, hasFont, 0}}, - {1788, {wxTextAttr, hasTextColour, 0}}, - {1789, {wxTextAttr, getFlags, 0}}, - {1790, {wxTextAttr, isDefault, 0}}, - {1791, {wxTextAttr, setAlignment, 1}}, - {1792, {wxTextAttr, setBackgroundColour, 1}}, - {1793, {wxTextAttr, setFlags, 1}}, - {1794, {wxTextAttr, setFont, 2}}, - {1795, {wxTextAttr, setLeftIndent, 2}}, - {1796, {wxTextAttr, setRightIndent, 1}}, - {1797, {wxTextAttr, setTabs, 1}}, - {1798, {wxTextAttr, setTextColour, 1}}, - {1799, {wxTextAttr, 'Destroy', undefined}}, - {1801, {wxTextCtrl, new_3, 3}}, - {1802, {wxTextCtrl, new_0, 0}}, - {1804, {wxTextCtrl, destruct, 0}}, - {1805, {wxTextCtrl, appendText, 1}}, - {1806, {wxTextCtrl, canCopy, 0}}, - {1807, {wxTextCtrl, canCut, 0}}, - {1808, {wxTextCtrl, canPaste, 0}}, - {1809, {wxTextCtrl, canRedo, 0}}, - {1810, {wxTextCtrl, canUndo, 0}}, - {1811, {wxTextCtrl, clear, 0}}, - {1812, {wxTextCtrl, copy, 0}}, - {1813, {wxTextCtrl, create, 3}}, - {1814, {wxTextCtrl, cut, 0}}, - {1815, {wxTextCtrl, discardEdits, 0}}, - {1816, {wxTextCtrl, emulateKeyPress, 1}}, - {1817, {wxTextCtrl, getDefaultStyle, 0}}, - {1818, {wxTextCtrl, getInsertionPoint, 0}}, - {1819, {wxTextCtrl, getLastPosition, 0}}, - {1820, {wxTextCtrl, getLineLength, 1}}, - {1821, {wxTextCtrl, getLineText, 1}}, - {1822, {wxTextCtrl, getNumberOfLines, 0}}, - {1823, {wxTextCtrl, getRange, 2}}, - {1824, {wxTextCtrl, getSelection, 2}}, - {1825, {wxTextCtrl, getStringSelection, 0}}, - {1826, {wxTextCtrl, getStyle, 2}}, - {1827, {wxTextCtrl, getValue, 0}}, - {1828, {wxTextCtrl, isEditable, 0}}, - {1829, {wxTextCtrl, isModified, 0}}, - {1830, {wxTextCtrl, isMultiLine, 0}}, - {1831, {wxTextCtrl, isSingleLine, 0}}, - {1832, {wxTextCtrl, loadFile, 2}}, - {1833, {wxTextCtrl, markDirty, 0}}, - {1834, {wxTextCtrl, paste, 0}}, - {1835, {wxTextCtrl, positionToXY, 3}}, - {1836, {wxTextCtrl, redo, 0}}, - {1837, {wxTextCtrl, remove, 2}}, - {1838, {wxTextCtrl, replace, 3}}, - {1839, {wxTextCtrl, saveFile, 1}}, - {1840, {wxTextCtrl, setDefaultStyle, 1}}, - {1841, {wxTextCtrl, setEditable, 1}}, - {1842, {wxTextCtrl, setInsertionPoint, 1}}, - {1843, {wxTextCtrl, setInsertionPointEnd, 0}}, - {1845, {wxTextCtrl, setMaxLength, 1}}, - {1846, {wxTextCtrl, setSelection, 2}}, - {1847, {wxTextCtrl, setStyle, 3}}, - {1848, {wxTextCtrl, setValue, 1}}, - {1849, {wxTextCtrl, showPosition, 1}}, - {1850, {wxTextCtrl, undo, 0}}, - {1851, {wxTextCtrl, writeText, 1}}, - {1852, {wxTextCtrl, xYToPosition, 2}}, - {1855, {wxNotebook, new_0, 0}}, - {1856, {wxNotebook, new_3, 3}}, - {1857, {wxNotebook, destruct, 0}}, - {1858, {wxNotebook, addPage, 3}}, - {1859, {wxNotebook, advanceSelection, 1}}, - {1860, {wxNotebook, assignImageList, 1}}, - {1861, {wxNotebook, create, 3}}, - {1862, {wxNotebook, deleteAllPages, 0}}, - {1863, {wxNotebook, deletePage, 1}}, - {1864, {wxNotebook, removePage, 1}}, - {1865, {wxNotebook, getCurrentPage, 0}}, - {1866, {wxNotebook, getImageList, 0}}, - {1868, {wxNotebook, getPage, 1}}, - {1869, {wxNotebook, getPageCount, 0}}, - {1870, {wxNotebook, getPageImage, 1}}, - {1871, {wxNotebook, getPageText, 1}}, - {1872, {wxNotebook, getRowCount, 0}}, - {1873, {wxNotebook, getSelection, 0}}, - {1874, {wxNotebook, getThemeBackgroundColour, 0}}, - {1876, {wxNotebook, hitTest, 2}}, - {1878, {wxNotebook, insertPage, 4}}, - {1879, {wxNotebook, setImageList, 1}}, - {1880, {wxNotebook, setPadding, 1}}, - {1881, {wxNotebook, setPageSize, 1}}, - {1882, {wxNotebook, setPageImage, 2}}, - {1883, {wxNotebook, setPageText, 2}}, - {1884, {wxNotebook, setSelection, 1}}, - {1885, {wxNotebook, changeSelection, 1}}, - {1886, {wxChoicebook, new_0, 0}}, - {1887, {wxChoicebook, new_3, 3}}, - {1888, {wxChoicebook, addPage, 3}}, - {1889, {wxChoicebook, advanceSelection, 1}}, - {1890, {wxChoicebook, assignImageList, 1}}, - {1891, {wxChoicebook, create, 3}}, - {1892, {wxChoicebook, deleteAllPages, 0}}, - {1893, {wxChoicebook, deletePage, 1}}, - {1894, {wxChoicebook, removePage, 1}}, - {1895, {wxChoicebook, getCurrentPage, 0}}, - {1896, {wxChoicebook, getImageList, 0}}, - {1898, {wxChoicebook, getPage, 1}}, - {1899, {wxChoicebook, getPageCount, 0}}, - {1900, {wxChoicebook, getPageImage, 1}}, - {1901, {wxChoicebook, getPageText, 1}}, - {1902, {wxChoicebook, getSelection, 0}}, - {1903, {wxChoicebook, hitTest, 2}}, - {1904, {wxChoicebook, insertPage, 4}}, - {1905, {wxChoicebook, setImageList, 1}}, - {1906, {wxChoicebook, setPageSize, 1}}, - {1907, {wxChoicebook, setPageImage, 2}}, - {1908, {wxChoicebook, setPageText, 2}}, - {1909, {wxChoicebook, setSelection, 1}}, - {1910, {wxChoicebook, changeSelection, 1}}, - {1911, {wxChoicebook, 'Destroy', undefined}}, - {1912, {wxToolbook, new_0, 0}}, - {1913, {wxToolbook, new_3, 3}}, - {1914, {wxToolbook, addPage, 3}}, - {1915, {wxToolbook, advanceSelection, 1}}, - {1916, {wxToolbook, assignImageList, 1}}, - {1917, {wxToolbook, create, 3}}, - {1918, {wxToolbook, deleteAllPages, 0}}, - {1919, {wxToolbook, deletePage, 1}}, - {1920, {wxToolbook, removePage, 1}}, - {1921, {wxToolbook, getCurrentPage, 0}}, - {1922, {wxToolbook, getImageList, 0}}, - {1924, {wxToolbook, getPage, 1}}, - {1925, {wxToolbook, getPageCount, 0}}, - {1926, {wxToolbook, getPageImage, 1}}, - {1927, {wxToolbook, getPageText, 1}}, - {1928, {wxToolbook, getSelection, 0}}, - {1930, {wxToolbook, hitTest, 2}}, - {1931, {wxToolbook, insertPage, 4}}, - {1932, {wxToolbook, setImageList, 1}}, - {1933, {wxToolbook, setPageSize, 1}}, - {1934, {wxToolbook, setPageImage, 2}}, - {1935, {wxToolbook, setPageText, 2}}, - {1936, {wxToolbook, setSelection, 1}}, - {1937, {wxToolbook, changeSelection, 1}}, - {1938, {wxToolbook, 'Destroy', undefined}}, - {1939, {wxListbook, new_0, 0}}, - {1940, {wxListbook, new_3, 3}}, - {1941, {wxListbook, addPage, 3}}, - {1942, {wxListbook, advanceSelection, 1}}, - {1943, {wxListbook, assignImageList, 1}}, - {1944, {wxListbook, create, 3}}, - {1945, {wxListbook, deleteAllPages, 0}}, - {1946, {wxListbook, deletePage, 1}}, - {1947, {wxListbook, removePage, 1}}, - {1948, {wxListbook, getCurrentPage, 0}}, - {1949, {wxListbook, getImageList, 0}}, - {1951, {wxListbook, getPage, 1}}, - {1952, {wxListbook, getPageCount, 0}}, - {1953, {wxListbook, getPageImage, 1}}, - {1954, {wxListbook, getPageText, 1}}, - {1955, {wxListbook, getSelection, 0}}, - {1957, {wxListbook, hitTest, 2}}, - {1958, {wxListbook, insertPage, 4}}, - {1959, {wxListbook, setImageList, 1}}, - {1960, {wxListbook, setPageSize, 1}}, - {1961, {wxListbook, setPageImage, 2}}, - {1962, {wxListbook, setPageText, 2}}, - {1963, {wxListbook, setSelection, 1}}, - {1964, {wxListbook, changeSelection, 1}}, - {1965, {wxListbook, 'Destroy', undefined}}, - {1966, {wxTreebook, new_0, 0}}, - {1967, {wxTreebook, new_3, 3}}, - {1968, {wxTreebook, addPage, 3}}, - {1969, {wxTreebook, advanceSelection, 1}}, - {1970, {wxTreebook, assignImageList, 1}}, - {1971, {wxTreebook, create, 3}}, - {1972, {wxTreebook, deleteAllPages, 0}}, - {1973, {wxTreebook, deletePage, 1}}, - {1974, {wxTreebook, removePage, 1}}, - {1975, {wxTreebook, getCurrentPage, 0}}, - {1976, {wxTreebook, getImageList, 0}}, - {1978, {wxTreebook, getPage, 1}}, - {1979, {wxTreebook, getPageCount, 0}}, - {1980, {wxTreebook, getPageImage, 1}}, - {1981, {wxTreebook, getPageText, 1}}, - {1982, {wxTreebook, getSelection, 0}}, - {1983, {wxTreebook, expandNode, 2}}, - {1984, {wxTreebook, isNodeExpanded, 1}}, - {1986, {wxTreebook, hitTest, 2}}, - {1987, {wxTreebook, insertPage, 4}}, - {1988, {wxTreebook, insertSubPage, 4}}, - {1989, {wxTreebook, setImageList, 1}}, - {1990, {wxTreebook, setPageSize, 1}}, - {1991, {wxTreebook, setPageImage, 2}}, - {1992, {wxTreebook, setPageText, 2}}, - {1993, {wxTreebook, setSelection, 1}}, - {1994, {wxTreebook, changeSelection, 1}}, - {1995, {wxTreebook, 'Destroy', undefined}}, - {1998, {wxTreeCtrl, new_2, 2}}, - {1999, {wxTreeCtrl, new_0, 0}}, - {2001, {wxTreeCtrl, destruct, 0}}, - {2002, {wxTreeCtrl, addRoot, 2}}, - {2003, {wxTreeCtrl, appendItem, 3}}, - {2004, {wxTreeCtrl, assignImageList, 1}}, - {2005, {wxTreeCtrl, assignStateImageList, 1}}, - {2006, {wxTreeCtrl, collapse, 1}}, - {2007, {wxTreeCtrl, collapseAndReset, 1}}, - {2008, {wxTreeCtrl, create, 2}}, - {2009, {wxTreeCtrl, delete, 1}}, - {2010, {wxTreeCtrl, deleteAllItems, 0}}, - {2011, {wxTreeCtrl, deleteChildren, 1}}, - {2012, {wxTreeCtrl, ensureVisible, 1}}, - {2013, {wxTreeCtrl, expand, 1}}, - {2014, {wxTreeCtrl, getBoundingRect, 3}}, - {2016, {wxTreeCtrl, getChildrenCount, 2}}, - {2017, {wxTreeCtrl, getCount, 0}}, - {2018, {wxTreeCtrl, getEditControl, 0}}, - {2019, {wxTreeCtrl, getFirstChild, 2}}, - {2020, {wxTreeCtrl, getNextChild, 2}}, - {2021, {wxTreeCtrl, getFirstVisibleItem, 0}}, - {2022, {wxTreeCtrl, getImageList, 0}}, - {2023, {wxTreeCtrl, getIndent, 0}}, - {2024, {wxTreeCtrl, getItemBackgroundColour, 1}}, - {2025, {wxTreeCtrl, getItemData, 1}}, - {2026, {wxTreeCtrl, getItemFont, 1}}, - {2027, {wxTreeCtrl, getItemImage_1, 1}}, - {2028, {wxTreeCtrl, getItemImage_2, 2}}, - {2029, {wxTreeCtrl, getItemText, 1}}, - {2030, {wxTreeCtrl, getItemTextColour, 1}}, - {2031, {wxTreeCtrl, getLastChild, 1}}, - {2032, {wxTreeCtrl, getNextSibling, 1}}, - {2033, {wxTreeCtrl, getNextVisible, 1}}, - {2034, {wxTreeCtrl, getItemParent, 1}}, - {2035, {wxTreeCtrl, getPrevSibling, 1}}, - {2036, {wxTreeCtrl, getPrevVisible, 1}}, - {2037, {wxTreeCtrl, getRootItem, 0}}, - {2038, {wxTreeCtrl, getSelection, 0}}, - {2039, {wxTreeCtrl, getSelections, 1}}, - {2040, {wxTreeCtrl, getStateImageList, 0}}, - {2041, {wxTreeCtrl, hitTest, 1}}, - {2043, {wxTreeCtrl, insertItem, 4}}, - {2044, {wxTreeCtrl, isBold, 1}}, - {2045, {wxTreeCtrl, isExpanded, 1}}, - {2046, {wxTreeCtrl, isSelected, 1}}, - {2047, {wxTreeCtrl, isVisible, 1}}, - {2048, {wxTreeCtrl, itemHasChildren, 1}}, - {2049, {wxTreeCtrl, prependItem, 3}}, - {2050, {wxTreeCtrl, scrollTo, 1}}, - {2051, {wxTreeCtrl, selectItem_1, 1}}, - {2052, {wxTreeCtrl, selectItem_2, 2}}, - {2053, {wxTreeCtrl, setIndent, 1}}, - {2054, {wxTreeCtrl, setImageList, 1}}, - {2055, {wxTreeCtrl, setItemBackgroundColour, 2}}, - {2056, {wxTreeCtrl, setItemBold, 2}}, - {2057, {wxTreeCtrl, setItemData, 2}}, - {2058, {wxTreeCtrl, setItemDropHighlight, 2}}, - {2059, {wxTreeCtrl, setItemFont, 2}}, - {2060, {wxTreeCtrl, setItemHasChildren, 2}}, - {2061, {wxTreeCtrl, setItemImage_2, 2}}, - {2062, {wxTreeCtrl, setItemImage_3, 3}}, - {2063, {wxTreeCtrl, setItemText, 2}}, - {2064, {wxTreeCtrl, setItemTextColour, 2}}, - {2065, {wxTreeCtrl, setStateImageList, 1}}, - {2066, {wxTreeCtrl, setWindowStyle, 1}}, - {2067, {wxTreeCtrl, sortChildren, 1}}, - {2068, {wxTreeCtrl, toggle, 1}}, - {2069, {wxTreeCtrl, toggleItemSelection, 1}}, - {2070, {wxTreeCtrl, unselect, 0}}, - {2071, {wxTreeCtrl, unselectAll, 0}}, - {2072, {wxTreeCtrl, unselectItem, 1}}, - {2073, {wxScrollBar, new_0, 0}}, - {2074, {wxScrollBar, new_3, 3}}, - {2075, {wxScrollBar, destruct, 0}}, - {2076, {wxScrollBar, create, 3}}, - {2077, {wxScrollBar, getRange, 0}}, - {2078, {wxScrollBar, getPageSize, 0}}, - {2079, {wxScrollBar, getThumbPosition, 0}}, - {2080, {wxScrollBar, getThumbSize, 0}}, - {2081, {wxScrollBar, setThumbPosition, 1}}, - {2082, {wxScrollBar, setScrollbar, 5}}, - {2084, {wxSpinButton, new_2, 2}}, - {2085, {wxSpinButton, new_0, 0}}, - {2086, {wxSpinButton, create, 2}}, - {2087, {wxSpinButton, getMax, 0}}, - {2088, {wxSpinButton, getMin, 0}}, - {2089, {wxSpinButton, getValue, 0}}, - {2090, {wxSpinButton, setRange, 2}}, - {2091, {wxSpinButton, setValue, 1}}, - {2092, {wxSpinButton, 'Destroy', undefined}}, - {2093, {wxSpinCtrl, new_0, 0}}, - {2094, {wxSpinCtrl, new_2, 2}}, - {2096, {wxSpinCtrl, create, 2}}, - {2099, {wxSpinCtrl, setValue_1_1, 1}}, - {2100, {wxSpinCtrl, setValue_1_0, 1}}, - {2102, {wxSpinCtrl, getValue, 0}}, - {2104, {wxSpinCtrl, setRange, 2}}, - {2105, {wxSpinCtrl, setSelection, 2}}, - {2107, {wxSpinCtrl, getMin, 0}}, - {2109, {wxSpinCtrl, getMax, 0}}, - {2110, {wxSpinCtrl, 'Destroy', undefined}}, - {2111, {wxStaticText, new_0, 0}}, - {2112, {wxStaticText, new_4, 4}}, - {2113, {wxStaticText, create, 4}}, - {2114, {wxStaticText, getLabel, 0}}, - {2115, {wxStaticText, setLabel, 1}}, - {2116, {wxStaticText, wrap, 1}}, - {2117, {wxStaticText, 'Destroy', undefined}}, - {2118, {wxStaticBitmap, new_0, 0}}, - {2119, {wxStaticBitmap, new_4, 4}}, - {2120, {wxStaticBitmap, create, 4}}, - {2121, {wxStaticBitmap, getBitmap, 0}}, - {2122, {wxStaticBitmap, setBitmap, 1}}, - {2123, {wxStaticBitmap, 'Destroy', undefined}}, - {2124, {wxRadioBox, new, 7}}, - {2126, {wxRadioBox, destruct, 0}}, - {2127, {wxRadioBox, create, 7}}, - {2128, {wxRadioBox, enable_2, 2}}, - {2129, {wxRadioBox, enable_1, 1}}, - {2130, {wxRadioBox, getSelection, 0}}, - {2131, {wxRadioBox, getString, 1}}, - {2132, {wxRadioBox, setSelection, 1}}, - {2133, {wxRadioBox, show_2, 2}}, - {2134, {wxRadioBox, show_1, 1}}, - {2135, {wxRadioBox, getColumnCount, 0}}, - {2136, {wxRadioBox, getItemHelpText, 1}}, - {2137, {wxRadioBox, getItemToolTip, 1}}, - {2139, {wxRadioBox, getItemFromPoint, 1}}, - {2140, {wxRadioBox, getRowCount, 0}}, - {2141, {wxRadioBox, isItemEnabled, 1}}, - {2142, {wxRadioBox, isItemShown, 1}}, - {2143, {wxRadioBox, setItemHelpText, 2}}, - {2144, {wxRadioBox, setItemToolTip, 2}}, - {2145, {wxRadioButton, new_0, 0}}, - {2146, {wxRadioButton, new_4, 4}}, - {2147, {wxRadioButton, create, 4}}, - {2148, {wxRadioButton, getValue, 0}}, - {2149, {wxRadioButton, setValue, 1}}, - {2150, {wxRadioButton, 'Destroy', undefined}}, - {2152, {wxSlider, new_6, 6}}, - {2153, {wxSlider, new_0, 0}}, - {2154, {wxSlider, create, 6}}, - {2155, {wxSlider, getLineSize, 0}}, - {2156, {wxSlider, getMax, 0}}, - {2157, {wxSlider, getMin, 0}}, - {2158, {wxSlider, getPageSize, 0}}, - {2159, {wxSlider, getThumbLength, 0}}, - {2160, {wxSlider, getValue, 0}}, - {2161, {wxSlider, setLineSize, 1}}, - {2162, {wxSlider, setPageSize, 1}}, - {2163, {wxSlider, setRange, 2}}, - {2164, {wxSlider, setThumbLength, 1}}, - {2165, {wxSlider, setValue, 1}}, - {2166, {wxSlider, 'Destroy', undefined}}, - {2168, {wxDialog, new_4, 4}}, - {2169, {wxDialog, new_0, 0}}, - {2171, {wxDialog, destruct, 0}}, - {2172, {wxDialog, create, 4}}, - {2173, {wxDialog, createButtonSizer, 1}}, - {2174, {wxDialog, createStdDialogButtonSizer, 1}}, - {2175, {wxDialog, endModal, 1}}, - {2176, {wxDialog, getAffirmativeId, 0}}, - {2177, {wxDialog, getReturnCode, 0}}, - {2178, {wxDialog, isModal, 0}}, - {2179, {wxDialog, setAffirmativeId, 1}}, - {2180, {wxDialog, setReturnCode, 1}}, - {2181, {wxDialog, show, 1}}, - {2182, {wxDialog, showModal, 0}}, - {2183, {wxColourDialog, new_0, 0}}, - {2184, {wxColourDialog, new_2, 2}}, - {2185, {wxColourDialog, destruct, 0}}, - {2186, {wxColourDialog, create, 2}}, - {2187, {wxColourDialog, getColourData, 0}}, - {2188, {wxColourData, new_0, 0}}, - {2189, {wxColourData, new_1, 1}}, - {2190, {wxColourData, destruct, 0}}, - {2191, {wxColourData, getChooseFull, 0}}, - {2192, {wxColourData, getColour, 0}}, - {2194, {wxColourData, getCustomColour, 1}}, - {2195, {wxColourData, setChooseFull, 1}}, - {2196, {wxColourData, setColour, 1}}, - {2197, {wxColourData, setCustomColour, 2}}, - {2198, {wxPalette, new_0, 0}}, - {2199, {wxPalette, new_4, 4}}, - {2201, {wxPalette, destruct, 0}}, - {2202, {wxPalette, create, 4}}, - {2203, {wxPalette, getColoursCount, 0}}, - {2204, {wxPalette, getPixel, 3}}, - {2205, {wxPalette, getRGB, 4}}, - {2206, {wxPalette, isOk, 0}}, - {2210, {wxDirDialog, new, 2}}, - {2211, {wxDirDialog, destruct, 0}}, - {2212, {wxDirDialog, getPath, 0}}, - {2213, {wxDirDialog, getMessage, 0}}, - {2214, {wxDirDialog, setMessage, 1}}, - {2215, {wxDirDialog, setPath, 1}}, - {2219, {wxFileDialog, new, 2}}, - {2220, {wxFileDialog, destruct, 0}}, - {2221, {wxFileDialog, getDirectory, 0}}, - {2222, {wxFileDialog, getFilename, 0}}, - {2223, {wxFileDialog, getFilenames, 1}}, - {2224, {wxFileDialog, getFilterIndex, 0}}, - {2225, {wxFileDialog, getMessage, 0}}, - {2226, {wxFileDialog, getPath, 0}}, - {2227, {wxFileDialog, getPaths, 1}}, - {2228, {wxFileDialog, getWildcard, 0}}, - {2229, {wxFileDialog, setDirectory, 1}}, - {2230, {wxFileDialog, setFilename, 1}}, - {2231, {wxFileDialog, setFilterIndex, 1}}, - {2232, {wxFileDialog, setMessage, 1}}, - {2233, {wxFileDialog, setPath, 1}}, - {2234, {wxFileDialog, setWildcard, 1}}, - {2235, {wxPickerBase, setInternalMargin, 1}}, - {2236, {wxPickerBase, getInternalMargin, 0}}, - {2237, {wxPickerBase, setTextCtrlProportion, 1}}, - {2238, {wxPickerBase, setPickerCtrlProportion, 1}}, - {2239, {wxPickerBase, getTextCtrlProportion, 0}}, - {2240, {wxPickerBase, getPickerCtrlProportion, 0}}, - {2241, {wxPickerBase, hasTextCtrl, 0}}, - {2242, {wxPickerBase, getTextCtrl, 0}}, - {2243, {wxPickerBase, isTextCtrlGrowable, 0}}, - {2244, {wxPickerBase, setPickerCtrlGrowable, 1}}, - {2245, {wxPickerBase, setTextCtrlGrowable, 1}}, - {2246, {wxPickerBase, isPickerCtrlGrowable, 0}}, - {2247, {wxFilePickerCtrl, new_0, 0}}, - {2248, {wxFilePickerCtrl, new_3, 3}}, - {2249, {wxFilePickerCtrl, create, 3}}, - {2250, {wxFilePickerCtrl, getPath, 0}}, - {2251, {wxFilePickerCtrl, setPath, 1}}, - {2252, {wxFilePickerCtrl, 'Destroy', undefined}}, - {2253, {wxDirPickerCtrl, new_0, 0}}, - {2254, {wxDirPickerCtrl, new_3, 3}}, - {2255, {wxDirPickerCtrl, create, 3}}, - {2256, {wxDirPickerCtrl, getPath, 0}}, - {2257, {wxDirPickerCtrl, setPath, 1}}, - {2258, {wxDirPickerCtrl, 'Destroy', undefined}}, - {2259, {wxColourPickerCtrl, new_0, 0}}, - {2260, {wxColourPickerCtrl, new_3, 3}}, - {2261, {wxColourPickerCtrl, create, 3}}, - {2262, {wxColourPickerCtrl, getColour, 0}}, - {2263, {wxColourPickerCtrl, setColour_1_1, 1}}, - {2264, {wxColourPickerCtrl, setColour_1_0, 1}}, - {2265, {wxColourPickerCtrl, 'Destroy', undefined}}, - {2266, {wxDatePickerCtrl, new_0, 0}}, - {2267, {wxDatePickerCtrl, new_3, 3}}, - {2268, {wxDatePickerCtrl, getRange, 2}}, - {2269, {wxDatePickerCtrl, getValue, 0}}, - {2270, {wxDatePickerCtrl, setRange, 2}}, - {2271, {wxDatePickerCtrl, setValue, 1}}, - {2272, {wxDatePickerCtrl, 'Destroy', undefined}}, - {2273, {wxFontPickerCtrl, new_0, 0}}, - {2274, {wxFontPickerCtrl, new_3, 3}}, - {2275, {wxFontPickerCtrl, create, 3}}, - {2276, {wxFontPickerCtrl, getSelectedFont, 0}}, - {2277, {wxFontPickerCtrl, setSelectedFont, 1}}, - {2278, {wxFontPickerCtrl, getMaxPointSize, 0}}, - {2279, {wxFontPickerCtrl, setMaxPointSize, 1}}, - {2280, {wxFontPickerCtrl, 'Destroy', undefined}}, - {2283, {wxFindReplaceDialog, new_0, 0}}, - {2284, {wxFindReplaceDialog, new_4, 4}}, - {2285, {wxFindReplaceDialog, destruct, 0}}, - {2286, {wxFindReplaceDialog, create, 4}}, - {2287, {wxFindReplaceDialog, getData, 0}}, - {2288, {wxFindReplaceData, new_0, 0}}, - {2289, {wxFindReplaceData, new_1, 1}}, - {2290, {wxFindReplaceData, getFindString, 0}}, - {2291, {wxFindReplaceData, getReplaceString, 0}}, - {2292, {wxFindReplaceData, getFlags, 0}}, - {2293, {wxFindReplaceData, setFlags, 1}}, - {2294, {wxFindReplaceData, setFindString, 1}}, - {2295, {wxFindReplaceData, setReplaceString, 1}}, - {2296, {wxFindReplaceData, 'Destroy', undefined}}, - {2297, {wxMultiChoiceDialog, new_0, 0}}, - {2299, {wxMultiChoiceDialog, new_5, 5}}, - {2300, {wxMultiChoiceDialog, getSelections, 0}}, - {2301, {wxMultiChoiceDialog, setSelections, 1}}, - {2302, {wxMultiChoiceDialog, 'Destroy', undefined}}, - {2303, {wxSingleChoiceDialog, new_0, 0}}, - {2305, {wxSingleChoiceDialog, new_5, 5}}, - {2306, {wxSingleChoiceDialog, getSelection, 0}}, - {2307, {wxSingleChoiceDialog, getStringSelection, 0}}, - {2308, {wxSingleChoiceDialog, setSelection, 1}}, - {2309, {wxSingleChoiceDialog, 'Destroy', undefined}}, - {2310, {wxTextEntryDialog, new, 3}}, - {2311, {wxTextEntryDialog, getValue, 0}}, - {2312, {wxTextEntryDialog, setValue, 1}}, - {2313, {wxTextEntryDialog, 'Destroy', undefined}}, - {2314, {wxPasswordEntryDialog, new, 3}}, - {2315, {wxPasswordEntryDialog, 'Destroy', undefined}}, - {2316, {wxFontData, new_0, 0}}, - {2317, {wxFontData, new_1, 1}}, - {2318, {wxFontData, destruct, 0}}, - {2319, {wxFontData, enableEffects, 1}}, - {2320, {wxFontData, getAllowSymbols, 0}}, - {2321, {wxFontData, getColour, 0}}, - {2322, {wxFontData, getChosenFont, 0}}, - {2323, {wxFontData, getEnableEffects, 0}}, - {2324, {wxFontData, getInitialFont, 0}}, - {2325, {wxFontData, getShowHelp, 0}}, - {2326, {wxFontData, setAllowSymbols, 1}}, - {2327, {wxFontData, setChosenFont, 1}}, - {2328, {wxFontData, setColour, 1}}, - {2329, {wxFontData, setInitialFont, 1}}, - {2330, {wxFontData, setRange, 2}}, - {2331, {wxFontData, setShowHelp, 1}}, - {2335, {wxFontDialog, new_0, 0}}, - {2337, {wxFontDialog, new_2, 2}}, - {2339, {wxFontDialog, create, 2}}, - {2340, {wxFontDialog, getFontData, 0}}, - {2342, {wxFontDialog, 'Destroy', undefined}}, - {2343, {wxProgressDialog, new, 3}}, - {2344, {wxProgressDialog, destruct, 0}}, - {2345, {wxProgressDialog, resume, 0}}, - {2346, {wxProgressDialog, update_2, 2}}, - {2347, {wxProgressDialog, update_0, 0}}, - {2348, {wxMessageDialog, new, 3}}, - {2349, {wxMessageDialog, destruct, 0}}, - {2350, {wxPageSetupDialog, new, 2}}, - {2351, {wxPageSetupDialog, destruct, 0}}, - {2352, {wxPageSetupDialog, getPageSetupData, 0}}, - {2353, {wxPageSetupDialog, showModal, 0}}, - {2354, {wxPageSetupDialogData, new_0, 0}}, - {2355, {wxPageSetupDialogData, new_1_0, 1}}, - {2356, {wxPageSetupDialogData, new_1_1, 1}}, - {2357, {wxPageSetupDialogData, destruct, 0}}, - {2358, {wxPageSetupDialogData, enableHelp, 1}}, - {2359, {wxPageSetupDialogData, enableMargins, 1}}, - {2360, {wxPageSetupDialogData, enableOrientation, 1}}, - {2361, {wxPageSetupDialogData, enablePaper, 1}}, - {2362, {wxPageSetupDialogData, enablePrinter, 1}}, - {2363, {wxPageSetupDialogData, getDefaultMinMargins, 0}}, - {2364, {wxPageSetupDialogData, getEnableMargins, 0}}, - {2365, {wxPageSetupDialogData, getEnableOrientation, 0}}, - {2366, {wxPageSetupDialogData, getEnablePaper, 0}}, - {2367, {wxPageSetupDialogData, getEnablePrinter, 0}}, - {2368, {wxPageSetupDialogData, getEnableHelp, 0}}, - {2369, {wxPageSetupDialogData, getDefaultInfo, 0}}, - {2370, {wxPageSetupDialogData, getMarginTopLeft, 0}}, - {2371, {wxPageSetupDialogData, getMarginBottomRight, 0}}, - {2372, {wxPageSetupDialogData, getMinMarginTopLeft, 0}}, - {2373, {wxPageSetupDialogData, getMinMarginBottomRight, 0}}, - {2374, {wxPageSetupDialogData, getPaperId, 0}}, - {2375, {wxPageSetupDialogData, getPaperSize, 0}}, - {2377, {wxPageSetupDialogData, getPrintData, 0}}, - {2378, {wxPageSetupDialogData, isOk, 0}}, - {2379, {wxPageSetupDialogData, setDefaultInfo, 1}}, - {2380, {wxPageSetupDialogData, setDefaultMinMargins, 1}}, - {2381, {wxPageSetupDialogData, setMarginTopLeft, 1}}, - {2382, {wxPageSetupDialogData, setMarginBottomRight, 1}}, - {2383, {wxPageSetupDialogData, setMinMarginTopLeft, 1}}, - {2384, {wxPageSetupDialogData, setMinMarginBottomRight, 1}}, - {2385, {wxPageSetupDialogData, setPaperId, 1}}, - {2386, {wxPageSetupDialogData, setPaperSize_1_1, 1}}, - {2387, {wxPageSetupDialogData, setPaperSize_1_0, 1}}, - {2388, {wxPageSetupDialogData, setPrintData, 1}}, - {2389, {wxPrintDialog, new_2_0, 2}}, - {2390, {wxPrintDialog, new_2_1, 2}}, - {2391, {wxPrintDialog, destruct, 0}}, - {2392, {wxPrintDialog, getPrintDialogData, 0}}, - {2393, {wxPrintDialog, getPrintDC, 0}}, - {2394, {wxPrintDialogData, new_0, 0}}, - {2395, {wxPrintDialogData, new_1_1, 1}}, - {2396, {wxPrintDialogData, new_1_0, 1}}, - {2397, {wxPrintDialogData, destruct, 0}}, - {2398, {wxPrintDialogData, enableHelp, 1}}, - {2399, {wxPrintDialogData, enablePageNumbers, 1}}, - {2400, {wxPrintDialogData, enablePrintToFile, 1}}, - {2401, {wxPrintDialogData, enableSelection, 1}}, - {2402, {wxPrintDialogData, getAllPages, 0}}, - {2403, {wxPrintDialogData, getCollate, 0}}, - {2404, {wxPrintDialogData, getFromPage, 0}}, - {2405, {wxPrintDialogData, getMaxPage, 0}}, - {2406, {wxPrintDialogData, getMinPage, 0}}, - {2407, {wxPrintDialogData, getNoCopies, 0}}, - {2408, {wxPrintDialogData, getPrintData, 0}}, - {2409, {wxPrintDialogData, getPrintToFile, 0}}, - {2410, {wxPrintDialogData, getSelection, 0}}, - {2411, {wxPrintDialogData, getToPage, 0}}, - {2412, {wxPrintDialogData, isOk, 0}}, - {2413, {wxPrintDialogData, setCollate, 1}}, - {2414, {wxPrintDialogData, setFromPage, 1}}, - {2415, {wxPrintDialogData, setMaxPage, 1}}, - {2416, {wxPrintDialogData, setMinPage, 1}}, - {2417, {wxPrintDialogData, setNoCopies, 1}}, - {2418, {wxPrintDialogData, setPrintData, 1}}, - {2419, {wxPrintDialogData, setPrintToFile, 1}}, - {2420, {wxPrintDialogData, setSelection, 1}}, - {2421, {wxPrintDialogData, setToPage, 1}}, - {2422, {wxPrintData, new_0, 0}}, - {2423, {wxPrintData, new_1, 1}}, - {2424, {wxPrintData, destruct, 0}}, - {2425, {wxPrintData, getCollate, 0}}, - {2426, {wxPrintData, getBin, 0}}, - {2427, {wxPrintData, getColour, 0}}, - {2428, {wxPrintData, getDuplex, 0}}, - {2429, {wxPrintData, getNoCopies, 0}}, - {2430, {wxPrintData, getOrientation, 0}}, - {2431, {wxPrintData, getPaperId, 0}}, - {2432, {wxPrintData, getPrinterName, 0}}, - {2433, {wxPrintData, getQuality, 0}}, - {2434, {wxPrintData, isOk, 0}}, - {2435, {wxPrintData, setBin, 1}}, - {2436, {wxPrintData, setCollate, 1}}, - {2437, {wxPrintData, setColour, 1}}, - {2438, {wxPrintData, setDuplex, 1}}, - {2439, {wxPrintData, setNoCopies, 1}}, - {2440, {wxPrintData, setOrientation, 1}}, - {2441, {wxPrintData, setPaperId, 1}}, - {2442, {wxPrintData, setPrinterName, 1}}, - {2443, {wxPrintData, setQuality, 1}}, - {2446, {wxPrintPreview, new_2, 2}}, - {2447, {wxPrintPreview, new_3, 3}}, - {2449, {wxPrintPreview, destruct, 0}}, - {2450, {wxPrintPreview, getCanvas, 0}}, - {2451, {wxPrintPreview, getCurrentPage, 0}}, - {2452, {wxPrintPreview, getFrame, 0}}, - {2453, {wxPrintPreview, getMaxPage, 0}}, - {2454, {wxPrintPreview, getMinPage, 0}}, - {2455, {wxPrintPreview, getPrintout, 0}}, - {2456, {wxPrintPreview, getPrintoutForPrinting, 0}}, - {2457, {wxPrintPreview, isOk, 0}}, - {2458, {wxPrintPreview, paintPage, 2}}, - {2459, {wxPrintPreview, print, 1}}, - {2460, {wxPrintPreview, renderPage, 1}}, - {2461, {wxPrintPreview, setCanvas, 1}}, - {2462, {wxPrintPreview, setCurrentPage, 1}}, - {2463, {wxPrintPreview, setFrame, 1}}, - {2464, {wxPrintPreview, setPrintout, 1}}, - {2465, {wxPrintPreview, setZoom, 1}}, - {2466, {wxPreviewFrame, new, 3}}, - {2467, {wxPreviewFrame, destruct, 0}}, - {2468, {wxPreviewFrame, createControlBar, 0}}, - {2469, {wxPreviewFrame, createCanvas, 0}}, - {2470, {wxPreviewFrame, initialize, 0}}, - {2471, {wxPreviewFrame, onCloseWindow, 1}}, - {2472, {wxPreviewControlBar, new, 4}}, - {2473, {wxPreviewControlBar, destruct, 0}}, - {2474, {wxPreviewControlBar, createButtons, 0}}, - {2475, {wxPreviewControlBar, getPrintPreview, 0}}, - {2476, {wxPreviewControlBar, getZoomControl, 0}}, - {2477, {wxPreviewControlBar, setZoomControl, 1}}, - {2479, {wxPrinter, new, 1}}, - {2480, {wxPrinter, createAbortWindow, 2}}, - {2481, {wxPrinter, getAbort, 0}}, - {2482, {wxPrinter, getLastError, 0}}, - {2483, {wxPrinter, getPrintDialogData, 0}}, - {2484, {wxPrinter, print, 3}}, - {2485, {wxPrinter, printDialog, 1}}, - {2486, {wxPrinter, reportError, 3}}, - {2487, {wxPrinter, setup, 1}}, - {2488, {wxPrinter, 'Destroy', undefined}}, - {2489, {wxXmlResource, new_1, 1}}, - {2490, {wxXmlResource, new_2, 2}}, - {2491, {wxXmlResource, destruct, 0}}, - {2492, {wxXmlResource, attachUnknownControl, 3}}, - {2493, {wxXmlResource, clearHandlers, 0}}, - {2494, {wxXmlResource, compareVersion, 4}}, - {2495, {wxXmlResource, get, 0}}, - {2496, {wxXmlResource, getFlags, 0}}, - {2497, {wxXmlResource, getVersion, 0}}, - {2498, {wxXmlResource, getXRCID, 2}}, - {2499, {wxXmlResource, initAllHandlers, 0}}, - {2500, {wxXmlResource, load, 1}}, - {2501, {wxXmlResource, loadBitmap, 1}}, - {2502, {wxXmlResource, loadDialog_2, 2}}, - {2503, {wxXmlResource, loadDialog_3, 3}}, - {2504, {wxXmlResource, loadFrame_2, 2}}, - {2505, {wxXmlResource, loadFrame_3, 3}}, - {2506, {wxXmlResource, loadIcon, 1}}, - {2507, {wxXmlResource, loadMenu, 1}}, - {2508, {wxXmlResource, loadMenuBar_2, 2}}, - {2509, {wxXmlResource, loadMenuBar_1, 1}}, - {2510, {wxXmlResource, loadPanel_2, 2}}, - {2511, {wxXmlResource, loadPanel_3, 3}}, - {2512, {wxXmlResource, loadToolBar, 2}}, - {2513, {wxXmlResource, set, 1}}, - {2514, {wxXmlResource, setFlags, 1}}, - {2515, {wxXmlResource, unload, 1}}, - {2516, {wxXmlResource, xrcctrl, 3}}, - {2517, {wxHtmlEasyPrinting, new, 1}}, - {2518, {wxHtmlEasyPrinting, destruct, 0}}, - {2519, {wxHtmlEasyPrinting, getPrintData, 0}}, - {2520, {wxHtmlEasyPrinting, getPageSetupData, 0}}, - {2521, {wxHtmlEasyPrinting, previewFile, 1}}, - {2522, {wxHtmlEasyPrinting, previewText, 2}}, - {2523, {wxHtmlEasyPrinting, printFile, 1}}, - {2524, {wxHtmlEasyPrinting, printText, 2}}, - {2525, {wxHtmlEasyPrinting, pageSetup, 0}}, - {2526, {wxHtmlEasyPrinting, setFonts, 3}}, - {2527, {wxHtmlEasyPrinting, setHeader, 2}}, - {2528, {wxHtmlEasyPrinting, setFooter, 2}}, - {2530, {wxGLCanvas, new_2, 2}}, - {2531, {wxGLCanvas, new_3_1, 3}}, - {2532, {wxGLCanvas, new_3_0, 3}}, - {2533, {wxGLCanvas, getContext, 0}}, - {2535, {wxGLCanvas, setCurrent, 0}}, - {2536, {wxGLCanvas, swapBuffers, 0}}, - {2537, {wxGLCanvas, 'Destroy', undefined}}, - {2538, {wxAuiManager, new, 1}}, - {2539, {wxAuiManager, destruct, 0}}, - {2540, {wxAuiManager, addPane_2_1, 2}}, - {2541, {wxAuiManager, addPane_3, 3}}, - {2542, {wxAuiManager, addPane_2_0, 2}}, - {2543, {wxAuiManager, detachPane, 1}}, - {2544, {wxAuiManager, getAllPanes, 0}}, - {2545, {wxAuiManager, getArtProvider, 0}}, - {2546, {wxAuiManager, getDockSizeConstraint, 2}}, - {2547, {wxAuiManager, getFlags, 0}}, - {2548, {wxAuiManager, getManagedWindow, 0}}, - {2549, {wxAuiManager, getManager, 1}}, - {2550, {wxAuiManager, getPane_1_1, 1}}, - {2551, {wxAuiManager, getPane_1_0, 1}}, - {2552, {wxAuiManager, hideHint, 0}}, - {2553, {wxAuiManager, insertPane, 3}}, - {2554, {wxAuiManager, loadPaneInfo, 2}}, - {2555, {wxAuiManager, loadPerspective, 2}}, - {2556, {wxAuiManager, savePaneInfo, 1}}, - {2557, {wxAuiManager, savePerspective, 0}}, - {2558, {wxAuiManager, setArtProvider, 1}}, - {2559, {wxAuiManager, setDockSizeConstraint, 2}}, - {2560, {wxAuiManager, setFlags, 1}}, - {2561, {wxAuiManager, setManagedWindow, 1}}, - {2562, {wxAuiManager, showHint, 1}}, - {2563, {wxAuiManager, unInit, 0}}, - {2564, {wxAuiManager, update, 0}}, - {2565, {wxAuiPaneInfo, new_0, 0}}, - {2566, {wxAuiPaneInfo, new_1, 1}}, - {2567, {wxAuiPaneInfo, destruct, 0}}, - {2568, {wxAuiPaneInfo, bestSize_1, 1}}, - {2569, {wxAuiPaneInfo, bestSize_2, 2}}, - {2570, {wxAuiPaneInfo, bottom, 0}}, - {2571, {wxAuiPaneInfo, bottomDockable, 1}}, - {2572, {wxAuiPaneInfo, caption, 1}}, - {2573, {wxAuiPaneInfo, captionVisible, 1}}, - {2574, {wxAuiPaneInfo, centre, 0}}, - {2575, {wxAuiPaneInfo, centrePane, 0}}, - {2576, {wxAuiPaneInfo, closeButton, 1}}, - {2577, {wxAuiPaneInfo, defaultPane, 0}}, - {2578, {wxAuiPaneInfo, destroyOnClose, 1}}, - {2579, {wxAuiPaneInfo, direction, 1}}, - {2580, {wxAuiPaneInfo, dock, 0}}, - {2581, {wxAuiPaneInfo, dockable, 1}}, - {2582, {wxAuiPaneInfo, fixed, 0}}, - {2583, {wxAuiPaneInfo, float, 0}}, - {2584, {wxAuiPaneInfo, floatable, 1}}, - {2585, {wxAuiPaneInfo, floatingPosition_1, 1}}, - {2586, {wxAuiPaneInfo, floatingPosition_2, 2}}, - {2587, {wxAuiPaneInfo, floatingSize_1, 1}}, - {2588, {wxAuiPaneInfo, floatingSize_2, 2}}, - {2589, {wxAuiPaneInfo, gripper, 1}}, - {2590, {wxAuiPaneInfo, gripperTop, 1}}, - {2591, {wxAuiPaneInfo, hasBorder, 0}}, - {2592, {wxAuiPaneInfo, hasCaption, 0}}, - {2593, {wxAuiPaneInfo, hasCloseButton, 0}}, - {2594, {wxAuiPaneInfo, hasFlag, 1}}, - {2595, {wxAuiPaneInfo, hasGripper, 0}}, - {2596, {wxAuiPaneInfo, hasGripperTop, 0}}, - {2597, {wxAuiPaneInfo, hasMaximizeButton, 0}}, - {2598, {wxAuiPaneInfo, hasMinimizeButton, 0}}, - {2599, {wxAuiPaneInfo, hasPinButton, 0}}, - {2600, {wxAuiPaneInfo, hide, 0}}, - {2601, {wxAuiPaneInfo, isBottomDockable, 0}}, - {2602, {wxAuiPaneInfo, isDocked, 0}}, - {2603, {wxAuiPaneInfo, isFixed, 0}}, - {2604, {wxAuiPaneInfo, isFloatable, 0}}, - {2605, {wxAuiPaneInfo, isFloating, 0}}, - {2606, {wxAuiPaneInfo, isLeftDockable, 0}}, - {2607, {wxAuiPaneInfo, isMovable, 0}}, - {2608, {wxAuiPaneInfo, isOk, 0}}, - {2609, {wxAuiPaneInfo, isResizable, 0}}, - {2610, {wxAuiPaneInfo, isRightDockable, 0}}, - {2611, {wxAuiPaneInfo, isShown, 0}}, - {2612, {wxAuiPaneInfo, isToolbar, 0}}, - {2613, {wxAuiPaneInfo, isTopDockable, 0}}, - {2614, {wxAuiPaneInfo, layer, 1}}, - {2615, {wxAuiPaneInfo, left, 0}}, - {2616, {wxAuiPaneInfo, leftDockable, 1}}, - {2617, {wxAuiPaneInfo, maxSize_1, 1}}, - {2618, {wxAuiPaneInfo, maxSize_2, 2}}, - {2619, {wxAuiPaneInfo, maximizeButton, 1}}, - {2620, {wxAuiPaneInfo, minSize_1, 1}}, - {2621, {wxAuiPaneInfo, minSize_2, 2}}, - {2622, {wxAuiPaneInfo, minimizeButton, 1}}, - {2623, {wxAuiPaneInfo, movable, 1}}, - {2624, {wxAuiPaneInfo, name, 1}}, - {2625, {wxAuiPaneInfo, paneBorder, 1}}, - {2626, {wxAuiPaneInfo, pinButton, 1}}, - {2627, {wxAuiPaneInfo, position, 1}}, - {2628, {wxAuiPaneInfo, resizable, 1}}, - {2629, {wxAuiPaneInfo, right, 0}}, - {2630, {wxAuiPaneInfo, rightDockable, 1}}, - {2631, {wxAuiPaneInfo, row, 1}}, - {2632, {wxAuiPaneInfo, safeSet, 1}}, - {2633, {wxAuiPaneInfo, setFlag, 2}}, - {2634, {wxAuiPaneInfo, show, 1}}, - {2635, {wxAuiPaneInfo, toolbarPane, 0}}, - {2636, {wxAuiPaneInfo, top, 0}}, - {2637, {wxAuiPaneInfo, topDockable, 1}}, - {2638, {wxAuiPaneInfo, window, 1}}, - {2639, {wxAuiNotebook, new_0, 0}}, - {2640, {wxAuiNotebook, new_2, 2}}, - {2641, {wxAuiNotebook, addPage, 3}}, - {2642, {wxAuiNotebook, create, 2}}, - {2643, {wxAuiNotebook, deletePage, 1}}, - {2644, {wxAuiNotebook, getArtProvider, 0}}, - {2645, {wxAuiNotebook, getPage, 1}}, - {2646, {wxAuiNotebook, getPageBitmap, 1}}, - {2647, {wxAuiNotebook, getPageCount, 0}}, - {2648, {wxAuiNotebook, getPageIndex, 1}}, - {2649, {wxAuiNotebook, getPageText, 1}}, - {2650, {wxAuiNotebook, getSelection, 0}}, - {2651, {wxAuiNotebook, insertPage, 4}}, - {2652, {wxAuiNotebook, removePage, 1}}, - {2653, {wxAuiNotebook, setArtProvider, 1}}, - {2654, {wxAuiNotebook, setFont, 1}}, - {2655, {wxAuiNotebook, setPageBitmap, 2}}, - {2656, {wxAuiNotebook, setPageText, 2}}, - {2657, {wxAuiNotebook, setSelection, 1}}, - {2658, {wxAuiNotebook, setTabCtrlHeight, 1}}, - {2659, {wxAuiNotebook, setUniformBitmapSize, 1}}, - {2660, {wxAuiNotebook, 'Destroy', undefined}}, - {2661, {wxMDIParentFrame, new_0, 0}}, - {2662, {wxMDIParentFrame, new_4, 4}}, - {2663, {wxMDIParentFrame, destruct, 0}}, - {2664, {wxMDIParentFrame, activateNext, 0}}, - {2665, {wxMDIParentFrame, activatePrevious, 0}}, - {2666, {wxMDIParentFrame, arrangeIcons, 0}}, - {2667, {wxMDIParentFrame, cascade, 0}}, - {2668, {wxMDIParentFrame, create, 4}}, - {2669, {wxMDIParentFrame, getActiveChild, 0}}, - {2670, {wxMDIParentFrame, getClientWindow, 0}}, - {2671, {wxMDIParentFrame, tile, 1}}, - {2672, {wxMDIChildFrame, new_0, 0}}, - {2673, {wxMDIChildFrame, new_4, 4}}, - {2674, {wxMDIChildFrame, destruct, 0}}, - {2675, {wxMDIChildFrame, activate, 0}}, - {2676, {wxMDIChildFrame, create, 4}}, - {2677, {wxMDIChildFrame, maximize, 1}}, - {2678, {wxMDIChildFrame, restore, 0}}, - {2679, {wxMDIClientWindow, new_0, 0}}, - {2680, {wxMDIClientWindow, new_2, 2}}, - {2681, {wxMDIClientWindow, destruct, 0}}, - {2682, {wxMDIClientWindow, createClient, 2}}, - {2683, {wxLayoutAlgorithm, new, 0}}, - {2684, {wxLayoutAlgorithm, layoutFrame, 2}}, - {2685, {wxLayoutAlgorithm, layoutMDIFrame, 2}}, - {2686, {wxLayoutAlgorithm, layoutWindow, 2}}, - {2687, {wxLayoutAlgorithm, 'Destroy', undefined}}, - {2688, {wxEvent, getId, 0}}, - {2689, {wxEvent, getSkipped, 0}}, - {2690, {wxEvent, getTimestamp, 0}}, - {2691, {wxEvent, isCommandEvent, 0}}, - {2692, {wxEvent, resumePropagation, 1}}, - {2693, {wxEvent, shouldPropagate, 0}}, - {2694, {wxEvent, skip, 1}}, - {2695, {wxEvent, stopPropagation, 0}}, - {2696, {wxCommandEvent, getClientData, 0}}, - {2697, {wxCommandEvent, getExtraLong, 0}}, - {2698, {wxCommandEvent, getInt, 0}}, - {2699, {wxCommandEvent, getSelection, 0}}, - {2700, {wxCommandEvent, getString, 0}}, - {2701, {wxCommandEvent, isChecked, 0}}, - {2702, {wxCommandEvent, isSelection, 0}}, - {2703, {wxCommandEvent, setInt, 1}}, - {2704, {wxCommandEvent, setString, 1}}, - {2705, {wxScrollEvent, getOrientation, 0}}, - {2706, {wxScrollEvent, getPosition, 0}}, - {2707, {wxScrollWinEvent, getOrientation, 0}}, - {2708, {wxScrollWinEvent, getPosition, 0}}, - {2709, {wxMouseEvent, altDown, 0}}, - {2710, {wxMouseEvent, button, 1}}, - {2711, {wxMouseEvent, buttonDClick, 1}}, - {2712, {wxMouseEvent, buttonDown, 1}}, - {2713, {wxMouseEvent, buttonUp, 1}}, - {2714, {wxMouseEvent, cmdDown, 0}}, - {2715, {wxMouseEvent, controlDown, 0}}, - {2716, {wxMouseEvent, dragging, 0}}, - {2717, {wxMouseEvent, entering, 0}}, - {2718, {wxMouseEvent, getButton, 0}}, - {2721, {wxMouseEvent, getPosition, 0}}, - {2722, {wxMouseEvent, getLogicalPosition, 1}}, - {2723, {wxMouseEvent, getLinesPerAction, 0}}, - {2724, {wxMouseEvent, getWheelRotation, 0}}, - {2725, {wxMouseEvent, getWheelDelta, 0}}, - {2726, {wxMouseEvent, getX, 0}}, - {2727, {wxMouseEvent, getY, 0}}, - {2728, {wxMouseEvent, isButton, 0}}, - {2729, {wxMouseEvent, isPageScroll, 0}}, - {2730, {wxMouseEvent, leaving, 0}}, - {2731, {wxMouseEvent, leftDClick, 0}}, - {2732, {wxMouseEvent, leftDown, 0}}, - {2733, {wxMouseEvent, leftIsDown, 0}}, - {2734, {wxMouseEvent, leftUp, 0}}, - {2735, {wxMouseEvent, metaDown, 0}}, - {2736, {wxMouseEvent, middleDClick, 0}}, - {2737, {wxMouseEvent, middleDown, 0}}, - {2738, {wxMouseEvent, middleIsDown, 0}}, - {2739, {wxMouseEvent, middleUp, 0}}, - {2740, {wxMouseEvent, moving, 0}}, - {2741, {wxMouseEvent, rightDClick, 0}}, - {2742, {wxMouseEvent, rightDown, 0}}, - {2743, {wxMouseEvent, rightIsDown, 0}}, - {2744, {wxMouseEvent, rightUp, 0}}, - {2745, {wxMouseEvent, shiftDown, 0}}, - {2746, {wxSetCursorEvent, getCursor, 0}}, - {2747, {wxSetCursorEvent, getX, 0}}, - {2748, {wxSetCursorEvent, getY, 0}}, - {2749, {wxSetCursorEvent, hasCursor, 0}}, - {2750, {wxSetCursorEvent, setCursor, 1}}, - {2751, {wxKeyEvent, altDown, 0}}, - {2752, {wxKeyEvent, cmdDown, 0}}, - {2753, {wxKeyEvent, controlDown, 0}}, - {2754, {wxKeyEvent, getKeyCode, 0}}, - {2755, {wxKeyEvent, getModifiers, 0}}, - {2758, {wxKeyEvent, getPosition, 0}}, - {2759, {wxKeyEvent, getRawKeyCode, 0}}, - {2760, {wxKeyEvent, getRawKeyFlags, 0}}, - {2761, {wxKeyEvent, getUnicodeKey, 0}}, - {2762, {wxKeyEvent, getX, 0}}, - {2763, {wxKeyEvent, getY, 0}}, - {2764, {wxKeyEvent, hasModifiers, 0}}, - {2765, {wxKeyEvent, metaDown, 0}}, - {2766, {wxKeyEvent, shiftDown, 0}}, - {2767, {wxSizeEvent, getSize, 0}}, - {2768, {wxMoveEvent, getPosition, 0}}, - {2769, {wxEraseEvent, getDC, 0}}, - {2770, {wxFocusEvent, getWindow, 0}}, - {2771, {wxChildFocusEvent, getWindow, 0}}, - {2772, {wxMenuEvent, getMenu, 0}}, - {2773, {wxMenuEvent, getMenuId, 0}}, - {2774, {wxMenuEvent, isPopup, 0}}, - {2775, {wxCloseEvent, canVeto, 0}}, - {2776, {wxCloseEvent, getLoggingOff, 0}}, - {2777, {wxCloseEvent, setCanVeto, 1}}, - {2778, {wxCloseEvent, setLoggingOff, 1}}, - {2779, {wxCloseEvent, veto, 1}}, - {2780, {wxShowEvent, setShow, 1}}, - {2781, {wxShowEvent, getShow, 0}}, - {2782, {wxIconizeEvent, iconized, 0}}, - {2783, {wxJoystickEvent, buttonDown, 1}}, - {2784, {wxJoystickEvent, buttonIsDown, 1}}, - {2785, {wxJoystickEvent, buttonUp, 1}}, - {2786, {wxJoystickEvent, getButtonChange, 0}}, - {2787, {wxJoystickEvent, getButtonState, 0}}, - {2788, {wxJoystickEvent, getJoystick, 0}}, - {2789, {wxJoystickEvent, getPosition, 0}}, - {2790, {wxJoystickEvent, getZPosition, 0}}, - {2791, {wxJoystickEvent, isButton, 0}}, - {2792, {wxJoystickEvent, isMove, 0}}, - {2793, {wxJoystickEvent, isZMove, 0}}, - {2794, {wxUpdateUIEvent, canUpdate, 1}}, - {2795, {wxUpdateUIEvent, check, 1}}, - {2796, {wxUpdateUIEvent, enable, 1}}, - {2797, {wxUpdateUIEvent, show, 1}}, - {2798, {wxUpdateUIEvent, getChecked, 0}}, - {2799, {wxUpdateUIEvent, getEnabled, 0}}, - {2800, {wxUpdateUIEvent, getShown, 0}}, - {2801, {wxUpdateUIEvent, getSetChecked, 0}}, - {2802, {wxUpdateUIEvent, getSetEnabled, 0}}, - {2803, {wxUpdateUIEvent, getSetShown, 0}}, - {2804, {wxUpdateUIEvent, getSetText, 0}}, - {2805, {wxUpdateUIEvent, getText, 0}}, - {2806, {wxUpdateUIEvent, getMode, 0}}, - {2807, {wxUpdateUIEvent, getUpdateInterval, 0}}, - {2808, {wxUpdateUIEvent, resetUpdateTime, 0}}, - {2809, {wxUpdateUIEvent, setMode, 1}}, - {2810, {wxUpdateUIEvent, setText, 1}}, - {2811, {wxUpdateUIEvent, setUpdateInterval, 1}}, - {2812, {wxMouseCaptureChangedEvent, getCapturedWindow, 0}}, - {2813, {wxPaletteChangedEvent, setChangedWindow, 1}}, - {2814, {wxPaletteChangedEvent, getChangedWindow, 0}}, - {2815, {wxQueryNewPaletteEvent, setPaletteRealized, 1}}, - {2816, {wxQueryNewPaletteEvent, getPaletteRealized, 0}}, - {2817, {wxNavigationKeyEvent, getDirection, 0}}, - {2818, {wxNavigationKeyEvent, setDirection, 1}}, - {2819, {wxNavigationKeyEvent, isWindowChange, 0}}, - {2820, {wxNavigationKeyEvent, setWindowChange, 1}}, - {2821, {wxNavigationKeyEvent, isFromTab, 0}}, - {2822, {wxNavigationKeyEvent, setFromTab, 1}}, - {2823, {wxNavigationKeyEvent, getCurrentFocus, 0}}, - {2824, {wxNavigationKeyEvent, setCurrentFocus, 1}}, - {2825, {wxHelpEvent, getOrigin, 0}}, - {2826, {wxHelpEvent, getPosition, 0}}, - {2827, {wxHelpEvent, setOrigin, 1}}, - {2828, {wxHelpEvent, setPosition, 1}}, - {2829, {wxContextMenuEvent, getPosition, 0}}, - {2830, {wxContextMenuEvent, setPosition, 1}}, - {2831, {wxIdleEvent, canSend, 1}}, - {2832, {wxIdleEvent, getMode, 0}}, - {2833, {wxIdleEvent, requestMore, 1}}, - {2834, {wxIdleEvent, moreRequested, 0}}, - {2835, {wxIdleEvent, setMode, 1}}, - {2836, {wxGridEvent, altDown, 0}}, - {2837, {wxGridEvent, controlDown, 0}}, - {2838, {wxGridEvent, getCol, 0}}, - {2839, {wxGridEvent, getPosition, 0}}, - {2840, {wxGridEvent, getRow, 0}}, - {2841, {wxGridEvent, metaDown, 0}}, - {2842, {wxGridEvent, selecting, 0}}, - {2843, {wxGridEvent, shiftDown, 0}}, - {2844, {wxNotifyEvent, allow, 0}}, - {2845, {wxNotifyEvent, isAllowed, 0}}, - {2846, {wxNotifyEvent, veto, 0}}, - {2847, {wxSashEvent, getEdge, 0}}, - {2848, {wxSashEvent, getDragRect, 0}}, - {2849, {wxSashEvent, getDragStatus, 0}}, - {2850, {wxListEvent, getCacheFrom, 0}}, - {2851, {wxListEvent, getCacheTo, 0}}, - {2852, {wxListEvent, getKeyCode, 0}}, - {2853, {wxListEvent, getIndex, 0}}, - {2854, {wxListEvent, getColumn, 0}}, - {2855, {wxListEvent, getPoint, 0}}, - {2856, {wxListEvent, getLabel, 0}}, - {2857, {wxListEvent, getText, 0}}, - {2858, {wxListEvent, getImage, 0}}, - {2859, {wxListEvent, getData, 0}}, - {2860, {wxListEvent, getMask, 0}}, - {2861, {wxListEvent, getItem, 0}}, - {2862, {wxListEvent, isEditCancelled, 0}}, - {2863, {wxDateEvent, getDate, 0}}, - {2864, {wxCalendarEvent, getWeekDay, 0}}, - {2865, {wxFileDirPickerEvent, getPath, 0}}, - {2866, {wxColourPickerEvent, getColour, 0}}, - {2867, {wxFontPickerEvent, getFont, 0}}, - {2868, {wxStyledTextEvent, getPosition, 0}}, - {2869, {wxStyledTextEvent, getKey, 0}}, - {2870, {wxStyledTextEvent, getModifiers, 0}}, - {2871, {wxStyledTextEvent, getModificationType, 0}}, - {2872, {wxStyledTextEvent, getText, 0}}, - {2873, {wxStyledTextEvent, getLength, 0}}, - {2874, {wxStyledTextEvent, getLinesAdded, 0}}, - {2875, {wxStyledTextEvent, getLine, 0}}, - {2876, {wxStyledTextEvent, getFoldLevelNow, 0}}, - {2877, {wxStyledTextEvent, getFoldLevelPrev, 0}}, - {2878, {wxStyledTextEvent, getMargin, 0}}, - {2879, {wxStyledTextEvent, getMessage, 0}}, - {2880, {wxStyledTextEvent, getWParam, 0}}, - {2881, {wxStyledTextEvent, getLParam, 0}}, - {2882, {wxStyledTextEvent, getListType, 0}}, - {2883, {wxStyledTextEvent, getX, 0}}, - {2884, {wxStyledTextEvent, getY, 0}}, - {2885, {wxStyledTextEvent, getDragText, 0}}, - {2886, {wxStyledTextEvent, getDragAllowMove, 0}}, - {2887, {wxStyledTextEvent, getDragResult, 0}}, - {2888, {wxStyledTextEvent, getShift, 0}}, - {2889, {wxStyledTextEvent, getControl, 0}}, - {2890, {wxStyledTextEvent, getAlt, 0}}, - {2891, {utils, getKeyState, 1}}, - {2892, {utils, getMousePosition, 2}}, - {2893, {utils, getMouseState, 0}}, - {2894, {utils, setDetectableAutoRepeat, 1}}, - {2895, {utils, bell, 0}}, - {2896, {utils, findMenuItemId, 3}}, - {2897, {utils, genericFindWindowAtPoint, 1}}, - {2898, {utils, findWindowAtPoint, 1}}, - {2899, {utils, beginBusyCursor, 1}}, - {2900, {utils, endBusyCursor, 0}}, - {2901, {utils, isBusy, 0}}, - {2902, {utils, shutdown, 1}}, - {2903, {utils, shell, 1}}, - {2904, {utils, launchDefaultBrowser, 2}}, - {2905, {utils, getEmailAddress, 0}}, - {2906, {utils, getUserId, 0}}, - {2907, {utils, getHomeDir, 0}}, - {2908, {utils, newId, 0}}, - {2909, {utils, registerId, 1}}, - {2910, {utils, getCurrentId, 0}}, - {2911, {utils, getOsDescription, 0}}, - {2912, {utils, isPlatformLittleEndian, 0}}, - {2913, {utils, isPlatform64Bit, 0}}, - {2914, {wxPrintout, new, 1}}, - {2915, {wxPrintout, destruct, 0}}, - {2916, {wxPrintout, getDC, 0}}, - {2917, {wxPrintout, getPageSizeMM, 2}}, - {2918, {wxPrintout, getPageSizePixels, 2}}, - {2919, {wxPrintout, getPaperRectPixels, 0}}, - {2920, {wxPrintout, getPPIPrinter, 2}}, - {2921, {wxPrintout, getPPIScreen, 2}}, - {2922, {wxPrintout, getTitle, 0}}, - {2923, {wxPrintout, isPreview, 0}}, - {2924, {wxPrintout, fitThisSizeToPaper, 1}}, - {2925, {wxPrintout, fitThisSizeToPage, 1}}, - {2926, {wxPrintout, fitThisSizeToPageMargins, 2}}, - {2927, {wxPrintout, mapScreenSizeToPaper, 0}}, - {2928, {wxPrintout, mapScreenSizeToPage, 0}}, - {2929, {wxPrintout, mapScreenSizeToPageMargins, 1}}, - {2930, {wxPrintout, mapScreenSizeToDevice, 0}}, - {2931, {wxPrintout, getLogicalPaperRect, 0}}, - {2932, {wxPrintout, getLogicalPageRect, 0}}, - {2933, {wxPrintout, getLogicalPageMarginsRect, 1}}, - {2934, {wxPrintout, setLogicalOrigin, 2}}, - {2935, {wxPrintout, offsetLogicalOrigin, 2}}, - {2936, {wxStyledTextCtrl, new_2, 2}}, - {2937, {wxStyledTextCtrl, new_0, 0}}, - {2938, {wxStyledTextCtrl, destruct, 0}}, - {2939, {wxStyledTextCtrl, create, 2}}, - {2940, {wxStyledTextCtrl, addText, 1}}, - {2941, {wxStyledTextCtrl, addStyledText, 1}}, - {2942, {wxStyledTextCtrl, insertText, 2}}, - {2943, {wxStyledTextCtrl, clearAll, 0}}, - {2944, {wxStyledTextCtrl, clearDocumentStyle, 0}}, - {2945, {wxStyledTextCtrl, getLength, 0}}, - {2946, {wxStyledTextCtrl, getCharAt, 1}}, - {2947, {wxStyledTextCtrl, getCurrentPos, 0}}, - {2948, {wxStyledTextCtrl, getAnchor, 0}}, - {2949, {wxStyledTextCtrl, getStyleAt, 1}}, - {2950, {wxStyledTextCtrl, redo, 0}}, - {2951, {wxStyledTextCtrl, setUndoCollection, 1}}, - {2952, {wxStyledTextCtrl, selectAll, 0}}, - {2953, {wxStyledTextCtrl, setSavePoint, 0}}, - {2954, {wxStyledTextCtrl, getStyledText, 2}}, - {2955, {wxStyledTextCtrl, canRedo, 0}}, - {2956, {wxStyledTextCtrl, markerLineFromHandle, 1}}, - {2957, {wxStyledTextCtrl, markerDeleteHandle, 1}}, - {2958, {wxStyledTextCtrl, getUndoCollection, 0}}, - {2959, {wxStyledTextCtrl, getViewWhiteSpace, 0}}, - {2960, {wxStyledTextCtrl, setViewWhiteSpace, 1}}, - {2961, {wxStyledTextCtrl, positionFromPoint, 1}}, - {2962, {wxStyledTextCtrl, positionFromPointClose, 2}}, - {2963, {wxStyledTextCtrl, gotoLine, 1}}, - {2964, {wxStyledTextCtrl, gotoPos, 1}}, - {2965, {wxStyledTextCtrl, setAnchor, 1}}, - {2966, {wxStyledTextCtrl, getCurLine, 1}}, - {2967, {wxStyledTextCtrl, getEndStyled, 0}}, - {2968, {wxStyledTextCtrl, convertEOLs, 1}}, - {2969, {wxStyledTextCtrl, getEOLMode, 0}}, - {2970, {wxStyledTextCtrl, setEOLMode, 1}}, - {2971, {wxStyledTextCtrl, startStyling, 2}}, - {2972, {wxStyledTextCtrl, setStyling, 2}}, - {2973, {wxStyledTextCtrl, getBufferedDraw, 0}}, - {2974, {wxStyledTextCtrl, setBufferedDraw, 1}}, - {2975, {wxStyledTextCtrl, setTabWidth, 1}}, - {2976, {wxStyledTextCtrl, getTabWidth, 0}}, - {2977, {wxStyledTextCtrl, setCodePage, 1}}, - {2978, {wxStyledTextCtrl, markerDefine, 3}}, - {2979, {wxStyledTextCtrl, markerSetForeground, 2}}, - {2980, {wxStyledTextCtrl, markerSetBackground, 2}}, - {2981, {wxStyledTextCtrl, markerAdd, 2}}, - {2982, {wxStyledTextCtrl, markerDelete, 2}}, - {2983, {wxStyledTextCtrl, markerDeleteAll, 1}}, - {2984, {wxStyledTextCtrl, markerGet, 1}}, - {2985, {wxStyledTextCtrl, markerNext, 2}}, - {2986, {wxStyledTextCtrl, markerPrevious, 2}}, - {2987, {wxStyledTextCtrl, markerDefineBitmap, 2}}, - {2988, {wxStyledTextCtrl, markerAddSet, 2}}, - {2989, {wxStyledTextCtrl, markerSetAlpha, 2}}, - {2990, {wxStyledTextCtrl, setMarginType, 2}}, - {2991, {wxStyledTextCtrl, getMarginType, 1}}, - {2992, {wxStyledTextCtrl, setMarginWidth, 2}}, - {2993, {wxStyledTextCtrl, getMarginWidth, 1}}, - {2994, {wxStyledTextCtrl, setMarginMask, 2}}, - {2995, {wxStyledTextCtrl, getMarginMask, 1}}, - {2996, {wxStyledTextCtrl, setMarginSensitive, 2}}, - {2997, {wxStyledTextCtrl, getMarginSensitive, 1}}, - {2998, {wxStyledTextCtrl, styleClearAll, 0}}, - {2999, {wxStyledTextCtrl, styleSetForeground, 2}}, - {3000, {wxStyledTextCtrl, styleSetBackground, 2}}, - {3001, {wxStyledTextCtrl, styleSetBold, 2}}, - {3002, {wxStyledTextCtrl, styleSetItalic, 2}}, - {3003, {wxStyledTextCtrl, styleSetSize, 2}}, - {3004, {wxStyledTextCtrl, styleSetFaceName, 2}}, - {3005, {wxStyledTextCtrl, styleSetEOLFilled, 2}}, - {3006, {wxStyledTextCtrl, styleResetDefault, 0}}, - {3007, {wxStyledTextCtrl, styleSetUnderline, 2}}, - {3008, {wxStyledTextCtrl, styleSetCase, 2}}, - {3009, {wxStyledTextCtrl, styleSetHotSpot, 2}}, - {3010, {wxStyledTextCtrl, setSelForeground, 2}}, - {3011, {wxStyledTextCtrl, setSelBackground, 2}}, - {3012, {wxStyledTextCtrl, getSelAlpha, 0}}, - {3013, {wxStyledTextCtrl, setSelAlpha, 1}}, - {3014, {wxStyledTextCtrl, setCaretForeground, 1}}, - {3015, {wxStyledTextCtrl, cmdKeyAssign, 3}}, - {3016, {wxStyledTextCtrl, cmdKeyClear, 2}}, - {3017, {wxStyledTextCtrl, cmdKeyClearAll, 0}}, - {3018, {wxStyledTextCtrl, setStyleBytes, 2}}, - {3019, {wxStyledTextCtrl, styleSetVisible, 2}}, - {3020, {wxStyledTextCtrl, getCaretPeriod, 0}}, - {3021, {wxStyledTextCtrl, setCaretPeriod, 1}}, - {3022, {wxStyledTextCtrl, setWordChars, 1}}, - {3023, {wxStyledTextCtrl, beginUndoAction, 0}}, - {3024, {wxStyledTextCtrl, endUndoAction, 0}}, - {3025, {wxStyledTextCtrl, indicatorSetStyle, 2}}, - {3026, {wxStyledTextCtrl, indicatorGetStyle, 1}}, - {3027, {wxStyledTextCtrl, indicatorSetForeground, 2}}, - {3028, {wxStyledTextCtrl, indicatorGetForeground, 1}}, - {3029, {wxStyledTextCtrl, setWhitespaceForeground, 2}}, - {3030, {wxStyledTextCtrl, setWhitespaceBackground, 2}}, - {3031, {wxStyledTextCtrl, getStyleBits, 0}}, - {3032, {wxStyledTextCtrl, setLineState, 2}}, - {3033, {wxStyledTextCtrl, getLineState, 1}}, - {3034, {wxStyledTextCtrl, getMaxLineState, 0}}, - {3035, {wxStyledTextCtrl, getCaretLineVisible, 0}}, - {3036, {wxStyledTextCtrl, setCaretLineVisible, 1}}, - {3037, {wxStyledTextCtrl, getCaretLineBackground, 0}}, - {3038, {wxStyledTextCtrl, setCaretLineBackground, 1}}, - {3039, {wxStyledTextCtrl, autoCompShow, 2}}, - {3040, {wxStyledTextCtrl, autoCompCancel, 0}}, - {3041, {wxStyledTextCtrl, autoCompActive, 0}}, - {3042, {wxStyledTextCtrl, autoCompPosStart, 0}}, - {3043, {wxStyledTextCtrl, autoCompComplete, 0}}, - {3044, {wxStyledTextCtrl, autoCompStops, 1}}, - {3045, {wxStyledTextCtrl, autoCompSetSeparator, 1}}, - {3046, {wxStyledTextCtrl, autoCompGetSeparator, 0}}, - {3047, {wxStyledTextCtrl, autoCompSelect, 1}}, - {3048, {wxStyledTextCtrl, autoCompSetCancelAtStart, 1}}, - {3049, {wxStyledTextCtrl, autoCompGetCancelAtStart, 0}}, - {3050, {wxStyledTextCtrl, autoCompSetFillUps, 1}}, - {3051, {wxStyledTextCtrl, autoCompSetChooseSingle, 1}}, - {3052, {wxStyledTextCtrl, autoCompGetChooseSingle, 0}}, - {3053, {wxStyledTextCtrl, autoCompSetIgnoreCase, 1}}, - {3054, {wxStyledTextCtrl, autoCompGetIgnoreCase, 0}}, - {3055, {wxStyledTextCtrl, userListShow, 2}}, - {3056, {wxStyledTextCtrl, autoCompSetAutoHide, 1}}, - {3057, {wxStyledTextCtrl, autoCompGetAutoHide, 0}}, - {3058, {wxStyledTextCtrl, autoCompSetDropRestOfWord, 1}}, - {3059, {wxStyledTextCtrl, autoCompGetDropRestOfWord, 0}}, - {3060, {wxStyledTextCtrl, registerImage, 2}}, - {3061, {wxStyledTextCtrl, clearRegisteredImages, 0}}, - {3062, {wxStyledTextCtrl, autoCompGetTypeSeparator, 0}}, - {3063, {wxStyledTextCtrl, autoCompSetTypeSeparator, 1}}, - {3064, {wxStyledTextCtrl, autoCompSetMaxWidth, 1}}, - {3065, {wxStyledTextCtrl, autoCompGetMaxWidth, 0}}, - {3066, {wxStyledTextCtrl, autoCompSetMaxHeight, 1}}, - {3067, {wxStyledTextCtrl, autoCompGetMaxHeight, 0}}, - {3068, {wxStyledTextCtrl, setIndent, 1}}, - {3069, {wxStyledTextCtrl, getIndent, 0}}, - {3070, {wxStyledTextCtrl, setUseTabs, 1}}, - {3071, {wxStyledTextCtrl, getUseTabs, 0}}, - {3072, {wxStyledTextCtrl, setLineIndentation, 2}}, - {3073, {wxStyledTextCtrl, getLineIndentation, 1}}, - {3074, {wxStyledTextCtrl, getLineIndentPosition, 1}}, - {3075, {wxStyledTextCtrl, getColumn, 1}}, - {3076, {wxStyledTextCtrl, setUseHorizontalScrollBar, 1}}, - {3077, {wxStyledTextCtrl, getUseHorizontalScrollBar, 0}}, - {3078, {wxStyledTextCtrl, setIndentationGuides, 1}}, - {3079, {wxStyledTextCtrl, getIndentationGuides, 0}}, - {3080, {wxStyledTextCtrl, setHighlightGuide, 1}}, - {3081, {wxStyledTextCtrl, getHighlightGuide, 0}}, - {3082, {wxStyledTextCtrl, getLineEndPosition, 1}}, - {3083, {wxStyledTextCtrl, getCodePage, 0}}, - {3084, {wxStyledTextCtrl, getCaretForeground, 0}}, - {3085, {wxStyledTextCtrl, getReadOnly, 0}}, - {3086, {wxStyledTextCtrl, setCurrentPos, 1}}, - {3087, {wxStyledTextCtrl, setSelectionStart, 1}}, - {3088, {wxStyledTextCtrl, getSelectionStart, 0}}, - {3089, {wxStyledTextCtrl, setSelectionEnd, 1}}, - {3090, {wxStyledTextCtrl, getSelectionEnd, 0}}, - {3091, {wxStyledTextCtrl, setPrintMagnification, 1}}, - {3092, {wxStyledTextCtrl, getPrintMagnification, 0}}, - {3093, {wxStyledTextCtrl, setPrintColourMode, 1}}, - {3094, {wxStyledTextCtrl, getPrintColourMode, 0}}, - {3095, {wxStyledTextCtrl, findText, 4}}, - {3096, {wxStyledTextCtrl, formatRange, 7}}, - {3097, {wxStyledTextCtrl, getFirstVisibleLine, 0}}, - {3098, {wxStyledTextCtrl, getLine, 1}}, - {3099, {wxStyledTextCtrl, getLineCount, 0}}, - {3100, {wxStyledTextCtrl, setMarginLeft, 1}}, - {3101, {wxStyledTextCtrl, getMarginLeft, 0}}, - {3102, {wxStyledTextCtrl, setMarginRight, 1}}, - {3103, {wxStyledTextCtrl, getMarginRight, 0}}, - {3104, {wxStyledTextCtrl, getModify, 0}}, - {3105, {wxStyledTextCtrl, setSelection, 2}}, - {3106, {wxStyledTextCtrl, getSelectedText, 0}}, - {3107, {wxStyledTextCtrl, getTextRange, 2}}, - {3108, {wxStyledTextCtrl, hideSelection, 1}}, - {3109, {wxStyledTextCtrl, lineFromPosition, 1}}, - {3110, {wxStyledTextCtrl, positionFromLine, 1}}, - {3111, {wxStyledTextCtrl, lineScroll, 2}}, - {3112, {wxStyledTextCtrl, ensureCaretVisible, 0}}, - {3113, {wxStyledTextCtrl, replaceSelection, 1}}, - {3114, {wxStyledTextCtrl, setReadOnly, 1}}, - {3115, {wxStyledTextCtrl, canPaste, 0}}, - {3116, {wxStyledTextCtrl, canUndo, 0}}, - {3117, {wxStyledTextCtrl, emptyUndoBuffer, 0}}, - {3118, {wxStyledTextCtrl, undo, 0}}, - {3119, {wxStyledTextCtrl, cut, 0}}, - {3120, {wxStyledTextCtrl, copy, 0}}, - {3121, {wxStyledTextCtrl, paste, 0}}, - {3122, {wxStyledTextCtrl, clear, 0}}, - {3123, {wxStyledTextCtrl, setText, 1}}, - {3124, {wxStyledTextCtrl, getText, 0}}, - {3125, {wxStyledTextCtrl, getTextLength, 0}}, - {3126, {wxStyledTextCtrl, getOvertype, 0}}, - {3127, {wxStyledTextCtrl, setCaretWidth, 1}}, - {3128, {wxStyledTextCtrl, getCaretWidth, 0}}, - {3129, {wxStyledTextCtrl, setTargetStart, 1}}, - {3130, {wxStyledTextCtrl, getTargetStart, 0}}, - {3131, {wxStyledTextCtrl, setTargetEnd, 1}}, - {3132, {wxStyledTextCtrl, getTargetEnd, 0}}, - {3133, {wxStyledTextCtrl, replaceTarget, 1}}, - {3134, {wxStyledTextCtrl, searchInTarget, 1}}, - {3135, {wxStyledTextCtrl, setSearchFlags, 1}}, - {3136, {wxStyledTextCtrl, getSearchFlags, 0}}, - {3137, {wxStyledTextCtrl, callTipShow, 2}}, - {3138, {wxStyledTextCtrl, callTipCancel, 0}}, - {3139, {wxStyledTextCtrl, callTipActive, 0}}, - {3140, {wxStyledTextCtrl, callTipPosAtStart, 0}}, - {3141, {wxStyledTextCtrl, callTipSetHighlight, 2}}, - {3142, {wxStyledTextCtrl, callTipSetBackground, 1}}, - {3143, {wxStyledTextCtrl, callTipSetForeground, 1}}, - {3144, {wxStyledTextCtrl, callTipSetForegroundHighlight, 1}}, - {3145, {wxStyledTextCtrl, callTipUseStyle, 1}}, - {3146, {wxStyledTextCtrl, visibleFromDocLine, 1}}, - {3147, {wxStyledTextCtrl, docLineFromVisible, 1}}, - {3148, {wxStyledTextCtrl, wrapCount, 1}}, - {3149, {wxStyledTextCtrl, setFoldLevel, 2}}, - {3150, {wxStyledTextCtrl, getFoldLevel, 1}}, - {3151, {wxStyledTextCtrl, getLastChild, 2}}, - {3152, {wxStyledTextCtrl, getFoldParent, 1}}, - {3153, {wxStyledTextCtrl, showLines, 2}}, - {3154, {wxStyledTextCtrl, hideLines, 2}}, - {3155, {wxStyledTextCtrl, getLineVisible, 1}}, - {3156, {wxStyledTextCtrl, setFoldExpanded, 2}}, - {3157, {wxStyledTextCtrl, getFoldExpanded, 1}}, - {3158, {wxStyledTextCtrl, toggleFold, 1}}, - {3159, {wxStyledTextCtrl, ensureVisible, 1}}, - {3160, {wxStyledTextCtrl, setFoldFlags, 1}}, - {3161, {wxStyledTextCtrl, ensureVisibleEnforcePolicy, 1}}, - {3162, {wxStyledTextCtrl, setTabIndents, 1}}, - {3163, {wxStyledTextCtrl, getTabIndents, 0}}, - {3164, {wxStyledTextCtrl, setBackSpaceUnIndents, 1}}, - {3165, {wxStyledTextCtrl, getBackSpaceUnIndents, 0}}, - {3166, {wxStyledTextCtrl, setMouseDwellTime, 1}}, - {3167, {wxStyledTextCtrl, getMouseDwellTime, 0}}, - {3168, {wxStyledTextCtrl, wordStartPosition, 2}}, - {3169, {wxStyledTextCtrl, wordEndPosition, 2}}, - {3170, {wxStyledTextCtrl, setWrapMode, 1}}, - {3171, {wxStyledTextCtrl, getWrapMode, 0}}, - {3172, {wxStyledTextCtrl, setWrapVisualFlags, 1}}, - {3173, {wxStyledTextCtrl, getWrapVisualFlags, 0}}, - {3174, {wxStyledTextCtrl, setWrapVisualFlagsLocation, 1}}, - {3175, {wxStyledTextCtrl, getWrapVisualFlagsLocation, 0}}, - {3176, {wxStyledTextCtrl, setWrapStartIndent, 1}}, - {3177, {wxStyledTextCtrl, getWrapStartIndent, 0}}, - {3178, {wxStyledTextCtrl, setLayoutCache, 1}}, - {3179, {wxStyledTextCtrl, getLayoutCache, 0}}, - {3180, {wxStyledTextCtrl, setScrollWidth, 1}}, - {3181, {wxStyledTextCtrl, getScrollWidth, 0}}, - {3182, {wxStyledTextCtrl, textWidth, 2}}, - {3183, {wxStyledTextCtrl, getEndAtLastLine, 0}}, - {3184, {wxStyledTextCtrl, textHeight, 1}}, - {3185, {wxStyledTextCtrl, setUseVerticalScrollBar, 1}}, - {3186, {wxStyledTextCtrl, getUseVerticalScrollBar, 0}}, - {3187, {wxStyledTextCtrl, appendText, 1}}, - {3188, {wxStyledTextCtrl, getTwoPhaseDraw, 0}}, - {3189, {wxStyledTextCtrl, setTwoPhaseDraw, 1}}, - {3190, {wxStyledTextCtrl, targetFromSelection, 0}}, - {3191, {wxStyledTextCtrl, linesJoin, 0}}, - {3192, {wxStyledTextCtrl, linesSplit, 1}}, - {3193, {wxStyledTextCtrl, setFoldMarginColour, 2}}, - {3194, {wxStyledTextCtrl, setFoldMarginHiColour, 2}}, - {3195, {wxStyledTextCtrl, lineDown, 0}}, - {3196, {wxStyledTextCtrl, lineDownExtend, 0}}, - {3197, {wxStyledTextCtrl, lineUp, 0}}, - {3198, {wxStyledTextCtrl, lineUpExtend, 0}}, - {3199, {wxStyledTextCtrl, charLeft, 0}}, - {3200, {wxStyledTextCtrl, charLeftExtend, 0}}, - {3201, {wxStyledTextCtrl, charRight, 0}}, - {3202, {wxStyledTextCtrl, charRightExtend, 0}}, - {3203, {wxStyledTextCtrl, wordLeft, 0}}, - {3204, {wxStyledTextCtrl, wordLeftExtend, 0}}, - {3205, {wxStyledTextCtrl, wordRight, 0}}, - {3206, {wxStyledTextCtrl, wordRightExtend, 0}}, - {3207, {wxStyledTextCtrl, home, 0}}, - {3208, {wxStyledTextCtrl, homeExtend, 0}}, - {3209, {wxStyledTextCtrl, lineEnd, 0}}, - {3210, {wxStyledTextCtrl, lineEndExtend, 0}}, - {3211, {wxStyledTextCtrl, documentStart, 0}}, - {3212, {wxStyledTextCtrl, documentStartExtend, 0}}, - {3213, {wxStyledTextCtrl, documentEnd, 0}}, - {3214, {wxStyledTextCtrl, documentEndExtend, 0}}, - {3215, {wxStyledTextCtrl, pageUp, 0}}, - {3216, {wxStyledTextCtrl, pageUpExtend, 0}}, - {3217, {wxStyledTextCtrl, pageDown, 0}}, - {3218, {wxStyledTextCtrl, pageDownExtend, 0}}, - {3219, {wxStyledTextCtrl, editToggleOvertype, 0}}, - {3220, {wxStyledTextCtrl, cancel, 0}}, - {3221, {wxStyledTextCtrl, deleteBack, 0}}, - {3222, {wxStyledTextCtrl, tab, 0}}, - {3223, {wxStyledTextCtrl, backTab, 0}}, - {3224, {wxStyledTextCtrl, newLine, 0}}, - {3225, {wxStyledTextCtrl, formFeed, 0}}, - {3226, {wxStyledTextCtrl, vCHome, 0}}, - {3227, {wxStyledTextCtrl, vCHomeExtend, 0}}, - {3228, {wxStyledTextCtrl, zoomIn, 0}}, - {3229, {wxStyledTextCtrl, zoomOut, 0}}, - {3230, {wxStyledTextCtrl, delWordLeft, 0}}, - {3231, {wxStyledTextCtrl, delWordRight, 0}}, - {3232, {wxStyledTextCtrl, lineCut, 0}}, - {3233, {wxStyledTextCtrl, lineDelete, 0}}, - {3234, {wxStyledTextCtrl, lineTranspose, 0}}, - {3235, {wxStyledTextCtrl, lineDuplicate, 0}}, - {3236, {wxStyledTextCtrl, lowerCase, 0}}, - {3237, {wxStyledTextCtrl, upperCase, 0}}, - {3238, {wxStyledTextCtrl, lineScrollDown, 0}}, - {3239, {wxStyledTextCtrl, lineScrollUp, 0}}, - {3240, {wxStyledTextCtrl, deleteBackNotLine, 0}}, - {3241, {wxStyledTextCtrl, homeDisplay, 0}}, - {3242, {wxStyledTextCtrl, homeDisplayExtend, 0}}, - {3243, {wxStyledTextCtrl, lineEndDisplay, 0}}, - {3244, {wxStyledTextCtrl, lineEndDisplayExtend, 0}}, - {3245, {wxStyledTextCtrl, homeWrapExtend, 0}}, - {3246, {wxStyledTextCtrl, lineEndWrap, 0}}, - {3247, {wxStyledTextCtrl, lineEndWrapExtend, 0}}, - {3248, {wxStyledTextCtrl, vCHomeWrap, 0}}, - {3249, {wxStyledTextCtrl, vCHomeWrapExtend, 0}}, - {3250, {wxStyledTextCtrl, lineCopy, 0}}, - {3251, {wxStyledTextCtrl, moveCaretInsideView, 0}}, - {3252, {wxStyledTextCtrl, lineLength, 1}}, - {3253, {wxStyledTextCtrl, braceHighlight, 2}}, - {3254, {wxStyledTextCtrl, braceBadLight, 1}}, - {3255, {wxStyledTextCtrl, braceMatch, 1}}, - {3256, {wxStyledTextCtrl, getViewEOL, 0}}, - {3257, {wxStyledTextCtrl, setViewEOL, 1}}, - {3258, {wxStyledTextCtrl, setModEventMask, 1}}, - {3259, {wxStyledTextCtrl, getEdgeColumn, 0}}, - {3260, {wxStyledTextCtrl, setEdgeColumn, 1}}, - {3261, {wxStyledTextCtrl, getEdgeMode, 0}}, - {3262, {wxStyledTextCtrl, getEdgeColour, 0}}, - {3263, {wxStyledTextCtrl, setEdgeColour, 1}}, - {3264, {wxStyledTextCtrl, searchAnchor, 0}}, - {3265, {wxStyledTextCtrl, searchNext, 2}}, - {3266, {wxStyledTextCtrl, searchPrev, 2}}, - {3267, {wxStyledTextCtrl, linesOnScreen, 0}}, - {3268, {wxStyledTextCtrl, usePopUp, 1}}, - {3269, {wxStyledTextCtrl, selectionIsRectangle, 0}}, - {3270, {wxStyledTextCtrl, setZoom, 1}}, - {3271, {wxStyledTextCtrl, getZoom, 0}}, - {3272, {wxStyledTextCtrl, getModEventMask, 0}}, - {3273, {wxStyledTextCtrl, setSTCFocus, 1}}, - {3274, {wxStyledTextCtrl, getSTCFocus, 0}}, - {3275, {wxStyledTextCtrl, setStatus, 1}}, - {3276, {wxStyledTextCtrl, getStatus, 0}}, - {3277, {wxStyledTextCtrl, setMouseDownCaptures, 1}}, - {3278, {wxStyledTextCtrl, getMouseDownCaptures, 0}}, - {3279, {wxStyledTextCtrl, setSTCCursor, 1}}, - {3280, {wxStyledTextCtrl, getSTCCursor, 0}}, - {3281, {wxStyledTextCtrl, setControlCharSymbol, 1}}, - {3282, {wxStyledTextCtrl, getControlCharSymbol, 0}}, - {3283, {wxStyledTextCtrl, wordPartLeft, 0}}, - {3284, {wxStyledTextCtrl, wordPartLeftExtend, 0}}, - {3285, {wxStyledTextCtrl, wordPartRight, 0}}, - {3286, {wxStyledTextCtrl, wordPartRightExtend, 0}}, - {3287, {wxStyledTextCtrl, setVisiblePolicy, 2}}, - {3288, {wxStyledTextCtrl, delLineLeft, 0}}, - {3289, {wxStyledTextCtrl, delLineRight, 0}}, - {3290, {wxStyledTextCtrl, getXOffset, 0}}, - {3291, {wxStyledTextCtrl, chooseCaretX, 0}}, - {3292, {wxStyledTextCtrl, setXCaretPolicy, 2}}, - {3293, {wxStyledTextCtrl, setYCaretPolicy, 2}}, - {3294, {wxStyledTextCtrl, getPrintWrapMode, 0}}, - {3295, {wxStyledTextCtrl, setHotspotActiveForeground, 2}}, - {3296, {wxStyledTextCtrl, setHotspotActiveBackground, 2}}, - {3297, {wxStyledTextCtrl, setHotspotActiveUnderline, 1}}, - {3298, {wxStyledTextCtrl, setHotspotSingleLine, 1}}, - {3299, {wxStyledTextCtrl, paraDownExtend, 0}}, - {3300, {wxStyledTextCtrl, paraUp, 0}}, - {3301, {wxStyledTextCtrl, paraUpExtend, 0}}, - {3302, {wxStyledTextCtrl, positionBefore, 1}}, - {3303, {wxStyledTextCtrl, positionAfter, 1}}, - {3304, {wxStyledTextCtrl, copyRange, 2}}, - {3305, {wxStyledTextCtrl, copyText, 2}}, - {3306, {wxStyledTextCtrl, setSelectionMode, 1}}, - {3307, {wxStyledTextCtrl, getSelectionMode, 0}}, - {3308, {wxStyledTextCtrl, lineDownRectExtend, 0}}, - {3309, {wxStyledTextCtrl, lineUpRectExtend, 0}}, - {3310, {wxStyledTextCtrl, charLeftRectExtend, 0}}, - {3311, {wxStyledTextCtrl, charRightRectExtend, 0}}, - {3312, {wxStyledTextCtrl, homeRectExtend, 0}}, - {3313, {wxStyledTextCtrl, vCHomeRectExtend, 0}}, - {3314, {wxStyledTextCtrl, lineEndRectExtend, 0}}, - {3315, {wxStyledTextCtrl, pageUpRectExtend, 0}}, - {3316, {wxStyledTextCtrl, pageDownRectExtend, 0}}, - {3317, {wxStyledTextCtrl, stutteredPageUp, 0}}, - {3318, {wxStyledTextCtrl, stutteredPageUpExtend, 0}}, - {3319, {wxStyledTextCtrl, stutteredPageDown, 0}}, - {3320, {wxStyledTextCtrl, stutteredPageDownExtend, 0}}, - {3321, {wxStyledTextCtrl, wordLeftEnd, 0}}, - {3322, {wxStyledTextCtrl, wordLeftEndExtend, 0}}, - {3323, {wxStyledTextCtrl, wordRightEnd, 0}}, - {3324, {wxStyledTextCtrl, wordRightEndExtend, 0}}, - {3325, {wxStyledTextCtrl, setWhitespaceChars, 1}}, - {3326, {wxStyledTextCtrl, setCharsDefault, 0}}, - {3327, {wxStyledTextCtrl, autoCompGetCurrent, 0}}, - {3328, {wxStyledTextCtrl, allocate, 1}}, - {3329, {wxStyledTextCtrl, findColumn, 2}}, - {3330, {wxStyledTextCtrl, getCaretSticky, 0}}, - {3331, {wxStyledTextCtrl, setCaretSticky, 1}}, - {3332, {wxStyledTextCtrl, toggleCaretSticky, 0}}, - {3333, {wxStyledTextCtrl, setPasteConvertEndings, 1}}, - {3334, {wxStyledTextCtrl, getPasteConvertEndings, 0}}, - {3335, {wxStyledTextCtrl, selectionDuplicate, 0}}, - {3336, {wxStyledTextCtrl, setCaretLineBackAlpha, 1}}, - {3337, {wxStyledTextCtrl, getCaretLineBackAlpha, 0}}, - {3338, {wxStyledTextCtrl, startRecord, 0}}, - {3339, {wxStyledTextCtrl, stopRecord, 0}}, - {3340, {wxStyledTextCtrl, setLexer, 1}}, - {3341, {wxStyledTextCtrl, getLexer, 0}}, - {3342, {wxStyledTextCtrl, colourise, 2}}, - {3343, {wxStyledTextCtrl, setProperty, 2}}, - {3344, {wxStyledTextCtrl, setKeyWords, 2}}, - {3345, {wxStyledTextCtrl, setLexerLanguage, 1}}, - {3346, {wxStyledTextCtrl, getProperty, 1}}, - {3347, {wxStyledTextCtrl, getStyleBitsNeeded, 0}}, - {3348, {wxStyledTextCtrl, getCurrentLine, 0}}, - {3349, {wxStyledTextCtrl, styleSetSpec, 2}}, - {3350, {wxStyledTextCtrl, styleSetFont, 2}}, - {3351, {wxStyledTextCtrl, styleSetFontAttr, 7}}, - {3352, {wxStyledTextCtrl, styleSetCharacterSet, 2}}, - {3353, {wxStyledTextCtrl, styleSetFontEncoding, 2}}, - {3354, {wxStyledTextCtrl, cmdKeyExecute, 1}}, - {3355, {wxStyledTextCtrl, setMargins, 2}}, - {3356, {wxStyledTextCtrl, getSelection, 2}}, - {3357, {wxStyledTextCtrl, pointFromPosition, 1}}, - {3358, {wxStyledTextCtrl, scrollToLine, 1}}, - {3359, {wxStyledTextCtrl, scrollToColumn, 1}}, - {3360, {wxStyledTextCtrl, sendMsg, 2}}, - {3361, {wxStyledTextCtrl, setVScrollBar, 1}}, - {3362, {wxStyledTextCtrl, setHScrollBar, 1}}, - {3363, {wxStyledTextCtrl, getLastKeydownProcessed, 0}}, - {3364, {wxStyledTextCtrl, setLastKeydownProcessed, 1}}, - {3365, {wxStyledTextCtrl, saveFile, 1}}, - {3366, {wxStyledTextCtrl, loadFile, 1}}, - {3367, {wxStyledTextCtrl, doDragOver, 3}}, - {3368, {wxStyledTextCtrl, doDropText, 3}}, - {3369, {wxStyledTextCtrl, getUseAntiAliasing, 0}}, - {3370, {wxStyledTextCtrl, addTextRaw, 1}}, - {3371, {wxStyledTextCtrl, insertTextRaw, 2}}, - {3372, {wxStyledTextCtrl, getCurLineRaw, 1}}, - {3373, {wxStyledTextCtrl, getLineRaw, 1}}, - {3374, {wxStyledTextCtrl, getSelectedTextRaw, 0}}, - {3375, {wxStyledTextCtrl, getTextRangeRaw, 2}}, - {3376, {wxStyledTextCtrl, setTextRaw, 1}}, - {3377, {wxStyledTextCtrl, getTextRaw, 0}}, - {3378, {wxStyledTextCtrl, appendTextRaw, 1}}, - {3379, {wxArtProvider, getBitmap, 2}}, - {3380, {wxArtProvider, getIcon, 2}}, - {3381, {wxTreeEvent, getKeyCode, 0}}, - {3382, {wxTreeEvent, getItem, 0}}, - {3383, {wxTreeEvent, getKeyEvent, 0}}, - {3384, {wxTreeEvent, getLabel, 0}}, - {3385, {wxTreeEvent, getOldItem, 0}}, - {3386, {wxTreeEvent, getPoint, 0}}, - {3387, {wxTreeEvent, isEditCancelled, 0}}, - {3388, {wxTreeEvent, setToolTip, 1}}, - {3389, {wxNotebookEvent, getOldSelection, 0}}, - {3390, {wxNotebookEvent, getSelection, 0}}, - {3391, {wxNotebookEvent, setOldSelection, 1}}, - {3392, {wxNotebookEvent, setSelection, 1}}, - {3393, {wxFileDataObject, new, 0}}, - {3394, {wxFileDataObject, addFile, 1}}, - {3395, {wxFileDataObject, getFilenames, 0}}, - {3396, {wxFileDataObject, 'Destroy', undefined}}, - {3397, {wxTextDataObject, new, 1}}, - {3398, {wxTextDataObject, getTextLength, 0}}, - {3399, {wxTextDataObject, getText, 0}}, - {3400, {wxTextDataObject, setText, 1}}, - {3401, {wxTextDataObject, 'Destroy', undefined}}, - {3402, {wxBitmapDataObject, new_1_1, 1}}, - {3403, {wxBitmapDataObject, new_1_0, 1}}, - {3404, {wxBitmapDataObject, getBitmap, 0}}, - {3405, {wxBitmapDataObject, setBitmap, 1}}, - {3406, {wxBitmapDataObject, 'Destroy', undefined}}, - {3408, {wxClipboard, new, 0}}, - {3409, {wxClipboard, destruct, 0}}, - {3410, {wxClipboard, addData, 1}}, - {3411, {wxClipboard, clear, 0}}, - {3412, {wxClipboard, close, 0}}, - {3413, {wxClipboard, flush, 0}}, - {3414, {wxClipboard, getData, 1}}, - {3415, {wxClipboard, isOpened, 0}}, - {3416, {wxClipboard, open, 0}}, - {3417, {wxClipboard, setData, 1}}, - {3419, {wxClipboard, usePrimarySelection, 1}}, - {3420, {wxClipboard, isSupported, 1}}, - {3421, {wxClipboard, get, 0}}, - {3422, {wxSpinEvent, getPosition, 0}}, - {3423, {wxSpinEvent, setPosition, 1}}, - {3424, {wxSplitterWindow, new_0, 0}}, - {3425, {wxSplitterWindow, new_2, 2}}, - {3426, {wxSplitterWindow, destruct, 0}}, - {3427, {wxSplitterWindow, create, 2}}, - {3428, {wxSplitterWindow, getMinimumPaneSize, 0}}, - {3429, {wxSplitterWindow, getSashGravity, 0}}, - {3430, {wxSplitterWindow, getSashPosition, 0}}, - {3431, {wxSplitterWindow, getSplitMode, 0}}, - {3432, {wxSplitterWindow, getWindow1, 0}}, - {3433, {wxSplitterWindow, getWindow2, 0}}, - {3434, {wxSplitterWindow, initialize, 1}}, - {3435, {wxSplitterWindow, isSplit, 0}}, - {3436, {wxSplitterWindow, replaceWindow, 2}}, - {3437, {wxSplitterWindow, setSashGravity, 1}}, - {3438, {wxSplitterWindow, setSashPosition, 2}}, - {3439, {wxSplitterWindow, setSashSize, 1}}, - {3440, {wxSplitterWindow, setMinimumPaneSize, 1}}, - {3441, {wxSplitterWindow, setSplitMode, 1}}, - {3442, {wxSplitterWindow, splitHorizontally, 3}}, - {3443, {wxSplitterWindow, splitVertically, 3}}, - {3444, {wxSplitterWindow, unsplit, 1}}, - {3445, {wxSplitterWindow, updateSize, 0}}, - {3446, {wxSplitterEvent, getSashPosition, 0}}, - {3447, {wxSplitterEvent, getX, 0}}, - {3448, {wxSplitterEvent, getY, 0}}, - {3449, {wxSplitterEvent, getWindowBeingRemoved, 0}}, - {3450, {wxSplitterEvent, setSashPosition, 1}}, - {3451, {wxHtmlWindow, new_0, 0}}, - {3452, {wxHtmlWindow, new_2, 2}}, - {3453, {wxHtmlWindow, appendToPage, 1}}, - {3454, {wxHtmlWindow, getOpenedAnchor, 0}}, - {3455, {wxHtmlWindow, getOpenedPage, 0}}, - {3456, {wxHtmlWindow, getOpenedPageTitle, 0}}, - {3457, {wxHtmlWindow, getRelatedFrame, 0}}, - {3458, {wxHtmlWindow, historyBack, 0}}, - {3459, {wxHtmlWindow, historyCanBack, 0}}, - {3460, {wxHtmlWindow, historyCanForward, 0}}, - {3461, {wxHtmlWindow, historyClear, 0}}, - {3462, {wxHtmlWindow, historyForward, 0}}, - {3463, {wxHtmlWindow, loadFile, 1}}, - {3464, {wxHtmlWindow, loadPage, 1}}, - {3465, {wxHtmlWindow, selectAll, 0}}, - {3466, {wxHtmlWindow, selectionToText, 0}}, - {3467, {wxHtmlWindow, selectLine, 1}}, - {3468, {wxHtmlWindow, selectWord, 1}}, - {3469, {wxHtmlWindow, setBorders, 1}}, - {3470, {wxHtmlWindow, setFonts, 3}}, - {3471, {wxHtmlWindow, setPage, 1}}, - {3472, {wxHtmlWindow, setRelatedFrame, 2}}, - {3473, {wxHtmlWindow, setRelatedStatusBar, 1}}, - {3474, {wxHtmlWindow, toText, 0}}, - {3475, {wxHtmlWindow, 'Destroy', undefined}}, - {3476, {wxHtmlLinkEvent, getLinkInfo, 0}}, - {3477, {wxAuiNotebookEvent, setSelection, 1}}, - {3478, {wxAuiNotebookEvent, getSelection, 0}}, - {3479, {wxAuiNotebookEvent, setOldSelection, 1}}, - {3480, {wxAuiNotebookEvent, getOldSelection, 0}}, - {3481, {wxAuiNotebookEvent, setDragSource, 1}}, - {3482, {wxAuiNotebookEvent, getDragSource, 0}}, - {3483, {wxAuiManagerEvent, setManager, 1}}, - {3484, {wxAuiManagerEvent, getManager, 0}}, - {3485, {wxAuiManagerEvent, setPane, 1}}, - {3486, {wxAuiManagerEvent, getPane, 0}}, - {3487, {wxAuiManagerEvent, setButton, 1}}, - {3488, {wxAuiManagerEvent, getButton, 0}}, - {3489, {wxAuiManagerEvent, setDC, 1}}, - {3490, {wxAuiManagerEvent, getDC, 0}}, - {3491, {wxAuiManagerEvent, veto, 1}}, - {3492, {wxAuiManagerEvent, getVeto, 0}}, - {3493, {wxAuiManagerEvent, setCanVeto, 1}}, - {3494, {wxAuiManagerEvent, canVeto, 0}}, - {3495, {wxLogNull, new, 0}}, - {3496, {wxLogNull, 'Destroy', undefined}}, + {885, {wxControlWithItems, getClientData, 1}}, + {886, {wxControlWithItems, setClientData, 2}}, + {887, {wxControlWithItems, getCount, 0}}, + {888, {wxControlWithItems, getSelection, 0}}, + {889, {wxControlWithItems, getString, 1}}, + {890, {wxControlWithItems, getStringSelection, 0}}, + {891, {wxControlWithItems, insert_2, 2}}, + {892, {wxControlWithItems, insert_3, 3}}, + {893, {wxControlWithItems, isEmpty, 0}}, + {894, {wxControlWithItems, select, 1}}, + {895, {wxControlWithItems, setSelection, 1}}, + {896, {wxControlWithItems, setString, 2}}, + {897, {wxControlWithItems, setStringSelection, 1}}, + {900, {wxMenu, new_2, 2}}, + {901, {wxMenu, new_1, 1}}, + {903, {wxMenu, destruct, 0}}, + {904, {wxMenu, append_3, 3}}, + {905, {wxMenu, append_1, 1}}, + {906, {wxMenu, append_4_0, 4}}, + {907, {wxMenu, append_4_1, 4}}, + {908, {wxMenu, appendCheckItem, 3}}, + {909, {wxMenu, appendRadioItem, 3}}, + {910, {wxMenu, appendSeparator, 0}}, + {911, {wxMenu, break, 0}}, + {912, {wxMenu, check, 2}}, + {913, {wxMenu, delete_1_0, 1}}, + {914, {wxMenu, delete_1_1, 1}}, + {915, {wxMenu, destroy_1_0, 1}}, + {916, {wxMenu, destroy_1_1, 1}}, + {917, {wxMenu, enable, 2}}, + {918, {wxMenu, findItem_1, 1}}, + {919, {wxMenu, findItem_2, 2}}, + {920, {wxMenu, findItemByPosition, 1}}, + {921, {wxMenu, getHelpString, 1}}, + {922, {wxMenu, getLabel, 1}}, + {923, {wxMenu, getMenuItemCount, 0}}, + {924, {wxMenu, getMenuItems, 0}}, + {926, {wxMenu, getTitle, 0}}, + {927, {wxMenu, insert_2, 2}}, + {928, {wxMenu, insert_3, 3}}, + {929, {wxMenu, insert_5_1, 5}}, + {930, {wxMenu, insert_5_0, 5}}, + {931, {wxMenu, insertCheckItem, 4}}, + {932, {wxMenu, insertRadioItem, 4}}, + {933, {wxMenu, insertSeparator, 1}}, + {934, {wxMenu, isChecked, 1}}, + {935, {wxMenu, isEnabled, 1}}, + {936, {wxMenu, prepend_1, 1}}, + {937, {wxMenu, prepend_2, 2}}, + {938, {wxMenu, prepend_4_1, 4}}, + {939, {wxMenu, prepend_4_0, 4}}, + {940, {wxMenu, prependCheckItem, 3}}, + {941, {wxMenu, prependRadioItem, 3}}, + {942, {wxMenu, prependSeparator, 0}}, + {943, {wxMenu, remove_1_0, 1}}, + {944, {wxMenu, remove_1_1, 1}}, + {945, {wxMenu, setHelpString, 2}}, + {946, {wxMenu, setLabel, 2}}, + {947, {wxMenu, setTitle, 1}}, + {948, {wxMenuItem, new, 1}}, + {950, {wxMenuItem, destruct, 0}}, + {951, {wxMenuItem, check, 1}}, + {952, {wxMenuItem, enable, 1}}, + {953, {wxMenuItem, getBitmap, 0}}, + {954, {wxMenuItem, getHelp, 0}}, + {955, {wxMenuItem, getId, 0}}, + {956, {wxMenuItem, getKind, 0}}, + {957, {wxMenuItem, getLabel, 0}}, + {958, {wxMenuItem, getLabelFromText, 1}}, + {959, {wxMenuItem, getMenu, 0}}, + {960, {wxMenuItem, getText, 0}}, + {961, {wxMenuItem, getSubMenu, 0}}, + {962, {wxMenuItem, isCheckable, 0}}, + {963, {wxMenuItem, isChecked, 0}}, + {964, {wxMenuItem, isEnabled, 0}}, + {965, {wxMenuItem, isSeparator, 0}}, + {966, {wxMenuItem, isSubMenu, 0}}, + {967, {wxMenuItem, setBitmap, 1}}, + {968, {wxMenuItem, setHelp, 1}}, + {969, {wxMenuItem, setMenu, 1}}, + {970, {wxMenuItem, setSubMenu, 1}}, + {971, {wxMenuItem, setText, 1}}, + {972, {wxToolBar, addControl, 1}}, + {973, {wxToolBar, addSeparator, 0}}, + {974, {wxToolBar, addTool_5, 5}}, + {975, {wxToolBar, addTool_4_0, 4}}, + {976, {wxToolBar, addTool_1, 1}}, + {977, {wxToolBar, addTool_4_1, 4}}, + {978, {wxToolBar, addTool_3, 3}}, + {979, {wxToolBar, addTool_6, 6}}, + {980, {wxToolBar, addCheckTool, 4}}, + {981, {wxToolBar, addRadioTool, 4}}, + {982, {wxToolBar, deleteTool, 1}}, + {983, {wxToolBar, deleteToolByPos, 1}}, + {984, {wxToolBar, enableTool, 2}}, + {985, {wxToolBar, findById, 1}}, + {986, {wxToolBar, findControl, 1}}, + {987, {wxToolBar, findToolForPosition, 2}}, + {988, {wxToolBar, getToolSize, 0}}, + {989, {wxToolBar, getToolBitmapSize, 0}}, + {990, {wxToolBar, getMargins, 0}}, + {991, {wxToolBar, getToolEnabled, 1}}, + {992, {wxToolBar, getToolLongHelp, 1}}, + {993, {wxToolBar, getToolPacking, 0}}, + {994, {wxToolBar, getToolPos, 1}}, + {995, {wxToolBar, getToolSeparation, 0}}, + {996, {wxToolBar, getToolShortHelp, 1}}, + {997, {wxToolBar, getToolState, 1}}, + {998, {wxToolBar, insertControl, 2}}, + {999, {wxToolBar, insertSeparator, 1}}, + {1000, {wxToolBar, insertTool_5, 5}}, + {1001, {wxToolBar, insertTool_2, 2}}, + {1002, {wxToolBar, insertTool_4, 4}}, + {1003, {wxToolBar, realize, 0}}, + {1004, {wxToolBar, removeTool, 1}}, + {1005, {wxToolBar, setMargins, 2}}, + {1006, {wxToolBar, setToolBitmapSize, 1}}, + {1007, {wxToolBar, setToolLongHelp, 2}}, + {1008, {wxToolBar, setToolPacking, 1}}, + {1009, {wxToolBar, setToolShortHelp, 2}}, + {1010, {wxToolBar, setToolSeparation, 1}}, + {1011, {wxToolBar, toggleTool, 2}}, + {1013, {wxStatusBar, new_0, 0}}, + {1014, {wxStatusBar, new_2, 2}}, + {1016, {wxStatusBar, destruct, 0}}, + {1017, {wxStatusBar, create, 2}}, + {1018, {wxStatusBar, getFieldRect, 2}}, + {1019, {wxStatusBar, getFieldsCount, 0}}, + {1020, {wxStatusBar, getStatusText, 1}}, + {1021, {wxStatusBar, popStatusText, 1}}, + {1022, {wxStatusBar, pushStatusText, 2}}, + {1023, {wxStatusBar, setFieldsCount, 2}}, + {1024, {wxStatusBar, setMinHeight, 1}}, + {1025, {wxStatusBar, setStatusText, 2}}, + {1026, {wxStatusBar, setStatusWidths, 2}}, + {1027, {wxStatusBar, setStatusStyles, 2}}, + {1028, {wxBitmap, new_0, 0}}, + {1029, {wxBitmap, new_3, 3}}, + {1030, {wxBitmap, new_4, 4}}, + {1031, {wxBitmap, new_2_0, 2}}, + {1032, {wxBitmap, new_2_1, 2}}, + {1033, {wxBitmap, destruct, 0}}, + {1034, {wxBitmap, convertToImage, 0}}, + {1035, {wxBitmap, copyFromIcon, 1}}, + {1036, {wxBitmap, create, 3}}, + {1037, {wxBitmap, getDepth, 0}}, + {1038, {wxBitmap, getHeight, 0}}, + {1039, {wxBitmap, getPalette, 0}}, + {1040, {wxBitmap, getMask, 0}}, + {1041, {wxBitmap, getWidth, 0}}, + {1042, {wxBitmap, getSubBitmap, 1}}, + {1043, {wxBitmap, loadFile, 2}}, + {1044, {wxBitmap, ok, 0}}, + {1045, {wxBitmap, saveFile, 3}}, + {1046, {wxBitmap, setDepth, 1}}, + {1047, {wxBitmap, setHeight, 1}}, + {1048, {wxBitmap, setMask, 1}}, + {1049, {wxBitmap, setPalette, 1}}, + {1050, {wxBitmap, setWidth, 1}}, + {1051, {wxIcon, new_0, 0}}, + {1052, {wxIcon, new_2, 2}}, + {1053, {wxIcon, new_1, 1}}, + {1054, {wxIcon, copyFromBitmap, 1}}, + {1055, {wxIcon, 'Destroy', undefined}}, + {1056, {wxIconBundle, new_0, 0}}, + {1057, {wxIconBundle, new_2, 2}}, + {1058, {wxIconBundle, new_1_0, 1}}, + {1059, {wxIconBundle, new_1_1, 1}}, + {1060, {wxIconBundle, destruct, 0}}, + {1061, {wxIconBundle, addIcon_2, 2}}, + {1062, {wxIconBundle, addIcon_1, 1}}, + {1063, {wxIconBundle, getIcon_1_1, 1}}, + {1064, {wxIconBundle, getIcon_1_0, 1}}, + {1065, {wxCursor, new_0, 0}}, + {1066, {wxCursor, new_1_0, 1}}, + {1067, {wxCursor, new_1_1, 1}}, + {1068, {wxCursor, new_4, 4}}, + {1069, {wxCursor, destruct, 0}}, + {1070, {wxCursor, ok, 0}}, + {1071, {wxMask, new_0, 0}}, + {1072, {wxMask, new_2_1, 2}}, + {1073, {wxMask, new_2_0, 2}}, + {1074, {wxMask, new_1, 1}}, + {1075, {wxMask, destruct, 0}}, + {1076, {wxMask, create_2_1, 2}}, + {1077, {wxMask, create_2_0, 2}}, + {1078, {wxMask, create_1, 1}}, + {1079, {wxImage, new_0, 0}}, + {1080, {wxImage, new_3_0, 3}}, + {1081, {wxImage, new_4, 4}}, + {1082, {wxImage, new_5, 5}}, + {1083, {wxImage, new_2, 2}}, + {1084, {wxImage, new_3_1, 3}}, + {1085, {wxImage, blur, 1}}, + {1086, {wxImage, blurHorizontal, 1}}, + {1087, {wxImage, blurVertical, 1}}, + {1088, {wxImage, convertAlphaToMask, 1}}, + {1089, {wxImage, convertToGreyscale, 1}}, + {1090, {wxImage, convertToMono, 3}}, + {1091, {wxImage, copy, 0}}, + {1092, {wxImage, create_3, 3}}, + {1093, {wxImage, create_4, 4}}, + {1094, {wxImage, create_5, 5}}, + {1095, {wxImage, 'Destroy', 0}}, + {1096, {wxImage, findFirstUnusedColour, 4}}, + {1097, {wxImage, getImageExtWildcard, 0}}, + {1098, {wxImage, getAlpha_2, 2}}, + {1099, {wxImage, getAlpha_0, 0}}, + {1100, {wxImage, getBlue, 2}}, + {1101, {wxImage, getData, 0}}, + {1102, {wxImage, getGreen, 2}}, + {1103, {wxImage, getImageCount, 2}}, + {1104, {wxImage, getHeight, 0}}, + {1105, {wxImage, getMaskBlue, 0}}, + {1106, {wxImage, getMaskGreen, 0}}, + {1107, {wxImage, getMaskRed, 0}}, + {1108, {wxImage, getOrFindMaskColour, 3}}, + {1109, {wxImage, getPalette, 0}}, + {1110, {wxImage, getRed, 2}}, + {1111, {wxImage, getSubImage, 1}}, + {1112, {wxImage, getWidth, 0}}, + {1113, {wxImage, hasAlpha, 0}}, + {1114, {wxImage, hasMask, 0}}, + {1115, {wxImage, getOption, 1}}, + {1116, {wxImage, getOptionInt, 1}}, + {1117, {wxImage, hasOption, 1}}, + {1118, {wxImage, initAlpha, 0}}, + {1119, {wxImage, initStandardHandlers, 0}}, + {1120, {wxImage, isTransparent, 3}}, + {1121, {wxImage, loadFile_2, 2}}, + {1122, {wxImage, loadFile_3, 3}}, + {1123, {wxImage, ok, 0}}, + {1124, {wxImage, removeHandler, 1}}, + {1125, {wxImage, mirror, 1}}, + {1126, {wxImage, replace, 6}}, + {1127, {wxImage, rescale, 3}}, + {1128, {wxImage, resize, 3}}, + {1129, {wxImage, rotate, 3}}, + {1130, {wxImage, rotateHue, 1}}, + {1131, {wxImage, rotate90, 1}}, + {1132, {wxImage, saveFile_1, 1}}, + {1133, {wxImage, saveFile_2_0, 2}}, + {1134, {wxImage, saveFile_2_1, 2}}, + {1135, {wxImage, scale, 3}}, + {1136, {wxImage, size, 3}}, + {1137, {wxImage, setAlpha_3, 3}}, + {1138, {wxImage, setAlpha_2, 2}}, + {1139, {wxImage, setData_2, 2}}, + {1140, {wxImage, setData_4, 4}}, + {1141, {wxImage, setMask, 1}}, + {1142, {wxImage, setMaskColour, 3}}, + {1143, {wxImage, setMaskFromImage, 4}}, + {1144, {wxImage, setOption_2_1, 2}}, + {1145, {wxImage, setOption_2_0, 2}}, + {1146, {wxImage, setPalette, 1}}, + {1147, {wxImage, setRGB_5, 5}}, + {1148, {wxImage, setRGB_4, 4}}, + {1149, {wxImage, 'Destroy', undefined}}, + {1150, {wxBrush, new_0, 0}}, + {1151, {wxBrush, new_2, 2}}, + {1152, {wxBrush, new_1, 1}}, + {1154, {wxBrush, destruct, 0}}, + {1155, {wxBrush, getColour, 0}}, + {1156, {wxBrush, getStipple, 0}}, + {1157, {wxBrush, getStyle, 0}}, + {1158, {wxBrush, isHatch, 0}}, + {1159, {wxBrush, isOk, 0}}, + {1160, {wxBrush, setColour_1, 1}}, + {1161, {wxBrush, setColour_3, 3}}, + {1162, {wxBrush, setStipple, 1}}, + {1163, {wxBrush, setStyle, 1}}, + {1164, {wxPen, new_0, 0}}, + {1165, {wxPen, new_2, 2}}, + {1166, {wxPen, destruct, 0}}, + {1167, {wxPen, getCap, 0}}, + {1168, {wxPen, getColour, 0}}, + {1169, {wxPen, getJoin, 0}}, + {1170, {wxPen, getStyle, 0}}, + {1171, {wxPen, getWidth, 0}}, + {1172, {wxPen, isOk, 0}}, + {1173, {wxPen, setCap, 1}}, + {1174, {wxPen, setColour_1, 1}}, + {1175, {wxPen, setColour_3, 3}}, + {1176, {wxPen, setJoin, 1}}, + {1177, {wxPen, setStyle, 1}}, + {1178, {wxPen, setWidth, 1}}, + {1179, {wxRegion, new_0, 0}}, + {1180, {wxRegion, new_4, 4}}, + {1181, {wxRegion, new_2, 2}}, + {1182, {wxRegion, new_1_1, 1}}, + {1184, {wxRegion, new_1_0, 1}}, + {1186, {wxRegion, destruct, 0}}, + {1187, {wxRegion, clear, 0}}, + {1188, {wxRegion, contains_2, 2}}, + {1189, {wxRegion, contains_1_0, 1}}, + {1190, {wxRegion, contains_4, 4}}, + {1191, {wxRegion, contains_1_1, 1}}, + {1192, {wxRegion, convertToBitmap, 0}}, + {1193, {wxRegion, getBox, 0}}, + {1194, {wxRegion, intersect_4, 4}}, + {1195, {wxRegion, intersect_1_1, 1}}, + {1196, {wxRegion, intersect_1_0, 1}}, + {1197, {wxRegion, isEmpty, 0}}, + {1198, {wxRegion, subtract_4, 4}}, + {1199, {wxRegion, subtract_1_1, 1}}, + {1200, {wxRegion, subtract_1_0, 1}}, + {1201, {wxRegion, offset_2, 2}}, + {1202, {wxRegion, offset_1, 1}}, + {1203, {wxRegion, union_4, 4}}, + {1204, {wxRegion, union_1_2, 1}}, + {1205, {wxRegion, union_1_1, 1}}, + {1206, {wxRegion, union_1_0, 1}}, + {1207, {wxRegion, union_3, 3}}, + {1208, {wxRegion, xor_4, 4}}, + {1209, {wxRegion, xor_1_1, 1}}, + {1210, {wxRegion, xor_1_0, 1}}, + {1211, {wxAcceleratorTable, new_0, 0}}, + {1212, {wxAcceleratorTable, new_2, 2}}, + {1213, {wxAcceleratorTable, destruct, 0}}, + {1214, {wxAcceleratorTable, ok, 0}}, + {1215, {wxAcceleratorEntry, new_1_0, 1}}, + {1216, {wxAcceleratorEntry, new_1_1, 1}}, + {1217, {wxAcceleratorEntry, getCommand, 0}}, + {1218, {wxAcceleratorEntry, getFlags, 0}}, + {1219, {wxAcceleratorEntry, getKeyCode, 0}}, + {1220, {wxAcceleratorEntry, set, 4}}, + {1221, {wxAcceleratorEntry, 'Destroy', undefined}}, + {1226, {wxCaret, new_3, 3}}, + {1227, {wxCaret, new_2, 2}}, + {1229, {wxCaret, destruct, 0}}, + {1230, {wxCaret, create_3, 3}}, + {1231, {wxCaret, create_2, 2}}, + {1232, {wxCaret, getBlinkTime, 0}}, + {1234, {wxCaret, getPosition, 0}}, + {1236, {wxCaret, getSize, 0}}, + {1237, {wxCaret, getWindow, 0}}, + {1238, {wxCaret, hide, 0}}, + {1239, {wxCaret, isOk, 0}}, + {1240, {wxCaret, isVisible, 0}}, + {1241, {wxCaret, move_2, 2}}, + {1242, {wxCaret, move_1, 1}}, + {1243, {wxCaret, setBlinkTime, 1}}, + {1244, {wxCaret, setSize_2, 2}}, + {1245, {wxCaret, setSize_1, 1}}, + {1246, {wxCaret, show, 1}}, + {1247, {wxSizer, add_2_1, 2}}, + {1248, {wxSizer, add_2_0, 2}}, + {1249, {wxSizer, add_3, 3}}, + {1250, {wxSizer, add_2_3, 2}}, + {1251, {wxSizer, add_2_2, 2}}, + {1252, {wxSizer, addSpacer, 1}}, + {1253, {wxSizer, addStretchSpacer, 1}}, + {1254, {wxSizer, calcMin, 0}}, + {1255, {wxSizer, clear, 1}}, + {1256, {wxSizer, detach_1_2, 1}}, + {1257, {wxSizer, detach_1_1, 1}}, + {1258, {wxSizer, detach_1_0, 1}}, + {1259, {wxSizer, fit, 1}}, + {1260, {wxSizer, fitInside, 1}}, + {1261, {wxSizer, getChildren, 0}}, + {1262, {wxSizer, getItem_2_1, 2}}, + {1263, {wxSizer, getItem_2_0, 2}}, + {1264, {wxSizer, getItem_1, 1}}, + {1265, {wxSizer, getSize, 0}}, + {1266, {wxSizer, getPosition, 0}}, + {1267, {wxSizer, getMinSize, 0}}, + {1268, {wxSizer, hide_2_0, 2}}, + {1269, {wxSizer, hide_2_1, 2}}, + {1270, {wxSizer, hide_1, 1}}, + {1271, {wxSizer, insert_3_1, 3}}, + {1272, {wxSizer, insert_3_0, 3}}, + {1273, {wxSizer, insert_4, 4}}, + {1274, {wxSizer, insert_3_3, 3}}, + {1275, {wxSizer, insert_3_2, 3}}, + {1276, {wxSizer, insert_2, 2}}, + {1277, {wxSizer, insertSpacer, 2}}, + {1278, {wxSizer, insertStretchSpacer, 2}}, + {1279, {wxSizer, isShown_1_2, 1}}, + {1280, {wxSizer, isShown_1_1, 1}}, + {1281, {wxSizer, isShown_1_0, 1}}, + {1282, {wxSizer, layout, 0}}, + {1283, {wxSizer, prepend_2_1, 2}}, + {1284, {wxSizer, prepend_2_0, 2}}, + {1285, {wxSizer, prepend_3, 3}}, + {1286, {wxSizer, prepend_2_3, 2}}, + {1287, {wxSizer, prepend_2_2, 2}}, + {1288, {wxSizer, prepend_1, 1}}, + {1289, {wxSizer, prependSpacer, 1}}, + {1290, {wxSizer, prependStretchSpacer, 1}}, + {1291, {wxSizer, recalcSizes, 0}}, + {1292, {wxSizer, remove_1_1, 1}}, + {1293, {wxSizer, remove_1_0, 1}}, + {1294, {wxSizer, replace_3_1, 3}}, + {1295, {wxSizer, replace_3_0, 3}}, + {1296, {wxSizer, replace_2, 2}}, + {1297, {wxSizer, setDimension, 4}}, + {1298, {wxSizer, setMinSize_2, 2}}, + {1299, {wxSizer, setMinSize_1, 1}}, + {1300, {wxSizer, setItemMinSize_3_2, 3}}, + {1301, {wxSizer, setItemMinSize_2_2, 2}}, + {1302, {wxSizer, setItemMinSize_3_1, 3}}, + {1303, {wxSizer, setItemMinSize_2_1, 2}}, + {1304, {wxSizer, setItemMinSize_3_0, 3}}, + {1305, {wxSizer, setItemMinSize_2_0, 2}}, + {1306, {wxSizer, setSizeHints, 1}}, + {1307, {wxSizer, setVirtualSizeHints, 1}}, + {1308, {wxSizer, show_2_2, 2}}, + {1309, {wxSizer, show_2_1, 2}}, + {1310, {wxSizer, show_2_0, 2}}, + {1311, {wxSizer, show_1, 1}}, + {1312, {wxSizerFlags, new, 1}}, + {1313, {wxSizerFlags, align, 1}}, + {1314, {wxSizerFlags, border_2, 2}}, + {1315, {wxSizerFlags, border_1, 1}}, + {1316, {wxSizerFlags, center, 0}}, + {1317, {wxSizerFlags, centre, 0}}, + {1318, {wxSizerFlags, expand, 0}}, + {1319, {wxSizerFlags, left, 0}}, + {1320, {wxSizerFlags, proportion, 1}}, + {1321, {wxSizerFlags, right, 0}}, + {1322, {wxSizerFlags, 'Destroy', undefined}}, + {1323, {wxSizerItem, new_5_1, 5}}, + {1324, {wxSizerItem, new_2_1, 2}}, + {1325, {wxSizerItem, new_5_0, 5}}, + {1326, {wxSizerItem, new_2_0, 2}}, + {1327, {wxSizerItem, new_6, 6}}, + {1328, {wxSizerItem, new_3, 3}}, + {1329, {wxSizerItem, new_0, 0}}, + {1330, {wxSizerItem, destruct, 0}}, + {1331, {wxSizerItem, calcMin, 0}}, + {1332, {wxSizerItem, deleteWindows, 0}}, + {1333, {wxSizerItem, detachSizer, 0}}, + {1334, {wxSizerItem, getBorder, 0}}, + {1335, {wxSizerItem, getFlag, 0}}, + {1336, {wxSizerItem, getMinSize, 0}}, + {1337, {wxSizerItem, getPosition, 0}}, + {1338, {wxSizerItem, getProportion, 0}}, + {1339, {wxSizerItem, getRatio, 0}}, + {1340, {wxSizerItem, getRect, 0}}, + {1341, {wxSizerItem, getSize, 0}}, + {1342, {wxSizerItem, getSizer, 0}}, + {1343, {wxSizerItem, getSpacer, 0}}, + {1344, {wxSizerItem, getUserData, 0}}, + {1345, {wxSizerItem, getWindow, 0}}, + {1346, {wxSizerItem, isSizer, 0}}, + {1347, {wxSizerItem, isShown, 0}}, + {1348, {wxSizerItem, isSpacer, 0}}, + {1349, {wxSizerItem, isWindow, 0}}, + {1350, {wxSizerItem, setBorder, 1}}, + {1351, {wxSizerItem, setDimension, 2}}, + {1352, {wxSizerItem, setFlag, 1}}, + {1353, {wxSizerItem, setInitSize, 2}}, + {1354, {wxSizerItem, setMinSize_1, 1}}, + {1355, {wxSizerItem, setMinSize_2, 2}}, + {1356, {wxSizerItem, setProportion, 1}}, + {1357, {wxSizerItem, setRatio_2, 2}}, + {1358, {wxSizerItem, setRatio_1_1, 1}}, + {1359, {wxSizerItem, setRatio_1_0, 1}}, + {1360, {wxSizerItem, setSizer, 1}}, + {1361, {wxSizerItem, setSpacer_1, 1}}, + {1362, {wxSizerItem, setSpacer_2, 2}}, + {1363, {wxSizerItem, setWindow, 1}}, + {1364, {wxSizerItem, show, 1}}, + {1365, {wxBoxSizer, new, 1}}, + {1366, {wxBoxSizer, getOrientation, 0}}, + {1367, {wxBoxSizer, 'Destroy', undefined}}, + {1368, {wxStaticBoxSizer, new_2, 2}}, + {1369, {wxStaticBoxSizer, new_3, 3}}, + {1370, {wxStaticBoxSizer, getStaticBox, 0}}, + {1371, {wxStaticBoxSizer, 'Destroy', undefined}}, + {1372, {wxGridSizer, new_4, 4}}, + {1373, {wxGridSizer, new_2, 2}}, + {1374, {wxGridSizer, getCols, 0}}, + {1375, {wxGridSizer, getHGap, 0}}, + {1376, {wxGridSizer, getRows, 0}}, + {1377, {wxGridSizer, getVGap, 0}}, + {1378, {wxGridSizer, setCols, 1}}, + {1379, {wxGridSizer, setHGap, 1}}, + {1380, {wxGridSizer, setRows, 1}}, + {1381, {wxGridSizer, setVGap, 1}}, + {1382, {wxGridSizer, 'Destroy', undefined}}, + {1383, {wxFlexGridSizer, new_4, 4}}, + {1384, {wxFlexGridSizer, new_2, 2}}, + {1385, {wxFlexGridSizer, addGrowableCol, 2}}, + {1386, {wxFlexGridSizer, addGrowableRow, 2}}, + {1387, {wxFlexGridSizer, getFlexibleDirection, 0}}, + {1388, {wxFlexGridSizer, getNonFlexibleGrowMode, 0}}, + {1389, {wxFlexGridSizer, removeGrowableCol, 1}}, + {1390, {wxFlexGridSizer, removeGrowableRow, 1}}, + {1391, {wxFlexGridSizer, setFlexibleDirection, 1}}, + {1392, {wxFlexGridSizer, setNonFlexibleGrowMode, 1}}, + {1393, {wxFlexGridSizer, 'Destroy', undefined}}, + {1394, {wxGridBagSizer, new, 1}}, + {1395, {wxGridBagSizer, add_3_2, 3}}, + {1396, {wxGridBagSizer, add_3_1, 3}}, + {1397, {wxGridBagSizer, add_4, 4}}, + {1398, {wxGridBagSizer, add_1_0, 1}}, + {1399, {wxGridBagSizer, add_2_1, 2}}, + {1400, {wxGridBagSizer, add_2_0, 2}}, + {1401, {wxGridBagSizer, add_3_0, 3}}, + {1402, {wxGridBagSizer, add_1_1, 1}}, + {1403, {wxGridBagSizer, calcMin, 0}}, + {1404, {wxGridBagSizer, checkForIntersection_2, 2}}, + {1405, {wxGridBagSizer, checkForIntersection_3, 3}}, + {1406, {wxGridBagSizer, findItem_1_1, 1}}, + {1407, {wxGridBagSizer, findItem_1_0, 1}}, + {1408, {wxGridBagSizer, findItemAtPoint, 1}}, + {1409, {wxGridBagSizer, findItemAtPosition, 1}}, + {1410, {wxGridBagSizer, findItemWithData, 1}}, + {1411, {wxGridBagSizer, getCellSize, 2}}, + {1412, {wxGridBagSizer, getEmptyCellSize, 0}}, + {1413, {wxGridBagSizer, getItemPosition_1_2, 1}}, + {1414, {wxGridBagSizer, getItemPosition_1_1, 1}}, + {1415, {wxGridBagSizer, getItemPosition_1_0, 1}}, + {1416, {wxGridBagSizer, getItemSpan_1_2, 1}}, + {1417, {wxGridBagSizer, getItemSpan_1_1, 1}}, + {1418, {wxGridBagSizer, getItemSpan_1_0, 1}}, + {1419, {wxGridBagSizer, setEmptyCellSize, 1}}, + {1420, {wxGridBagSizer, setItemPosition_2_2, 2}}, + {1421, {wxGridBagSizer, setItemPosition_2_1, 2}}, + {1422, {wxGridBagSizer, setItemPosition_2_0, 2}}, + {1423, {wxGridBagSizer, setItemSpan_2_2, 2}}, + {1424, {wxGridBagSizer, setItemSpan_2_1, 2}}, + {1425, {wxGridBagSizer, setItemSpan_2_0, 2}}, + {1426, {wxGridBagSizer, 'Destroy', undefined}}, + {1427, {wxStdDialogButtonSizer, new, 0}}, + {1428, {wxStdDialogButtonSizer, addButton, 1}}, + {1429, {wxStdDialogButtonSizer, realize, 0}}, + {1430, {wxStdDialogButtonSizer, setAffirmativeButton, 1}}, + {1431, {wxStdDialogButtonSizer, setCancelButton, 1}}, + {1432, {wxStdDialogButtonSizer, setNegativeButton, 1}}, + {1433, {wxStdDialogButtonSizer, 'Destroy', undefined}}, + {1434, {wxFont, new_0, 0}}, + {1435, {wxFont, new_1, 1}}, + {1436, {wxFont, new_5, 5}}, + {1438, {wxFont, destruct, 0}}, + {1439, {wxFont, isFixedWidth, 0}}, + {1440, {wxFont, getDefaultEncoding, 0}}, + {1441, {wxFont, getFaceName, 0}}, + {1442, {wxFont, getFamily, 0}}, + {1443, {wxFont, getNativeFontInfoDesc, 0}}, + {1444, {wxFont, getNativeFontInfoUserDesc, 0}}, + {1445, {wxFont, getPointSize, 0}}, + {1446, {wxFont, getStyle, 0}}, + {1447, {wxFont, getUnderlined, 0}}, + {1448, {wxFont, getWeight, 0}}, + {1449, {wxFont, ok, 0}}, + {1450, {wxFont, setDefaultEncoding, 1}}, + {1451, {wxFont, setFaceName, 1}}, + {1452, {wxFont, setFamily, 1}}, + {1453, {wxFont, setPointSize, 1}}, + {1454, {wxFont, setStyle, 1}}, + {1455, {wxFont, setUnderlined, 1}}, + {1456, {wxFont, setWeight, 1}}, + {1457, {wxToolTip, enable, 1}}, + {1458, {wxToolTip, setDelay, 1}}, + {1459, {wxToolTip, new, 1}}, + {1460, {wxToolTip, setTip, 1}}, + {1461, {wxToolTip, getTip, 0}}, + {1462, {wxToolTip, getWindow, 0}}, + {1463, {wxToolTip, 'Destroy', undefined}}, + {1465, {wxButton, new_3, 3}}, + {1466, {wxButton, new_0, 0}}, + {1467, {wxButton, destruct, 0}}, + {1468, {wxButton, create, 3}}, + {1469, {wxButton, getDefaultSize, 0}}, + {1470, {wxButton, setDefault, 0}}, + {1471, {wxButton, setLabel, 1}}, + {1473, {wxBitmapButton, new_4, 4}}, + {1474, {wxBitmapButton, new_0, 0}}, + {1475, {wxBitmapButton, create, 4}}, + {1476, {wxBitmapButton, getBitmapDisabled, 0}}, + {1478, {wxBitmapButton, getBitmapFocus, 0}}, + {1480, {wxBitmapButton, getBitmapLabel, 0}}, + {1482, {wxBitmapButton, getBitmapSelected, 0}}, + {1484, {wxBitmapButton, setBitmapDisabled, 1}}, + {1485, {wxBitmapButton, setBitmapFocus, 1}}, + {1486, {wxBitmapButton, setBitmapLabel, 1}}, + {1487, {wxBitmapButton, setBitmapSelected, 1}}, + {1488, {wxBitmapButton, 'Destroy', undefined}}, + {1489, {wxToggleButton, new_0, 0}}, + {1490, {wxToggleButton, new_4, 4}}, + {1491, {wxToggleButton, create, 4}}, + {1492, {wxToggleButton, getValue, 0}}, + {1493, {wxToggleButton, setValue, 1}}, + {1494, {wxToggleButton, 'Destroy', undefined}}, + {1495, {wxCalendarCtrl, new_0, 0}}, + {1496, {wxCalendarCtrl, new_3, 3}}, + {1497, {wxCalendarCtrl, create, 3}}, + {1498, {wxCalendarCtrl, destruct, 0}}, + {1499, {wxCalendarCtrl, setDate, 1}}, + {1500, {wxCalendarCtrl, getDate, 0}}, + {1501, {wxCalendarCtrl, enableYearChange, 1}}, + {1502, {wxCalendarCtrl, enableMonthChange, 1}}, + {1503, {wxCalendarCtrl, enableHolidayDisplay, 1}}, + {1504, {wxCalendarCtrl, setHeaderColours, 2}}, + {1505, {wxCalendarCtrl, getHeaderColourFg, 0}}, + {1506, {wxCalendarCtrl, getHeaderColourBg, 0}}, + {1507, {wxCalendarCtrl, setHighlightColours, 2}}, + {1508, {wxCalendarCtrl, getHighlightColourFg, 0}}, + {1509, {wxCalendarCtrl, getHighlightColourBg, 0}}, + {1510, {wxCalendarCtrl, setHolidayColours, 2}}, + {1511, {wxCalendarCtrl, getHolidayColourFg, 0}}, + {1512, {wxCalendarCtrl, getHolidayColourBg, 0}}, + {1513, {wxCalendarCtrl, getAttr, 1}}, + {1514, {wxCalendarCtrl, setAttr, 2}}, + {1515, {wxCalendarCtrl, setHoliday, 1}}, + {1516, {wxCalendarCtrl, resetAttr, 1}}, + {1517, {wxCalendarCtrl, hitTest, 2}}, + {1518, {wxCalendarDateAttr, new_0, 0}}, + {1519, {wxCalendarDateAttr, new_2_1, 2}}, + {1520, {wxCalendarDateAttr, new_2_0, 2}}, + {1521, {wxCalendarDateAttr, setTextColour, 1}}, + {1522, {wxCalendarDateAttr, setBackgroundColour, 1}}, + {1523, {wxCalendarDateAttr, setBorderColour, 1}}, + {1524, {wxCalendarDateAttr, setFont, 1}}, + {1525, {wxCalendarDateAttr, setBorder, 1}}, + {1526, {wxCalendarDateAttr, setHoliday, 1}}, + {1527, {wxCalendarDateAttr, hasTextColour, 0}}, + {1528, {wxCalendarDateAttr, hasBackgroundColour, 0}}, + {1529, {wxCalendarDateAttr, hasBorderColour, 0}}, + {1530, {wxCalendarDateAttr, hasFont, 0}}, + {1531, {wxCalendarDateAttr, hasBorder, 0}}, + {1532, {wxCalendarDateAttr, isHoliday, 0}}, + {1533, {wxCalendarDateAttr, getTextColour, 0}}, + {1534, {wxCalendarDateAttr, getBackgroundColour, 0}}, + {1535, {wxCalendarDateAttr, getBorderColour, 0}}, + {1536, {wxCalendarDateAttr, getFont, 0}}, + {1537, {wxCalendarDateAttr, getBorder, 0}}, + {1538, {wxCalendarDateAttr, 'Destroy', undefined}}, + {1540, {wxCheckBox, new_4, 4}}, + {1541, {wxCheckBox, new_0, 0}}, + {1542, {wxCheckBox, create, 4}}, + {1543, {wxCheckBox, getValue, 0}}, + {1544, {wxCheckBox, get3StateValue, 0}}, + {1545, {wxCheckBox, is3rdStateAllowedForUser, 0}}, + {1546, {wxCheckBox, is3State, 0}}, + {1547, {wxCheckBox, isChecked, 0}}, + {1548, {wxCheckBox, setValue, 1}}, + {1549, {wxCheckBox, set3StateValue, 1}}, + {1550, {wxCheckBox, 'Destroy', undefined}}, + {1551, {wxCheckListBox, new_0, 0}}, + {1553, {wxCheckListBox, new_3, 3}}, + {1554, {wxCheckListBox, check, 2}}, + {1555, {wxCheckListBox, isChecked, 1}}, + {1556, {wxCheckListBox, 'Destroy', undefined}}, + {1559, {wxChoice, new_3, 3}}, + {1560, {wxChoice, new_0, 0}}, + {1562, {wxChoice, destruct, 0}}, + {1564, {wxChoice, create, 6}}, + {1565, {wxChoice, delete, 1}}, + {1566, {wxChoice, getColumns, 0}}, + {1567, {wxChoice, setColumns, 1}}, + {1568, {wxComboBox, new_0, 0}}, + {1570, {wxComboBox, new_3, 3}}, + {1571, {wxComboBox, destruct, 0}}, + {1573, {wxComboBox, create, 7}}, + {1574, {wxComboBox, canCopy, 0}}, + {1575, {wxComboBox, canCut, 0}}, + {1576, {wxComboBox, canPaste, 0}}, + {1577, {wxComboBox, canRedo, 0}}, + {1578, {wxComboBox, canUndo, 0}}, + {1579, {wxComboBox, copy, 0}}, + {1580, {wxComboBox, cut, 0}}, + {1581, {wxComboBox, getInsertionPoint, 0}}, + {1582, {wxComboBox, getLastPosition, 0}}, + {1583, {wxComboBox, getValue, 0}}, + {1584, {wxComboBox, paste, 0}}, + {1585, {wxComboBox, redo, 0}}, + {1586, {wxComboBox, replace, 3}}, + {1587, {wxComboBox, remove, 2}}, + {1588, {wxComboBox, setInsertionPoint, 1}}, + {1589, {wxComboBox, setInsertionPointEnd, 0}}, + {1590, {wxComboBox, setSelection_1, 1}}, + {1591, {wxComboBox, setSelection_2, 2}}, + {1592, {wxComboBox, setValue, 1}}, + {1593, {wxComboBox, undo, 0}}, + {1594, {wxGauge, new_0, 0}}, + {1595, {wxGauge, new_4, 4}}, + {1596, {wxGauge, create, 4}}, + {1597, {wxGauge, getBezelFace, 0}}, + {1598, {wxGauge, getRange, 0}}, + {1599, {wxGauge, getShadowWidth, 0}}, + {1600, {wxGauge, getValue, 0}}, + {1601, {wxGauge, isVertical, 0}}, + {1602, {wxGauge, setBezelFace, 1}}, + {1603, {wxGauge, setRange, 1}}, + {1604, {wxGauge, setShadowWidth, 1}}, + {1605, {wxGauge, setValue, 1}}, + {1606, {wxGauge, pulse, 0}}, + {1607, {wxGauge, 'Destroy', undefined}}, + {1608, {wxGenericDirCtrl, new_0, 0}}, + {1609, {wxGenericDirCtrl, new_2, 2}}, + {1610, {wxGenericDirCtrl, destruct, 0}}, + {1611, {wxGenericDirCtrl, create, 2}}, + {1612, {wxGenericDirCtrl, init, 0}}, + {1613, {wxGenericDirCtrl, collapseTree, 0}}, + {1614, {wxGenericDirCtrl, expandPath, 1}}, + {1615, {wxGenericDirCtrl, getDefaultPath, 0}}, + {1616, {wxGenericDirCtrl, getPath, 0}}, + {1617, {wxGenericDirCtrl, getFilePath, 0}}, + {1618, {wxGenericDirCtrl, getFilter, 0}}, + {1619, {wxGenericDirCtrl, getFilterIndex, 0}}, + {1620, {wxGenericDirCtrl, getRootId, 0}}, + {1621, {wxGenericDirCtrl, getTreeCtrl, 0}}, + {1622, {wxGenericDirCtrl, reCreateTree, 0}}, + {1623, {wxGenericDirCtrl, setDefaultPath, 1}}, + {1624, {wxGenericDirCtrl, setFilter, 1}}, + {1625, {wxGenericDirCtrl, setFilterIndex, 1}}, + {1626, {wxGenericDirCtrl, setPath, 1}}, + {1628, {wxStaticBox, new_4, 4}}, + {1629, {wxStaticBox, new_0, 0}}, + {1630, {wxStaticBox, create, 4}}, + {1631, {wxStaticBox, 'Destroy', undefined}}, + {1633, {wxStaticLine, new_2, 2}}, + {1634, {wxStaticLine, new_0, 0}}, + {1635, {wxStaticLine, create, 2}}, + {1636, {wxStaticLine, isVertical, 0}}, + {1637, {wxStaticLine, getDefaultSize, 0}}, + {1638, {wxStaticLine, 'Destroy', undefined}}, + {1641, {wxListBox, new_3, 3}}, + {1642, {wxListBox, new_0, 0}}, + {1644, {wxListBox, destruct, 0}}, + {1646, {wxListBox, create, 6}}, + {1647, {wxListBox, deselect, 1}}, + {1648, {wxListBox, getSelections, 1}}, + {1649, {wxListBox, insertItems, 2}}, + {1650, {wxListBox, isSelected, 1}}, + {1652, {wxListBox, set, 2}}, + {1653, {wxListBox, hitTest, 1}}, + {1654, {wxListBox, setFirstItem_1_0, 1}}, + {1655, {wxListBox, setFirstItem_1_1, 1}}, + {1656, {wxListCtrl, new_0, 0}}, + {1657, {wxListCtrl, new_2, 2}}, + {1658, {wxListCtrl, arrange, 1}}, + {1659, {wxListCtrl, assignImageList, 2}}, + {1660, {wxListCtrl, clearAll, 0}}, + {1661, {wxListCtrl, create, 2}}, + {1662, {wxListCtrl, deleteAllItems, 0}}, + {1663, {wxListCtrl, deleteColumn, 1}}, + {1664, {wxListCtrl, deleteItem, 1}}, + {1665, {wxListCtrl, editLabel, 1}}, + {1666, {wxListCtrl, ensureVisible, 1}}, + {1667, {wxListCtrl, findItem_3_0, 3}}, + {1668, {wxListCtrl, findItem_3_1, 3}}, + {1669, {wxListCtrl, getColumn, 2}}, + {1670, {wxListCtrl, getColumnCount, 0}}, + {1671, {wxListCtrl, getColumnWidth, 1}}, + {1672, {wxListCtrl, getCountPerPage, 0}}, + {1673, {wxListCtrl, getEditControl, 0}}, + {1674, {wxListCtrl, getImageList, 1}}, + {1675, {wxListCtrl, getItem, 1}}, + {1676, {wxListCtrl, getItemBackgroundColour, 1}}, + {1677, {wxListCtrl, getItemCount, 0}}, + {1678, {wxListCtrl, getItemData, 1}}, + {1679, {wxListCtrl, getItemFont, 1}}, + {1680, {wxListCtrl, getItemPosition, 2}}, + {1681, {wxListCtrl, getItemRect, 3}}, + {1682, {wxListCtrl, getItemSpacing, 0}}, + {1683, {wxListCtrl, getItemState, 2}}, + {1684, {wxListCtrl, getItemText, 1}}, + {1685, {wxListCtrl, getItemTextColour, 1}}, + {1686, {wxListCtrl, getNextItem, 2}}, + {1687, {wxListCtrl, getSelectedItemCount, 0}}, + {1688, {wxListCtrl, getTextColour, 0}}, + {1689, {wxListCtrl, getTopItem, 0}}, + {1690, {wxListCtrl, getViewRect, 0}}, + {1691, {wxListCtrl, hitTest, 2}}, + {1692, {wxListCtrl, insertColumn_2, 2}}, + {1693, {wxListCtrl, insertColumn_3, 3}}, + {1694, {wxListCtrl, insertItem_1, 1}}, + {1695, {wxListCtrl, insertItem_2_1, 2}}, + {1696, {wxListCtrl, insertItem_2_0, 2}}, + {1697, {wxListCtrl, insertItem_3, 3}}, + {1698, {wxListCtrl, refreshItem, 1}}, + {1699, {wxListCtrl, refreshItems, 2}}, + {1700, {wxListCtrl, scrollList, 2}}, + {1701, {wxListCtrl, setBackgroundColour, 1}}, + {1702, {wxListCtrl, setColumn, 2}}, + {1703, {wxListCtrl, setColumnWidth, 2}}, + {1704, {wxListCtrl, setImageList, 2}}, + {1705, {wxListCtrl, setItem_1, 1}}, + {1706, {wxListCtrl, setItem_4, 4}}, + {1707, {wxListCtrl, setItemBackgroundColour, 2}}, + {1708, {wxListCtrl, setItemCount, 1}}, + {1709, {wxListCtrl, setItemData, 2}}, + {1710, {wxListCtrl, setItemFont, 2}}, + {1711, {wxListCtrl, setItemImage, 3}}, + {1712, {wxListCtrl, setItemColumnImage, 3}}, + {1713, {wxListCtrl, setItemPosition, 2}}, + {1714, {wxListCtrl, setItemState, 3}}, + {1715, {wxListCtrl, setItemText, 2}}, + {1716, {wxListCtrl, setItemTextColour, 2}}, + {1717, {wxListCtrl, setSingleStyle, 2}}, + {1718, {wxListCtrl, setTextColour, 1}}, + {1719, {wxListCtrl, setWindowStyleFlag, 1}}, + {1720, {wxListCtrl, sortItems, 2}}, + {1721, {wxListCtrl, 'Destroy', undefined}}, + {1722, {wxListView, clearColumnImage, 1}}, + {1723, {wxListView, focus, 1}}, + {1724, {wxListView, getFirstSelected, 0}}, + {1725, {wxListView, getFocusedItem, 0}}, + {1726, {wxListView, getNextSelected, 1}}, + {1727, {wxListView, isSelected, 1}}, + {1728, {wxListView, select, 2}}, + {1729, {wxListView, setColumnImage, 2}}, + {1730, {wxListItem, new_0, 0}}, + {1731, {wxListItem, new_1, 1}}, + {1732, {wxListItem, destruct, 0}}, + {1733, {wxListItem, clear, 0}}, + {1734, {wxListItem, getAlign, 0}}, + {1735, {wxListItem, getBackgroundColour, 0}}, + {1736, {wxListItem, getColumn, 0}}, + {1737, {wxListItem, getFont, 0}}, + {1738, {wxListItem, getId, 0}}, + {1739, {wxListItem, getImage, 0}}, + {1740, {wxListItem, getMask, 0}}, + {1741, {wxListItem, getState, 0}}, + {1742, {wxListItem, getText, 0}}, + {1743, {wxListItem, getTextColour, 0}}, + {1744, {wxListItem, getWidth, 0}}, + {1745, {wxListItem, setAlign, 1}}, + {1746, {wxListItem, setBackgroundColour, 1}}, + {1747, {wxListItem, setColumn, 1}}, + {1748, {wxListItem, setFont, 1}}, + {1749, {wxListItem, setId, 1}}, + {1750, {wxListItem, setImage, 1}}, + {1751, {wxListItem, setMask, 1}}, + {1752, {wxListItem, setState, 1}}, + {1753, {wxListItem, setStateMask, 1}}, + {1754, {wxListItem, setText, 1}}, + {1755, {wxListItem, setTextColour, 1}}, + {1756, {wxListItem, setWidth, 1}}, + {1757, {wxImageList, new_0, 0}}, + {1758, {wxImageList, new_3, 3}}, + {1759, {wxImageList, add_1, 1}}, + {1760, {wxImageList, add_2_0, 2}}, + {1761, {wxImageList, add_2_1, 2}}, + {1762, {wxImageList, create, 3}}, + {1764, {wxImageList, draw, 5}}, + {1765, {wxImageList, getBitmap, 1}}, + {1766, {wxImageList, getIcon, 1}}, + {1767, {wxImageList, getImageCount, 0}}, + {1768, {wxImageList, getSize, 3}}, + {1769, {wxImageList, remove, 1}}, + {1770, {wxImageList, removeAll, 0}}, + {1771, {wxImageList, replace_2, 2}}, + {1772, {wxImageList, replace_3, 3}}, + {1773, {wxImageList, 'Destroy', undefined}}, + {1774, {wxTextAttr, new_0, 0}}, + {1775, {wxTextAttr, new_2, 2}}, + {1776, {wxTextAttr, getAlignment, 0}}, + {1777, {wxTextAttr, getBackgroundColour, 0}}, + {1778, {wxTextAttr, getFont, 0}}, + {1779, {wxTextAttr, getLeftIndent, 0}}, + {1780, {wxTextAttr, getLeftSubIndent, 0}}, + {1781, {wxTextAttr, getRightIndent, 0}}, + {1782, {wxTextAttr, getTabs, 0}}, + {1783, {wxTextAttr, getTextColour, 0}}, + {1784, {wxTextAttr, hasBackgroundColour, 0}}, + {1785, {wxTextAttr, hasFont, 0}}, + {1786, {wxTextAttr, hasTextColour, 0}}, + {1787, {wxTextAttr, getFlags, 0}}, + {1788, {wxTextAttr, isDefault, 0}}, + {1789, {wxTextAttr, setAlignment, 1}}, + {1790, {wxTextAttr, setBackgroundColour, 1}}, + {1791, {wxTextAttr, setFlags, 1}}, + {1792, {wxTextAttr, setFont, 2}}, + {1793, {wxTextAttr, setLeftIndent, 2}}, + {1794, {wxTextAttr, setRightIndent, 1}}, + {1795, {wxTextAttr, setTabs, 1}}, + {1796, {wxTextAttr, setTextColour, 1}}, + {1797, {wxTextAttr, 'Destroy', undefined}}, + {1799, {wxTextCtrl, new_3, 3}}, + {1800, {wxTextCtrl, new_0, 0}}, + {1802, {wxTextCtrl, destruct, 0}}, + {1803, {wxTextCtrl, appendText, 1}}, + {1804, {wxTextCtrl, canCopy, 0}}, + {1805, {wxTextCtrl, canCut, 0}}, + {1806, {wxTextCtrl, canPaste, 0}}, + {1807, {wxTextCtrl, canRedo, 0}}, + {1808, {wxTextCtrl, canUndo, 0}}, + {1809, {wxTextCtrl, clear, 0}}, + {1810, {wxTextCtrl, copy, 0}}, + {1811, {wxTextCtrl, create, 3}}, + {1812, {wxTextCtrl, cut, 0}}, + {1813, {wxTextCtrl, discardEdits, 0}}, + {1814, {wxTextCtrl, emulateKeyPress, 1}}, + {1815, {wxTextCtrl, getDefaultStyle, 0}}, + {1816, {wxTextCtrl, getInsertionPoint, 0}}, + {1817, {wxTextCtrl, getLastPosition, 0}}, + {1818, {wxTextCtrl, getLineLength, 1}}, + {1819, {wxTextCtrl, getLineText, 1}}, + {1820, {wxTextCtrl, getNumberOfLines, 0}}, + {1821, {wxTextCtrl, getRange, 2}}, + {1822, {wxTextCtrl, getSelection, 2}}, + {1823, {wxTextCtrl, getStringSelection, 0}}, + {1824, {wxTextCtrl, getStyle, 2}}, + {1825, {wxTextCtrl, getValue, 0}}, + {1826, {wxTextCtrl, isEditable, 0}}, + {1827, {wxTextCtrl, isModified, 0}}, + {1828, {wxTextCtrl, isMultiLine, 0}}, + {1829, {wxTextCtrl, isSingleLine, 0}}, + {1830, {wxTextCtrl, loadFile, 2}}, + {1831, {wxTextCtrl, markDirty, 0}}, + {1832, {wxTextCtrl, paste, 0}}, + {1833, {wxTextCtrl, positionToXY, 3}}, + {1834, {wxTextCtrl, redo, 0}}, + {1835, {wxTextCtrl, remove, 2}}, + {1836, {wxTextCtrl, replace, 3}}, + {1837, {wxTextCtrl, saveFile, 1}}, + {1838, {wxTextCtrl, setDefaultStyle, 1}}, + {1839, {wxTextCtrl, setEditable, 1}}, + {1840, {wxTextCtrl, setInsertionPoint, 1}}, + {1841, {wxTextCtrl, setInsertionPointEnd, 0}}, + {1843, {wxTextCtrl, setMaxLength, 1}}, + {1844, {wxTextCtrl, setSelection, 2}}, + {1845, {wxTextCtrl, setStyle, 3}}, + {1846, {wxTextCtrl, setValue, 1}}, + {1847, {wxTextCtrl, showPosition, 1}}, + {1848, {wxTextCtrl, undo, 0}}, + {1849, {wxTextCtrl, writeText, 1}}, + {1850, {wxTextCtrl, xYToPosition, 2}}, + {1853, {wxNotebook, new_0, 0}}, + {1854, {wxNotebook, new_3, 3}}, + {1855, {wxNotebook, destruct, 0}}, + {1856, {wxNotebook, addPage, 3}}, + {1857, {wxNotebook, advanceSelection, 1}}, + {1858, {wxNotebook, assignImageList, 1}}, + {1859, {wxNotebook, create, 3}}, + {1860, {wxNotebook, deleteAllPages, 0}}, + {1861, {wxNotebook, deletePage, 1}}, + {1862, {wxNotebook, removePage, 1}}, + {1863, {wxNotebook, getCurrentPage, 0}}, + {1864, {wxNotebook, getImageList, 0}}, + {1866, {wxNotebook, getPage, 1}}, + {1867, {wxNotebook, getPageCount, 0}}, + {1868, {wxNotebook, getPageImage, 1}}, + {1869, {wxNotebook, getPageText, 1}}, + {1870, {wxNotebook, getRowCount, 0}}, + {1871, {wxNotebook, getSelection, 0}}, + {1872, {wxNotebook, getThemeBackgroundColour, 0}}, + {1874, {wxNotebook, hitTest, 2}}, + {1876, {wxNotebook, insertPage, 4}}, + {1877, {wxNotebook, setImageList, 1}}, + {1878, {wxNotebook, setPadding, 1}}, + {1879, {wxNotebook, setPageSize, 1}}, + {1880, {wxNotebook, setPageImage, 2}}, + {1881, {wxNotebook, setPageText, 2}}, + {1882, {wxNotebook, setSelection, 1}}, + {1883, {wxNotebook, changeSelection, 1}}, + {1884, {wxChoicebook, new_0, 0}}, + {1885, {wxChoicebook, new_3, 3}}, + {1886, {wxChoicebook, addPage, 3}}, + {1887, {wxChoicebook, advanceSelection, 1}}, + {1888, {wxChoicebook, assignImageList, 1}}, + {1889, {wxChoicebook, create, 3}}, + {1890, {wxChoicebook, deleteAllPages, 0}}, + {1891, {wxChoicebook, deletePage, 1}}, + {1892, {wxChoicebook, removePage, 1}}, + {1893, {wxChoicebook, getCurrentPage, 0}}, + {1894, {wxChoicebook, getImageList, 0}}, + {1896, {wxChoicebook, getPage, 1}}, + {1897, {wxChoicebook, getPageCount, 0}}, + {1898, {wxChoicebook, getPageImage, 1}}, + {1899, {wxChoicebook, getPageText, 1}}, + {1900, {wxChoicebook, getSelection, 0}}, + {1901, {wxChoicebook, hitTest, 2}}, + {1902, {wxChoicebook, insertPage, 4}}, + {1903, {wxChoicebook, setImageList, 1}}, + {1904, {wxChoicebook, setPageSize, 1}}, + {1905, {wxChoicebook, setPageImage, 2}}, + {1906, {wxChoicebook, setPageText, 2}}, + {1907, {wxChoicebook, setSelection, 1}}, + {1908, {wxChoicebook, changeSelection, 1}}, + {1909, {wxChoicebook, 'Destroy', undefined}}, + {1910, {wxToolbook, new_0, 0}}, + {1911, {wxToolbook, new_3, 3}}, + {1912, {wxToolbook, addPage, 3}}, + {1913, {wxToolbook, advanceSelection, 1}}, + {1914, {wxToolbook, assignImageList, 1}}, + {1915, {wxToolbook, create, 3}}, + {1916, {wxToolbook, deleteAllPages, 0}}, + {1917, {wxToolbook, deletePage, 1}}, + {1918, {wxToolbook, removePage, 1}}, + {1919, {wxToolbook, getCurrentPage, 0}}, + {1920, {wxToolbook, getImageList, 0}}, + {1922, {wxToolbook, getPage, 1}}, + {1923, {wxToolbook, getPageCount, 0}}, + {1924, {wxToolbook, getPageImage, 1}}, + {1925, {wxToolbook, getPageText, 1}}, + {1926, {wxToolbook, getSelection, 0}}, + {1928, {wxToolbook, hitTest, 2}}, + {1929, {wxToolbook, insertPage, 4}}, + {1930, {wxToolbook, setImageList, 1}}, + {1931, {wxToolbook, setPageSize, 1}}, + {1932, {wxToolbook, setPageImage, 2}}, + {1933, {wxToolbook, setPageText, 2}}, + {1934, {wxToolbook, setSelection, 1}}, + {1935, {wxToolbook, changeSelection, 1}}, + {1936, {wxToolbook, 'Destroy', undefined}}, + {1937, {wxListbook, new_0, 0}}, + {1938, {wxListbook, new_3, 3}}, + {1939, {wxListbook, addPage, 3}}, + {1940, {wxListbook, advanceSelection, 1}}, + {1941, {wxListbook, assignImageList, 1}}, + {1942, {wxListbook, create, 3}}, + {1943, {wxListbook, deleteAllPages, 0}}, + {1944, {wxListbook, deletePage, 1}}, + {1945, {wxListbook, removePage, 1}}, + {1946, {wxListbook, getCurrentPage, 0}}, + {1947, {wxListbook, getImageList, 0}}, + {1949, {wxListbook, getPage, 1}}, + {1950, {wxListbook, getPageCount, 0}}, + {1951, {wxListbook, getPageImage, 1}}, + {1952, {wxListbook, getPageText, 1}}, + {1953, {wxListbook, getSelection, 0}}, + {1955, {wxListbook, hitTest, 2}}, + {1956, {wxListbook, insertPage, 4}}, + {1957, {wxListbook, setImageList, 1}}, + {1958, {wxListbook, setPageSize, 1}}, + {1959, {wxListbook, setPageImage, 2}}, + {1960, {wxListbook, setPageText, 2}}, + {1961, {wxListbook, setSelection, 1}}, + {1962, {wxListbook, changeSelection, 1}}, + {1963, {wxListbook, 'Destroy', undefined}}, + {1964, {wxTreebook, new_0, 0}}, + {1965, {wxTreebook, new_3, 3}}, + {1966, {wxTreebook, addPage, 3}}, + {1967, {wxTreebook, advanceSelection, 1}}, + {1968, {wxTreebook, assignImageList, 1}}, + {1969, {wxTreebook, create, 3}}, + {1970, {wxTreebook, deleteAllPages, 0}}, + {1971, {wxTreebook, deletePage, 1}}, + {1972, {wxTreebook, removePage, 1}}, + {1973, {wxTreebook, getCurrentPage, 0}}, + {1974, {wxTreebook, getImageList, 0}}, + {1976, {wxTreebook, getPage, 1}}, + {1977, {wxTreebook, getPageCount, 0}}, + {1978, {wxTreebook, getPageImage, 1}}, + {1979, {wxTreebook, getPageText, 1}}, + {1980, {wxTreebook, getSelection, 0}}, + {1981, {wxTreebook, expandNode, 2}}, + {1982, {wxTreebook, isNodeExpanded, 1}}, + {1984, {wxTreebook, hitTest, 2}}, + {1985, {wxTreebook, insertPage, 4}}, + {1986, {wxTreebook, insertSubPage, 4}}, + {1987, {wxTreebook, setImageList, 1}}, + {1988, {wxTreebook, setPageSize, 1}}, + {1989, {wxTreebook, setPageImage, 2}}, + {1990, {wxTreebook, setPageText, 2}}, + {1991, {wxTreebook, setSelection, 1}}, + {1992, {wxTreebook, changeSelection, 1}}, + {1993, {wxTreebook, 'Destroy', undefined}}, + {1996, {wxTreeCtrl, new_2, 2}}, + {1997, {wxTreeCtrl, new_0, 0}}, + {1999, {wxTreeCtrl, destruct, 0}}, + {2000, {wxTreeCtrl, addRoot, 2}}, + {2001, {wxTreeCtrl, appendItem, 3}}, + {2002, {wxTreeCtrl, assignImageList, 1}}, + {2003, {wxTreeCtrl, assignStateImageList, 1}}, + {2004, {wxTreeCtrl, collapse, 1}}, + {2005, {wxTreeCtrl, collapseAndReset, 1}}, + {2006, {wxTreeCtrl, create, 2}}, + {2007, {wxTreeCtrl, delete, 1}}, + {2008, {wxTreeCtrl, deleteAllItems, 0}}, + {2009, {wxTreeCtrl, deleteChildren, 1}}, + {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 b1d5e50647..cf672644c6 100644 --- a/lib/wx/src/gen/wxe_funcs.hrl +++ b/lib/wx/src/gen/wxe_funcs.hrl @@ -767,2509 +767,2514 @@ -define(wxControlWithItems_Clear, 882). -define(wxControlWithItems_Delete, 883). -define(wxControlWithItems_FindString, 884). --define(wxControlWithItems_getClientData, 886). --define(wxControlWithItems_setClientData, 888). --define(wxControlWithItems_GetCount, 889). --define(wxControlWithItems_GetSelection, 890). --define(wxControlWithItems_GetString, 891). --define(wxControlWithItems_GetStringSelection, 892). --define(wxControlWithItems_Insert_2, 893). --define(wxControlWithItems_Insert_3, 894). --define(wxControlWithItems_IsEmpty, 895). --define(wxControlWithItems_Select, 896). --define(wxControlWithItems_SetSelection, 897). --define(wxControlWithItems_SetString, 898). --define(wxControlWithItems_SetStringSelection, 899). --define(wxMenu_new_2, 902). --define(wxMenu_new_1, 903). --define(wxMenu_destruct, 905). --define(wxMenu_Append_3, 906). --define(wxMenu_Append_1, 907). --define(wxMenu_Append_4_0, 908). --define(wxMenu_Append_4_1, 909). --define(wxMenu_AppendCheckItem, 910). --define(wxMenu_AppendRadioItem, 911). --define(wxMenu_AppendSeparator, 912). --define(wxMenu_Break, 913). --define(wxMenu_Check, 914). --define(wxMenu_Delete_1_0, 915). --define(wxMenu_Delete_1_1, 916). --define(wxMenu_Destroy_1_0, 917). --define(wxMenu_Destroy_1_1, 918). --define(wxMenu_Enable, 919). --define(wxMenu_FindItem_1, 920). --define(wxMenu_FindItem_2, 921). --define(wxMenu_FindItemByPosition, 922). --define(wxMenu_GetHelpString, 923). --define(wxMenu_GetLabel, 924). --define(wxMenu_GetMenuItemCount, 925). --define(wxMenu_GetMenuItems, 926). --define(wxMenu_GetTitle, 928). --define(wxMenu_Insert_2, 929). --define(wxMenu_Insert_3, 930). --define(wxMenu_Insert_5_1, 931). --define(wxMenu_Insert_5_0, 932). --define(wxMenu_InsertCheckItem, 933). --define(wxMenu_InsertRadioItem, 934). --define(wxMenu_InsertSeparator, 935). --define(wxMenu_IsChecked, 936). --define(wxMenu_IsEnabled, 937). --define(wxMenu_Prepend_1, 938). --define(wxMenu_Prepend_2, 939). --define(wxMenu_Prepend_4_1, 940). --define(wxMenu_Prepend_4_0, 941). --define(wxMenu_PrependCheckItem, 942). --define(wxMenu_PrependRadioItem, 943). --define(wxMenu_PrependSeparator, 944). --define(wxMenu_Remove_1_0, 945). --define(wxMenu_Remove_1_1, 946). --define(wxMenu_SetHelpString, 947). --define(wxMenu_SetLabel, 948). --define(wxMenu_SetTitle, 949). --define(wxMenuItem_new, 950). --define(wxMenuItem_destruct, 952). --define(wxMenuItem_Check, 953). --define(wxMenuItem_Enable, 954). --define(wxMenuItem_GetBitmap, 955). --define(wxMenuItem_GetHelp, 956). --define(wxMenuItem_GetId, 957). --define(wxMenuItem_GetKind, 958). --define(wxMenuItem_GetLabel, 959). --define(wxMenuItem_GetLabelFromText, 960). --define(wxMenuItem_GetMenu, 961). --define(wxMenuItem_GetText, 962). --define(wxMenuItem_GetSubMenu, 963). --define(wxMenuItem_IsCheckable, 964). --define(wxMenuItem_IsChecked, 965). --define(wxMenuItem_IsEnabled, 966). --define(wxMenuItem_IsSeparator, 967). --define(wxMenuItem_IsSubMenu, 968). --define(wxMenuItem_SetBitmap, 969). --define(wxMenuItem_SetHelp, 970). --define(wxMenuItem_SetMenu, 971). --define(wxMenuItem_SetSubMenu, 972). --define(wxMenuItem_SetText, 973). --define(wxToolBar_AddControl, 974). --define(wxToolBar_AddSeparator, 975). --define(wxToolBar_AddTool_5, 976). --define(wxToolBar_AddTool_4_0, 977). --define(wxToolBar_AddTool_1, 978). --define(wxToolBar_AddTool_4_1, 979). --define(wxToolBar_AddTool_3, 980). --define(wxToolBar_AddTool_6, 981). --define(wxToolBar_AddCheckTool, 982). --define(wxToolBar_AddRadioTool, 983). --define(wxToolBar_DeleteTool, 984). --define(wxToolBar_DeleteToolByPos, 985). --define(wxToolBar_EnableTool, 986). --define(wxToolBar_FindById, 987). --define(wxToolBar_FindControl, 988). --define(wxToolBar_FindToolForPosition, 989). --define(wxToolBar_GetToolSize, 990). --define(wxToolBar_GetToolBitmapSize, 991). --define(wxToolBar_GetMargins, 992). --define(wxToolBar_GetToolEnabled, 993). --define(wxToolBar_GetToolLongHelp, 994). --define(wxToolBar_GetToolPacking, 995). --define(wxToolBar_GetToolPos, 996). --define(wxToolBar_GetToolSeparation, 997). --define(wxToolBar_GetToolShortHelp, 998). --define(wxToolBar_GetToolState, 999). --define(wxToolBar_InsertControl, 1000). --define(wxToolBar_InsertSeparator, 1001). --define(wxToolBar_InsertTool_5, 1002). --define(wxToolBar_InsertTool_2, 1003). --define(wxToolBar_InsertTool_4, 1004). --define(wxToolBar_Realize, 1005). --define(wxToolBar_RemoveTool, 1006). --define(wxToolBar_SetMargins, 1007). --define(wxToolBar_SetToolBitmapSize, 1008). --define(wxToolBar_SetToolLongHelp, 1009). --define(wxToolBar_SetToolPacking, 1010). --define(wxToolBar_SetToolShortHelp, 1011). --define(wxToolBar_SetToolSeparation, 1012). --define(wxToolBar_ToggleTool, 1013). --define(wxStatusBar_new_0, 1015). --define(wxStatusBar_new_2, 1016). --define(wxStatusBar_destruct, 1018). --define(wxStatusBar_Create, 1019). --define(wxStatusBar_GetFieldRect, 1020). --define(wxStatusBar_GetFieldsCount, 1021). --define(wxStatusBar_GetStatusText, 1022). --define(wxStatusBar_PopStatusText, 1023). --define(wxStatusBar_PushStatusText, 1024). --define(wxStatusBar_SetFieldsCount, 1025). --define(wxStatusBar_SetMinHeight, 1026). --define(wxStatusBar_SetStatusText, 1027). --define(wxStatusBar_SetStatusWidths, 1028). --define(wxStatusBar_SetStatusStyles, 1029). --define(wxBitmap_new_0, 1030). --define(wxBitmap_new_3, 1031). --define(wxBitmap_new_4, 1032). --define(wxBitmap_new_2_0, 1033). --define(wxBitmap_new_2_1, 1034). --define(wxBitmap_destruct, 1035). --define(wxBitmap_ConvertToImage, 1036). --define(wxBitmap_CopyFromIcon, 1037). --define(wxBitmap_Create, 1038). --define(wxBitmap_GetDepth, 1039). --define(wxBitmap_GetHeight, 1040). --define(wxBitmap_GetPalette, 1041). --define(wxBitmap_GetMask, 1042). --define(wxBitmap_GetWidth, 1043). --define(wxBitmap_GetSubBitmap, 1044). --define(wxBitmap_LoadFile, 1045). --define(wxBitmap_Ok, 1046). --define(wxBitmap_SaveFile, 1047). --define(wxBitmap_SetDepth, 1048). --define(wxBitmap_SetHeight, 1049). --define(wxBitmap_SetMask, 1050). --define(wxBitmap_SetPalette, 1051). --define(wxBitmap_SetWidth, 1052). --define(wxIcon_new_0, 1053). --define(wxIcon_new_2, 1054). --define(wxIcon_new_1, 1055). --define(wxIcon_CopyFromBitmap, 1056). --define(wxIcon_destroy, 1057). --define(wxIconBundle_new_0, 1058). --define(wxIconBundle_new_2, 1059). --define(wxIconBundle_new_1_0, 1060). --define(wxIconBundle_new_1_1, 1061). --define(wxIconBundle_destruct, 1062). --define(wxIconBundle_AddIcon_2, 1063). --define(wxIconBundle_AddIcon_1, 1064). --define(wxIconBundle_GetIcon_1_1, 1065). --define(wxIconBundle_GetIcon_1_0, 1066). --define(wxCursor_new_0, 1067). --define(wxCursor_new_1_0, 1068). --define(wxCursor_new_1_1, 1069). --define(wxCursor_new_4, 1070). --define(wxCursor_destruct, 1071). --define(wxCursor_Ok, 1072). --define(wxMask_new_0, 1073). --define(wxMask_new_2_1, 1074). --define(wxMask_new_2_0, 1075). --define(wxMask_new_1, 1076). --define(wxMask_destruct, 1077). --define(wxMask_Create_2_1, 1078). --define(wxMask_Create_2_0, 1079). --define(wxMask_Create_1, 1080). --define(wxImage_new_0, 1081). --define(wxImage_new_3_0, 1082). --define(wxImage_new_4, 1083). --define(wxImage_new_5, 1084). --define(wxImage_new_2, 1085). --define(wxImage_new_3_1, 1086). --define(wxImage_Blur, 1087). --define(wxImage_BlurHorizontal, 1088). --define(wxImage_BlurVertical, 1089). --define(wxImage_ConvertAlphaToMask, 1090). --define(wxImage_ConvertToGreyscale, 1091). --define(wxImage_ConvertToMono, 1092). --define(wxImage_Copy, 1093). --define(wxImage_Create_3, 1094). --define(wxImage_Create_4, 1095). --define(wxImage_Create_5, 1096). --define(wxImage_Destroy, 1097). --define(wxImage_FindFirstUnusedColour, 1098). --define(wxImage_GetImageExtWildcard, 1099). --define(wxImage_GetAlpha_2, 1100). --define(wxImage_GetAlpha_0, 1101). --define(wxImage_GetBlue, 1102). --define(wxImage_GetData, 1103). --define(wxImage_GetGreen, 1104). --define(wxImage_GetImageCount, 1105). --define(wxImage_GetHeight, 1106). --define(wxImage_GetMaskBlue, 1107). --define(wxImage_GetMaskGreen, 1108). --define(wxImage_GetMaskRed, 1109). --define(wxImage_GetOrFindMaskColour, 1110). --define(wxImage_GetPalette, 1111). --define(wxImage_GetRed, 1112). --define(wxImage_GetSubImage, 1113). --define(wxImage_GetWidth, 1114). --define(wxImage_HasAlpha, 1115). --define(wxImage_HasMask, 1116). --define(wxImage_GetOption, 1117). --define(wxImage_GetOptionInt, 1118). --define(wxImage_HasOption, 1119). --define(wxImage_InitAlpha, 1120). --define(wxImage_InitStandardHandlers, 1121). --define(wxImage_IsTransparent, 1122). --define(wxImage_LoadFile_2, 1123). --define(wxImage_LoadFile_3, 1124). --define(wxImage_Ok, 1125). --define(wxImage_RemoveHandler, 1126). --define(wxImage_Mirror, 1127). --define(wxImage_Replace, 1128). --define(wxImage_Rescale, 1129). --define(wxImage_Resize, 1130). --define(wxImage_Rotate, 1131). --define(wxImage_RotateHue, 1132). --define(wxImage_Rotate90, 1133). --define(wxImage_SaveFile_1, 1134). --define(wxImage_SaveFile_2_0, 1135). --define(wxImage_SaveFile_2_1, 1136). --define(wxImage_Scale, 1137). --define(wxImage_Size, 1138). --define(wxImage_SetAlpha_3, 1139). --define(wxImage_SetAlpha_2, 1140). --define(wxImage_SetData_2, 1141). --define(wxImage_SetData_4, 1142). --define(wxImage_SetMask, 1143). --define(wxImage_SetMaskColour, 1144). --define(wxImage_SetMaskFromImage, 1145). --define(wxImage_SetOption_2_1, 1146). --define(wxImage_SetOption_2_0, 1147). --define(wxImage_SetPalette, 1148). --define(wxImage_SetRGB_5, 1149). --define(wxImage_SetRGB_4, 1150). --define(wxImage_destroy, 1151). --define(wxBrush_new_0, 1152). --define(wxBrush_new_2, 1153). --define(wxBrush_new_1, 1154). --define(wxBrush_destruct, 1156). --define(wxBrush_GetColour, 1157). --define(wxBrush_GetStipple, 1158). --define(wxBrush_GetStyle, 1159). --define(wxBrush_IsHatch, 1160). --define(wxBrush_IsOk, 1161). --define(wxBrush_SetColour_1, 1162). --define(wxBrush_SetColour_3, 1163). --define(wxBrush_SetStipple, 1164). --define(wxBrush_SetStyle, 1165). --define(wxPen_new_0, 1166). --define(wxPen_new_2, 1167). --define(wxPen_destruct, 1168). --define(wxPen_GetCap, 1169). --define(wxPen_GetColour, 1170). --define(wxPen_GetJoin, 1171). --define(wxPen_GetStyle, 1172). --define(wxPen_GetWidth, 1173). --define(wxPen_IsOk, 1174). --define(wxPen_SetCap, 1175). --define(wxPen_SetColour_1, 1176). --define(wxPen_SetColour_3, 1177). --define(wxPen_SetJoin, 1178). --define(wxPen_SetStyle, 1179). --define(wxPen_SetWidth, 1180). --define(wxRegion_new_0, 1181). --define(wxRegion_new_4, 1182). --define(wxRegion_new_2, 1183). --define(wxRegion_new_1_1, 1184). --define(wxRegion_new_1_0, 1186). --define(wxRegion_destruct, 1188). --define(wxRegion_Clear, 1189). --define(wxRegion_Contains_2, 1190). --define(wxRegion_Contains_1_0, 1191). --define(wxRegion_Contains_4, 1192). --define(wxRegion_Contains_1_1, 1193). --define(wxRegion_ConvertToBitmap, 1194). --define(wxRegion_GetBox, 1195). --define(wxRegion_Intersect_4, 1196). --define(wxRegion_Intersect_1_1, 1197). --define(wxRegion_Intersect_1_0, 1198). --define(wxRegion_IsEmpty, 1199). --define(wxRegion_Subtract_4, 1200). --define(wxRegion_Subtract_1_1, 1201). --define(wxRegion_Subtract_1_0, 1202). --define(wxRegion_Offset_2, 1203). --define(wxRegion_Offset_1, 1204). --define(wxRegion_Union_4, 1205). --define(wxRegion_Union_1_2, 1206). --define(wxRegion_Union_1_1, 1207). --define(wxRegion_Union_1_0, 1208). --define(wxRegion_Union_3, 1209). --define(wxRegion_Xor_4, 1210). --define(wxRegion_Xor_1_1, 1211). --define(wxRegion_Xor_1_0, 1212). --define(wxAcceleratorTable_new_0, 1213). --define(wxAcceleratorTable_new_2, 1214). --define(wxAcceleratorTable_destruct, 1215). --define(wxAcceleratorTable_Ok, 1216). --define(wxAcceleratorEntry_new_1_0, 1217). --define(wxAcceleratorEntry_new_1_1, 1218). --define(wxAcceleratorEntry_GetCommand, 1219). --define(wxAcceleratorEntry_GetFlags, 1220). --define(wxAcceleratorEntry_GetKeyCode, 1221). --define(wxAcceleratorEntry_Set, 1222). --define(wxAcceleratorEntry_destroy, 1223). --define(wxCaret_new_3, 1228). --define(wxCaret_new_2, 1229). --define(wxCaret_destruct, 1231). --define(wxCaret_Create_3, 1232). --define(wxCaret_Create_2, 1233). --define(wxCaret_GetBlinkTime, 1234). --define(wxCaret_GetPosition, 1236). --define(wxCaret_GetSize, 1238). --define(wxCaret_GetWindow, 1239). --define(wxCaret_Hide, 1240). --define(wxCaret_IsOk, 1241). --define(wxCaret_IsVisible, 1242). --define(wxCaret_Move_2, 1243). --define(wxCaret_Move_1, 1244). --define(wxCaret_SetBlinkTime, 1245). --define(wxCaret_SetSize_2, 1246). --define(wxCaret_SetSize_1, 1247). --define(wxCaret_Show, 1248). --define(wxSizer_Add_2_1, 1249). --define(wxSizer_Add_2_0, 1250). --define(wxSizer_Add_3, 1251). --define(wxSizer_Add_2_3, 1252). --define(wxSizer_Add_2_2, 1253). --define(wxSizer_AddSpacer, 1254). --define(wxSizer_AddStretchSpacer, 1255). --define(wxSizer_CalcMin, 1256). --define(wxSizer_Clear, 1257). --define(wxSizer_Detach_1_2, 1258). --define(wxSizer_Detach_1_1, 1259). --define(wxSizer_Detach_1_0, 1260). --define(wxSizer_Fit, 1261). --define(wxSizer_FitInside, 1262). --define(wxSizer_GetChildren, 1263). --define(wxSizer_GetItem_2_1, 1264). --define(wxSizer_GetItem_2_0, 1265). --define(wxSizer_GetItem_1, 1266). --define(wxSizer_GetSize, 1267). --define(wxSizer_GetPosition, 1268). --define(wxSizer_GetMinSize, 1269). --define(wxSizer_Hide_2_0, 1270). --define(wxSizer_Hide_2_1, 1271). --define(wxSizer_Hide_1, 1272). --define(wxSizer_Insert_3_1, 1273). --define(wxSizer_Insert_3_0, 1274). --define(wxSizer_Insert_4, 1275). --define(wxSizer_Insert_3_3, 1276). --define(wxSizer_Insert_3_2, 1277). --define(wxSizer_Insert_2, 1278). --define(wxSizer_InsertSpacer, 1279). --define(wxSizer_InsertStretchSpacer, 1280). --define(wxSizer_IsShown_1_2, 1281). --define(wxSizer_IsShown_1_1, 1282). --define(wxSizer_IsShown_1_0, 1283). --define(wxSizer_Layout, 1284). --define(wxSizer_Prepend_2_1, 1285). --define(wxSizer_Prepend_2_0, 1286). --define(wxSizer_Prepend_3, 1287). --define(wxSizer_Prepend_2_3, 1288). --define(wxSizer_Prepend_2_2, 1289). --define(wxSizer_Prepend_1, 1290). --define(wxSizer_PrependSpacer, 1291). --define(wxSizer_PrependStretchSpacer, 1292). --define(wxSizer_RecalcSizes, 1293). --define(wxSizer_Remove_1_1, 1294). --define(wxSizer_Remove_1_0, 1295). --define(wxSizer_Replace_3_1, 1296). --define(wxSizer_Replace_3_0, 1297). --define(wxSizer_Replace_2, 1298). --define(wxSizer_SetDimension, 1299). --define(wxSizer_SetMinSize_2, 1300). --define(wxSizer_SetMinSize_1, 1301). --define(wxSizer_SetItemMinSize_3_2, 1302). --define(wxSizer_SetItemMinSize_2_2, 1303). --define(wxSizer_SetItemMinSize_3_1, 1304). --define(wxSizer_SetItemMinSize_2_1, 1305). --define(wxSizer_SetItemMinSize_3_0, 1306). --define(wxSizer_SetItemMinSize_2_0, 1307). --define(wxSizer_SetSizeHints, 1308). --define(wxSizer_SetVirtualSizeHints, 1309). --define(wxSizer_Show_2_2, 1310). --define(wxSizer_Show_2_1, 1311). --define(wxSizer_Show_2_0, 1312). --define(wxSizer_Show_1, 1313). --define(wxSizerFlags_new, 1314). --define(wxSizerFlags_Align, 1315). --define(wxSizerFlags_Border_2, 1316). --define(wxSizerFlags_Border_1, 1317). --define(wxSizerFlags_Center, 1318). --define(wxSizerFlags_Centre, 1319). --define(wxSizerFlags_Expand, 1320). --define(wxSizerFlags_Left, 1321). --define(wxSizerFlags_Proportion, 1322). --define(wxSizerFlags_Right, 1323). --define(wxSizerFlags_destroy, 1324). --define(wxSizerItem_new_5_1, 1325). --define(wxSizerItem_new_2_1, 1326). --define(wxSizerItem_new_5_0, 1327). --define(wxSizerItem_new_2_0, 1328). --define(wxSizerItem_new_6, 1329). --define(wxSizerItem_new_3, 1330). --define(wxSizerItem_new_0, 1331). --define(wxSizerItem_destruct, 1332). --define(wxSizerItem_CalcMin, 1333). --define(wxSizerItem_DeleteWindows, 1334). --define(wxSizerItem_DetachSizer, 1335). --define(wxSizerItem_GetBorder, 1336). --define(wxSizerItem_GetFlag, 1337). --define(wxSizerItem_GetMinSize, 1338). --define(wxSizerItem_GetPosition, 1339). --define(wxSizerItem_GetProportion, 1340). --define(wxSizerItem_GetRatio, 1341). --define(wxSizerItem_GetRect, 1342). --define(wxSizerItem_GetSize, 1343). --define(wxSizerItem_GetSizer, 1344). --define(wxSizerItem_GetSpacer, 1345). --define(wxSizerItem_GetUserData, 1346). --define(wxSizerItem_GetWindow, 1347). --define(wxSizerItem_IsSizer, 1348). --define(wxSizerItem_IsShown, 1349). --define(wxSizerItem_IsSpacer, 1350). --define(wxSizerItem_IsWindow, 1351). --define(wxSizerItem_SetBorder, 1352). --define(wxSizerItem_SetDimension, 1353). --define(wxSizerItem_SetFlag, 1354). --define(wxSizerItem_SetInitSize, 1355). --define(wxSizerItem_SetMinSize_1, 1356). --define(wxSizerItem_SetMinSize_2, 1357). --define(wxSizerItem_SetProportion, 1358). --define(wxSizerItem_SetRatio_2, 1359). --define(wxSizerItem_SetRatio_1_1, 1360). --define(wxSizerItem_SetRatio_1_0, 1361). --define(wxSizerItem_SetSizer, 1362). --define(wxSizerItem_SetSpacer_1, 1363). --define(wxSizerItem_SetSpacer_2, 1364). --define(wxSizerItem_SetWindow, 1365). --define(wxSizerItem_Show, 1366). --define(wxBoxSizer_new, 1367). --define(wxBoxSizer_GetOrientation, 1368). --define(wxBoxSizer_destroy, 1369). --define(wxStaticBoxSizer_new_2, 1370). --define(wxStaticBoxSizer_new_3, 1371). --define(wxStaticBoxSizer_GetStaticBox, 1372). --define(wxStaticBoxSizer_destroy, 1373). --define(wxGridSizer_new_4, 1374). --define(wxGridSizer_new_2, 1375). --define(wxGridSizer_GetCols, 1376). --define(wxGridSizer_GetHGap, 1377). --define(wxGridSizer_GetRows, 1378). --define(wxGridSizer_GetVGap, 1379). --define(wxGridSizer_SetCols, 1380). --define(wxGridSizer_SetHGap, 1381). --define(wxGridSizer_SetRows, 1382). --define(wxGridSizer_SetVGap, 1383). --define(wxGridSizer_destroy, 1384). --define(wxFlexGridSizer_new_4, 1385). --define(wxFlexGridSizer_new_2, 1386). --define(wxFlexGridSizer_AddGrowableCol, 1387). --define(wxFlexGridSizer_AddGrowableRow, 1388). --define(wxFlexGridSizer_GetFlexibleDirection, 1389). --define(wxFlexGridSizer_GetNonFlexibleGrowMode, 1390). --define(wxFlexGridSizer_RemoveGrowableCol, 1391). --define(wxFlexGridSizer_RemoveGrowableRow, 1392). --define(wxFlexGridSizer_SetFlexibleDirection, 1393). --define(wxFlexGridSizer_SetNonFlexibleGrowMode, 1394). --define(wxFlexGridSizer_destroy, 1395). --define(wxGridBagSizer_new, 1396). --define(wxGridBagSizer_Add_3_2, 1397). --define(wxGridBagSizer_Add_3_1, 1398). --define(wxGridBagSizer_Add_4, 1399). --define(wxGridBagSizer_Add_1_0, 1400). --define(wxGridBagSizer_Add_2_1, 1401). --define(wxGridBagSizer_Add_2_0, 1402). --define(wxGridBagSizer_Add_3_0, 1403). --define(wxGridBagSizer_Add_1_1, 1404). --define(wxGridBagSizer_CalcMin, 1405). --define(wxGridBagSizer_CheckForIntersection_2, 1406). --define(wxGridBagSizer_CheckForIntersection_3, 1407). --define(wxGridBagSizer_FindItem_1_1, 1408). --define(wxGridBagSizer_FindItem_1_0, 1409). --define(wxGridBagSizer_FindItemAtPoint, 1410). --define(wxGridBagSizer_FindItemAtPosition, 1411). --define(wxGridBagSizer_FindItemWithData, 1412). --define(wxGridBagSizer_GetCellSize, 1413). --define(wxGridBagSizer_GetEmptyCellSize, 1414). --define(wxGridBagSizer_GetItemPosition_1_2, 1415). --define(wxGridBagSizer_GetItemPosition_1_1, 1416). --define(wxGridBagSizer_GetItemPosition_1_0, 1417). --define(wxGridBagSizer_GetItemSpan_1_2, 1418). --define(wxGridBagSizer_GetItemSpan_1_1, 1419). --define(wxGridBagSizer_GetItemSpan_1_0, 1420). --define(wxGridBagSizer_SetEmptyCellSize, 1421). --define(wxGridBagSizer_SetItemPosition_2_2, 1422). --define(wxGridBagSizer_SetItemPosition_2_1, 1423). --define(wxGridBagSizer_SetItemPosition_2_0, 1424). --define(wxGridBagSizer_SetItemSpan_2_2, 1425). --define(wxGridBagSizer_SetItemSpan_2_1, 1426). --define(wxGridBagSizer_SetItemSpan_2_0, 1427). --define(wxGridBagSizer_destroy, 1428). --define(wxStdDialogButtonSizer_new, 1429). --define(wxStdDialogButtonSizer_AddButton, 1430). --define(wxStdDialogButtonSizer_Realize, 1431). --define(wxStdDialogButtonSizer_SetAffirmativeButton, 1432). --define(wxStdDialogButtonSizer_SetCancelButton, 1433). --define(wxStdDialogButtonSizer_SetNegativeButton, 1434). --define(wxStdDialogButtonSizer_destroy, 1435). --define(wxFont_new_0, 1436). --define(wxFont_new_1, 1437). --define(wxFont_new_5, 1438). --define(wxFont_destruct, 1440). --define(wxFont_IsFixedWidth, 1441). --define(wxFont_GetDefaultEncoding, 1442). --define(wxFont_GetFaceName, 1443). --define(wxFont_GetFamily, 1444). --define(wxFont_GetNativeFontInfoDesc, 1445). --define(wxFont_GetNativeFontInfoUserDesc, 1446). --define(wxFont_GetPointSize, 1447). --define(wxFont_GetStyle, 1448). --define(wxFont_GetUnderlined, 1449). --define(wxFont_GetWeight, 1450). --define(wxFont_Ok, 1451). --define(wxFont_SetDefaultEncoding, 1452). --define(wxFont_SetFaceName, 1453). --define(wxFont_SetFamily, 1454). --define(wxFont_SetPointSize, 1455). --define(wxFont_SetStyle, 1456). --define(wxFont_SetUnderlined, 1457). --define(wxFont_SetWeight, 1458). --define(wxToolTip_Enable, 1459). --define(wxToolTip_SetDelay, 1460). --define(wxToolTip_new, 1461). --define(wxToolTip_SetTip, 1462). --define(wxToolTip_GetTip, 1463). --define(wxToolTip_GetWindow, 1464). --define(wxToolTip_destroy, 1465). --define(wxButton_new_3, 1467). --define(wxButton_new_0, 1468). --define(wxButton_destruct, 1469). --define(wxButton_Create, 1470). --define(wxButton_GetDefaultSize, 1471). --define(wxButton_SetDefault, 1472). --define(wxButton_SetLabel, 1473). --define(wxBitmapButton_new_4, 1475). --define(wxBitmapButton_new_0, 1476). --define(wxBitmapButton_Create, 1477). --define(wxBitmapButton_GetBitmapDisabled, 1478). --define(wxBitmapButton_GetBitmapFocus, 1480). --define(wxBitmapButton_GetBitmapLabel, 1482). --define(wxBitmapButton_GetBitmapSelected, 1484). --define(wxBitmapButton_SetBitmapDisabled, 1486). --define(wxBitmapButton_SetBitmapFocus, 1487). --define(wxBitmapButton_SetBitmapLabel, 1488). --define(wxBitmapButton_SetBitmapSelected, 1489). --define(wxBitmapButton_destroy, 1490). --define(wxToggleButton_new_0, 1491). --define(wxToggleButton_new_4, 1492). --define(wxToggleButton_Create, 1493). --define(wxToggleButton_GetValue, 1494). --define(wxToggleButton_SetValue, 1495). --define(wxToggleButton_destroy, 1496). --define(wxCalendarCtrl_new_0, 1497). --define(wxCalendarCtrl_new_3, 1498). --define(wxCalendarCtrl_Create, 1499). --define(wxCalendarCtrl_destruct, 1500). --define(wxCalendarCtrl_SetDate, 1501). --define(wxCalendarCtrl_GetDate, 1502). --define(wxCalendarCtrl_EnableYearChange, 1503). --define(wxCalendarCtrl_EnableMonthChange, 1504). --define(wxCalendarCtrl_EnableHolidayDisplay, 1505). --define(wxCalendarCtrl_SetHeaderColours, 1506). --define(wxCalendarCtrl_GetHeaderColourFg, 1507). --define(wxCalendarCtrl_GetHeaderColourBg, 1508). --define(wxCalendarCtrl_SetHighlightColours, 1509). --define(wxCalendarCtrl_GetHighlightColourFg, 1510). --define(wxCalendarCtrl_GetHighlightColourBg, 1511). --define(wxCalendarCtrl_SetHolidayColours, 1512). --define(wxCalendarCtrl_GetHolidayColourFg, 1513). --define(wxCalendarCtrl_GetHolidayColourBg, 1514). --define(wxCalendarCtrl_GetAttr, 1515). --define(wxCalendarCtrl_SetAttr, 1516). --define(wxCalendarCtrl_SetHoliday, 1517). --define(wxCalendarCtrl_ResetAttr, 1518). --define(wxCalendarCtrl_HitTest, 1519). --define(wxCalendarDateAttr_new_0, 1520). --define(wxCalendarDateAttr_new_2_1, 1521). --define(wxCalendarDateAttr_new_2_0, 1522). --define(wxCalendarDateAttr_SetTextColour, 1523). --define(wxCalendarDateAttr_SetBackgroundColour, 1524). --define(wxCalendarDateAttr_SetBorderColour, 1525). --define(wxCalendarDateAttr_SetFont, 1526). --define(wxCalendarDateAttr_SetBorder, 1527). --define(wxCalendarDateAttr_SetHoliday, 1528). --define(wxCalendarDateAttr_HasTextColour, 1529). --define(wxCalendarDateAttr_HasBackgroundColour, 1530). --define(wxCalendarDateAttr_HasBorderColour, 1531). --define(wxCalendarDateAttr_HasFont, 1532). --define(wxCalendarDateAttr_HasBorder, 1533). --define(wxCalendarDateAttr_IsHoliday, 1534). --define(wxCalendarDateAttr_GetTextColour, 1535). --define(wxCalendarDateAttr_GetBackgroundColour, 1536). --define(wxCalendarDateAttr_GetBorderColour, 1537). --define(wxCalendarDateAttr_GetFont, 1538). --define(wxCalendarDateAttr_GetBorder, 1539). --define(wxCalendarDateAttr_destroy, 1540). --define(wxCheckBox_new_4, 1542). --define(wxCheckBox_new_0, 1543). --define(wxCheckBox_Create, 1544). --define(wxCheckBox_GetValue, 1545). --define(wxCheckBox_Get3StateValue, 1546). --define(wxCheckBox_Is3rdStateAllowedForUser, 1547). --define(wxCheckBox_Is3State, 1548). --define(wxCheckBox_IsChecked, 1549). --define(wxCheckBox_SetValue, 1550). --define(wxCheckBox_Set3StateValue, 1551). --define(wxCheckBox_destroy, 1552). --define(wxCheckListBox_new_0, 1553). --define(wxCheckListBox_new_3, 1555). --define(wxCheckListBox_Check, 1556). --define(wxCheckListBox_IsChecked, 1557). --define(wxCheckListBox_destroy, 1558). --define(wxChoice_new_3, 1561). --define(wxChoice_new_0, 1562). --define(wxChoice_destruct, 1564). --define(wxChoice_Create, 1566). --define(wxChoice_Delete, 1567). --define(wxChoice_GetColumns, 1568). --define(wxChoice_SetColumns, 1569). --define(wxComboBox_new_0, 1570). --define(wxComboBox_new_3, 1572). --define(wxComboBox_destruct, 1573). --define(wxComboBox_Create, 1575). --define(wxComboBox_CanCopy, 1576). --define(wxComboBox_CanCut, 1577). --define(wxComboBox_CanPaste, 1578). --define(wxComboBox_CanRedo, 1579). --define(wxComboBox_CanUndo, 1580). --define(wxComboBox_Copy, 1581). --define(wxComboBox_Cut, 1582). --define(wxComboBox_GetInsertionPoint, 1583). --define(wxComboBox_GetLastPosition, 1584). --define(wxComboBox_GetValue, 1585). --define(wxComboBox_Paste, 1586). --define(wxComboBox_Redo, 1587). --define(wxComboBox_Replace, 1588). --define(wxComboBox_Remove, 1589). --define(wxComboBox_SetInsertionPoint, 1590). --define(wxComboBox_SetInsertionPointEnd, 1591). --define(wxComboBox_SetSelection_1, 1592). --define(wxComboBox_SetSelection_2, 1593). --define(wxComboBox_SetValue, 1594). --define(wxComboBox_Undo, 1595). --define(wxGauge_new_0, 1596). --define(wxGauge_new_4, 1597). --define(wxGauge_Create, 1598). --define(wxGauge_GetBezelFace, 1599). --define(wxGauge_GetRange, 1600). --define(wxGauge_GetShadowWidth, 1601). --define(wxGauge_GetValue, 1602). --define(wxGauge_IsVertical, 1603). --define(wxGauge_SetBezelFace, 1604). --define(wxGauge_SetRange, 1605). --define(wxGauge_SetShadowWidth, 1606). --define(wxGauge_SetValue, 1607). --define(wxGauge_Pulse, 1608). --define(wxGauge_destroy, 1609). --define(wxGenericDirCtrl_new_0, 1610). --define(wxGenericDirCtrl_new_2, 1611). --define(wxGenericDirCtrl_destruct, 1612). --define(wxGenericDirCtrl_Create, 1613). --define(wxGenericDirCtrl_Init, 1614). --define(wxGenericDirCtrl_CollapseTree, 1615). --define(wxGenericDirCtrl_ExpandPath, 1616). --define(wxGenericDirCtrl_GetDefaultPath, 1617). --define(wxGenericDirCtrl_GetPath, 1618). --define(wxGenericDirCtrl_GetFilePath, 1619). --define(wxGenericDirCtrl_GetFilter, 1620). --define(wxGenericDirCtrl_GetFilterIndex, 1621). --define(wxGenericDirCtrl_GetRootId, 1622). --define(wxGenericDirCtrl_GetTreeCtrl, 1623). --define(wxGenericDirCtrl_ReCreateTree, 1624). --define(wxGenericDirCtrl_SetDefaultPath, 1625). --define(wxGenericDirCtrl_SetFilter, 1626). --define(wxGenericDirCtrl_SetFilterIndex, 1627). --define(wxGenericDirCtrl_SetPath, 1628). --define(wxStaticBox_new_4, 1630). --define(wxStaticBox_new_0, 1631). --define(wxStaticBox_Create, 1632). --define(wxStaticBox_destroy, 1633). --define(wxStaticLine_new_2, 1635). --define(wxStaticLine_new_0, 1636). --define(wxStaticLine_Create, 1637). --define(wxStaticLine_IsVertical, 1638). --define(wxStaticLine_GetDefaultSize, 1639). --define(wxStaticLine_destroy, 1640). --define(wxListBox_new_3, 1643). --define(wxListBox_new_0, 1644). --define(wxListBox_destruct, 1646). --define(wxListBox_Create, 1648). --define(wxListBox_Deselect, 1649). --define(wxListBox_GetSelections, 1650). --define(wxListBox_InsertItems, 1651). --define(wxListBox_IsSelected, 1652). --define(wxListBox_Set, 1654). --define(wxListBox_HitTest, 1655). --define(wxListBox_SetFirstItem_1_0, 1656). --define(wxListBox_SetFirstItem_1_1, 1657). --define(wxListCtrl_new_0, 1658). --define(wxListCtrl_new_2, 1659). --define(wxListCtrl_Arrange, 1660). --define(wxListCtrl_AssignImageList, 1661). --define(wxListCtrl_ClearAll, 1662). --define(wxListCtrl_Create, 1663). --define(wxListCtrl_DeleteAllItems, 1664). --define(wxListCtrl_DeleteColumn, 1665). --define(wxListCtrl_DeleteItem, 1666). --define(wxListCtrl_EditLabel, 1667). --define(wxListCtrl_EnsureVisible, 1668). --define(wxListCtrl_FindItem_3_0, 1669). --define(wxListCtrl_FindItem_3_1, 1670). --define(wxListCtrl_GetColumn, 1671). --define(wxListCtrl_GetColumnCount, 1672). --define(wxListCtrl_GetColumnWidth, 1673). --define(wxListCtrl_GetCountPerPage, 1674). --define(wxListCtrl_GetEditControl, 1675). --define(wxListCtrl_GetImageList, 1676). --define(wxListCtrl_GetItem, 1677). --define(wxListCtrl_GetItemBackgroundColour, 1678). --define(wxListCtrl_GetItemCount, 1679). --define(wxListCtrl_GetItemData, 1680). --define(wxListCtrl_GetItemFont, 1681). --define(wxListCtrl_GetItemPosition, 1682). --define(wxListCtrl_GetItemRect, 1683). --define(wxListCtrl_GetItemSpacing, 1684). --define(wxListCtrl_GetItemState, 1685). --define(wxListCtrl_GetItemText, 1686). --define(wxListCtrl_GetItemTextColour, 1687). --define(wxListCtrl_GetNextItem, 1688). --define(wxListCtrl_GetSelectedItemCount, 1689). --define(wxListCtrl_GetTextColour, 1690). --define(wxListCtrl_GetTopItem, 1691). --define(wxListCtrl_GetViewRect, 1692). --define(wxListCtrl_HitTest, 1693). --define(wxListCtrl_InsertColumn_2, 1694). --define(wxListCtrl_InsertColumn_3, 1695). --define(wxListCtrl_InsertItem_1, 1696). --define(wxListCtrl_InsertItem_2_1, 1697). --define(wxListCtrl_InsertItem_2_0, 1698). --define(wxListCtrl_InsertItem_3, 1699). --define(wxListCtrl_RefreshItem, 1700). --define(wxListCtrl_RefreshItems, 1701). --define(wxListCtrl_ScrollList, 1702). --define(wxListCtrl_SetBackgroundColour, 1703). --define(wxListCtrl_SetColumn, 1704). --define(wxListCtrl_SetColumnWidth, 1705). --define(wxListCtrl_SetImageList, 1706). --define(wxListCtrl_SetItem_1, 1707). --define(wxListCtrl_SetItem_4, 1708). --define(wxListCtrl_SetItemBackgroundColour, 1709). --define(wxListCtrl_SetItemCount, 1710). --define(wxListCtrl_SetItemData, 1711). --define(wxListCtrl_SetItemFont, 1712). --define(wxListCtrl_SetItemImage, 1713). --define(wxListCtrl_SetItemColumnImage, 1714). --define(wxListCtrl_SetItemPosition, 1715). --define(wxListCtrl_SetItemState, 1716). --define(wxListCtrl_SetItemText, 1717). --define(wxListCtrl_SetItemTextColour, 1718). --define(wxListCtrl_SetSingleStyle, 1719). --define(wxListCtrl_SetTextColour, 1720). --define(wxListCtrl_SetWindowStyleFlag, 1721). --define(wxListCtrl_SortItems, 1722). --define(wxListCtrl_destroy, 1723). --define(wxListView_ClearColumnImage, 1724). --define(wxListView_Focus, 1725). --define(wxListView_GetFirstSelected, 1726). --define(wxListView_GetFocusedItem, 1727). --define(wxListView_GetNextSelected, 1728). --define(wxListView_IsSelected, 1729). --define(wxListView_Select, 1730). --define(wxListView_SetColumnImage, 1731). --define(wxListItem_new_0, 1732). --define(wxListItem_new_1, 1733). --define(wxListItem_destruct, 1734). --define(wxListItem_Clear, 1735). --define(wxListItem_GetAlign, 1736). --define(wxListItem_GetBackgroundColour, 1737). --define(wxListItem_GetColumn, 1738). --define(wxListItem_GetFont, 1739). --define(wxListItem_GetId, 1740). --define(wxListItem_GetImage, 1741). --define(wxListItem_GetMask, 1742). --define(wxListItem_GetState, 1743). --define(wxListItem_GetText, 1744). --define(wxListItem_GetTextColour, 1745). --define(wxListItem_GetWidth, 1746). --define(wxListItem_SetAlign, 1747). --define(wxListItem_SetBackgroundColour, 1748). --define(wxListItem_SetColumn, 1749). --define(wxListItem_SetFont, 1750). --define(wxListItem_SetId, 1751). --define(wxListItem_SetImage, 1752). --define(wxListItem_SetMask, 1753). --define(wxListItem_SetState, 1754). --define(wxListItem_SetStateMask, 1755). --define(wxListItem_SetText, 1756). --define(wxListItem_SetTextColour, 1757). --define(wxListItem_SetWidth, 1758). --define(wxImageList_new_0, 1759). --define(wxImageList_new_3, 1760). --define(wxImageList_Add_1, 1761). --define(wxImageList_Add_2_0, 1762). --define(wxImageList_Add_2_1, 1763). --define(wxImageList_Create, 1764). --define(wxImageList_Draw, 1766). --define(wxImageList_GetBitmap, 1767). --define(wxImageList_GetIcon, 1768). --define(wxImageList_GetImageCount, 1769). --define(wxImageList_GetSize, 1770). --define(wxImageList_Remove, 1771). --define(wxImageList_RemoveAll, 1772). --define(wxImageList_Replace_2, 1773). --define(wxImageList_Replace_3, 1774). --define(wxImageList_destroy, 1775). --define(wxTextAttr_new_0, 1776). --define(wxTextAttr_new_2, 1777). --define(wxTextAttr_GetAlignment, 1778). --define(wxTextAttr_GetBackgroundColour, 1779). --define(wxTextAttr_GetFont, 1780). --define(wxTextAttr_GetLeftIndent, 1781). --define(wxTextAttr_GetLeftSubIndent, 1782). --define(wxTextAttr_GetRightIndent, 1783). --define(wxTextAttr_GetTabs, 1784). --define(wxTextAttr_GetTextColour, 1785). --define(wxTextAttr_HasBackgroundColour, 1786). --define(wxTextAttr_HasFont, 1787). --define(wxTextAttr_HasTextColour, 1788). --define(wxTextAttr_GetFlags, 1789). --define(wxTextAttr_IsDefault, 1790). --define(wxTextAttr_SetAlignment, 1791). --define(wxTextAttr_SetBackgroundColour, 1792). --define(wxTextAttr_SetFlags, 1793). --define(wxTextAttr_SetFont, 1794). --define(wxTextAttr_SetLeftIndent, 1795). --define(wxTextAttr_SetRightIndent, 1796). --define(wxTextAttr_SetTabs, 1797). --define(wxTextAttr_SetTextColour, 1798). --define(wxTextAttr_destroy, 1799). --define(wxTextCtrl_new_3, 1801). --define(wxTextCtrl_new_0, 1802). --define(wxTextCtrl_destruct, 1804). --define(wxTextCtrl_AppendText, 1805). --define(wxTextCtrl_CanCopy, 1806). --define(wxTextCtrl_CanCut, 1807). --define(wxTextCtrl_CanPaste, 1808). --define(wxTextCtrl_CanRedo, 1809). --define(wxTextCtrl_CanUndo, 1810). --define(wxTextCtrl_Clear, 1811). --define(wxTextCtrl_Copy, 1812). --define(wxTextCtrl_Create, 1813). --define(wxTextCtrl_Cut, 1814). --define(wxTextCtrl_DiscardEdits, 1815). --define(wxTextCtrl_EmulateKeyPress, 1816). --define(wxTextCtrl_GetDefaultStyle, 1817). --define(wxTextCtrl_GetInsertionPoint, 1818). --define(wxTextCtrl_GetLastPosition, 1819). --define(wxTextCtrl_GetLineLength, 1820). --define(wxTextCtrl_GetLineText, 1821). --define(wxTextCtrl_GetNumberOfLines, 1822). --define(wxTextCtrl_GetRange, 1823). --define(wxTextCtrl_GetSelection, 1824). --define(wxTextCtrl_GetStringSelection, 1825). --define(wxTextCtrl_GetStyle, 1826). --define(wxTextCtrl_GetValue, 1827). --define(wxTextCtrl_IsEditable, 1828). --define(wxTextCtrl_IsModified, 1829). --define(wxTextCtrl_IsMultiLine, 1830). --define(wxTextCtrl_IsSingleLine, 1831). --define(wxTextCtrl_LoadFile, 1832). --define(wxTextCtrl_MarkDirty, 1833). --define(wxTextCtrl_Paste, 1834). --define(wxTextCtrl_PositionToXY, 1835). --define(wxTextCtrl_Redo, 1836). --define(wxTextCtrl_Remove, 1837). --define(wxTextCtrl_Replace, 1838). --define(wxTextCtrl_SaveFile, 1839). --define(wxTextCtrl_SetDefaultStyle, 1840). --define(wxTextCtrl_SetEditable, 1841). --define(wxTextCtrl_SetInsertionPoint, 1842). --define(wxTextCtrl_SetInsertionPointEnd, 1843). --define(wxTextCtrl_SetMaxLength, 1845). --define(wxTextCtrl_SetSelection, 1846). --define(wxTextCtrl_SetStyle, 1847). --define(wxTextCtrl_SetValue, 1848). --define(wxTextCtrl_ShowPosition, 1849). --define(wxTextCtrl_Undo, 1850). --define(wxTextCtrl_WriteText, 1851). --define(wxTextCtrl_XYToPosition, 1852). --define(wxNotebook_new_0, 1855). --define(wxNotebook_new_3, 1856). --define(wxNotebook_destruct, 1857). --define(wxNotebook_AddPage, 1858). --define(wxNotebook_AdvanceSelection, 1859). --define(wxNotebook_AssignImageList, 1860). --define(wxNotebook_Create, 1861). --define(wxNotebook_DeleteAllPages, 1862). --define(wxNotebook_DeletePage, 1863). --define(wxNotebook_RemovePage, 1864). --define(wxNotebook_GetCurrentPage, 1865). --define(wxNotebook_GetImageList, 1866). --define(wxNotebook_GetPage, 1868). --define(wxNotebook_GetPageCount, 1869). --define(wxNotebook_GetPageImage, 1870). --define(wxNotebook_GetPageText, 1871). --define(wxNotebook_GetRowCount, 1872). --define(wxNotebook_GetSelection, 1873). --define(wxNotebook_GetThemeBackgroundColour, 1874). --define(wxNotebook_HitTest, 1876). --define(wxNotebook_InsertPage, 1878). --define(wxNotebook_SetImageList, 1879). --define(wxNotebook_SetPadding, 1880). --define(wxNotebook_SetPageSize, 1881). --define(wxNotebook_SetPageImage, 1882). --define(wxNotebook_SetPageText, 1883). --define(wxNotebook_SetSelection, 1884). --define(wxNotebook_ChangeSelection, 1885). --define(wxChoicebook_new_0, 1886). --define(wxChoicebook_new_3, 1887). --define(wxChoicebook_AddPage, 1888). --define(wxChoicebook_AdvanceSelection, 1889). --define(wxChoicebook_AssignImageList, 1890). --define(wxChoicebook_Create, 1891). --define(wxChoicebook_DeleteAllPages, 1892). --define(wxChoicebook_DeletePage, 1893). --define(wxChoicebook_RemovePage, 1894). --define(wxChoicebook_GetCurrentPage, 1895). --define(wxChoicebook_GetImageList, 1896). --define(wxChoicebook_GetPage, 1898). --define(wxChoicebook_GetPageCount, 1899). --define(wxChoicebook_GetPageImage, 1900). --define(wxChoicebook_GetPageText, 1901). --define(wxChoicebook_GetSelection, 1902). --define(wxChoicebook_HitTest, 1903). --define(wxChoicebook_InsertPage, 1904). --define(wxChoicebook_SetImageList, 1905). --define(wxChoicebook_SetPageSize, 1906). --define(wxChoicebook_SetPageImage, 1907). --define(wxChoicebook_SetPageText, 1908). --define(wxChoicebook_SetSelection, 1909). --define(wxChoicebook_ChangeSelection, 1910). --define(wxChoicebook_destroy, 1911). --define(wxToolbook_new_0, 1912). --define(wxToolbook_new_3, 1913). --define(wxToolbook_AddPage, 1914). --define(wxToolbook_AdvanceSelection, 1915). --define(wxToolbook_AssignImageList, 1916). --define(wxToolbook_Create, 1917). --define(wxToolbook_DeleteAllPages, 1918). --define(wxToolbook_DeletePage, 1919). --define(wxToolbook_RemovePage, 1920). --define(wxToolbook_GetCurrentPage, 1921). --define(wxToolbook_GetImageList, 1922). --define(wxToolbook_GetPage, 1924). --define(wxToolbook_GetPageCount, 1925). --define(wxToolbook_GetPageImage, 1926). --define(wxToolbook_GetPageText, 1927). --define(wxToolbook_GetSelection, 1928). --define(wxToolbook_HitTest, 1930). --define(wxToolbook_InsertPage, 1931). --define(wxToolbook_SetImageList, 1932). --define(wxToolbook_SetPageSize, 1933). --define(wxToolbook_SetPageImage, 1934). --define(wxToolbook_SetPageText, 1935). --define(wxToolbook_SetSelection, 1936). --define(wxToolbook_ChangeSelection, 1937). --define(wxToolbook_destroy, 1938). --define(wxListbook_new_0, 1939). --define(wxListbook_new_3, 1940). --define(wxListbook_AddPage, 1941). --define(wxListbook_AdvanceSelection, 1942). --define(wxListbook_AssignImageList, 1943). --define(wxListbook_Create, 1944). --define(wxListbook_DeleteAllPages, 1945). --define(wxListbook_DeletePage, 1946). --define(wxListbook_RemovePage, 1947). --define(wxListbook_GetCurrentPage, 1948). --define(wxListbook_GetImageList, 1949). --define(wxListbook_GetPage, 1951). --define(wxListbook_GetPageCount, 1952). --define(wxListbook_GetPageImage, 1953). --define(wxListbook_GetPageText, 1954). --define(wxListbook_GetSelection, 1955). --define(wxListbook_HitTest, 1957). --define(wxListbook_InsertPage, 1958). --define(wxListbook_SetImageList, 1959). --define(wxListbook_SetPageSize, 1960). --define(wxListbook_SetPageImage, 1961). --define(wxListbook_SetPageText, 1962). --define(wxListbook_SetSelection, 1963). --define(wxListbook_ChangeSelection, 1964). --define(wxListbook_destroy, 1965). --define(wxTreebook_new_0, 1966). --define(wxTreebook_new_3, 1967). --define(wxTreebook_AddPage, 1968). --define(wxTreebook_AdvanceSelection, 1969). --define(wxTreebook_AssignImageList, 1970). --define(wxTreebook_Create, 1971). --define(wxTreebook_DeleteAllPages, 1972). --define(wxTreebook_DeletePage, 1973). --define(wxTreebook_RemovePage, 1974). --define(wxTreebook_GetCurrentPage, 1975). --define(wxTreebook_GetImageList, 1976). --define(wxTreebook_GetPage, 1978). --define(wxTreebook_GetPageCount, 1979). --define(wxTreebook_GetPageImage, 1980). --define(wxTreebook_GetPageText, 1981). --define(wxTreebook_GetSelection, 1982). --define(wxTreebook_ExpandNode, 1983). --define(wxTreebook_IsNodeExpanded, 1984). --define(wxTreebook_HitTest, 1986). --define(wxTreebook_InsertPage, 1987). --define(wxTreebook_InsertSubPage, 1988). --define(wxTreebook_SetImageList, 1989). --define(wxTreebook_SetPageSize, 1990). --define(wxTreebook_SetPageImage, 1991). --define(wxTreebook_SetPageText, 1992). --define(wxTreebook_SetSelection, 1993). --define(wxTreebook_ChangeSelection, 1994). --define(wxTreebook_destroy, 1995). --define(wxTreeCtrl_new_2, 1998). --define(wxTreeCtrl_new_0, 1999). --define(wxTreeCtrl_destruct, 2001). --define(wxTreeCtrl_AddRoot, 2002). --define(wxTreeCtrl_AppendItem, 2003). --define(wxTreeCtrl_AssignImageList, 2004). --define(wxTreeCtrl_AssignStateImageList, 2005). --define(wxTreeCtrl_Collapse, 2006). --define(wxTreeCtrl_CollapseAndReset, 2007). --define(wxTreeCtrl_Create, 2008). --define(wxTreeCtrl_Delete, 2009). --define(wxTreeCtrl_DeleteAllItems, 2010). --define(wxTreeCtrl_DeleteChildren, 2011). --define(wxTreeCtrl_EnsureVisible, 2012). --define(wxTreeCtrl_Expand, 2013). --define(wxTreeCtrl_GetBoundingRect, 2014). --define(wxTreeCtrl_GetChildrenCount, 2016). --define(wxTreeCtrl_GetCount, 2017). --define(wxTreeCtrl_GetEditControl, 2018). --define(wxTreeCtrl_GetFirstChild, 2019). --define(wxTreeCtrl_GetNextChild, 2020). --define(wxTreeCtrl_GetFirstVisibleItem, 2021). --define(wxTreeCtrl_GetImageList, 2022). --define(wxTreeCtrl_GetIndent, 2023). --define(wxTreeCtrl_GetItemBackgroundColour, 2024). --define(wxTreeCtrl_GetItemData, 2025). --define(wxTreeCtrl_GetItemFont, 2026). --define(wxTreeCtrl_GetItemImage_1, 2027). --define(wxTreeCtrl_GetItemImage_2, 2028). --define(wxTreeCtrl_GetItemText, 2029). --define(wxTreeCtrl_GetItemTextColour, 2030). --define(wxTreeCtrl_GetLastChild, 2031). --define(wxTreeCtrl_GetNextSibling, 2032). --define(wxTreeCtrl_GetNextVisible, 2033). --define(wxTreeCtrl_GetItemParent, 2034). --define(wxTreeCtrl_GetPrevSibling, 2035). --define(wxTreeCtrl_GetPrevVisible, 2036). --define(wxTreeCtrl_GetRootItem, 2037). --define(wxTreeCtrl_GetSelection, 2038). --define(wxTreeCtrl_GetSelections, 2039). --define(wxTreeCtrl_GetStateImageList, 2040). --define(wxTreeCtrl_HitTest, 2041). --define(wxTreeCtrl_InsertItem, 2043). --define(wxTreeCtrl_IsBold, 2044). --define(wxTreeCtrl_IsExpanded, 2045). --define(wxTreeCtrl_IsSelected, 2046). --define(wxTreeCtrl_IsVisible, 2047). --define(wxTreeCtrl_ItemHasChildren, 2048). --define(wxTreeCtrl_PrependItem, 2049). --define(wxTreeCtrl_ScrollTo, 2050). --define(wxTreeCtrl_SelectItem_1, 2051). --define(wxTreeCtrl_SelectItem_2, 2052). --define(wxTreeCtrl_SetIndent, 2053). --define(wxTreeCtrl_SetImageList, 2054). --define(wxTreeCtrl_SetItemBackgroundColour, 2055). --define(wxTreeCtrl_SetItemBold, 2056). --define(wxTreeCtrl_SetItemData, 2057). --define(wxTreeCtrl_SetItemDropHighlight, 2058). --define(wxTreeCtrl_SetItemFont, 2059). --define(wxTreeCtrl_SetItemHasChildren, 2060). --define(wxTreeCtrl_SetItemImage_2, 2061). --define(wxTreeCtrl_SetItemImage_3, 2062). --define(wxTreeCtrl_SetItemText, 2063). --define(wxTreeCtrl_SetItemTextColour, 2064). --define(wxTreeCtrl_SetStateImageList, 2065). --define(wxTreeCtrl_SetWindowStyle, 2066). --define(wxTreeCtrl_SortChildren, 2067). --define(wxTreeCtrl_Toggle, 2068). --define(wxTreeCtrl_ToggleItemSelection, 2069). --define(wxTreeCtrl_Unselect, 2070). --define(wxTreeCtrl_UnselectAll, 2071). --define(wxTreeCtrl_UnselectItem, 2072). --define(wxScrollBar_new_0, 2073). --define(wxScrollBar_new_3, 2074). --define(wxScrollBar_destruct, 2075). --define(wxScrollBar_Create, 2076). --define(wxScrollBar_GetRange, 2077). --define(wxScrollBar_GetPageSize, 2078). --define(wxScrollBar_GetThumbPosition, 2079). --define(wxScrollBar_GetThumbSize, 2080). --define(wxScrollBar_SetThumbPosition, 2081). --define(wxScrollBar_SetScrollbar, 2082). --define(wxSpinButton_new_2, 2084). --define(wxSpinButton_new_0, 2085). --define(wxSpinButton_Create, 2086). --define(wxSpinButton_GetMax, 2087). --define(wxSpinButton_GetMin, 2088). --define(wxSpinButton_GetValue, 2089). --define(wxSpinButton_SetRange, 2090). --define(wxSpinButton_SetValue, 2091). --define(wxSpinButton_destroy, 2092). --define(wxSpinCtrl_new_0, 2093). --define(wxSpinCtrl_new_2, 2094). --define(wxSpinCtrl_Create, 2096). --define(wxSpinCtrl_SetValue_1_1, 2099). --define(wxSpinCtrl_SetValue_1_0, 2100). --define(wxSpinCtrl_GetValue, 2102). --define(wxSpinCtrl_SetRange, 2104). --define(wxSpinCtrl_SetSelection, 2105). --define(wxSpinCtrl_GetMin, 2107). --define(wxSpinCtrl_GetMax, 2109). --define(wxSpinCtrl_destroy, 2110). --define(wxStaticText_new_0, 2111). --define(wxStaticText_new_4, 2112). --define(wxStaticText_Create, 2113). --define(wxStaticText_GetLabel, 2114). --define(wxStaticText_SetLabel, 2115). --define(wxStaticText_Wrap, 2116). --define(wxStaticText_destroy, 2117). --define(wxStaticBitmap_new_0, 2118). --define(wxStaticBitmap_new_4, 2119). --define(wxStaticBitmap_Create, 2120). --define(wxStaticBitmap_GetBitmap, 2121). --define(wxStaticBitmap_SetBitmap, 2122). --define(wxStaticBitmap_destroy, 2123). --define(wxRadioBox_new, 2124). --define(wxRadioBox_destruct, 2126). --define(wxRadioBox_Create, 2127). --define(wxRadioBox_Enable_2, 2128). --define(wxRadioBox_Enable_1, 2129). --define(wxRadioBox_GetSelection, 2130). --define(wxRadioBox_GetString, 2131). --define(wxRadioBox_SetSelection, 2132). --define(wxRadioBox_Show_2, 2133). --define(wxRadioBox_Show_1, 2134). --define(wxRadioBox_GetColumnCount, 2135). --define(wxRadioBox_GetItemHelpText, 2136). --define(wxRadioBox_GetItemToolTip, 2137). --define(wxRadioBox_GetItemFromPoint, 2139). --define(wxRadioBox_GetRowCount, 2140). --define(wxRadioBox_IsItemEnabled, 2141). --define(wxRadioBox_IsItemShown, 2142). --define(wxRadioBox_SetItemHelpText, 2143). --define(wxRadioBox_SetItemToolTip, 2144). --define(wxRadioButton_new_0, 2145). --define(wxRadioButton_new_4, 2146). --define(wxRadioButton_Create, 2147). --define(wxRadioButton_GetValue, 2148). --define(wxRadioButton_SetValue, 2149). --define(wxRadioButton_destroy, 2150). --define(wxSlider_new_6, 2152). --define(wxSlider_new_0, 2153). --define(wxSlider_Create, 2154). --define(wxSlider_GetLineSize, 2155). --define(wxSlider_GetMax, 2156). --define(wxSlider_GetMin, 2157). --define(wxSlider_GetPageSize, 2158). --define(wxSlider_GetThumbLength, 2159). --define(wxSlider_GetValue, 2160). --define(wxSlider_SetLineSize, 2161). --define(wxSlider_SetPageSize, 2162). --define(wxSlider_SetRange, 2163). --define(wxSlider_SetThumbLength, 2164). --define(wxSlider_SetValue, 2165). --define(wxSlider_destroy, 2166). --define(wxDialog_new_4, 2168). --define(wxDialog_new_0, 2169). --define(wxDialog_destruct, 2171). --define(wxDialog_Create, 2172). --define(wxDialog_CreateButtonSizer, 2173). --define(wxDialog_CreateStdDialogButtonSizer, 2174). --define(wxDialog_EndModal, 2175). --define(wxDialog_GetAffirmativeId, 2176). --define(wxDialog_GetReturnCode, 2177). --define(wxDialog_IsModal, 2178). --define(wxDialog_SetAffirmativeId, 2179). --define(wxDialog_SetReturnCode, 2180). --define(wxDialog_Show, 2181). --define(wxDialog_ShowModal, 2182). --define(wxColourDialog_new_0, 2183). --define(wxColourDialog_new_2, 2184). --define(wxColourDialog_destruct, 2185). --define(wxColourDialog_Create, 2186). --define(wxColourDialog_GetColourData, 2187). --define(wxColourData_new_0, 2188). --define(wxColourData_new_1, 2189). --define(wxColourData_destruct, 2190). --define(wxColourData_GetChooseFull, 2191). --define(wxColourData_GetColour, 2192). --define(wxColourData_GetCustomColour, 2194). --define(wxColourData_SetChooseFull, 2195). --define(wxColourData_SetColour, 2196). --define(wxColourData_SetCustomColour, 2197). --define(wxPalette_new_0, 2198). --define(wxPalette_new_4, 2199). --define(wxPalette_destruct, 2201). --define(wxPalette_Create, 2202). --define(wxPalette_GetColoursCount, 2203). --define(wxPalette_GetPixel, 2204). --define(wxPalette_GetRGB, 2205). --define(wxPalette_IsOk, 2206). --define(wxDirDialog_new, 2210). --define(wxDirDialog_destruct, 2211). --define(wxDirDialog_GetPath, 2212). --define(wxDirDialog_GetMessage, 2213). --define(wxDirDialog_SetMessage, 2214). --define(wxDirDialog_SetPath, 2215). --define(wxFileDialog_new, 2219). --define(wxFileDialog_destruct, 2220). --define(wxFileDialog_GetDirectory, 2221). --define(wxFileDialog_GetFilename, 2222). --define(wxFileDialog_GetFilenames, 2223). --define(wxFileDialog_GetFilterIndex, 2224). --define(wxFileDialog_GetMessage, 2225). --define(wxFileDialog_GetPath, 2226). --define(wxFileDialog_GetPaths, 2227). --define(wxFileDialog_GetWildcard, 2228). --define(wxFileDialog_SetDirectory, 2229). --define(wxFileDialog_SetFilename, 2230). --define(wxFileDialog_SetFilterIndex, 2231). --define(wxFileDialog_SetMessage, 2232). --define(wxFileDialog_SetPath, 2233). --define(wxFileDialog_SetWildcard, 2234). --define(wxPickerBase_SetInternalMargin, 2235). --define(wxPickerBase_GetInternalMargin, 2236). --define(wxPickerBase_SetTextCtrlProportion, 2237). --define(wxPickerBase_SetPickerCtrlProportion, 2238). --define(wxPickerBase_GetTextCtrlProportion, 2239). --define(wxPickerBase_GetPickerCtrlProportion, 2240). --define(wxPickerBase_HasTextCtrl, 2241). --define(wxPickerBase_GetTextCtrl, 2242). --define(wxPickerBase_IsTextCtrlGrowable, 2243). --define(wxPickerBase_SetPickerCtrlGrowable, 2244). --define(wxPickerBase_SetTextCtrlGrowable, 2245). --define(wxPickerBase_IsPickerCtrlGrowable, 2246). --define(wxFilePickerCtrl_new_0, 2247). --define(wxFilePickerCtrl_new_3, 2248). --define(wxFilePickerCtrl_Create, 2249). --define(wxFilePickerCtrl_GetPath, 2250). --define(wxFilePickerCtrl_SetPath, 2251). --define(wxFilePickerCtrl_destroy, 2252). --define(wxDirPickerCtrl_new_0, 2253). --define(wxDirPickerCtrl_new_3, 2254). --define(wxDirPickerCtrl_Create, 2255). --define(wxDirPickerCtrl_GetPath, 2256). --define(wxDirPickerCtrl_SetPath, 2257). --define(wxDirPickerCtrl_destroy, 2258). --define(wxColourPickerCtrl_new_0, 2259). --define(wxColourPickerCtrl_new_3, 2260). --define(wxColourPickerCtrl_Create, 2261). --define(wxColourPickerCtrl_GetColour, 2262). --define(wxColourPickerCtrl_SetColour_1_1, 2263). --define(wxColourPickerCtrl_SetColour_1_0, 2264). --define(wxColourPickerCtrl_destroy, 2265). --define(wxDatePickerCtrl_new_0, 2266). --define(wxDatePickerCtrl_new_3, 2267). --define(wxDatePickerCtrl_GetRange, 2268). --define(wxDatePickerCtrl_GetValue, 2269). --define(wxDatePickerCtrl_SetRange, 2270). --define(wxDatePickerCtrl_SetValue, 2271). --define(wxDatePickerCtrl_destroy, 2272). --define(wxFontPickerCtrl_new_0, 2273). --define(wxFontPickerCtrl_new_3, 2274). --define(wxFontPickerCtrl_Create, 2275). --define(wxFontPickerCtrl_GetSelectedFont, 2276). --define(wxFontPickerCtrl_SetSelectedFont, 2277). --define(wxFontPickerCtrl_GetMaxPointSize, 2278). --define(wxFontPickerCtrl_SetMaxPointSize, 2279). --define(wxFontPickerCtrl_destroy, 2280). --define(wxFindReplaceDialog_new_0, 2283). --define(wxFindReplaceDialog_new_4, 2284). --define(wxFindReplaceDialog_destruct, 2285). --define(wxFindReplaceDialog_Create, 2286). --define(wxFindReplaceDialog_GetData, 2287). --define(wxFindReplaceData_new_0, 2288). --define(wxFindReplaceData_new_1, 2289). --define(wxFindReplaceData_GetFindString, 2290). --define(wxFindReplaceData_GetReplaceString, 2291). --define(wxFindReplaceData_GetFlags, 2292). --define(wxFindReplaceData_SetFlags, 2293). --define(wxFindReplaceData_SetFindString, 2294). --define(wxFindReplaceData_SetReplaceString, 2295). --define(wxFindReplaceData_destroy, 2296). --define(wxMultiChoiceDialog_new_0, 2297). --define(wxMultiChoiceDialog_new_5, 2299). --define(wxMultiChoiceDialog_GetSelections, 2300). --define(wxMultiChoiceDialog_SetSelections, 2301). --define(wxMultiChoiceDialog_destroy, 2302). --define(wxSingleChoiceDialog_new_0, 2303). --define(wxSingleChoiceDialog_new_5, 2305). --define(wxSingleChoiceDialog_GetSelection, 2306). --define(wxSingleChoiceDialog_GetStringSelection, 2307). --define(wxSingleChoiceDialog_SetSelection, 2308). --define(wxSingleChoiceDialog_destroy, 2309). --define(wxTextEntryDialog_new, 2310). --define(wxTextEntryDialog_GetValue, 2311). --define(wxTextEntryDialog_SetValue, 2312). --define(wxTextEntryDialog_destroy, 2313). --define(wxPasswordEntryDialog_new, 2314). --define(wxPasswordEntryDialog_destroy, 2315). --define(wxFontData_new_0, 2316). --define(wxFontData_new_1, 2317). --define(wxFontData_destruct, 2318). --define(wxFontData_EnableEffects, 2319). --define(wxFontData_GetAllowSymbols, 2320). --define(wxFontData_GetColour, 2321). --define(wxFontData_GetChosenFont, 2322). --define(wxFontData_GetEnableEffects, 2323). --define(wxFontData_GetInitialFont, 2324). --define(wxFontData_GetShowHelp, 2325). --define(wxFontData_SetAllowSymbols, 2326). --define(wxFontData_SetChosenFont, 2327). --define(wxFontData_SetColour, 2328). --define(wxFontData_SetInitialFont, 2329). --define(wxFontData_SetRange, 2330). --define(wxFontData_SetShowHelp, 2331). --define(wxFontDialog_new_0, 2335). --define(wxFontDialog_new_2, 2337). --define(wxFontDialog_Create, 2339). --define(wxFontDialog_GetFontData, 2340). --define(wxFontDialog_destroy, 2342). --define(wxProgressDialog_new, 2343). --define(wxProgressDialog_destruct, 2344). --define(wxProgressDialog_Resume, 2345). --define(wxProgressDialog_Update_2, 2346). --define(wxProgressDialog_Update_0, 2347). --define(wxMessageDialog_new, 2348). --define(wxMessageDialog_destruct, 2349). --define(wxPageSetupDialog_new, 2350). --define(wxPageSetupDialog_destruct, 2351). --define(wxPageSetupDialog_GetPageSetupData, 2352). --define(wxPageSetupDialog_ShowModal, 2353). --define(wxPageSetupDialogData_new_0, 2354). --define(wxPageSetupDialogData_new_1_0, 2355). --define(wxPageSetupDialogData_new_1_1, 2356). --define(wxPageSetupDialogData_destruct, 2357). --define(wxPageSetupDialogData_EnableHelp, 2358). --define(wxPageSetupDialogData_EnableMargins, 2359). --define(wxPageSetupDialogData_EnableOrientation, 2360). --define(wxPageSetupDialogData_EnablePaper, 2361). --define(wxPageSetupDialogData_EnablePrinter, 2362). --define(wxPageSetupDialogData_GetDefaultMinMargins, 2363). --define(wxPageSetupDialogData_GetEnableMargins, 2364). --define(wxPageSetupDialogData_GetEnableOrientation, 2365). --define(wxPageSetupDialogData_GetEnablePaper, 2366). --define(wxPageSetupDialogData_GetEnablePrinter, 2367). --define(wxPageSetupDialogData_GetEnableHelp, 2368). --define(wxPageSetupDialogData_GetDefaultInfo, 2369). --define(wxPageSetupDialogData_GetMarginTopLeft, 2370). --define(wxPageSetupDialogData_GetMarginBottomRight, 2371). --define(wxPageSetupDialogData_GetMinMarginTopLeft, 2372). --define(wxPageSetupDialogData_GetMinMarginBottomRight, 2373). --define(wxPageSetupDialogData_GetPaperId, 2374). --define(wxPageSetupDialogData_GetPaperSize, 2375). --define(wxPageSetupDialogData_GetPrintData, 2377). --define(wxPageSetupDialogData_IsOk, 2378). --define(wxPageSetupDialogData_SetDefaultInfo, 2379). --define(wxPageSetupDialogData_SetDefaultMinMargins, 2380). --define(wxPageSetupDialogData_SetMarginTopLeft, 2381). --define(wxPageSetupDialogData_SetMarginBottomRight, 2382). --define(wxPageSetupDialogData_SetMinMarginTopLeft, 2383). --define(wxPageSetupDialogData_SetMinMarginBottomRight, 2384). --define(wxPageSetupDialogData_SetPaperId, 2385). --define(wxPageSetupDialogData_SetPaperSize_1_1, 2386). --define(wxPageSetupDialogData_SetPaperSize_1_0, 2387). --define(wxPageSetupDialogData_SetPrintData, 2388). --define(wxPrintDialog_new_2_0, 2389). --define(wxPrintDialog_new_2_1, 2390). --define(wxPrintDialog_destruct, 2391). --define(wxPrintDialog_GetPrintDialogData, 2392). --define(wxPrintDialog_GetPrintDC, 2393). --define(wxPrintDialogData_new_0, 2394). --define(wxPrintDialogData_new_1_1, 2395). --define(wxPrintDialogData_new_1_0, 2396). --define(wxPrintDialogData_destruct, 2397). --define(wxPrintDialogData_EnableHelp, 2398). --define(wxPrintDialogData_EnablePageNumbers, 2399). --define(wxPrintDialogData_EnablePrintToFile, 2400). --define(wxPrintDialogData_EnableSelection, 2401). --define(wxPrintDialogData_GetAllPages, 2402). --define(wxPrintDialogData_GetCollate, 2403). --define(wxPrintDialogData_GetFromPage, 2404). --define(wxPrintDialogData_GetMaxPage, 2405). --define(wxPrintDialogData_GetMinPage, 2406). --define(wxPrintDialogData_GetNoCopies, 2407). --define(wxPrintDialogData_GetPrintData, 2408). --define(wxPrintDialogData_GetPrintToFile, 2409). --define(wxPrintDialogData_GetSelection, 2410). --define(wxPrintDialogData_GetToPage, 2411). --define(wxPrintDialogData_IsOk, 2412). --define(wxPrintDialogData_SetCollate, 2413). --define(wxPrintDialogData_SetFromPage, 2414). --define(wxPrintDialogData_SetMaxPage, 2415). --define(wxPrintDialogData_SetMinPage, 2416). --define(wxPrintDialogData_SetNoCopies, 2417). --define(wxPrintDialogData_SetPrintData, 2418). --define(wxPrintDialogData_SetPrintToFile, 2419). --define(wxPrintDialogData_SetSelection, 2420). --define(wxPrintDialogData_SetToPage, 2421). --define(wxPrintData_new_0, 2422). --define(wxPrintData_new_1, 2423). --define(wxPrintData_destruct, 2424). --define(wxPrintData_GetCollate, 2425). --define(wxPrintData_GetBin, 2426). --define(wxPrintData_GetColour, 2427). --define(wxPrintData_GetDuplex, 2428). --define(wxPrintData_GetNoCopies, 2429). --define(wxPrintData_GetOrientation, 2430). --define(wxPrintData_GetPaperId, 2431). --define(wxPrintData_GetPrinterName, 2432). --define(wxPrintData_GetQuality, 2433). --define(wxPrintData_IsOk, 2434). --define(wxPrintData_SetBin, 2435). --define(wxPrintData_SetCollate, 2436). --define(wxPrintData_SetColour, 2437). --define(wxPrintData_SetDuplex, 2438). --define(wxPrintData_SetNoCopies, 2439). --define(wxPrintData_SetOrientation, 2440). --define(wxPrintData_SetPaperId, 2441). --define(wxPrintData_SetPrinterName, 2442). --define(wxPrintData_SetQuality, 2443). --define(wxPrintPreview_new_2, 2446). --define(wxPrintPreview_new_3, 2447). --define(wxPrintPreview_destruct, 2449). --define(wxPrintPreview_GetCanvas, 2450). --define(wxPrintPreview_GetCurrentPage, 2451). --define(wxPrintPreview_GetFrame, 2452). --define(wxPrintPreview_GetMaxPage, 2453). --define(wxPrintPreview_GetMinPage, 2454). --define(wxPrintPreview_GetPrintout, 2455). --define(wxPrintPreview_GetPrintoutForPrinting, 2456). --define(wxPrintPreview_IsOk, 2457). --define(wxPrintPreview_PaintPage, 2458). --define(wxPrintPreview_Print, 2459). --define(wxPrintPreview_RenderPage, 2460). --define(wxPrintPreview_SetCanvas, 2461). --define(wxPrintPreview_SetCurrentPage, 2462). --define(wxPrintPreview_SetFrame, 2463). --define(wxPrintPreview_SetPrintout, 2464). --define(wxPrintPreview_SetZoom, 2465). --define(wxPreviewFrame_new, 2466). --define(wxPreviewFrame_destruct, 2467). --define(wxPreviewFrame_CreateControlBar, 2468). --define(wxPreviewFrame_CreateCanvas, 2469). --define(wxPreviewFrame_Initialize, 2470). --define(wxPreviewFrame_OnCloseWindow, 2471). --define(wxPreviewControlBar_new, 2472). --define(wxPreviewControlBar_destruct, 2473). --define(wxPreviewControlBar_CreateButtons, 2474). --define(wxPreviewControlBar_GetPrintPreview, 2475). --define(wxPreviewControlBar_GetZoomControl, 2476). --define(wxPreviewControlBar_SetZoomControl, 2477). --define(wxPrinter_new, 2479). --define(wxPrinter_CreateAbortWindow, 2480). --define(wxPrinter_GetAbort, 2481). --define(wxPrinter_GetLastError, 2482). --define(wxPrinter_GetPrintDialogData, 2483). --define(wxPrinter_Print, 2484). --define(wxPrinter_PrintDialog, 2485). --define(wxPrinter_ReportError, 2486). --define(wxPrinter_Setup, 2487). --define(wxPrinter_destroy, 2488). --define(wxXmlResource_new_1, 2489). --define(wxXmlResource_new_2, 2490). --define(wxXmlResource_destruct, 2491). --define(wxXmlResource_AttachUnknownControl, 2492). --define(wxXmlResource_ClearHandlers, 2493). --define(wxXmlResource_CompareVersion, 2494). --define(wxXmlResource_Get, 2495). --define(wxXmlResource_GetFlags, 2496). --define(wxXmlResource_GetVersion, 2497). --define(wxXmlResource_GetXRCID, 2498). --define(wxXmlResource_InitAllHandlers, 2499). --define(wxXmlResource_Load, 2500). --define(wxXmlResource_LoadBitmap, 2501). --define(wxXmlResource_LoadDialog_2, 2502). --define(wxXmlResource_LoadDialog_3, 2503). --define(wxXmlResource_LoadFrame_2, 2504). --define(wxXmlResource_LoadFrame_3, 2505). --define(wxXmlResource_LoadIcon, 2506). --define(wxXmlResource_LoadMenu, 2507). --define(wxXmlResource_LoadMenuBar_2, 2508). --define(wxXmlResource_LoadMenuBar_1, 2509). --define(wxXmlResource_LoadPanel_2, 2510). --define(wxXmlResource_LoadPanel_3, 2511). --define(wxXmlResource_LoadToolBar, 2512). --define(wxXmlResource_Set, 2513). --define(wxXmlResource_SetFlags, 2514). --define(wxXmlResource_Unload, 2515). --define(wxXmlResource_xrcctrl, 2516). --define(wxHtmlEasyPrinting_new, 2517). --define(wxHtmlEasyPrinting_destruct, 2518). --define(wxHtmlEasyPrinting_GetPrintData, 2519). --define(wxHtmlEasyPrinting_GetPageSetupData, 2520). --define(wxHtmlEasyPrinting_PreviewFile, 2521). --define(wxHtmlEasyPrinting_PreviewText, 2522). --define(wxHtmlEasyPrinting_PrintFile, 2523). --define(wxHtmlEasyPrinting_PrintText, 2524). --define(wxHtmlEasyPrinting_PageSetup, 2525). --define(wxHtmlEasyPrinting_SetFonts, 2526). --define(wxHtmlEasyPrinting_SetHeader, 2527). --define(wxHtmlEasyPrinting_SetFooter, 2528). --define(wxGLCanvas_new_2, 2530). --define(wxGLCanvas_new_3_1, 2531). --define(wxGLCanvas_new_3_0, 2532). --define(wxGLCanvas_GetContext, 2533). --define(wxGLCanvas_SetCurrent, 2535). --define(wxGLCanvas_SwapBuffers, 2536). --define(wxGLCanvas_destroy, 2537). --define(wxAuiManager_new, 2538). --define(wxAuiManager_destruct, 2539). --define(wxAuiManager_AddPane_2_1, 2540). --define(wxAuiManager_AddPane_3, 2541). --define(wxAuiManager_AddPane_2_0, 2542). --define(wxAuiManager_DetachPane, 2543). --define(wxAuiManager_GetAllPanes, 2544). --define(wxAuiManager_GetArtProvider, 2545). --define(wxAuiManager_GetDockSizeConstraint, 2546). --define(wxAuiManager_GetFlags, 2547). --define(wxAuiManager_GetManagedWindow, 2548). --define(wxAuiManager_GetManager, 2549). --define(wxAuiManager_GetPane_1_1, 2550). --define(wxAuiManager_GetPane_1_0, 2551). --define(wxAuiManager_HideHint, 2552). --define(wxAuiManager_InsertPane, 2553). --define(wxAuiManager_LoadPaneInfo, 2554). --define(wxAuiManager_LoadPerspective, 2555). --define(wxAuiManager_SavePaneInfo, 2556). --define(wxAuiManager_SavePerspective, 2557). --define(wxAuiManager_SetArtProvider, 2558). --define(wxAuiManager_SetDockSizeConstraint, 2559). --define(wxAuiManager_SetFlags, 2560). --define(wxAuiManager_SetManagedWindow, 2561). --define(wxAuiManager_ShowHint, 2562). --define(wxAuiManager_UnInit, 2563). --define(wxAuiManager_Update, 2564). --define(wxAuiPaneInfo_new_0, 2565). --define(wxAuiPaneInfo_new_1, 2566). --define(wxAuiPaneInfo_destruct, 2567). --define(wxAuiPaneInfo_BestSize_1, 2568). --define(wxAuiPaneInfo_BestSize_2, 2569). --define(wxAuiPaneInfo_Bottom, 2570). --define(wxAuiPaneInfo_BottomDockable, 2571). --define(wxAuiPaneInfo_Caption, 2572). --define(wxAuiPaneInfo_CaptionVisible, 2573). --define(wxAuiPaneInfo_Centre, 2574). --define(wxAuiPaneInfo_CentrePane, 2575). --define(wxAuiPaneInfo_CloseButton, 2576). --define(wxAuiPaneInfo_DefaultPane, 2577). --define(wxAuiPaneInfo_DestroyOnClose, 2578). --define(wxAuiPaneInfo_Direction, 2579). --define(wxAuiPaneInfo_Dock, 2580). --define(wxAuiPaneInfo_Dockable, 2581). --define(wxAuiPaneInfo_Fixed, 2582). --define(wxAuiPaneInfo_Float, 2583). --define(wxAuiPaneInfo_Floatable, 2584). --define(wxAuiPaneInfo_FloatingPosition_1, 2585). --define(wxAuiPaneInfo_FloatingPosition_2, 2586). --define(wxAuiPaneInfo_FloatingSize_1, 2587). --define(wxAuiPaneInfo_FloatingSize_2, 2588). --define(wxAuiPaneInfo_Gripper, 2589). --define(wxAuiPaneInfo_GripperTop, 2590). --define(wxAuiPaneInfo_HasBorder, 2591). --define(wxAuiPaneInfo_HasCaption, 2592). --define(wxAuiPaneInfo_HasCloseButton, 2593). --define(wxAuiPaneInfo_HasFlag, 2594). --define(wxAuiPaneInfo_HasGripper, 2595). --define(wxAuiPaneInfo_HasGripperTop, 2596). --define(wxAuiPaneInfo_HasMaximizeButton, 2597). --define(wxAuiPaneInfo_HasMinimizeButton, 2598). --define(wxAuiPaneInfo_HasPinButton, 2599). --define(wxAuiPaneInfo_Hide, 2600). --define(wxAuiPaneInfo_IsBottomDockable, 2601). --define(wxAuiPaneInfo_IsDocked, 2602). --define(wxAuiPaneInfo_IsFixed, 2603). --define(wxAuiPaneInfo_IsFloatable, 2604). --define(wxAuiPaneInfo_IsFloating, 2605). --define(wxAuiPaneInfo_IsLeftDockable, 2606). --define(wxAuiPaneInfo_IsMovable, 2607). --define(wxAuiPaneInfo_IsOk, 2608). --define(wxAuiPaneInfo_IsResizable, 2609). --define(wxAuiPaneInfo_IsRightDockable, 2610). --define(wxAuiPaneInfo_IsShown, 2611). --define(wxAuiPaneInfo_IsToolbar, 2612). --define(wxAuiPaneInfo_IsTopDockable, 2613). --define(wxAuiPaneInfo_Layer, 2614). --define(wxAuiPaneInfo_Left, 2615). --define(wxAuiPaneInfo_LeftDockable, 2616). --define(wxAuiPaneInfo_MaxSize_1, 2617). --define(wxAuiPaneInfo_MaxSize_2, 2618). --define(wxAuiPaneInfo_MaximizeButton, 2619). --define(wxAuiPaneInfo_MinSize_1, 2620). --define(wxAuiPaneInfo_MinSize_2, 2621). --define(wxAuiPaneInfo_MinimizeButton, 2622). --define(wxAuiPaneInfo_Movable, 2623). --define(wxAuiPaneInfo_Name, 2624). --define(wxAuiPaneInfo_PaneBorder, 2625). --define(wxAuiPaneInfo_PinButton, 2626). --define(wxAuiPaneInfo_Position, 2627). --define(wxAuiPaneInfo_Resizable, 2628). --define(wxAuiPaneInfo_Right, 2629). --define(wxAuiPaneInfo_RightDockable, 2630). --define(wxAuiPaneInfo_Row, 2631). --define(wxAuiPaneInfo_SafeSet, 2632). --define(wxAuiPaneInfo_SetFlag, 2633). --define(wxAuiPaneInfo_Show, 2634). --define(wxAuiPaneInfo_ToolbarPane, 2635). --define(wxAuiPaneInfo_Top, 2636). --define(wxAuiPaneInfo_TopDockable, 2637). --define(wxAuiPaneInfo_Window, 2638). --define(wxAuiNotebook_new_0, 2639). --define(wxAuiNotebook_new_2, 2640). --define(wxAuiNotebook_AddPage, 2641). --define(wxAuiNotebook_Create, 2642). --define(wxAuiNotebook_DeletePage, 2643). --define(wxAuiNotebook_GetArtProvider, 2644). --define(wxAuiNotebook_GetPage, 2645). --define(wxAuiNotebook_GetPageBitmap, 2646). --define(wxAuiNotebook_GetPageCount, 2647). --define(wxAuiNotebook_GetPageIndex, 2648). --define(wxAuiNotebook_GetPageText, 2649). --define(wxAuiNotebook_GetSelection, 2650). --define(wxAuiNotebook_InsertPage, 2651). --define(wxAuiNotebook_RemovePage, 2652). --define(wxAuiNotebook_SetArtProvider, 2653). --define(wxAuiNotebook_SetFont, 2654). --define(wxAuiNotebook_SetPageBitmap, 2655). --define(wxAuiNotebook_SetPageText, 2656). --define(wxAuiNotebook_SetSelection, 2657). --define(wxAuiNotebook_SetTabCtrlHeight, 2658). --define(wxAuiNotebook_SetUniformBitmapSize, 2659). --define(wxAuiNotebook_destroy, 2660). --define(wxMDIParentFrame_new_0, 2661). --define(wxMDIParentFrame_new_4, 2662). --define(wxMDIParentFrame_destruct, 2663). --define(wxMDIParentFrame_ActivateNext, 2664). --define(wxMDIParentFrame_ActivatePrevious, 2665). --define(wxMDIParentFrame_ArrangeIcons, 2666). --define(wxMDIParentFrame_Cascade, 2667). --define(wxMDIParentFrame_Create, 2668). --define(wxMDIParentFrame_GetActiveChild, 2669). --define(wxMDIParentFrame_GetClientWindow, 2670). --define(wxMDIParentFrame_Tile, 2671). --define(wxMDIChildFrame_new_0, 2672). --define(wxMDIChildFrame_new_4, 2673). --define(wxMDIChildFrame_destruct, 2674). --define(wxMDIChildFrame_Activate, 2675). --define(wxMDIChildFrame_Create, 2676). --define(wxMDIChildFrame_Maximize, 2677). --define(wxMDIChildFrame_Restore, 2678). --define(wxMDIClientWindow_new_0, 2679). --define(wxMDIClientWindow_new_2, 2680). --define(wxMDIClientWindow_destruct, 2681). --define(wxMDIClientWindow_CreateClient, 2682). --define(wxLayoutAlgorithm_new, 2683). --define(wxLayoutAlgorithm_LayoutFrame, 2684). --define(wxLayoutAlgorithm_LayoutMDIFrame, 2685). --define(wxLayoutAlgorithm_LayoutWindow, 2686). --define(wxLayoutAlgorithm_destroy, 2687). --define(wxEvent_GetId, 2688). --define(wxEvent_GetSkipped, 2689). --define(wxEvent_GetTimestamp, 2690). --define(wxEvent_IsCommandEvent, 2691). --define(wxEvent_ResumePropagation, 2692). --define(wxEvent_ShouldPropagate, 2693). --define(wxEvent_Skip, 2694). --define(wxEvent_StopPropagation, 2695). --define(wxCommandEvent_getClientData, 2696). --define(wxCommandEvent_GetExtraLong, 2697). --define(wxCommandEvent_GetInt, 2698). --define(wxCommandEvent_GetSelection, 2699). --define(wxCommandEvent_GetString, 2700). --define(wxCommandEvent_IsChecked, 2701). --define(wxCommandEvent_IsSelection, 2702). --define(wxCommandEvent_SetInt, 2703). --define(wxCommandEvent_SetString, 2704). --define(wxScrollEvent_GetOrientation, 2705). --define(wxScrollEvent_GetPosition, 2706). --define(wxScrollWinEvent_GetOrientation, 2707). --define(wxScrollWinEvent_GetPosition, 2708). --define(wxMouseEvent_AltDown, 2709). --define(wxMouseEvent_Button, 2710). --define(wxMouseEvent_ButtonDClick, 2711). --define(wxMouseEvent_ButtonDown, 2712). --define(wxMouseEvent_ButtonUp, 2713). --define(wxMouseEvent_CmdDown, 2714). --define(wxMouseEvent_ControlDown, 2715). --define(wxMouseEvent_Dragging, 2716). --define(wxMouseEvent_Entering, 2717). --define(wxMouseEvent_GetButton, 2718). --define(wxMouseEvent_GetPosition, 2721). --define(wxMouseEvent_GetLogicalPosition, 2722). --define(wxMouseEvent_GetLinesPerAction, 2723). --define(wxMouseEvent_GetWheelRotation, 2724). --define(wxMouseEvent_GetWheelDelta, 2725). --define(wxMouseEvent_GetX, 2726). --define(wxMouseEvent_GetY, 2727). --define(wxMouseEvent_IsButton, 2728). --define(wxMouseEvent_IsPageScroll, 2729). --define(wxMouseEvent_Leaving, 2730). --define(wxMouseEvent_LeftDClick, 2731). --define(wxMouseEvent_LeftDown, 2732). --define(wxMouseEvent_LeftIsDown, 2733). --define(wxMouseEvent_LeftUp, 2734). --define(wxMouseEvent_MetaDown, 2735). --define(wxMouseEvent_MiddleDClick, 2736). --define(wxMouseEvent_MiddleDown, 2737). --define(wxMouseEvent_MiddleIsDown, 2738). --define(wxMouseEvent_MiddleUp, 2739). --define(wxMouseEvent_Moving, 2740). --define(wxMouseEvent_RightDClick, 2741). --define(wxMouseEvent_RightDown, 2742). --define(wxMouseEvent_RightIsDown, 2743). --define(wxMouseEvent_RightUp, 2744). --define(wxMouseEvent_ShiftDown, 2745). --define(wxSetCursorEvent_GetCursor, 2746). --define(wxSetCursorEvent_GetX, 2747). --define(wxSetCursorEvent_GetY, 2748). --define(wxSetCursorEvent_HasCursor, 2749). --define(wxSetCursorEvent_SetCursor, 2750). --define(wxKeyEvent_AltDown, 2751). --define(wxKeyEvent_CmdDown, 2752). --define(wxKeyEvent_ControlDown, 2753). --define(wxKeyEvent_GetKeyCode, 2754). --define(wxKeyEvent_GetModifiers, 2755). --define(wxKeyEvent_GetPosition, 2758). --define(wxKeyEvent_GetRawKeyCode, 2759). --define(wxKeyEvent_GetRawKeyFlags, 2760). --define(wxKeyEvent_GetUnicodeKey, 2761). --define(wxKeyEvent_GetX, 2762). --define(wxKeyEvent_GetY, 2763). --define(wxKeyEvent_HasModifiers, 2764). --define(wxKeyEvent_MetaDown, 2765). --define(wxKeyEvent_ShiftDown, 2766). --define(wxSizeEvent_GetSize, 2767). --define(wxMoveEvent_GetPosition, 2768). --define(wxEraseEvent_GetDC, 2769). --define(wxFocusEvent_GetWindow, 2770). --define(wxChildFocusEvent_GetWindow, 2771). --define(wxMenuEvent_GetMenu, 2772). --define(wxMenuEvent_GetMenuId, 2773). --define(wxMenuEvent_IsPopup, 2774). --define(wxCloseEvent_CanVeto, 2775). --define(wxCloseEvent_GetLoggingOff, 2776). --define(wxCloseEvent_SetCanVeto, 2777). --define(wxCloseEvent_SetLoggingOff, 2778). --define(wxCloseEvent_Veto, 2779). --define(wxShowEvent_SetShow, 2780). --define(wxShowEvent_GetShow, 2781). --define(wxIconizeEvent_Iconized, 2782). --define(wxJoystickEvent_ButtonDown, 2783). --define(wxJoystickEvent_ButtonIsDown, 2784). --define(wxJoystickEvent_ButtonUp, 2785). --define(wxJoystickEvent_GetButtonChange, 2786). --define(wxJoystickEvent_GetButtonState, 2787). --define(wxJoystickEvent_GetJoystick, 2788). --define(wxJoystickEvent_GetPosition, 2789). --define(wxJoystickEvent_GetZPosition, 2790). --define(wxJoystickEvent_IsButton, 2791). --define(wxJoystickEvent_IsMove, 2792). --define(wxJoystickEvent_IsZMove, 2793). --define(wxUpdateUIEvent_CanUpdate, 2794). --define(wxUpdateUIEvent_Check, 2795). --define(wxUpdateUIEvent_Enable, 2796). --define(wxUpdateUIEvent_Show, 2797). --define(wxUpdateUIEvent_GetChecked, 2798). --define(wxUpdateUIEvent_GetEnabled, 2799). --define(wxUpdateUIEvent_GetShown, 2800). --define(wxUpdateUIEvent_GetSetChecked, 2801). --define(wxUpdateUIEvent_GetSetEnabled, 2802). --define(wxUpdateUIEvent_GetSetShown, 2803). --define(wxUpdateUIEvent_GetSetText, 2804). --define(wxUpdateUIEvent_GetText, 2805). --define(wxUpdateUIEvent_GetMode, 2806). --define(wxUpdateUIEvent_GetUpdateInterval, 2807). --define(wxUpdateUIEvent_ResetUpdateTime, 2808). --define(wxUpdateUIEvent_SetMode, 2809). --define(wxUpdateUIEvent_SetText, 2810). --define(wxUpdateUIEvent_SetUpdateInterval, 2811). --define(wxMouseCaptureChangedEvent_GetCapturedWindow, 2812). --define(wxPaletteChangedEvent_SetChangedWindow, 2813). --define(wxPaletteChangedEvent_GetChangedWindow, 2814). --define(wxQueryNewPaletteEvent_SetPaletteRealized, 2815). --define(wxQueryNewPaletteEvent_GetPaletteRealized, 2816). --define(wxNavigationKeyEvent_GetDirection, 2817). --define(wxNavigationKeyEvent_SetDirection, 2818). --define(wxNavigationKeyEvent_IsWindowChange, 2819). --define(wxNavigationKeyEvent_SetWindowChange, 2820). --define(wxNavigationKeyEvent_IsFromTab, 2821). --define(wxNavigationKeyEvent_SetFromTab, 2822). --define(wxNavigationKeyEvent_GetCurrentFocus, 2823). --define(wxNavigationKeyEvent_SetCurrentFocus, 2824). --define(wxHelpEvent_GetOrigin, 2825). --define(wxHelpEvent_GetPosition, 2826). --define(wxHelpEvent_SetOrigin, 2827). --define(wxHelpEvent_SetPosition, 2828). --define(wxContextMenuEvent_GetPosition, 2829). --define(wxContextMenuEvent_SetPosition, 2830). --define(wxIdleEvent_CanSend, 2831). --define(wxIdleEvent_GetMode, 2832). --define(wxIdleEvent_RequestMore, 2833). --define(wxIdleEvent_MoreRequested, 2834). --define(wxIdleEvent_SetMode, 2835). --define(wxGridEvent_AltDown, 2836). --define(wxGridEvent_ControlDown, 2837). --define(wxGridEvent_GetCol, 2838). --define(wxGridEvent_GetPosition, 2839). --define(wxGridEvent_GetRow, 2840). --define(wxGridEvent_MetaDown, 2841). --define(wxGridEvent_Selecting, 2842). --define(wxGridEvent_ShiftDown, 2843). --define(wxNotifyEvent_Allow, 2844). --define(wxNotifyEvent_IsAllowed, 2845). --define(wxNotifyEvent_Veto, 2846). --define(wxSashEvent_GetEdge, 2847). --define(wxSashEvent_GetDragRect, 2848). --define(wxSashEvent_GetDragStatus, 2849). --define(wxListEvent_GetCacheFrom, 2850). --define(wxListEvent_GetCacheTo, 2851). --define(wxListEvent_GetKeyCode, 2852). --define(wxListEvent_GetIndex, 2853). --define(wxListEvent_GetColumn, 2854). --define(wxListEvent_GetPoint, 2855). --define(wxListEvent_GetLabel, 2856). --define(wxListEvent_GetText, 2857). --define(wxListEvent_GetImage, 2858). --define(wxListEvent_GetData, 2859). --define(wxListEvent_GetMask, 2860). --define(wxListEvent_GetItem, 2861). --define(wxListEvent_IsEditCancelled, 2862). --define(wxDateEvent_GetDate, 2863). --define(wxCalendarEvent_GetWeekDay, 2864). --define(wxFileDirPickerEvent_GetPath, 2865). --define(wxColourPickerEvent_GetColour, 2866). --define(wxFontPickerEvent_GetFont, 2867). --define(wxStyledTextEvent_GetPosition, 2868). --define(wxStyledTextEvent_GetKey, 2869). --define(wxStyledTextEvent_GetModifiers, 2870). --define(wxStyledTextEvent_GetModificationType, 2871). --define(wxStyledTextEvent_GetText, 2872). --define(wxStyledTextEvent_GetLength, 2873). --define(wxStyledTextEvent_GetLinesAdded, 2874). --define(wxStyledTextEvent_GetLine, 2875). --define(wxStyledTextEvent_GetFoldLevelNow, 2876). --define(wxStyledTextEvent_GetFoldLevelPrev, 2877). --define(wxStyledTextEvent_GetMargin, 2878). --define(wxStyledTextEvent_GetMessage, 2879). --define(wxStyledTextEvent_GetWParam, 2880). --define(wxStyledTextEvent_GetLParam, 2881). --define(wxStyledTextEvent_GetListType, 2882). --define(wxStyledTextEvent_GetX, 2883). --define(wxStyledTextEvent_GetY, 2884). --define(wxStyledTextEvent_GetDragText, 2885). --define(wxStyledTextEvent_GetDragAllowMove, 2886). --define(wxStyledTextEvent_GetDragResult, 2887). --define(wxStyledTextEvent_GetShift, 2888). --define(wxStyledTextEvent_GetControl, 2889). --define(wxStyledTextEvent_GetAlt, 2890). --define(utils_wxGetKeyState, 2891). --define(utils_wxGetMousePosition, 2892). --define(utils_wxGetMouseState, 2893). --define(utils_wxSetDetectableAutoRepeat, 2894). --define(utils_wxBell, 2895). --define(utils_wxFindMenuItemId, 2896). --define(utils_wxGenericFindWindowAtPoint, 2897). --define(utils_wxFindWindowAtPoint, 2898). --define(utils_wxBeginBusyCursor, 2899). --define(utils_wxEndBusyCursor, 2900). --define(utils_wxIsBusy, 2901). --define(utils_wxShutdown, 2902). --define(utils_wxShell, 2903). --define(utils_wxLaunchDefaultBrowser, 2904). --define(utils_wxGetEmailAddress, 2905). --define(utils_wxGetUserId, 2906). --define(utils_wxGetHomeDir, 2907). --define(utils_wxNewId, 2908). --define(utils_wxRegisterId, 2909). --define(utils_wxGetCurrentId, 2910). --define(utils_wxGetOsDescription, 2911). --define(utils_wxIsPlatformLittleEndian, 2912). --define(utils_wxIsPlatform64Bit, 2913). --define(wxPrintout_new, 2914). --define(wxPrintout_destruct, 2915). --define(wxPrintout_GetDC, 2916). --define(wxPrintout_GetPageSizeMM, 2917). --define(wxPrintout_GetPageSizePixels, 2918). --define(wxPrintout_GetPaperRectPixels, 2919). --define(wxPrintout_GetPPIPrinter, 2920). --define(wxPrintout_GetPPIScreen, 2921). --define(wxPrintout_GetTitle, 2922). --define(wxPrintout_IsPreview, 2923). --define(wxPrintout_FitThisSizeToPaper, 2924). --define(wxPrintout_FitThisSizeToPage, 2925). --define(wxPrintout_FitThisSizeToPageMargins, 2926). --define(wxPrintout_MapScreenSizeToPaper, 2927). --define(wxPrintout_MapScreenSizeToPage, 2928). --define(wxPrintout_MapScreenSizeToPageMargins, 2929). --define(wxPrintout_MapScreenSizeToDevice, 2930). --define(wxPrintout_GetLogicalPaperRect, 2931). --define(wxPrintout_GetLogicalPageRect, 2932). --define(wxPrintout_GetLogicalPageMarginsRect, 2933). --define(wxPrintout_SetLogicalOrigin, 2934). --define(wxPrintout_OffsetLogicalOrigin, 2935). --define(wxStyledTextCtrl_new_2, 2936). --define(wxStyledTextCtrl_new_0, 2937). --define(wxStyledTextCtrl_destruct, 2938). --define(wxStyledTextCtrl_Create, 2939). --define(wxStyledTextCtrl_AddText, 2940). --define(wxStyledTextCtrl_AddStyledText, 2941). --define(wxStyledTextCtrl_InsertText, 2942). --define(wxStyledTextCtrl_ClearAll, 2943). --define(wxStyledTextCtrl_ClearDocumentStyle, 2944). --define(wxStyledTextCtrl_GetLength, 2945). --define(wxStyledTextCtrl_GetCharAt, 2946). --define(wxStyledTextCtrl_GetCurrentPos, 2947). --define(wxStyledTextCtrl_GetAnchor, 2948). --define(wxStyledTextCtrl_GetStyleAt, 2949). --define(wxStyledTextCtrl_Redo, 2950). --define(wxStyledTextCtrl_SetUndoCollection, 2951). --define(wxStyledTextCtrl_SelectAll, 2952). --define(wxStyledTextCtrl_SetSavePoint, 2953). --define(wxStyledTextCtrl_GetStyledText, 2954). --define(wxStyledTextCtrl_CanRedo, 2955). --define(wxStyledTextCtrl_MarkerLineFromHandle, 2956). --define(wxStyledTextCtrl_MarkerDeleteHandle, 2957). --define(wxStyledTextCtrl_GetUndoCollection, 2958). --define(wxStyledTextCtrl_GetViewWhiteSpace, 2959). --define(wxStyledTextCtrl_SetViewWhiteSpace, 2960). --define(wxStyledTextCtrl_PositionFromPoint, 2961). --define(wxStyledTextCtrl_PositionFromPointClose, 2962). --define(wxStyledTextCtrl_GotoLine, 2963). --define(wxStyledTextCtrl_GotoPos, 2964). --define(wxStyledTextCtrl_SetAnchor, 2965). --define(wxStyledTextCtrl_GetCurLine, 2966). --define(wxStyledTextCtrl_GetEndStyled, 2967). --define(wxStyledTextCtrl_ConvertEOLs, 2968). --define(wxStyledTextCtrl_GetEOLMode, 2969). --define(wxStyledTextCtrl_SetEOLMode, 2970). --define(wxStyledTextCtrl_StartStyling, 2971). --define(wxStyledTextCtrl_SetStyling, 2972). --define(wxStyledTextCtrl_GetBufferedDraw, 2973). --define(wxStyledTextCtrl_SetBufferedDraw, 2974). --define(wxStyledTextCtrl_SetTabWidth, 2975). --define(wxStyledTextCtrl_GetTabWidth, 2976). --define(wxStyledTextCtrl_SetCodePage, 2977). --define(wxStyledTextCtrl_MarkerDefine, 2978). --define(wxStyledTextCtrl_MarkerSetForeground, 2979). --define(wxStyledTextCtrl_MarkerSetBackground, 2980). --define(wxStyledTextCtrl_MarkerAdd, 2981). --define(wxStyledTextCtrl_MarkerDelete, 2982). --define(wxStyledTextCtrl_MarkerDeleteAll, 2983). --define(wxStyledTextCtrl_MarkerGet, 2984). --define(wxStyledTextCtrl_MarkerNext, 2985). --define(wxStyledTextCtrl_MarkerPrevious, 2986). --define(wxStyledTextCtrl_MarkerDefineBitmap, 2987). --define(wxStyledTextCtrl_MarkerAddSet, 2988). --define(wxStyledTextCtrl_MarkerSetAlpha, 2989). --define(wxStyledTextCtrl_SetMarginType, 2990). --define(wxStyledTextCtrl_GetMarginType, 2991). --define(wxStyledTextCtrl_SetMarginWidth, 2992). --define(wxStyledTextCtrl_GetMarginWidth, 2993). --define(wxStyledTextCtrl_SetMarginMask, 2994). --define(wxStyledTextCtrl_GetMarginMask, 2995). --define(wxStyledTextCtrl_SetMarginSensitive, 2996). --define(wxStyledTextCtrl_GetMarginSensitive, 2997). --define(wxStyledTextCtrl_StyleClearAll, 2998). --define(wxStyledTextCtrl_StyleSetForeground, 2999). --define(wxStyledTextCtrl_StyleSetBackground, 3000). --define(wxStyledTextCtrl_StyleSetBold, 3001). --define(wxStyledTextCtrl_StyleSetItalic, 3002). --define(wxStyledTextCtrl_StyleSetSize, 3003). --define(wxStyledTextCtrl_StyleSetFaceName, 3004). --define(wxStyledTextCtrl_StyleSetEOLFilled, 3005). --define(wxStyledTextCtrl_StyleResetDefault, 3006). --define(wxStyledTextCtrl_StyleSetUnderline, 3007). --define(wxStyledTextCtrl_StyleSetCase, 3008). --define(wxStyledTextCtrl_StyleSetHotSpot, 3009). --define(wxStyledTextCtrl_SetSelForeground, 3010). --define(wxStyledTextCtrl_SetSelBackground, 3011). --define(wxStyledTextCtrl_GetSelAlpha, 3012). --define(wxStyledTextCtrl_SetSelAlpha, 3013). --define(wxStyledTextCtrl_SetCaretForeground, 3014). --define(wxStyledTextCtrl_CmdKeyAssign, 3015). --define(wxStyledTextCtrl_CmdKeyClear, 3016). --define(wxStyledTextCtrl_CmdKeyClearAll, 3017). --define(wxStyledTextCtrl_SetStyleBytes, 3018). --define(wxStyledTextCtrl_StyleSetVisible, 3019). --define(wxStyledTextCtrl_GetCaretPeriod, 3020). --define(wxStyledTextCtrl_SetCaretPeriod, 3021). --define(wxStyledTextCtrl_SetWordChars, 3022). --define(wxStyledTextCtrl_BeginUndoAction, 3023). --define(wxStyledTextCtrl_EndUndoAction, 3024). --define(wxStyledTextCtrl_IndicatorSetStyle, 3025). --define(wxStyledTextCtrl_IndicatorGetStyle, 3026). --define(wxStyledTextCtrl_IndicatorSetForeground, 3027). --define(wxStyledTextCtrl_IndicatorGetForeground, 3028). --define(wxStyledTextCtrl_SetWhitespaceForeground, 3029). --define(wxStyledTextCtrl_SetWhitespaceBackground, 3030). --define(wxStyledTextCtrl_GetStyleBits, 3031). --define(wxStyledTextCtrl_SetLineState, 3032). --define(wxStyledTextCtrl_GetLineState, 3033). --define(wxStyledTextCtrl_GetMaxLineState, 3034). --define(wxStyledTextCtrl_GetCaretLineVisible, 3035). --define(wxStyledTextCtrl_SetCaretLineVisible, 3036). --define(wxStyledTextCtrl_GetCaretLineBackground, 3037). --define(wxStyledTextCtrl_SetCaretLineBackground, 3038). --define(wxStyledTextCtrl_AutoCompShow, 3039). --define(wxStyledTextCtrl_AutoCompCancel, 3040). --define(wxStyledTextCtrl_AutoCompActive, 3041). --define(wxStyledTextCtrl_AutoCompPosStart, 3042). --define(wxStyledTextCtrl_AutoCompComplete, 3043). --define(wxStyledTextCtrl_AutoCompStops, 3044). --define(wxStyledTextCtrl_AutoCompSetSeparator, 3045). --define(wxStyledTextCtrl_AutoCompGetSeparator, 3046). --define(wxStyledTextCtrl_AutoCompSelect, 3047). --define(wxStyledTextCtrl_AutoCompSetCancelAtStart, 3048). --define(wxStyledTextCtrl_AutoCompGetCancelAtStart, 3049). --define(wxStyledTextCtrl_AutoCompSetFillUps, 3050). --define(wxStyledTextCtrl_AutoCompSetChooseSingle, 3051). --define(wxStyledTextCtrl_AutoCompGetChooseSingle, 3052). --define(wxStyledTextCtrl_AutoCompSetIgnoreCase, 3053). --define(wxStyledTextCtrl_AutoCompGetIgnoreCase, 3054). --define(wxStyledTextCtrl_UserListShow, 3055). --define(wxStyledTextCtrl_AutoCompSetAutoHide, 3056). --define(wxStyledTextCtrl_AutoCompGetAutoHide, 3057). --define(wxStyledTextCtrl_AutoCompSetDropRestOfWord, 3058). --define(wxStyledTextCtrl_AutoCompGetDropRestOfWord, 3059). --define(wxStyledTextCtrl_RegisterImage, 3060). --define(wxStyledTextCtrl_ClearRegisteredImages, 3061). --define(wxStyledTextCtrl_AutoCompGetTypeSeparator, 3062). --define(wxStyledTextCtrl_AutoCompSetTypeSeparator, 3063). --define(wxStyledTextCtrl_AutoCompSetMaxWidth, 3064). --define(wxStyledTextCtrl_AutoCompGetMaxWidth, 3065). --define(wxStyledTextCtrl_AutoCompSetMaxHeight, 3066). --define(wxStyledTextCtrl_AutoCompGetMaxHeight, 3067). --define(wxStyledTextCtrl_SetIndent, 3068). --define(wxStyledTextCtrl_GetIndent, 3069). --define(wxStyledTextCtrl_SetUseTabs, 3070). --define(wxStyledTextCtrl_GetUseTabs, 3071). --define(wxStyledTextCtrl_SetLineIndentation, 3072). --define(wxStyledTextCtrl_GetLineIndentation, 3073). --define(wxStyledTextCtrl_GetLineIndentPosition, 3074). --define(wxStyledTextCtrl_GetColumn, 3075). --define(wxStyledTextCtrl_SetUseHorizontalScrollBar, 3076). --define(wxStyledTextCtrl_GetUseHorizontalScrollBar, 3077). --define(wxStyledTextCtrl_SetIndentationGuides, 3078). --define(wxStyledTextCtrl_GetIndentationGuides, 3079). --define(wxStyledTextCtrl_SetHighlightGuide, 3080). --define(wxStyledTextCtrl_GetHighlightGuide, 3081). --define(wxStyledTextCtrl_GetLineEndPosition, 3082). --define(wxStyledTextCtrl_GetCodePage, 3083). --define(wxStyledTextCtrl_GetCaretForeground, 3084). --define(wxStyledTextCtrl_GetReadOnly, 3085). --define(wxStyledTextCtrl_SetCurrentPos, 3086). --define(wxStyledTextCtrl_SetSelectionStart, 3087). --define(wxStyledTextCtrl_GetSelectionStart, 3088). --define(wxStyledTextCtrl_SetSelectionEnd, 3089). --define(wxStyledTextCtrl_GetSelectionEnd, 3090). --define(wxStyledTextCtrl_SetPrintMagnification, 3091). --define(wxStyledTextCtrl_GetPrintMagnification, 3092). --define(wxStyledTextCtrl_SetPrintColourMode, 3093). --define(wxStyledTextCtrl_GetPrintColourMode, 3094). --define(wxStyledTextCtrl_FindText, 3095). --define(wxStyledTextCtrl_FormatRange, 3096). --define(wxStyledTextCtrl_GetFirstVisibleLine, 3097). --define(wxStyledTextCtrl_GetLine, 3098). --define(wxStyledTextCtrl_GetLineCount, 3099). --define(wxStyledTextCtrl_SetMarginLeft, 3100). --define(wxStyledTextCtrl_GetMarginLeft, 3101). --define(wxStyledTextCtrl_SetMarginRight, 3102). --define(wxStyledTextCtrl_GetMarginRight, 3103). --define(wxStyledTextCtrl_GetModify, 3104). --define(wxStyledTextCtrl_SetSelection, 3105). --define(wxStyledTextCtrl_GetSelectedText, 3106). --define(wxStyledTextCtrl_GetTextRange, 3107). --define(wxStyledTextCtrl_HideSelection, 3108). --define(wxStyledTextCtrl_LineFromPosition, 3109). --define(wxStyledTextCtrl_PositionFromLine, 3110). --define(wxStyledTextCtrl_LineScroll, 3111). --define(wxStyledTextCtrl_EnsureCaretVisible, 3112). --define(wxStyledTextCtrl_ReplaceSelection, 3113). --define(wxStyledTextCtrl_SetReadOnly, 3114). --define(wxStyledTextCtrl_CanPaste, 3115). --define(wxStyledTextCtrl_CanUndo, 3116). --define(wxStyledTextCtrl_EmptyUndoBuffer, 3117). --define(wxStyledTextCtrl_Undo, 3118). --define(wxStyledTextCtrl_Cut, 3119). --define(wxStyledTextCtrl_Copy, 3120). --define(wxStyledTextCtrl_Paste, 3121). --define(wxStyledTextCtrl_Clear, 3122). --define(wxStyledTextCtrl_SetText, 3123). --define(wxStyledTextCtrl_GetText, 3124). --define(wxStyledTextCtrl_GetTextLength, 3125). --define(wxStyledTextCtrl_GetOvertype, 3126). --define(wxStyledTextCtrl_SetCaretWidth, 3127). --define(wxStyledTextCtrl_GetCaretWidth, 3128). --define(wxStyledTextCtrl_SetTargetStart, 3129). --define(wxStyledTextCtrl_GetTargetStart, 3130). --define(wxStyledTextCtrl_SetTargetEnd, 3131). --define(wxStyledTextCtrl_GetTargetEnd, 3132). --define(wxStyledTextCtrl_ReplaceTarget, 3133). --define(wxStyledTextCtrl_SearchInTarget, 3134). --define(wxStyledTextCtrl_SetSearchFlags, 3135). --define(wxStyledTextCtrl_GetSearchFlags, 3136). --define(wxStyledTextCtrl_CallTipShow, 3137). --define(wxStyledTextCtrl_CallTipCancel, 3138). --define(wxStyledTextCtrl_CallTipActive, 3139). --define(wxStyledTextCtrl_CallTipPosAtStart, 3140). --define(wxStyledTextCtrl_CallTipSetHighlight, 3141). --define(wxStyledTextCtrl_CallTipSetBackground, 3142). --define(wxStyledTextCtrl_CallTipSetForeground, 3143). --define(wxStyledTextCtrl_CallTipSetForegroundHighlight, 3144). --define(wxStyledTextCtrl_CallTipUseStyle, 3145). --define(wxStyledTextCtrl_VisibleFromDocLine, 3146). --define(wxStyledTextCtrl_DocLineFromVisible, 3147). --define(wxStyledTextCtrl_WrapCount, 3148). --define(wxStyledTextCtrl_SetFoldLevel, 3149). --define(wxStyledTextCtrl_GetFoldLevel, 3150). --define(wxStyledTextCtrl_GetLastChild, 3151). --define(wxStyledTextCtrl_GetFoldParent, 3152). --define(wxStyledTextCtrl_ShowLines, 3153). --define(wxStyledTextCtrl_HideLines, 3154). --define(wxStyledTextCtrl_GetLineVisible, 3155). --define(wxStyledTextCtrl_SetFoldExpanded, 3156). --define(wxStyledTextCtrl_GetFoldExpanded, 3157). --define(wxStyledTextCtrl_ToggleFold, 3158). --define(wxStyledTextCtrl_EnsureVisible, 3159). --define(wxStyledTextCtrl_SetFoldFlags, 3160). --define(wxStyledTextCtrl_EnsureVisibleEnforcePolicy, 3161). --define(wxStyledTextCtrl_SetTabIndents, 3162). --define(wxStyledTextCtrl_GetTabIndents, 3163). --define(wxStyledTextCtrl_SetBackSpaceUnIndents, 3164). --define(wxStyledTextCtrl_GetBackSpaceUnIndents, 3165). --define(wxStyledTextCtrl_SetMouseDwellTime, 3166). --define(wxStyledTextCtrl_GetMouseDwellTime, 3167). --define(wxStyledTextCtrl_WordStartPosition, 3168). --define(wxStyledTextCtrl_WordEndPosition, 3169). --define(wxStyledTextCtrl_SetWrapMode, 3170). --define(wxStyledTextCtrl_GetWrapMode, 3171). --define(wxStyledTextCtrl_SetWrapVisualFlags, 3172). --define(wxStyledTextCtrl_GetWrapVisualFlags, 3173). --define(wxStyledTextCtrl_SetWrapVisualFlagsLocation, 3174). --define(wxStyledTextCtrl_GetWrapVisualFlagsLocation, 3175). --define(wxStyledTextCtrl_SetWrapStartIndent, 3176). --define(wxStyledTextCtrl_GetWrapStartIndent, 3177). --define(wxStyledTextCtrl_SetLayoutCache, 3178). --define(wxStyledTextCtrl_GetLayoutCache, 3179). --define(wxStyledTextCtrl_SetScrollWidth, 3180). --define(wxStyledTextCtrl_GetScrollWidth, 3181). --define(wxStyledTextCtrl_TextWidth, 3182). --define(wxStyledTextCtrl_GetEndAtLastLine, 3183). --define(wxStyledTextCtrl_TextHeight, 3184). --define(wxStyledTextCtrl_SetUseVerticalScrollBar, 3185). --define(wxStyledTextCtrl_GetUseVerticalScrollBar, 3186). --define(wxStyledTextCtrl_AppendText, 3187). --define(wxStyledTextCtrl_GetTwoPhaseDraw, 3188). --define(wxStyledTextCtrl_SetTwoPhaseDraw, 3189). --define(wxStyledTextCtrl_TargetFromSelection, 3190). --define(wxStyledTextCtrl_LinesJoin, 3191). --define(wxStyledTextCtrl_LinesSplit, 3192). --define(wxStyledTextCtrl_SetFoldMarginColour, 3193). --define(wxStyledTextCtrl_SetFoldMarginHiColour, 3194). --define(wxStyledTextCtrl_LineDown, 3195). --define(wxStyledTextCtrl_LineDownExtend, 3196). --define(wxStyledTextCtrl_LineUp, 3197). --define(wxStyledTextCtrl_LineUpExtend, 3198). --define(wxStyledTextCtrl_CharLeft, 3199). --define(wxStyledTextCtrl_CharLeftExtend, 3200). --define(wxStyledTextCtrl_CharRight, 3201). --define(wxStyledTextCtrl_CharRightExtend, 3202). --define(wxStyledTextCtrl_WordLeft, 3203). --define(wxStyledTextCtrl_WordLeftExtend, 3204). --define(wxStyledTextCtrl_WordRight, 3205). --define(wxStyledTextCtrl_WordRightExtend, 3206). --define(wxStyledTextCtrl_Home, 3207). --define(wxStyledTextCtrl_HomeExtend, 3208). --define(wxStyledTextCtrl_LineEnd, 3209). --define(wxStyledTextCtrl_LineEndExtend, 3210). --define(wxStyledTextCtrl_DocumentStart, 3211). --define(wxStyledTextCtrl_DocumentStartExtend, 3212). --define(wxStyledTextCtrl_DocumentEnd, 3213). --define(wxStyledTextCtrl_DocumentEndExtend, 3214). --define(wxStyledTextCtrl_PageUp, 3215). --define(wxStyledTextCtrl_PageUpExtend, 3216). --define(wxStyledTextCtrl_PageDown, 3217). --define(wxStyledTextCtrl_PageDownExtend, 3218). --define(wxStyledTextCtrl_EditToggleOvertype, 3219). --define(wxStyledTextCtrl_Cancel, 3220). --define(wxStyledTextCtrl_DeleteBack, 3221). --define(wxStyledTextCtrl_Tab, 3222). --define(wxStyledTextCtrl_BackTab, 3223). --define(wxStyledTextCtrl_NewLine, 3224). --define(wxStyledTextCtrl_FormFeed, 3225). --define(wxStyledTextCtrl_VCHome, 3226). --define(wxStyledTextCtrl_VCHomeExtend, 3227). --define(wxStyledTextCtrl_ZoomIn, 3228). --define(wxStyledTextCtrl_ZoomOut, 3229). --define(wxStyledTextCtrl_DelWordLeft, 3230). --define(wxStyledTextCtrl_DelWordRight, 3231). --define(wxStyledTextCtrl_LineCut, 3232). --define(wxStyledTextCtrl_LineDelete, 3233). --define(wxStyledTextCtrl_LineTranspose, 3234). --define(wxStyledTextCtrl_LineDuplicate, 3235). --define(wxStyledTextCtrl_LowerCase, 3236). --define(wxStyledTextCtrl_UpperCase, 3237). --define(wxStyledTextCtrl_LineScrollDown, 3238). --define(wxStyledTextCtrl_LineScrollUp, 3239). --define(wxStyledTextCtrl_DeleteBackNotLine, 3240). --define(wxStyledTextCtrl_HomeDisplay, 3241). --define(wxStyledTextCtrl_HomeDisplayExtend, 3242). --define(wxStyledTextCtrl_LineEndDisplay, 3243). --define(wxStyledTextCtrl_LineEndDisplayExtend, 3244). --define(wxStyledTextCtrl_HomeWrapExtend, 3245). --define(wxStyledTextCtrl_LineEndWrap, 3246). --define(wxStyledTextCtrl_LineEndWrapExtend, 3247). --define(wxStyledTextCtrl_VCHomeWrap, 3248). --define(wxStyledTextCtrl_VCHomeWrapExtend, 3249). --define(wxStyledTextCtrl_LineCopy, 3250). --define(wxStyledTextCtrl_MoveCaretInsideView, 3251). --define(wxStyledTextCtrl_LineLength, 3252). --define(wxStyledTextCtrl_BraceHighlight, 3253). --define(wxStyledTextCtrl_BraceBadLight, 3254). --define(wxStyledTextCtrl_BraceMatch, 3255). --define(wxStyledTextCtrl_GetViewEOL, 3256). --define(wxStyledTextCtrl_SetViewEOL, 3257). --define(wxStyledTextCtrl_SetModEventMask, 3258). --define(wxStyledTextCtrl_GetEdgeColumn, 3259). --define(wxStyledTextCtrl_SetEdgeColumn, 3260). --define(wxStyledTextCtrl_GetEdgeMode, 3261). --define(wxStyledTextCtrl_GetEdgeColour, 3262). --define(wxStyledTextCtrl_SetEdgeColour, 3263). --define(wxStyledTextCtrl_SearchAnchor, 3264). --define(wxStyledTextCtrl_SearchNext, 3265). --define(wxStyledTextCtrl_SearchPrev, 3266). --define(wxStyledTextCtrl_LinesOnScreen, 3267). --define(wxStyledTextCtrl_UsePopUp, 3268). --define(wxStyledTextCtrl_SelectionIsRectangle, 3269). --define(wxStyledTextCtrl_SetZoom, 3270). --define(wxStyledTextCtrl_GetZoom, 3271). --define(wxStyledTextCtrl_GetModEventMask, 3272). --define(wxStyledTextCtrl_SetSTCFocus, 3273). --define(wxStyledTextCtrl_GetSTCFocus, 3274). --define(wxStyledTextCtrl_SetStatus, 3275). --define(wxStyledTextCtrl_GetStatus, 3276). --define(wxStyledTextCtrl_SetMouseDownCaptures, 3277). --define(wxStyledTextCtrl_GetMouseDownCaptures, 3278). --define(wxStyledTextCtrl_SetSTCCursor, 3279). --define(wxStyledTextCtrl_GetSTCCursor, 3280). --define(wxStyledTextCtrl_SetControlCharSymbol, 3281). --define(wxStyledTextCtrl_GetControlCharSymbol, 3282). --define(wxStyledTextCtrl_WordPartLeft, 3283). --define(wxStyledTextCtrl_WordPartLeftExtend, 3284). --define(wxStyledTextCtrl_WordPartRight, 3285). --define(wxStyledTextCtrl_WordPartRightExtend, 3286). --define(wxStyledTextCtrl_SetVisiblePolicy, 3287). --define(wxStyledTextCtrl_DelLineLeft, 3288). --define(wxStyledTextCtrl_DelLineRight, 3289). --define(wxStyledTextCtrl_GetXOffset, 3290). --define(wxStyledTextCtrl_ChooseCaretX, 3291). --define(wxStyledTextCtrl_SetXCaretPolicy, 3292). --define(wxStyledTextCtrl_SetYCaretPolicy, 3293). --define(wxStyledTextCtrl_GetPrintWrapMode, 3294). --define(wxStyledTextCtrl_SetHotspotActiveForeground, 3295). --define(wxStyledTextCtrl_SetHotspotActiveBackground, 3296). --define(wxStyledTextCtrl_SetHotspotActiveUnderline, 3297). --define(wxStyledTextCtrl_SetHotspotSingleLine, 3298). --define(wxStyledTextCtrl_ParaDownExtend, 3299). --define(wxStyledTextCtrl_ParaUp, 3300). --define(wxStyledTextCtrl_ParaUpExtend, 3301). --define(wxStyledTextCtrl_PositionBefore, 3302). --define(wxStyledTextCtrl_PositionAfter, 3303). --define(wxStyledTextCtrl_CopyRange, 3304). --define(wxStyledTextCtrl_CopyText, 3305). --define(wxStyledTextCtrl_SetSelectionMode, 3306). --define(wxStyledTextCtrl_GetSelectionMode, 3307). --define(wxStyledTextCtrl_LineDownRectExtend, 3308). --define(wxStyledTextCtrl_LineUpRectExtend, 3309). --define(wxStyledTextCtrl_CharLeftRectExtend, 3310). --define(wxStyledTextCtrl_CharRightRectExtend, 3311). --define(wxStyledTextCtrl_HomeRectExtend, 3312). --define(wxStyledTextCtrl_VCHomeRectExtend, 3313). --define(wxStyledTextCtrl_LineEndRectExtend, 3314). --define(wxStyledTextCtrl_PageUpRectExtend, 3315). --define(wxStyledTextCtrl_PageDownRectExtend, 3316). --define(wxStyledTextCtrl_StutteredPageUp, 3317). --define(wxStyledTextCtrl_StutteredPageUpExtend, 3318). --define(wxStyledTextCtrl_StutteredPageDown, 3319). --define(wxStyledTextCtrl_StutteredPageDownExtend, 3320). --define(wxStyledTextCtrl_WordLeftEnd, 3321). --define(wxStyledTextCtrl_WordLeftEndExtend, 3322). --define(wxStyledTextCtrl_WordRightEnd, 3323). --define(wxStyledTextCtrl_WordRightEndExtend, 3324). --define(wxStyledTextCtrl_SetWhitespaceChars, 3325). --define(wxStyledTextCtrl_SetCharsDefault, 3326). --define(wxStyledTextCtrl_AutoCompGetCurrent, 3327). --define(wxStyledTextCtrl_Allocate, 3328). --define(wxStyledTextCtrl_FindColumn, 3329). --define(wxStyledTextCtrl_GetCaretSticky, 3330). --define(wxStyledTextCtrl_SetCaretSticky, 3331). --define(wxStyledTextCtrl_ToggleCaretSticky, 3332). --define(wxStyledTextCtrl_SetPasteConvertEndings, 3333). --define(wxStyledTextCtrl_GetPasteConvertEndings, 3334). --define(wxStyledTextCtrl_SelectionDuplicate, 3335). --define(wxStyledTextCtrl_SetCaretLineBackAlpha, 3336). --define(wxStyledTextCtrl_GetCaretLineBackAlpha, 3337). --define(wxStyledTextCtrl_StartRecord, 3338). --define(wxStyledTextCtrl_StopRecord, 3339). --define(wxStyledTextCtrl_SetLexer, 3340). --define(wxStyledTextCtrl_GetLexer, 3341). --define(wxStyledTextCtrl_Colourise, 3342). --define(wxStyledTextCtrl_SetProperty, 3343). --define(wxStyledTextCtrl_SetKeyWords, 3344). --define(wxStyledTextCtrl_SetLexerLanguage, 3345). --define(wxStyledTextCtrl_GetProperty, 3346). --define(wxStyledTextCtrl_GetStyleBitsNeeded, 3347). --define(wxStyledTextCtrl_GetCurrentLine, 3348). --define(wxStyledTextCtrl_StyleSetSpec, 3349). --define(wxStyledTextCtrl_StyleSetFont, 3350). --define(wxStyledTextCtrl_StyleSetFontAttr, 3351). --define(wxStyledTextCtrl_StyleSetCharacterSet, 3352). --define(wxStyledTextCtrl_StyleSetFontEncoding, 3353). --define(wxStyledTextCtrl_CmdKeyExecute, 3354). --define(wxStyledTextCtrl_SetMargins, 3355). --define(wxStyledTextCtrl_GetSelection, 3356). --define(wxStyledTextCtrl_PointFromPosition, 3357). --define(wxStyledTextCtrl_ScrollToLine, 3358). --define(wxStyledTextCtrl_ScrollToColumn, 3359). --define(wxStyledTextCtrl_SendMsg, 3360). --define(wxStyledTextCtrl_SetVScrollBar, 3361). --define(wxStyledTextCtrl_SetHScrollBar, 3362). --define(wxStyledTextCtrl_GetLastKeydownProcessed, 3363). --define(wxStyledTextCtrl_SetLastKeydownProcessed, 3364). --define(wxStyledTextCtrl_SaveFile, 3365). --define(wxStyledTextCtrl_LoadFile, 3366). --define(wxStyledTextCtrl_DoDragOver, 3367). --define(wxStyledTextCtrl_DoDropText, 3368). --define(wxStyledTextCtrl_GetUseAntiAliasing, 3369). --define(wxStyledTextCtrl_AddTextRaw, 3370). --define(wxStyledTextCtrl_InsertTextRaw, 3371). --define(wxStyledTextCtrl_GetCurLineRaw, 3372). --define(wxStyledTextCtrl_GetLineRaw, 3373). --define(wxStyledTextCtrl_GetSelectedTextRaw, 3374). --define(wxStyledTextCtrl_GetTextRangeRaw, 3375). --define(wxStyledTextCtrl_SetTextRaw, 3376). --define(wxStyledTextCtrl_GetTextRaw, 3377). --define(wxStyledTextCtrl_AppendTextRaw, 3378). --define(wxArtProvider_GetBitmap, 3379). --define(wxArtProvider_GetIcon, 3380). --define(wxTreeEvent_GetKeyCode, 3381). --define(wxTreeEvent_GetItem, 3382). --define(wxTreeEvent_GetKeyEvent, 3383). --define(wxTreeEvent_GetLabel, 3384). --define(wxTreeEvent_GetOldItem, 3385). --define(wxTreeEvent_GetPoint, 3386). --define(wxTreeEvent_IsEditCancelled, 3387). --define(wxTreeEvent_SetToolTip, 3388). --define(wxNotebookEvent_GetOldSelection, 3389). --define(wxNotebookEvent_GetSelection, 3390). --define(wxNotebookEvent_SetOldSelection, 3391). --define(wxNotebookEvent_SetSelection, 3392). --define(wxFileDataObject_new, 3393). --define(wxFileDataObject_AddFile, 3394). --define(wxFileDataObject_GetFilenames, 3395). --define(wxFileDataObject_destroy, 3396). --define(wxTextDataObject_new, 3397). --define(wxTextDataObject_GetTextLength, 3398). --define(wxTextDataObject_GetText, 3399). --define(wxTextDataObject_SetText, 3400). --define(wxTextDataObject_destroy, 3401). --define(wxBitmapDataObject_new_1_1, 3402). --define(wxBitmapDataObject_new_1_0, 3403). --define(wxBitmapDataObject_GetBitmap, 3404). --define(wxBitmapDataObject_SetBitmap, 3405). --define(wxBitmapDataObject_destroy, 3406). --define(wxClipboard_new, 3408). --define(wxClipboard_destruct, 3409). --define(wxClipboard_AddData, 3410). --define(wxClipboard_Clear, 3411). --define(wxClipboard_Close, 3412). --define(wxClipboard_Flush, 3413). --define(wxClipboard_GetData, 3414). --define(wxClipboard_IsOpened, 3415). --define(wxClipboard_Open, 3416). --define(wxClipboard_SetData, 3417). --define(wxClipboard_UsePrimarySelection, 3419). --define(wxClipboard_IsSupported, 3420). --define(wxClipboard_Get, 3421). --define(wxSpinEvent_GetPosition, 3422). --define(wxSpinEvent_SetPosition, 3423). --define(wxSplitterWindow_new_0, 3424). --define(wxSplitterWindow_new_2, 3425). --define(wxSplitterWindow_destruct, 3426). --define(wxSplitterWindow_Create, 3427). --define(wxSplitterWindow_GetMinimumPaneSize, 3428). --define(wxSplitterWindow_GetSashGravity, 3429). --define(wxSplitterWindow_GetSashPosition, 3430). --define(wxSplitterWindow_GetSplitMode, 3431). --define(wxSplitterWindow_GetWindow1, 3432). --define(wxSplitterWindow_GetWindow2, 3433). --define(wxSplitterWindow_Initialize, 3434). --define(wxSplitterWindow_IsSplit, 3435). --define(wxSplitterWindow_ReplaceWindow, 3436). --define(wxSplitterWindow_SetSashGravity, 3437). --define(wxSplitterWindow_SetSashPosition, 3438). --define(wxSplitterWindow_SetSashSize, 3439). --define(wxSplitterWindow_SetMinimumPaneSize, 3440). --define(wxSplitterWindow_SetSplitMode, 3441). --define(wxSplitterWindow_SplitHorizontally, 3442). --define(wxSplitterWindow_SplitVertically, 3443). --define(wxSplitterWindow_Unsplit, 3444). --define(wxSplitterWindow_UpdateSize, 3445). --define(wxSplitterEvent_GetSashPosition, 3446). --define(wxSplitterEvent_GetX, 3447). --define(wxSplitterEvent_GetY, 3448). --define(wxSplitterEvent_GetWindowBeingRemoved, 3449). --define(wxSplitterEvent_SetSashPosition, 3450). --define(wxHtmlWindow_new_0, 3451). --define(wxHtmlWindow_new_2, 3452). --define(wxHtmlWindow_AppendToPage, 3453). --define(wxHtmlWindow_GetOpenedAnchor, 3454). --define(wxHtmlWindow_GetOpenedPage, 3455). --define(wxHtmlWindow_GetOpenedPageTitle, 3456). --define(wxHtmlWindow_GetRelatedFrame, 3457). --define(wxHtmlWindow_HistoryBack, 3458). --define(wxHtmlWindow_HistoryCanBack, 3459). --define(wxHtmlWindow_HistoryCanForward, 3460). --define(wxHtmlWindow_HistoryClear, 3461). --define(wxHtmlWindow_HistoryForward, 3462). --define(wxHtmlWindow_LoadFile, 3463). --define(wxHtmlWindow_LoadPage, 3464). --define(wxHtmlWindow_SelectAll, 3465). --define(wxHtmlWindow_SelectionToText, 3466). --define(wxHtmlWindow_SelectLine, 3467). --define(wxHtmlWindow_SelectWord, 3468). --define(wxHtmlWindow_SetBorders, 3469). --define(wxHtmlWindow_SetFonts, 3470). --define(wxHtmlWindow_SetPage, 3471). --define(wxHtmlWindow_SetRelatedFrame, 3472). --define(wxHtmlWindow_SetRelatedStatusBar, 3473). --define(wxHtmlWindow_ToText, 3474). --define(wxHtmlWindow_destroy, 3475). --define(wxHtmlLinkEvent_GetLinkInfo, 3476). --define(wxAuiNotebookEvent_SetSelection, 3477). --define(wxAuiNotebookEvent_GetSelection, 3478). --define(wxAuiNotebookEvent_SetOldSelection, 3479). --define(wxAuiNotebookEvent_GetOldSelection, 3480). --define(wxAuiNotebookEvent_SetDragSource, 3481). --define(wxAuiNotebookEvent_GetDragSource, 3482). --define(wxAuiManagerEvent_SetManager, 3483). --define(wxAuiManagerEvent_GetManager, 3484). --define(wxAuiManagerEvent_SetPane, 3485). --define(wxAuiManagerEvent_GetPane, 3486). --define(wxAuiManagerEvent_SetButton, 3487). --define(wxAuiManagerEvent_GetButton, 3488). --define(wxAuiManagerEvent_SetDC, 3489). --define(wxAuiManagerEvent_GetDC, 3490). --define(wxAuiManagerEvent_Veto, 3491). --define(wxAuiManagerEvent_GetVeto, 3492). --define(wxAuiManagerEvent_SetCanVeto, 3493). --define(wxAuiManagerEvent_CanVeto, 3494). --define(wxLogNull_new, 3495). --define(wxLogNull_destroy, 3496). +-define(wxControlWithItems_getClientData, 885). +-define(wxControlWithItems_setClientData, 886). +-define(wxControlWithItems_GetCount, 887). +-define(wxControlWithItems_GetSelection, 888). +-define(wxControlWithItems_GetString, 889). +-define(wxControlWithItems_GetStringSelection, 890). +-define(wxControlWithItems_Insert_2, 891). +-define(wxControlWithItems_Insert_3, 892). +-define(wxControlWithItems_IsEmpty, 893). +-define(wxControlWithItems_Select, 894). +-define(wxControlWithItems_SetSelection, 895). +-define(wxControlWithItems_SetString, 896). +-define(wxControlWithItems_SetStringSelection, 897). +-define(wxMenu_new_2, 900). +-define(wxMenu_new_1, 901). +-define(wxMenu_destruct, 903). +-define(wxMenu_Append_3, 904). +-define(wxMenu_Append_1, 905). +-define(wxMenu_Append_4_0, 906). +-define(wxMenu_Append_4_1, 907). +-define(wxMenu_AppendCheckItem, 908). +-define(wxMenu_AppendRadioItem, 909). +-define(wxMenu_AppendSeparator, 910). +-define(wxMenu_Break, 911). +-define(wxMenu_Check, 912). +-define(wxMenu_Delete_1_0, 913). +-define(wxMenu_Delete_1_1, 914). +-define(wxMenu_Destroy_1_0, 915). +-define(wxMenu_Destroy_1_1, 916). +-define(wxMenu_Enable, 917). +-define(wxMenu_FindItem_1, 918). +-define(wxMenu_FindItem_2, 919). +-define(wxMenu_FindItemByPosition, 920). +-define(wxMenu_GetHelpString, 921). +-define(wxMenu_GetLabel, 922). +-define(wxMenu_GetMenuItemCount, 923). +-define(wxMenu_GetMenuItems, 924). +-define(wxMenu_GetTitle, 926). +-define(wxMenu_Insert_2, 927). +-define(wxMenu_Insert_3, 928). +-define(wxMenu_Insert_5_1, 929). +-define(wxMenu_Insert_5_0, 930). +-define(wxMenu_InsertCheckItem, 931). +-define(wxMenu_InsertRadioItem, 932). +-define(wxMenu_InsertSeparator, 933). +-define(wxMenu_IsChecked, 934). +-define(wxMenu_IsEnabled, 935). +-define(wxMenu_Prepend_1, 936). +-define(wxMenu_Prepend_2, 937). +-define(wxMenu_Prepend_4_1, 938). +-define(wxMenu_Prepend_4_0, 939). +-define(wxMenu_PrependCheckItem, 940). +-define(wxMenu_PrependRadioItem, 941). +-define(wxMenu_PrependSeparator, 942). +-define(wxMenu_Remove_1_0, 943). +-define(wxMenu_Remove_1_1, 944). +-define(wxMenu_SetHelpString, 945). +-define(wxMenu_SetLabel, 946). +-define(wxMenu_SetTitle, 947). +-define(wxMenuItem_new, 948). +-define(wxMenuItem_destruct, 950). +-define(wxMenuItem_Check, 951). +-define(wxMenuItem_Enable, 952). +-define(wxMenuItem_GetBitmap, 953). +-define(wxMenuItem_GetHelp, 954). +-define(wxMenuItem_GetId, 955). +-define(wxMenuItem_GetKind, 956). +-define(wxMenuItem_GetLabel, 957). +-define(wxMenuItem_GetLabelFromText, 958). +-define(wxMenuItem_GetMenu, 959). +-define(wxMenuItem_GetText, 960). +-define(wxMenuItem_GetSubMenu, 961). +-define(wxMenuItem_IsCheckable, 962). +-define(wxMenuItem_IsChecked, 963). +-define(wxMenuItem_IsEnabled, 964). +-define(wxMenuItem_IsSeparator, 965). +-define(wxMenuItem_IsSubMenu, 966). +-define(wxMenuItem_SetBitmap, 967). +-define(wxMenuItem_SetHelp, 968). +-define(wxMenuItem_SetMenu, 969). +-define(wxMenuItem_SetSubMenu, 970). +-define(wxMenuItem_SetText, 971). +-define(wxToolBar_AddControl, 972). +-define(wxToolBar_AddSeparator, 973). +-define(wxToolBar_AddTool_5, 974). +-define(wxToolBar_AddTool_4_0, 975). +-define(wxToolBar_AddTool_1, 976). +-define(wxToolBar_AddTool_4_1, 977). +-define(wxToolBar_AddTool_3, 978). +-define(wxToolBar_AddTool_6, 979). +-define(wxToolBar_AddCheckTool, 980). +-define(wxToolBar_AddRadioTool, 981). +-define(wxToolBar_DeleteTool, 982). +-define(wxToolBar_DeleteToolByPos, 983). +-define(wxToolBar_EnableTool, 984). +-define(wxToolBar_FindById, 985). +-define(wxToolBar_FindControl, 986). +-define(wxToolBar_FindToolForPosition, 987). +-define(wxToolBar_GetToolSize, 988). +-define(wxToolBar_GetToolBitmapSize, 989). +-define(wxToolBar_GetMargins, 990). +-define(wxToolBar_GetToolEnabled, 991). +-define(wxToolBar_GetToolLongHelp, 992). +-define(wxToolBar_GetToolPacking, 993). +-define(wxToolBar_GetToolPos, 994). +-define(wxToolBar_GetToolSeparation, 995). +-define(wxToolBar_GetToolShortHelp, 996). +-define(wxToolBar_GetToolState, 997). +-define(wxToolBar_InsertControl, 998). +-define(wxToolBar_InsertSeparator, 999). +-define(wxToolBar_InsertTool_5, 1000). +-define(wxToolBar_InsertTool_2, 1001). +-define(wxToolBar_InsertTool_4, 1002). +-define(wxToolBar_Realize, 1003). +-define(wxToolBar_RemoveTool, 1004). +-define(wxToolBar_SetMargins, 1005). +-define(wxToolBar_SetToolBitmapSize, 1006). +-define(wxToolBar_SetToolLongHelp, 1007). +-define(wxToolBar_SetToolPacking, 1008). +-define(wxToolBar_SetToolShortHelp, 1009). +-define(wxToolBar_SetToolSeparation, 1010). +-define(wxToolBar_ToggleTool, 1011). +-define(wxStatusBar_new_0, 1013). +-define(wxStatusBar_new_2, 1014). +-define(wxStatusBar_destruct, 1016). +-define(wxStatusBar_Create, 1017). +-define(wxStatusBar_GetFieldRect, 1018). +-define(wxStatusBar_GetFieldsCount, 1019). +-define(wxStatusBar_GetStatusText, 1020). +-define(wxStatusBar_PopStatusText, 1021). +-define(wxStatusBar_PushStatusText, 1022). +-define(wxStatusBar_SetFieldsCount, 1023). +-define(wxStatusBar_SetMinHeight, 1024). +-define(wxStatusBar_SetStatusText, 1025). +-define(wxStatusBar_SetStatusWidths, 1026). +-define(wxStatusBar_SetStatusStyles, 1027). +-define(wxBitmap_new_0, 1028). +-define(wxBitmap_new_3, 1029). +-define(wxBitmap_new_4, 1030). +-define(wxBitmap_new_2_0, 1031). +-define(wxBitmap_new_2_1, 1032). +-define(wxBitmap_destruct, 1033). +-define(wxBitmap_ConvertToImage, 1034). +-define(wxBitmap_CopyFromIcon, 1035). +-define(wxBitmap_Create, 1036). +-define(wxBitmap_GetDepth, 1037). +-define(wxBitmap_GetHeight, 1038). +-define(wxBitmap_GetPalette, 1039). +-define(wxBitmap_GetMask, 1040). +-define(wxBitmap_GetWidth, 1041). +-define(wxBitmap_GetSubBitmap, 1042). +-define(wxBitmap_LoadFile, 1043). +-define(wxBitmap_Ok, 1044). +-define(wxBitmap_SaveFile, 1045). +-define(wxBitmap_SetDepth, 1046). +-define(wxBitmap_SetHeight, 1047). +-define(wxBitmap_SetMask, 1048). +-define(wxBitmap_SetPalette, 1049). +-define(wxBitmap_SetWidth, 1050). +-define(wxIcon_new_0, 1051). +-define(wxIcon_new_2, 1052). +-define(wxIcon_new_1, 1053). +-define(wxIcon_CopyFromBitmap, 1054). +-define(wxIcon_destroy, 1055). +-define(wxIconBundle_new_0, 1056). +-define(wxIconBundle_new_2, 1057). +-define(wxIconBundle_new_1_0, 1058). +-define(wxIconBundle_new_1_1, 1059). +-define(wxIconBundle_destruct, 1060). +-define(wxIconBundle_AddIcon_2, 1061). +-define(wxIconBundle_AddIcon_1, 1062). +-define(wxIconBundle_GetIcon_1_1, 1063). +-define(wxIconBundle_GetIcon_1_0, 1064). +-define(wxCursor_new_0, 1065). +-define(wxCursor_new_1_0, 1066). +-define(wxCursor_new_1_1, 1067). +-define(wxCursor_new_4, 1068). +-define(wxCursor_destruct, 1069). +-define(wxCursor_Ok, 1070). +-define(wxMask_new_0, 1071). +-define(wxMask_new_2_1, 1072). +-define(wxMask_new_2_0, 1073). +-define(wxMask_new_1, 1074). +-define(wxMask_destruct, 1075). +-define(wxMask_Create_2_1, 1076). +-define(wxMask_Create_2_0, 1077). +-define(wxMask_Create_1, 1078). +-define(wxImage_new_0, 1079). +-define(wxImage_new_3_0, 1080). +-define(wxImage_new_4, 1081). +-define(wxImage_new_5, 1082). +-define(wxImage_new_2, 1083). +-define(wxImage_new_3_1, 1084). +-define(wxImage_Blur, 1085). +-define(wxImage_BlurHorizontal, 1086). +-define(wxImage_BlurVertical, 1087). +-define(wxImage_ConvertAlphaToMask, 1088). +-define(wxImage_ConvertToGreyscale, 1089). +-define(wxImage_ConvertToMono, 1090). +-define(wxImage_Copy, 1091). +-define(wxImage_Create_3, 1092). +-define(wxImage_Create_4, 1093). +-define(wxImage_Create_5, 1094). +-define(wxImage_Destroy, 1095). +-define(wxImage_FindFirstUnusedColour, 1096). +-define(wxImage_GetImageExtWildcard, 1097). +-define(wxImage_GetAlpha_2, 1098). +-define(wxImage_GetAlpha_0, 1099). +-define(wxImage_GetBlue, 1100). +-define(wxImage_GetData, 1101). +-define(wxImage_GetGreen, 1102). +-define(wxImage_GetImageCount, 1103). +-define(wxImage_GetHeight, 1104). +-define(wxImage_GetMaskBlue, 1105). +-define(wxImage_GetMaskGreen, 1106). +-define(wxImage_GetMaskRed, 1107). +-define(wxImage_GetOrFindMaskColour, 1108). +-define(wxImage_GetPalette, 1109). +-define(wxImage_GetRed, 1110). +-define(wxImage_GetSubImage, 1111). +-define(wxImage_GetWidth, 1112). +-define(wxImage_HasAlpha, 1113). +-define(wxImage_HasMask, 1114). +-define(wxImage_GetOption, 1115). +-define(wxImage_GetOptionInt, 1116). +-define(wxImage_HasOption, 1117). +-define(wxImage_InitAlpha, 1118). +-define(wxImage_InitStandardHandlers, 1119). +-define(wxImage_IsTransparent, 1120). +-define(wxImage_LoadFile_2, 1121). +-define(wxImage_LoadFile_3, 1122). +-define(wxImage_Ok, 1123). +-define(wxImage_RemoveHandler, 1124). +-define(wxImage_Mirror, 1125). +-define(wxImage_Replace, 1126). +-define(wxImage_Rescale, 1127). +-define(wxImage_Resize, 1128). +-define(wxImage_Rotate, 1129). +-define(wxImage_RotateHue, 1130). +-define(wxImage_Rotate90, 1131). +-define(wxImage_SaveFile_1, 1132). +-define(wxImage_SaveFile_2_0, 1133). +-define(wxImage_SaveFile_2_1, 1134). +-define(wxImage_Scale, 1135). +-define(wxImage_Size, 1136). +-define(wxImage_SetAlpha_3, 1137). +-define(wxImage_SetAlpha_2, 1138). +-define(wxImage_SetData_2, 1139). +-define(wxImage_SetData_4, 1140). +-define(wxImage_SetMask, 1141). +-define(wxImage_SetMaskColour, 1142). +-define(wxImage_SetMaskFromImage, 1143). +-define(wxImage_SetOption_2_1, 1144). +-define(wxImage_SetOption_2_0, 1145). +-define(wxImage_SetPalette, 1146). +-define(wxImage_SetRGB_5, 1147). +-define(wxImage_SetRGB_4, 1148). +-define(wxImage_destroy, 1149). +-define(wxBrush_new_0, 1150). +-define(wxBrush_new_2, 1151). +-define(wxBrush_new_1, 1152). +-define(wxBrush_destruct, 1154). +-define(wxBrush_GetColour, 1155). +-define(wxBrush_GetStipple, 1156). +-define(wxBrush_GetStyle, 1157). +-define(wxBrush_IsHatch, 1158). +-define(wxBrush_IsOk, 1159). +-define(wxBrush_SetColour_1, 1160). +-define(wxBrush_SetColour_3, 1161). +-define(wxBrush_SetStipple, 1162). +-define(wxBrush_SetStyle, 1163). +-define(wxPen_new_0, 1164). +-define(wxPen_new_2, 1165). +-define(wxPen_destruct, 1166). +-define(wxPen_GetCap, 1167). +-define(wxPen_GetColour, 1168). +-define(wxPen_GetJoin, 1169). +-define(wxPen_GetStyle, 1170). +-define(wxPen_GetWidth, 1171). +-define(wxPen_IsOk, 1172). +-define(wxPen_SetCap, 1173). +-define(wxPen_SetColour_1, 1174). +-define(wxPen_SetColour_3, 1175). +-define(wxPen_SetJoin, 1176). +-define(wxPen_SetStyle, 1177). +-define(wxPen_SetWidth, 1178). +-define(wxRegion_new_0, 1179). +-define(wxRegion_new_4, 1180). +-define(wxRegion_new_2, 1181). +-define(wxRegion_new_1_1, 1182). +-define(wxRegion_new_1_0, 1184). +-define(wxRegion_destruct, 1186). +-define(wxRegion_Clear, 1187). +-define(wxRegion_Contains_2, 1188). +-define(wxRegion_Contains_1_0, 1189). +-define(wxRegion_Contains_4, 1190). +-define(wxRegion_Contains_1_1, 1191). +-define(wxRegion_ConvertToBitmap, 1192). +-define(wxRegion_GetBox, 1193). +-define(wxRegion_Intersect_4, 1194). +-define(wxRegion_Intersect_1_1, 1195). +-define(wxRegion_Intersect_1_0, 1196). +-define(wxRegion_IsEmpty, 1197). +-define(wxRegion_Subtract_4, 1198). +-define(wxRegion_Subtract_1_1, 1199). +-define(wxRegion_Subtract_1_0, 1200). +-define(wxRegion_Offset_2, 1201). +-define(wxRegion_Offset_1, 1202). +-define(wxRegion_Union_4, 1203). +-define(wxRegion_Union_1_2, 1204). +-define(wxRegion_Union_1_1, 1205). +-define(wxRegion_Union_1_0, 1206). +-define(wxRegion_Union_3, 1207). +-define(wxRegion_Xor_4, 1208). +-define(wxRegion_Xor_1_1, 1209). +-define(wxRegion_Xor_1_0, 1210). +-define(wxAcceleratorTable_new_0, 1211). +-define(wxAcceleratorTable_new_2, 1212). +-define(wxAcceleratorTable_destruct, 1213). +-define(wxAcceleratorTable_Ok, 1214). +-define(wxAcceleratorEntry_new_1_0, 1215). +-define(wxAcceleratorEntry_new_1_1, 1216). +-define(wxAcceleratorEntry_GetCommand, 1217). +-define(wxAcceleratorEntry_GetFlags, 1218). +-define(wxAcceleratorEntry_GetKeyCode, 1219). +-define(wxAcceleratorEntry_Set, 1220). +-define(wxAcceleratorEntry_destroy, 1221). +-define(wxCaret_new_3, 1226). +-define(wxCaret_new_2, 1227). +-define(wxCaret_destruct, 1229). +-define(wxCaret_Create_3, 1230). +-define(wxCaret_Create_2, 1231). +-define(wxCaret_GetBlinkTime, 1232). +-define(wxCaret_GetPosition, 1234). +-define(wxCaret_GetSize, 1236). +-define(wxCaret_GetWindow, 1237). +-define(wxCaret_Hide, 1238). +-define(wxCaret_IsOk, 1239). +-define(wxCaret_IsVisible, 1240). +-define(wxCaret_Move_2, 1241). +-define(wxCaret_Move_1, 1242). +-define(wxCaret_SetBlinkTime, 1243). +-define(wxCaret_SetSize_2, 1244). +-define(wxCaret_SetSize_1, 1245). +-define(wxCaret_Show, 1246). +-define(wxSizer_Add_2_1, 1247). +-define(wxSizer_Add_2_0, 1248). +-define(wxSizer_Add_3, 1249). +-define(wxSizer_Add_2_3, 1250). +-define(wxSizer_Add_2_2, 1251). +-define(wxSizer_AddSpacer, 1252). +-define(wxSizer_AddStretchSpacer, 1253). +-define(wxSizer_CalcMin, 1254). +-define(wxSizer_Clear, 1255). +-define(wxSizer_Detach_1_2, 1256). +-define(wxSizer_Detach_1_1, 1257). +-define(wxSizer_Detach_1_0, 1258). +-define(wxSizer_Fit, 1259). +-define(wxSizer_FitInside, 1260). +-define(wxSizer_GetChildren, 1261). +-define(wxSizer_GetItem_2_1, 1262). +-define(wxSizer_GetItem_2_0, 1263). +-define(wxSizer_GetItem_1, 1264). +-define(wxSizer_GetSize, 1265). +-define(wxSizer_GetPosition, 1266). +-define(wxSizer_GetMinSize, 1267). +-define(wxSizer_Hide_2_0, 1268). +-define(wxSizer_Hide_2_1, 1269). +-define(wxSizer_Hide_1, 1270). +-define(wxSizer_Insert_3_1, 1271). +-define(wxSizer_Insert_3_0, 1272). +-define(wxSizer_Insert_4, 1273). +-define(wxSizer_Insert_3_3, 1274). +-define(wxSizer_Insert_3_2, 1275). +-define(wxSizer_Insert_2, 1276). +-define(wxSizer_InsertSpacer, 1277). +-define(wxSizer_InsertStretchSpacer, 1278). +-define(wxSizer_IsShown_1_2, 1279). +-define(wxSizer_IsShown_1_1, 1280). +-define(wxSizer_IsShown_1_0, 1281). +-define(wxSizer_Layout, 1282). +-define(wxSizer_Prepend_2_1, 1283). +-define(wxSizer_Prepend_2_0, 1284). +-define(wxSizer_Prepend_3, 1285). +-define(wxSizer_Prepend_2_3, 1286). +-define(wxSizer_Prepend_2_2, 1287). +-define(wxSizer_Prepend_1, 1288). +-define(wxSizer_PrependSpacer, 1289). +-define(wxSizer_PrependStretchSpacer, 1290). +-define(wxSizer_RecalcSizes, 1291). +-define(wxSizer_Remove_1_1, 1292). +-define(wxSizer_Remove_1_0, 1293). +-define(wxSizer_Replace_3_1, 1294). +-define(wxSizer_Replace_3_0, 1295). +-define(wxSizer_Replace_2, 1296). +-define(wxSizer_SetDimension, 1297). +-define(wxSizer_SetMinSize_2, 1298). +-define(wxSizer_SetMinSize_1, 1299). +-define(wxSizer_SetItemMinSize_3_2, 1300). +-define(wxSizer_SetItemMinSize_2_2, 1301). +-define(wxSizer_SetItemMinSize_3_1, 1302). +-define(wxSizer_SetItemMinSize_2_1, 1303). +-define(wxSizer_SetItemMinSize_3_0, 1304). +-define(wxSizer_SetItemMinSize_2_0, 1305). +-define(wxSizer_SetSizeHints, 1306). +-define(wxSizer_SetVirtualSizeHints, 1307). +-define(wxSizer_Show_2_2, 1308). +-define(wxSizer_Show_2_1, 1309). +-define(wxSizer_Show_2_0, 1310). +-define(wxSizer_Show_1, 1311). +-define(wxSizerFlags_new, 1312). +-define(wxSizerFlags_Align, 1313). +-define(wxSizerFlags_Border_2, 1314). +-define(wxSizerFlags_Border_1, 1315). +-define(wxSizerFlags_Center, 1316). +-define(wxSizerFlags_Centre, 1317). +-define(wxSizerFlags_Expand, 1318). +-define(wxSizerFlags_Left, 1319). +-define(wxSizerFlags_Proportion, 1320). +-define(wxSizerFlags_Right, 1321). +-define(wxSizerFlags_destroy, 1322). +-define(wxSizerItem_new_5_1, 1323). +-define(wxSizerItem_new_2_1, 1324). +-define(wxSizerItem_new_5_0, 1325). +-define(wxSizerItem_new_2_0, 1326). +-define(wxSizerItem_new_6, 1327). +-define(wxSizerItem_new_3, 1328). +-define(wxSizerItem_new_0, 1329). +-define(wxSizerItem_destruct, 1330). +-define(wxSizerItem_CalcMin, 1331). +-define(wxSizerItem_DeleteWindows, 1332). +-define(wxSizerItem_DetachSizer, 1333). +-define(wxSizerItem_GetBorder, 1334). +-define(wxSizerItem_GetFlag, 1335). +-define(wxSizerItem_GetMinSize, 1336). +-define(wxSizerItem_GetPosition, 1337). +-define(wxSizerItem_GetProportion, 1338). +-define(wxSizerItem_GetRatio, 1339). +-define(wxSizerItem_GetRect, 1340). +-define(wxSizerItem_GetSize, 1341). +-define(wxSizerItem_GetSizer, 1342). +-define(wxSizerItem_GetSpacer, 1343). +-define(wxSizerItem_GetUserData, 1344). +-define(wxSizerItem_GetWindow, 1345). +-define(wxSizerItem_IsSizer, 1346). +-define(wxSizerItem_IsShown, 1347). +-define(wxSizerItem_IsSpacer, 1348). +-define(wxSizerItem_IsWindow, 1349). +-define(wxSizerItem_SetBorder, 1350). +-define(wxSizerItem_SetDimension, 1351). +-define(wxSizerItem_SetFlag, 1352). +-define(wxSizerItem_SetInitSize, 1353). +-define(wxSizerItem_SetMinSize_1, 1354). +-define(wxSizerItem_SetMinSize_2, 1355). +-define(wxSizerItem_SetProportion, 1356). +-define(wxSizerItem_SetRatio_2, 1357). +-define(wxSizerItem_SetRatio_1_1, 1358). +-define(wxSizerItem_SetRatio_1_0, 1359). +-define(wxSizerItem_SetSizer, 1360). +-define(wxSizerItem_SetSpacer_1, 1361). +-define(wxSizerItem_SetSpacer_2, 1362). +-define(wxSizerItem_SetWindow, 1363). +-define(wxSizerItem_Show, 1364). +-define(wxBoxSizer_new, 1365). +-define(wxBoxSizer_GetOrientation, 1366). +-define(wxBoxSizer_destroy, 1367). +-define(wxStaticBoxSizer_new_2, 1368). +-define(wxStaticBoxSizer_new_3, 1369). +-define(wxStaticBoxSizer_GetStaticBox, 1370). +-define(wxStaticBoxSizer_destroy, 1371). +-define(wxGridSizer_new_4, 1372). +-define(wxGridSizer_new_2, 1373). +-define(wxGridSizer_GetCols, 1374). +-define(wxGridSizer_GetHGap, 1375). +-define(wxGridSizer_GetRows, 1376). +-define(wxGridSizer_GetVGap, 1377). +-define(wxGridSizer_SetCols, 1378). +-define(wxGridSizer_SetHGap, 1379). +-define(wxGridSizer_SetRows, 1380). +-define(wxGridSizer_SetVGap, 1381). +-define(wxGridSizer_destroy, 1382). +-define(wxFlexGridSizer_new_4, 1383). +-define(wxFlexGridSizer_new_2, 1384). +-define(wxFlexGridSizer_AddGrowableCol, 1385). +-define(wxFlexGridSizer_AddGrowableRow, 1386). +-define(wxFlexGridSizer_GetFlexibleDirection, 1387). +-define(wxFlexGridSizer_GetNonFlexibleGrowMode, 1388). +-define(wxFlexGridSizer_RemoveGrowableCol, 1389). +-define(wxFlexGridSizer_RemoveGrowableRow, 1390). +-define(wxFlexGridSizer_SetFlexibleDirection, 1391). +-define(wxFlexGridSizer_SetNonFlexibleGrowMode, 1392). +-define(wxFlexGridSizer_destroy, 1393). +-define(wxGridBagSizer_new, 1394). +-define(wxGridBagSizer_Add_3_2, 1395). +-define(wxGridBagSizer_Add_3_1, 1396). +-define(wxGridBagSizer_Add_4, 1397). +-define(wxGridBagSizer_Add_1_0, 1398). +-define(wxGridBagSizer_Add_2_1, 1399). +-define(wxGridBagSizer_Add_2_0, 1400). +-define(wxGridBagSizer_Add_3_0, 1401). +-define(wxGridBagSizer_Add_1_1, 1402). +-define(wxGridBagSizer_CalcMin, 1403). +-define(wxGridBagSizer_CheckForIntersection_2, 1404). +-define(wxGridBagSizer_CheckForIntersection_3, 1405). +-define(wxGridBagSizer_FindItem_1_1, 1406). +-define(wxGridBagSizer_FindItem_1_0, 1407). +-define(wxGridBagSizer_FindItemAtPoint, 1408). +-define(wxGridBagSizer_FindItemAtPosition, 1409). +-define(wxGridBagSizer_FindItemWithData, 1410). +-define(wxGridBagSizer_GetCellSize, 1411). +-define(wxGridBagSizer_GetEmptyCellSize, 1412). +-define(wxGridBagSizer_GetItemPosition_1_2, 1413). +-define(wxGridBagSizer_GetItemPosition_1_1, 1414). +-define(wxGridBagSizer_GetItemPosition_1_0, 1415). +-define(wxGridBagSizer_GetItemSpan_1_2, 1416). +-define(wxGridBagSizer_GetItemSpan_1_1, 1417). +-define(wxGridBagSizer_GetItemSpan_1_0, 1418). +-define(wxGridBagSizer_SetEmptyCellSize, 1419). +-define(wxGridBagSizer_SetItemPosition_2_2, 1420). +-define(wxGridBagSizer_SetItemPosition_2_1, 1421). +-define(wxGridBagSizer_SetItemPosition_2_0, 1422). +-define(wxGridBagSizer_SetItemSpan_2_2, 1423). +-define(wxGridBagSizer_SetItemSpan_2_1, 1424). +-define(wxGridBagSizer_SetItemSpan_2_0, 1425). +-define(wxGridBagSizer_destroy, 1426). +-define(wxStdDialogButtonSizer_new, 1427). +-define(wxStdDialogButtonSizer_AddButton, 1428). +-define(wxStdDialogButtonSizer_Realize, 1429). +-define(wxStdDialogButtonSizer_SetAffirmativeButton, 1430). +-define(wxStdDialogButtonSizer_SetCancelButton, 1431). +-define(wxStdDialogButtonSizer_SetNegativeButton, 1432). +-define(wxStdDialogButtonSizer_destroy, 1433). +-define(wxFont_new_0, 1434). +-define(wxFont_new_1, 1435). +-define(wxFont_new_5, 1436). +-define(wxFont_destruct, 1438). +-define(wxFont_IsFixedWidth, 1439). +-define(wxFont_GetDefaultEncoding, 1440). +-define(wxFont_GetFaceName, 1441). +-define(wxFont_GetFamily, 1442). +-define(wxFont_GetNativeFontInfoDesc, 1443). +-define(wxFont_GetNativeFontInfoUserDesc, 1444). +-define(wxFont_GetPointSize, 1445). +-define(wxFont_GetStyle, 1446). +-define(wxFont_GetUnderlined, 1447). +-define(wxFont_GetWeight, 1448). +-define(wxFont_Ok, 1449). +-define(wxFont_SetDefaultEncoding, 1450). +-define(wxFont_SetFaceName, 1451). +-define(wxFont_SetFamily, 1452). +-define(wxFont_SetPointSize, 1453). +-define(wxFont_SetStyle, 1454). +-define(wxFont_SetUnderlined, 1455). +-define(wxFont_SetWeight, 1456). +-define(wxToolTip_Enable, 1457). +-define(wxToolTip_SetDelay, 1458). +-define(wxToolTip_new, 1459). +-define(wxToolTip_SetTip, 1460). +-define(wxToolTip_GetTip, 1461). +-define(wxToolTip_GetWindow, 1462). +-define(wxToolTip_destroy, 1463). +-define(wxButton_new_3, 1465). +-define(wxButton_new_0, 1466). +-define(wxButton_destruct, 1467). +-define(wxButton_Create, 1468). +-define(wxButton_GetDefaultSize, 1469). +-define(wxButton_SetDefault, 1470). +-define(wxButton_SetLabel, 1471). +-define(wxBitmapButton_new_4, 1473). +-define(wxBitmapButton_new_0, 1474). +-define(wxBitmapButton_Create, 1475). +-define(wxBitmapButton_GetBitmapDisabled, 1476). +-define(wxBitmapButton_GetBitmapFocus, 1478). +-define(wxBitmapButton_GetBitmapLabel, 1480). +-define(wxBitmapButton_GetBitmapSelected, 1482). +-define(wxBitmapButton_SetBitmapDisabled, 1484). +-define(wxBitmapButton_SetBitmapFocus, 1485). +-define(wxBitmapButton_SetBitmapLabel, 1486). +-define(wxBitmapButton_SetBitmapSelected, 1487). +-define(wxBitmapButton_destroy, 1488). +-define(wxToggleButton_new_0, 1489). +-define(wxToggleButton_new_4, 1490). +-define(wxToggleButton_Create, 1491). +-define(wxToggleButton_GetValue, 1492). +-define(wxToggleButton_SetValue, 1493). +-define(wxToggleButton_destroy, 1494). +-define(wxCalendarCtrl_new_0, 1495). +-define(wxCalendarCtrl_new_3, 1496). +-define(wxCalendarCtrl_Create, 1497). +-define(wxCalendarCtrl_destruct, 1498). +-define(wxCalendarCtrl_SetDate, 1499). +-define(wxCalendarCtrl_GetDate, 1500). +-define(wxCalendarCtrl_EnableYearChange, 1501). +-define(wxCalendarCtrl_EnableMonthChange, 1502). +-define(wxCalendarCtrl_EnableHolidayDisplay, 1503). +-define(wxCalendarCtrl_SetHeaderColours, 1504). +-define(wxCalendarCtrl_GetHeaderColourFg, 1505). +-define(wxCalendarCtrl_GetHeaderColourBg, 1506). +-define(wxCalendarCtrl_SetHighlightColours, 1507). +-define(wxCalendarCtrl_GetHighlightColourFg, 1508). +-define(wxCalendarCtrl_GetHighlightColourBg, 1509). +-define(wxCalendarCtrl_SetHolidayColours, 1510). +-define(wxCalendarCtrl_GetHolidayColourFg, 1511). +-define(wxCalendarCtrl_GetHolidayColourBg, 1512). +-define(wxCalendarCtrl_GetAttr, 1513). +-define(wxCalendarCtrl_SetAttr, 1514). +-define(wxCalendarCtrl_SetHoliday, 1515). +-define(wxCalendarCtrl_ResetAttr, 1516). +-define(wxCalendarCtrl_HitTest, 1517). +-define(wxCalendarDateAttr_new_0, 1518). +-define(wxCalendarDateAttr_new_2_1, 1519). +-define(wxCalendarDateAttr_new_2_0, 1520). +-define(wxCalendarDateAttr_SetTextColour, 1521). +-define(wxCalendarDateAttr_SetBackgroundColour, 1522). +-define(wxCalendarDateAttr_SetBorderColour, 1523). +-define(wxCalendarDateAttr_SetFont, 1524). +-define(wxCalendarDateAttr_SetBorder, 1525). +-define(wxCalendarDateAttr_SetHoliday, 1526). +-define(wxCalendarDateAttr_HasTextColour, 1527). +-define(wxCalendarDateAttr_HasBackgroundColour, 1528). +-define(wxCalendarDateAttr_HasBorderColour, 1529). +-define(wxCalendarDateAttr_HasFont, 1530). +-define(wxCalendarDateAttr_HasBorder, 1531). +-define(wxCalendarDateAttr_IsHoliday, 1532). +-define(wxCalendarDateAttr_GetTextColour, 1533). +-define(wxCalendarDateAttr_GetBackgroundColour, 1534). +-define(wxCalendarDateAttr_GetBorderColour, 1535). +-define(wxCalendarDateAttr_GetFont, 1536). +-define(wxCalendarDateAttr_GetBorder, 1537). +-define(wxCalendarDateAttr_destroy, 1538). +-define(wxCheckBox_new_4, 1540). +-define(wxCheckBox_new_0, 1541). +-define(wxCheckBox_Create, 1542). +-define(wxCheckBox_GetValue, 1543). +-define(wxCheckBox_Get3StateValue, 1544). +-define(wxCheckBox_Is3rdStateAllowedForUser, 1545). +-define(wxCheckBox_Is3State, 1546). +-define(wxCheckBox_IsChecked, 1547). +-define(wxCheckBox_SetValue, 1548). +-define(wxCheckBox_Set3StateValue, 1549). +-define(wxCheckBox_destroy, 1550). +-define(wxCheckListBox_new_0, 1551). +-define(wxCheckListBox_new_3, 1553). +-define(wxCheckListBox_Check, 1554). +-define(wxCheckListBox_IsChecked, 1555). +-define(wxCheckListBox_destroy, 1556). +-define(wxChoice_new_3, 1559). +-define(wxChoice_new_0, 1560). +-define(wxChoice_destruct, 1562). +-define(wxChoice_Create, 1564). +-define(wxChoice_Delete, 1565). +-define(wxChoice_GetColumns, 1566). +-define(wxChoice_SetColumns, 1567). +-define(wxComboBox_new_0, 1568). +-define(wxComboBox_new_3, 1570). +-define(wxComboBox_destruct, 1571). +-define(wxComboBox_Create, 1573). +-define(wxComboBox_CanCopy, 1574). +-define(wxComboBox_CanCut, 1575). +-define(wxComboBox_CanPaste, 1576). +-define(wxComboBox_CanRedo, 1577). +-define(wxComboBox_CanUndo, 1578). +-define(wxComboBox_Copy, 1579). +-define(wxComboBox_Cut, 1580). +-define(wxComboBox_GetInsertionPoint, 1581). +-define(wxComboBox_GetLastPosition, 1582). +-define(wxComboBox_GetValue, 1583). +-define(wxComboBox_Paste, 1584). +-define(wxComboBox_Redo, 1585). +-define(wxComboBox_Replace, 1586). +-define(wxComboBox_Remove, 1587). +-define(wxComboBox_SetInsertionPoint, 1588). +-define(wxComboBox_SetInsertionPointEnd, 1589). +-define(wxComboBox_SetSelection_1, 1590). +-define(wxComboBox_SetSelection_2, 1591). +-define(wxComboBox_SetValue, 1592). +-define(wxComboBox_Undo, 1593). +-define(wxGauge_new_0, 1594). +-define(wxGauge_new_4, 1595). +-define(wxGauge_Create, 1596). +-define(wxGauge_GetBezelFace, 1597). +-define(wxGauge_GetRange, 1598). +-define(wxGauge_GetShadowWidth, 1599). +-define(wxGauge_GetValue, 1600). +-define(wxGauge_IsVertical, 1601). +-define(wxGauge_SetBezelFace, 1602). +-define(wxGauge_SetRange, 1603). +-define(wxGauge_SetShadowWidth, 1604). +-define(wxGauge_SetValue, 1605). +-define(wxGauge_Pulse, 1606). +-define(wxGauge_destroy, 1607). +-define(wxGenericDirCtrl_new_0, 1608). +-define(wxGenericDirCtrl_new_2, 1609). +-define(wxGenericDirCtrl_destruct, 1610). +-define(wxGenericDirCtrl_Create, 1611). +-define(wxGenericDirCtrl_Init, 1612). +-define(wxGenericDirCtrl_CollapseTree, 1613). +-define(wxGenericDirCtrl_ExpandPath, 1614). +-define(wxGenericDirCtrl_GetDefaultPath, 1615). +-define(wxGenericDirCtrl_GetPath, 1616). +-define(wxGenericDirCtrl_GetFilePath, 1617). +-define(wxGenericDirCtrl_GetFilter, 1618). +-define(wxGenericDirCtrl_GetFilterIndex, 1619). +-define(wxGenericDirCtrl_GetRootId, 1620). +-define(wxGenericDirCtrl_GetTreeCtrl, 1621). +-define(wxGenericDirCtrl_ReCreateTree, 1622). +-define(wxGenericDirCtrl_SetDefaultPath, 1623). +-define(wxGenericDirCtrl_SetFilter, 1624). +-define(wxGenericDirCtrl_SetFilterIndex, 1625). +-define(wxGenericDirCtrl_SetPath, 1626). +-define(wxStaticBox_new_4, 1628). +-define(wxStaticBox_new_0, 1629). +-define(wxStaticBox_Create, 1630). +-define(wxStaticBox_destroy, 1631). +-define(wxStaticLine_new_2, 1633). +-define(wxStaticLine_new_0, 1634). +-define(wxStaticLine_Create, 1635). +-define(wxStaticLine_IsVertical, 1636). +-define(wxStaticLine_GetDefaultSize, 1637). +-define(wxStaticLine_destroy, 1638). +-define(wxListBox_new_3, 1641). +-define(wxListBox_new_0, 1642). +-define(wxListBox_destruct, 1644). +-define(wxListBox_Create, 1646). +-define(wxListBox_Deselect, 1647). +-define(wxListBox_GetSelections, 1648). +-define(wxListBox_InsertItems, 1649). +-define(wxListBox_IsSelected, 1650). +-define(wxListBox_Set, 1652). +-define(wxListBox_HitTest, 1653). +-define(wxListBox_SetFirstItem_1_0, 1654). +-define(wxListBox_SetFirstItem_1_1, 1655). +-define(wxListCtrl_new_0, 1656). +-define(wxListCtrl_new_2, 1657). +-define(wxListCtrl_Arrange, 1658). +-define(wxListCtrl_AssignImageList, 1659). +-define(wxListCtrl_ClearAll, 1660). +-define(wxListCtrl_Create, 1661). +-define(wxListCtrl_DeleteAllItems, 1662). +-define(wxListCtrl_DeleteColumn, 1663). +-define(wxListCtrl_DeleteItem, 1664). +-define(wxListCtrl_EditLabel, 1665). +-define(wxListCtrl_EnsureVisible, 1666). +-define(wxListCtrl_FindItem_3_0, 1667). +-define(wxListCtrl_FindItem_3_1, 1668). +-define(wxListCtrl_GetColumn, 1669). +-define(wxListCtrl_GetColumnCount, 1670). +-define(wxListCtrl_GetColumnWidth, 1671). +-define(wxListCtrl_GetCountPerPage, 1672). +-define(wxListCtrl_GetEditControl, 1673). +-define(wxListCtrl_GetImageList, 1674). +-define(wxListCtrl_GetItem, 1675). +-define(wxListCtrl_GetItemBackgroundColour, 1676). +-define(wxListCtrl_GetItemCount, 1677). +-define(wxListCtrl_GetItemData, 1678). +-define(wxListCtrl_GetItemFont, 1679). +-define(wxListCtrl_GetItemPosition, 1680). +-define(wxListCtrl_GetItemRect, 1681). +-define(wxListCtrl_GetItemSpacing, 1682). +-define(wxListCtrl_GetItemState, 1683). +-define(wxListCtrl_GetItemText, 1684). +-define(wxListCtrl_GetItemTextColour, 1685). +-define(wxListCtrl_GetNextItem, 1686). +-define(wxListCtrl_GetSelectedItemCount, 1687). +-define(wxListCtrl_GetTextColour, 1688). +-define(wxListCtrl_GetTopItem, 1689). +-define(wxListCtrl_GetViewRect, 1690). +-define(wxListCtrl_HitTest, 1691). +-define(wxListCtrl_InsertColumn_2, 1692). +-define(wxListCtrl_InsertColumn_3, 1693). +-define(wxListCtrl_InsertItem_1, 1694). +-define(wxListCtrl_InsertItem_2_1, 1695). +-define(wxListCtrl_InsertItem_2_0, 1696). +-define(wxListCtrl_InsertItem_3, 1697). +-define(wxListCtrl_RefreshItem, 1698). +-define(wxListCtrl_RefreshItems, 1699). +-define(wxListCtrl_ScrollList, 1700). +-define(wxListCtrl_SetBackgroundColour, 1701). +-define(wxListCtrl_SetColumn, 1702). +-define(wxListCtrl_SetColumnWidth, 1703). +-define(wxListCtrl_SetImageList, 1704). +-define(wxListCtrl_SetItem_1, 1705). +-define(wxListCtrl_SetItem_4, 1706). +-define(wxListCtrl_SetItemBackgroundColour, 1707). +-define(wxListCtrl_SetItemCount, 1708). +-define(wxListCtrl_SetItemData, 1709). +-define(wxListCtrl_SetItemFont, 1710). +-define(wxListCtrl_SetItemImage, 1711). +-define(wxListCtrl_SetItemColumnImage, 1712). +-define(wxListCtrl_SetItemPosition, 1713). +-define(wxListCtrl_SetItemState, 1714). +-define(wxListCtrl_SetItemText, 1715). +-define(wxListCtrl_SetItemTextColour, 1716). +-define(wxListCtrl_SetSingleStyle, 1717). +-define(wxListCtrl_SetTextColour, 1718). +-define(wxListCtrl_SetWindowStyleFlag, 1719). +-define(wxListCtrl_SortItems, 1720). +-define(wxListCtrl_destroy, 1721). +-define(wxListView_ClearColumnImage, 1722). +-define(wxListView_Focus, 1723). +-define(wxListView_GetFirstSelected, 1724). +-define(wxListView_GetFocusedItem, 1725). +-define(wxListView_GetNextSelected, 1726). +-define(wxListView_IsSelected, 1727). +-define(wxListView_Select, 1728). +-define(wxListView_SetColumnImage, 1729). +-define(wxListItem_new_0, 1730). +-define(wxListItem_new_1, 1731). +-define(wxListItem_destruct, 1732). +-define(wxListItem_Clear, 1733). +-define(wxListItem_GetAlign, 1734). +-define(wxListItem_GetBackgroundColour, 1735). +-define(wxListItem_GetColumn, 1736). +-define(wxListItem_GetFont, 1737). +-define(wxListItem_GetId, 1738). +-define(wxListItem_GetImage, 1739). +-define(wxListItem_GetMask, 1740). +-define(wxListItem_GetState, 1741). +-define(wxListItem_GetText, 1742). +-define(wxListItem_GetTextColour, 1743). +-define(wxListItem_GetWidth, 1744). +-define(wxListItem_SetAlign, 1745). +-define(wxListItem_SetBackgroundColour, 1746). +-define(wxListItem_SetColumn, 1747). +-define(wxListItem_SetFont, 1748). +-define(wxListItem_SetId, 1749). +-define(wxListItem_SetImage, 1750). +-define(wxListItem_SetMask, 1751). +-define(wxListItem_SetState, 1752). +-define(wxListItem_SetStateMask, 1753). +-define(wxListItem_SetText, 1754). +-define(wxListItem_SetTextColour, 1755). +-define(wxListItem_SetWidth, 1756). +-define(wxImageList_new_0, 1757). +-define(wxImageList_new_3, 1758). +-define(wxImageList_Add_1, 1759). +-define(wxImageList_Add_2_0, 1760). +-define(wxImageList_Add_2_1, 1761). +-define(wxImageList_Create, 1762). +-define(wxImageList_Draw, 1764). +-define(wxImageList_GetBitmap, 1765). +-define(wxImageList_GetIcon, 1766). +-define(wxImageList_GetImageCount, 1767). +-define(wxImageList_GetSize, 1768). +-define(wxImageList_Remove, 1769). +-define(wxImageList_RemoveAll, 1770). +-define(wxImageList_Replace_2, 1771). +-define(wxImageList_Replace_3, 1772). +-define(wxImageList_destroy, 1773). +-define(wxTextAttr_new_0, 1774). +-define(wxTextAttr_new_2, 1775). +-define(wxTextAttr_GetAlignment, 1776). +-define(wxTextAttr_GetBackgroundColour, 1777). +-define(wxTextAttr_GetFont, 1778). +-define(wxTextAttr_GetLeftIndent, 1779). +-define(wxTextAttr_GetLeftSubIndent, 1780). +-define(wxTextAttr_GetRightIndent, 1781). +-define(wxTextAttr_GetTabs, 1782). +-define(wxTextAttr_GetTextColour, 1783). +-define(wxTextAttr_HasBackgroundColour, 1784). +-define(wxTextAttr_HasFont, 1785). +-define(wxTextAttr_HasTextColour, 1786). +-define(wxTextAttr_GetFlags, 1787). +-define(wxTextAttr_IsDefault, 1788). +-define(wxTextAttr_SetAlignment, 1789). +-define(wxTextAttr_SetBackgroundColour, 1790). +-define(wxTextAttr_SetFlags, 1791). +-define(wxTextAttr_SetFont, 1792). +-define(wxTextAttr_SetLeftIndent, 1793). +-define(wxTextAttr_SetRightIndent, 1794). +-define(wxTextAttr_SetTabs, 1795). +-define(wxTextAttr_SetTextColour, 1796). +-define(wxTextAttr_destroy, 1797). +-define(wxTextCtrl_new_3, 1799). +-define(wxTextCtrl_new_0, 1800). +-define(wxTextCtrl_destruct, 1802). +-define(wxTextCtrl_AppendText, 1803). +-define(wxTextCtrl_CanCopy, 1804). +-define(wxTextCtrl_CanCut, 1805). +-define(wxTextCtrl_CanPaste, 1806). +-define(wxTextCtrl_CanRedo, 1807). +-define(wxTextCtrl_CanUndo, 1808). +-define(wxTextCtrl_Clear, 1809). +-define(wxTextCtrl_Copy, 1810). +-define(wxTextCtrl_Create, 1811). +-define(wxTextCtrl_Cut, 1812). +-define(wxTextCtrl_DiscardEdits, 1813). +-define(wxTextCtrl_EmulateKeyPress, 1814). +-define(wxTextCtrl_GetDefaultStyle, 1815). +-define(wxTextCtrl_GetInsertionPoint, 1816). +-define(wxTextCtrl_GetLastPosition, 1817). +-define(wxTextCtrl_GetLineLength, 1818). +-define(wxTextCtrl_GetLineText, 1819). +-define(wxTextCtrl_GetNumberOfLines, 1820). +-define(wxTextCtrl_GetRange, 1821). +-define(wxTextCtrl_GetSelection, 1822). +-define(wxTextCtrl_GetStringSelection, 1823). +-define(wxTextCtrl_GetStyle, 1824). +-define(wxTextCtrl_GetValue, 1825). +-define(wxTextCtrl_IsEditable, 1826). +-define(wxTextCtrl_IsModified, 1827). +-define(wxTextCtrl_IsMultiLine, 1828). +-define(wxTextCtrl_IsSingleLine, 1829). +-define(wxTextCtrl_LoadFile, 1830). +-define(wxTextCtrl_MarkDirty, 1831). +-define(wxTextCtrl_Paste, 1832). +-define(wxTextCtrl_PositionToXY, 1833). +-define(wxTextCtrl_Redo, 1834). +-define(wxTextCtrl_Remove, 1835). +-define(wxTextCtrl_Replace, 1836). +-define(wxTextCtrl_SaveFile, 1837). +-define(wxTextCtrl_SetDefaultStyle, 1838). +-define(wxTextCtrl_SetEditable, 1839). +-define(wxTextCtrl_SetInsertionPoint, 1840). +-define(wxTextCtrl_SetInsertionPointEnd, 1841). +-define(wxTextCtrl_SetMaxLength, 1843). +-define(wxTextCtrl_SetSelection, 1844). +-define(wxTextCtrl_SetStyle, 1845). +-define(wxTextCtrl_SetValue, 1846). +-define(wxTextCtrl_ShowPosition, 1847). +-define(wxTextCtrl_Undo, 1848). +-define(wxTextCtrl_WriteText, 1849). +-define(wxTextCtrl_XYToPosition, 1850). +-define(wxNotebook_new_0, 1853). +-define(wxNotebook_new_3, 1854). +-define(wxNotebook_destruct, 1855). +-define(wxNotebook_AddPage, 1856). +-define(wxNotebook_AdvanceSelection, 1857). +-define(wxNotebook_AssignImageList, 1858). +-define(wxNotebook_Create, 1859). +-define(wxNotebook_DeleteAllPages, 1860). +-define(wxNotebook_DeletePage, 1861). +-define(wxNotebook_RemovePage, 1862). +-define(wxNotebook_GetCurrentPage, 1863). +-define(wxNotebook_GetImageList, 1864). +-define(wxNotebook_GetPage, 1866). +-define(wxNotebook_GetPageCount, 1867). +-define(wxNotebook_GetPageImage, 1868). +-define(wxNotebook_GetPageText, 1869). +-define(wxNotebook_GetRowCount, 1870). +-define(wxNotebook_GetSelection, 1871). +-define(wxNotebook_GetThemeBackgroundColour, 1872). +-define(wxNotebook_HitTest, 1874). +-define(wxNotebook_InsertPage, 1876). +-define(wxNotebook_SetImageList, 1877). +-define(wxNotebook_SetPadding, 1878). +-define(wxNotebook_SetPageSize, 1879). +-define(wxNotebook_SetPageImage, 1880). +-define(wxNotebook_SetPageText, 1881). +-define(wxNotebook_SetSelection, 1882). +-define(wxNotebook_ChangeSelection, 1883). +-define(wxChoicebook_new_0, 1884). +-define(wxChoicebook_new_3, 1885). +-define(wxChoicebook_AddPage, 1886). +-define(wxChoicebook_AdvanceSelection, 1887). +-define(wxChoicebook_AssignImageList, 1888). +-define(wxChoicebook_Create, 1889). +-define(wxChoicebook_DeleteAllPages, 1890). +-define(wxChoicebook_DeletePage, 1891). +-define(wxChoicebook_RemovePage, 1892). +-define(wxChoicebook_GetCurrentPage, 1893). +-define(wxChoicebook_GetImageList, 1894). +-define(wxChoicebook_GetPage, 1896). +-define(wxChoicebook_GetPageCount, 1897). +-define(wxChoicebook_GetPageImage, 1898). +-define(wxChoicebook_GetPageText, 1899). +-define(wxChoicebook_GetSelection, 1900). +-define(wxChoicebook_HitTest, 1901). +-define(wxChoicebook_InsertPage, 1902). +-define(wxChoicebook_SetImageList, 1903). +-define(wxChoicebook_SetPageSize, 1904). +-define(wxChoicebook_SetPageImage, 1905). +-define(wxChoicebook_SetPageText, 1906). +-define(wxChoicebook_SetSelection, 1907). +-define(wxChoicebook_ChangeSelection, 1908). +-define(wxChoicebook_destroy, 1909). +-define(wxToolbook_new_0, 1910). +-define(wxToolbook_new_3, 1911). +-define(wxToolbook_AddPage, 1912). +-define(wxToolbook_AdvanceSelection, 1913). +-define(wxToolbook_AssignImageList, 1914). +-define(wxToolbook_Create, 1915). +-define(wxToolbook_DeleteAllPages, 1916). +-define(wxToolbook_DeletePage, 1917). +-define(wxToolbook_RemovePage, 1918). +-define(wxToolbook_GetCurrentPage, 1919). +-define(wxToolbook_GetImageList, 1920). +-define(wxToolbook_GetPage, 1922). +-define(wxToolbook_GetPageCount, 1923). +-define(wxToolbook_GetPageImage, 1924). +-define(wxToolbook_GetPageText, 1925). +-define(wxToolbook_GetSelection, 1926). +-define(wxToolbook_HitTest, 1928). +-define(wxToolbook_InsertPage, 1929). +-define(wxToolbook_SetImageList, 1930). +-define(wxToolbook_SetPageSize, 1931). +-define(wxToolbook_SetPageImage, 1932). +-define(wxToolbook_SetPageText, 1933). +-define(wxToolbook_SetSelection, 1934). +-define(wxToolbook_ChangeSelection, 1935). +-define(wxToolbook_destroy, 1936). +-define(wxListbook_new_0, 1937). +-define(wxListbook_new_3, 1938). +-define(wxListbook_AddPage, 1939). +-define(wxListbook_AdvanceSelection, 1940). +-define(wxListbook_AssignImageList, 1941). +-define(wxListbook_Create, 1942). +-define(wxListbook_DeleteAllPages, 1943). +-define(wxListbook_DeletePage, 1944). +-define(wxListbook_RemovePage, 1945). +-define(wxListbook_GetCurrentPage, 1946). +-define(wxListbook_GetImageList, 1947). +-define(wxListbook_GetPage, 1949). +-define(wxListbook_GetPageCount, 1950). +-define(wxListbook_GetPageImage, 1951). +-define(wxListbook_GetPageText, 1952). +-define(wxListbook_GetSelection, 1953). +-define(wxListbook_HitTest, 1955). +-define(wxListbook_InsertPage, 1956). +-define(wxListbook_SetImageList, 1957). +-define(wxListbook_SetPageSize, 1958). +-define(wxListbook_SetPageImage, 1959). +-define(wxListbook_SetPageText, 1960). +-define(wxListbook_SetSelection, 1961). +-define(wxListbook_ChangeSelection, 1962). +-define(wxListbook_destroy, 1963). +-define(wxTreebook_new_0, 1964). +-define(wxTreebook_new_3, 1965). +-define(wxTreebook_AddPage, 1966). +-define(wxTreebook_AdvanceSelection, 1967). +-define(wxTreebook_AssignImageList, 1968). +-define(wxTreebook_Create, 1969). +-define(wxTreebook_DeleteAllPages, 1970). +-define(wxTreebook_DeletePage, 1971). +-define(wxTreebook_RemovePage, 1972). +-define(wxTreebook_GetCurrentPage, 1973). +-define(wxTreebook_GetImageList, 1974). +-define(wxTreebook_GetPage, 1976). +-define(wxTreebook_GetPageCount, 1977). +-define(wxTreebook_GetPageImage, 1978). +-define(wxTreebook_GetPageText, 1979). +-define(wxTreebook_GetSelection, 1980). +-define(wxTreebook_ExpandNode, 1981). +-define(wxTreebook_IsNodeExpanded, 1982). +-define(wxTreebook_HitTest, 1984). +-define(wxTreebook_InsertPage, 1985). +-define(wxTreebook_InsertSubPage, 1986). +-define(wxTreebook_SetImageList, 1987). +-define(wxTreebook_SetPageSize, 1988). +-define(wxTreebook_SetPageImage, 1989). +-define(wxTreebook_SetPageText, 1990). +-define(wxTreebook_SetSelection, 1991). +-define(wxTreebook_ChangeSelection, 1992). +-define(wxTreebook_destroy, 1993). +-define(wxTreeCtrl_new_2, 1996). +-define(wxTreeCtrl_new_0, 1997). +-define(wxTreeCtrl_destruct, 1999). +-define(wxTreeCtrl_AddRoot, 2000). +-define(wxTreeCtrl_AppendItem, 2001). +-define(wxTreeCtrl_AssignImageList, 2002). +-define(wxTreeCtrl_AssignStateImageList, 2003). +-define(wxTreeCtrl_Collapse, 2004). +-define(wxTreeCtrl_CollapseAndReset, 2005). +-define(wxTreeCtrl_Create, 2006). +-define(wxTreeCtrl_Delete, 2007). +-define(wxTreeCtrl_DeleteAllItems, 2008). +-define(wxTreeCtrl_DeleteChildren, 2009). +-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/src/wx.app.src b/lib/wx/src/wx.app.src new file mode 100644 index 0000000000..e13982b0c1 --- /dev/null +++ b/lib/wx/src/wx.app.src @@ -0,0 +1,37 @@ +%% This is an -*- erlang -*- file. +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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, wx, + [{description, "Yet another graphics system"}, + {vsn, "%VSN%"}, + {modules, + [ + %% Generated modules + %GEN_MODS% + %% Handcrafted modules + wx, + wx_object, + wxe_master, + wxe_server, + wxe_util + ]}, + {registered, []}, + {applications, [stdlib, kernel]}, + {env, []} + ]}. diff --git a/lib/wx/src/wx.appup.src b/lib/wx/src/wx.appup.src new file mode 100644 index 0000000000..c02edd2afb --- /dev/null +++ b/lib/wx/src/wx.appup.src @@ -0,0 +1,22 @@ +%% This is an -*- erlang -*- file. +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% + +{"%VSN%", + [ ] +}. diff --git a/lib/wx/src/wx_object.erl b/lib/wx/src/wx_object.erl index 1f0b7922a0..bfd38960dd 100644 --- a/lib/wx/src/wx_object.erl +++ b/lib/wx/src/wx_object.erl @@ -1,19 +1,19 @@ %% %% %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 %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %%%------------------------------------------------------------------- %%% File : wx_object.erl @@ -321,7 +321,8 @@ loop(Parent, Name, State, Mod, Time, Debug) -> _Msg when Debug =:= [] -> handle_msg(Msg, Parent, Name, State, Mod); _Msg -> - Debug1 = sys:handle_debug(Debug, {gen_server, print_event}, Name, {in, Msg}), + Debug1 = sys:handle_debug(Debug, fun print_event/3, + Name, {in, Msg}), handle_msg(Msg, Parent, Name, State, Mod, Debug1) end. @@ -410,12 +411,12 @@ handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod, Debug) -> Debug1 = reply(Name, From, Reply, NState, Debug), loop(Parent, Name, NState, Mod, Time1, Debug1); {noreply, NState} -> - Debug1 = sys:handle_debug(Debug, {gen_server, print_event}, Name, - {noreply, NState}), + Debug1 = sys:handle_debug(Debug, fun print_event/3, + Name, {noreply, NState}), loop(Parent, Name, NState, Mod, infinity, Debug1); {noreply, NState, Time1} -> - Debug1 = sys:handle_debug(Debug, {gen_server, print_event}, Name, - {noreply, NState}), + Debug1 = sys:handle_debug(Debug, fun print_event/3, + Name, {noreply, NState}), loop(Parent, Name, NState, Mod, Time1, Debug1); {stop, Reason, Reply, NState} -> {'EXIT', R} = @@ -437,12 +438,12 @@ handle_no_reply({noreply, NState}, Parent, Name, _Msg, Mod, _State, []) -> handle_no_reply({noreply, NState, Time1}, Parent, Name, _Msg, Mod, _State, []) -> loop(Parent, Name, NState, Mod, Time1, []); handle_no_reply({noreply, NState}, Parent, Name, _Msg, Mod, _State, Debug) -> - Debug1 = sys:handle_debug(Debug, {gen_server, print_event}, Name, - {noreply, NState}), + Debug1 = sys:handle_debug(Debug, fun print_event/3, + Name, {noreply, NState}), loop(Parent, Name, NState, Mod, infinity, Debug1); handle_no_reply({noreply, NState, Time1}, Parent, Name, _Msg, Mod, _State, Debug) -> - Debug1 = sys:handle_debug(Debug, {gen_server, print_event}, Name, - {noreply, NState}), + Debug1 = sys:handle_debug(Debug, fun print_event/3, + Name, {noreply, NState}), loop(Parent, Name, NState, Mod, Time1, Debug1); handle_no_reply(Reply, _Parent, Name, Msg, Mod, State, Debug) -> handle_common_reply(Reply, Name, Msg, Mod, State,Debug). @@ -462,8 +463,8 @@ handle_common_reply(Reply, Name, Msg, Mod, State, Debug) -> %% @hidden reply(Name, {To, Tag}, Reply, State, Debug) -> reply({To, Tag}, Reply), - sys:handle_debug(Debug, {gen_server, print_event}, Name, - {out, Reply, To, State} ). + sys:handle_debug(Debug, fun print_event/3, + Name, {out, Reply, To, State}). %%----------------------------------------------------------------- @@ -485,6 +486,29 @@ system_code_change([Name, State, Mod, Time], _Module, OldVsn, Extra) -> Else -> Else end. +%%----------------------------------------------------------------- +%% Format debug messages. Print them as the call-back module sees +%% them, not as the real erlang messages. Use trace for that. +%%----------------------------------------------------------------- +print_event(Dev, {in, Msg}, Name) -> + case Msg of + {'$gen_call', {From, _Tag}, Call} -> + io:format(Dev, "*DBG* ~p got call ~p from ~w~n", + [Name, Call, From]); + {'$gen_cast', Cast} -> + io:format(Dev, "*DBG* ~p got cast ~p~n", + [Name, Cast]); + _ -> + io:format(Dev, "*DBG* ~p got ~p~n", [Name, Msg]) + end; +print_event(Dev, {out, Msg, To, State}, Name) -> + io:format(Dev, "*DBG* ~p sent ~p to ~w, new state ~w~n", + [Name, Msg, To, State]); +print_event(Dev, {noreply, State}, Name) -> + io:format(Dev, "*DBG* ~p new state ~w~n", [Name, State]); +print_event(Dev, Event, Name) -> + io:format(Dev, "*DBG* ~p dbg ~p~n", [Name, Event]). + %%% --------------------------------------------------- %%% Terminate the server. %%% --------------------------------------------------- @@ -581,12 +605,15 @@ dbg_opts(Name, Opts) -> %%----------------------------------------------------------------- format_status(Opt, StatusData) -> [PDict, SysState, Parent, Debug, [Name, State, Mod, _Time]] = StatusData, - NameTag = if is_pid(Name) -> - pid_to_list(Name); - is_atom(Name) -> - Name - end, - Header = lists:concat(["Status for generic server ", NameTag]), + StatusHdr = "Status for wx object ", + Header = if + is_pid(Name) -> + lists:concat([StatusHdr, pid_to_list(Name)]); + is_atom(Name); is_list(Name) -> + lists:concat([StatusHdr, Name]); + true -> + {StatusHdr, Name} + end, Log = sys:get_debug(log, Debug, []), Specfic = case erlang:function_exported(Mod, format_status, 2) of diff --git a/lib/wx/src/wxe_master.erl b/lib/wx/src/wxe_master.erl index 70872775fb..5ab76a77cf 100644 --- a/lib/wx/src/wxe_master.erl +++ b/lib/wx/src/wxe_master.erl @@ -1,19 +1,19 @@ %% %% %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 %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %%%------------------------------------------------------------------- %%% File : wxe_server.erl @@ -33,7 +33,6 @@ %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). --compile(export_all). -record(state, {cb_port, %% Callback port and to erlang messages goes via it. users, %% List of wx servers, needed ?? diff --git a/lib/wx/test/Makefile b/lib/wx/test/Makefile index 65d7d56650..dfec4bb695 100644 --- a/lib/wx/test/Makefile +++ b/lib/wx/test/Makefile @@ -1,19 +1,19 @@ # # %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 # 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% # @@ -28,7 +28,9 @@ APPDIR = $(shell dirname $(PWD)) ERL_COMPILE_FLAGS = -pa $(APPDIR)/ebin Mods = wxt wx_test_lib \ - wx_basic_SUITE wx_event_SUITE \ + wx_app_SUITE \ + wx_basic_SUITE \ + wx_event_SUITE \ wx_class_SUITE \ wx_xtra_SUITE \ wx_opengl_SUITE @@ -61,7 +63,7 @@ release_spec: release_tests_spec: opt $(INSTALL_DIR) $(RELSYSDIR) $(INSTALL_DATA) wx.spec wx_test_lib.hrl $(ErlSrc) $(ErlTargets) $(RELSYSDIR) - $(INSTALL_PROGRAM) wxt $(RELSYSDIR) + $(INSTALL_SCRIPT) wxt $(RELSYSDIR) release_docs_spec: diff --git a/lib/wx/test/wx_app_SUITE.erl b/lib/wx/test/wx_app_SUITE.erl new file mode 100644 index 0000000000..8fff324913 --- /dev/null +++ b/lib/wx/test/wx_app_SUITE.erl @@ -0,0 +1,277 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% +%% + +%% +%%---------------------------------------------------------------------- +%% Purpose: Verify the application specifics of the Wx application +%%---------------------------------------------------------------------- +-module(wx_app_SUITE). + +-compile(export_all). + +-include("wx_test_lib.hrl"). + + +t() -> wx_test_lib:t(?MODULE). +t(Case) -> wx_test_lib:t({?MODULE, Case}). + +%% Test server callbacks +init_per_testcase(Case, Config0) -> + Config1 = wx_test_lib:init_per_testcase(Case, Config0), + case is_app(wx) of + {ok, AppFile} -> + %% io:format("AppFile: ~n~p~n", [AppFile]), + [{app_file, AppFile} | Config1]; + {error, Reason} -> + fail(Reason) + end. + +end_per_testcase(Func,Config) -> + wx_test_lib:end_per_testcase(Func, Config). + +fin_per_testcase(Case, Config) -> + wx_test_lib:end_per_testcase(Case, Config). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +all() -> + all(suite). + +all(suite) -> + [ + fields, + modules, + exportall, + app_depend, + undef_funcs + ]. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +is_app(App) -> + LibDir = code:lib_dir(App), + File = filename:join([LibDir, "ebin", atom_to_list(App) ++ ".app"]), + case file:consult(File) of + {ok, [{application, App, AppFile}]} -> + {ok, AppFile}; + Error -> + {error, {invalid_format, Error}} + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +fields(suite) -> + []; +fields(doc) -> + []; +fields(Config) when is_list(Config) -> + AppFile = key1search(app_file, Config), + Fields = [vsn, description, modules, registered, applications], + case check_fields(Fields, AppFile, []) of + [] -> + ok; + Missing -> + fail({missing_fields, Missing}) + end. + +check_fields([], _AppFile, Missing) -> + Missing; +check_fields([Field|Fields], AppFile, Missing) -> + check_fields(Fields, AppFile, check_field(Field, AppFile, Missing)). + +check_field(Name, AppFile, Missing) -> + io:format("checking field: ~p~n", [Name]), + case lists:keymember(Name, 1, AppFile) of + true -> + Missing; + false -> + [Name|Missing] + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +modules(suite) -> + []; +modules(doc) -> + []; +modules(Config) when is_list(Config) -> + AppFile = key1search(app_file, Config), + Mods = key1search(modules, AppFile), + EbinList = get_ebin_mods(wx), + case missing_modules(Mods, EbinList, []) of + [] -> + ok; + Missing -> + throw({error, {missing_modules, Missing}}) + end, + case extra_modules(Mods, EbinList, []) of + [] -> + ok; + Extra -> + throw({error, {extra_modules, Extra}}) + end, + {ok, Mods}. + +get_ebin_mods(App) -> + LibDir = code:lib_dir(App), + EbinDir = filename:join([LibDir,"ebin"]), + {ok, Files0} = file:list_dir(EbinDir), + Files1 = [lists:reverse(File) || File <- Files0], + [list_to_atom(lists:reverse(Name)) || [$m,$a,$e,$b,$.|Name] <- Files1]. + +missing_modules([], _Ebins, Missing) -> + Missing; +missing_modules([Mod|Mods], Ebins, Missing) -> + case lists:member(Mod, Ebins) of + true -> + missing_modules(Mods, Ebins, Missing); + false -> + io:format("missing module: ~p~n", [Mod]), + missing_modules(Mods, Ebins, [Mod|Missing]) + end. + + +extra_modules(_Mods, [], Extra) -> + Extra; +extra_modules(Mods, [Mod|Ebins], Extra) -> + case lists:member(Mod, Mods) of + true -> + extra_modules(Mods, Ebins, Extra); + false -> + io:format("supefluous module: ~p~n", [Mod]), + extra_modules(Mods, Ebins, [Mod|Extra]) + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +exportall(suite) -> + []; +exportall(doc) -> + []; +exportall(Config) when is_list(Config) -> + AppFile = key1search(app_file, Config), + Mods = key1search(modules, AppFile), + check_export_all(Mods). + + +check_export_all([]) -> + ok; +check_export_all([Mod|Mods]) -> + case (catch apply(Mod, module_info, [compile])) of + {'EXIT', {undef, _}} -> + check_export_all(Mods); + O -> + case lists:keysearch(options, 1, O) of + false -> + check_export_all(Mods); + {value, {options, List}} -> + case lists:member(export_all, List) of + true -> + throw({error, {export_all, Mod}}); + false -> + check_export_all(Mods) + end + end + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +app_depend(suite) -> + []; +app_depend(doc) -> + []; +app_depend(Config) when is_list(Config) -> + AppFile = key1search(app_file, Config), + Apps = key1search(applications, AppFile), + check_apps(Apps). + +check_apps([]) -> + ok; +check_apps([App|Apps]) -> + case is_app(App) of + {ok, _} -> + check_apps(Apps); + Error -> + throw({error, {missing_app, {App, Error}}}) + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +undef_funcs(suite) -> + []; +undef_funcs(doc) -> + []; +undef_funcs(Config) when is_list(Config) -> + catch test_server:timetrap(timer:minutes(10)), + App = wx, + AppFile = key1search(app_file, Config), + Mods = key1search(modules, AppFile), + Root = code:root_dir(), + LibDir = code:lib_dir(App), + EbinDir = filename:join([LibDir,"ebin"]), + XRefTestName = undef_funcs_make_name(App, xref_test_name), + {ok, XRef} = xref:start(XRefTestName), + ok = xref:set_default(XRef, + [{verbose,false},{warnings,false}]), + XRefName = undef_funcs_make_name(App, xref_name), + {ok, XRefName} = xref:add_release(XRef, Root, {name,XRefName}), + {ok, App} = xref:replace_application(XRef, App, EbinDir), + {ok, Undefs} = xref:analyze(XRef, undefined_function_calls), + xref:stop(XRef), + analyze_undefined_function_calls(Undefs, Mods, []). + +analyze_undefined_function_calls([], _, []) -> + ok; +analyze_undefined_function_calls([], _, AppUndefs) -> + exit({suite_failed, {undefined_function_calls, AppUndefs}}); +analyze_undefined_function_calls([{{Mod, _F, _A}, _C} = AppUndef|Undefs], + AppModules, AppUndefs) -> + %% Check that this module is ours + case lists:member(Mod,AppModules) of + true -> + {Calling,Called} = AppUndef, + {Mod1,Func1,Ar1} = Calling, + {Mod2,Func2,Ar2} = Called, + io:format("undefined function call: " + "~n ~w:~w/~w calls ~w:~w/~w~n", + [Mod1,Func1,Ar1,Mod2,Func2,Ar2]), + analyze_undefined_function_calls(Undefs, AppModules, + [AppUndef|AppUndefs]); + false -> + io:format("dropping ~p~n", [Mod]), + analyze_undefined_function_calls(Undefs, AppModules, AppUndefs) + end. + +%% This function is used simply to avoid cut-and-paste errors later... +undef_funcs_make_name(App, PostFix) -> + list_to_atom(atom_to_list(App) ++ "_" ++ atom_to_list(PostFix)). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +fail(Reason) -> + exit({suite_failed, Reason}). + +key1search(Key, L) -> + case lists:keysearch(Key, 1, L) of + false -> + fail({not_found, Key, L}); + {value, {Key, Value}} -> + Value + end. 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 54ab92cad2..c0cc302317 100644 --- a/lib/wx/vsn.mk +++ b/lib/wx/vsn.mk @@ -1,7 +1 @@ -WX_VSN = 0.98.5 - -TICKETS = 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 +WX_VSN = 0.98.7 diff --git a/lib/xmerl/doc/src/notes.xml b/lib/xmerl/doc/src/notes.xml index 91a98808a2..d67a622481 100644 --- a/lib/xmerl/doc/src/notes.xml +++ b/lib/xmerl/doc/src/notes.xml @@ -31,15 +31,51 @@ <p>This document describes the changes made to the Xmerl application.</p> -<section><title>Xmerl 1.2.4.1</title> +<section><title>Xmerl 1.2.6</title> <section><title>Fixed Bugs and Malfunctions</title> <list> <item> - <p> An empty element declared as simpleContent was not - properly validated. </p> + <p> Fixed problem with hex entities in UTF-8 documents: + When a document was in UTF-8 encoding, xmerl_scan + improperly replaced hex entities by the UTF-8 bytes + instead of returning the character, as it does with + inline UTF-8 text and decimal entities. (Thanks to Paul + Guyot.) </p> <p> - Own Id: OTP-8599</p> + Own Id: OTP-8697</p> + </item> + </list> + </section> + +</section> + +<section><title>Xmerl 1.2.5</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + All Erlang files are now built by the test server instead of the test directory Makefile. + </p> + <p> + Erlang files in data directories are now built by the test suites instead of using + prebuilt versions under version control. + </p> + <p> + Removed a number of obsolete guards. + </p> + <p> + Own Id: OTP-8537 + </p> + </item> + <item> + <p> + An empty element declared as a simpleContent was not properly validated. + </p> + <p> + Own Id: OTP-8599 + </p> </item> </list> </section> @@ -69,7 +105,7 @@ <item> <p> A continuation clause of <c>parse_reference/3</c> had - it's parameters in wrong order.</p> + its parameters in wrong order.</p> <p> Own Id: OTP-8251 Aux Id: seq11429 </p> </item> 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/src/xmerl_scan.erl b/lib/xmerl/src/xmerl_scan.erl index 4e5cc59d8f..e2e6f95c4a 100644 --- a/lib/xmerl/src/xmerl_scan.erl +++ b/lib/xmerl/src/xmerl_scan.erl @@ -1,19 +1,19 @@ %% %% %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 %% 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% %% @@ -2602,8 +2602,7 @@ scan_reference("#x" ++ T, S0) -> %% [66] CharRef ?bump_col(1), if hd(T) /= $; -> - {[Ch], T2, S2} = scan_char_ref_hex(T, S, 0), - {to_char_set(S2#xmerl_scanner.encoding,Ch),T2,S2}; + scan_char_ref_hex(T, S, 0); true -> ?fatal(invalid_char_ref, S) end; @@ -3452,14 +3451,14 @@ scan_entity_value("%" ++ T, S0, Delim, Acc, PEName,Namespace,PENesting) -> %% {system,URI} or {public,URI} %% Included in literal. {ExpRef,Sx}=fetch_not_parse(Tuple,S1), - {EntV,_,_S2} = - scan_entity_value(ExpRef, Sx, no_delim,[], + {EntV, _, S5} = + scan_entity_value(ExpRef, Sx, no_delim,[], PERefName,parameter,[]), %% should do an update Write(parameter_entity) %% so next expand_pe_reference is faster - {EntV,_S2}; + {string_to_char_set(S5#xmerl_scanner.encoding, EntV), S5}; ExpRef -> - {ExpRef,S1} + {string_to_char_set(S1#xmerl_scanner.encoding, ExpRef) ,S1} end, %% single or duoble qoutes are not treated as delimeters %% in passages "included in literal" @@ -4020,12 +4019,12 @@ utf8_2_ucs([A|Rest]) when A < 16#80 -> utf8_2_ucs([A|Rest]) -> {{error,{bad_character,A}},Rest}. -to_char_set("iso-10646-utf-1",Ch) -> - [Ch]; -to_char_set(UTF8,Ch) when UTF8 =:= "utf-8"; UTF8 =:= undefined -> - ucs_2_utf8(Ch); -to_char_set(_,Ch) -> - [Ch]. +%% to_char_set("iso-10646-utf-1",Ch) -> +%% [Ch]; +%% to_char_set(UTF8,Ch) when UTF8 =:= "utf-8"; UTF8 =:= undefined -> +%% ucs_2_utf8(Ch); +%% to_char_set(_,Ch) -> +%% [Ch]. ucs_2_utf8(Ch) when Ch < 128 -> %% 0vvvvvvv diff --git a/lib/xmerl/vsn.mk b/lib/xmerl/vsn.mk index 39213a2c4a..d85a57f447 100644 --- a/lib/xmerl/vsn.mk +++ b/lib/xmerl/vsn.mk @@ -1,107 +1 @@ -XMERL_VSN = 1.2.4.1 - - -TICKETS = \ - OTP-8343 - -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 \ - +XMERL_VSN = 1.2.6 |