Ticket #17099: R12B5-updated.diff

File R12B5-updated.diff, 32.1 KB (added by nottwo (Trannie Carter), 15 years ago)

This patch does not assume that the P1 patch has been integrated into the erlang port

  • files/patch-lib_ssl_c_src_Makefile.in

     
    1 --- lib/ssl/c_src/Makefile.in.orig      2008-04-13 20:41:08.000000000 -0700
    2 +++ lib/ssl/c_src/Makefile.in   2008-04-13 20:38:18.000000000 -0700
    3 @@ -38,7 +38,7 @@
     1--- lib/ssl/c_src/Makefile.in.orig      2008-11-04 12:17:23.000000000 +0100
     2+++ lib/ssl/c_src/Makefile.in   2008-11-06 07:46:48.000000000 +0100
     3@@ -40,7 +40,7 @@
    44 CC = @CC@
    55 LD = @LD@
    66 SHELL = /bin/sh
     
    99 PLAIN_CFLAGS = @CFLAGS@
    1010 
    1111 # ----------------------------------------------------
    12 @@ -124,7 +124,7 @@
     12@@ -126,7 +126,7 @@
    1313 CC_R_OPT = $(CC_R_FLAG)$(SSL_LIBDIR)
    1414 endif
    1515 
  • files/patch-decode_fun.c.diff

     
     1--- lib/erl_interface/src/decode/decode_fun.c.orig      2008-11-06 06:53:46.000000000 +0100
     2+++ lib/erl_interface/src/decode/decode_fun.c   2008-11-06 06:54:09.000000000 +0100
     3@@ -103,7 +103,7 @@
     4                memcpy(p->free_vars, s, n);
     5            }
     6        }
     7-       *index += s-s0;
     8+       *index += n + s-s0;
     9         return 0;
     10        break;
     11     default:
  • files/patch-erts_emulator_sys_unix_ddll.c

     
    1 --- erts/emulator/sys/unix/erl_unix_sys_ddll.c  2007-11-26 20:01:23.000000000 +0100
    2 +++ erts/emulator/sys/unix/erl_unix_sys_ddll.c  2008-09-07 10:13:54.000000000 +0200
    3 @@ -127,6 +127,7 @@
    4             } else {
    5                 ret = ERL_DE_ERROR_UNSPECIFIED;
    6             }
    7 +               NSDestroyObjectFileImage(ofile);
    8             break;
    9         /* XXX:PaN should anything return something else ? */
    10         /*case NSObjectFileImageInappropriateFile:
    11 @@ -240,7 +241,15 @@
    12  int erts_sys_ddll_close(void *handle)
    13  {
    14  #if defined(HAVE_MACH_O_DYLD_H)
    15 -    return ERL_DE_NO_ERROR; /* XXX:PaN No close functionality in MacOSX??? */
    16 +    {
    17 +       int ret;
    18 +       if (NSUnLinkModule((NSModule) handle, NSUNLINKMODULE_OPTION_NONE)) {
    19 +           ret = ERL_DE_NO_ERROR;
    20 +       } else {
    21 +           ret = ERL_DE_ERROR_UNSPECIFIED;
    22 +       }
    23 +       return ret;
    24 +    }
    25  #elif defined(HAVE_DLOPEN)
    26      {
    27         int ret;
  • files/patch-lib_ssl_c_src_esock_openssl.c

     
    1 --- lib/ssl/c_src/esock_openssl.c.orig  2008-03-12 22:15:41.000000000 -0700
    2 +++ lib/ssl/c_src/esock_openssl.c       2008-03-12 22:16:01.000000000 -0700
    3 @@ -905,8 +905,8 @@
     1--- lib/ssl/c_src/esock_openssl.c.orig  2008-11-04 12:17:23.000000000 +0100
     2+++ lib/ssl/c_src/esock_openssl.c       2008-11-06 07:46:48.000000000 +0100
     3@@ -907,8 +907,8 @@
    44     }
    55 
    66     /* info callback */
  • files/patch-eunit_xml.diff

     
     1Index: lib/eunit/src/eunit_xml.erl
     2===================================================================
     3--- lib/eunit/src/eunit_xml.erl (revision 0)
     4+++ lib/eunit/src/eunit_xml.erl (revision 0)
     5@@ -0,0 +1,496 @@
     6+%% This library is free software; you can redistribute it and/or modify
     7+%% it under the terms of the GNU Lesser General Public License as
     8+%% published by the Free Software Foundation; either version 2 of the
     9+%% License, or (at your option) any later version.
     10+%%
     11+%% This library is distributed in the hope that it will be useful, but
     12+%% WITHOUT ANY WARRANTY; without even the implied warranty of
     13+%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     14+%% Lesser General Public License for more details.
     15+%%
     16+%% You should have received a copy of the GNU Lesser General Public
     17+%% License along with this library; if not, write to the Free Software
     18+%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
     19+%% USA
     20+%%
     21+%% $Id$
     22+%%
     23+%% @author Paul Guyot <paulguyot@ieee.org>
     24+%% @copyright 2008 Paul Guyot
     25+%% @private
     26+%% @see eunit
     27+%% @doc XML reports for EUnit
     28+
     29+-module(eunit_xml).
     30+
     31+-include("eunit.hrl").
     32+-include("eunit_internal.hrl").
     33+
     34+-export([start/3]).
     35+
     36+%% ============================================================================
     37+%% MACROS
     38+%% ============================================================================
     39+-define(INDENT, <<"  ">>).
     40+-define(NEWLINE, <<"\n">>).
     41+
     42+%% ============================================================================
     43+%% TYPES
     44+%% ============================================================================
     45+-type(chars() :: [char() | any()]). % chars()
     46+-type(item_name() :: {
     47+    Module :: atom(),
     48+    Function :: atom(),
     49+    Line :: integer() } | {
     50+    Module :: atom(),
     51+    Function :: atom() }).
     52+-type(tree_entry() :: {
     53+    Kind :: group | item,
     54+    Id :: [integer()],
     55+    Description :: string(),
     56+    item_name() | [any()]}). % tree_entry()
     57+
     58+%% ============================================================================
     59+%% RECORDS
     60+%% ============================================================================
     61+-record(testcase,
     62+    {
     63+    name :: chars(),
     64+    description :: chars(),
     65+    result :: ok | {failed, tuple()} | {aborted, tuple()} | {skipped, tuple()},
     66+    time :: integer(),
     67+    output :: chars()
     68+    }).
     69+-record(testsuite,
     70+    {
     71+    name = [] :: chars(),
     72+    time = 0 :: integer(),
     73+    output = [] :: chars(),
     74+    succeeded = 0 :: integer(),
     75+    failed = 0 :: integer(),
     76+    aborted = 0 :: integer(),
     77+    skipped = 0 :: integer(),
     78+    testcases = [] :: [#testcase{}]
     79+    }).
     80+
     81+-spec(start/3::([any()], [any()], string())->pid()).
     82+start(List, Options, XmlDir) ->
     83+    spawn(fun() -> init(List, Options, XmlDir) end).
     84+
     85+init(List, _Options, XmlDir) ->
     86+    TestSuites = dict:new(),
     87+    loop(TestSuites, List, XmlDir).
     88+
     89+loop(TestSuites, List, XmlDir) ->
     90+    receive
     91+        {status, Id, Status} ->
     92+            NewTestSuites = process_status(TestSuites, List, Id, Status),
     93+            loop(NewTestSuites, List, XmlDir);
     94+        {start, _Reference} ->
     95+            loop(TestSuites, List, XmlDir);
     96+        {stop, _Reference, _Pid} ->
     97+            write_reports(TestSuites, XmlDir);
     98+        Unknown ->
     99+            io:format("Unknown message: ~p~n", [Unknown]),
     100+            loop(TestSuites, List, XmlDir)
     101+    end.
     102+
     103+%% ----------------------------------------------------------------------------
     104+%% Process a status message.
     105+%% ----------------------------------------------------------------------------
     106+process_status(TestSuites, _List, _Id, {progress, 'begin', _Result}) ->
     107+    TestSuites;
     108+process_status(TestSuites, _List, [], {progress, 'end', _Result}) ->
     109+    TestSuites;
     110+process_status(TestSuites, List, [GroupId] = Id, {progress, 'end', {Count, Time, Output}}) when is_integer(Count) ->
     111+    TestSuite = case dict:find(GroupId, TestSuites) of
     112+        {ok, Value} -> Value;
     113+        error -> #testsuite{}
     114+    end,
     115+    Name = case entry(List, Id) of
     116+        {value, {group, Id, Description, _Items}} ->
     117+            Description;
     118+        _ -> ["Unknown-", integer_to_list(GroupId)]
     119+    end,
     120+    NewTestSuite = TestSuite#testsuite{
     121+        name = Name,
     122+        time = Time,
     123+        output = Output},
     124+    dict:store(GroupId, NewTestSuite, TestSuites);
     125+process_status(TestSuites, _List, _Id, {progress, 'end', {Count, _Time, _Output}}) when is_integer(Count)->
     126+    TestSuites;
     127+process_status(TestSuites, List, [GroupId | _Tail] = Id, {progress, 'end', {ok, Time, Output}}) ->
     128+    case entry(List, Id) of
     129+        {value, {item, Id, Description, NameTuple}} ->
     130+            TestSuite = case dict:find(GroupId, TestSuites) of
     131+                {ok, Value} -> Value;
     132+                error -> #testsuite{}
     133+            end,
     134+            Name = format_name(NameTuple),
     135+            TestCase = #testcase{
     136+                    name = Name,
     137+                    description = Description,
     138+                    result = ok,
     139+                    time = Time,
     140+                    output = Output},
     141+            NewTestSuite = TestSuite#testsuite{
     142+                succeeded = TestSuite#testsuite.succeeded + 1,
     143+                testcases = [TestCase | TestSuite#testsuite.testcases]},
     144+            dict:store(GroupId, NewTestSuite, TestSuites);
     145+        _ -> TestSuites
     146+    end;
     147+process_status(
     148+        TestSuites, List, [GroupId | _Tail] = Id,
     149+        {progress, 'end', {{error, {error, {AssertionException, _Details}, _Trace} = Exception}, Time, Output}})
     150+            when
     151+                AssertionException == assertion_failed;
     152+                AssertionException == assertMatch_failed;
     153+                AssertionException == assertEqual_failed;
     154+                AssertionException == assertException_failed;
     155+                AssertionException == assertCmd_failed;
     156+                AssertionException == assertCmdOutput_failed ->
     157+    case entry(List, Id) of
     158+        {value, {item, Id, Description, NameTuple}} ->
     159+            TestSuite = case dict:find(GroupId, TestSuites) of
     160+                {ok, Value} -> Value;
     161+                error -> #testsuite{}
     162+            end,
     163+            Name = format_name(NameTuple),
     164+            TestCase = #testcase{
     165+                    name = Name,
     166+                    description = Description,
     167+                    result = {failed, Exception},
     168+                    time = Time,
     169+                    output = Output},
     170+            NewTestSuite = TestSuite#testsuite{
     171+                failed = TestSuite#testsuite.failed + 1,
     172+                testcases = [TestCase | TestSuite#testsuite.testcases]},
     173+            dict:store(GroupId, NewTestSuite, TestSuites);
     174+        _ -> TestSuites
     175+    end;
     176+process_status(TestSuites, List, [GroupId | _Tail] = Id, {progress, 'end', {{error, Exception}, Time, Output}}) ->
     177+    case entry(List, Id) of
     178+        {value, {item, Id, Description, NameTuple}} ->
     179+            TestSuite = case dict:find(GroupId, TestSuites) of
     180+                {ok, Value} -> Value;
     181+                error -> #testsuite{}
     182+            end,
     183+            Name = format_name(NameTuple),
     184+            TestCase = #testcase{
     185+                    name = Name,
     186+                    description = Description,
     187+                    result = {aborted, Exception},
     188+                    time = Time,
     189+                    output = Output},
     190+            NewTestSuite = TestSuite#testsuite{
     191+                aborted = TestSuite#testsuite.aborted + 1,
     192+                testcases = [TestCase | TestSuite#testsuite.testcases]},
     193+            dict:store(GroupId, NewTestSuite, TestSuites);
     194+        _ -> TestSuites
     195+    end;
     196+process_status(TestSuites, _List, _Id, {cancel, undefined}) -> TestSuites;
     197+process_status(TestSuites, List, [GroupId, _Tail] = Id, {cancel, Reason}) ->
     198+    TestSuite = case dict:find(GroupId, TestSuites) of
     199+        {ok, Value} -> Value;
     200+        error -> #testsuite{}
     201+    end,
     202+    dict:store(GroupId, process_cancel(TestSuite, List, Id, Reason), TestSuites);
     203+process_status(TestSuites, _List, _Id, Status) ->
     204+    io:format("Unknown status = ~p~n", [Status]),
     205+    TestSuites.
     206+
     207+%% ----------------------------------------------------------------------------
     208+%% Process a cancel status.
     209+%% ----------------------------------------------------------------------------
     210+process_cancel(TestSuite, List, Id, Reason) ->
     211+    case entry(List, Id) of
     212+        {value, {item, Id, _Description, _NameTuple} = Item} ->
     213+            process_cancel_items(TestSuite, [Item], [], Reason);
     214+        {value, {group, Id, _Description, Items}} ->
     215+            process_cancel_items(TestSuite, Items, [], Reason);
     216+        _ -> TestSuite
     217+    end.
     218+
     219+%% ----------------------------------------------------------------------------
     220+%% Process the tests that were skipped because of an error.
     221+%%
     222+-spec(process_cancel_items/4 :: (#testsuite{}, Items :: [tree_entry()], Acc :: [[tree_entry()]], Reason :: tuple()) -> #testsuite{}).
     223+%% ----------------------------------------------------------------------------
     224+process_cancel_items(TestSuite, [], [], _Reason) -> TestSuite;
     225+process_cancel_items(TestSuite, [], [Acc | Tail], Reason) ->
     226+    process_cancel_items(TestSuite, Acc, Tail, Reason);
     227+process_cancel_items(TestSuite, [{item, _Id, Description, NameTuple} | Tail], Acc, Reason) ->
     228+    Name = format_name(NameTuple),
     229+    TestCase = #testcase{
     230+        name = Name,
     231+        description = Description,
     232+        result = {skipped, Reason},
     233+        time = 0,
     234+        output = []},
     235+    NewTestSuite = TestSuite#testsuite{
     236+        skipped = TestSuite#testsuite.skipped + 1,
     237+        testcases = [TestCase | TestSuite#testsuite.testcases]},
     238+    process_cancel_items(NewTestSuite, Tail, Acc, Reason);
     239+process_cancel_items(TestSuite, [{group, _Id, _Description, Items} | Tail], Acc, Reason) ->
     240+    process_cancel_items(TestSuite, Items, [Tail | Acc], Reason).
     241+
     242+%% ----------------------------------------------------------------------------
     243+%% Convert a test description into a test case name.
     244+%% If the test description is a module function, use the function's name.
     245+%% If the test description is a module function plus a line, use function.line.
     246+%% ----------------------------------------------------------------------------
     247+format_name({_Module, Function}) -> atom_to_list(Function);
     248+format_name({_Module, Function, Line}) -> [atom_to_list(Function), $., integer_to_list(Line)].
     249+
     250+%% ----------------------------------------------------------------------------
     251+%% Write the reports to the XML directory.
     252+%% ----------------------------------------------------------------------------
     253+write_reports(TestSuites, XmlDir) ->
     254+    dict:fold(fun(_GroupId, TestSuite, Acc) -> write_report(TestSuite, XmlDir), Acc end, [], TestSuites).
     255+
     256+%% ----------------------------------------------------------------------------
     257+%% Write a report to the XML directory.
     258+%% This function opens the report file, calls write_report_to/2 and closes the file.
     259+%% ----------------------------------------------------------------------------
     260+write_report(#testsuite{name = Name} = TestSuite, XmlDir) ->
     261+    Filename = filename:join(XmlDir, lists:flatten(["TEST-", escape_suitename(Name)], ".xml")),
     262+    case file:open(Filename, [write, raw]) of
     263+        {ok, FileDescriptor} ->
     264+            try
     265+                write_report_to(TestSuite, FileDescriptor)
     266+            after
     267+                file:close(FileDescriptor)
     268+            end;
     269+        {error, _Reason} = Error -> throw(Error)
     270+    end.
     271+
     272+%% ----------------------------------------------------------------------------
     273+%% Actually write a report.
     274+%% ----------------------------------------------------------------------------
     275+write_report_to(TestSuite, FileDescriptor) ->
     276+    write_header(FileDescriptor),
     277+    write_start_tag(TestSuite, FileDescriptor),
     278+    write_testcases(TestSuite#testsuite.testcases, FileDescriptor),
     279+    write_end_tag(FileDescriptor).
     280+
     281+%% ----------------------------------------------------------------------------
     282+%% Write the XML header.
     283+%% ----------------------------------------------------------------------------
     284+write_header(FileDescriptor) ->
     285+    file:write(FileDescriptor, [<<"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>">>, ?NEWLINE]).
     286+
     287+%% ----------------------------------------------------------------------------
     288+%% Write the testsuite start tag, with attributes describing the statistics
     289+%% of the test suite.
     290+%% ----------------------------------------------------------------------------
     291+write_start_tag(
     292+        #testsuite{
     293+            name = Name,
     294+            time = Time,
     295+            succeeded = Succeeded,
     296+            failed = Failed,
     297+            skipped = Skipped,
     298+            aborted = Aborted},
     299+        FileDescriptor) ->
     300+    Total = Succeeded + Failed + Skipped + Aborted,
     301+    StartTag = [
     302+        <<"<testsuite tests=\"">>, integer_to_list(Total),
     303+        <<"\" failures=\"">>, integer_to_list(Failed),
     304+        <<"\" errors=\"">>, integer_to_list(Aborted),
     305+        <<"\" skipped=\"">>, integer_to_list(Skipped),
     306+        <<"\" time=\"">>, format_time(Time),
     307+        <<"\" name=\"">>, escape_attr(Name),
     308+        <<"\">">>, ?NEWLINE],       
     309+    file:write(FileDescriptor, StartTag).
     310+
     311+%% ----------------------------------------------------------------------------
     312+%% Recursive function to write the test cases.
     313+%% ----------------------------------------------------------------------------
     314+write_testcases([], _FileDescriptor) -> void;
     315+write_testcases([TestCase| Tail], FileDescriptor) ->
     316+    write_testcase(TestCase, FileDescriptor),
     317+    write_testcases(Tail, FileDescriptor).
     318+
     319+%% ----------------------------------------------------------------------------
     320+%% Write the testsuite end tag.
     321+%% ----------------------------------------------------------------------------
     322+write_end_tag(FileDescriptor) ->
     323+    file:write(FileDescriptor, [<<"</testsuite>">>, ?NEWLINE]).
     324+
     325+%% ----------------------------------------------------------------------------
     326+%% Write a test case, as a testcase tag.
     327+%% If the test case was successful and if there was no output, we write an empty
     328+%% tag.
     329+%% ----------------------------------------------------------------------------
     330+write_testcase(
     331+        #testcase{
     332+            name = Name,
     333+            description = Description,
     334+            result = Result,
     335+            time = Time,
     336+            output = Output},
     337+        FileDescriptor) ->
     338+    DescriptionAttr = case Description of
     339+        [] -> [];
     340+        _ -> [<<" description=\"">>, escape_attr(Description), <<"\"">>]
     341+    end,
     342+    StartTag = [
     343+        ?INDENT, <<"<testcase time=\"">>, format_time(Time),
     344+        <<"\" name=\"">>, escape_attr(Name), <<"\"">>,
     345+        DescriptionAttr],
     346+    ContentAndEndTag = case {Result, Output} of
     347+        {ok, []} -> [<<"/>">>, ?NEWLINE];
     348+        _ -> [<<">">>, ?NEWLINE, format_testcase_result(Result), format_testcase_output(Output), ?INDENT, <<"</testcase>">>, ?NEWLINE]
     349+    end,
     350+    file:write(FileDescriptor, [StartTag, ContentAndEndTag]).
     351+
     352+%% ----------------------------------------------------------------------------
     353+%% Format the result of the test.
     354+%% Failed tests are represented with a failure tag.
     355+%% Aborted tests are represented with an error tag.
     356+%% Skipped tests are represented with a skipped tag.
     357+%% ----------------------------------------------------------------------------
     358+format_testcase_result(ok) -> [];
     359+format_testcase_result({failed, {error, {Type, _}, _} = Exception}) when is_atom(Type) ->
     360+    [?INDENT, ?INDENT, <<"<failure type=\"">>, escape_attr(atom_to_list(Type)), <<"\">">>, ?NEWLINE,
     361+    <<"::">>, escape_text(eunit_lib:format_exception(Exception)),
     362+    ?INDENT, ?INDENT, <<"</failure>">>, ?NEWLINE];
     363+format_testcase_result({failed, Term}) ->
     364+    [?INDENT, ?INDENT, <<"<failure type=\"unknown\">">>, ?NEWLINE,
     365+    escape_text(io_lib:write(Term)),
     366+    ?INDENT, ?INDENT, <<"</failure>">>, ?NEWLINE];
     367+format_testcase_result({aborted, {Class, _Term, _Trace} = Exception}) when is_atom(Class) ->
     368+    [?INDENT, ?INDENT, <<"<error type=\"">>, escape_attr(atom_to_list(Class)), <<"\">">>, ?NEWLINE,
     369+    <<"::">>, escape_text(eunit_lib:format_exception(Exception)),
     370+    ?INDENT, ?INDENT, <<"</error>">>, ?NEWLINE];
     371+format_testcase_result({aborted, Term}) ->
     372+    [?INDENT, ?INDENT, <<"<error type=\"unknown\">">>, ?NEWLINE,
     373+    escape_text(io_lib:write(Term)),
     374+    ?INDENT, ?INDENT, <<"</error>">>, ?NEWLINE];
     375+format_testcase_result({skipped, {abort, Error}}) when is_tuple(Error) ->
     376+    [?INDENT, ?INDENT, <<"<skipped type=\"">>, escape_attr(atom_to_list(element(1, Error))), <<"\">">>, ?NEWLINE,
     377+    escape_text(eunit_lib:format_error(Error)),
     378+    ?INDENT, ?INDENT, <<"</skipped>">>, ?NEWLINE];
     379+format_testcase_result({skipped, {Type, Term}}) when is_atom(Type) ->
     380+    [?INDENT, ?INDENT, <<"<skipped type=\"">>, escape_attr(atom_to_list(Type)), <<"\">">>, ?NEWLINE,
     381+    escape_text(io_lib:write(Term)),
     382+    ?INDENT, ?INDENT, <<"</skipped>">>, ?NEWLINE];
     383+format_testcase_result({skipped, Term}) ->
     384+    [?INDENT, ?INDENT, <<"<skipped type=\"unknown\">">>, ?NEWLINE,
     385+    escape_text(io_lib:write(Term)),
     386+    ?INDENT, ?INDENT, <<"</skipped>">>, ?NEWLINE].
     387+
     388+%% ----------------------------------------------------------------------------
     389+%% Format the output of a test case in xml.
     390+%% Empty output is simply the empty string.
     391+%% Other output is inside a <system-out> xml tag.
     392+%% ----------------------------------------------------------------------------
     393+format_testcase_output([]) -> [];
     394+format_testcase_output(Output) ->
     395+    [?INDENT, ?INDENT, <<"<system-out>">>, escape_text(Output), ?NEWLINE, ?INDENT, ?INDENT, <<"</system-out>">>, ?NEWLINE].
     396+
     397+%% ----------------------------------------------------------------------------
     398+%% Return the time in the SECS.MILLISECS format.
     399+%% ----------------------------------------------------------------------------
     400+format_time(Time) ->
     401+    format_time_s(lists:reverse(integer_to_list(Time))).
     402+format_time_s([Digit]) -> ["0.00", Digit];
     403+format_time_s([Digit1, Digit2]) -> ["0.0", Digit2, Digit1];
     404+format_time_s([Digit1, Digit2, Digit3]) -> ["0.", Digit3, Digit2, Digit1];
     405+format_time_s([Digit1, Digit2, Digit3 | Tail]) -> [lists:reverse(Tail), $., Digit3, Digit2, Digit1].
     406+
     407+%% ----------------------------------------------------------------------------
     408+%% Escape a suite's name to generate the filename.
     409+%% Remark: we might overwrite another testsuite's file.
     410+%% ----------------------------------------------------------------------------
     411+escape_suitename([Head | _T] = List) when is_list(Head) ->
     412+    escape_suitename(lists:flatten(List));
     413+escape_suitename("module '" ++ String) ->
     414+    escape_suitename(String);
     415+escape_suitename(String) ->
     416+    escape_suitename(String, []).
     417+
     418+escape_suitename([], Acc) -> lists:reverse(Acc);
     419+escape_suitename([$  | Tail], Acc) -> escape_suitename(Tail, [$_ | Acc]);
     420+escape_suitename([$' | Tail], Acc) -> escape_suitename(Tail, Acc);
     421+escape_suitename([$/ | Tail], Acc) -> escape_suitename(Tail, [$: | Acc]);
     422+escape_suitename([$\\ | Tail], Acc) -> escape_suitename(Tail, [$: | Acc]);
     423+escape_suitename([Char | Tail], Acc) when Char < $! -> escape_suitename(Tail, Acc);
     424+escape_suitename([Char | Tail], Acc) when Char > $~ -> escape_suitename(Tail, Acc);
     425+escape_suitename([Char | Tail], Acc) -> escape_suitename(Tail, [Char | Acc]).
     426+
     427+%% ----------------------------------------------------------------------------
     428+%% Escape text for XML text nodes.
     429+%% Replace < with &lt;, > with &gt; and & with &amp;
     430+%% ----------------------------------------------------------------------------
     431+escape_text(Text) -> escape_xml(lists:flatten(Text), [], false).
     432+
     433+%% ----------------------------------------------------------------------------
     434+%% Escape text for XML attribute nodes.
     435+%% Replace < with &lt;, > with &gt; and & with &amp;
     436+%% ----------------------------------------------------------------------------
     437+escape_attr(Text) -> escape_xml(lists:flatten(Text), [], true).
     438+
     439+escape_xml([], Acc, _ForAttr) -> lists:reverse(Acc);
     440+escape_xml([$< | Tail], Acc, ForAttr) -> escape_xml(Tail, [$;, $t, $l, $& | Acc], ForAttr);
     441+escape_xml([$> | Tail], Acc, ForAttr) -> escape_xml(Tail, [$;, $t, $g, $& | Acc], ForAttr);
     442+escape_xml([$& | Tail], Acc, ForAttr) -> escape_xml(Tail, [$;, $p, $m, $a, $& | Acc], ForAttr);
     443+escape_xml([$" | Tail], Acc, true) -> escape_xml(Tail, [$;, $t, $o, $u, $q, $& | Acc], true);
     444+escape_xml([Char | Tail], Acc, ForAttr) when is_integer(Char) -> escape_xml(Tail, [Char | Acc], ForAttr).
     445+
     446+%% ----------------------------------------------------------------------------
     447+%% Determine if the second list begins with the first list.
     448+%% Return true if it does, false if it doesn't.
     449+%% ----------------------------------------------------------------------------
     450+begins_with([], _L2) -> true;
     451+begins_with([H|T1], [H|T2]) -> begins_with(T1, T2);
     452+begins_with(_, _) -> false.
     453+
     454+%% ----------------------------------------------------------------------------
     455+%% Return the entry in the tree for a given ID.
     456+%% Return {value, Entry} if the entry was found or
     457+%% not_found if it wasn't.
     458+-spec(entry/2 :: (List :: [tree_entry()], Id :: [integer()]) -> {value, tree_entry()} | not_found).
     459+%% ----------------------------------------------------------------------------
     460+entry([{_Kind, Id, _Description, _Data} = Entry | _Tail], Id) -> {value, Entry};
     461+entry([{group, [H|_] = Id, _Description, Subnodes} | Tail], [H|_] = NodeId) ->
     462+    case begins_with(Id, NodeId) of
     463+        true -> entry(Subnodes, NodeId);
     464+        false -> entry(Tail, NodeId)
     465+    end;
     466+entry([_Node | Tail], NodeId) -> entry(Tail, NodeId);
     467+entry([], _NodeId) -> not_found.
     468+
     469+-ifdef(TEST).
     470+
     471+format_time_test_() ->
     472+    [
     473+    ?_assertEqual("0.000", lists:flatten(format_time(0))),
     474+    ?_assertEqual("0.001", lists:flatten(format_time(1))),
     475+    ?_assertEqual("0.042", lists:flatten(format_time(42))),
     476+    ?_assertEqual("0.123", lists:flatten(format_time(123))),
     477+    ?_assertEqual("1.000", lists:flatten(format_time(1000))),
     478+    ?_assertEqual("1.001", lists:flatten(format_time(1001))),
     479+    ?_assertEqual("1.042", lists:flatten(format_time(1042))),
     480+    ?_assertEqual("20.042", lists:flatten(format_time(20042)))
     481+    ].
     482+
     483+escape_suitename_test_() ->
     484+    [
     485+    ?_assertEqual("sqlite_test", escape_suitename("module 'sqlite_test'")),
     486+    ?_assertEqual("Unknown-2", escape_suitename(["Unknown-", "2"]))
     487+    ].
     488+
     489+escape_test_() ->
     490+    [
     491+    ?_assertEqual("bla bla bla", escape_text("bla bla bla")),
     492+    ?_assertEqual("1 &lt; 2 -&gt; true", escape_text("1 < 2 -> true")),
     493+    ?_assertEqual("1 &amp; 2 -&gt; 0", escape_text("1 & 2 -> 0")),
     494+    ?_assertEqual("and then it said \"Hello, Dave!\"", escape_text("and then it said \"Hello, Dave!\"")),
     495+    ?_assertEqual("bla bla bla", escape_attr("bla bla bla")),
     496+    ?_assertEqual("1 &lt; 2 -&gt; true", escape_attr("1 < 2 -> true")),
     497+    ?_assertEqual("1 &amp; 2 -&gt; 0", escape_attr("1 & 2 -> 0")),
     498+    ?_assertEqual("and then it said &quot;Hello, Dave!&quot;", escape_attr("and then it said \"Hello, Dave!\""))
     499+    ].
     500+
     501+-endif.  % TEST
     502Index: lib/eunit/src/eunit.erl
     503===================================================================
     504--- lib/eunit/src/eunit.erl.orig        2008-11-04 11:52:12.000000000 +0100
     505+++ lib/eunit/src/eunit.erl     2008-11-06 07:24:28.000000000 +0100
     506@@ -148,7 +148,7 @@
     507     try eunit_data:list(Tests) of
     508        List ->
     509            Listeners = [eunit_tty:start(List, Options)
     510-                        | listeners(Options)],
     511+                        | listeners(List, Options)],
     512            Serial = eunit_serial:start(Listeners),
     513            case eunit_server:start_test(Server, Serial, Tests, Options) of
     514                {ok, Reference} -> test_run(Reference, Listeners);
     515@@ -197,10 +197,12 @@
     516     Dummy = spawn(fun devnull/0),
     517     eunit_server:start_test(Server, Dummy, T, Options).
     518 
     519-listeners(Options) ->
     520+listeners(List, Options) ->
     521     case proplists:get_value(event_log, Options) of
     522        undefined ->
     523            [];
     524+       {xml, XmlDirectory} ->
     525+           [eunit_xml:start(List, Options, XmlDirectory)];
     526        LogFile ->
     527            [spawn(fun () -> event_logger(LogFile) end)]
     528     end.
     529Index: lib/eunit/src/Makefile
     530===================================================================
     531--- lib/eunit/src/Makefile.orig 2008-11-04 11:52:12.000000000 +0100
     532+++ lib/eunit/src/Makefile      2008-11-06 07:23:09.000000000 +0100
     533@@ -37,7 +37,8 @@
     534        eunit_test.erl \
     535        eunit_lib.erl \
     536        eunit_data.erl \
     537-       eunit_tty.erl
     538+       eunit_tty.erl \
     539+       eunit_xml.erl
     540 
     541 OBJECTS=$(SOURCES:%.erl=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET)
     542 
  • files/patch-decode_big.c.diff

     
     1--- lib/erl_interface/src/decode/decode_big.c.orig      2008-11-06 06:57:02.000000000 +0100
     2+++ lib/erl_interface/src/decode/decode_big.c   2008-11-06 06:58:39.000000000 +0100
     3@@ -51,7 +51,9 @@
     4       u = (unsigned char *) s;
     5       for (i = 0; i < b->arity; ++i) {
     6          dt[i] = u[i*2];
     7-         dt[i] |= ((unsigned short) u[(i*2)+1]) << 8;
     8+        if ((i*2 + 1) < digit_bytes) {
     9+          dt[i] |= ((unsigned short) u[(i*2)+1]) << 8;
     10+        }
     11       }
     12   } else {
     13       s++; /* skip sign byte */
  • Portfile

     
    22
    33PortSystem 1.0
    44name            erlang
    5 version         R12B-4
    6 revision    1
     5version         R12B-5
    76categories      lang erlang
    87maintainers     bfulgham@macports.org
    98platforms       darwin
     
    3231                otp_doc_man_${version}${extract.suffix}         \
    3332                otp_doc_html_${version}${extract.suffix}
    3433
    35 checksums       otp_src_R12B-4.tar.gz \
    36                     md5     ae81edda4a17506af7a9d73abca033b2 \
    37                     sha1    4e42454c3f560ce6efd3c917a79a5b288664e329 \
    38                     rmd160  3c57ae04388c0493d97c76529c57c50de639bdce \
    39                 otp_doc_man_R12B-4.tar.gz \
    40                     md5     ef8f96d1721a2345cc87b208cde3de06 \
    41                     sha1    b954711b493e384606ce23d32a6d980017637b10 \
    42                     rmd160  f14eb1f542ebecceddd6ac70aa4ed325f91b0b24 \
    43                 otp_doc_html_R12B-4.tar.gz \
    44                     md5     f633cd418d8260af7a11c998aa88072b \
    45                     sha1    cbe6bc52a5000b21de5cac5f9b2672b935e94ed7 \
    46                     rmd160  bf05981ddf2e97910141739980cee09572b1c34d
     34checksums       otp_src_R12B-5.tar.gz \
     35                    md5     250fc48242a098073474e563c3f23e76 \
     36                    sha1    681570df942cd53d2c18404b356dd5dc1ff016ef \
     37                    rmd160  7473d6119a55365ebe582c55c8b19c3f2870565a \
     38                otp_doc_man_R12B-5.tar.gz \
     39                    md5     6231cb172847040395cc34b20781aa3b \
     40                    sha1    ae7036bd2afc9d1fca97f0de2eca84f56656def8 \
     41                    rmd160  e28d555d0a86fc69e0ee091864828c8eaa58d2be \
     42                otp_doc_html_R12B-5.tar.gz \
     43                    md5     fb0c5454bbd865e881b6712295f6d41f \
     44                    sha1    0bd369d02051e01bac58c9b8665bd3538e116f51 \
     45                    rmd160  b460906043171b27735332ec90c45e38d888869a
    4746
    4847extract.only    otp_src_${version}${extract.suffix}
    4948
    5049pre-patch       { file rename ${workpath}/otp_src_${version} ${workpath}/${name}-${version} }
    5150
     51# http://www.erlang.org/pipermail/erlang-bugs/2008-October/001023.html
     52# http://www.erlang.org/pipermail/erlang-bugs/2008-October/001024.html
     53# http://support.process-one.net/browse/EUNIT-13
    5254patchfiles      patch-toolbar.erl \
    5355                patch-erts_emulator_Makefile.in \
    5456                patch-lib_ssl_c_src_esock_openssl.c \
    5557                patch-lib_ssl_c_src_Makefile.dist \
    5658                patch-lib_ssl_c_src_Makefile.in \
    57                 patch-erts_emulator_sys_unix_ddll.c
     59                patch-decode_big.c.diff \
     60                patch-decode_fun.c.diff \
     61                patch-eunit_xml.diff
    5862
    5963configure.args  --prefix=${destroot}${prefix}   \
    6064                --enable-kernel-poll            \
     
    9498        system "tar -C ${destroot}${prefix}/lib/erlang -zxvf ${distpath}/otp_doc_html_${version}${extract.suffix}"
    9599        system "tar -C ${destroot}${prefix}/lib/erlang -zxvf ${distpath}/otp_doc_man_${version}${extract.suffix}"
    96100 
    97         set erts_dir   erts-5.6.4
     101        set erts_dir   erts-5.6.5
    98102
    99103        reinplace s|${destroot}|| ${destroot}${prefix}/lib/erlang/bin/erl
    100104        reinplace s|${destroot}|| ${destroot}${prefix}/lib/erlang/bin/start
     
    106110
    107111        file delete -force ${destroot}${prefix}/lib/erlang/bin/epmd
    108112        system "ln -s ../${erts_dir}/bin/epmd ${destroot}${prefix}/lib/erlang/bin/epmd"
     113
     114    # Fix eunit.
     115    # See http://www.erlang.org/pipermail/erlang-questions/2008-November/039625.html
     116    file mkdir ${destroot}${prefix}/lib/erlang/lib/eunit-2.0/include/
     117        file copy ${worksrcpath}/lib/eunit/include/eunit.hrl ${destroot}${prefix}/lib/erlang/lib/eunit-2.0/include/
    109118}