diff options
80 files changed, 1452 insertions, 731 deletions
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index ad0b909b2a..3309b77086 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -77,15 +77,35 @@ static ERTS_INLINE ErlIOQueue* drvport2ioq(ErlDrvPort drvport) { int ix = (int) drvport; + Uint32 status; + if (ix < 0 || erts_max_ports <= ix) return NULL; - if (erts_port[ix].status & ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP) - return NULL; - ERTS_LC_ASSERT(!erts_port[ix].port_data_lock - || erts_lc_mtx_is_locked(&erts_port[ix].port_data_lock->mtx)); - ERTS_SMP_LC_ASSERT(erts_port[ix].port_data_lock - || erts_lc_is_port_locked(&erts_port[ix])); - return &erts_port[ix].ioq; + + if (erts_get_scheduler_data()) { + ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(&erts_port[ix])); + ERTS_LC_ASSERT(!erts_port[ix].port_data_lock + || erts_lc_mtx_is_locked( + &erts_port[ix].port_data_lock->mtx)); + + status = erts_port[ix].status; + } + else { + erts_smp_port_state_lock(&erts_port[ix]); + status = erts_port[ix].status; + erts_smp_port_state_unlock(&erts_port[ix]); + + ERTS_LC_ASSERT((status & ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP) + || erts_port[ix].port_data_lock); + ERTS_LC_ASSERT(!erts_port[ix].port_data_lock + || erts_lc_mtx_is_locked( + &erts_port[ix].port_data_lock->mtx)); + + } + + return ((status & ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP) + ? NULL + : &erts_port[ix].ioq); } static ERTS_INLINE int diff --git a/erts/emulator/beam/register.c b/erts/emulator/beam/register.c index 7ba097382a..964c10a380 100644 --- a/erts/emulator/beam/register.c +++ b/erts/emulator/beam/register.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% */ @@ -500,8 +500,8 @@ int erts_unregister_name(Process *c_p, if ((rp = (RegProc*) hash_get(&process_reg, (void*) &r)) != NULL) { if (rp->pt) { -#ifdef ERTS_SMP if (port != rp->pt) { +#ifdef ERTS_SMP if (port) { ERTS_SMP_LC_ASSERT(port != c_prt); erts_smp_port_unlock(port); @@ -519,10 +519,13 @@ int erts_unregister_name(Process *c_p, port = erts_id2port(id, NULL, 0); goto restart; } +#endif port = rp->pt; } -#endif - ERTS_SMP_LC_ASSERT(rp->pt == port && erts_lc_is_port_locked(port)); + + ASSERT(rp->pt == port); + ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(port)); + rp->pt->reg = NULL; if (IS_TRACED_FL(port, F_TRACE_PORTS)) { diff --git a/erts/emulator/test/driver_SUITE_data/ioq_exit_drv.c b/erts/emulator/test/driver_SUITE_data/ioq_exit_drv.c index 2048d06123..c7a42aa687 100644 --- a/erts/emulator/test/driver_SUITE_data/ioq_exit_drv.c +++ b/erts/emulator/test/driver_SUITE_data/ioq_exit_drv.c @@ -1,19 +1,20 @@ -/* ``The contents of this file are subject to the Erlang Public License, +/* + * %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 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% */ /* @@ -77,6 +78,7 @@ typedef struct { int ofd; int outstanding_async_task; long async_task; + ErlDrvPDL pdl; #ifdef HAVE_POLL_H struct erl_drv_event_data event_data; #endif @@ -144,6 +146,7 @@ start(ErlDrvPort port, char *command) ddp->ofd = -1; ddp->outstanding_async_task = 0; ddp->async_task = -1; + ddp->pdl = driver_pdl_create(port); #ifdef HAVE_POLL_H ddp->event_data.events = (short) 0; ddp->event_data.revents = (short) 0; @@ -217,8 +220,9 @@ static int control(ErlDrvData drv_data, res_str = "error: command not supported"; goto done; } - + driver_pdl_lock(ddp->pdl); driver_enq(ddp->port, "!", 1); + driver_pdl_unlock(ddp->pdl); ddp->test = (IOQExitTest) command; res_str = "ok"; @@ -333,8 +337,11 @@ static void ready_input(ErlDrvData drv_data, ErlDrvEvent event) ddp->ifd = -1; if (ddp->test == IOQ_EXIT_READY_INPUT_ASYNC) do_driver_async(ddp); - else + else { + driver_pdl_lock(ddp->pdl); driver_deq(ddp->port, 1); + driver_pdl_unlock(ddp->pdl); + } } #endif } @@ -352,8 +359,11 @@ static void ready_output(ErlDrvData drv_data, ErlDrvEvent event) ddp->ofd = -1; if (ddp->test == IOQ_EXIT_READY_OUTPUT_ASYNC) do_driver_async(ddp); - else + else { + driver_pdl_lock(ddp->pdl); driver_deq(ddp->port, 1); + driver_pdl_unlock(ddp->pdl); + } } #endif } @@ -366,8 +376,11 @@ static void timeout(ErlDrvData drv_data) if (ddp->test == IOQ_EXIT_TIMEOUT_ASYNC) do_driver_async(ddp); - else + else { + driver_pdl_lock(ddp->pdl); driver_deq(ddp->port, 1); + driver_pdl_unlock(ddp->pdl); + } } static void ready_async(ErlDrvData drv_data, ErlDrvThreadData thread_data) @@ -377,7 +390,9 @@ static void ready_async(ErlDrvData drv_data, ErlDrvThreadData thread_data) PRINTF(("ready_async(%p, %p) called\r\n", drv_data, thread_data)); if (drv_data == (ErlDrvData) thread_data) { + driver_pdl_lock(ddp->pdl); driver_deq(ddp->port, 1); + driver_pdl_unlock(ddp->pdl); ddp->outstanding_async_task = 0; } } @@ -397,8 +412,11 @@ static void event(ErlDrvData drv_data, ddp->ofd = -1; if (ddp->test == IOQ_EXIT_EVENT_ASYNC) do_driver_async(ddp); - else + else { + driver_pdl_lock(ddp->pdl); driver_deq(ddp->port, 1); + driver_pdl_unlock(ddp->pdl); + } } #endif } diff --git a/erts/emulator/test/port_SUITE.erl b/erts/emulator/test/port_SUITE.erl index 9a09d20eab..b9100738e4 100644 --- a/erts/emulator/test/port_SUITE.erl +++ b/erts/emulator/test/port_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% %% @@ -88,7 +88,8 @@ otp_3906/1, otp_4389/1, win_massive/1, win_massive_client/1, mix_up_ports/1, otp_5112/1, otp_5119/1, otp_6224/1, exit_status_multi_scheduling_block/1, ports/1, - spawn_driver/1,spawn_executable/1]). + spawn_driver/1,spawn_executable/1, + unregister_name/1]). -export([]). @@ -112,7 +113,8 @@ all(suite) -> otp_3906, otp_4389, win_massive, mix_up_ports, otp_5112, otp_5119, exit_status_multi_scheduling_block, - ports, spawn_driver, spawn_executable + ports, spawn_driver, spawn_executable, + unregister_name ]. -define(DEFAULT_TIMEOUT, ?t:minutes(5)). @@ -1434,6 +1436,10 @@ spawn_executable(Config) when is_list(Config) -> ?line test_server:timetrap_cancel(Dog), ok. +unregister_name(Config) when is_list(Config) -> + ?line true = register(crash, open_port({spawn, "sleep 100"}, [])), + ?line true = unregister(crash). + test_bat_file(Dir) -> FN = "tf.bat", Full = filename:join([Dir,FN]), diff --git a/erts/etc/unix/cerl.src b/erts/etc/unix/cerl.src index f81ef6b0fe..9dab9fcfcc 100644 --- a/erts/etc/unix/cerl.src +++ b/erts/etc/unix/cerl.src @@ -1,20 +1,20 @@ #!/bin/sh # # %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% # # @@ -277,6 +277,16 @@ else ;; esac + # Set annotation level for gdb in emacs 22 and higher. + emacs_major=`$EMACS --version | head -1 | sed 's,^[^0-9]*\([0-9]*\).*,\1,g'` + if [ '!' -z "$emacs_major" -a $emacs_major -gt 21 ]; then + # Hack - wait for etp-commands to be loaded and then set + # annotation level, could be done more beautifully than with sit-for... + gdbcmd="$gdbcmd \ + (sit-for 1) \ + (insert-string \"set annotate 3\") \ + (comint-send-input)" + fi gdbcmd="$gdbcmd $GDBBP \ (insert-string \"source $ROOTDIR/erts/etc/unix/etp-commands\") \ (comint-send-input)" diff --git a/erts/vsn.mk b/erts/vsn.mk index 8f940339df..6e1338cff5 100644 --- a/erts/vsn.mk +++ b/erts/vsn.mk @@ -1,24 +1,24 @@ # # %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% # -VSN = 5.7.5 -SYSTEM_VSN = R13B04 +VSN = 5.8 +SYSTEM_VSN = R14A # Port number 4365 in 4.2 # Port number 4366 in 4.3 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_bin_SUITE_data/P-Record.py b/lib/asn1/test/asn1_bin_SUITE_data/P-Record.py index f1db09ac6c..ac3dc9abe0 100644 --- a/lib/asn1/test/asn1_bin_SUITE_data/P-Record.py +++ b/lib/asn1/test/asn1_bin_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_bin_SUITE_data/XSeq.py b/lib/asn1/test/asn1_bin_SUITE_data/XSeq.py index b068ab4393..35b4469440 100644 --- a/lib/asn1/test/asn1_bin_SUITE_data/XSeq.py +++ b/lib/asn1/test/asn1_bin_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_bin_SUITE_data/XSeqOf.py b/lib/asn1/test/asn1_bin_SUITE_data/XSeqOf.py index f9fee92e56..116bd4a82d 100644 --- a/lib/asn1/test/asn1_bin_SUITE_data/XSeqOf.py +++ b/lib/asn1/test/asn1_bin_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_bin_v2_SUITE_data/P-Record.py b/lib/asn1/test/asn1_bin_v2_SUITE_data/P-Record.py index f1db09ac6c..ac3dc9abe0 100644 --- a/lib/asn1/test/asn1_bin_v2_SUITE_data/P-Record.py +++ b/lib/asn1/test/asn1_bin_v2_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_bin_v2_SUITE_data/XSeq.py b/lib/asn1/test/asn1_bin_v2_SUITE_data/XSeq.py index b068ab4393..35b4469440 100644 --- a/lib/asn1/test/asn1_bin_v2_SUITE_data/XSeq.py +++ b/lib/asn1/test/asn1_bin_v2_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_bin_v2_SUITE_data/XSeqOf.py b/lib/asn1/test/asn1_bin_v2_SUITE_data/XSeqOf.py index f9fee92e56..116bd4a82d 100644 --- a/lib/asn1/test/asn1_bin_v2_SUITE_data/XSeqOf.py +++ b/lib/asn1/test/asn1_bin_v2_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/cosNotification/doc/src/notes.xml b/lib/cosNotification/doc/src/notes.xml index 29879e95fb..8062c883cf 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,20 @@ </header> <section> + <title>cosNotification 1.1.14</title> + + <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..f4196a2f33 100644 --- a/lib/cosNotification/vsn.mk +++ b/lib/cosNotification/vsn.mk @@ -1,6 +1,8 @@ -COSNOTIFICATION_VSN = 1.1.13 +COSNOTIFICATION_VSN = 1.1.14 -TICKETS = OTP-8353 \ +TICKETS = OTP-8489 + +TICKETS_1.1.13 = OTP-8353 \ OTP-8354 \ OTP-8355 diff --git a/lib/cosTransactions/doc/src/notes.xml b/lib/cosTransactions/doc/src/notes.xml index 41a754b034..77541a9f85 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,20 @@ </header> <section> + <title>cosTransactions 1.2.10</title> + + <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..b45f192f45 100644 --- a/lib/cosTransactions/vsn.mk +++ b/lib/cosTransactions/vsn.mk @@ -1,6 +1,8 @@ -COSTRANSACTIONS_VSN = 1.2.9 +COSTRANSACTIONS_VSN = 1.2.10 -TICKETS = OTP-8355 +TICKETS = OTP-8489 + +TICKETS_1.2.9 = OTP-8355 TICKETS_1.2.8 = OTP-8201 diff --git a/lib/dialyzer/src/dialyzer_dataflow.erl b/lib/dialyzer/src/dialyzer_dataflow.erl index a57d9a96c6..1ccfaaa52f 100644 --- a/lib/dialyzer/src/dialyzer_dataflow.erl +++ b/lib/dialyzer/src/dialyzer_dataflow.erl @@ -2290,11 +2290,11 @@ handle_guard_or(Guard, Map, Env, Eval, State) -> 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 diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml index 7bb6aea40e..9c3f6524ae 100644 --- a/lib/kernel/doc/src/notes.xml +++ b/lib/kernel/doc/src/notes.xml @@ -30,6 +30,22 @@ </header> <p>This document describes the changes made to the Kernel application.</p> +<section><title>Kernel 2.13.5.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + A race condition in <c>os:cmd/1</c> could cause the + caller to get stuck in <c>os:cmd/1</c> forever.</p> + <p> + Own Id: OTP-8502</p> + </item> + </list> + </section> + +</section> + <section><title>Kernel 2.13.5</title> <section><title>Fixed Bugs and Malfunctions</title> 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/src/application_controller.erl b/lib/kernel/src/application_controller.erl index 7c1f059875..5277472ea6 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). @@ -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 @@ -604,6 +609,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} -> @@ -885,6 +903,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). @@ -977,6 +998,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} -> @@ -1155,6 +1179,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 +1196,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}. @@ -1937,6 +1965,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/auth.erl b/lib/kernel/src/auth.erl index 62c0bef0cc..31ee1d1ef4 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"). @@ -61,24 +63,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 +88,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); @@ -122,6 +124,8 @@ print(Node,Format,Args) -> %%--gen_server callbacks------------------------------------------------ +-spec init([]) -> {'ok', state()}. + init([]) -> process_flag(trap_exit, true), {ok, init_cookie()}. @@ -130,6 +134,11 @@ init([]) -> %% The net kernel will let all message to the auth server %% through as is +-type calls() :: 'echo' | 'sync_cookie' | {'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) -> @@ -164,6 +173,13 @@ 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), @@ -171,6 +187,8 @@ handle_cast({print,What,Args}, 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()]), @@ -218,9 +236,13 @@ handle_info({From,badcookie,Name,Mess}, Opened) -> 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. diff --git a/lib/kernel/src/code_server.erl b/lib/kernel/src/code_server.erl index 7aeddb73d1..2bc93b8238 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(), @@ -221,6 +222,7 @@ system_terminate(_Reason, _Parent, _Debug, _State) -> % 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}. 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/erl_boot_server.erl b/lib/kernel/src/erl_boot_server.erl index 702b2feac9..c5a4305731 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}]), @@ -186,6 +189,9 @@ init(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), S0#state.bootp ! {slaves, 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..c4ff4c7281 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 -> @@ -141,11 +149,15 @@ handle_call(stop, _From, 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}. diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl index a42771dfb6..46ffa9d708 100644 --- a/lib/kernel/src/file.erl +++ b/lib/kernel/src/file.erl @@ -74,15 +74,22 @@ %% 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'. +-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()}. + %%%----------------------------------------------------------------- %%% General functions 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/inet_db.erl b/lib/kernel/src/inet_db.erl index a05b380855..ec95620cc0 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"). @@ -844,6 +845,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 +901,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) -> @@ -1145,6 +1153,9 @@ handle_call(Request, From, #state{db=Db}=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 +1165,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 +1180,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. diff --git a/lib/kernel/src/inet_gethost_native.erl b/lib/kernel/src/inet_gethost_native.erl index fabe9bf8b3..b7b3007b99 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), @@ -154,8 +157,10 @@ run_once() -> 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. %%----------------------------------------------------------------------- @@ -431,6 +436,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/kernel_config.erl b/lib/kernel/src/kernel_config.erl index e5e9a0498d..cdad354876 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}. diff --git a/lib/kernel/src/os.erl b/lib/kernel/src/os.erl index 196e6cdeb2..d0b498edc9 100644 --- a/lib/kernel/src/os.erl +++ b/lib/kernel/src/os.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(os). @@ -169,6 +169,7 @@ unix_cmd(Cmd) -> %% $1 parameter for easy identification of the resident shell. %% -define(SHELL, "/bin/sh -s unix:cmd 2>&1"). +-define(PORT_CREATOR_NAME, os_cmd_port_creator). %% %% Serializing open_port through a process to avoid smp lock contention @@ -176,18 +177,37 @@ unix_cmd(Cmd) -> %% -spec start_port() -> port(). start_port() -> - {Ref,Client} = {make_ref(),self()}, - try (os_cmd_port_creator ! {Ref,Client}) - catch - error:_ -> spawn(fun() -> start_port_srv({Ref,Client}) end) - end, + Ref = make_ref(), + Request = {Ref,self()}, + {Pid, Mon} = case whereis(?PORT_CREATOR_NAME) of + undefined -> + spawn_monitor(fun() -> + start_port_srv(Request) + end); + P -> + P ! Request, + M = erlang:monitor(process, P), + {P, M} + end, receive - {Ref,Port} when is_port(Port) -> Port; - {Ref,Error} -> exit(Error) + {Ref, Port} when is_port(Port) -> + erlang:demonitor(Mon, [flush]), + Port; + {Ref, Error} -> + erlang:demonitor(Mon, [flush]), + exit(Error); + {'DOWN', Mon, process, Pid, _Reason} -> + start_port() end. start_port_srv(Request) -> - StayAlive = try register(os_cmd_port_creator, self()) + %% We don't want a group leader of some random application. Use + %% kernel_sup's group leader. + {group_leader, GL} = process_info(whereis(kernel_sup), + group_leader), + true = group_leader(GL, self()), + process_flag(trap_exit, true), + StayAlive = try register(?PORT_CREATOR_NAME, self()) catch error:_ -> false end, @@ -196,7 +216,7 @@ start_port_srv(Request) -> start_port_srv_loop({Ref,Client}, StayAlive) -> Reply = try open_port({spawn, ?SHELL},[stream]) of Port when is_port(Port) -> - port_connect(Port, Client), + (catch port_connect(Port, Client)), unlink(Port), Port catch @@ -205,10 +225,19 @@ start_port_srv_loop({Ref,Client}, StayAlive) -> end, Client ! {Ref,Reply}, case StayAlive of - true -> start_port_srv_loop(receive Msg -> Msg end, true); + true -> start_port_srv_loop(get_open_port_request(), true); false -> exiting end. +get_open_port_request() -> + receive + {Ref, Client} = Request when is_reference(Ref), + is_pid(Client) -> + Request; + _Junk -> + get_open_port_request() + end. + %% %% unix_get_data(Port) -> Result %% diff --git a/lib/kernel/src/rpc.erl b/lib/kernel/src/rpc.erl index d69f2a12ad..43a987f313 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). @@ -64,25 +64,41 @@ %%------------------------------------------------------------------------ +-type state() :: gb_tree(). + +%%------------------------------------------------------------------------ + %% Remote execution and broadcasting facility +-spec start() -> {'ok', pid()} | 'ignore' | {'error', term()}. + start() -> gen_server:start({local,?NAME},?MODULE,[],[]). +-spec start_link() -> {'ok', pid()} | 'ignore' | {'error', term()}. + start_link() -> gen_server:start_link({local,?NAME},?MODULE,[],[]). +-spec stop() -> term(). + stop() -> stop(?NAME). 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,6 +118,7 @@ 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( @@ -113,6 +130,7 @@ handle_cast({cast, Mod, Fun, Args, Gleader}, 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 @@ -160,9 +178,13 @@ handle_info({From, {call,Mod,Fun,Args,Gleader}}, S) -> handle_info(_, S) -> {noreply,S}. +-spec terminate(term(), state()) -> 'ok'. + terminate(_, _S) -> ok. +-spec code_change(term(), state(), term()) -> {'ok', state()}. + code_change(_, S, _) -> {ok, S}. @@ -226,6 +248,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..98a44d1ee9 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). @@ -33,13 +33,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) -> 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/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/os_SUITE.erl b/lib/kernel/test/os_SUITE.erl index 1673b33010..6a3534b094 100644 --- a/lib/kernel/test/os_SUITE.erl +++ b/lib/kernel/test/os_SUITE.erl @@ -20,13 +20,13 @@ -export([all/1]). -export([space_in_cwd/1, quoting/1, space_in_name/1, bad_command/1, - find_executable/1, unix_comment_in_command/1]). + find_executable/1, unix_comment_in_command/1, evil/1]). -include("test_server.hrl"). all(suite) -> [space_in_cwd, quoting, space_in_name, bad_command, find_executable, - unix_comment_in_command]. + unix_comment_in_command, evil]. space_in_cwd(doc) -> "Test that executing a command in a current working directory " @@ -186,6 +186,48 @@ unix_comment_in_command(Config) when is_list(Config) -> ?line test_server:timetrap_cancel(Dog), ok. +-define(EVIL_PROCS, 100). +-define(EVIL_LOOPS, 100). +-define(PORT_CREATOR, os_cmd_port_creator). +evil(Config) when is_list(Config) -> + Dog = test_server:timetrap(test_server:minutes(5)), + Parent = self(), + Ps = lists:map(fun (N) -> + spawn_link(fun () -> + evil_loop(Parent, ?EVIL_LOOPS,N) + end) + end, lists:seq(1, ?EVIL_PROCS)), + Devil = spawn(fun () -> devil(hd(Ps), hd(lists:reverse(Ps))) end), + lists:foreach(fun (P) -> receive {P, done} -> ok end end, Ps), + exit(Devil, kill), + test_server:timetrap_cancel(Dog), + ok. + +devil(P1, P2) -> + erlang:display({?PORT_CREATOR, whereis(?PORT_CREATOR)}), + (catch ?PORT_CREATOR ! lists:seq(1,1000000)), + (catch ?PORT_CREATOR ! lists:seq(1,666)), + (catch ?PORT_CREATOR ! grrrrrrrrrrrrrrrr), + (catch ?PORT_CREATOR ! {'EXIT', P1, buhuuu}), + (catch ?PORT_CREATOR ! {'EXIT', hd(erlang:ports()), buhuuu}), + (catch ?PORT_CREATOR ! {'EXIT', P2, arggggggg}), + receive after 500 -> ok end, + (catch exit(whereis(?PORT_CREATOR), kill)), + (catch ?PORT_CREATOR ! ">8|"), + receive after 500 -> ok end, + (catch exit(whereis(?PORT_CREATOR), diiiiiiiiiiiiiiiiiiiie)), + receive after 100 -> ok end, + devil(P1, P2). + +evil_loop(Parent, Loops, N) -> + Res = integer_to_list(N), + evil_loop(Parent, Loops, Res, "echo " ++ Res). + +evil_loop(Parent, 0, _Res, _Cmd) -> + Parent ! {self(), done}; +evil_loop(Parent, Loops, Res, Cmd) -> + comp(Res, os:cmd(Cmd)), + evil_loop(Parent, Loops-1, Res, Cmd). comp(Expected, Got) -> case strip_nl(Got) of diff --git a/lib/kernel/vsn.mk b/lib/kernel/vsn.mk index 5b4369740d..64a358f114 100644 --- a/lib/kernel/vsn.mk +++ b/lib/kernel/vsn.mk @@ -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% # -KERNEL_VSN = 2.13.5 +KERNEL_VSN = 2.14 diff --git a/lib/odbc/AUTHORS b/lib/odbc/AUTHORS index d1ed32bde1..22813f36ce 100644 --- a/lib/odbc/AUTHORS +++ b/lib/odbc/AUTHORS @@ -5,4 +5,5 @@ 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
\ No newline at end of file diff --git a/lib/odbc/c_src/odbcserver.c b/lib/odbc/c_src/odbcserver.c index aaaea20a10..5865cddcda 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,7 @@ 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 Scale - integer Precision - integer Max - integer @@ -173,7 +174,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 ----------------------*/ @@ -433,26 +434,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); @@ -1102,8 +1110,21 @@ static db_result_msg encode_out_params(db_state *state, void* values = retrive_param_values(&column); switch(column.type.c) { 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; @@ -1365,7 +1386,16 @@ static void encode_column_dyn(db_column column, int column_nr, } else { switch(column.type.c) { 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 +1409,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 +1439,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"); @@ -1492,7 +1537,7 @@ 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; @@ -1504,15 +1549,25 @@ static Boolean decode_params(byte *buffer, int *index, param_array **params, 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; + 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_SLONG: if(!((erl_type == ERL_SMALL_INTEGER_EXT) || (erl_type == ERL_INTEGER_EXT) || @@ -2053,6 +2108,24 @@ 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_FLOAT: params->type.sql = SQL_FLOAT; params->type.c = SQL_C_DOUBLE; @@ -2190,11 +2263,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: @@ -2280,7 +2359,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 +2388,8 @@ 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: + 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..3b5a2b4d4d 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,8 @@ #define USER_DOUBLE 9 #define USER_BOOLEAN 10 #define USER_TINY_INT 11 +#define USER_WCHAR 12 +#define USER_WVARCHAR 13 /*------------------------ TYPDEFS ----------------------------------*/ @@ -170,6 +172,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 +191,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/doc/src/databases.xml b/lib/odbc/doc/src/databases.xml index c06327e11d..2c1b932084 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> @@ -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> @@ -194,19 +202,19 @@ when p >= 16 </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> 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/notes.xml b/lib/odbc/doc/src/notes.xml index 99584efec9..29fed0e286 100644 --- a/lib/odbc/doc/src/notes.xml +++ b/lib/odbc/doc/src/notes.xml @@ -30,6 +30,25 @@ </header> <p>This document describes the changes made to the odbc application. </p> + + <section><title>ODBC 2.10.8</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + ODBC now handles the types SQL_WCHAR and SQL_WVARCHAR. + 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. This provides some + but not a full unicode support.</p> + <p> + Own Id: OTP-7452</p> + </item> + </list> + </section> + + </section> <section><title>ODBC 2.10.7</title> diff --git a/lib/odbc/doc/src/odbc.xml b/lib/odbc/doc/src/odbc.xml index 450531c81c..3efbac8dd4 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> diff --git a/lib/odbc/src/odbc.erl b/lib/odbc/src/odbc.erl index 8178accf6d..f8914639e6 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}) -> @@ -941,3 +941,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..10ed139338 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,8 @@ -define(USER_DOUBLE, 9). -define(USER_BOOLEAN, 10). -define(USER_TINY_INT, 11). +-define(USER_WCHAR, 12). +-define(USER_WVARCHAR, 13). %% INPUT & OUTPUT TYPE -define(IN, 0). diff --git a/lib/odbc/vsn.mk b/lib/odbc/vsn.mk index 92540d90f8..7af25db25b 100644 --- a/lib/odbc/vsn.mk +++ b/lib/odbc/vsn.mk @@ -1,10 +1,11 @@ -ODBC_VSN = 2.10.7 +ODBC_VSN = 2.10.8 + +TICKETS = OTP-7452 TICKETS_2.10.6 = \ OTP-8250 \ OTP-8291 - TICKETS_2.10.5 = \ OTP-7978 diff --git a/lib/orber/doc/src/notes.xml b/lib/orber/doc/src/notes.xml index d388cc42a8..f97d7ac1fa 100644 --- a/lib/orber/doc/src/notes.xml +++ b/lib/orber/doc/src/notes.xml @@ -33,6 +33,19 @@ </header> <section> + <title>Orber 3.6.16</title> + <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> <section> 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/vsn.mk b/lib/orber/vsn.mk index d074bfb86c..79847451d2 100644 --- a/lib/orber/vsn.mk +++ b/lib/orber/vsn.mk @@ -1,7 +1,9 @@ -ORBER_VSN = 3.6.15 +ORBER_VSN = 3.6.16 -TICKETS = OTP-8353 \ +TICKETS = OTP-8489 + +TICKETS_3.6.15 = OTP-8353 \ OTP-8354 \ OTP-8374 \ OTP-8409 \ diff --git a/lib/parsetools/src/yecc.erl b/lib/parsetools/src/yecc.erl index b8b2b2308c..c4a47d008f 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]. @@ -1994,14 +2006,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 +2092,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) -> diff --git a/lib/parsetools/test/yecc_SUITE.erl b/lib/parsetools/test/yecc_SUITE.erl index b5da414f7b..61e2456323 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]). @@ -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]. diff --git a/lib/sasl/src/overload.erl b/lib/sasl/src/overload.erl index 0deca868be..5a4782efff 100644 --- a/lib/sasl/src/overload.erl +++ b/lib/sasl/src/overload.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(overload). diff --git a/lib/sasl/src/release_handler.erl b/lib/sasl/src/release_handler.erl index 0a3770df6e..4c43277848 100644 --- a/lib/sasl/src/release_handler.erl +++ b/lib/sasl/src/release_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(release_handler). diff --git a/lib/sasl/src/si_sasl_supp.erl b/lib/sasl/src/si_sasl_supp.erl index c64e256115..9c96d11c28 100644 --- a/lib/sasl/src/si_sasl_supp.erl +++ b/lib/sasl/src/si_sasl_supp.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(si_sasl_supp). diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml index 8939fbd6df..33e304abfa 100644 --- a/lib/snmp/doc/src/notes.xml +++ b/lib/snmp/doc/src/notes.xml @@ -33,6 +33,66 @@ </header> <section> + <title>SNMP Development Toolkit 4.16.1</title> + <p>Version 4.16.1 supports code replacement in runtime from/to + version 4.16, 4.15, 4.14 and 4.13.5.</p> + + <section> + <title>Improvements and new features</title> + <p>-</p> + <!-- + <list type="bulleted"> + <item> + <p>[agent|manager] Entries in the audit trail log can now be + augmented by a sequence number. </p> + <p>This is enabled by the <c>seqno</c> option, which is part of the + <seealso marker="snmp_config#audit_trail_log">Audit Trail Log</seealso> + config option. </p> + <p>See the + <seealso marker="snmp_app#configuration_params">reference manual</seealso> + or the + <seealso marker="snmp_config#configuration_params">Configuring the application</seealso> + chapter of the User's Guide for further info. </p> + + <p>Own Id: OTP-8395</p> + </item> + + </list> + --> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + + <list type="bulleted"> + <item> + <p>[manager] Fixed an upgrade/downgrade problem. </p> + <p>Upgrade/downgrade from/to 4.13.5 did not work for the net-if + process. This has now been fixed. </p> + <p>Own Id: OTP-8481</p> + </item> + + <item> + <p>[agent] A minor mnesia related performance improvement. </p> + <p>Own Id: OTP-8480</p> + </item> + + </list> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.16.1 --> + + + <section> <title>SNMP Development Toolkit 4.16</title> <p>Version 4.16 supports code replacement in runtime from/to version 4.15, 4.14 and 4.13.5.</p> diff --git a/lib/snmp/src/agent/snmpa_general_db.erl b/lib/snmp/src/agent/snmpa_general_db.erl index 795c353a9e..a06604c9cf 100644 --- a/lib/snmp/src/agent/snmpa_general_db.erl +++ b/lib/snmp/src/agent/snmpa_general_db.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(snmpa_general_db). @@ -114,14 +114,7 @@ ets_open(Name, Dir, clear, Type) -> mnesia_open({table_exist,Name},_Nodes,_RecName,_Attr,_Type,clear) -> ?vtrace("[mnesia] database ~p already exists; clear content",[Name]), - Pattern = '_', - F = fun() -> - Recs = mnesia:match_object(Name,Pattern,read), - lists:foreach(fun(Rec) -> - mnesia:delete_object(Name,Rec,write) - end, Recs), - Recs - end, + F = fun() -> mnesia:clear_table(Name) end, case mnesia:transaction(F) of {aborted,Reason} -> exit({aborted,Reason}); diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src index 56b8c593a8..204de71c2e 100644 --- a/lib/snmp/src/app/snmp.appup.src +++ b/lib/snmp/src/app/snmp.appup.src @@ -22,11 +22,18 @@ %% ----- U p g r a d e ------------------------------------------------------- [ + {"4.16", + [ + {load_module, snmpa_general_db, soft_purge, soft_purge, []}, + {update, snmpm_net_if, soft, soft_purge, soft_purge, []} + ] + }, {"4.15", [ {load_module, snmpa, soft_purge, soft_purge, [snmp_log]}, {load_module, snmp_config, soft_purge, soft_purge, []}, {load_module, snmp_log, soft_purge, soft_purge, []}, + {load_module, snmpa_general_db, soft_purge, soft_purge, []}, {update, snmpm_net_if, {advanced, upgrade_from_pre_4_16}, soft_purge, soft_purge, [snmpm_config, snmp_log]}, {update, snmpa_net_if, {advanced, upgrade_from_pre_4_16}, @@ -41,14 +48,15 @@ {load_module, snmpa, soft_purge, soft_purge, [snmp_log]}, {load_module, snmp_config, soft_purge, soft_purge, []}, {load_module, snmp_log, soft_purge, soft_purge, []}, - {update, snmpm_net_if, {advanced, upgrade_from_pre_4_16}, - soft_purge, soft_purge, [snmpm_config, snmp_log]}, + {load_module, snmpa_general_db, soft_purge, soft_purge, []}, {update, snmpa_net_if, {advanced, upgrade_from_pre_4_16}, soft_purge, soft_purge, [snmpa_agent, snmp_log]}, {update, snmpa_agent, soft, 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]}, {update, snmpm_config, soft, soft_purge, soft_purge, []}, {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_user_default]} @@ -60,14 +68,15 @@ {load_module, snmpa, soft_purge, soft_purge, [snmp_log]}, {load_module, snmp_config, soft_purge, soft_purge, []}, {load_module, snmp_log, soft_purge, soft_purge, []}, - {update, snmpm_net_if, {advanced, upgrade_from_pre_4_16}, - soft_purge, soft_purge, [snmpm_config, snmp_log]}, + {load_module, snmpa_general_db, soft_purge, soft_purge, []}, {update, snmpa_net_if, {advanced, upgrade_from_pre_4_16}, soft_purge, soft_purge, [snmpa_agent, snmp_log]}, {update, snmpa_agent, soft, 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}, @@ -79,17 +88,25 @@ %% ------D o w n g r a d e --------------------------------------------------- [ + {"4.16", + [ + {load_module, snmpa_general_db, soft_purge, soft_purge, []}, + {update, snmpm_net_if, soft, soft_purge, soft_purge, []} + ] + }, {"4.15", [ {load_module, snmpa, soft_purge, soft_purge, [snmp_log]}, {load_module, snmp_config, soft_purge, soft_purge, []}, {load_module, snmp_log, soft_purge, soft_purge, []}, - {update, snmpm_net_if, {advanced, downgrade_to_pre_4_16}, - soft_purge, soft_purge, [snmpm_config, snmp_log]}, + {load_module, snmpa_general_db, soft_purge, soft_purge, []}, {update, snmpa_net_if, {advanced, downgrade_to_pre_4_16}, soft_purge, soft_purge, [snmpa_agent, snmp_log]}, {update, snmpa_agent, soft, soft_purge, soft_purge, []}, + {load_module, snmpa_general_db, soft_purge, soft_purge, []}, + {update, snmpm_net_if, {advanced, downgrade_to_pre_4_16}, + soft_purge, soft_purge, [snmpm_config, snmp_log]}, {update, snmpm_config, soft, soft_purge, soft_purge, []} ] }, @@ -98,14 +115,15 @@ {load_module, snmpa, soft_purge, soft_purge, [snmp_log]}, {load_module, snmp_config, soft_purge, soft_purge, []}, {load_module, snmp_log, soft_purge, soft_purge, []}, - {update, snmpm_net_if, {advanced, downgrade_to_pre_4_16}, - soft_purge, soft_purge, [snmpm_config, snmp_log]}, + {load_module, snmpa_general_db, soft_purge, soft_purge, []}, {update, snmpa_net_if, {advanced, downgrade_to_pre_4_16}, soft_purge, soft_purge, [snmpa_agent, snmp_log]}, {update, snmpa_agent, soft, 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]}, {update, snmpm_config, soft, soft_purge, soft_purge, []}, {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_user_default]} @@ -117,16 +135,18 @@ {load_module, snmp_config, soft_purge, soft_purge, []}, {load_module, snmpa, soft_purge, soft_purge, [snmp_log]}, {load_module, snmp_log, soft_purge, soft_purge, []}, - {update, snmpm_net_if, {advanced, downgrade_to_pre_4_16}, - soft_purge, soft_purge, [snmpm_config, snmp_log]}, + {load_module, snmpa_general_db, soft_purge, soft_purge, []}, {update, snmpa_net_if, {advanced, downgrade_to_pre_4_16}, soft_purge, soft_purge, [snmpa_agent, snmp_log]}, {update, snmpa_agent, soft, 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}} ] diff --git a/lib/snmp/src/manager/snmpm_net_if.erl b/lib/snmp/src/manager/snmpm_net_if.erl index ad39157721..07156dacd9 100644 --- a/lib/snmp/src/manager/snmpm_net_if.erl +++ b/lib/snmp/src/manager/snmpm_net_if.erl @@ -441,7 +441,7 @@ handle_info(Info, State) -> %% Returns: any (ignored by gen_server) %%-------------------------------------------------------------------- terminate(Reason, #state{log = Log, irgc = IrGcRef}) -> - ?vdebug("terminate: ~p",[Reason]), + ?vdebug("terminate: ~p", [Reason]), irgc_stop(IrGcRef), %% Close logs do_close_log(Log), @@ -462,22 +462,59 @@ do_close_log(_) -> %% Returns: {ok, NewState} %%---------------------------------------------------------------------- +code_change({down, _Vsn}, OldState, downgrade_to_pre_4_14) -> + ?d("code_change(down, downgrade_to_pre_4_14) -> entry with" + "~n OldState: ~p", [OldState]), + #state{server = Server, + note_store = NoteStore, + sock = Sock, + mpd_state = MpdState, + log = {OldLog, Type}, + irb = IRB, + irgc = IRGC} = OldState, + NewLog = snmp_log:downgrade(OldLog), + State = + {state, Server, NoteStore, Sock, MpdState, {NewLog, Type}, IRB, IRGC}, + {ok, State}; + code_change({down, _Vsn}, OldState, downgrade_to_pre_4_16) -> - ?d("code_change(down) -> entry", []), + ?d("code_change(down, downgrade_to_pre_4_16) -> entry with" + "~n OldState: ~p", [OldState]), {OldLog, Type} = OldState#state.log, NewLog = snmp_log:downgrade(OldLog), State = OldState#state{log = {NewLog, Type}}, {ok, State}; % upgrade +code_change(_Vsn, OldState, upgrade_from_pre_4_14) -> + ?d("code_change(up, upgrade_from_pre_4_14) -> entry with" + "~n OldState: ~p", [OldState]), + {state, Server, NoteStore, Sock, MpdState, {OldLog, Type}, IRB, IRGC} = + OldState, + NewLog = snmp_log:upgrade(OldLog), + State = #state{server = Server, + note_store = NoteStore, + sock = Sock, + mpd_state = MpdState, + log = {NewLog, Type}, + irb = IRB, + irgc = IRGC, + filter = ?DEFAULT_FILTER_MODULE}, + {ok, State}; + code_change(_Vsn, OldState, upgrade_from_pre_4_16) -> - ?d("code_change(up) -> entry", []), + ?d("code_change(up, upgrade_from_pre_4_16) -> entry with" + "~n OldState: ~p", [OldState]), {OldLog, Type} = OldState#state.log, NewLog = snmp_log:upgrade(OldLog), State = OldState#state{log = {NewLog, Type}}, {ok, State}; code_change(_Vsn, State, _Extra) -> + ?d("code_change -> entry with" + "~n Vsn: ~p" + "~n State: ~p" + "~n Extra: ~p", [_Vsn, State, _Extra]), {ok, State}. diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk index c4550d9b44..50c72b33b5 100644 --- a/lib/snmp/vsn.mk +++ b/lib/snmp/vsn.mk @@ -17,11 +17,13 @@ # # %CopyrightEnd% -SNMP_VSN = 4.16 +SNMP_VSN = 4.16.1 PRE_VSN = APP_VSN = "snmp-$(SNMP_VSN)$(PRE_VSN)" -TICKETS = \ +TICKETS = OTP-8480 OTP-8481 + +TICKETS_4_16 = \ OTP-8395 \ OTP-8433 \ OTP-8442 diff --git a/lib/stdlib/src/epp.erl b/lib/stdlib/src/epp.erl index 424aed3d2e..e1b569d389 100644 --- a/lib/stdlib/src/epp.erl +++ b/lib/stdlib/src/epp.erl @@ -176,6 +176,8 @@ parse_file(Epp) -> [{eof,Location}] end. +normalize_typed_record_fields([]) -> + {typed, []}; normalize_typed_record_fields(Fields) -> normalize_typed_record_fields(Fields, [], false). @@ -753,7 +755,7 @@ 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). diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl index 91f7641af7..22f435aff8 100644 --- a/lib/stdlib/src/erl_lint.erl +++ b/lib/stdlib/src/erl_lint.erl @@ -1021,11 +1021,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 +1035,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. diff --git a/lib/stdlib/src/erl_pp.erl b/lib/stdlib/src/erl_pp.erl index b1b5bad294..0859bf0466 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). @@ -161,15 +161,16 @@ 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). diff --git a/lib/stdlib/src/filelib.erl b/lib/stdlib/src/filelib.erl index 74c5172137..5c5e084e17 100644 --- a/lib/stdlib/src/filelib.erl +++ b/lib/stdlib/src/filelib.erl @@ -40,66 +40,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 +218,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/test/epp_SUITE.erl b/lib/stdlib/test/epp_SUITE.erl index 9a3ae0baf5..3342e8f1ff 100644 --- a/lib/stdlib/test/epp_SUITE.erl +++ b/lib/stdlib/test/epp_SUITE.erl @@ -23,7 +23,7 @@ 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]). -export([epp_parse_erl_form/2]). @@ -63,7 +63,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]. rec_1(doc) -> ["Recursive macros hang or crash epp (OTP-1398)."]; @@ -1134,11 +1134,47 @@ otp_8388(Config) when is_list(Config) -> {errors,[{{2,8},epp,{mismatch,'A'}}],[]}}, {macro_5, <<"-define(Q, {?F0(), ?F1(,,4)}).\n">>, - {errors,[{{1,24},epp,{arg_error,'F1'}}],[]}} + {errors,[{{1,24},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,11},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. + check(Config, Tests) -> eval_tests(Config, fun check_test/2, Tests). diff --git a/lib/stdlib/test/erl_pp_SUITE.erl b/lib/stdlib/test/erl_pp_SUITE.erl index 0a119d1e38..a695374908 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]). %% Internal export. -export([ehook/6]). @@ -763,7 +764,7 @@ 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_6321(doc) -> "OTP_6321. Bug fix of exprs()."; @@ -911,6 +912,16 @@ 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. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% compile(Config, Tests) -> diff --git a/lib/stdlib/vsn.mk b/lib/stdlib/vsn.mk index e02bad48df..f081bd60e2 100644 --- a/lib/stdlib/vsn.mk +++ b/lib/stdlib/vsn.mk @@ -1,21 +1,21 @@ # # %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% # -STDLIB_VSN = 1.16.5 +STDLIB_VSN = 1.17 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/src/cover.erl b/lib/tools/src/cover.erl index 1a7ebdc69a..6501e05a6e 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 -> 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_utils.erl b/lib/tools/src/xref_utils.erl index 680b7e8aac..0ef199cec7 100644 --- a/lib/tools/src/xref_utils.erl +++ b/lib/tools/src/xref_utils.erl @@ -640,22 +640,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/xref_SUITE.erl b/lib/tools/test/xref_SUITE.erl index b4684140ca..a7855b0bb9 100644 --- a/lib/tools/test/xref_SUITE.erl +++ b/lib/tools/test/xref_SUITE.erl @@ -2306,8 +2306,8 @@ format_error(Conf) when is_list(Conf) -> ?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' @@ -2705,7 +2705,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 diff --git a/system/doc/reference_manual/expressions.xml b/system/doc/reference_manual/expressions.xml index fa7870d96c..b56b8acbf0 100644 --- a/system/doc/reference_manual/expressions.xml +++ b/system/doc/reference_manual/expressions.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>Expressions</title> @@ -1257,6 +1257,9 @@ end</pre> <cell align="left" valign="middle"><c>is_bitstring/1</c></cell> </row> <row> + <cell align="left" valign="middle"><c>is_boolean/1</c></cell> + </row> + <row> <cell align="left" valign="middle"><c>is_float/1</c></cell> </row> <row> |