diff options
54 files changed, 1273 insertions, 395 deletions
diff --git a/.gitignore b/.gitignore index cbf7881ae7..234d21c7df 100644 --- a/.gitignore +++ b/.gitignore @@ -94,8 +94,6 @@ lib/os_mon/priv/obj/win32/ lib/runtime_tools/c_src/win32/ lib/runtime_tools/priv/lib/ lib/runtime_tools/priv/obj/ -lib/runtime_tools/doc/src/DTRACE.xml -lib/runtime_tools/doc/src/SYSTEMTAP.xml lib/tools/bin/win32/ lib/tools/c_src/win32/ lib/tools/obj/win32/ @@ -178,7 +176,7 @@ JAVADOC-GENERATED /lib/*/doc/man[0-9]/*.[0-9] /lib/*/doc/pdf/*.fo /lib/*/doc/pdf/*.pdf - +/lib/*/doc/xml/*.xml /lib/configure /lib/config.log @@ -206,6 +204,7 @@ JAVADOC-GENERATED /lib/erl_interface/src/auxdir/config.guess /lib/erl_interface/src/auxdir/config.sub /lib/erl_interface/src/auxdir/install-sh +/lib/erl_interface/config.h.in /lib/megaco/aclocal.m4 /lib/odbc/aclocal.m4 /lib/common_test/test_server/config.guess @@ -232,15 +231,12 @@ JAVADOC-GENERATED # asn1 -/lib/asn1/doc/src/asn1_spec.xml /lib/asn1/test/asn1_SUITE.erl /lib/asn1/test/asn1_bin_SUITE.erl /lib/asn1/test/asn1_bin_v2_SUITE.erl # common_test -/lib/common_test/doc/src/ct_property_test.xml -/lib/common_test/doc/src/ct_slave.xml /lib/common_test/priv/install.sh # compiler @@ -274,15 +270,13 @@ JAVADOC-GENERATED /erts/doc/html/*.eix /erts/doc/pdf/*.fo /erts/doc/pdf/*.pdf +/erts/doc/xml/*.xml /erts/doc/man[0-9]/*.[0-9] /erts/doc/CONF_INFO # et /lib/et/doc/html/*.png -/lib/et/doc/src/et_desc.xml -/lib/et/doc/src/et_examples.xml -/lib/et/doc/src/et_tutorial.xml # gs @@ -366,27 +360,15 @@ JAVADOC-GENERATED /lib/snmp/priv/mibs/[A-Z]*.bin /lib/snmp/test/snmp_test_data/[A-Z]*.bin /lib/snmp/test/snmp_test_data/[A-Z]*.hrl +/lib/snmp/doc/intex.html # system /system/doc/pdf /system/doc/html +/system/doc/xml /system/doc/top/PR.template /system/doc/top/erlresolvelinks.js -/system/doc/programming_examples/funs.xml -/system/doc/system_principles/create_target.xml -/system/doc/tutorial/c_port.xml -/system/doc/tutorial/c_portdriver.xml -/system/doc/tutorial/cnode.xml -/system/doc/tutorial/erl_interface.xml -/system/doc/tutorial/example.xml -/system/doc/tutorial/nif.xml -/system/doc/html/installation_guide -/system/doc/installation_guide/INSTALL.xml -/system/doc/installation_guide/INSTALL-CROSS.xml -/system/doc/installation_guide/INSTALL-WIN32.xml -/system/doc/installation_guide/OTP-PATCH-APPLY.xml -/system/doc/installation_guide/MARKDOWN.xml # test_server @@ -406,7 +388,7 @@ JAVADOC-GENERATED /lib/wx/api_gen/*_generated /lib/wx/wx-*.ez /lib/wx/CONF_INFO -/lib/wx/doc/src/wx*.xml +/lib/wx/doc/src/ref_man.xml /lib/wx/priv/wxe_driver.* /lib/wx/priv/erl_gl.* @@ -416,4 +398,3 @@ JAVADOC-GENERATED /lib/xmerl/src/xmerl_b64Bin.erl /lib/xmerl/src/xmerl_xpath_parse.erl /lib/xmerl/test/xmerl_test.erl -/lib/erl_interface/config.h.in diff --git a/erts/doc/src/Makefile b/erts/doc/src/Makefile index c4f1baf89e..5fa8b0673a 100644 --- a/erts/doc/src/Makefile +++ b/erts/doc/src/Makefile @@ -155,7 +155,7 @@ clean: rm -f errs core *~ $(SPECDIR)/specs_%.xml: - escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ + $(gen_verbose)escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ -o$(dir $@) -module $(patsubst $(SPECDIR)/specs_%.xml,%,$@) # ---------------------------------------------------- diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index c086928bb3..d4d4dd7f31 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -53,14 +53,14 @@ <datatypes> <datatype> - <name>ext_binary()</name> + <name name="ext_binary"/> <desc> <p>A binary data object, structured according to the Erlang external term format.</p> </desc> </datatype> <datatype> - <name>iovec()</name> + <name name="iovec"/> <desc> <p>A list of binaries. This datatype is useful to use together with <seealso marker="erl_nif#enif_inspect_iovec"> @@ -204,10 +204,6 @@ <name name="abs" arity="1" clause_i="1"/> <name name="abs" arity="1" clause_i="2"/> <fsummary>Arithmetical absolute value.</fsummary> - <type> - <v>Float = float()</v> - <v>Int = integer()</v> - </type> <desc> <p>Returns an integer or float that is the arithmetical absolute value of <c><anno>Float</anno></c> or diff --git a/erts/emulator/beam/erl_proc_sig_queue.c b/erts/emulator/beam/erl_proc_sig_queue.c index 1ba0b789ec..b32ba1b2e6 100644 --- a/erts/emulator/beam/erl_proc_sig_queue.c +++ b/erts/emulator/beam/erl_proc_sig_queue.c @@ -723,7 +723,7 @@ erts_proc_sig_fetch(Process *proc) ERTS_HDBG_CHECK_SIGNAL_PRIV_QUEUE(proc); } -void do_seq_trace_output(Eterm to, Eterm token, Eterm msg); +static void do_seq_trace_output(Eterm to, Eterm token, Eterm msg); static void send_gen_exit_signal(Process *c_p, Eterm from_tag, @@ -869,7 +869,7 @@ send_gen_exit_signal(Process *c_p, Eterm from_tag, } } -void +static void do_seq_trace_output(Eterm to, Eterm token, Eterm msg) { /* @@ -887,15 +887,17 @@ do_seq_trace_output(Eterm to, Eterm token, Eterm msg) else rp = erts_proc_lookup_raw_inc_refc(to); - erts_proc_lock(rp, ERTS_PROC_LOCK_MSGQ); + if (rp) { + erts_proc_lock(rp, ERTS_PROC_LOCK_MSGQ); - if (!ERTS_PROC_IS_EXITING(rp)) - seq_trace_output(token, msg, SEQ_TRACE_SEND, to, rp); + if (!ERTS_PROC_IS_EXITING(rp)) + seq_trace_output(token, msg, SEQ_TRACE_SEND, to, rp); - erts_proc_unlock(rp, ERTS_PROC_LOCK_MSGQ); + erts_proc_unlock(rp, ERTS_PROC_LOCK_MSGQ); - if (!is_normal_sched) - erts_proc_dec_refc(rp); + if (!is_normal_sched) + erts_proc_dec_refc(rp); + } } void diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index be1306cd79..ba0a9fbc79 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -10785,7 +10785,6 @@ exit_permanent_prio_elevation(Process *c_p, erts_aint32_t state) while (1) { erts_aint32_t aprio, uprio, n, e; ASSERT(a & ERTS_PSFLG_EXITING); - ASSERT(!(a & ERTS_PSFLG_FREE)); aprio = ERTS_PSFLGS_GET_ACT_PRIO(a); uprio = ERTS_PSFLGS_GET_USR_PRIO(a); if (aprio >= uprio) diff --git a/erts/emulator/sys/common/erl_poll.c b/erts/emulator/sys/common/erl_poll.c index 7aa53e8f36..ced8a4a2a7 100644 --- a/erts/emulator/sys/common/erl_poll.c +++ b/erts/emulator/sys/common/erl_poll.c @@ -782,10 +782,14 @@ update_pollset(ErtsPollSet *ps, int fd, ErtsPollOp op, ErtsPollEvents events) struct kevent evts[2]; struct timespec ts = {0, 0}; -#ifdef EV_DISPATCH - /* If we have EV_DISPATCH we use it. The kevent descriptions for both - read and write are added on OP_ADD and removed on OP_DEL. And then - after than only EV_ENABLE|EV_DISPATCH are used. +#if defined(EV_DISPATCH) && !defined(__OpenBSD__) + /* If we have EV_DISPATCH we use it, unless we are on OpenBSD as the + behavior of EV_EOF seems to be edge triggered there and we need it + to be level triggered. + + The kevent descriptions for both read and write are added on OP_ADD + and removed on OP_DEL. And then after than only EV_ENABLE|EV_DISPATCH + are used. It could be possible to not modify the pollset when disabling and/or deleting events, but that may cause the poll threads to be awoken diff --git a/erts/etc/unix/etp-commands.in b/erts/etc/unix/etp-commands.in index bac90cb472..e5ef819444 100644 --- a/erts/etc/unix/etp-commands.in +++ b/erts/etc/unix/etp-commands.in @@ -1997,7 +1997,7 @@ define etp-process-info printf " Msgq len: %d\n", $etp_proc->sig_qs.len end printf " Parent: " - etp-1 $etp_proc->parent + etp-1 ((Eterm)($etp_proc->parent)) printf "\n Pointer: (Process *) %p\n", $etp_proc end end @@ -2017,15 +2017,17 @@ define etp-processes set $proc_ix = 0 set $proc_max_ix = erts_proc.r.o.max set $proc_tab = erts_proc.r.o.tab + set $proc_cnt = erts_proc.vola.tile.count.counter set $invalid_proc = &erts_invalid_process set $proc_decentile = $proc_max_ix / 10 set $proc_printile = $proc_decentile - while $proc_ix < $proc_max_ix + while $proc_ix < $proc_max_ix && $proc_cnt > 0 set $proc = (Process *) *((UWord *) ($proc_tab + $proc_ix)) if ($proc != ((Process *) 0) && $proc != $invalid_proc) printf "---\n" printf " Pix: %d\n", $proc_ix etp-process-info $proc + set $proc_cnt-- end if $proc_ix == $proc_printile printf "--- %d%% (%d / %d) searched\n", $proc_printile / $proc_decentile * 10, $proc_ix, $proc_max_ix @@ -2363,10 +2365,11 @@ define etp-ports set $port_ix = 0 set $port_max_ix = erts_port.r.o.max set $port_tab = erts_port.r.o.tab + set $port_cnt = erts_proc.vola.tile.count.counter set $invalid_port = &erts_invalid_port set $port_decentile = $port_max_ix / 10 set $port_printile = $port_decentile - while $port_ix < $port_max_ix + while $port_ix < $port_max_ix && $port_cnt > 0 set $port = (Port *) *((UWord *) ($port_tab + $port_ix)) if ($port != ((Port *) 0) && $port != $invalid_port) if (*(((Uint32 *) &(((Port *) $port)->state))) & 0x100) == 0 @@ -2374,6 +2377,7 @@ define etp-ports printf "---\n" printf " Pix: %d\n", $port_ix etp-port-info $port + set $port_cnt-- end end if $port_ix == $port_printile diff --git a/lib/.gitignore b/lib/.gitignore index 283393faa9..7cef9d7cf3 100644 --- a/lib/.gitignore +++ b/lib/.gitignore @@ -1,32 +1,3 @@ -# common test - -/common_test/doc/src/ct.xml -/common_test/doc/src/ct_cover.xml -/common_test/doc/src/ct_ftp.xml -/common_test/doc/src/ct_master.xml -/common_test/doc/src/ct_rpc.xml -/common_test/doc/src/ct_snmp.xml -/common_test/doc/src/ct_ssh.xml -/common_test/doc/src/ct_netconfc.xml -/common_test/doc/src/ct_telnet.xml -/common_test/doc/src/unix_telnet.xml - -# edoc - -/edoc/doc/src/chapter.xml -/edoc/doc/src/edoc.xml -/edoc/doc/src/edoc_doclet.xml -/edoc/doc/src/edoc_extract.xml -/edoc/doc/src/edoc_layout.xml -/edoc/doc/src/edoc_lib.xml -/edoc/doc/src/edoc_run.xml - -# eunit - -/eunit/doc/src/chapter.xml -/eunit/doc/src/eunit.xml -/eunit/doc/src/eunit_surefire.xml - # erl_interface /erl_interface/bin @@ -34,15 +5,6 @@ /erl_interface/obj.st /erl_interface/obj -# gs - -/gs/doc/src/gs_chapter2.xml -/gs/doc/src/gs_chapter4.xml -/gs/doc/src/gs_chapter5.xml -/gs/doc/src/gs_chapter6.xml -/gs/doc/src/gs_chapter7.xml -/gs/doc/src/gs_chapter8.xml - # megaco /megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3a.erl @@ -129,19 +91,6 @@ /megaco/src/text/megaco_text_parser_v1.erl /megaco/src/text/megaco_text_parser_v2.erl /megaco/src/text/megaco_text_parser_v3.erl -/megaco/doc/html/mstone1.jpg - -# mnesia - -/mnesia/doc/src/Mnesia_App_A.xml -/mnesia/doc/src/Mnesia_App_B.xml -/mnesia/doc/src/Mnesia_App_C.xml -/mnesia/doc/src/Mnesia_App_D.xml -/mnesia/doc/src/Mnesia_chap2.xml -/mnesia/doc/src/Mnesia_chap3.xml -/mnesia/doc/src/Mnesia_chap4.xml -/mnesia/doc/src/Mnesia_chap5.xml -/mnesia/doc/src/Mnesia_chap7.xml # orber & cos* applications @@ -525,39 +474,3 @@ /orber/src/oe_OrberIFR.hrl /orber/src/oe_erlang.erl /orber/src/oe_erlang.hrl - -# snmp - -snmp/doc/intex.html - -# syntax_tools - -/syntax_tools/doc/src/chapter.xml -/syntax_tools/doc/src/epp_dodger.xml -/syntax_tools/doc/src/erl_comment_scan.xml -/syntax_tools/doc/src/erl_prettypr.xml -/syntax_tools/doc/src/erl_recomment.xml -/syntax_tools/doc/src/erl_syntax.xml -/syntax_tools/doc/src/erl_syntax_lib.xml -/syntax_tools/doc/src/erl_tidy.xml -/syntax_tools/doc/src/merl.xml -/syntax_tools/doc/src/merl_transform.xml -/syntax_tools/doc/src/igor.xml -/syntax_tools/doc/src/prettypr.xml - -# wx - -/wx/doc/src/chapter.xml -/wx/doc/src/gl.xml -/wx/doc/src/glu.xml -/wx/doc/src/ref_man.xml - -# xmerl - -/xmerl/doc/src/xmerl.xml -/xmerl/doc/src/xmerl_eventp.xml -/xmerl/doc/src/xmerl_scan.xml -/xmerl/doc/src/xmerl_ug.xml -/xmerl/doc/src/xmerl_xpath.xml -/xmerl/doc/src/xmerl_xs.xml -/xmerl/doc/src/xmerl_xsd.xml diff --git a/lib/asn1/doc/src/Makefile b/lib/asn1/doc/src/Makefile index 9a388e4e8a..2b5d9467d9 100644 --- a/lib/asn1/doc/src/Makefile +++ b/lib/asn1/doc/src/Makefile @@ -51,13 +51,14 @@ XML_CHAPTER_FILES = \ asn1_introduction.xml \ asn1_getting_started.xml \ asn1_overview.xml \ - asn1_spec.xml \ notes.xml BOOK_FILES = book.xml XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) \ - $(GEN_XML) $(XML_PART_FILES) $(XML_CHAPTER_FILES) + $(XML_PART_FILES) $(XML_CHAPTER_FILES) + +XML_GEN_FILES = $(GEN_XML:%=$(XMLDIR)/%) GIF_FILES = \ exclusive_Win_But.gif \ @@ -75,7 +76,8 @@ EXTRA_FILES = \ $(DEFAULT_HTML_FILES) \ $(ASN1_FILES) \ $(XML_REF3_FILES:%.xml=$(HTMLDIR)/%.html) \ - $(XML_CHAPTER_FILES:%.xml=$(HTMLDIR)/%.html) + $(XML_CHAPTER_FILES:%.xml=$(HTMLDIR)/%.html) \ + $(GEN_XML:%.xml=$(HTMLDIR)/%.html) \ MAN3_FILES = $(XML_REF3_FILES:%.xml=$(MAN3DIR)/%.3) diff --git a/lib/edoc/doc/src/Makefile b/lib/edoc/doc/src/Makefile index ca9ea66e3c..71de42795a 100644 --- a/lib/edoc/doc/src/Makefile +++ b/lib/edoc/doc/src/Makefile @@ -54,9 +54,10 @@ XML_NOTES_FILES = notes.xml BOOK_FILES = book.xml XML_FILES=\ - $(BOOK_FILES) $(XML_CHAPTER_FILES) \ - $(XML_PART_FILES) $(XML_REF3_FILES) $(XML_APPLICATION_FILES) \ - $(XML_NOTES_FILES) + $(BOOK_FILES) $(XML_APPLICATION_FILES) \ + $(XML_PART_FILES) $(XML_NOTES_FILES) + +XML_GEN_FILES=$(XML_REF3_FILES:%=$(XMLDIR)/%) $(XML_CHAPTER_FILES:%=$(XMLDIR)/%) # ---------------------------------------------------- INFO_FILE = ../../info @@ -101,11 +102,11 @@ html: gifs $(HTML_REF_MAN_FILE) man: $(MAN3_FILES) -$(XML_REF3_FILES): - escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(EDOC_VSN) -i $(ERL_TOP)/lib/edoc/include $(SRC_DIR)/$(@:%.xml=%.erl) +$(XML_REF3_FILES:%=$(XMLDIR)/%): + $(gen_verbose)escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(EDOC_VSN) -i $(ERL_TOP)/lib/edoc/include -dir $(XMLDIR) $(SRC_DIR)/$(@:$(XMLDIR)/%.xml=%.erl) -$(XML_CHAPTER_FILES): ../overview.edoc - escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(EDOC_VSN) -chapter ../overview.edoc +$(XML_CHAPTER_FILES:%=$(XMLDIR)/%): ../overview.edoc + $(gen_verbose)escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(EDOC_VSN) -chapter -dir $(XMLDIR) $< gifs: $(GIF_FILES:%=$(HTMLDIR)/%) diff --git a/lib/erl_docgen/priv/bin/codeline_preprocessing.escript b/lib/erl_docgen/priv/bin/codeline_preprocessing.escript index 8e1e35bcdd..67966b79e6 100755 --- a/lib/erl_docgen/priv/bin/codeline_preprocessing.escript +++ b/lib/erl_docgen/priv/bin/codeline_preprocessing.escript @@ -30,7 +30,7 @@ %% Function: main/1 %% Description: %%---------------------------------------------------------------------- -main([InFile, OutFile]) -> +main([CPath, InFile, OutFile]) -> InDev = case file:open(InFile, [read]) of {ok,ID} -> @@ -38,7 +38,6 @@ main([InFile, OutFile]) -> _ -> halt(5) end, - CPath=filename:dirname(InFile), OutDev = case file:open(OutFile, [write]) of {ok,OD} -> diff --git a/lib/erl_docgen/priv/bin/github_link.escript b/lib/erl_docgen/priv/bin/github_link.escript new file mode 100755 index 0000000000..1b36fca202 --- /dev/null +++ b/lib/erl_docgen/priv/bin/github_link.escript @@ -0,0 +1,51 @@ +#!/usr/bin/env escript +%% -*- erlang -*- +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010-2016. All Rights Reserved. +%% +%% 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. +%% +%% %CopyrightEnd% +%%---------------------------------------------------------------------- +%% File : github_link.escript +%% +%% Created : 12 Dec 2017 by Lukas Larsson +%%---------------------------------------------------------------------- + +main([In, Filename, Sha, Out]) -> + {ok, Bin} = file:read_file(In), + + TagsToAnnotate = ["description", "func", "datatype", "section"], + + Subs = subs(TagsToAnnotate, Filename, Sha, re:split(Bin,[$\n])), + + file:write_file(Out, Subs). + +subs([], _, _, Bin) -> + lists:join("\n", Bin); +subs([Pat|Pats], Fn, Sha, Bin) -> + subs(Pats, Fn, Sha, sub(Bin, Pat, Fn, Sha)). + +sub(Bin, Pat, Fn, Sha) -> + sub(Bin, Pat, Fn, Sha, 1). +sub([], _Pat, _Fn, _Sha, _Cnt) -> + []; +sub([H|T], Pat, Fn, Sha, Cnt) -> + %% We use the maint branch here, it is not as exact as the tag, + %% but it is the best we can do as github does not allow doing + %% pullrequests on anything but branches. + [re:replace(H,["<",Pat,">"], + ["<",Pat," ghlink=\"maint/",Fn,"#L", + integer_to_list(Cnt),"\">"],[{return,list}]) | + sub(T, Pat, Fn, Sha, Cnt+1)]. diff --git a/lib/erl_docgen/priv/bin/xml_from_edoc.escript b/lib/erl_docgen/priv/bin/xml_from_edoc.escript index b930ae3818..b0e3764fae 100755 --- a/lib/erl_docgen/priv/bin/xml_from_edoc.escript +++ b/lib/erl_docgen/priv/bin/xml_from_edoc.escript @@ -28,6 +28,7 @@ %% Records %%====================================================================== -record(args, {suffix=".xml", + dir=".", layout=docgen_edoc_xml_cb, def=[], includes=[], @@ -85,7 +86,7 @@ module(File, Args) -> {app_default, "OTPROOT"}, {file_suffix, Args#args.suffix}, - {dir, "."}, + {dir, Args#args.dir}, {layout, Args#args.layout}], edoc:file(File, Opts); false -> @@ -118,7 +119,7 @@ users_guide(File, Args) -> Text = edoc_lib:run_layout(F, Opts), OutFile = "chapter" ++ Args#args.suffix, - edoc_lib:write_file(Text, ".", OutFile, Encoding); + edoc_lib:write_file(Text, Args#args.dir, OutFile, Encoding); false -> io:format("~s: not a regular file\n", [File]), usage() @@ -139,6 +140,8 @@ parse(["-def", Key, Val |RawOpts], Type, Args) -> parse(["-i", Dir |RawOpts], Type, Args) -> Args2 = Args#args{includes=Args#args.includes++[Dir]}, parse(RawOpts, Type, Args2); +parse(["-dir", Dir |RawOpts], Type, Args) -> + parse(RawOpts, Type, Args#args{dir=Dir}); parse(["-preprocess", Bool |RawOpts], Type, Args) when Bool == "true"; Bool == "false" -> parse(RawOpts, Type, Args#args{preprocess=list_to_atom(Bool)}); diff --git a/lib/erl_docgen/priv/css/otp_doc.css b/lib/erl_docgen/priv/css/otp_doc.css index 66ea09b53a..34c6befb0e 100644 --- a/lib/erl_docgen/priv/css/otp_doc.css +++ b/lib/erl_docgen/priv/css/otp_doc.css @@ -242,8 +242,25 @@ th { font-size: small; } -h3>a, h4>a{ - color: #1a1a1a !important; +.title_link { + color: #1a1a1a !important; + outline: none; +} + +.ghlink { + margin-left: -2.7em; /* .pencil.font-size + .pencil.padding.left + .pencil.padding.right = 2.7 */ + visibility: hidden; +} + +.pencil:before { + transform: rotateZ(90deg); + content: "\270E"; + color: #1a1a1a !important; + font-weight: bold; + font-size: 1.5em; + padding: .3em .6em .6em; + line-height: 1em; + font-family: mono; } hr{ diff --git a/lib/erl_docgen/priv/dtd/chapter.dtd b/lib/erl_docgen/priv/dtd/chapter.dtd index 8d940b90f7..3e9113d798 100644 --- a/lib/erl_docgen/priv/dtd/chapter.dtd +++ b/lib/erl_docgen/priv/dtd/chapter.dtd @@ -35,3 +35,4 @@ <!ELEMENT section (marker*,title, (%block;|quote|warning|note|dont|do|br|image|marker| table|section)*) > +<!ATTLIST section ghlink CDATA #IMPLIED> diff --git a/lib/erl_docgen/priv/dtd/common.refs.dtd b/lib/erl_docgen/priv/dtd/common.refs.dtd index 172cd16ad4..07c876a17f 100644 --- a/lib/erl_docgen/priv/dtd/common.refs.dtd +++ b/lib/erl_docgen/priv/dtd/common.refs.dtd @@ -26,8 +26,10 @@ %common.header; <!ELEMENT description (%block;|quote|br|marker|warning|note|dont|do)* > +<!ATTLIST description ghlink CDATA #IMPLIED> <!ELEMENT funcs (func)+ > <!ELEMENT func (name+,fsummary,(type|type_desc)*,desc?) > +<!ATTLIST func ghlink CDATA #IMPLIED> <!-- ELEMENT name is defined in each ref dtd --> <!ELEMENT fsummary (#PCDATA|c|i|em|anno)* > <!ELEMENT type (v,d?)* > @@ -42,9 +44,11 @@ <!ELEMENT email (#PCDATA) > <!ELEMENT section (marker*,title,(%block;|quote|br|marker| warning|note|dont|do|section)*) > +<!ATTLIST section ghlink CDATA #IMPLIED> <!ELEMENT datatypes (datatype_title?,datatype)+ > <!ELEMENT datatype_title (#PCDATA) > <!ELEMENT datatype (name+,desc?) > +<!ATTLIST datatype ghlink CDATA #IMPLIED> <!ELEMENT type_desc (#PCDATA|anno|c|seealso)* > <!ATTLIST type_desc variable CDATA #IMPLIED name CDATA #IMPLIED> diff --git a/lib/erl_docgen/priv/xsl/db_html.xsl b/lib/erl_docgen/priv/xsl/db_html.xsl index f9f3a356be..b6ebcc0c67 100644 --- a/lib/erl_docgen/priv/xsl/db_html.xsl +++ b/lib/erl_docgen/priv/xsl/db_html.xsl @@ -54,6 +54,24 @@ <func:result select="$result"/> </func:function> + <func:function name="erl:lower-case"> + <xsl:param name="str"/> + + <xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/> + <xsl:variable name="lowercase" select="'abcdefghijklmnopqrstuvwxyz'"/> + + <xsl:variable name="result"> + <xsl:value-of select="translate($str, $uppercase, $lowercase)"/> + </xsl:variable> + + <func:result select="$result"/> + </func:function> + + <func:function name="erl:to-link"> + <xsl:param name="text"/> + <func:result select="translate(erl:lower-case($text),': /()" ','-------')"/> + </func:function> + <!-- Used from template menu.funcs to sort a module's functions for the lefthand index list, from the module's .xml file. Returns a value on which to sort the entity in question (a <name> element). @@ -208,6 +226,7 @@ <xsl:variable name="local_types" select="../type[string-length(@name) > 0]"/> <xsl:apply-templates select="$spec/contract/clause/head"> + <xsl:with-param name="ghlink" select="ancestor-or-self::*[@ghlink]/@ghlink"/> <xsl:with-param name="local_types" select="$local_types"/> <xsl:with-param name="global_types" select="$global_types"/> </xsl:apply-templates> @@ -216,9 +235,17 @@ </xsl:template> <xsl:template match="head"> + <xsl:param name="ghlink"/> <xsl:param name="local_types"/> <xsl:param name="global_types"/> - <div class="bold_code func-head"> + <xsl:variable name="id" select="concat(concat(concat(concat(../../../name,'-'),../../../arity),'-'),generate-id(.))"/> + <div class="bold_code func-head" + onMouseOver="document.getElementById('ghlink-{$id}').style.visibility = 'visible';" + onMouseOut="document.getElementById('ghlink-{$id}').style.visibility = 'hidden';"> + <xsl:call-template name="ghlink"> + <xsl:with-param name="ghlink" select="$ghlink"/> + <xsl:with-param name="id" select="$id"/> + </xsl:call-template> <xsl:apply-templates mode="local_type"> <xsl:with-param name="local_types" select="$local_types"/> <xsl:with-param name="global_types" select="$global_types"/> @@ -403,24 +430,35 @@ <!-- Datatypes --> <xsl:template match="datatypes"> - <h3> - <a name="data-types" href="#data-types"><xsl:text>Data Types</xsl:text></a> - </h3> + <xsl:call-template name="h3_title_link"> + <xsl:with-param name="title">Data Types</xsl:with-param> + </xsl:call-template> <xsl:apply-templates/> </xsl:template> - <!-- Datatype Title--> + <!-- Datatype Title, is the really needed? not used by anything --> <xsl:template match="datatype_title"> - <xsl:variable name="title" select="."/> - <h4> - <a name="{$title}" href="#{$title}"><xsl:apply-templates/></a> + <xsl:variable name="title" select="."/> + <h4> + <xsl:call-template name="title_link"> + <xsl:with-param name="title"><xsl:apply-templates/></xsl:with-param> + <xsl:with-param name="link" select="$title"/> + </xsl:call-template> </h4> </xsl:template> <!-- Datatype --> <xsl:template match="datatype"> + <xsl:variable name="id" select="concat('type-',name/@name)"/> <div class="data-types-body"> - <div class="data-type-name"><xsl:apply-templates select="name"/></div> + <div class="data-type-name" + onMouseOver="document.getElementById('ghlink-{$id}').style.visibility = 'visible';" + onMouseOut="document.getElementById('ghlink-{$id}').style.visibility = 'hidden';"> + <xsl:call-template name="ghlink"> + <xsl:with-param name="id" select="$id"/> + </xsl:call-template> + <xsl:apply-templates select="name"/> + </div> <div class="data-type-desc"><xsl:apply-templates select="desc"/></div> </div> </xsl:template> @@ -904,7 +942,7 @@ <!-- Header --> <xsl:template match="header"/> - + <!-- Section/Title --> <xsl:template match="section/title"/> @@ -917,10 +955,12 @@ <xsl:for-each select="marker"> <xsl:call-template name="marker-before-title"/> </xsl:for-each> - <a name="{generate-id(title)}"> - <xsl:value-of select="$chapnum"/>.<xsl:number/>  - <xsl:value-of select="title"/> - </a> + <xsl:call-template name="title_link"> + <xsl:with-param name="title"> + <xsl:value-of select="$chapnum"/>.<xsl:number/>  + <xsl:value-of select="title"/> + </xsl:with-param> + </xsl:call-template> </h3> <xsl:apply-templates> <xsl:with-param name="chapnum" select="$chapnum"/> @@ -937,7 +977,9 @@ <xsl:call-template name="marker-before-title"/> </xsl:for-each> <!-- xsl:value-of select="$partnum"/>.<xsl:value-of select="$chapnum"/>.<xsl:value-of select="$sectnum"/>.<xsl:number/ --> - <xsl:value-of select="title"/> + <xsl:call-template name="title_link"> + <xsl:with-param name="title" select="title"/> + </xsl:call-template> </h4> <xsl:apply-templates> <xsl:with-param name="chapnum" select="$chapnum"/> @@ -967,9 +1009,9 @@ <xsl:for-each select="marker"> <xsl:call-template name="marker-before-title"/> </xsl:for-each> - <a name="{generate-id(title)}"> - <xsl:value-of select="title"/> - </a> + <xsl:call-template name="title_link"> + <xsl:with-param name="title" select="title"/> + </xsl:call-template> </h3> <div class="REFBODY rb-3"> <xsl:apply-templates> @@ -1359,7 +1401,7 @@ <xsl:param name="chapter_file"/> <xsl:for-each select="$entries"> <li title="{title}"> - <a href="{$chapter_file}.html#{generate-id(title)}"> + <a href="{$chapter_file}.html#{erl:to-link(title)}"> <xsl:value-of select="title"/> </a> </li> @@ -1813,7 +1855,9 @@ <!-- Module --> <xsl:template match="module"> <xsl:param name="partnum"/> - <h3><a name="module" href="#module">Module</a></h3> + <xsl:call-template name="h3_title_link"> + <xsl:with-param name="title">Module</xsl:with-param> + </xsl:call-template> <div class="REFBODY module-body"> <xsl:apply-templates> <xsl:with-param name="partnum" select="$partnum"/> @@ -1825,7 +1869,9 @@ <!-- Modulesummary --> <xsl:template match="modulesummary"> <xsl:param name="partnum"/> - <h3><a name="module-summary" href="#module-summary">Module Summary</a></h3> + <xsl:call-template name="h3_title_link"> + <xsl:with-param name="title">Module Summary</xsl:with-param> + </xsl:call-template> <div class="REFBODY module-summary-body"> <xsl:apply-templates> <xsl:with-param name="partnum" select="$partnum"/> @@ -1836,7 +1882,9 @@ <!-- Lib --> <xsl:template match="lib"> <xsl:param name="partnum"/> - <h3><a name="c-library" href="#c-library">C Library</a></h3> + <xsl:call-template name="h3_title_link"> + <xsl:with-param name="title">C Library</xsl:with-param> + </xsl:call-template> <div class="REFBODY c-library-body"> <xsl:apply-templates> <xsl:with-param name="partnum" select="$partnum"/> @@ -1848,7 +1896,9 @@ <!-- Libsummary --> <xsl:template match="libsummary"> <xsl:param name="partnum"/> - <h3><a name="library-summary" href="#library-summary">Library Summary</a></h3> + <xsl:call-template name="h3_title_link"> + <xsl:with-param name="title">Library Summary</xsl:with-param> + </xsl:call-template> <div class="REFBODY library-summary-body"> <xsl:apply-templates> <xsl:with-param name="partnum" select="$partnum"/> @@ -1859,7 +1909,9 @@ <!-- Com --> <xsl:template match="com"> <xsl:param name="partnum"/> - <h3><a name="command" href="#command">Command</a></h3> + <xsl:call-template name="h3_title_link"> + <xsl:with-param name="title">Command</xsl:with-param> + </xsl:call-template> <div class="REFBODY command-body"> <xsl:apply-templates> <xsl:with-param name="partnum" select="$partnum"/> @@ -1871,7 +1923,9 @@ <!-- Comsummary --> <xsl:template match="comsummary"> <xsl:param name="partnum"/> - <h3><a name="command-summary" href="#command-summary">Command Summary</a></h3> + <xsl:call-template name="h3_title_link"> + <xsl:with-param name="title">Command Summary</xsl:with-param> + </xsl:call-template> <div class="REFBODY command-summary-body"> <xsl:apply-templates> <xsl:with-param name="partnum" select="$partnum"/> @@ -1882,7 +1936,9 @@ <!-- File --> <xsl:template match="file"> <xsl:param name="partnum"/> - <h3><a name="file" href="#file">File</a></h3> + <xsl:call-template name="h3_title_link"> + <xsl:with-param name="title">File</xsl:with-param> + </xsl:call-template> <div class="REFBODY file-body"> <xsl:apply-templates> <xsl:with-param name="partnum" select="$partnum"/> @@ -1894,7 +1950,9 @@ <!-- Filesummary --> <xsl:template match="filesummary"> <xsl:param name="partnum"/> - <h3><a name="file-summary" href="#file-summary">File Summary</a></h3> + <xsl:call-template name="h3_title_link"> + <xsl:with-param name="title">File Summary</xsl:with-param> + </xsl:call-template> <div class="REFBODY file-summary-body"> <xsl:apply-templates> <xsl:with-param name="partnum" select="$partnum"/> @@ -1906,7 +1964,9 @@ <!-- App --> <xsl:template match="app"> <xsl:param name="partnum"/> - <h3><a name="application" href="#application">Application</a></h3> + <xsl:call-template name="h3_title_link"> + <xsl:with-param name="title">Application</xsl:with-param> + </xsl:call-template> <div class="REFBODY application-body"> <xsl:apply-templates> <xsl:with-param name="partnum" select="$partnum"/> @@ -1918,7 +1978,9 @@ <!-- Appsummary --> <xsl:template match="appsummary"> <xsl:param name="partnum"/> - <h3><a name="application-summary" href="#application-summary">Application Summary</a></h3> + <xsl:call-template name="h3_title_link"> + <xsl:with-param name="title">Application Summary</xsl:with-param> + </xsl:call-template> <div class="REFBODY application-summary-body"> <xsl:apply-templates> <xsl:with-param name="partnum" select="$partnum"/> @@ -1929,7 +1991,9 @@ <!-- Description --> <xsl:template match="description"> <xsl:param name="partnum"/> - <h3><a name="description" href="#description">Description</a></h3> + <xsl:call-template name="h3_title_link"> + <xsl:with-param name="title">Description</xsl:with-param> + </xsl:call-template> <div class="REFBODY description-body"> <p> <xsl:apply-templates> @@ -1943,7 +2007,9 @@ <xsl:template match="funcs"> <xsl:param name="partnum"/> - <h3><a name="exports" href="#exports"><xsl:text>Exports</xsl:text></a></h3> + <xsl:call-template name="h3_title_link"> + <xsl:with-param name="title">Exports</xsl:with-param> + </xsl:call-template> <div class="exports-body"> <xsl:apply-templates> @@ -1960,7 +2026,8 @@ <p><xsl:apply-templates select="name"/> <xsl:apply-templates select="name[string-length(@arity) > 0 and position()=last()]" - mode="types"/></p> + mode="types"/> + </p> <xsl:apply-templates select="fsummary|type|desc"> <xsl:with-param name="partnum" select="$partnum"/> @@ -2019,14 +2086,19 @@ <xsl:choose> <xsl:when test="ancestor::cref"> - <a name="{substring-before(nametext, '(')}"> - <span class="bold_code bc-7"> - <xsl:value-of select="ret"/> - <xsl:call-template name="maybe-space-after-ret"> - <xsl:with-param name="s" select="ret"/> - </xsl:call-template> - <xsl:value-of select="nametext"/> - </span></a><br/> + <span class="bold_code bc-7"> + <xsl:call-template name="title_link"> + <xsl:with-param name="link" select="substring-before(nametext, '(')"/> + <xsl:with-param name="title"> + <xsl:value-of select="ret"/> + <xsl:call-template name="maybe-space-after-ret"> + <xsl:with-param name="s" select="ret"/> + </xsl:call-template> + <xsl:value-of select="nametext"/> + </xsl:with-param> + </xsl:call-template> + </span> + <br/> </xsl:when> <xsl:when test="ancestor::erlref"> <xsl:variable name="fname"> @@ -2047,15 +2119,29 @@ </xsl:variable> <xsl:choose> <xsl:when test="ancestor::datatype"> - <a name="type-{$fname}"></a><span class="bold_code bc-8"><xsl:apply-templates/></span><br/> + <div class="bold_code bc-8"> + <xsl:call-template name="title_link"> + <xsl:with-param name="link" select="concat('type-',$fname)"/> + <xsl:with-param name="title"> + <xsl:apply-templates/> + </xsl:with-param> + </xsl:call-template> + </div> </xsl:when> <xsl:otherwise> - <a name="{$fname}-{$arity}"></a><span class="bold_code fun-type"><xsl:apply-templates/></span><br/> + <div class="bold_code fun-type"> + <xsl:call-template name="title_link"> + <xsl:with-param name="link" select="concat(concat($fname,'-'),$arity)"/> + <xsl:with-param name="title"> + <xsl:apply-templates/> + </xsl:with-param> + </xsl:call-template> + </div> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> - <span class="bold_code bc-10"><xsl:value-of select="."/></span> + <div class="bold_code bc-10"><xsl:value-of select="."/></div> </xsl:otherwise> </xsl:choose> @@ -2115,6 +2201,49 @@ </div> </xsl:template> + <xsl:template name="h3_title_link"> + <xsl:param name="title"/> + <h3> + <xsl:call-template name="title_link"> + <xsl:with-param name="title" select="$title"/> + <xsl:with-param name="link" select="erl:to-link($title)"/> + </xsl:call-template> + </h3> + </xsl:template> + + <xsl:template name="title_link"> + <xsl:param name="title"/> + <xsl:param name="link" select="erl:to-link(title)"/> + <xsl:param name="ghlink" select="ancestor-or-self::*[@ghlink][position() = 1]/@ghlink"/> + <xsl:variable name="id" select="concat(concat($link,'-'), generate-id(.))"/> + <span onMouseOver="document.getElementById('ghlink-{$id}').style.visibility = 'visible';" + onMouseOut="document.getElementById('ghlink-{$id}').style.visibility = 'hidden';"> + <xsl:call-template name="ghlink"> + <xsl:with-param name="id" select="$id"/> + <xsl:with-param name="ghlink" select="$ghlink"/> + </xsl:call-template> + <a class="title_link" name="{$link}" href="#{$link}"><xsl:value-of select="$title"/></a> + </span> + </xsl:template> + + <xsl:template name="ghlink"> + <xsl:param name="id"/> + <xsl:param name="ghlink" select="ancestor-or-self::*[@ghlink][position() = 1]/@ghlink"/> + <xsl:choose> + <xsl:when test="string-length($ghlink) > 0"> + <span id="ghlink-{$id}" class="ghlink"> + <a href="https://github.com/erlang/otp/edit/{$ghlink}" + title="Found an issue with the documentation? Fix it by clicking here!"> + <span class="pencil"/> + </a> + </span> + </xsl:when> + <xsl:otherwise> + <span id="ghlink-{$id}"/> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + <!-- Desc --> <xsl:template match="desc"> <xsl:param name="partnum"/> diff --git a/lib/et/doc/src/Makefile b/lib/et/doc/src/Makefile index 0257a8f817..162d36e274 100644 --- a/lib/et/doc/src/Makefile +++ b/lib/et/doc/src/Makefile @@ -45,8 +45,11 @@ include files.mk XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) \ $(XML_PART_FILES) $(XML_CHAPTER_FILES) +XML_GEN_FILES = $(GEN_XML:%=$(XMLDIR)/%) + HTML_FILES = $(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.html) \ - $(XML_PART_FILES:%.xml=$(HTMLDIR)/%.html) + $(XML_PART_FILES:%.xml=$(HTMLDIR)/%.html) \ + $(GEN_XML:%.xml=$(HTMLDIR)/%.html) INFO_FILE = ../../info diff --git a/lib/et/doc/src/files.mk b/lib/et/doc/src/files.mk index e0ea9b0b76..7437da7ce3 100644 --- a/lib/et/doc/src/files.mk +++ b/lib/et/doc/src/files.mk @@ -31,10 +31,13 @@ XML_PART_FILES = \ XML_CHAPTER_FILES = \ et_intro.xml \ + notes.xml + +GEN_XML = \ et_tutorial.xml \ et_desc.xml \ - et_examples.xml \ - notes.xml + et_examples.xml + BOOK_FILES = book.xml diff --git a/lib/eunit/doc/src/Makefile b/lib/eunit/doc/src/Makefile index 610e575af6..e91d947592 100644 --- a/lib/eunit/doc/src/Makefile +++ b/lib/eunit/doc/src/Makefile @@ -70,9 +70,10 @@ HTML_STYLESHEET_FILES = \ BOOK_FILES = book.xml XML_FILES = \ - $(BOOK_FILES) $(XML_CHAPTER_FILES) $(XML_NOTES_FILES) \ - $(XML_PART_FILES) $(XML_REF3_FILES) $(XML_APPLICATION_FILES) + $(BOOK_FILES) $(XML_NOTES_FILES) \ + $(XML_PART_FILES) $(XML_APPLICATION_FILES) +XML_GEN_FILES = $(XML_REF3_FILES:%=$(XMLDIR)/%) $(XML_CHAPTER_FILES:%=$(XMLDIR)/%) # ---------------------------------------------------- INFO_FILE = ../../info @@ -122,11 +123,11 @@ man: $(MAN3_FILES) gifs: $(GIF_FILES:%=$(HTMLDIR)/%) -$(XML_REF3_FILES): - escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(EUNIT_VSN) -i $(EUNIT_INC_DIR) $(EUNIT_DIR)/$(@:%.xml=%.erl) +$(XML_REF3_FILES:%=$(XMLDIR)/%): + $(gen_verbose)escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(EUNIT_VSN) -i $(EUNIT_INC_DIR) -dir $(XMLDIR) $(EUNIT_DIR)/$(@:$(XMLDIR)/%.xml=%.erl) -$(XML_CHAPTER_FILES): - escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(EUNIT_VSN) -chapter ../overview.edoc +$(XML_CHAPTER_FILES:%=$(XMLDIR)/%): + $(gen_verbose)escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(EUNIT_VSN) -chapter -dir $(XMLDIR) ../overview.edoc info: @echo "XML_PART_FILES: $(XML_PART_FILES)" diff --git a/lib/inets/doc/src/httpc.xml b/lib/inets/doc/src/httpc.xml index 14662f257c..ffc6fec518 100644 --- a/lib/inets/doc/src/httpc.xml +++ b/lib/inets/doc/src/httpc.xml @@ -312,8 +312,7 @@ <v>Body = string() | binary()</v> <v>Profile = profile() | pid()</v> <d>When started <c>stand_alone</c> only the pid can be used.</d> - <v>Reason = {connect_failed, term()} | - {send_failed, term()} | term()</v> + <v>Reason = term()</v> </type> <desc> diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl index 9b09832eb8..eeb08ce0ee 100644 --- a/lib/inets/src/http_client/httpc_handler.erl +++ b/lib/inets/src/http_client/httpc_handler.erl @@ -48,19 +48,17 @@ queue_timer :: reference() | 'undefined' }). --type session_failed() :: {'connect_failed',term()} | {'send_failed',term()}. - -record(state, { request :: request() | 'undefined', - session :: session() | session_failed() | 'undefined', + session :: session() | 'undefined', status_line, % {Version, StatusCode, ReasonPharse} headers :: http_response_h() | 'undefined', body :: binary() | 'undefined', mfa, % {Module, Function, Args} pipeline = queue:new() :: queue:queue(), keep_alive = queue:new() :: queue:queue(), - status, % undefined | new | pipeline | keep_alive | close | {ssl_tunnel, Request} + status :: undefined | new | pipeline | keep_alive | close | {ssl_tunnel, request()}, canceled = [], % [RequestId] max_header_size = nolimit :: nolimit | integer(), max_body_size = nolimit :: nolimit | integer(), @@ -255,8 +253,8 @@ handle_call(Request, From, State) -> Result -> Result catch - _:Reason -> - {stop, {shutdown, Reason} , State} + Class:Reason:ST -> + {stop, {shutdown, {{Class, Reason}, ST}}, State} end. @@ -271,8 +269,8 @@ handle_cast(Msg, State) -> Result -> Result catch - _:Reason -> - {stop, {shutdown, Reason} , State} + Class:Reason:ST -> + {stop, {shutdown, {{Class, Reason}, ST}}, State} end. %%-------------------------------------------------------------------- @@ -286,8 +284,8 @@ handle_info(Info, State) -> Result -> Result catch - _:Reason -> - {stop, {shutdown, Reason} , State} + Class:Reason:ST -> + {stop, {shutdown, {{Class, Reason}, ST}}, State} end. %%-------------------------------------------------------------------- @@ -295,23 +293,6 @@ handle_info(Info, State) -> %% Description: Shutdown the httpc_handler %%-------------------------------------------------------------------- -%% Init error there is no socket to be closed. -terminate(normal, - #state{request = Request, - session = {send_failed, _} = Reason} = State) -> - maybe_send_answer(Request, - httpc_response:error(Request, Reason), - State), - ok; - -terminate(normal, - #state{request = Request, - session = {connect_failed, _} = Reason} = State) -> - maybe_send_answer(Request, - httpc_response:error(Request, Reason), - State), - ok; - terminate(normal, #state{session = undefined}) -> ok; @@ -588,11 +569,11 @@ do_handle_info({Proto, _Socket, Data}, activate_once(Session), {noreply, State#state{mfa = NewMFA}} catch - _:Reason -> + Class:Reason:ST -> ClientReason = {could_not_parse_as_http, Data}, ClientErrMsg = httpc_response:error(Request, ClientReason), NewState = answer_request(Request, ClientErrMsg, State), - {stop, {shutdown, Reason}, NewState} + {stop, {shutdown, {{Class, Reason}, ST}}, NewState} end; do_handle_info({Proto, Socket, Data}, @@ -1058,15 +1039,15 @@ handle_response(#state{status = new} = State) -> ?hcrd("handle response - status = new", []), handle_response(try_to_enable_pipeline_or_keep_alive(State)); -handle_response(#state{request = Request, - status = Status, - session = Session, - status_line = StatusLine, - headers = Headers, - body = Body, - options = Options, - profile_name = ProfileName} = State) - when Status =/= new -> +handle_response(#state{status = Status0} = State0) when Status0 =/= new -> + State = handle_server_closing(State0), + #state{request = Request, + session = Session, + status_line = StatusLine, + headers = Headers, + body = Body, + options = Options, + profile_name = ProfileName} = State, handle_cookies(Headers, Request, Options, ProfileName), case httpc_response:result({StatusLine, Headers, Body}, Request) of %% 100-continue @@ -1330,6 +1311,14 @@ try_to_enable_pipeline_or_keep_alive( State#state{status = close} end. +handle_server_closing(State = #state{status = close}) -> State; +handle_server_closing(State = #state{headers = undefined}) -> State; +handle_server_closing(State = #state{headers = Headers}) -> + case httpc_response:is_server_closing(Headers) of + true -> State#state{status = close}; + false -> State + end. + answer_request(#request{id = RequestId, from = From} = Request, Msg, #state{session = Session, timers = Timers, diff --git a/lib/inets/src/http_client/httpc_response.erl b/lib/inets/src/http_client/httpc_response.erl index 58ab9144df..92dc9b0e02 100644 --- a/lib/inets/src/http_client/httpc_response.erl +++ b/lib/inets/src/http_client/httpc_response.erl @@ -83,7 +83,6 @@ whole_body(Body, Length) -> %% result(Response, Request) -> %% Response - {StatusLine, Headers, Body} %% Request - #request{} -%% Session - #tcp_session{} %% %% Description: Checks the status code ... %%------------------------------------------------------------------------- diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl index 38705372c9..1116fdb1b6 100644 --- a/lib/inets/test/httpc_SUITE.erl +++ b/lib/inets/test/httpc_SUITE.erl @@ -67,7 +67,7 @@ groups() -> %% process_leak_on_keepalive is depending on stream_fun_server_close %% and it shall be the last test case in the suite otherwise cookie %% will fail. - {sim_http, [], only_simulated() ++ [process_leak_on_keepalive]}, + {sim_http, [], only_simulated() ++ server_closing_connection() ++ [process_leak_on_keepalive]}, {http_internal, [], real_requests_esi()}, {http_unix_socket, [], simulated_unix_socket()}, {https, [], real_requests()}, @@ -154,6 +154,12 @@ only_simulated() -> stream_fun_server_close ]. +server_closing_connection() -> + [ + server_closing_connection_on_first_response, + server_closing_connection_on_second_response + ]. + misc() -> [ server_does_not_exist, @@ -233,7 +239,7 @@ init_per_testcase(pipeline, Config) -> init_per_testcase(persistent_connection, Config) -> inets:start(httpc, [{profile, persistent}]), httpc:set_options([{keep_alive_timeout, 50000}, - {max_keep_alive_length, 3}], persistent_connection), + {max_keep_alive_length, 3}], persistent), Config; init_per_testcase(wait_for_whole_response, Config) -> @@ -252,6 +258,24 @@ end_per_testcase(pipeline, _Config) -> inets:stop(httpc, pipeline); end_per_testcase(persistent_connection, _Config) -> inets:stop(httpc, persistent); +end_per_testcase(Case, Config) + when Case == server_closing_connection_on_first_response; + Case == server_closing_connection_on_second_response -> + %% Test case uses at most one session. Ensure no leftover + %% sessions left behind. + {_, Status} = proplists:lookup(tc_status, Config), + ShallCleanup = case Status of + ok -> true; + {failed, _} -> true; + {skipped, _} -> false + end, + if ShallCleanup =:= true -> + httpc:request(url(group_name(Config), "/just_close.html", Config)), + ok; + true -> + ct:pal("Not cleaning up because test case status was ~p", [Status]), + ok + end; end_per_testcase(_Case, _Config) -> ok. @@ -1275,6 +1299,53 @@ stream_fun_server_close(Config) when is_list(Config) -> end. %%-------------------------------------------------------------------- +server_closing_connection_on_first_response() -> + [{doc, "Client receives \"Connection: close\" on first response." + "A client that receives a \"close\" connection option MUST cease sending" + "requests on that connection and close the connection after reading" + "the response message containing the \"close\""}]. +server_closing_connection_on_first_response(Config) when is_list(Config) -> + ReqSrvSendOctFun = + fun(V, U, S) -> + {ok, {{V, S, _}, Headers0, []}} = + httpc:request(get, {U, []}, [{version, V}], []), + {_, SendOctStr} = + proplists:lookup("x-socket-stat-send-oct", Headers0), + list_to_integer(SendOctStr) + end, + V = "HTTP/1.1", + Url0 = url(group_name(Config), "/http_1_1_send_oct.html", Config), + Url1 = url(group_name(Config), "/http_1_1_send_oct_and_connection_close.html", Config), + %% Test case assumes at most one reusable past session. + _ = ReqSrvSendOctFun(V, Url1, 204), + 0 = ReqSrvSendOctFun(V, Url0, 204), + ok. + +%%-------------------------------------------------------------------- +server_closing_connection_on_second_response() -> + [{doc, "Client receives \"Connection: close\" on second response." + "A client that receives a \"close\" connection option MUST cease sending" + "requests on that connection and close the connection after reading" + "the response message containing the \"close\""}]. +server_closing_connection_on_second_response(Config) when is_list(Config) -> + ReqSrvSendOctFun = + fun(V, U, S) -> + {ok, {{V, S, _}, Headers0, []}} = + httpc:request(get, {U, []}, [{version, V}], []), + {_, SendOctStr} = + proplists:lookup("x-socket-stat-send-oct", Headers0), + list_to_integer(SendOctStr) + end, + V = "HTTP/1.1", + Url0 = url(group_name(Config), "/http_1_1_send_oct.html", Config), + Url1 = url(group_name(Config), "/http_1_1_send_oct_and_connection_close.html", Config), + %% Test case assumes no reusable past sessions. + SendOct0 = 0 = ReqSrvSendOctFun(V, Url0, 204), + case ReqSrvSendOctFun(V, Url1, 204) of SendOct1 when SendOct1 > SendOct0 -> ok end, + 0 = ReqSrvSendOctFun(V, Url0, 204), + ok. + +%%-------------------------------------------------------------------- slow_connection() -> [{doc, "Test that a request on a slow keep-alive connection won't crash the httpc_manager"}]. slow_connection(Config) when is_list(Config) -> @@ -2232,10 +2303,32 @@ handle_uri("GET","/v1/kv/foo",_,_,_,_) -> "Content-Length: 24\r\n" ++ "Content-Type: application/json\r\n\r\n" ++ "[{\"Value\": \"aGVsbG8=\"}]\n"; +handle_uri(_,"/http_1_1_send_oct.html",_,_,Socket,_) -> + "HTTP/1.1 204 No Content\r\n" ++ + "X-Socket-Stat-Send-Oct: " ++ integer_to_list(get_stat(Socket, send_oct)) ++ "\r\n" ++ + "\r\n"; +handle_uri(_,"/http_1_1_send_oct_and_connection_close.html",_,_,Socket,_) -> + "HTTP/1.1 204 No Content\r\n" ++ + "X-Socket-Stat-Send-Oct: " ++ integer_to_list(get_stat(Socket, send_oct)) ++ "\r\n" ++ + "Connection: close\r\n" ++ + "\r\n"; handle_uri(_,_,_,_,_,DefaultResponse) -> DefaultResponse. +get_stat(S, Opt) -> + case getstat(S, [Opt]) of + {ok, [{Opt, V}]} when is_integer(V) -> + V; + {error, _} = E -> + E + end. + +getstat(#sslsocket{} = S, Opts) -> + ssl:getstat(S, Opts); +getstat(S, Opts) -> + inet:getstat(S, Opts). + url_start(#sslsocket{}) -> {ok,Host} = inet:gethostname(), ?TLS_URL_START ++ Host ++ ":"; diff --git a/lib/kernel/doc/src/Makefile b/lib/kernel/doc/src/Makefile index 0759f362d4..2413541082 100644 --- a/lib/kernel/doc/src/Makefile +++ b/lib/kernel/doc/src/Makefile @@ -137,16 +137,16 @@ clean clean_docs: rm -f errs core *~ $(SPECDIR)/specs_erl_prim_loader_stub.xml: - escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ + $(gen_verbose)escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ -o$(dir $@) -module erl_prim_loader_stub $(SPECDIR)/specs_erlang_stub.xml: - escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ + $(gen_verbose)escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ -o$(dir $@) -module erlang_stub $(SPECDIR)/specs_init_stub.xml: - escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ + $(gen_verbose)escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ -o$(dir $@) -module init_stub $(SPECDIR)/specs_zlib_stub.xml: - escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ + $(gen_verbose)escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ -o$(dir $@) -module zlib_stub # ---------------------------------------------------- diff --git a/lib/kernel/doc/src/heart.xml b/lib/kernel/doc/src/heart.xml index 5b5b71e521..46c7ce60b6 100644 --- a/lib/kernel/doc/src/heart.xml +++ b/lib/kernel/doc/src/heart.xml @@ -59,8 +59,9 @@ <pre> % <input>erl -heart -env HEART_BEAT_TIMEOUT 30 ...</input></pre> <p>The value (in seconds) must be in the range 10 < X <= 65535.</p> - <p>Notice that if the system clock is adjusted with - more than <c>HEART_BEAT_TIMEOUT</c> seconds, <c>heart</c> + <p>When running on OSs lacking support for monotonic time, + <c>heart</c> is susceptible to system clock adjustments of more than + <c>HEART_BEAT_TIMEOUT</c> seconds. When this happens, <c>heart</c> times out and tries to reboot the system. This can occur, for example, if the system clock is adjusted automatically by use of the Network Time Protocol (NTP).</p> diff --git a/lib/mnesia/doc/src/Makefile b/lib/mnesia/doc/src/Makefile index 82fcf66256..aed46d50db 100644 --- a/lib/mnesia/doc/src/Makefile +++ b/lib/mnesia/doc/src/Makefile @@ -49,16 +49,18 @@ XML_PART_FILES = \ XML_CHAPTER_FILES = \ Mnesia_chap1.xml \ Mnesia_overview.xml \ + Mnesia_chap8.xml \ + notes.xml + +XML_CHAPTER_GEN_FILES = \ Mnesia_chap2.xml \ Mnesia_chap3.xml \ Mnesia_chap4.xml \ Mnesia_chap5.xml \ Mnesia_chap7.xml \ - Mnesia_chap8.xml \ Mnesia_App_A.xml \ Mnesia_App_B.xml \ - Mnesia_App_C.xml \ - notes.xml + Mnesia_App_C.xml BOOK_FILES = book.xml @@ -66,6 +68,8 @@ XML_FILES = \ $(BOOK_FILES) $(XML_CHAPTER_FILES) \ $(XML_PART_FILES) $(XML_REF3_FILES) $(XML_APPLICATION_FILES) +XML_GEN_FILES = $(XML_CHAPTER_GEN_FILES:%=$(XMLDIR)/%) + GIF_FILES = \ company.gif diff --git a/lib/runtime_tools/doc/src/Makefile b/lib/runtime_tools/doc/src/Makefile index a9b0056a93..11583406b7 100644 --- a/lib/runtime_tools/doc/src/Makefile +++ b/lib/runtime_tools/doc/src/Makefile @@ -60,8 +60,9 @@ BOOK_FILES = book.xml XML_FILES = \ $(BOOK_FILES) $(XML_CHAPTER_FILES) \ $(XML_PART_FILES) $(XML_REF3_FILES) \ - $(XML_REF6_FILES) $(XML_APPLICATION_FILES) \ - $(GENERATED_XML_FILES) + $(XML_REF6_FILES) $(XML_APPLICATION_FILES) + +XML_GEN_FILES = $(GENERATED_XML_FILES:%=$(XMLDIR)/%) GIF_FILES = @@ -97,7 +98,7 @@ SPECS_FLAGS = -I../../include -I../../../kernel/src # Targets # ---------------------------------------------------- -%.xml: $(ERL_TOP)/HOWTO/%.md $(ERL_TOP)/make/emd2exml +$(XMLDIR)/%.xml: $(ERL_TOP)/HOWTO/%.md $(ERL_TOP)/make/emd2exml $(ERL_TOP)/make/emd2exml $< $@ $(HTMLDIR)/%.gif: %.gif diff --git a/lib/stdlib/doc/src/Makefile b/lib/stdlib/doc/src/Makefile index af27efa6c1..508a4fa2de 100644 --- a/lib/stdlib/doc/src/Makefile +++ b/lib/stdlib/doc/src/Makefile @@ -163,7 +163,7 @@ clean clean_docs: rm -f errs core *~ $(SPECDIR)/specs_erl_id_trans.xml: - escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ + $(gen_verbose)escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ -o$(dir $@) -module erl_id_trans # ---------------------------------------------------- diff --git a/lib/stdlib/doc/src/timer.xml b/lib/stdlib/doc/src/timer.xml index 8e828f8f56..53107ade2c 100644 --- a/lib/stdlib/doc/src/timer.xml +++ b/lib/stdlib/doc/src/timer.xml @@ -270,7 +270,7 @@ <item> <p>Evaluates <c>apply(<anno>Module</anno>, <anno>Function</anno>, <anno>Arguments</anno>)</c> and measures the elapsed real time as - reported by <seealso marker="erlang#monotonic_time/0"> + reported by <seealso marker="erts:erlang#monotonic_time/0"> <c>erlang:monotonic_time/0</c></seealso>.</p> <p>Returns <c>{<anno>Time</anno>, <anno>Value</anno>}</c>, where <c><anno>Time</anno></c> is the elapsed real time in diff --git a/lib/syntax_tools/doc/src/Makefile b/lib/syntax_tools/doc/src/Makefile index 1ce620b3d6..a346b9a0bd 100644 --- a/lib/syntax_tools/doc/src/Makefile +++ b/lib/syntax_tools/doc/src/Makefile @@ -63,10 +63,11 @@ BOOK_FILES = book.xml XML_FILES=\ - $(BOOK_FILES) $(XML_CHAPTER_FILES) \ - $(XML_PART_FILES) $(XML_REF3_FILES) $(XML_APPLICATION_FILES) \ + $(BOOK_FILES) $(XML_PART_FILES) $(XML_APPLICATION_FILES) \ $(XML_NOTES_FILES) +XML_GEN_FILES = $(XML_REF3_FILES:%=$(XMLDIR)/%) $(XML_CHAPTER_FILES:%=$(XMLDIR)/%) + # ---------------------------------------------------- INFO_FILE = ../../info @@ -108,11 +109,13 @@ html: gifs $(HTML_REF_MAN_FILE) man: $(MAN3_FILES) -$(XML_REF3_FILES): - escript $(DOCGEN)/priv/bin/xml_from_edoc.escript $(SRC_DIR)/$(@:%.xml=%.erl) +$(XML_REF3_FILES:%=$(XMLDIR)/%): + $(gen_verbose)escript $(DOCGEN)/priv/bin/xml_from_edoc.escript \ + -dir $(XMLDIR) $(SRC_DIR)/$(@:$(XMLDIR)/%.xml=%.erl) -$(XML_CHAPTER_FILES): - escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(VSN) -chapter ../overview.edoc +$(XML_CHAPTER_FILES:%=$(XMLDIR)/%): + $(gen_verbose)escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(VSN) \ + -chapter -dir $(XMLDIR) ../overview.edoc gifs: $(GIF_FILES:%=$(HTMLDIR)/%) diff --git a/lib/wx/doc/src/Makefile b/lib/wx/doc/src/Makefile index a76740adf1..c132c628f7 100644 --- a/lib/wx/doc/src/Makefile +++ b/lib/wx/doc/src/Makefile @@ -46,9 +46,13 @@ XML_NOTES_FILES = notes.xml BOOK_FILES = book.xml XML_FILES = \ - $(BOOK_FILES) $(XML_CHAPTER_FILES) \ - $(XML_PART_FILES) $(XML_REF3_FILES) \ - $(XML_NOTES_FILES) $(XML_APPLICATION_FILES) + $(BOOK_FILES) \ + $(XML_PART_FILES) $(XML_NOTES_FILES) + +XML_GEN_FILES = \ + $(XML_CHAPTER_FILES:%=$(XMLDIR)/%) \ + $(XML_REF3_FILES:%=$(XMLDIR)/%) \ + $(XML_APPLICATION_FILES:%=$(XMLDIR)/%) # ---------------------------------------------------- INFO_FILE = ../../info @@ -93,22 +97,26 @@ gifs: $(GIF_FILES:%=$(HTMLDIR)/%) xml: $(XML_REF3_FILES) $(XML_CHAPTER_FILES) ref_man.xml: ref_man.xml.src - @echo Preparing ref_man.xml - @cat ref_man.xml.src > ref_man.xml + @echo Preparing $@ + @cat ref_man.xml.src > $@ @for d in $(ModsNoExt); do \ - echo " <xi:include href=\"$$d.xml\"/>" >> ref_man.xml ; \ + echo " <xi:include href=\"$$d.xml\"/>" >> $@ ; \ done - @echo "</application>" >> ref_man.xml - @echo + @echo "</application>" >> $@ -$(ErlMods:%.erl=%.xml): ../../src/$(@:%.xml=%.erl) - escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(VSN) -preprocess true -sort_functions false ../../src/$(@:%.xml=%.erl) +$(ErlMods:%.erl=$(XMLDIR)/%.xml): + $(gen_verbose)escript $(DOCGEN)/priv/bin/xml_from_edoc.escript \ + -def vsn $(VSN) -preprocess true -sort_functions false -dir $(XMLDIR) \ + ../../src/$(@:$(XMLDIR)/%.xml=%.erl) -$(GenMods:%.erl=%.xml): ../../src/gen/$(@:%.xml=%.erl) - escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(VSN) -i ../../src -preprocess true -sort_functions false ../../src/gen/$(@:%.xml=%.erl) +$(GenMods:%.erl=$(XMLDIR)/%.xml): + $(gen_verbose)escript $(DOCGEN)/priv/bin/xml_from_edoc.escript \ + -def vsn $(VSN) -i ../../src -preprocess true -sort_functions false -dir $(XMLDIR) \ + ../../src/gen/$(@:$(XMLDIR)/%.xml=%.erl) -$(XML_CHAPTER_FILES): ../overview.edoc - escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(VSN) -chapter ../overview.edoc +$(XML_CHAPTER_FILES:%=$(XMLDIR)/%): ../overview.edoc + $(gen_verbose)escript $(DOCGEN)/priv/bin/xml_from_edoc.escript \ + -def vsn $(VSN) -chapter -dir $(XMLDIR) $< debug opt: @@ -118,7 +126,7 @@ clean clean_docs: rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f $(SPECDIR)/* rm -f errs core *~ ../html/edoc-info - rm -f $(XML_REF3_FILES) $(XML_CHAPTER_FILES) *.html + rm -f $(XML_GEN_FILES) *.html # ---------------------------------------------------- # Release Target diff --git a/lib/xmerl/doc/src/Makefile b/lib/xmerl/doc/src/Makefile index 7d0b0b2392..94100910ef 100644 --- a/lib/xmerl/doc/src/Makefile +++ b/lib/xmerl/doc/src/Makefile @@ -54,10 +54,9 @@ XMERL_MODULES = \ XML_APPLICATION_FILES = ref_man.xml -XMERL_XML_FILES = $(XMERL_MODULES:=.xml) +XMERL_XML_FILES = $(XMERL_MODULES:%=$(XMLDIR)/%.xml) -XML_REF3_FILES = $(XMERL_XML_FILES) \ - xmerl_sax_parser.xml +XML_REF3_FILES = xmerl_sax_parser.xml XML_PART_FILES = \ part.xml @@ -65,9 +64,10 @@ XML_PART_FILES = \ XML_REF6_FILES = XML_CHAPTER_FILES = \ - xmerl_ug.xml \ notes.xml +XML_CHAPTER_GEN_FILES = \ + $(XMLDIR)/xmerl_ug.xml HTML_EXAMPLE_FILES = \ xmerl_examples.html \ @@ -89,6 +89,8 @@ XML_FILES= \ $(BOOK_FILES) $(XML_CHAPTER_FILES) \ $(XML_PART_FILES) $(XML_REF3_FILES) $(XML_APPLICATION_FILES) +XML_GEN_FILES = $(XMERL_XML_FILES) $(XML_CHAPTER_GEN_FILES) + # ---------------------------------------------------- INFO_FILE = ../../info @@ -97,7 +99,7 @@ HTML_FILES = $(XML_REF_MAN:%.xml=$(HTMLDIR)/%.html) \ $(XML_PART_FILES:%.xml=$(HTMLDIR)/%.html) -MAN3_FILES = $(XML_REF3_FILES:%.xml=$(MAN3DIR)/%.3) +MAN3_FILES = $(XML_REF3_FILES:%.xml=$(MAN3DIR)/%.3) $(XMERL_MODULES:%=$(MAN3DIR)/%.3) MAN6_FILES = $(XML_REF6_FILES:%_app.xml=$(MAN6DIR)/%.6) HTML_REF_MAN_FILE = $(HTMLDIR)/index.html @@ -126,7 +128,7 @@ pdf: $(TOP_PDF_FILE) html: gifs $(HTML_REF_MAN_FILE) $(XMERL_XML_FILES): - escript $(DOCGEN)/priv/bin/xml_from_edoc.escript $(XMERL_DIR)/$(@:%.xml=%.erl) + $(gen_verbose)escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -dir $(XMLDIR) $(XMERL_DIR)/$(@:$(XMLDIR)/%.xml=%.erl) man: $(MAN3_FILES) $(MAN6_FILES) diff --git a/make/emd2exml.in b/make/emd2exml.in index 13bd6700d9..57bcaba24d 100755 --- a/make/emd2exml.in +++ b/make/emd2exml.in @@ -747,7 +747,7 @@ header(#state{ofile = {File, _}} = S0, Title) -> integer_to_list(Day), "</date>", nl(), "<rev>1</rev>", nl(), - "<file>",File,"</file>", nl(), + "<file>",filename:basename(File),"</file>", nl(), "</header>", nl()]), put_delayed(S3, ?DELAYED_TOC_IX). diff --git a/make/otp.mk.in b/make/otp.mk.in index 1d538fa528..c514a150ca 100644 --- a/make/otp.mk.in +++ b/make/otp.mk.in @@ -222,6 +222,7 @@ MAN9DIR = $(DOCDIR)/man9 TEXDIR = . SPECDIR = $(DOCDIR)/specs +XMLDIR = $(DOCDIR)/xml ifeq ($(CSS_FILE),) CSS_FILE = otp_doc.css @@ -276,55 +277,34 @@ endif SPECS_EXTRACTOR=$(DOCGEN)/priv/bin/specs_gen.escript # Extract specifications and types from Erlang source files (-spec, -type) $(SPECDIR)/specs_%.xml: $(SPECS_ESRC)/%.erl - escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) -o$(dir $@) $< + $(gen_verbose)escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) -o$(dir $@) $< $(SPECDIR)/specs_%.xml: $(SPECS_ESRC)/gen/%.erl - escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) -o$(dir $@) $< + $(gen_verbose)escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) -o$(dir $@) $< +MANXSLTARGS=--stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/dtd -path $(DOCGEN)/priv/dtd_man_entities -path . -$(MAN1DIR)/%.1: %.xml - date=`date +"%B %e, %Y"`; \ - xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $< - -$(MAN2DIR)/%.2: %.xml - date=`date +"%B %e, %Y"`; \ - xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $< +$(MAN1DIR)/%.1 $(MAN2DIR)/%.2 $(MAN4DIR)/%.4 $(MAN4DIR)/%.5 $(MAN9DIR)/%.9: $(XMLDIR)/%.xml + $(gen_verbose)date=`date +"%B %e, %Y"`; \ + xsltproc --output "$@" $(MANXSLTARGS) $(DOCGEN)/priv/xsl/db_man.xsl $< ifneq ($(wildcard $(SPECDIR)),) -$(MAN3DIR)/%.3: %.xml $(SPECDIR)/specs_%.xml - date=`date +"%B %e, %Y"`; \ +$(MAN3DIR)/%.3: $(XMLDIR)/%.xml $(SPECDIR)/specs_%.xml + $(gen_verbose)date=`date +"%B %e, %Y"`; \ specs_file=`pwd`/$(SPECDIR)/specs_$*.xml; \ - xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --stringparam specs_file "$$specs_file" --xinclude -path $(DOCGEN)/priv/dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $< + xsltproc --output "$@" $(MANXSLTARGS) --stringparam specs_file "$$specs_file" $(DOCGEN)/priv/xsl/db_man.xsl $< else -$(MAN3DIR)/%.3: %.xml - date=`date +"%B %e, %Y"`; \ - xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $< +$(MAN3DIR)/%.3: $(XMLDIR)/%.xml + $(gen_verbose)date=`date +"%B %e, %Y"`; \ + xsltproc --output "$@" $(MANXSLTARGS) $(DOCGEN)/priv/xsl/db_man.xsl $< endif # left for compatibility -$(MAN4DIR)/%.4: %.xml - date=`date +"%B %e, %Y"`; \ - xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $< - -$(MAN4DIR)/%.5: %.xml - date=`date +"%B %e, %Y"`; \ - xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $< - -# left for compatibility -$(MAN6DIR)/%.6: %_app.xml - date=`date +"%B %e, %Y"`; \ - xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $< - -$(MAN6DIR)/%.7: %_app.xml - date=`date +"%B %e, %Y"`; \ - xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $< - -$(MAN9DIR)/%.9: %.xml - date=`date +"%B %e, %Y"`; \ - xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $< - +$(MAN6DIR)/%.6 $(MAN6DIR)/%.7: $(XMLDIR)/%_app.xml + $(gen_verbose)date=`date +"%B %e, %Y"`; \ + xsltproc --output "$@" $(MANXSLTARGS) $(DOCGEN)/priv/xsl/db_man.xsl $< -.xmlsrc.xml: - escript $(DOCGEN)/priv/bin/codeline_preprocessing.escript $< $@ +$(XMLDIR)/%.xml: $(XMLDIR)/%.xmlsrc + $(gen_verbose)escript $(DOCGEN)/priv/bin/codeline_preprocessing.escript $(shell pwd) $< $@ .fo.pdf: $(FOP) -c $(FOP_CONFIG) -cache $(ERL_TOP)/make/$(TARGET)/fop-fonts.cache -fo $< -pdf $@ diff --git a/make/otp_release_targets.mk b/make/otp_release_targets.mk index 23b4416963..779aaa1a1e 100644 --- a/make/otp_release_targets.mk +++ b/make/otp_release_targets.mk @@ -33,9 +33,24 @@ ifneq ($(wildcard $(MOD2APP)),) MOD2APP_PARAM = --stringparam mod2app_file "$(MOD2APP)" endif +# ------------------------------------------------------- +# Take the XML files and add the github link info to them +# ------------------------------------------------------- +_create_xml_dirs := $(shell mkdir -p $(XMLDIR)) + +XML_GEN_FILES+=$(patsubst %.xml,$(XMLDIR)/%.xml,$(XML_FILES)) +$(XMLDIR)/%.xml: %.xml + $(gen_verbose)escript $(DOCGEN)/priv/bin/github_link.escript $< \ + "$(subst $(ERL_TOP)/,,$(CURDIR)/$^)" "NA" $@ + +$(XMLDIR)/%.xmlsrc: %.xmlsrc + $(gen_verbose)escript $(DOCGEN)/priv/bin/github_link.escript $< \ + "$(subst $(ERL_TOP)/,,$(CURDIR)/$^)" "NA" $@ + ifeq ($(TOPDOC),) -$(HTMLDIR)/index.html: $(XML_FILES) $(SPECS_FILES) - date=`date +"%B %e, %Y"`; \ + +$(HTMLDIR)/index.html: $(XML_GEN_FILES) $(SPECS_FILES) + $(gen_verbose)date=`date +"%B %e, %Y"`; \ $(XSLTPROC) --noout \ --stringparam outdir $(HTMLDIR) \ --stringparam docgen "$(DOCGEN)" \ @@ -50,14 +65,15 @@ $(HTMLDIR)/index.html: $(XML_FILES) $(SPECS_FILES) --stringparam winprefix "$(WINPREFIX)" \ --stringparam logo "$(HTMLLOGO_FILE)" \ --stringparam pdfname "$(PDFNAME)" \ + -path . \ -path $(DOCGEN)/priv/dtd \ -path $(DOCGEN)/priv/dtd_html_entities \ - $(DOCGEN)/priv/xsl/db_html.xsl book.xml + $(DOCGEN)/priv/xsl/db_html.xsl $(XMLDIR)/book.xml endif -$(HTMLDIR)/users_guide.html: $(XML_FILES) - date=`date +"%B %e, %Y"`; \ +$(HTMLDIR)/users_guide.html: $(XML_GEN_FILES) + $(gen_verbose)date=`date +"%B %e, %Y"`; \ $(XSLTPROC) --noout \ --stringparam outdir $(HTMLDIR) \ --stringparam docgen "$(DOCGEN)" \ @@ -72,12 +88,13 @@ $(HTMLDIR)/users_guide.html: $(XML_FILES) --stringparam logo "$(HTMLLOGO_FILE)" \ --stringparam pdfname "$(PDFNAME)" \ --xinclude \ + -path . \ -path $(DOCGEN)/priv/dtd \ -path $(DOCGEN)/priv/dtd_html_entities \ - $(DOCGEN)/priv/xsl/db_html.xsl book.xml + $(DOCGEN)/priv/xsl/db_html.xsl $(XMLDIR)/book.xml -%.fo: $(XML_FILES) $(SPECS_FILES) - date=`date +"%B %e, %Y"`; \ +%.fo: $(XML_GEN_FILES) $(SPECS_FILES) + $(gen_verbose)date=`date +"%B %e, %Y"`; \ $(XSLTPROC) \ --stringparam docgen "$(DOCGEN)" \ --stringparam gendate "$$date" \ @@ -87,9 +104,10 @@ $(HTMLDIR)/users_guide.html: $(XML_FILES) --stringparam logo "$(PDFLOGO_FILE)" \ --stringparam pdfcolor "$(PDFCOLOR)" \ --xinclude $(TOP_SPECS_PARAM) \ + -path . \ -path $(DOCGEN)/priv/dtd \ -path $(DOCGEN)/priv/dtd_html_entities \ - $(DOCGEN)/priv/xsl/db_pdf.xsl book.xml > $@ + $(DOCGEN)/priv/xsl/db_pdf.xsl $(XMLDIR)/book.xml > $@ # ------------------------------------------------------------------------ # The following targets just exist in the documentation directory @@ -101,16 +119,17 @@ ifneq ($(XML_FILES),) # ---------------------------------------------------- # Generation of application index data # ---------------------------------------------------- -$(HTMLDIR)/$(APPLICATION).eix: $(XML_FILES) $(SPECS_FILES) - date=`date +"%B %e, %Y"`; \ +$(HTMLDIR)/$(APPLICATION).eix: $(XML_GEN_FILES) $(SPECS_FILES) + $(gen_verbose)date=`date +"%B %e, %Y"`; \ $(XSLTPROC) --stringparam docgen "$(DOCGEN)" \ --stringparam gendate "$$date" \ --stringparam appname "$(APPLICATION)" \ --stringparam appver "$(VSN)" \ -xinclude $(TOP_SPECS_PARAM) \ + -path . \ -path $(DOCGEN)/priv/dtd \ -path $(DOCGEN)/priv/dtd_html_entities \ - $(DOCGEN)/priv/xsl/db_eix.xsl book.xml > $@ + $(DOCGEN)/priv/xsl/db_eix.xsl $(XMLDIR)/book.xml > $@ docs: $(HTMLDIR)/$(APPLICATION).eix @@ -118,30 +137,37 @@ docs: $(HTMLDIR)/$(APPLICATION).eix ## Then we look into all those files check for xi:includes BOOK_XI_INC_FILES:=$(foreach file,$(BOOK_FILES),$(shell awk -F\" '/xi:include/ {print $$2}' $(file))) $(BOOK_FILES) ALL_XI_INC_FILES:=$(foreach file,$(BOOK_XI_INC_FILES),$(shell awk -F\" '/xi:include/ {if ("$(dir $(file))" != "./") printf "$(dir $(file))"; print $$2}' $(file))) $(BOOK_XI_INC_FILES) +ifeq ($(TOPDOC), true) +ALL_XI_INC_GEN_FILES:=$(filter-out book.xml,$(ALL_XI_INC_FILES)) $(BOOK_FILES:%=$(XMLDIR)/%) +else +ALL_XI_INC_GEN_FILES:=$(ALL_XI_INC_FILES:%=$(XMLDIR)/%) +endif + ## These are the patterns of file names that xmllint cannot currently parse XI_INC_FILES:=%user_man.xml %usersguide.xml %refman.xml %ref_man.xml %part.xml %book.xml ## These are the files that we should run the xmllint on LINT_XI_INC_FILES := $(filter-out $(XI_INC_FILES), $(ALL_XI_INC_FILES)) +LINT_XI_INC_GEN_FILES := $(filter-out $(XI_INC_FILES), $(ALL_XI_INC_GEN_FILES)) EMPTY := SPACE := $(EMPTY) $(EMPTY) XMLLINT_SRCDIRS:=$(subst $(SPACE),:,$(sort $(foreach file,$(XML_FILES),$(dir $(file))))) -xmllint: $(ALL_XI_INC_FILES) -## We verify that the $(XML_FILES) variable in the Makefile have exactly +xmllint: $(ALL_XI_INC_GEN_FILES) +## We verify that the $(XML_GEN_FILES) variable in the Makefile have exactly ## the same files as we found out by following xi:include. -ifneq ($(filter-out $(filter %.xml,$(XML_FILES)),$(ALL_XI_INC_FILES)),) - $(error "$(filter-out $(filter %.xml,$(XML_FILES)),$(ALL_XI_INC_FILES)) in $$ALL_XI_INC_FILES but not in $$XML_FILES"); +ifneq ($(filter-out $(filter %.xml,$(XML_GEN_FILES)),$(ALL_XI_INC_GEN_FILES)),) + $(error "$(filter-out $(filter %.xml,$(XML_GEN_FILES)),$(ALL_XI_INC_GEN_FILES)) in $$ALL_XI_INC_FILES but not in $$XML_GEN_FILES"); endif -ifneq ($(filter-out $(ALL_XI_INC_FILES),$(filter %.xml,$(XML_FILES))),) - $(error "$(filter-out $(ALL_XI_INC_FILES),$(filter %.xml,$(XML_FILES))) in $$XML_FILES but not in $$ALL_XI_INC_FILES"); +ifneq ($(filter-out $(ALL_XI_INC_GEN_FILES),$(filter %.xml,$(XML_GEN_FILES))),) + $(error "$(filter-out $(ALL_XI_INC_GEN_FILES),$(filter %.xml,$(XML_GEN_FILES))) in $$XML_GEN_FILES but not in $$ALL_XI_INC_FILES"); endif - @echo "xmllint $(LINT_XI_INC_FILES)" + @echo "xmllint $(LINT_XI_INC_GEN_FILES)" @xmllint --noout --valid --nodefdtd --loaddtd --path \ $(DOCGEN)/priv/dtd:$(DOCGEN)/priv/dtd_html_entities:$(XMLLINT_SRCDIRS) \ - $(LINT_XI_INC_FILES) + $(LINT_XI_INC_GEN_FILES) # ---------------------------------------------------- # Local documentation target for testing diff --git a/scripts/diffable b/scripts/diffable new file mode 100755 index 0000000000..f22194e99f --- /dev/null +++ b/scripts/diffable @@ -0,0 +1,620 @@ +#!/usr/bin/env escript +%% -*- erlang -*- +-mode(compile). + +main(Args0) -> + {Args,Opts} = opts(Args0, #{format=>asm,no_compile=>false}), + case Args of + [OutDir] -> + do_compile(OutDir, Opts); + _ -> + usage(), + halt(1) + end. + +usage() -> + S = "usage: otp-diffable-asm [OPTION] DIRECTORY\n\n" + "Options:\n" + " --asm Output to .S files (default)\n" + " --dis Output to .dis files\n" + " --no-compile Disassemble from BEAM files (use with --dis)\n" + "\n" + "DESCRIPTION\n" + "\n" + "Compile some applications from OTP (more than 700 modules) to either\n" + ".S files or .dis files. The files are massaged to make them diff-friendly.\n" + "\n" + "EXAMPLES\n" + "\n" + "This example shows how the effectiveness of a compiler \n" + "optimization can be verified (alternatively, that pure code\n" + "refactoring has no effect on the generated code):\n" + "\n" + "$ scripts/diffable old\n" + "# Hack the compiler.\n" + "$ scripts/diffable new\n" + "$ diff -u old new\n" + "\n" + "This example shows how the effectiveness of loader hacks\n" + "can be verified:\n" + "\n" + "$ scripts/diffable --dis --no-compile old\n" + "# Hack ops.tab and/or one of the *instr.tab files.\n" + "$ scripts/diffable --dis --no-compile new\n" + "$ diff -u old new\n", + io:put_chars(S). + +opts(["--asm"|Args], Opts) -> + opts(Args, Opts#{format:=asm}); +opts(["--dis"|Args], Opts) -> + opts(Args, Opts#{format:=dis}); +opts(["--no-compile"|Args], Opts) -> + opts(Args, Opts#{format:=dis,no_compile:=true}); +opts(Args, Opts) -> + {Args,Opts}. + +do_compile(OutDir, Opts0) -> + Opts1 = Opts0#{outdir=>OutDir}, + _ = filelib:ensure_dir(filename:join(OutDir, "dummy")), + Apps = ["preloaded", + "asn1", + "stdlib", + "kernel", + "reltool", + "runtime_tools", + "xmerl", + "common_test", + "compiler", + "diameter", + "mnesia", + "inets", + "syntax_tools", + "parsetools", + "dialyzer", + "ssl", + "wx"], + {Files,Opts} = get_files(Apps, Opts1), + CF = choose_format(Opts), + p_run(fun(File) -> + compile_file(CF, File) + end, Files). + +choose_format(#{format:=Format}=Opts) -> + case Format of + asm -> + compile_to_asm_fun(Opts); + dis -> + compile_to_dis_fun(Opts) + end. + +compile_file(CF, File) -> + try + CF(File) + catch + Class:Error:Stk -> + io:format("~s: ~p ~p\n~p\n", + [File,Class,Error,Stk]), + error + end. + +%%% +%%% Get names of files (either .erl files or BEAM files). +%%% + +get_files(Apps, #{format:=dis,no_compile:=true}=Opts) -> + Files = get_beams(Apps), + {Files,Opts}; +get_files(Apps, #{}=Opts) -> + Inc = make_includes(), + CompilerOpts = [{d,epmd_dist_high,42}, + {d,epmd_dist_low,37}, + {d,'VSN',1}, + {d,'COMPILER_VSN',1}, + {d,erlang_daemon_port,1337}|Inc], + Files0 = get_src(Apps), + Files = add_opts(Files0, CompilerOpts), + {Files,Opts}. + +add_opts([F|Fs], Opts0) -> + Opts = case filename:basename(F) of + "group_history.erl" -> + Opts0 -- [{d,'VSN',1}]; + _ -> + Opts0 + end, + [{F,Opts}|add_opts(Fs, Opts0)]; +add_opts([], _Opts) -> + []. + +get_src(["preloaded"|Apps]) -> + WC = filename:join(code:root_dir(), "erts/preloaded/src/*.erl"), + filelib:wildcard(WC) ++ get_src(Apps); +get_src(["inets"|Apps]) -> + LibDir = code:lib_dir(inets), + WC = filename:join(LibDir, "src/*/*.erl"), + filelib:wildcard(WC) ++ get_src(Apps); +get_src(["syntax_tools"|Apps]) -> + LibDir = code:lib_dir(syntax_tools), + WC = filename:join(LibDir, "src/*.erl"), + Files0 = filelib:wildcard(WC), + Files = [F || F <- Files0, + filename:basename(F) =/= "merl_tests.erl"], + Files ++ get_src(Apps); +get_src(["wx"|Apps]) -> + LibDir = code:lib_dir(wx), + WC1 = filename:join(LibDir, "src/gen/*.erl"), + WC2 = filename:join(LibDir, "src/*.erl"), + filelib:wildcard(WC1) ++ filelib:wildcard(WC2) ++ get_src(Apps); +get_src([App|Apps]) -> + WC = filename:join(code:lib_dir(App), "src/*.erl"), + filelib:wildcard(WC) ++ get_src(Apps); +get_src([]) -> []. + +make_includes() -> + Is = [{common_test,"include"}, + {inets,"include"}, + {inets,"src/http_client"}, + {inets,"src/http_lib"}, + {inets,"src/http_server"}, + {inets,"src/inets_app"}, + {kernel,"include"}, + {kernel,"src"}, + {public_key,"include"}, + {runtime_tools,"include"}, + {ssh,"include"}, + {snmp,"include"}, + {stdlib,"include"}, + {syntax_tools,"include"}, + {wx,"src"}, + {wx,"include"}, + {xmerl,"include"}], + [{i,filename:join(code:lib_dir(App), Path)} || {App,Path} <- Is]. + +get_beams(["preloaded"|Apps]) -> + WC = filename:join(code:root_dir(), "erts/preloaded/ebin/*.beam"), + filelib:wildcard(WC) ++ get_beams(Apps); +get_beams([App|Apps]) -> + WC = filename:join(code:lib_dir(App), "ebin/*.beam"), + filelib:wildcard(WC) ++ get_beams(Apps); +get_beams([]) -> []. + + +%%% +%%% Generate renumbered .S files. +%%% + +compile_to_asm_fun(#{outdir:=OutDir}) -> + fun(File) -> + compile_to_asm(File, OutDir) + end. + +compile_to_asm({File,Opts}, OutDir) -> + case compile:file(File, [to_asm,binary,report_errors|Opts]) of + error -> + error; + {ok,Mod,Asm0} -> + {ok,Asm1} = beam_a:module(Asm0, []), + Asm2 = renumber_asm(Asm1), + {ok,Asm} = beam_z:module(Asm2, []), + print_asm(Mod, OutDir, Asm) + end. + +print_asm(Mod, OutDir, Asm) -> + S = atom_to_list(Mod) ++ ".S", + Name = filename:join(OutDir, S), + {ok,Fd} = file:open(Name, [write,raw,delayed_write]), + ok = beam_listing(Fd, Asm), + ok = file:close(Fd). + +renumber_asm({Mod,Exp,Attr,Fs0,NumLabels}) -> + EntryLabels = maps:from_list(entry_labels(Fs0)), + Fs = [fix_func(F, EntryLabels) || F <- Fs0], + {Mod,Exp,Attr,Fs,NumLabels}. + +entry_labels(Fs) -> + [{Entry,{Name,Arity}} || {function,Name,Arity,Entry,_} <- Fs]. + +fix_func({function,Name,Arity,Entry0,Is0}, LabelMap0) -> + Entry = maps:get(Entry0, LabelMap0), + LabelMap = label_map(Is0, 1, LabelMap0), + Is = replace(Is0, [], LabelMap), + {function,Name,Arity,Entry,Is}. + +label_map([{label,Old}|Is], New, Map) -> + case maps:is_key(Old, Map) of + false -> + label_map(Is, New+1, Map#{Old=>New}); + true -> + label_map(Is, New, Map) + end; +label_map([_|Is], New, Map) -> + label_map(Is, New, Map); +label_map([], _New, Map) -> + Map. + +replace([{label,Lbl}|Is], Acc, D) -> + replace(Is, [{label,label(Lbl, D)}|Acc], D); +replace([{test,Test,{f,Lbl},Ops}|Is], Acc, D) -> + replace(Is, [{test,Test,{f,label(Lbl, D)},Ops}|Acc], D); +replace([{test,Test,{f,Lbl},Live,Ops,Dst}|Is], Acc, D) -> + replace(Is, [{test,Test,{f,label(Lbl, D)},Live,Ops,Dst}|Acc], D); +replace([{select,I,R,{f,Fail0},Vls0}|Is], Acc, D) -> + Vls = lists:map(fun ({f,L}) -> {f,label(L, D)}; + (Other) -> Other + end, Vls0), + Fail = label(Fail0, D), + replace(Is, [{select,I,R,{f,Fail},Vls}|Acc], D); +replace([{'try',R,{f,Lbl}}|Is], Acc, D) -> + replace(Is, [{'try',R,{f,label(Lbl, D)}}|Acc], D); +replace([{'catch',R,{f,Lbl}}|Is], Acc, D) -> + replace(Is, [{'catch',R,{f,label(Lbl, D)}}|Acc], D); +replace([{jump,{f,Lbl}}|Is], Acc, D) -> + replace(Is, [{jump,{f,label(Lbl, D)}}|Acc], D); +replace([{loop_rec,{f,Lbl},R}|Is], Acc, D) -> + replace(Is, [{loop_rec,{f,label(Lbl, D)},R}|Acc], D); +replace([{loop_rec_end,{f,Lbl}}|Is], Acc, D) -> + replace(Is, [{loop_rec_end,{f,label(Lbl, D)}}|Acc], D); +replace([{wait,{f,Lbl}}|Is], Acc, D) -> + replace(Is, [{wait,{f,label(Lbl, D)}}|Acc], D); +replace([{wait_timeout,{f,Lbl},To}|Is], Acc, D) -> + replace(Is, [{wait_timeout,{f,label(Lbl, D)},To}|Acc], D); +replace([{bif,Name,{f,Lbl},As,R}|Is], Acc, D) when Lbl =/= 0 -> + replace(Is, [{bif,Name,{f,label(Lbl, D)},As,R}|Acc], D); +replace([{gc_bif,Name,{f,Lbl},Live,As,R}|Is], Acc, D) when Lbl =/= 0 -> + replace(Is, [{gc_bif,Name,{f,label(Lbl, D)},Live,As,R}|Acc], D); +replace([{call,Ar,{f,Lbl}}|Is], Acc, D) -> + replace(Is, [{call,Ar,{f,label(Lbl,D)}}|Acc], D); +replace([{make_fun2,{f,Lbl},U1,U2,U3}|Is], Acc, D) -> + replace(Is, [{make_fun2,{f,label(Lbl, D)},U1,U2,U3}|Acc], D); +replace([{bs_init,{f,Lbl},Info,Live,Ss,Dst}|Is], Acc, D) when Lbl =/= 0 -> + replace(Is, [{bs_init,{f,label(Lbl, D)},Info,Live,Ss,Dst}|Acc], D); +replace([{bs_put,{f,Lbl},Info,Ss}|Is], Acc, D) when Lbl =/= 0 -> + replace(Is, [{bs_put,{f,label(Lbl, D)},Info,Ss}|Acc], D); +replace([{put_map=I,{f,Lbl},Op,Src,Dst,Live,List}|Is], Acc, D) + when Lbl =/= 0 -> + replace(Is, [{I,{f,label(Lbl, D)},Op,Src,Dst,Live,List}|Acc], D); +replace([{get_map_elements=I,{f,Lbl},Src,List}|Is], Acc, D) when Lbl =/= 0 -> + replace(Is, [{I,{f,label(Lbl, D)},Src,List}|Acc], D); +replace([{recv_mark=I,{f,Lbl}}|Is], Acc, D) -> + replace(Is, [{I,{f,label(Lbl, D)}}|Acc], D); +replace([{recv_set=I,{f,Lbl}}|Is], Acc, D) -> + replace(Is, [{I,{f,label(Lbl, D)}}|Acc], D); +replace([I|Is], Acc, D) -> + replace(Is, [I|Acc], D); +replace([], Acc, _) -> + lists:reverse(Acc). + +label(Old, D) when is_integer(Old) -> + maps:get(Old, D). + +%%% +%%% Compile and disassemble the loaded code. +%%% + +compile_to_dis_fun(#{outdir:=OutDir,no_compile:=false}) -> + fun(File) -> + compile_to_dis(File, OutDir) + end; +compile_to_dis_fun(#{outdir:=OutDir,no_compile:=true}) -> + fun(File) -> + dis_only(File, OutDir) + end. + +compile_to_dis({File,Opts}, OutDir) -> + case compile:file(File, [to_asm,binary,report_errors|Opts]) of + error -> + error; + {ok,Mod,Asm0} -> + NewMod = list_to_atom("--"++atom_to_list(Mod)++"--"), + Asm = rename_mod_in_asm(Asm0, Mod, NewMod), + AsmOpts = [from_asm,report,no_postopt,binary], + {ok,NewMod,Beam} = compile:forms(Asm, AsmOpts), + Dis0 = disasm(NewMod, Beam), + Dis1 = renumber_disasm(Dis0, Mod, NewMod), + Dis = format_disasm(Dis1), + OutFile = filename:join(OutDir, atom_to_list(Mod)++".dis"), + ok = file:write_file(OutFile, Dis) + end. + +dis_only(File, OutDir) -> + Mod0 = filename:rootname(filename:basename(File)), + Mod = list_to_atom(Mod0), + Dis0 = disasm(Mod), + Dis1 = renumber_disasm(Dis0, Mod, Mod), + Dis = format_disasm(Dis1), + OutFile = filename:join(OutDir, atom_to_list(Mod)++".dis"), + ok = file:write_file(OutFile, Dis). + +%%% Loading system modules can cause any number of problems. +%%% Therefore, we rename all modules to a dummy name before +%%% loading and disassembling them. + +rename_mod_in_asm({OldMod,Exp,_Attr,Fs0,NumLabels}, OldMod, NewMod) -> + Fs = [fix_func_info(F, {atom,OldMod}, {atom,NewMod}) || F <- Fs0], + {NewMod,Exp,[],Fs,NumLabels}. + +fix_func_info({function,Name,Arity,Entry,Is0}, OldMod, NewMod) -> + Is1 = [begin + case I of + {func_info,_,F,A} -> + {func_info,NewMod,F,A}; + _ -> + I + end + end || I <- Is0], + Is = case {Name,Arity} of + {module_info,0} -> fix_module_info(Is1, OldMod, NewMod); + {module_info,1} -> fix_module_info(Is1, OldMod, NewMod); + {_,_} -> Is1 + end, + {function,Name,Arity,Entry,Is}. + +fix_module_info([{move,OldMod,Dst}|Is], OldMod, NewMod) -> + [{move,NewMod,Dst}|fix_module_info(Is, OldMod, NewMod)]; +fix_module_info([I|Is], OldMod, NewMod) -> + [I|fix_module_info(Is, OldMod, NewMod)]; +fix_module_info([], _, _) -> + []. + + +%%% Disassemble the module. + +disasm(Mod, Beam) -> + {module,Mod} = code:load_binary(Mod, "", Beam), + disasm(Mod). + +disasm(Mod) -> + disasm_1(Mod:module_info(functions), Mod). + +disasm_1([{Name,Arity}|Fs], Mod) -> + MFA = {Mod,Name,Arity}, + Dis = disasm_func({MFA,<<>>,MFA}, MFA), + [{Name,Arity,Dis}|disasm_1(Fs, Mod)]; +disasm_1([], _) -> + []. + +disasm_func({Next,_,MFA}, MFA) -> + case erts_debug:disassemble(Next) of + {_,Line,MFA}=Cont -> + [Line|disasm_func(Cont, MFA)]; + {_,_,_} -> + []; + false -> + [] + end. + +%%% Renumber the disassembled module to use labels instead of +%%% absolute addresses. Also do other translations so that the +%%% output will be the same each time (for the same BEAM file +%%% runtime system). + +renumber_disasm(Fs0, OldMod, NewMod) -> + Fs1 = split_dis_lines(Fs0), + renumber_disasm_fs(Fs1, OldMod, NewMod). + +renumber_disasm_fs([{Name,Arity,Is0}|Fs], OldMod, NewMod) -> + Labels = find_labels(Is0, Name, Arity), + Is1 = rename_mod(Is0, OldMod, NewMod), + Is = renumber_disasm_func(Is1, Labels), + [{Name,Arity,Is}|renumber_disasm_fs(Fs, OldMod, NewMod)]; +renumber_disasm_fs([], _OldMod, _NewMod) -> + []. + +renumber_disasm_func([[A,OpCode|Ops0]|Is], Labels) -> + Spaces = " ", + Left = case maps:find(A, Labels) of + {ok,Lbl} -> + case byte_size(Lbl) of + LblSize when LblSize < length(Spaces) -> + [$\n,Lbl,":",lists:nth(LblSize, Spaces)]; + _ -> + [Lbl,":\n"|Spaces] + end; + error -> + Spaces + end, + Ops1 = [replace_label(Op, Labels) || Op <- Ops0], + Ops = handle_special_instrs(OpCode, Ops1), + [[Left,OpCode|Ops]|renumber_disasm_func(Is, Labels)]; +renumber_disasm_func([], _) -> + []. + +handle_special_instrs(<<"i_get_hash_cId">>, [Key,_Hash,Dst]) -> + [Key,hash_value(),Dst]; +handle_special_instrs(<<"i_get_map_element_",_/binary>>, + [Fail,Src,Key,_Hash,Dst]) -> + [Fail,Src,Key,hash_value(),Dst]; +handle_special_instrs(<<"i_get_map_elements_",_/binary>>, + [Fail,Src,N,Space|List0]) -> + List1 = rejoin_atoms(List0), + List = fix_hash_value(List1), + [Fail,Src,N,Space|List]; +handle_special_instrs(<<"i_select_val_bins_",_/binary>>, + [Src,Fail,Num|List0]) -> + %% Atoms are sorted in atom-number order, which is + %% different every time the runtime system is restarted. + %% Resort the values in ASCII order. + List1 = rejoin_atoms(List0), + {Values0,Labels0} = lists:split(length(List1) div 2, List1), + Zipped0 = lists:zip(Values0, Labels0), + Zipped = lists:sort(Zipped0), + {Values,Labels} = lists:unzip(Zipped), + [Src,Fail,Num|Values++Labels]; +handle_special_instrs(<<"i_select_val_lins_",_/binary>>, + [Src,Fail,Num|List0]) -> + List1 = rejoin_atoms(List0), + {Values0,Labels0} = lists:split(length(List1) div 2, List1), + Values1 = lists:droplast(Values0), + Labels1 = lists:droplast(Labels0), + Vlast = lists:last(Values0), + Llast = lists:last(Labels0), + Zipped0 = lists:zip(Values1, Labels1), + Zipped = lists:sort(Zipped0), + {Values,Labels} = lists:unzip(Zipped), + [Src,Fail,Num|Values++[Vlast]++Labels++[Llast]]; +handle_special_instrs(_, Ops) -> + Ops. + +fix_hash_value([Val,Dst,_Hash|T]) -> + [Val,Dst,hash_value()|fix_hash_value(T)]; +fix_hash_value([]) -> + []. + +hash_value() -> + <<"--hash-value--">>. + +replace_label(<<"f(",T/binary>>, Labels) -> + replace_label_1("f(", T, Labels); +replace_label(<<"j(",T/binary>>, Labels) -> + replace_label_1("j(", T, Labels); +replace_label(Op, _Labels) -> + Op. + +replace_label_1(Prefix, Lbl0, Labels) -> + Sz = byte_size(Lbl0)-1, + Lbl = case Lbl0 of + <<"0)">> -> + Lbl0; + <<Lbl1:Sz/bytes,")">> -> + [maps:get(Lbl1, Labels),")"]; + _ -> + Lbl0 + end, + iolist_to_binary([Prefix,Lbl]). + +split_dis_lines(Fs) -> + {ok,RE} = re:compile(<<"\\s*\\n$">>), + Colon = binary:compile_pattern(<<": ">>), + Space = binary:compile_pattern(<<" ">>), + [split_dis_func(F, RE, Colon, Space) || F <- Fs]. + +split_dis_func({Name,Arity,Lines0}, RE, Colon, Space) -> + Lines1 = [re:replace(L, RE, <<>>, [{return,binary}]) || L <- Lines0], + Lines2 = [begin + [A,I] = binary:split(L, Colon), + Ops = binary:split(I, Space, [global]), + [A|Ops] + end|| L <- Lines1], + {Name,Arity,Lines2}. + +rejoin_atoms([<<"'",Tail/binary>> = Bin0,Next|Ops]) -> + Sz = byte_size(Tail) - 1, + case Tail of + <<_:Sz/bytes,"'">> -> + [Bin0|rejoin_atoms([Next|Ops])]; + <<>> -> + Bin = <<Bin0/binary,$\s,Next/binary>>, + rejoin_atoms([Bin|Ops]); + _ -> + Bin = <<Bin0/binary,$\s,Next/binary>>, + rejoin_atoms([Bin|Ops]) + end; +rejoin_atoms(Ops) -> + Ops. + +find_labels(Is, Name, Arity) -> + [_,[Entry|_]|_] = Is, + EntryLabel = iolist_to_binary(io_lib:format("~p/~p", [Name,Arity])), + {ok,RE} = re:compile(<<"^[fj]\\(([0-9A-F]{8,16})\\)$">>), + Ls0 = [find_labels_1(Ops, RE) || [_Addr,_OpCode|Ops] <- Is], + Ls1 = lists:flatten(Ls0), + Ls2 = lists:usort(Ls1), + Ls3 = number(Ls2, 1), + Ls = [{Entry,EntryLabel}|Ls3], + maps:from_list(Ls). + +find_labels_1([Op|Ops], RE) -> + case re:run(Op, RE, [{capture,all_but_first,binary}]) of + nomatch -> + find_labels_1(Ops, RE); + {match,[M]} -> + [M|find_labels_1(Ops, RE)] + end; +find_labels_1([], _) -> + []. + +number([H|T], N) -> + S = iolist_to_binary(["L",integer_to_list(N)]), + [{H,S}|number(T, N+1)]; +number([], _) -> + []. + +format_disasm([{_,_,Is}|Fs]) -> + L = [lists:join(" ", I) || I <- Is], + [lists:join("\n", L),"\n\n"|format_disasm(Fs)]; +format_disasm([]) -> + []. + +rename_mod(Is, OldMod0, NewMod) -> + OldMod = atom_to_binary(OldMod0, utf8), + Pattern = <<"'",(atom_to_binary(NewMod, utf8))/binary,"'">>, + [rename_mod_1(I, Pattern, OldMod) || I <- Is]. + +rename_mod_1([A,OpCode|Ops], Pat, Replacement) -> + [A,OpCode|[rename_mod_2(Op, Pat, Replacement) || Op <- Ops]]. + +rename_mod_2(Subject, Pat, Replacement) -> + Sz = byte_size(Pat), + case Subject of + <<Pat:Sz/bytes,Tail/binary>> -> + <<Replacement/binary,Tail/binary>>; + _ -> + Subject + end. + +%%% +%%% Run tasks in parallel. +%%% + +p_run(Test, List) -> + N = erlang:system_info(schedulers) * 2, + p_run_loop(Test, List, N, [], 0). + +p_run_loop(_, [], _, [], Errors) -> + io:put_chars("\r \n"), + case Errors of + 0 -> + ok; + N -> + io:format("~p errors\n", [N]), + halt(1) + end; +p_run_loop(Test, [H|T], N, Refs, Errors) when length(Refs) < N -> + {_,Ref} = erlang:spawn_monitor(fun() -> exit(Test(H)) end), + p_run_loop(Test, T, N, [Ref|Refs], Errors); +p_run_loop(Test, List, N, Refs0, Errors0) -> + io:format("\r~p ", [length(List)+length(Refs0)]), + receive + {'DOWN',Ref,process,_,Res} -> + Errors = case Res of + ok -> Errors0; + error -> Errors0 + 1 + end, + Refs = Refs0 -- [Ref], + p_run_loop(Test, List, N, Refs, Errors) + end. + +%%% +%%% Borrowed from beam_listing and tweaked. +%%% + +beam_listing(Stream, {Mod,Exp,Attr,Code,NumLabels}) -> + Head = ["%% -*- encoding:latin-1 -*-\n", + io_lib:format("{module, ~p}. %% version = ~w\n", + [Mod, beam_opcodes:format_number()]), + io_lib:format("\n{exports, ~p}.\n", [Exp]), + io_lib:format("\n{attributes, ~p}.\n", [Attr]), + io_lib:format("\n{labels, ~p}.\n", [NumLabels])], + ok = file:write(Stream, Head), + lists:foreach( + fun ({function,Name,Arity,Entry,Asm}) -> + S = [io_lib:format("\n\n{function, ~w, ~w, ~w}.\n", + [Name,Arity,Entry])|format_asm(Asm)], + ok = file:write(Stream, S) + end, Code). + +format_asm([{label,_}=I|Is]) -> + [io_lib:format(" ~p", [I]),".\n"|format_asm(Is)]; +format_asm([I|Is]) -> + [io_lib:format(" ~p", [I]),".\n"|format_asm(Is)]; +format_asm([]) -> []. diff --git a/system/doc/design_principles/Makefile b/system/doc/design_principles/Makefile index 5743a50b47..611ab6da99 100644 --- a/system/doc/design_principles/Makefile +++ b/system/doc/design_principles/Makefile @@ -18,6 +18,7 @@ # %CopyrightEnd% # # + include $(ERL_TOP)/make/target.mk include $(ERL_TOP)/make/$(TARGET)/otp.mk @@ -27,6 +28,8 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk include $(ERL_TOP)/erts/vsn.mk APPLICATION=otp-system-documentation +XMLDIR := $(XMLDIR)/design_principles + # ---------------------------------------------------- # Release directory specification # ---------------------------------------------------- diff --git a/system/doc/efficiency_guide/Makefile b/system/doc/efficiency_guide/Makefile index 36e4cd00df..b1630a36e1 100644 --- a/system/doc/efficiency_guide/Makefile +++ b/system/doc/efficiency_guide/Makefile @@ -28,6 +28,7 @@ include $(ERL_TOP)/erts/vsn.mk #VSN=$(SYSTEM_VSN) APPLICATION=otp-system-documentation +XMLDIR := $(XMLDIR)/efficiency_guide # ---------------------------------------------------- # Release directory specification # ---------------------------------------------------- diff --git a/system/doc/embedded/Makefile b/system/doc/embedded/Makefile index 40a1b1fb23..23d3168e34 100644 --- a/system/doc/embedded/Makefile +++ b/system/doc/embedded/Makefile @@ -28,6 +28,7 @@ include $(ERL_TOP)/erts/vsn.mk #VSN=$(SYSTEM_VSN) APPLICATION=otp-system-documentation +XMLDIR := $(XMLDIR)/embedded # ---------------------------------------------------- # Release directory specification # ---------------------------------------------------- diff --git a/system/doc/getting_started/Makefile b/system/doc/getting_started/Makefile index 1fe3d39e4e..13d767daf5 100644 --- a/system/doc/getting_started/Makefile +++ b/system/doc/getting_started/Makefile @@ -28,6 +28,7 @@ include $(ERL_TOP)/erts/vsn.mk #VSN=$(SYSTEM_VSN) APPLICATION=otp-system-documentation +XMLDIR := $(XMLDIR)/getting_started # ---------------------------------------------------- # Release directory specification # ---------------------------------------------------- diff --git a/system/doc/installation_guide/Makefile b/system/doc/installation_guide/Makefile index 673c203422..002c2a536a 100644 --- a/system/doc/installation_guide/Makefile +++ b/system/doc/installation_guide/Makefile @@ -28,6 +28,8 @@ include $(ERL_TOP)/erts/vsn.mk #VSN=$(SYSTEM_VSN) APPLICATION=otp-system-documentation +XMLDIR := $(XMLDIR)/installation_guide + # ---------------------------------------------------- # Release directory specification # ---------------------------------------------------- @@ -43,6 +45,8 @@ include xmlfiles.mk XML_CHAPTER_FILES=$(INST_GUIDE_CHAPTER_FILES) +# ---------------------------------------------------- + TOPDOCDIR=.. BOOK_FILES = book.xml @@ -55,12 +59,7 @@ XML_FILES = \ $(BOOK_FILES) $(XML_CHAPTER_FILES) \ $(XML_PART_FILES) -# ---------------------------------------------------- -GENERATED_XML_FILES = \ - INSTALL.xml \ - INSTALL-CROSS.xml \ - INSTALL-WIN32.xml \ - OTP-PATCH-APPLY.xml +XML_GEN_FILES = $(INST_GUIDE_CHAPTER_GEN_FILES:%=$(XMLDIR)/%) # ---------------------------------------------------- @@ -88,7 +87,7 @@ DVIPS_FLAGS += # Targets # ---------------------------------------------------- -%.xml: $(ERL_TOP)/HOWTO/%.md $(ERL_TOP)/make/emd2exml +$(XMLDIR)/%.xml: $(ERL_TOP)/HOWTO/%.md $(ERL_TOP)/make/emd2exml $(ERL_TOP)/make/emd2exml $< $@ $(REDIRECT_HTML_DIR)/%.html: Makefile @@ -102,12 +101,12 @@ $(REDIRECT_HTML_DIR)/%.html: Makefile echo "This <a href=\"../"$(notdir $@)"\">link</a> will" >> $@ echo "take you there immediately.</p></body></html>" >> $@ -docs: $(GENERATED_XML_FILES) html +docs: $(XML_GEN_FILES) html local_docs: PDFDIR=../../pdf -local_docs: $(GENERATED_XML_FILES) +local_docs: $(XML_GEN_FILES) -html: $(REDIRECT_HTML_FILES) $(GENERATED_XML_FILES) $(GIF_FILES) $(HTML_UG_FILE) +html: $(REDIRECT_HTML_FILES) $(XML_GEN_FILES) $(GIF_FILES) $(HTML_UG_FILE) debug opt: diff --git a/system/doc/installation_guide/xmlfiles.mk b/system/doc/installation_guide/xmlfiles.mk index 3f720e1ee5..37fbeca96b 100644 --- a/system/doc/installation_guide/xmlfiles.mk +++ b/system/doc/installation_guide/xmlfiles.mk @@ -18,7 +18,9 @@ # %CopyrightEnd% # INST_GUIDE_CHAPTER_FILES = \ - install-binary.xml \ + install-binary.xml + +INST_GUIDE_CHAPTER_GEN_FILES = \ INSTALL.xml \ INSTALL-CROSS.xml \ INSTALL-WIN32.xml \ diff --git a/system/doc/oam/Makefile b/system/doc/oam/Makefile index 9095744423..dfebc6aca0 100644 --- a/system/doc/oam/Makefile +++ b/system/doc/oam/Makefile @@ -27,6 +27,7 @@ include $(ERL_TOP)/erts/vsn.mk #VSN=$(SYSTEM_VSN) APPLICATION=otp-system-documentation +XMLDIR := $(XMLDIR)/oam # ---------------------------------------------------- # Release directory specification # ---------------------------------------------------- diff --git a/system/doc/programming_examples/Makefile b/system/doc/programming_examples/Makefile index 237076d770..af731f85b4 100644 --- a/system/doc/programming_examples/Makefile +++ b/system/doc/programming_examples/Makefile @@ -28,6 +28,7 @@ include $(ERL_TOP)/erts/vsn.mk #VSN=$(SYSTEM_VSN) APPLICATION=otp-system-documentation +XMLDIR := $(XMLDIR)/programming_examples # ---------------------------------------------------- # Release directory specification # ---------------------------------------------------- @@ -52,7 +53,9 @@ PS_FILES = XML_FILES = \ $(BOOK_FILES) $(XML_CHAPTER_FILES) \ - $(XML_PART_FILES) + $(XML_PART_FILES) + +XML_GEN_FILES = $(PROG_EX_CHAPTER_GEN_FILES:%=$(XMLDIR)/%) # ---------------------------------------------------- HTML_FILES = \ diff --git a/system/doc/programming_examples/xmlfiles.mk b/system/doc/programming_examples/xmlfiles.mk index 5129e488f4..20b08d8cd3 100644 --- a/system/doc/programming_examples/xmlfiles.mk +++ b/system/doc/programming_examples/xmlfiles.mk @@ -19,6 +19,8 @@ # PROG_EX_CHAPTER_FILES = \ bit_syntax.xml \ - funs.xml \ list_comprehensions.xml \ records.xml + +PROG_EX_CHAPTER_GEN_FILES = \ + funs.xml diff --git a/system/doc/reference_manual/Makefile b/system/doc/reference_manual/Makefile index e14a056979..75c15e4b5f 100644 --- a/system/doc/reference_manual/Makefile +++ b/system/doc/reference_manual/Makefile @@ -28,6 +28,7 @@ include $(ERL_TOP)/erts/vsn.mk #VSN=$(SYSTEM_VSN) APPLICATION=otp-system-documentation +XMLDIR := $(XMLDIR)/reference_manual # ---------------------------------------------------- # Release directory specification # ---------------------------------------------------- diff --git a/system/doc/system_architecture_intro/Makefile b/system/doc/system_architecture_intro/Makefile index 446e66205c..7a10f305ba 100644 --- a/system/doc/system_architecture_intro/Makefile +++ b/system/doc/system_architecture_intro/Makefile @@ -28,6 +28,7 @@ include $(ERL_TOP)/erts/vsn.mk #VSN=$(SYSTEM_VSN) APPLICATION=otp-system-documentation +XMLDIR := $(XMLDIR)/system_architecture_intro # ---------------------------------------------------- # Release directory specification # ---------------------------------------------------- diff --git a/system/doc/system_principles/Makefile b/system/doc/system_principles/Makefile index 77edea8f58..ec6591ec6b 100644 --- a/system/doc/system_principles/Makefile +++ b/system/doc/system_principles/Makefile @@ -28,6 +28,7 @@ include $(ERL_TOP)/erts/vsn.mk #VSN=$(SYSTEM_VSN) APPLICATION=otp-system-documentation +XMLDIR := $(XMLDIR)/system_principles # ---------------------------------------------------- # Release directory specification # ---------------------------------------------------- @@ -52,6 +53,8 @@ XML_FILES = \ $(BOOK_FILES) $(XML_CHAPTER_FILES) \ $(XML_PART_FILES) +XML_GEN_FILES = $(SYSTEM_PRINCIPLES_CHAPTER_GEN_FILES:%=$(XMLDIR)/%) + # ---------------------------------------------------- HTMLDIR = ../html/system_principles diff --git a/system/doc/system_principles/xmlfiles.mk b/system/doc/system_principles/xmlfiles.mk index c3c3bb4731..f8972b24a7 100644 --- a/system/doc/system_principles/xmlfiles.mk +++ b/system/doc/system_principles/xmlfiles.mk @@ -20,6 +20,8 @@ SYSTEM_PRINCIPLES_CHAPTER_FILES = \ system_principles.xml \ error_logging.xml \ - create_target.xml \ upgrade.xml \ versions.xml + +SYSTEM_PRINCIPLES_CHAPTER_GEN_FILES = \ + create_target.xml diff --git a/system/doc/top/Makefile b/system/doc/top/Makefile index b6a80aadf5..73c943caa1 100644 --- a/system/doc/top/Makefile +++ b/system/doc/top/Makefile @@ -53,30 +53,45 @@ include ../oam/xmlfiles.mk BOOK_FILES = book.xml XML_FILES = \ - $(INST_GUIDE_CHAPTER_FILES:%=../installation_guide/%) \ - $(SYSTEM_PRINCIPLES_CHAPTER_FILES:%=../system_principles/%) \ - $(EMBEDDED_CHAPTER_FILES:%=../embedded/%) \ - $(GETTING_STARTED_CHAPTER_FILES:%=../getting_started/%) \ - $(REF_MAN_CHAPTER_FILES:%=../reference_manual/%) \ - $(PROG_EX_CHAPTER_FILES:%=../programming_examples/%) \ - $(EFF_GUIDE_CHAPTER_FILES:%=../efficiency_guide/%) \ - $(TUTORIAL_CHAPTER_FILES:%=../tutorial/%) \ - $(DESIGN_PRINCIPLES_CHAPTER_FILES:%=../design_principles/%) \ - $(OAM_CHAPTER_FILES:%=../oam/%) \ - ../installation_guide/part.xml \ - ../system_principles/part.xml \ - ../embedded/part.xml \ - ../getting_started/part.xml \ - ../reference_manual/part.xml \ - ../programming_examples/part.xml \ - ../efficiency_guide/part.xml \ - ../tutorial/part.xml \ - ../design_principles/part.xml \ - ../oam/part.xml \ $(BOOK_FILES) - -XMLLINT_SRCDIRS= ../installation_guide:../system_principles:../embedded:../getting_started:../reference_manual:../programming_examples:../efficiency_guide:../tutorial:../design_principles:../oam +XML_GUIDE_FILES = \ + $(INST_GUIDE_CHAPTER_FILES:%=installation_guide/%) \ + $(INST_GUIDE_CHAPTER_GEN_FILES:%=installation_guide/%) \ + $(SYSTEM_PRINCIPLES_CHAPTER_FILES:%=system_principles/%) \ + $(SYSTEM_PRINCIPLES_CHAPTER_GEN_FILES:%=system_principles/%) \ + $(EMBEDDED_CHAPTER_FILES:%=embedded/%) \ + $(EMBEDDED_CHAPTER_GEN_FILES:%=embedded/%) \ + $(GETTING_STARTED_CHAPTER_FILES:%=getting_started/%) \ + $(GETTING_STARTED_CHAPTER_GEN_FILES:%=getting_started/%) \ + $(REF_MAN_CHAPTER_FILES:%=reference_manual/%) \ + $(REF_MAN_CHAPTER_GEN_FILES:%=reference_manual/%) \ + $(PROG_EX_CHAPTER_FILES:%=programming_examples/%) \ + $(PROG_EX_CHAPTER_GEN_FILES:%=programming_examples/%) \ + $(EFF_GUIDE_CHAPTER_FILES:%=efficiency_guide/%) \ + $(EFF_GUIDE_CHAPTER_GEN_FILES:%=efficiency_guide/%) \ + $(TUTORIAL_CHAPTER_FILES:%=tutorial/%) \ + $(TUTORIAL_CHAPTER_GEN_FILES:%=tutorial/%) \ + $(DESIGN_PRINCIPLES_CHAPTER_FILES:%=design_principles/%) \ + $(DESIGN_PRINCIPLES_CHAPTER_GEN_FILES:%=design_principles/%) \ + $(OAM_CHAPTER_FILES:%=oam/%) \ + $(OAM_CHAPTER_GEN_FILES:%=oam/%) + +XML_GEN_FILES = \ + $(XML_GUIDE_FILES:%=$(XMLDIR)/%) \ + $(XMLDIR)/installation_guide/part.xml \ + $(XMLDIR)/system_principles/part.xml \ + $(XMLDIR)/embedded/part.xml \ + $(XMLDIR)/getting_started/part.xml \ + $(XMLDIR)/reference_manual/part.xml \ + $(XMLDIR)/programming_examples/part.xml \ + $(XMLDIR)/efficiency_guide/part.xml \ + $(XMLDIR)/tutorial/part.xml \ + $(XMLDIR)/design_principles/part.xml \ + $(XMLDIR)/oam/part.xml + + +XMLLINT_SRCDIRS= $(XMLDIR)/installation_guide:$(XMLDIR)/system_principles:$(XMLDIR)/embedded:$(XMLDIR)/getting_started:$(XMLDIR)/reference_manual:$(XMLDIR)/programming_examples:$(XMLDIR)/efficiency_guide:$(XMLDIR)/tutorial:$(XMLDIR)/design_principles:$(XMLDIR)/oam HTMLDIR= ../html PDFREFDIR= pdf @@ -240,13 +255,11 @@ clean: rm -f $(INDEX_SCRIPT) $(GLOSSARY_SCRIPT) \ $(JAVASCRIPT_BUILD_SCRIPT) rm -f erl_crash.dump errs core *~ - # ---------------------------------------------------- # Release Target # ---------------------------------------------------- include $(ERL_TOP)/make/otp_release_targets.mk - release_docs_spec: docs $(INSTALL_DIR) "$(RELEASE_PATH)" $(INSTALL_DATA) $(INFO_FILES) "$(RELEASE_PATH)" diff --git a/system/doc/top/book.xml b/system/doc/top/book.xml index c94b0f24d6..540b6bfd24 100644 --- a/system/doc/top/book.xml +++ b/system/doc/top/book.xml @@ -36,16 +36,16 @@ <contents level="2"></contents> </preamble> <parts lift="no"> - <xi:include href="../installation_guide/part.xml"/> - <xi:include href="../system_principles/part.xml"/> - <xi:include href="../embedded/part.xml"/> - <xi:include href="../getting_started/part.xml"/> - <xi:include href="../reference_manual/part.xml"/> - <xi:include href="../programming_examples/part.xml"/> - <xi:include href="../efficiency_guide/part.xml"/> - <xi:include href="../tutorial/part.xml"/> - <xi:include href="../design_principles/part.xml"/> - <xi:include href="../oam/part.xml"/> + <xi:include href="../xml/installation_guide/part.xml"/> + <xi:include href="../xml/system_principles/part.xml"/> + <xi:include href="../xml/embedded/part.xml"/> + <xi:include href="../xml/getting_started/part.xml"/> + <xi:include href="../xml/reference_manual/part.xml"/> + <xi:include href="../xml/programming_examples/part.xml"/> + <xi:include href="../xml/efficiency_guide/part.xml"/> + <xi:include href="../xml/tutorial/part.xml"/> + <xi:include href="../xml/design_principles/part.xml"/> + <xi:include href="../xml/oam/part.xml"/> </parts> <listofterms></listofterms> <index></index> diff --git a/system/doc/tutorial/Makefile b/system/doc/tutorial/Makefile index 5deea41f0a..606064da72 100644 --- a/system/doc/tutorial/Makefile +++ b/system/doc/tutorial/Makefile @@ -28,6 +28,7 @@ include $(ERL_TOP)/erts/vsn.mk #VSN=$(SYSTEM_VSN) APPLICATION=otp-system-documentation +XMLDIR := $(XMLDIR)/tutorial # ---------------------------------------------------- # Release directory specification # ---------------------------------------------------- @@ -53,6 +54,9 @@ XML_FILES = \ $(BOOK_FILES) $(XML_CHAPTER_FILES) \ $(XML_PART_FILES) +XML_GEN_FILES = \ + $(TUTORIAL_CHAPTER_GEN_FILES:%=$(XMLDIR)/%) + # ---------------------------------------------------- C_FILES = \ diff --git a/system/doc/tutorial/xmlfiles.mk b/system/doc/tutorial/xmlfiles.mk index f8ed7be064..53f82c6475 100644 --- a/system/doc/tutorial/xmlfiles.mk +++ b/system/doc/tutorial/xmlfiles.mk @@ -19,13 +19,16 @@ # TUTORIAL_CHAPTER_FILES = \ introduction.xml\ + overview.xml + +TUTORIAL_CHAPTER_GEN_FILES = \ cnode.xml\ c_port.xml\ erl_interface.xml \ c_portdriver.xml \ example.xml\ - overview.xml\ nif.xml + # appendix.xml # distribution.xml (to be part of tutorial later) |