summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--erts/etc/win32/erlang.icobin1398 -> 49853 bytes
-rw-r--r--erts/vsn.mk4
-rw-r--r--lib/eunit/include/eunit.hrl195
-rw-r--r--lib/eunit/src/Makefile2
-rw-r--r--lib/inets/src/http_client/httpc_response.erl16
-rw-r--r--lib/kernel/vsn.mk2
-rw-r--r--lib/observer/src/crashdump_viewer.erl5
-rw-r--r--lib/observer/src/observer_tv_table.erl4
-rw-r--r--lib/odbc/c_src/odbcserver.c2
-rw-r--r--lib/odbc/test/odbc_query_SUITE.erl22
-rw-r--r--lib/odbc/test/oracle.erl27
-rw-r--r--lib/odbc/test/postgres.erl39
-rw-r--r--lib/stdlib/include/assert.hrl230
-rw-r--r--lib/stdlib/src/Makefile1
-rw-r--r--lib/stdlib/test/Makefile3
-rw-r--r--lib/stdlib/test/stdlib_SUITE.erl29
-rw-r--r--lib/stdlib/vsn.mk2
-rw-r--r--lib/tools/emacs/erlang-pkg.el2
18 files changed, 381 insertions, 204 deletions
diff --git a/erts/etc/win32/erlang.ico b/erts/etc/win32/erlang.ico
index cee8b58af9..92857c507a 100644
--- a/erts/etc/win32/erlang.ico
+++ b/erts/etc/win32/erlang.ico
Binary files differ
diff --git a/erts/vsn.mk b/erts/vsn.mk
index 4cdc20b550..8baf169d6f 100644
--- a/erts/vsn.mk
+++ b/erts/vsn.mk
@@ -17,8 +17,8 @@
# %CopyrightEnd%
#
-VSN = 5.10.1
-SYSTEM_VSN = R16B
+VSN = 5.11
+SYSTEM_VSN = R17A
# Port number 4365 in 4.2
# Port number 4366 in 4.3
diff --git a/lib/eunit/include/eunit.hrl b/lib/eunit/include/eunit.hrl
index 8ebdb6ba16..4ddc5ebeab 100644
--- a/lib/eunit/include/eunit.hrl
+++ b/lib/eunit/include/eunit.hrl
@@ -16,6 +16,9 @@
%%
%% Copyright (C) 2004-2006 Mickaël Rémond, Richard Carlsson
+-ifndef(EUNIT_HRL).
+-define(EUNIT_HRL, true).
+
%% Including this file turns on testing and defines TEST, unless NOTEST
%% is defined before the file is included. If both NOTEST and TEST are
%% already defined, then TEST takes precedence, and NOTEST will become
@@ -36,9 +39,6 @@
%% After including this file, EUNIT will be defined if and only if TEST
%% is defined.
--ifndef(EUNIT_HRL).
--define(EUNIT_HRL, true).
-
%% allow defining TEST to override NOTEST
-ifdef(TEST).
@@ -50,13 +50,6 @@
-undef(NODEBUG).
-endif.
-%% allow NODEBUG to imply NOASSERT, unless overridden below
--ifdef(NODEBUG).
--ifndef(NOASSERT).
--define(NOASSERT, true).
--endif.
--endif.
-
%% note that the main switch used within this file is NOTEST; however,
%% both TEST and EUNIT may be used to check whether testing is enabled
-ifndef(NOTEST).
@@ -71,10 +64,8 @@
-undef(EUNIT).
-endif.
-%% allow ASSERT to override NOASSERT (regardless of TEST/NOTEST)
--ifdef(ASSERT).
--undef(NOASSERT).
--endif.
+%% include the assert macros; ASSERT overrides NOASSERT if defined
+-include_lib("stdlib/include/assert.hrl").
%% Parse transforms for automatic exporting/stripping of test functions.
%% (Note that although automatic stripping is convenient, it will make
@@ -129,195 +120,21 @@
current_function)))).
-endif.
-%% The plain assert macro should be defined to do nothing if this file
-%% is included when debugging/testing is turned off.
--ifdef(NOASSERT).
--ifndef(assert).
--define(assert(BoolExpr),ok).
--endif.
--else.
-%% The assert macro is written the way it is so as not to cause warnings
-%% for clauses that cannot match, even if the expression is a constant.
--undef(assert).
--define(assert(BoolExpr),
- ((fun () ->
- case (BoolExpr) of
- true -> ok;
- __V -> erlang:error({assertion_failed,
- [{module, ?MODULE},
- {line, ?LINE},
- {expression, (??BoolExpr)},
- {expected, true},
- {value, case __V of false -> __V;
- _ -> {not_a_boolean,__V}
- end}]})
- end
- end)())).
--endif.
--define(assertNot(BoolExpr), ?assert(not (BoolExpr))).
+%% General test macros
-define(_test(Expr), {?LINE, fun () -> (Expr) end}).
-
-define(_assert(BoolExpr), ?_test(?assert(BoolExpr))).
-
-define(_assertNot(BoolExpr), ?_assert(not (BoolExpr))).
-
-%% This is mostly a convenience which gives more detailed reports.
-%% Note: Guard is a guarded pattern, and can not be used for value.
--ifdef(NOASSERT).
--define(assertMatch(Guard, Expr), ok).
--else.
--define(assertMatch(Guard, Expr),
- ((fun () ->
- case (Expr) of
- Guard -> ok;
- __V -> erlang:error({assertMatch_failed,
- [{module, ?MODULE},
- {line, ?LINE},
- {expression, (??Expr)},
- {pattern, (??Guard)},
- {value, __V}]})
- end
- end)())).
--endif.
-define(_assertMatch(Guard, Expr), ?_test(?assertMatch(Guard, Expr))).
-
-%% This is the inverse case of assertMatch, for convenience.
--ifdef(NOASSERT).
--define(assertNotMatch(Guard, Expr), ok).
--else.
--define(assertNotMatch(Guard, Expr),
- ((fun () ->
- __V = (Expr),
- case __V of
- Guard -> erlang:error({assertNotMatch_failed,
- [{module, ?MODULE},
- {line, ?LINE},
- {expression, (??Expr)},
- {pattern, (??Guard)},
- {value, __V}]});
- _ -> ok
- end
- end)())).
--endif.
-define(_assertNotMatch(Guard, Expr), ?_test(?assertNotMatch(Guard, Expr))).
-
-%% This is a convenience macro which gives more detailed reports when
-%% the expected LHS value is not a pattern, but a computed value
--ifdef(NOASSERT).
--define(assertEqual(Expect, Expr), ok).
--else.
--define(assertEqual(Expect, Expr),
- ((fun (__X) ->
- case (Expr) of
- __X -> ok;
- __V -> erlang:error({assertEqual_failed,
- [{module, ?MODULE},
- {line, ?LINE},
- {expression, (??Expr)},
- {expected, __X},
- {value, __V}]})
- end
- end)(Expect))).
--endif.
-define(_assertEqual(Expect, Expr), ?_test(?assertEqual(Expect, Expr))).
-
-%% This is the inverse case of assertEqual, for convenience.
--ifdef(NOASSERT).
--define(assertNotEqual(Unexpected, Expr), ok).
--else.
--define(assertNotEqual(Unexpected, Expr),
- ((fun (__X) ->
- case (Expr) of
- __X -> erlang:error({assertNotEqual_failed,
- [{module, ?MODULE},
- {line, ?LINE},
- {expression, (??Expr)},
- {value, __X}]});
- _ -> ok
- end
- end)(Unexpected))).
--endif.
-define(_assertNotEqual(Unexpected, Expr),
?_test(?assertNotEqual(Unexpected, Expr))).
-
-%% Note: Class and Term are patterns, and can not be used for value.
-%% Term can be a guarded pattern, but Class cannot.
--ifdef(NOASSERT).
--define(assertException(Class, Term, Expr), ok).
--else.
--define(assertException(Class, Term, Expr),
- ((fun () ->
- try (Expr) of
- __V -> erlang:error({assertException_failed,
- [{module, ?MODULE},
- {line, ?LINE},
- {expression, (??Expr)},
- {pattern,
- "{ "++(??Class)++" , "++(??Term)
- ++" , [...] }"},
- {unexpected_success, __V}]})
- catch
- Class:Term -> ok;
- __C:__T ->
- erlang:error({assertException_failed,
- [{module, ?MODULE},
- {line, ?LINE},
- {expression, (??Expr)},
- {pattern,
- "{ "++(??Class)++" , "++(??Term)
- ++" , [...] }"},
- {unexpected_exception,
- {__C, __T,
- erlang:get_stacktrace()}}]})
- end
- end)())).
--endif.
-
--define(assertError(Term, Expr), ?assertException(error, Term, Expr)).
--define(assertExit(Term, Expr), ?assertException(exit, Term, Expr)).
--define(assertThrow(Term, Expr), ?assertException(throw, Term, Expr)).
-
-define(_assertException(Class, Term, Expr),
?_test(?assertException(Class, Term, Expr))).
-define(_assertError(Term, Expr), ?_assertException(error, Term, Expr)).
-define(_assertExit(Term, Expr), ?_assertException(exit, Term, Expr)).
-define(_assertThrow(Term, Expr), ?_assertException(throw, Term, Expr)).
-
-%% This is the inverse case of assertException, for convenience.
-%% Note: Class and Term are patterns, and can not be used for value.
-%% Both Class and Term can be guarded patterns.
--ifdef(NOASSERT).
--define(assertNotException(Class, Term, Expr), ok).
--else.
--define(assertNotException(Class, Term, Expr),
- ((fun () ->
- try (Expr) of
- _ -> ok
- catch
- __C:__T ->
- case __C of
- Class ->
- case __T of
- Term ->
- erlang:error({assertNotException_failed,
- [{module, ?MODULE},
- {line, ?LINE},
- {expression, (??Expr)},
- {pattern,
- "{ "++(??Class)++" , "
- ++(??Term)++" , [...] }"},
- {unexpected_exception,
- {__C, __T,
- erlang:get_stacktrace()
- }}]});
- _ -> ok
- end;
- _ -> ok
- end
- end
- end)())).
--endif.
-define(_assertNotException(Class, Term, Expr),
?_test(?assertNotException(Class, Term, Expr))).
diff --git a/lib/eunit/src/Makefile b/lib/eunit/src/Makefile
index e88e28df83..5b2c364887 100644
--- a/lib/eunit/src/Makefile
+++ b/lib/eunit/src/Makefile
@@ -24,7 +24,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/eunit-$(VSN)
EBIN = ../ebin
INCLUDE=../include
-ERL_COMPILE_FLAGS += -pa $(EBIN) -I$(INCLUDE) +warn_unused_vars +nowarn_shadow_vars +warn_unused_import +warn_obsolete_guard
+ERL_COMPILE_FLAGS += -pa $(EBIN) -pa ../../stdlib/ebin -I$(INCLUDE) +warn_unused_vars +nowarn_shadow_vars +warn_unused_import +warn_obsolete_guard
PARSE_TRANSFORM = eunit_autoexport.erl
diff --git a/lib/inets/src/http_client/httpc_response.erl b/lib/inets/src/http_client/httpc_response.erl
index f177aac8f2..8142eb8bce 100644
--- a/lib/inets/src/http_client/httpc_response.erl
+++ b/lib/inets/src/http_client/httpc_response.erl
@@ -426,7 +426,7 @@ format_response({{"HTTP/0.9", _, _} = StatusLine, _, Body}) ->
format_response({StatusLine, Headers, Body = <<>>}) ->
{{StatusLine, http_response:header_list(Headers), Body}, <<>>};
-format_response({StatusLine, Headers, Body}) ->
+format_response({{"HTTP/1.0", _, _} = StatusLine, Headers, Body}) ->
Length = list_to_integer(Headers#http_response_h.'content-length'),
{NewBody, Data} =
case Length of
@@ -440,6 +440,20 @@ format_response({StatusLine, Headers, Body}) ->
_ -> %% Connection prematurely ended.
{Body, <<>>}
end,
+ {{StatusLine, http_response:header_list(Headers), NewBody}, Data};
+
+format_response({{"HTTP/1.1", _, _} = StatusLine, Headers, Body}) ->
+ Length = list_to_integer(Headers#http_response_h.'content-length'),
+ {NewBody, Data} =
+ case Length of
+ -1 -> % When no lenght indicator is provided
+ {Body, <<>>};
+ Length when (Length =< size(Body)) ->
+ <<BodyThisReq:Length/binary, Next/binary>> = Body,
+ {BodyThisReq, Next};
+ _ -> %% Connection prematurely ended.
+ {Body, <<>>}
+ end,
{{StatusLine, http_response:header_list(Headers), NewBody}, Data}.
%%--------------------------------------------------------------------------
diff --git a/lib/kernel/vsn.mk b/lib/kernel/vsn.mk
index b6cf4407d2..23af0599fc 100644
--- a/lib/kernel/vsn.mk
+++ b/lib/kernel/vsn.mk
@@ -1 +1 @@
-KERNEL_VSN = 2.16.1
+KERNEL_VSN = 2.17
diff --git a/lib/observer/src/crashdump_viewer.erl b/lib/observer/src/crashdump_viewer.erl
index 3b8d17c7d9..64a8457d16 100644
--- a/lib/observer/src/crashdump_viewer.erl
+++ b/lib/observer/src/crashdump_viewer.erl
@@ -214,6 +214,7 @@ script_start([File]) ->
DefaultBrowser =
case os:type() of
{win32,_} -> iexplore;
+ {unix,darwin} -> open;
_ -> firefox
end,
script_start([File,DefaultBrowser]);
@@ -277,8 +278,8 @@ usage() ->
io:format(
"\nusage: cdv file [ browser ]\n"
"\tThe \'file\' must be an existing erlang crash dump.\n"
- "\tDefault browser is \'iexplore\' (Internet Explorer) on Windows\n"
- "\tor else \'firefox\'.\n",
+ "\tDefault browser is \'iexplore\' (Internet Explorer) on Windows,\n"
+ "\t\'open\' on Mac OS X, or else \'firefox\'.\n",
[]).
diff --git a/lib/observer/src/observer_tv_table.erl b/lib/observer/src/observer_tv_table.erl
index 5d1ab2e946..83619414ad 100644
--- a/lib/observer/src/observer_tv_table.erl
+++ b/lib/observer/src/observer_tv_table.erl
@@ -784,8 +784,10 @@ format_list(List) ->
make_list([Last]) ->
[format(Last), $]];
+make_list([Head|Tail]) when is_list(Tail) ->
+ [format(Head), $,|make_list(Tail)];
make_list([Head|Tail]) ->
- [format(Head), $,|make_list(Tail)].
+ [format(Head), $|, format(Tail), $]].
map_printable_list([$\n|Cs]) ->
[$\\, $n|map_printable_list(Cs)];
diff --git a/lib/odbc/c_src/odbcserver.c b/lib/odbc/c_src/odbcserver.c
index a6b3de6e48..5730e20774 100644
--- a/lib/odbc/c_src/odbcserver.c
+++ b/lib/odbc/c_src/odbcserver.c
@@ -1222,7 +1222,7 @@ static db_result_msg encode_out_params(db_state *state,
(column.type.strlen_or_indptr_array[j]));
break;
case SQL_C_SLONG:
- ei_x_encode_long(&dynamic_buffer(state), ((long*)values)[j]);
+ ei_x_encode_long(&dynamic_buffer(state), ((SQLINTEGER*)values)[j]);
break;
case SQL_C_DOUBLE:
ei_x_encode_double(&dynamic_buffer(state),
diff --git a/lib/odbc/test/odbc_query_SUITE.erl b/lib/odbc/test/odbc_query_SUITE.erl
index 062373afa0..56550bfaa6 100644
--- a/lib/odbc/test/odbc_query_SUITE.erl
+++ b/lib/odbc/test/odbc_query_SUITE.erl
@@ -43,7 +43,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
case odbc_test_lib:odbc_check() of
ok ->
- [sql_query, next, {group, scrollable_cursors}, select_count,
+ [stored_proc, sql_query, next, {group, scrollable_cursors}, select_count,
select_next, select_relative, select_absolute,
create_table_twice, delete_table_twice, duplicate_key,
not_connection_owner, no_result_set, query_error,
@@ -172,6 +172,26 @@ end_per_testcase(_Case, Config) ->
%%-------------------------------------------------------------------------
%% Test cases starts here.
%%-------------------------------------------------------------------------
+stored_proc(doc)->
+ ["Test stored proc with OUT param"];
+stored_proc(suite) -> [];
+stored_proc(Config) when is_list(Config) ->
+ case ?RDBMS of
+ X when X == oracle; X == postgres->
+ Ref = ?config(connection_ref, Config),
+ {updated, _} =
+ odbc:sql_query(Ref,
+ ?RDBMS:stored_proc_integer_out()),
+ Result = ?RDBMS:query_result(),
+ Result =
+ ?RDBMS:param_query(Ref),
+ {updated, _} =
+ odbc:sql_query(Ref, ?RDBMS:drop_proc()),
+ ok;
+ _ ->
+ {skip, "stored proc not yet supported"}
+ end.
+
sql_query(doc)->
["Test the common cases"];
sql_query(suite) -> [];
diff --git a/lib/odbc/test/oracle.erl b/lib/odbc/test/oracle.erl
index d74863d8c1..95cf7155dc 100644
--- a/lib/odbc/test/oracle.erl
+++ b/lib/odbc/test/oracle.erl
@@ -240,3 +240,30 @@ describe_floating() ->
{ok,[{"F",sql_double},{"R",sql_double},{"D",sql_double}]}.
describe_dec_num() ->
{ok,[{"MYDEC",{sql_decimal,9,3}},{"MYNUM",{sql_decimal,9,2}}]}.
+
+%-------------------------------------------------------------------------
+drop_proc() ->
+ "drop procedure test_proc1;".
+
+stored_proc_integer_out() ->
+ "create or replace PROCEDURE test_proc1(" ++
+ "int_a OUT NUMBER, " ++
+ "int_b OUT NUMBER) " ++
+ "is " ++
+ "begin " ++
+ " int_a := 123; " ++
+ " int_b := 456; " ++
+ "exception " ++
+ "WHEN NO_DATA_FOUND THEN " ++
+ " int_a := 0; " ++
+ " int_b := 0; " ++
+ "end;".
+
+param_query(Ref) ->
+ odbc:param_query(Ref, "call test_proc1(?,?)",
+ [{sql_integer, out, [0]},
+ {sql_integer, out, [0]}]).
+
+
+query_result() ->
+ {executed, 2, [{123, 456}]}.
diff --git a/lib/odbc/test/postgres.erl b/lib/odbc/test/postgres.erl
index d564dbd5ff..0c1761b835 100644
--- a/lib/odbc/test/postgres.erl
+++ b/lib/odbc/test/postgres.erl
@@ -293,3 +293,42 @@ describe_dec_num() ->
describe_timestamp() ->
{ok, [{"field", sql_timestamp}]}.
+
+%-------------------------------------------------------------------------
+drop_proc() ->
+ "drop function test_proc1(OUT integer, OUT integer);".
+
+stored_proc_integer_out() ->
+ "create or replace FUNCTION test_proc1(" ++
+ "OUT int_a INTEGER, " ++
+ "OUT int_b INTEGER) " ++
+ "AS $$ " ++
+ "BEGIN " ++
+ " int_a := 123; " ++
+ " int_b := 456; " ++
+ "END " ++
+ "$$ LANGUAGE plpgsql ".
+
+%% This does not test what you might think it is supposed to test.
+%% Since the stored procedure has got 2 out parameters and no
+%% in parameters it is of arity 0 as called below.
+%%
+%% The port program odbcserver.c will marshal these out parameters
+%% and hand them to ODBC. The ODBC driver for postgres will
+%% apparently not give a hoot about these out parameters and instead
+%% return the result in a regular result select set. The port program
+%% will assume it has the result in the out parameters and marshal
+%% these as they are i.e as it itself had packed them, so they
+%% come back unchanged.
+%%
+%% The real function result goes into the void but the code in odbcserver.c
+%% that marshals out parameters returned from ODBC will be run
+%% so that is what this test tests...
+%%
+param_query(Ref) ->
+ odbc:param_query(Ref, "select * from test_proc1()",
+ [{sql_integer, out, [111]},
+ {sql_integer, out, [444]}]).
+
+query_result() ->
+ {executed, 2, [{111, 444}]}.
diff --git a/lib/stdlib/include/assert.hrl b/lib/stdlib/include/assert.hrl
new file mode 100644
index 0000000000..a401229135
--- /dev/null
+++ b/lib/stdlib/include/assert.hrl
@@ -0,0 +1,230 @@
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% Copyright (C) 2004-2012 Richard Carlsson, Mickaël Rémond
+
+-ifndef(ASSERT_HRL).
+-define(ASSERT_HRL, true).
+
+%% Asserts are enabled unless NOASSERT is defined, and ASSERT can be used to
+%% override it: if both ASSERT and NOASSERT are defined, then ASSERT takes
+%% precedence, and NOASSERT will become undefined.
+%%
+%% Furthermore, if NODEBUG is defined, it implies NOASSERT, unless DEBUG or
+%% ASSERT are defined.
+
+
+%% allow NODEBUG to imply NOASSERT, unless DEBUG
+-ifdef(NODEBUG).
+-ifndef(DEBUG).
+-ifndef(NOASSERT).
+-define(NOASSERT, true).
+-endif.
+-endif.
+-endif.
+
+
+%% allow ASSERT to override NOASSERT
+-ifdef(ASSERT).
+-undef(NOASSERT).
+-endif.
+
+
+%% Assert macros must not depend on any non-kernel or stdlib libraries.
+%%
+%% We must use fun-call wrappers ((fun () -> ... end)()) to avoid
+%% exporting local variables, and furthermore we only use variable names
+%% prefixed with "__", that hopefully will not be bound outside the fun.
+%% It is not possible to nest assert macros.
+
+
+%% The plain assert macro should be defined to do nothing if this file is
+%% included when asserts are turned off, but avoid getting a compilation
+%% error if a macro called assert is already defined for some reason.
+-ifdef(NOASSERT).
+-ifndef(assert).
+-define(assert(BoolExpr),ok).
+-endif.
+-else.
+%% The assert macro is written the way it is so as not to cause warnings
+%% for clauses that cannot match, even if the expression is a constant.
+-undef(assert).
+-define(assert(BoolExpr),
+ ((fun () ->
+ case (BoolExpr) of
+ true -> ok;
+ __V -> erlang:error({assertion_failed,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {expression, (??BoolExpr)},
+ {expected, true},
+ {value, case __V of false -> __V;
+ _ -> {not_a_boolean,__V}
+ end}]})
+ end
+ end)())).
+-endif.
+
+-define(assertNot(BoolExpr), ?assert(not (BoolExpr))).
+
+
+%% This is mostly a convenience which gives more detailed reports.
+%% Note: Guard is a guarded pattern, and can not be used for value.
+-ifdef(NOASSERT).
+-define(assertMatch(Guard, Expr), ok).
+-else.
+-define(assertMatch(Guard, Expr),
+ ((fun () ->
+ case (Expr) of
+ Guard -> ok;
+ __V -> erlang:error({assertMatch_failed,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {expression, (??Expr)},
+ {pattern, (??Guard)},
+ {value, __V}]})
+ end
+ end)())).
+-endif.
+
+
+%% This is the inverse case of assertMatch, for convenience.
+-ifdef(NOASSERT).
+-define(assertNotMatch(Guard, Expr), ok).
+-else.
+-define(assertNotMatch(Guard, Expr),
+ ((fun () ->
+ __V = (Expr),
+ case __V of
+ Guard -> erlang:error({assertNotMatch_failed,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {expression, (??Expr)},
+ {pattern, (??Guard)},
+ {value, __V}]});
+ _ -> ok
+ end
+ end)())).
+-endif.
+
+
+%% This is a convenience macro which gives more detailed reports when
+%% the expected LHS value is not a pattern, but a computed value
+-ifdef(NOASSERT).
+-define(assertEqual(Expect, Expr), ok).
+-else.
+-define(assertEqual(Expect, Expr),
+ ((fun (__X) ->
+ case (Expr) of
+ __X -> ok;
+ __V -> erlang:error({assertEqual_failed,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {expression, (??Expr)},
+ {expected, __X},
+ {value, __V}]})
+ end
+ end)(Expect))).
+-endif.
+
+
+%% This is the inverse case of assertEqual, for convenience.
+-ifdef(NOASSERT).
+-define(assertNotEqual(Unexpected, Expr), ok).
+-else.
+-define(assertNotEqual(Unexpected, Expr),
+ ((fun (__X) ->
+ case (Expr) of
+ __X -> erlang:error({assertNotEqual_failed,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {expression, (??Expr)},
+ {value, __X}]});
+ _ -> ok
+ end
+ end)(Unexpected))).
+-endif.
+
+
+%% Note: Class and Term are patterns, and can not be used for value.
+%% Term can be a guarded pattern, but Class cannot.
+-ifdef(NOASSERT).
+-define(assertException(Class, Term, Expr), ok).
+-else.
+-define(assertException(Class, Term, Expr),
+ ((fun () ->
+ try (Expr) of
+ __V -> erlang:error({assertException_failed,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {expression, (??Expr)},
+ {pattern,
+ "{ "++(??Class)++" , "++(??Term)
+ ++" , [...] }"},
+ {unexpected_success, __V}]})
+ catch
+ Class:Term -> ok;
+ __C:__T ->
+ erlang:error({assertException_failed,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {expression, (??Expr)},
+ {pattern,
+ "{ "++(??Class)++" , "++(??Term)
+ ++" , [...] }"},
+ {unexpected_exception,
+ {__C, __T,
+ erlang:get_stacktrace()}}]})
+ end
+ end)())).
+-endif.
+
+-define(assertError(Term, Expr), ?assertException(error, Term, Expr)).
+-define(assertExit(Term, Expr), ?assertException(exit, Term, Expr)).
+-define(assertThrow(Term, Expr), ?assertException(throw, Term, Expr)).
+
+
+%% This is the inverse case of assertException, for convenience.
+%% Note: Class and Term are patterns, and can not be used for value.
+%% Both Class and Term can be guarded patterns.
+-ifdef(NOASSERT).
+-define(assertNotException(Class, Term, Expr), ok).
+-else.
+-define(assertNotException(Class, Term, Expr),
+ ((fun () ->
+ try (Expr) of
+ _ -> ok
+ catch
+ __C:__T ->
+ case __C of
+ Class ->
+ case __T of
+ Term ->
+ erlang:error({assertNotException_failed,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {expression, (??Expr)},
+ {pattern,
+ "{ "++(??Class)++" , "
+ ++(??Term)++" , [...] }"},
+ {unexpected_exception,
+ {__C, __T,
+ erlang:get_stacktrace()
+ }}]});
+ _ -> ok
+ end;
+ _ -> ok
+ end
+ end
+ end)())).
+-endif.
+
+
+-endif. % ASSERT_HRL
diff --git a/lib/stdlib/src/Makefile b/lib/stdlib/src/Makefile
index f3387d669b..1a5fb2462d 100644
--- a/lib/stdlib/src/Makefile
+++ b/lib/stdlib/src/Makefile
@@ -120,6 +120,7 @@ MODULES= \
zip
HRL_FILES= \
+ ../include/assert.hrl \
../include/erl_compile.hrl \
../include/erl_bits.hrl \
../include/ms_transform.hrl \
diff --git a/lib/stdlib/test/Makefile b/lib/stdlib/test/Makefile
index 6aa09d7bd0..b0bb83dfa0 100644
--- a/lib/stdlib/test/Makefile
+++ b/lib/stdlib/test/Makefile
@@ -101,7 +101,8 @@ RELSYSDIR = $(RELEASE_PATH)/stdlib_test
ERL_MAKE_FLAGS +=
ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include \
- -I$(ERL_TOP)/lib/kernel/include
+ -I$(ERL_TOP)/lib/kernel/include \
+ -I$(ERL_TOP)/lib/stdlib/include
EBIN = .
diff --git a/lib/stdlib/test/stdlib_SUITE.erl b/lib/stdlib/test/stdlib_SUITE.erl
index 8a2cb5ea6b..eb71463deb 100644
--- a/lib/stdlib/test/stdlib_SUITE.erl
+++ b/lib/stdlib/test/stdlib_SUITE.erl
@@ -33,7 +33,7 @@
-export([init_per_testcase/2, end_per_testcase/2]).
% Test cases must be exported.
--export([app_test/1, appup_test/1]).
+-export([app_test/1, appup_test/1, assert_test/1]).
%%
%% all/1
@@ -41,7 +41,7 @@
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [app_test, appup_test].
+ [app_test, appup_test, assert_test].
groups() ->
[].
@@ -136,3 +136,28 @@ check_appup([Vsn|Vsns],Instrs,Expected) ->
end;
check_appup([],_,_) ->
ok.
+
+-include_lib("stdlib/include/assert.hrl").
+-include_lib("stdlib/include/assert.hrl"). % test repeated inclusion
+assert_test(suite) ->
+ [];
+assert_test(doc) ->
+ ["Assert macros test."];
+assert_test(_Config) ->
+ ?assert(1 =:= 1),
+ ?assertNot(1 =:= 1.0),
+ ?assertMatch({foo,_}, {foo,bar}),
+ ?assertNotMatch({foo,_}, {foo,bar,baz}),
+ ?assertMatch({foo,N} when N > 0, {foo,1}),
+ ?assertNotMatch({foo,N} when N > 0, {foo,0}),
+ ?assertEqual(1.0, 1.0),
+ ?assertNotEqual(1, 1.0),
+ ?assertException(error, badarith, 1/0),
+ ?assertException(exit, foo, exit(foo)),
+ ?assertException(throw, foo, throw(foo)),
+ ?assertException(throw, {foo,_}, throw({foo,bar})),
+ ?assertNotException(throw, {foo,baz}, throw({foo,bar})),
+ ?assertError(badarith, 1/0),
+ ?assertExit(foo, exit(foo)),
+ ?assertThrow(foo, throw(foo)),
+ ok.
diff --git a/lib/stdlib/vsn.mk b/lib/stdlib/vsn.mk
index c1467697e3..c9d596f737 100644
--- a/lib/stdlib/vsn.mk
+++ b/lib/stdlib/vsn.mk
@@ -1 +1 @@
-STDLIB_VSN = 1.19.1
+STDLIB_VSN = 1.20
diff --git a/lib/tools/emacs/erlang-pkg.el b/lib/tools/emacs/erlang-pkg.el
index decc696e21..3bd1137eb3 100644
--- a/lib/tools/emacs/erlang-pkg.el
+++ b/lib/tools/emacs/erlang-pkg.el
@@ -1,3 +1,3 @@
(define-package "erlang" "2.7.0"
"Erlang major mode"
- '((flymake-mode "0.4.6")))
+ '((flymake "0.3")))